From 62e6b7e70ffa6bf69c9637d2125214aa94b5c670 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Fri, 12 Jun 2026 11:02:45 +0000 Subject: [PATCH] Doku: zentrale Billing-Referenz und Status-Sync Phase 9D - Neues Dokument docs/user-admin/Billing-und-Rechnungskreise.md: hybride Rechnungskreise (STR-/MAN-/Archiv), Tarif-Datenmodell, MAN-Faelligkeitslauf, USt-Regeln, Befehle/Scheduler, Konfiguration (billing.php + Cashier-ENV) und offene Punkte - README-Index + STATUS-ABGLEICH (Finanzen-Sektion) aktualisiert - PROGRESS-Eintrag Phase 9D (Datenmodell, Rechnungskreise, Grandfather-Migration, USt) Co-Authored-By: Claude Fable 5 --- dev/frontend/hub-flux/PROGRESS.md | 38 +++++ docs/README.md | 1 + docs/STATUS-ABGLEICH-USER-PANEL.md | 8 +- .../user-admin/Billing-und-Rechnungskreise.md | 144 ++++++++++++++++++ 4 files changed, 189 insertions(+), 2 deletions(-) create mode 100644 docs/user-admin/Billing-und-Rechnungskreise.md diff --git a/dev/frontend/hub-flux/PROGRESS.md b/dev/frontend/hub-flux/PROGRESS.md index 7966ad0..4a389a1 100644 --- a/dev/frontend/hub-flux/PROGRESS.md +++ b/dev/frontend/hub-flux/PROGRESS.md @@ -5,6 +5,44 @@ --- +## 2026-06-12 · Phase 9D · Tarif-Datenmodell, Rechnungskreise & USt ✅ + +Zentrale Doku: `docs/user-admin/Billing-und-Rechnungskreise.md`. +Plan: `docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md` (9D ✅, 9E in Arbeit). + +**Tarif-Datenmodell** +- Laravel Cashier ^16.5 (freigegeben), `User` ist Billable, + Cashier-Migrationen published + ausgeführt. +- `plans` (4 Tiers, Netto-Preise, Kontingente, Tageslimits, Seeder), + `single_purchases` (Einzel-PM, Extra-PM, Boost, PDF-Nachweis). +- `hasActiveBooking()` prüft hybrid: Cashier-Abo ∨ bezahlter + Einmalkauf ∨ aktive Legacy-Vereinbarung. + +**Hybride Rechnungskreise (Entscheidung 12.06.)** +- `InvoiceNumberGenerator`: atomare fortlaufende Nummern, STR- (Stripe) + / MAN- (manuell); Alt-Archiv `legacy_invoices` bleibt unverändert. +- MAN-Fälligkeitslauf `billing:generate-manual-invoices` (täglich + 04:30): Periodenende → Rechnung mit Adress-Snapshot → Periode weiter. + +**Legacy-Migration (P6.6, Runbook entsperrt)** +- `legacy:grandfather-subscriptions`: aktive jährliche Vereinbarungen + aus dem Rechnungsarchiv (22 im Test-Snapshot, 4 sofort fällig) als + `grandfathered` nach `user_payment_options` — Replay-fähig für den + Lauf kurz vor Relaunch. + +**USt (Einwand 12.06.: alle neuen Preise netto; Legacy war brutto)** +- `VatResolver`: DE immer Steuer, EU nur mit USt-ID befreit (Reverse + Charge + Pflichthinweis `invoices.tax_note`), Drittland befreit. +- `vat_id` an Rechnungsadresse + Rechnungs-Snapshot; Netto-Ableitung + der Legacy-Beträge (199 € brutto → 167,23 € netto + 31,77 € USt — + Brutto bleibt für DE-Bestandskunden identisch). +- Offen: VIES-Validierung, PDF-Layout, Steuerberater-Abnahme. + +**Verifikation**: Suite 490 passed / 4 skipped (39 neue Billing-Tests +über 4 Commits). Pint clean. Dry-Runs gegen Echtdaten validiert. + +--- + ## 2026-06-12 · Phase 9 · Veröffentlichungs-Flow Block 1 (9A–9C) ✅ Plan-Doc: `docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md`. Grundlage: diff --git a/docs/README.md b/docs/README.md index 75f55bf..de3add7 100644 --- a/docs/README.md +++ b/docs/README.md @@ -34,6 +34,7 @@ Sie verlinkt die zentralen Dokumente und sortiert sie nach „Was ist der aktuel Konzept und Status-Dokumentation für das User- und Admin-Backend. - [`Admin-User.md`](./user-admin/Admin-User.md) — Hauptdokument zum User-/Admin-Backend (Navigation, Firmen-Detail, Rollen). +- [`Billing-und-Rechnungskreise.md`](./user-admin/Billing-und-Rechnungskreise.md) — **Zentrale Billing-Referenz**: hybride Rechnungskreise (STR-/MAN-/Archiv), Tarif-Datenmodell, USt-Regeln, Befehle, Konfiguration. - [`checkliste-user-backend.md`](./user-admin/checkliste-user-backend.md) — Erledigt/Offen-Liste pro Phase (1, 7, 8, KI-Pipeline). - [`Entwicklungsplan KI-Pruefung und Veroeffentlichung.md`](./user-admin/Entwicklungsplan%20KI-Pruefung%20und%20Veroeffentlichung.md) — KI-Klassifikation (Rot/Gelb/Grün), Content-Score, Audit-Log; Phasen 0–5 umgesetzt (11.06.2026). - [`Umsetzung Pressemitteilung Bearbeitung Titelbild Veroeffentlichung.md`](./user-admin/Umsetzung%20Pressemitteilung%20Bearbeitung%20Titelbild%20Veroeffentlichung.md) — Umsetzungs-Notiz (11.06.2026): Titelbild/Cover, Lizenzformular, Zeitzonen-Handling, vereinfachte Veröffentlichungs-Box. diff --git a/docs/STATUS-ABGLEICH-USER-PANEL.md b/docs/STATUS-ABGLEICH-USER-PANEL.md index 2966a8f..661fd26 100644 --- a/docs/STATUS-ABGLEICH-USER-PANEL.md +++ b/docs/STATUS-ABGLEICH-USER-PANEL.md @@ -121,11 +121,15 @@ eingearbeitet. Preise & Veröffentlichungs-Flow: siehe ### Finanzen +Zentrale Billing-Referenz: [`user-admin/Billing-und-Rechnungskreise.md`](./user-admin/Billing-und-Rechnungskreise.md). + | Konzept-Aussage | IST | Status | |---|---|---| | Rechnungen mit Legacy-Archiv | umgesetzt | ✅ | -| Buchungen & Add-ons | nur Stub | 📝 (Phase 2) | -| Credits & Tarif | nur „bald"-Eintrag in Sidebar | 📝 (Phase 2) | +| Hybride Rechnungskreise STR-/MAN- (Decision 12.06.) | umgesetzt (Phase 9D) — Nummern-Generator, MAN-Fälligkeitslauf, Grandfather-Migration, USt-Logik (`VatResolver`) | ✅ | +| Tarif-Datenmodell + Cashier | umgesetzt (Phase 9D) — `plans`, `single_purchases`, `User` ist Billable | ✅ | +| Stripe-Checkout/Webhooks + STR-Spiegelung | **in Arbeit** (Phase 9E) | 📝 | +| Buchungen & Add-ons (UI) | nur Stub | 📝 (mit 9F Tarif-Seite) | | Zahlungsmethoden firmenscharf | **fehlt** | 📝 (Phase 2) | --- diff --git a/docs/user-admin/Billing-und-Rechnungskreise.md b/docs/user-admin/Billing-und-Rechnungskreise.md new file mode 100644 index 0000000..337f81a --- /dev/null +++ b/docs/user-admin/Billing-und-Rechnungskreise.md @@ -0,0 +1,144 @@ +# Billing & Rechnungskreise (hybrides Modell) + +Stand: 12.06.2026 — Datenmodell, MAN-Kreis und USt-Behandlung umgesetzt +(Phase 9D); Stripe-Checkout/Webhooks in Arbeit (Phase 9E). + +Dieses Dokument ist die zentrale Referenz für das Abrechnungssystem: +Rechnungskreise, Tarif-Datenmodell, Steuerlogik, Befehle und Konfiguration. + +Verwandte Dokumente: + +- [`docs/Decision-Update Preisstruktur & Veröffentlichungs-Flow.md`](../Decision-Update%20Preisstruktur%20&%20Ver%C3%B6ffentlichungs-Flow.md) — verbindliche Launch-Entscheidungen (Tarife, Kontingente, Flow, Netto-Preise). +- [`docs/PHASE-9-FLOW-UND-TARIFE-PLAN.md`](../PHASE-9-FLOW-UND-TARIFE-PLAN.md) — Umsetzungsplan mit Päckchen-Status. +- `dev/migration 2026/05-DATABASE-MERGE.md` §5.5/§5.6 — Rechnungsarchiv (D-12) und Grandfathering (D-13). + +--- + +## 1. Die drei Rechnungswelten + +| Welt | Präfix | Tabelle | Inhalt | +|---|---|---|---| +| **Stripe-Shop** | `STR-` | `invoices` | Alle **neuen** Abschlüsse (Abos, Einzel-PM, Credits). Abwicklung komplett über Stripe; Rechnungen werden per Webhook in `invoices` gespiegelt und erhalten eine fortlaufende STR-Nummer. *(Spiegelung: Phase 9E)* | +| **Manuell/Legacy** | `MAN-` | `invoices` | Laufende, noch aktive Alt-Zahlungsvereinbarungen ab Relaunch. Fälligkeit wird täglich geprüft, Rechnung wie im Altsystem ausgestellt. | +| **Alt-Archiv** | — | `legacy_invoices` | Read-only Archiv aller importierten Legacy-Rechnungen (D-12). Wird nie verändert; PDFs werden on-demand aus den Archivdaten erzeugt. | + +**Rechnungsnummern**: `InvoiceNumberGenerator` vergibt atomar (Row-Lock auf +`invoice_number_sequences`) fortlaufende, lückenlose Nummern pro Kreis: +`STR-00001`, `MAN-00001`, … (Padding: `billing.invoice_number_padding`). + +--- + +## 2. Tarif-Datenmodell + +| Tabelle | Zweck | +|---|---| +| `plans` | Tarif-Katalog (Starter/Business/Pro/Agency): Monats-/Jahrespreis **netto**, PM-Kontingent/Monat, Tageslimit, Stripe-Produkt-/Preis-IDs. Seeder: `PlanSeeder` (idempotent). | +| `subscriptions`, `subscription_items` | Laravel-Cashier-Tabellen — Zustand der Stripe-Abos. `User` ist `Billable`. | +| `single_purchases` | Einmalkäufe: Einzel-PM (19 €), Extra-PM, Boost, Veröffentlichungsnachweis-PDF. Status: pending → paid → consumed (oder refunded). | +| `payment_options` / `user_payment_options` | Legacy-Zahlungsvereinbarungen. Grandfathered-Einträge tragen die Netto-Vertragsbasis in `legacy_conditions`; versteckte Katalog-Platzhalter `LEGACY-{PE\|BP}-{Artikel}`. | +| `invoice_number_sequences` | Fortlaufende Nummern pro Rechnungskreis. | + +**Submit-Gate** (`User::hasActiveBooking()`, hinter `billing.enforce_booking`): +Eine aktive Buchung ist ein Cashier-Abo **oder** ein bezahlter, noch nicht +eingelöster Einzel-/Extra-PM-Kauf **oder** eine aktive/grandfathered +Legacy-Vereinbarung. Bestandskunden behalten damit nach Gate-Aktivierung +volle Einreichungsrechte. + +--- + +## 3. MAN-Kreis: Fälligkeitslauf für Legacy-Zahlungen + +Täglicher Scheduler-Lauf (04:30): `billing:generate-manual-invoices` + +1. Findet `user_payment_options` mit Status `active`/`grandfathered`, + **ohne** `stripe_subscription_id`, deren `current_period_end` erreicht ist. +2. Friert die Rechnungsadresse als Snapshot ein (`invoice_billing_addresses`, + inkl. `vat_id`). +3. Stellt die Rechnung aus: Netto-Basis × USt-Regel (Abschnitt 4), + MAN-Nummer, Zahlungsziel `billing.manual_due_days` (Default 14 Tage). +4. Schaltet die Periode weiter (`monthly`/`yearly` aus `legacy_conditions` + bzw. `payment_options.interval`). + +Nicht abrechenbare Fälle (fehlende Rechnungsadresse, kein Intervall) werden +geloggt, **die Periode bleibt stehen** — der nächste Lauf versucht es erneut. +Optionen: `--dry-run`, `--limit=50`. + +**Befüllung**: `legacy:grandfather-subscriptions` (Migrations-Runbook, nach +`legacy:archive-invoices`) leitet die aktiven jährlichen Vereinbarungen aus +dem Rechnungsarchiv ab — Replay-fähig für den Lauf kurz vor Relaunch. +Details: `dev/migration 2026/05-DATABASE-MERGE.md` §5.6. + +--- + +## 4. USt-Behandlung (Entscheidung 12.06.2026) + +**Alle neuen Preise sind Netto-Preise.** Die Steuer wird zur +Rechnungsstellung über `App\Services\Billing\VatResolver` aus der +Rechnungsadresse bestimmt: + +| Fall | Behandlung | Rechnung | +|---|---|---| +| Deutschland | immer mit Steuer (`billing.vat_rate`, Default 19 %) | Netto + USt ausgewiesen | +| EU mit gültiger USt-ID | befreit (Reverse Charge) | `is_netto`, Pflichthinweis in `tax_note` | +| EU ohne USt-ID | mit Steuer | Netto + USt ausgewiesen | +| Drittland | grundsätzlich befreit | `is_netto`, Hinweis „nicht im Inland steuerbar" | + +- Die USt-ID wird im Profil gepflegt (bestehendes Feld) und zusätzlich an + der Rechnungsadresse (`billing_addresses.vat_id`) gespeichert; jede + Rechnung friert sie im Adress-Snapshot ein. +- „Gültig" = vorhanden + formal plausibel (Länder-Präfix, EL für + Griechenland). **Offen: echte VIES-Validierung** — vor Aktivierung von + Gate/Checkout umsetzen. +- **Legacy-Umrechnung**: Das Altsystem fakturierte brutto (199 € inkl. + Steuer; Befreite mit Netto-Ausweis 167,23 €). Die Grandfather-Migration + leitet daraus die Netto-Basis ab (`legacy_conditions.net_cents`) — für + deutsche Bestandskunden bleibt der Bruttobetrag unverändert, die Steuer + wird künftig nur sauber ausgewiesen. + +--- + +## 5. Befehle & Scheduler + +| Befehl | Zweck | Scheduler | +|---|---|---| +| `billing:generate-manual-invoices` | MAN-Fälligkeitslauf (Abschnitt 3) | täglich 04:30 | +| `legacy:grandfather-subscriptions` | Aktive Legacy-Abos aus dem Archiv migrieren | manuell (Migrations-Runbook) | +| `press-releases:reset-monthly-quota` | Quota-Stub-Reset (entfällt mit Plan-Kontingent, 9E) | monatlich, 1. um 00:05 | + +--- + +## 6. Konfiguration + +`config/billing.php`: + +| Schlüssel | ENV | Default | Bedeutung | +|---|---|---|---| +| `enforce_booking` | `BILLING_ENFORCE_BOOKING` | `false` | Submit-Gate scharf schalten (Launch-Schalter) | +| `invoice_number_padding` | — | `5` | Stellen der laufenden Nummer | +| `manual_due_days` | `BILLING_MANUAL_DUE_DAYS` | `14` | Zahlungsziel MAN-Rechnungen | +| `vat_rate` | `BILLING_VAT_RATE` | `0.19` | USt-Satz für steuerpflichtige Fälle | +| `eu_country_codes` | — | EU-27 ohne DE | Basis der Drittland-/EU-Unterscheidung | + +Stripe/Cashier (`config/cashier.php`): + +| ENV | Bedeutung | +|---|---| +| `STRIPE_KEY` / `STRIPE_SECRET` | Publishable/Secret Key (Test-Keys gesetzt) | +| `STRIPE_WEBHOOK_SECRET` | Signatur-Prüfung des Webhook-Endpoints — wird beim Einrichten des Endpoints gesetzt (9E) | +| `CASHIER_CURRENCY` | Default `usd` → für uns `eur` setzen (9E) | + +--- + +## 7. Offene Punkte (Stand 12.06.2026) + +1. **Phase 9E**: Stripe-Produkte/Preise anlegen (netto) + IDs in `plans` + pflegen, Checkout (Abo + Einmalkauf), Webhooks inkl. Spiegelung der + Stripe-Rechnungen nach `invoices` mit STR-Nummer, Slot-Logik von + `users.press_release_quota`-Stub auf Plan-Kontingent umstellen. +2. **VIES-Validierung** der USt-ID (aktuell Formatprüfung). +3. **PDF-Erzeugung** für MAN-/STR-Rechnungen (Layout inkl. `tax_note`); + Archiv-PDFs existieren bereits on-demand. +4. **`ExpireGrandfatheredSubscriptions`**: Benachrichtigung zur Umstellung + auf neue Tarife am `grandfathered_until` (D-13-Rest). +5. **Steuerberater-Abnahme** der USt-Regeln und Rechnungstexte vor dem + ersten produktiven MAN-/STR-Lauf.