From b244451c42558a6c7dc129850e3d235516c784fc Mon Sep 17 00:00:00 2001 From: Clemens Creutzburg Date: Fri, 21 Aug 2026 00:27:44 +0200 Subject: [PATCH] Schalter fuer den Hinweis auf die Kaffeeliste Der Hinweis unten rechts laesst sich ab einem bezahlten Tarif in den Mandant-Einstellungen abschalten (neue Spalte tenant_settings. watermark_enabled, Standard an). Im kostenlosen Tarif bleibt er fest eingeschaltet: das Kaestchen ist angehakt und disabled, daneben steht der Grund. Zusaetzlich erzwingt saas_update_tenant_settings() den Wert dort noch einmal, damit ein nachgebauter POST ihn nicht abschalten kann. Der Titel des Wasserzeichens spricht nicht mehr vom kostenlosen Tarif - zahlende Mandanten koennen es jetzt freiwillig zeigen. Der Smoke-Test prueft die Einstellungsseite jetzt auch angemeldet. Sein Muster fuer PHP-Meldungen verlangt dafuer einen Doppelpunkt, sonst haette das Feld "negative_warning" als Warnung gezaehlt. Co-Authored-By: Claude Opus 5 --- app/plan-watermark.php | 22 +++++++++--- app/saas-auth.php | 22 +++++++++--- assets/css/app.css | 14 ++++++++ .../migrations/0027_watermark_setting.sql | 9 +++++ docs/billing.md | 25 ++++++++++---- mandant-einstellungen.php | 24 +++++++++++++ scripts/check-m3-settings-flow.php | 34 +++++++++++++++++++ scripts/http-smoke.php | 19 ++++++++++- 8 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 database/migrations/0027_watermark_setting.sql diff --git a/app/plan-watermark.php b/app/plan-watermark.php index f710ef6..ae1119e 100644 --- a/app/plan-watermark.php +++ b/app/plan-watermark.php @@ -44,7 +44,10 @@ function plan_watermark_plan_code(PDO $pdo, int $tenantId): string } /** - * Zeigt dieser Mandant das Wasserzeichen? Nur der kostenlose Tarif tut das. + * Zeigt dieser Mandant das Wasserzeichen? Im kostenlosen Tarif immer - es ist + * der Gegenwert fuer die kostenlose Nutzung und deshalb nicht abschaltbar. + * Alle anderen entscheiden ueber die Mandant-Einstellung + * `watermark_enabled` (Standard: an). */ function plan_watermark_visible(PDO $pdo, int $tenantId): bool { @@ -52,7 +55,18 @@ function plan_watermark_visible(PDO $pdo, int $tenantId): bool return false; } - return plan_watermark_plan_code($pdo, $tenantId) === 'free'; + $planCode = plan_watermark_plan_code($pdo, $tenantId); + if ($planCode === 'free') { + return true; + } + + if ($planCode === 'unknown') { + return false; + } + + require_once __DIR__ . '/features.php'; + + return app_tenant_switch_enabled($pdo, $tenantId, 'watermark_enabled'); } /** @@ -84,10 +98,10 @@ function plan_watermark_html(): string . '' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . ''; if ($url === '') { - return '
' . $inner . '
'; + return '
' . $inner . '
'; } return '' . $inner . ''; + . ' title="Kaffeeliste – die digitale Kaffeekasse">' . $inner . ''; } diff --git a/app/saas-auth.php b/app/saas-auth.php index f6fc952..bab5934 100644 --- a/app/saas-auth.php +++ b/app/saas-auth.php @@ -288,7 +288,8 @@ function saas_fetch_tenant_settings(PDO $pdo, int $tenantId): ?array ts.bank_account_holder, ts.bank_iban, ts.brand_logo, - ts.brand_color + ts.brand_color, + ts.watermark_enabled FROM tenants t LEFT JOIN tenant_settings ts ON ts.tenant_id = t.id WHERE t.id = ? @@ -336,6 +337,7 @@ function saas_fetch_tenant_settings(PDO $pdo, int $tenantId): ?array 'bank_iban' => (string)$settings['bank_iban'], 'brand_logo' => (string)$settings['brand_logo'], 'brand_color' => (string)$settings['brand_color'], + 'watermark_enabled' => (int)$settings['watermark_enabled'], ]; } @@ -425,6 +427,16 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr $pdfShowEmptyRows = !empty($input['pdf_show_empty_rows']) ? 1 : 0; $paymentReminderEnabled = !empty($input['payment_reminder_enabled']) ? 1 : 0; + // Der Hinweis auf die Kaffeeliste laesst sich abschalten - ausser im + // kostenlosen Tarif. Die Pruefung steht hier und nicht nur im Formular, + // damit auch ein nachgebauter POST das Kaestchen nicht leeren kann. Vor + // der Transaktion, weil billing_fetch_or_init() eine fehlende Zeile + // anlegt. + $watermarkEnabled = !empty($input['watermark_enabled']) ? 1 : 0; + if (billing_fetch_or_init($pdo, $tenantId)['plan_code'] === 'free') { + $watermarkEnabled = 1; + } + try { $pdo->beginTransaction(); @@ -443,8 +455,8 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr pdf_watermark_text, pdf_footer_text, payment_reminder_enabled, payment_reminder_interval_days, cash_enabled, cash_contact, bank_transfer_enabled, - bank_account_holder, bank_iban, brand_color) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + bank_account_holder, bank_iban, brand_color, watermark_enabled) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE mark_price_cents = VALUES(mark_price_cents), self_entry_enabled = VALUES(self_entry_enabled), @@ -464,7 +476,8 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr bank_transfer_enabled = VALUES(bank_transfer_enabled), bank_account_holder = VALUES(bank_account_holder), bank_iban = VALUES(bank_iban), - brand_color = VALUES(brand_color)' + brand_color = VALUES(brand_color), + watermark_enabled = VALUES(watermark_enabled)' ); $stmt->execute([ $tenantId, @@ -487,6 +500,7 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr $bankAccountHolder, $bankIban, $brandColor, + $watermarkEnabled, ]); $pdo->commit(); diff --git a/assets/css/app.css b/assets/css/app.css index a4daac3..eff5dd7 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -215,3 +215,17 @@ a.plan-watermark { display: none; } } + +/* --------------------------------------------------------------------------- + * Festgestellte Kaestchen (z. B. der Hinweis auf die Kaffeeliste im + * kostenlosen Tarif) + * + * Das Theme zeichnet das Kaestchen ueber das folgende