Rechtstexte und B2C-Vertragsabläufe absichern
This commit is contained in:
+58
-10
@@ -2,6 +2,8 @@
|
||||
|
||||
require_once __DIR__ . '/functions.php';
|
||||
require_once __DIR__ . '/app/ledger.php';
|
||||
require_once __DIR__ . '/app/billing.php';
|
||||
require_once __DIR__ . '/app/tenant-logo.php';
|
||||
|
||||
$pdo = app_db_pdo();
|
||||
$user = saas_require_login();
|
||||
@@ -13,25 +15,63 @@ if (!saas_user_has_role('owner', $user)) {
|
||||
|
||||
$tenantId = (int)$user['tenant_id'];
|
||||
$isDefaultTenant = ledger_is_default_tenant($pdo, $tenantId);
|
||||
$billing = billing_fetch_or_init($pdo, $tenantId);
|
||||
$hasRunningPaidSubscription = (string)$billing['plan_code'] !== 'free'
|
||||
&& (string)$billing['subscription_status'] !== 'canceled';
|
||||
$errors = [];
|
||||
$confirmInput = '';
|
||||
|
||||
if (!$isDefaultTenant && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
if (!$isDefaultTenant && !$hasRunningPaidSubscription && $_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
app_require_csrf();
|
||||
$confirmInput = trim((string)($_POST['confirm_slug'] ?? ''));
|
||||
|
||||
if ($confirmInput !== $user['tenant_slug']) {
|
||||
$errors[] = 'Bitte das Kundenkürzel exakt eingeben, um die Löschung zu bestätigen.';
|
||||
} else {
|
||||
// Loeschen der tenants-Zeile kaskadiert per FK auf alles
|
||||
// tenant-scoped (participants, ledger_entries, notices,
|
||||
// tenant_memberships, audit_log, outbound_emails,
|
||||
// payment_import_batches/rows, tenant_settings). users bleiben
|
||||
// erhalten, da ein Login-Konto zu mehreren Mandanten gehoeren kann.
|
||||
$pdo->prepare('DELETE FROM tenants WHERE id = ?')->execute([$tenantId]);
|
||||
saas_logout();
|
||||
header('Location: landing.php?tenant_deleted=1');
|
||||
exit;
|
||||
$settings = saas_fetch_tenant_settings($pdo, $tenantId) ?? [];
|
||||
$logoFiles = [
|
||||
(string)($settings['brand_logo'] ?? ''),
|
||||
(string)($settings['pdf_watermark_logo'] ?? ''),
|
||||
];
|
||||
$memberStmt = $pdo->prepare('SELECT user_id FROM tenant_memberships WHERE tenant_id = ?');
|
||||
$memberStmt->execute([$tenantId]);
|
||||
$userIds = array_map('intval', $memberStmt->fetchAll(PDO::FETCH_COLUMN));
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
// Tenant-bezogene Tabellen werden über ihre Fremdschlüssel
|
||||
// kaskadierend gelöscht. Rechtserklärungen bleiben entkoppelt als
|
||||
// notwendiger Vertragsnachweis erhalten.
|
||||
$pdo->prepare('DELETE FROM tenants WHERE id = ?')->execute([$tenantId]);
|
||||
|
||||
foreach ($userIds as $userId) {
|
||||
$stmt = $pdo->prepare('SELECT COUNT(*) FROM tenant_memberships WHERE user_id = ?');
|
||||
$stmt->execute([$userId]);
|
||||
$membershipCount = (int)$stmt->fetchColumn();
|
||||
$stmt = $pdo->prepare('SELECT COUNT(*) FROM platform_admins WHERE user_id = ?');
|
||||
$stmt->execute([$userId]);
|
||||
$isPlatformAdmin = (int)$stmt->fetchColumn() > 0;
|
||||
if ($membershipCount === 0 && !$isPlatformAdmin) {
|
||||
$pdo->prepare('DELETE FROM users WHERE id = ?')->execute([$userId]);
|
||||
}
|
||||
}
|
||||
$pdo->commit();
|
||||
} catch (Throwable $e) {
|
||||
if ($pdo->inTransaction()) {
|
||||
$pdo->rollBack();
|
||||
}
|
||||
$errors[] = 'Die Löschung konnte nicht vollständig ausgeführt werden. Bitte versuche es erneut oder nutze das Ticketsystem.';
|
||||
}
|
||||
|
||||
if ($errors !== []) {
|
||||
// Das Formular mit Fehlermeldung erneut anzeigen.
|
||||
} else {
|
||||
foreach ($logoFiles as $logoFile) {
|
||||
tenant_logo_delete($logoFile);
|
||||
}
|
||||
saas_logout();
|
||||
header('Location: landing.php?tenant_deleted=1');
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +90,14 @@ include 'nav.php';
|
||||
selbstständig gelöscht werden. Bitte wende dich für diesen Fall an den
|
||||
Betreiber.</p>
|
||||
</div>
|
||||
<?php elseif ($hasRunningPaidSubscription): ?>
|
||||
<div class="hint-box error">
|
||||
<p>Der Mandant hat noch einen laufenden kostenpflichtigen Tarif. Kündige
|
||||
ihn zuerst unter <a href="mandant-einstellungen.php">Mandant-Einstellungen</a>.
|
||||
Der Tarif bleibt bis zum Ende der bereits bezahlten Periode nutzbar;
|
||||
anschließend kannst du den Mandanten und seine operativen Daten hier
|
||||
endgültig löschen.</p>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="hint-box error">
|
||||
<p><b>Diese Aktion kann nicht rückgängig gemacht werden.</b> Alle Daten von
|
||||
|
||||
Reference in New Issue
Block a user