query( "SELECT t.id, t.slug, ts.brand_logo, ts.pdf_watermark_logo, tb.plan_code, tb.subscription_status FROM tenants t LEFT JOIN tenant_settings ts ON ts.tenant_id = t.id LEFT JOIN tenant_billing tb ON tb.tenant_id = t.id WHERE t.contract_ends_at IS NOT NULL AND t.contract_ends_at < DATE_SUB(NOW(), INTERVAL 30 DAY) AND t.slug <> 'default' ORDER BY t.id" ); $tenants = $stmt->fetchAll(); $deleted = 0; $skipped = 0; foreach ($tenants as $tenant) { if ((string)($tenant['plan_code'] ?? 'free') !== 'free' && (string)($tenant['subscription_status'] ?? '') !== 'canceled' ) { $skipped++; echo "SKIP {$tenant['slug']}: kostenpflichtiges Abo ist noch nicht beendet.\n"; continue; } if ($dryRun) { echo "WOULD_DELETE {$tenant['slug']}\n"; continue; } $memberStmt = $pdo->prepare('SELECT user_id FROM tenant_memberships WHERE tenant_id = ?'); $memberStmt->execute([(int)$tenant['id']]); $userIds = array_map('intval', $memberStmt->fetchAll(PDO::FETCH_COLUMN)); try { $pdo->beginTransaction(); $pdo->prepare('DELETE FROM tenants WHERE id = ?')->execute([(int)$tenant['id']]); foreach ($userIds as $userId) { $membershipStmt = $pdo->prepare('SELECT COUNT(*) FROM tenant_memberships WHERE user_id = ?'); $membershipStmt->execute([$userId]); $adminStmt = $pdo->prepare('SELECT COUNT(*) FROM platform_admins WHERE user_id = ?'); $adminStmt->execute([$userId]); if ((int)$membershipStmt->fetchColumn() === 0 && (int)$adminStmt->fetchColumn() === 0) { $pdo->prepare('DELETE FROM users WHERE id = ?')->execute([$userId]); } } $pdo->commit(); } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } $skipped++; echo "ERROR {$tenant['slug']}: {$e->getMessage()}\n"; continue; } tenant_logo_delete((string)($tenant['brand_logo'] ?? '')); tenant_logo_delete((string)($tenant['pdf_watermark_logo'] ?? '')); $deleted++; echo "DELETED {$tenant['slug']}\n"; } echo "Fertig: {$deleted} gelöscht, {$skipped} übersprungen.\n"; exit($skipped > 0 ? 1 : 0);