Nachträge aus der Planrunde (Fragment-Link, Teamkopie ohne Link, Schalter AUFTRAEGE_ENABLED, Projekt später zuordnen, Schlussrechnung bis 40 Zeilen, zusammengesetzte Sperrschlüssel, Zuständigkeiten). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
31 KiB
Aufträge und Rechnungen: Auftragsbestätigung und projektbezogene Rechnungen
Stand: 2026-10-06 · Status: freigegeben (Abschnitte im Chat einzeln freigegeben; Nachträge aus der Planrunde eingearbeitet, siehe „Nachträge“ am Ende)
Grundlage: Wunsch des Nutzers vom 06.10.2026 („Auftragsbestätigung und Rechnungen bei uns, wenn wir auf Kunden gehen;
Projekt auswählen, Zusammenfassung sehen, Festbeträge möglich“), Recherche im selben Gespräch (Quellen am Ende),
Bestand: Finanzen-Spezifikation 2026-10-01-finanzen-design.md (Stripe-Rechnungen aus WOMS, live seit 01.10.2026).
Ziel
Im Ticketsystem (WOMS) legt ein Admin beim Kunden Auftragsbestätigungen (AB) und Rechnungen zu einem Projekt an. Nach der Projektwahl zeigt eine Zusammenfassung, was vereinbart ist, was schon berechnet und bezahlt ist, was noch offen ist und wie viel Zeit im Projekt steckt. Die Rechnung entsteht als Anzahlung, Schlussrechnung, nach Aufwand oder als frei gewählter Festbetrag – auch wenn die erfasste Zeit mehr wert wäre (Beispiel: Frau Wolf, 500 € laut mündlicher Absprache).
Erfolg:
- Eine Projektrechnung (Festbetrag oder Aufwand) ist in unter zwei Minuten geschrieben und versendet.
- Eine AB geht mit PDF an den Kunden, der sie per Klick bestätigt; bei Privatkunden ist sie widerrufsrechtlich korrekt.
- Kein Arbeitsblatt wird doppelt berechnet, keine Anzahlung wird in der Schlussrechnung vergessen.
- Jede Rechnung erfüllt § 34a UStDV, jede gesendete AB liegt unveränderlich mit Prüfsumme vor.
Feststehende Rahmenbedingungen (geprüft)
- WEBklar GbR, Kleinunternehmer nach § 19 UStG. Rechnungen müssen nach § 34a UStDV (seit 01.01.2025) enthalten:
Name und Anschrift beider Seiten, Steuernummer (oder USt-IdNr./Kleinunternehmer-IdNr.), Ausstellungsdatum, Art
und Umfang der Leistung, Entgelt in einer Summe mit Hinweis auf die Kleinunternehmerbefreiung. Leistungszeitpunkt und
Rechnungsnummer sind für Kleinunternehmer keine Pflicht; § 33 UStDV (Kleinbetrag bis 250 €) bleibt unberührt.
Befund: Der heutige Rechnungsfuß (
config.stripe.invoiceFooter) enthält keine Steuernummer. - Aufbewahrung: Rechnungsdoppel 8 Jahre (§ 14b UStG seit 2025), Auftragsbestätigungen als Beleg 8 bzw. als Geschäftsbrief 6 Jahre. E-Rechnungen muss ein Kleinunternehmer nicht ausstellen.
- Verbraucher: Bei Fernabsatzverträgen (Telefon, E-Mail, Chat) muss der Unternehmer den Vertrag auf einem dauerhaften Datenträger bestätigen, spätestens bevor er mit der Leistung beginnt (§ 312f Abs. 2 BGB), samt der Angaben nach Art. 246a EGBGB und Widerrufsbelehrung. Ohne Belehrung läuft die Widerrufsfrist bis zu 12 Monate und 14 Tage; ohne ausdrückliches Verlangen des Verbrauchers vor Fristende schuldet er bei Widerruf keinen Wertersatz.
- Kostenschätzung: Zeichnet sich eine wesentliche Überschreitung eines Kostenanschlags ab, muss der Unternehmer den Besteller unverzüglich informieren (§ 649 Abs. 2 BGB).
- AGB (webklar.com/agb): Vergütung „ergibt sich aus dem Angebot“, Aufwand in 15-Minuten-Schritten, Unterstützung zur Hälfte (Nr. 9), Mitwirkung (Nr. 7), Abnahme (Nr. 8), „Projektleistungen sind nach Vereinbarung fällig“. Stundensatz in den Abo-Bedingungen: 100 € pro Stunde (Endpreis, § 19 UStG).
- Stripe (SDK
stripe@19, API 2025-10-29.clover): Rechnungen mit bis zu 4 Zusatzfeldern im Kopf (Name ≤ 40, Wert ≤ 140 Zeichen), Seitengröße perrendering.pdf.page_size(Standard außerhalb Japans: US-Letter), Rechnungsposten mit negativemamount(mindert den Betrag), Steuer-IDs des Kontos im Dashboard (Einstellungen → Billing → Rechnungen → „Steuerinformationen für Rechnungen“). Stripe-„Quotes“ taugen nicht als AB (Aufpreis, PDF-Titel „Angebot“, keine Verbraucher-Variante). - Bestand im Portal-Server:
createProjectInvoiceinserver/services/finance/stripeFinance.js(Entwurf/Senden, Adress-Sperre über 250 €, Doppel-Schutz), Finanzen-API/api/admin/finanzen/*mitrequireAppwriteStaff(Admin, zweiter Faktor), MailersendCustomerMailmit Anhängen, Fristenlogikdeadlines.js(withdrawalDeadline), Frühbeginn-Erklärungen nach Muster Terminplaner/Webshop, öffentliche Widerrufsseitewiderrufen.html(/api/abo/public/withdraw), Kundenansicht-Sperre (fail-closed), Arbeitszeit-RegelnworksheetMinutes.js. - Bestand im WOMS: Reiter „Rechnungen“ am Kunden (nur Admins), Dialog „Rechnung schreiben“ (freie Positionen),
Finanzen-Seite. Projekte (
websiteProjects) hängen an genau einem Ticket (ticketId), Arbeitsblätter (worksheets.totalTime,supporters,countsToPlan) an Tickets. - WOMS-Redesign (weißes Design, Pakete P4 Kunden und P7 Finanzen) baut parallel genau die betroffenen Dateien um.
Entscheidungen des Nutzers (06.10.2026)
- Abrechnungsarten: Festpreis, nach Aufwand (Arbeitsblätter × Stundensatz) und Anzahlung mit Schlussrechnung; ein freier Festbetrag geht immer.
- Auch Privatkunden: Kunden bekommen die Kundenart Unternehmen / Privatperson. Bei Privatpersonen enthält die AB Widerrufsbelehrung und Muster-Widerrufsformular; Arbeitsbeginn vor Fristende nur auf ausdrückliches Verlangen.
- AB-Versand: Mail mit PDF und Knopf „Auftrag bestätigen“ (Link ohne Anmeldung, auch im Portal sichtbar); der Klick wird protokolliert.
- Ansatz A: Rechnungen bleiben Stripe-Rechnungen (erweitert); die AB ist ein eigenes Dokument des Portal-Servers.
- Abschnitte 1–4 dieses Entwurfs (Oberfläche, AB, Rechnungen, Technik/Livegang) wie unten beschrieben.
- Reihenfolge: Portal-Server und Kundenseiten zuerst; WOMS-Oberfläche im neuen weißen Design, sobald die Redesign-Stränge Kunden (P4) und Finanzen (P7) zusammengeführt sind. Zwei Pläne (siehe unten).
Begriffe
| Begriff | Bedeutung |
|---|---|
| Auftrag / AB | Eine Auftragsbestätigung an einen Kunden, meist zu einem Projekt. Art Festpreis (Positionen) oder Aufwand (Stundensatz, Schätzung). |
| Projektkonto | Zusammenfassung je Projekt: vereinbart, berechnet, bezahlt, noch offen, Zeit erfasst. |
| Zeitquelle | Die Tickets, deren Arbeitsblätter zu einem Projekt/Auftrag zählen (Standard: das mit dem Projekt verknüpfte Ticket). |
| Rechnungsart | anzahlung, schluss, aufwand, festbetrag (mit Projekt) oder frei (ohne Projekt, wie heute). |
| Abo-Zeit | Arbeitsblätter mit countsToPlan = true; sie laufen über das Abo-Stundenkonto und werden nie projektbezogen berechnet. |
1. Oberfläche in WOMS
Ort: Kunde → Reiter „Aufträge und Rechnungen“ (bisher „Rechnungen“, id bleibt invoices), nur für Admins.
Gebaut im neuen weißen Design (Komponenten des Redesigns, z. B. <Dialog>).
Von oben nach unten:
- Projekte (Projektkonto): je Projekt des Kunden eine Zeile mit Name, Art und Ticketnummer; Spalten Vereinbart (Summe der gültigen Festpreis-ABs bzw. „nach Aufwand, 100 €/Std.“ bzw. „keine AB“), Berechnet (darunter „bezahlt x €“), Noch offen, Zeit erfasst (Stunden, darunter „Wert x €“). Knöpfe „Auftragsbestätigung“ und „Rechnung“. Eine letzte Zeile „Ohne Projekt“ sammelt Rechnungen ohne Projektbezug.
- Aufträge: Liste der ABs (Nummer, Projekt/Titel, Datum, Summe bzw. „nach Aufwand“, Status, Aktionen: PDF, Erinnerung senden, Neue Fassung, Stornieren, Entwurf bearbeiten/löschen).
- Rechnungen: die bestehende Rechnungsliste mit den zusätzlichen Spalten Projekt und Art.
Der neue Dialog „Rechnung schreiben“ ersetzt den bisherigen überall. Seine Projektliste endet mit „Ohne Projekt“
(Art frei: freie Positionen wie bisher), so bleibt eine Rechnung ohne Projekt möglich.
Kundenart: In der Kunden-Übersicht ein Feld „Kundenart: Unternehmen / Privatperson“ (leer = unbekannt). Ist es leer, fragt der AB-Dialog im ersten Schritt danach und speichert die Antwort am Kunden.
Finanzen-Seite: „Rechnung schreiben“ öffnet denselben neuen Dialog, mit Kundenwahl davor. Die Rechnungstabelle bekommt die Spalten Projekt und Art.
Arbeitsblätter (Ticketseite): Ein abgerechnetes Arbeitsblatt zeigt das Abzeichen „abgerechnet (Rechnungsnummer)“. Ändert jemand dessen Zeit, warnt der Dialog: „Dieses Arbeitsblatt ist abgerechnet (WEBKLAR-0009). Eine Änderung ändert die Rechnung nicht.“ (Keine harte Sperre: WOMS schreibt Arbeitsblätter direkt in Appwrite.) Das Abzeichen sehen alle Mitarbeiter (ohne Beträge).
Dialog „Rechnung schreiben“ (neu)
- Projekt (vorausgewählt, wenn vom Projektkonto geöffnet) oder „Ohne Projekt“.
- Zusammenfassung des Projektkontos (siehe Abschnitt 4) und Art: Anzahlung, Schlussrechnung, Nach Aufwand, Festbetrag. Anzahlung und Schlussrechnung sind nur mit gültiger Festpreis-AB wählbar (Hinweis statt Sperre ohne Erklärung: „Anzahlung und Schlussrechnung brauchen eine Auftragsbestätigung.“).
- Positionen (je Art vorausgefüllt, änderbar), Leistungszeitraum (optional, bei Aufwand vorausgefüllt), Zahlungsziel (Standard 14 Tage), Notiz; Summe mit § 19-Hinweis.
- „Als Entwurf speichern“ oder „Senden“ (mit Rückfrage wie heute; Adress-Sperre über 250 € wie heute).
Dialog „Auftragsbestätigung“ (neu)
- Projekt (oder freier Titel, wenn es noch kein Projekt gibt; später zuordenbar über „Projekt zuordnen“ in der AB-Liste, ohne das PDF zu ändern) und, falls leer, Kundenart.
- Auftrag: Datum der Absprache und Weg (mündlich, telefonisch, per E-Mail, vor Ort, im Chat). Art Festpreis (Positionen: Beschreibung, Menge, Einzelpreis; Grenzen wie bei Rechnungen) oder Nach Aufwand (Stundensatz, Standard 100 €; Schätzung in Stunden, optional, in 15-Minuten-Schritten).
- Zahlung und Termine: Zahlungsplan „Alles nach Abnahme“ · „Anzahlung x % bei Auftrag, Rest nach Abnahme“ (Standard 50 %) · „Monatlich nach Aufwand“ (nur Aufwand) · „Frei“ (Text, höchstens 500 Zeichen); Zahlungsziel (Standard 14 Tage); Start und voraussichtliche Fertigstellung (optional); Zeitquelle (Tickets des Kunden, Standard: Ticket des Projekts).
- Vorschau (PDF, nicht gespeichert) → „Als Entwurf speichern“ oder „Senden“ (mit Rückfrage).
2. Auftragsbestätigung (AB)
Nummer und Status
- Nummer
AB-JJJJ-NNNN, fortlaufend je Kalenderjahr (Berliner Datum des Sendens), vergeben erst beim Senden unter einer Sperre im Portal-Server (eine Instanz). Entwürfe haben keine Nummer. Scheitert das Senden vor dem Speichern des PDFs, wird keine Nummer verbraucht. - Status:
entwurf→versendet→bestaetigt→abgerechnet(nach finalisierter Schlussrechnung); außerdemstorniert(von Hand, ohne Mail),ersetzt(durch eine neue Fassung) undwiderrufen(Privatperson). - Unveränderlich nach dem Senden. Änderung = „Neue Fassung“: Kopie als neuer Entwurf mit Vermerk
„Ersetzt AB-… vom …“; beim Senden der neuen AB wird die alte
ersetzt. Rechnungen der alten AB wandern intern mit (projektRechnungen.auftragIdauf die neue AB); Stripe-Metadaten und der auf finalisierten Rechnungen aufgedruckte Bezug bleiben unverändert.
Inhalt des PDFs (A4)
- Kopf: WEBklar-Logo, WEBklar GbR, Anschrift, Kontakt, Steuernummer (Einstellung
financeSettings.steuernummer). - Empfänger: Firma bzw. Name, Anschrift (Straße, PLZ, Ort Pflicht für das Senden – auch unter 250 €).
- Titel „Auftragsbestätigung“, Nummer, Datum, Projekt bzw. Titel, Kundennummer (falls vorhanden).
- Einleitung: „Vielen Dank für Ihren Auftrag vom TT.MM.JJJJ (telefonisch). Wir bestätigen ihn wie folgt:“
- Leistungsumfang: Positionen mit Menge, Einzelpreis, Summe und Gesamtpreis oder Aufwandsregel („100 € pro Stunde in Schritten von 15 Minuten; unterstützt eine weitere Person, berechnen wir für sie die Hälfte der Arbeitszeit (AGB Nr. 9). Geschätzter Umfang: etwa X Stunden (unverbindlich). Zeichnet sich eine deutliche Überschreitung ab, melden wir uns vorher.“); Hinweis „Gemäß § 19 UStG wird keine Umsatzsteuer berechnet.“
- Zahlungsplan mit Beträgen (z. B. „Anzahlung 50 % (400,00 €) nach Auftragsbestätigung, Rest (400,00 €) nach Abnahme; zahlbar jeweils innerhalb von 14 Tagen nach Rechnung“), Termine.
- Mitwirkung und Abnahme laut AGB Nr. 7 und 8; „Es gelten unsere Allgemeinen Geschäftsbedingungen in der Fassung vom …, die dieser Bestätigung beiliegen.“
- Privatperson: zusätzliche Seiten „Widerrufsbelehrung“ (Projektauftrag) und „Muster-Widerrufsformular“.
- Fuß: Bankverbindung (
financeSettings.bankDetailsText), Kontakt, Seitenzahl. - Texte und Fassung kommen aus einer Konstante im Server (
texteFassung, Muster wieconfig.termine), die AB merkt sich die Fassung.
Erzeugung und Ablage
- PDF mit pdfkit (reines JavaScript; kein Chrome zur Laufzeit wegen knappem Arbeitsspeicher), statische
Figtree-Schnitte (OFL) unter
server/assets/fonts/, Logopublic/webklar-logo.png. - Beim Senden einmal erzeugt und unter
upload-data/auftraege/<kundenId>/<abId>.pdfabgelegt, SHA-256 im Dokument; danach wird nur noch diese Datei ausgeliefert. Die Datei liegt in der Hetzner-Serversicherung; jede Mail geht zudem per BCC an das Team-Postfach. - Die AGB werden als versionierte PDF-Datei ins Portal gedruckt (
public/rechtliches/agb-<fassung>.pdfmit.sha256, überscripts/build-legal-pdfs.sh, Quelle: Website-AGB). Jede AB merkt sichagbFassung.
Versand
- Mail K31 „Auftragsbestätigung“ (Kunde, Design der Mailvorlagen, ohne BCC ans Team, weil sie den
Bestätigungslink trägt): kurzer Text, Anhänge AB-PDF und AGB-PDF, Knopf „Auftrag bestätigen“ →
https://project.webklar.com/auftrag.html#t=<token>(Fragment: landet nicht in Server-Protokollen); bei Privatpersonen Hinweis auf Widerrufsbelehrung und Frühbeginn. Das Team bekommt eine Kopie ohne Link. - Token: 32 Zufallsbytes (base64url), gespeichert nur als SHA-256, gültig 60 Tage ab dem letzten Versand. „Erinnerung senden“ (WOMS, von Hand) schickt K31 erneut mit Erinnerungs-Hinweis und neuem Token (der alte gilt nicht mehr).
- Mail-Status am AB (
mailStatus: gesendet / nicht zugestellt + Zeitpunkt); bei Fehler „Erneut senden“.
Bestätigung
- Öffentliche Seite
auftrag.html#t=…(ohne Anmeldung,noindex, Ratenbegrenzung je IP im Arbeitsspeicher wie bei der Widerrufsseite): Zusammenfassung (Nummer, Datum, Projekt, Positionen bzw. Aufwandsregel, Summe, Zahlungsplan, Termine), Links auf AB-PDF und AGB-PDF, Häkchen „Ich bestätige den Auftrag zu diesen Bedingungen.“, Knopf „Auftrag bestätigen“. Nach der Bestätigung zeigt die Seite „Bestätigt am …“. Ungültiger oder abgelaufener Link: Erklärung und Kontaktweg. - Privatperson: zweites, freiwilliges Häkchen mit der Frühbeginn-Erklärung (Wortlaut aus der Rechtsrunde, Muster
der Funktionen). Ohne Häkchen zeigt WOMS „Arbeitsbeginn frühestens am TT.MM.“ = Tag nach
withdrawalDeadline(gesendetAm). - Im Portal (angemeldet): Reiter Rechnungen → Abschnitt „Aufträge“ mit Status, PDF und demselben Bestätigen-Ablauf.
- Kundenansicht: Bestätigen ist gesperrt (Erklärung im Namen des Kunden; der Endpunkt steht nicht auf der Freigabeliste der Kundenansicht-Sperre).
- Protokoll am AB:
bestaetigtAm,bestaetigtUeber(link|portal),bestaetigtPdfSha256(musspdfSha256entsprechen),texteFassung,fruehbeginn(ja/nein) und dessen Textfassung. Keine IP-Adresse. Eine zweite Bestätigung ändert nichts (die erste zählt). - Danach: Mail K32 „Auftrag bestätigt“ an den Kunden (Eingangsbestätigung mit Datum, Uhrzeit, Frühbeginn ja/nein; eine Frühbeginn-Erklärung wird wörtlich wiedergegeben) und T22 „Auftrag bestätigt“ an das Team.
Widerruf (Privatperson)
widerrufen.htmlbekommt die Vertragsart „Projektauftrag (Auftragsbestätigung)“ mit Feld AB-Nummer (optional, „falls zur Hand“; der Widerruf ist formfrei). Die Erklärung läuft über den bestehenden Weg (Eingangsbestätigung an den Kunden, Team-Mail); passt die AB zu Nummer und E-Mail-Adresse, wird siewiderrufenund WOMS zeigt es. Erstattung und Wertersatz bleiben Handarbeit.
3. Rechnungen
Alle Projektrechnungen bleiben Stripe-Rechnungen (collection_method: send_invoice, Mail mit PDF und Zahlungsseite,
Karte/SEPA, Bankabgleich und Finanzen-Übersicht unverändert).
Arten
| Art | Voraussetzung | Positionen |
|---|---|---|
anzahlung |
AB Festpreis, Status versendet oder bestaetigt |
Eine Zeile „Anzahlung 50 % gemäß Auftragsbestätigung AB-2026-0002 vom 06.10.2026 (Projekt)“; Betrag aus dem Zahlungsplan, änderbar in % oder €, höchstens AB-Summe minus bereits Berechnetes. Bezeichnung änderbar (auch „Teilrechnung“). |
schluss |
AB Festpreis, Status versendet oder bestaetigt; kein offener Entwurf zur AB |
Alle AB-Positionen, zusätzliche Positionen (Nachträge) möglich, dann je früherer finalisierter, nicht stornierter Rechnung zur AB eine Minuszeile („abzüglich Anzahlung, Rechnung WEBKLAR-0007 vom 08.10.2026“, negativer amount). Summe muss > 0 sein, sonst „Nichts mehr offen“. Nach dem Finalisieren: AB abgerechnet (Storno setzt zurück). |
aufwand |
Projekt; Zeitquelle mit noch nicht abgerechneten Arbeitsblättern | Alle offenen Arbeitsblätter der Zeitquelle (ohne Abo-Zeit, ohne reine Kommentare, ohne 0 Minuten) sind vorausgewählt und abwählbar; eine Zeile je Tag: „06.10.2026: Startseite, Kontaktformular – 2,25 Std. à 100,00 €“ (Menge 1, Betrag = Stunden × Satz). Minuten je Arbeitsblatt wie worksheetMinutes (inkl. Unterstützung), je Eintrag auf 15 Minuten aufgerundet. Zeilentext = Kurzfassungen der Arbeitsblätter des Tages, gefiltert wie in der Kundenansicht (customerProjectView: ohne Git-Anhänge, SHAs, Kontonamen), auf 200 Zeichen gekürzt, im Dialog änderbar. Satz aus der jüngsten gültigen Aufwands-AB des Projekts, sonst 100 €. |
festbetrag |
Projekt | Freie Positionen wie heute (Frau Wolf: „Erstellung der Website anelia-wolf.com, Pauschalpreis laut Absprache“, 500 €). |
frei |
„Ohne Projekt“ gewählt | Freie Positionen wie bisher, ohne Zusatzfelder „Projekt“/„Auftrag“ (aber A4). |
Grenzen wie heute (1–20 Positionen inkl. Minuszeilen; Beschreibung ≤ 200 Zeichen); eine Schlussrechnung darf bis 40 Zeilen haben (AB-Positionen ≤ 20, Zusatzpositionen ≤ 10, Abzüge ≤ 10). Ergäbe eine Aufwandsrechnung mehr als 20 Zeilen (zusätzliche Positionen zählen mit), werden die ältesten Tage zu Kalenderwochen zusammengefasst („KW 41/2026: … – 6,5 Std. à 100,00 €“), bis höchstens 20 Zeilen bleiben.
Auf jeder Projektrechnung
- Zusatzfelder (
custom_fields): „Projekt“ (Name, auf 140 Zeichen gekürzt), „Auftrag“ („AB-2026-0002 vom 06.10.2026“, nur mit AB), „Leistungszeitraum“ (bei Aufwand erster bis letzter Tag, sonst optional; immer änderbar). - Metadaten:
webklarCustomerId,quelle,erstelltVon(wie heute) plusprojektId,projektName,auftragId,auftragNummer,art. rendering.pdf.page_size = 'a4'– auch im bisherigen Dialog.- Fuß unverändert (§ 19-Hinweis, Bankverbindung, Verwendungszweck).
Abgerechnete Arbeitsblätter, Storno
- Jede Projektrechnung bekommt ein Dokument in
projektRechnungen(Kennung = Stripe-Rechnungs-ID) mit Projekt, AB, Art, Betrag und den abgerechneten Arbeitsblatt-IDs. Beim Anlegen prüft der Server, dass keines der Blätter in einer aktiven Projektrechnung steckt (sonst 409 „Arbeitsblatt bereits abgerechnet“). - Entwurf löschen oder Rechnung stornieren setzt das Dokument auf
aktiv = false: die Blätter sind wieder frei, der Betrag zählt nicht mehr als berechnet; eine Schlussrechnung setzt die AB auf den vorigen Status zurück.
Steuernummer
- Sofort, unabhängig vom Bau (Nutzer): Steuernummer der GbR im Stripe-Dashboard (Einstellungen → Billing → Rechnungen → „Steuerinformationen für Rechnungen“) hinterlegen und als Standard setzen – dann steht sie auf allen Rechnungen, auch Abo-Rechnungen.
- Beim Livegang an einem Entwurfs-PDF prüfen, wie Stripe sie beschriftet. Ist die Beschriftung unpassend, kommt sie
stattdessen in den Rechnungsfuß (
invoiceFooter, und per Skript ininvoice_settings.footerbestehender Stripe-Kunden). - Für das AB-PDF: neues Einstellungsfeld
steuernummerin WOMS Finanzen → Einstellungen.
Kundenportal
- Die Rechnungsliste zeigt zusätzlich das Projekt (
metadata.projektName).
4. Projektkonto (Rechenregeln)
Je Projekt, berechnet im Portal-Server bei jeder Anfrage (Stripe-Daten aus dem bestehenden 60-Sekunden-Zwischenspeicher; fehlt eine Rechnung dort, wird sie einzeln gelesen):
| Feld | Regel |
|---|---|
| Vereinbart | Summe summeCents aller Festpreis-ABs des Projekts mit Status versendet, bestaetigt oder abgerechnet. Aufwands-ABs: Text „nach Aufwand, €/Std.“ (mit Schätzung). Ohne AB: „keine AB“. |
| Berechnet | Summe der Rechnungen aus aktiven projektRechnungen des Projekts, die finalisiert sind (offen, überfällig, bezahlt, uneinbringlich); Entwürfe und Stornos zählen nicht. |
| davon bezahlt | Summe amount_paid dieser Rechnungen. |
| Noch offen | Festpreis: Vereinbart − Berechnet (nie unter 0). Aufwand: Wert der noch nicht abgerechneten Zeit. Ohne AB: „–“. |
| Zeit erfasst | Minuten aller Arbeitsblätter der Zeitquelle ohne Abo-Zeit (Regeln wie Aufwand), darunter „Wert x €“ zum Satz der AB bzw. 100 €; Abo-Zeit getrennt als „über Abo: y Std.“. |
Zeitquelle eines Projekts: Vereinigung der Zeitquellen seiner ABs, sonst das Ticket des Projekts; im Rechnungsdialog
können weitere Tickets des Kunden dazugenommen werden. „Ohne Projekt“: Stripe-Rechnungen des Kunden ohne aktive
projektRechnungen.
5. Daten (Appwrite woms-database, nur Server-Schlüssel)
Neue Collections (Setup-Skript scripts/auftraege-setup.mjs, idempotent wie setup-finanzen.mjs):
auftraege:nummer,jahr,laufnummer,status,kundenId,kundeJson(Name, Firma, Anschrift, E-Mail, Kundenart zum Zeitpunkt des Sendens),projektId,titel,zeitquelleTicketIds(string[]),art(festpreis|aufwand),positionenJson,stundensatzCents,schaetzungMinuten,summeCents,zahlungsplanJson,zahlungszielTage,auftragVom,auftragWeg,startAm,fertigBis,texteFassung,agbFassung,pdfDatei,pdfSha256,gesendetAm,gesendetAn,mailStatus,mailFehler,tokenHash,tokenGueltigBis,bestaetigtAm,bestaetigtUeber,bestaetigtPdfSha256,fruehbeginn,fruehbeginnFassung,ersetztId,ersetztDurchId,storniertAm,widerrufenAm,erstelltVon,erstelltAm,geaendertAm. Indizes:kundenId,projektId,nummer(normaler Index: Entwürfe haben keine Nummer; eindeutig über die Sperre beim Senden),tokenHash.projektRechnungen: Dokument-ID = Stripe-Rechnungs-ID;kundenId,projektId,auftragId,art,betragCents,arbeitsblattIds(string[]),aktiv(bool),erstelltVon,erstelltAm. Indizes:kundenId,projektId,auftragId.
Neue Attribute: customers.kundenart ('' | unternehmen | privat), financeSettings.steuernummer.
Stripe-Rechnungen werden weiter nicht gespiegelt.
6. Schnittstellen (Portal-Server)
Admin (unter dem bestehenden Finanzen-Router, requireAppwriteStaff):
| Methode, Pfad | Zweck |
|---|---|
GET /api/admin/finanzen/projektkonten?kunde= |
Projektkonten des Kunden inkl. „Ohne Projekt“ |
GET /api/admin/finanzen/projektkonten/:projektId |
Ein Projektkonto mit ABs, Rechnungen, offenen Arbeitsblättern |
GET, POST /api/admin/finanzen/auftraege (?kunde=) |
ABs lesen, Entwurf anlegen |
GET, PATCH, DELETE /api/admin/finanzen/auftraege/:id |
Lesen; Entwurf ändern/löschen |
GET /api/admin/finanzen/auftraege/:id/pdf |
Gespeichertes PDF bzw. Vorschau eines Entwurfs |
POST /api/admin/finanzen/auftraege/:id/senden |
Nummer, PDF, Ablage, Mail |
POST /api/admin/finanzen/auftraege/:id/erinnern |
K31 erneut, neuer Token |
POST /api/admin/finanzen/auftraege/:id/neue-fassung |
Kopie als Entwurf |
POST /api/admin/finanzen/auftraege/:id/stornieren |
Status storniert |
POST /api/admin/finanzen/rechnungen |
erweitert: { customerId, projektId?, auftragId?, art, items, arbeitsblattIds?, leistungszeitraum?, daysUntilDue, memo, senden, idempotencyKey }; Positionen für anzahlung/schluss/aufwand baut der Server nach (Minuszeilen nur serverseitig) |
PATCH /api/admin/finanzen/einstellungen |
erweitert um steuernummer |
Alle Mitarbeiter (/api/team, requireStaffJwt): GET /api/team/arbeitsblaetter/abgerechnet?ticketId= →
{ worksheetId: rechnungsnummer } (ohne Beträge).
Kunden: GET /api/auftraege (eigene ABs), GET /api/auftraege/:id/pdf, POST /api/auftraege/:id/bestaetigen
(Portal-Sitzung; in der Kundenansicht gesperrt).
Öffentlich (Token): GET /api/auftrag/:token, GET /api/auftrag/:token/pdf, POST /api/auftrag/:token/bestaetigen
({ bestaetigt: true, fruehbeginn }).
Widerruf: /api/abo/public/withdraw akzeptiert order = projekt mit abNummer.
Kundenart: WOMS schreibt customers.kundenart direkt (wie die übrigen Kundenfelder).
7. Mails
Nächste freie Kennungen zum Zeitpunkt des Baus prüfen (derzeit K31, K32, T22):
- K31 Auftragsbestätigung (Kunde; Anhänge AB-PDF und AGB-PDF; Variante Erinnerung; Variante Privatperson).
- K32 Auftrag bestätigt (Kunde; Eingangsbestätigung, Frühbeginn ja/nein).
- T22 Auftrag bestätigt (Team).
- Widerruf eines Projektauftrags nutzt die bestehenden Widerrufs-Mails (K04/T09) mit der neuen Vertragsart.
8. Rechtsrunde (vor dem Livegang von Plan 2)
Der Nutzer gibt frei; danach lädt Claude die Fassungen in WOMS → Rechtliches hoch:
- Textbausteine der AB (Einleitung, Aufwandsregel, Zahlungsplan, Mitwirkung/Abnahme, AGB-Satz).
- Widerrufsbelehrung für Projektaufträge und Muster-Widerrufsformular (Bauart wie
widerrufsbelehrung-funktionen). - Frühbeginn-Erklärung (Wortlaut nach Muster der Funktionen, passende Norm prüfen).
- Datenschutzerklärung: neuer Abschnitt „Auftragsbestätigungen“ (verarbeitete Daten, Bestätigungslink, keine IP, Aufbewahrung 6 bzw. 8 Jahre) und Ergänzung des Widerrufs-Abschnitts.
- AGB als PDF (Fassung, aus der Website gedruckt).
9. Fehlerverhalten
| Fall | Verhalten |
|---|---|
| Stripe nicht erreichbar | Rechnung scheitert mit „Stripe ist gerade nicht erreichbar.“; ABs und Projektkonto (ohne Stripe-Teil, markiert) gehen weiter |
| PDF-Erzeugung scheitert | AB bleibt Entwurf, keine Nummer verbraucht, Meldung im Dialog |
| Mail scheitert | AB ist versendet, mailStatus „nicht zugestellt“, Knopf „Erneut senden“ |
| Link ungültig/abgelaufen | Seite erklärt es, nennt den Kontaktweg; WOMS kann per „Erinnerung senden“ einen neuen Link schicken |
| Doppelte Bestätigung | folgenlos, die erste zählt |
| Arbeitsblatt schon abgerechnet | 409 mit Rechnungsnummer |
| Schlussrechnung mit offenem Entwurf zur AB | 409 „Erst den Entwurf … senden oder löschen.“ |
| Fehlende Anschrift beim AB-Senden | 409 „Adresse des Kunden unvollständig“ |
| Kundenart leer beim AB-Senden | 400 (der Dialog fragt vorher) |
10. Tests
- Unit (
node --test): Projektkonto-Regeln; Positionsbau je Art (Minuszeilen, Tageszeilen, 15-Minuten-Rundung, Unterstützung, Wochen-Zusammenfassung über 20 Tage); AB-Nummern (Jahreswechsel, Sperre); Token (Hash, Ablauf, Erneuerung); Frühbeginn-Datum; PDF enthält Pflichtangaben (Text aus dem PDF gelesen) und bei Privatpersonen die Belehrung; Stripe-Parameter (custom_fields,page_size, Metadaten) gegen das Fake-Stripe. - Server-Ablauf mit Appwrite-Nachbau, Fake-Stripe und SMTP-Senke (Rezept
kundenportal-testing): AB anlegen → senden → bestätigen (Link und Portal) → Anzahlung → Schlussrechnung; Aufwand mit Arbeitsblättern; Storno gibt frei; Kundenansicht kann nicht bestätigen; Widerruf eines Projektauftrags. - WOMS: Lib-Tests der Ansichtslogik; Bildschirmfotos über das Prüfwerkzeug des Redesigns (Desktop und Handy).
- Kundenseiten: Playwright (Handy, Desktop) gegen Fixture-Server.
- Live: nur Entwürfe mit dem Testkunden des Nutzers; nichts an echte Kunden.
11. Pläne und Livegang
- Plan 1 – Rechnungen mit Projektkonto:
projektRechnungen, Projektkonto, Artenaufwand,festbetragundfrei, Zusatzfelder, Metadaten, A4, Abzeichen „abgerechnet“, Projekt in der Kunden-Rechnungsliste, WOMS-Oberfläche (Projektkonto, neuer Rechnungsdialog, Reiter umbenannt). In Plan 1 zeigt Vereinbart immer „keine AB“. Keine Rechtsrunde nötig. - Plan 2 – Auftragsbestätigung:
auftraege, Kundenart, Steuernummer-Einstellung, PDF, Mails, Bestätigungsseite und Portal-Abschnitt, Verbraucher-Variante, Widerruf, Artenanzahlungundschluss(mit Minuszeilen), WOMS-Dialog und -Liste, Rechtsrunde. - Parallel gebaut, gestaffelt live: Auf Wunsch des Nutzers (06.10.2026) werden beide Pläne gleichzeitig in
parallelen Strängen gebaut (Umsetzungsplan
2026-10-06-auftraege-00-uebersicht.md). Der AB-Teil (und die Artenanzahlung/schluss) hängt hinter dem SchalterAUFTRAEGE_ENABLED(off|pilot|on, Vorgabeoff), so geht der Rechnungsteil ohne Rechtsrunde live; der Datenschutz-Abschnitt kommt erst mit dem AB-Livegang. - Reihenfolge je Plan: Portal-Server und Kundenseiten zuerst; WOMS-Oberfläche im neuen Design auf Basis der
zusammengeführten Redesign-Stränge Kunden (P4) und Finanzen (P7). Sind die Stränge beim Start der WOMS-Aufgaben noch
nicht zusammengeführt, wird mit dem Nutzer entschieden (warten oder auf
testbauen und eine Mitnahme-Notiz für das Redesign hinterlegen). - Livegang: (0) Nutzer hinterlegt die Steuernummer in Stripe; (1) Setup-Skript; (2) Nutzer pusht Portal
main; (3) Nutzer pusht WOMStest; (4) Prüfung mit Testkunde (Entwürfe, PDF-Ansicht); bei Plan 2 vorher Rechtsrunde und Upload in Rechtliches.
Nicht im Umfang
Angebote vor dem Auftrag, Mahnwesen (Stripe-Erinnerungen wie heute), E-Rechnung, Abrechnung des Abo-Mehraufwands
(hourLedger), Nachlass-/Rabattzeilen, eigene Archivkopien der Stripe-PDFs, englische ABs, mehrere Währungen,
Projektmarge und Auswertungen, automatische Erinnerungen.
Quellen
- § 34a UStDV: https://lxgesetze.de/ustdv/34a
- § 14b UStG: https://lxgesetze.de/ustg/14b
- § 312f BGB: https://www.haufe.de/id/norm/buergerliches-gesetzbuch-312f-abschriften-und-bestaetigungen-HI1049155_p312f.html
- Auftragsbestätigung (Inhalt): https://www.lexware.de/wissen/faktura-warenwirtschaft/auftragsbestaetigung-bedeutung-und-inhalt/
- Stripe Rechnungen anpassen: https://docs.stripe.com/invoicing/customize
- Agentur-Abrechnung (Festpreis/Aufwand): https://everhour.com/de/invoices/rechnungssoftware-fuer-digitalagenturen
Nachträge aus der Planrunde (06.10.2026)
- Kundentexte: Mails, PDF und die öffentliche Bestätigungsseite in Sie-Form; der Abschnitt „Aufträge“ im angemeldeten Portal in Du-Form wie das übrige Portal.
- Steuernummer-Feld akzeptiert auch eine USt-IdNr. („DE…“).
- Frühbeginn-Erklärung stützt sich auf § 356 Abs. 5 Nr. 2 und § 357a Abs. 2 BGB (Wortlaut in der Rechtsrunde).
- Bei Weg „vor Ort“ und Kundenart Privatperson zeigt der AB-Dialog den Hinweis „zusätzlich ausdrucken und übergeben“ (§ 312f Abs. 1 BGB), bis die Kanzlei-Frage beantwortet ist.
- Team-Mail T22 trägt im Betreff das Präfix „[Aufträge]“ wie die übrigen Team-Mails.