Selbstbedienungs-Tarifverwaltung: Admin kann Abo im Backend waehlen und bestellen
- mandant-einstellungen.php: vollstaendige Tarif-Vergleichstabelle statt nur erzwungenem Upgrade-Hinweis. Jeder Tarif zeigt Limit, Preis und einen Aktions-Button (Buchen/Kuendigen/Anfragen); aktueller Tarif markiert, zu kleine Tarife fuer die aktuelle Teilnehmerzahl deaktiviert. - abo-upgrade.php: unterscheidet jetzt Upgrade, Downgrade zwischen bezahlten Stufen (Preis wird in-place gewechselt statt neuer Checkout-Session, Stripe prorated automatisch) und Wechsel auf 'free' (echte Kuendigung der bestehenden Subscription), statt nur eine Checkout-Session zu erzeugen. - app/stripe.php: neue Helper stripe_get_subscription(), stripe_update_subscription_price(), stripe_cancel_subscription(). - app/billing.php: billing_plan_selectable_for() prueft serverseitig, ob ein Zieltarif die aktuelle Teilnehmerzahl noch abdeckt (Downgrade-Schutz). - docs/billing.md: Phase 4 dokumentiert. Getestet: php -l fuer alle geaenderten Dateien und das gesamte Repo (keine Syntaxfehler), reine Funktionslogik-Tests ohne DB (billing_plans(), billing_required_plan_code(), stripe_flatten_params()) gruen. Kein Live-Test gegen echte Stripe-Testobjekte moeglich (keine PHP/DB-Laufzeitumgebung verfuegbar) - vor Go-Live im Stripe-Testmodus nachholen.
This commit is contained in:
@@ -221,3 +221,25 @@ function billing_check_tenant(PDO $pdo, int $tenantId): array
|
||||
'needs_upgrade' => $requiredRank !== false && $currentRank !== false && $requiredRank > $currentRank,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a tenant could self-service switch to $planCode given its current
|
||||
* active participant count - i.e. the plan's limit (if any) still covers
|
||||
* them. Used to grey out/reject plan selections that would immediately put
|
||||
* the tenant over their own member count (a downgrade or lateral move that
|
||||
* doesn't fit). Unknown plan codes are treated as not selectable.
|
||||
*/
|
||||
function billing_plan_selectable_for(PDO $pdo, int $tenantId, string $planCode): bool
|
||||
{
|
||||
$plans = billing_plans();
|
||||
if (!isset($plans[$planCode])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$max = $plans[$planCode]['max_participants'];
|
||||
if ($max === null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return billing_count_active_participants($pdo, $tenantId) <= $max;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user