Downgrade-Vorkehrungen: Kontingent-Sperre beim Tarifwechsel, Gutschriften nicht spiegeln

QA-Befund 07.07.: Der Wechsel zurück in einen kleineren Tarif erzeugte
eine Proration-Gutschrift (negative Stripe-Rechnung) — die STR-Spiegelung
crashte an den unsigned-Spalten (Webhook-500), und der Wechsel war trotz
verbrauchtem Monatskontingent möglich.

- ProcessStripeWebhook: Belege ohne positiven Rechnungsbetrag
  (Gutschrift/Null-Rechnung) werden geloggt übersprungen statt gespiegelt
- CheckoutController::swap: Wechsel gesperrt, wenn der Monatsverbrauch
  das Kontingent des Ziel-Tarifs übersteigt (möglich ab Monatserstem)
- Buchungs-Modal: erklärt die Sperre inkl. Datum statt Bestätigungs-
  Button; Proration-Hinweis deckt jetzt auch die Guthaben-Richtung ab

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-07-07 13:22:30 +00:00
parent 14994e4748
commit 388ca0e620
6 changed files with 165 additions and 3 deletions

View file

@ -94,6 +94,22 @@ class CheckoutController extends Controller
return $this->backToBookings(__('Dieser Tarif ist bereits Ihr aktueller Tarif.'));
}
// Downgrade-Vorkehrung (QA-Befund 07.07.): Der Kontingent-Zähler
// läuft pro Kalendermonat — wer mehr PMs genutzt hat, als der
// Ziel-Tarif monatlich enthält, bekäme beim sofortigen Wechsel die
// anteilige Gutschrift für einen bereits konsumierten Monat. Solche
// Wechsel sind erst ab dem nächsten Monatsersten möglich.
$quotaUsed = (int) $user->press_release_quota_used_this_month;
if ($quotaUsed > (int) $plan->press_release_quota) {
return $this->backToBookings(__('Ein Wechsel zu :plan ist erst ab dem :date möglich: Sie haben in diesem Monat bereits :used Pressemitteilungen genutzt — dieser Tarif enthält :quota pro Monat.', [
'plan' => $plan->name,
'date' => now()->addMonth()->startOfMonth()->format('d.m.Y'),
'used' => $quotaUsed,
'quota' => (int) $plan->press_release_quota,
]));
}
try {
$this->checkout->swapSubscription($user, $plan, $interval);
} catch (IncompletePayment $exception) {