Offene PayPal-Zahlungen bleiben nach dem Abschalten erreichbar

Wird PayPal in den Mandant-Einstellungen abgeschaltet, waehrend noch
Zahlungen unzugeordnet in der Warteschlange liegen, kaeme ohne diese
Ausnahme niemand mehr an sie heran - weder ueber das Menue noch ueber die
URL.

paypal_inbox_accessible() haelt Menuepunkt und Seite deshalb offen, solange
paypal_count_unmatched() etwas findet; die Seite weist per Hinweis darauf
hin, dass sie nach dem Abarbeiten verschwindet. Eine Sperre durch den
Betreiber sticht die Ausnahme.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-20 23:42:52 +02:00
co-authored by Claude Opus 5
parent 3f6866e075
commit 6cd7fcc079
4 changed files with 85 additions and 4 deletions
+51
View File
@@ -328,3 +328,54 @@ function paypal_ignore_payment(PDO $pdo, int $tenantId, int $paymentId, ?int $ac
return ['ok' => false, 'error' => 'Diese Zahlung ist nicht (mehr) offen.'];
}
/**
* Anzahl der offenen Zahlungen in der Warteschlange. Bewusst als eigene
* Zaehl-Abfrage neben paypal_fetch_unmatched(): die Navigation braucht nur
* die Information "gibt es noch etwas zu tun", nicht die Datensaetze.
*/
function paypal_count_unmatched(PDO $pdo, int $tenantId): int
{
static $cache = [];
if (array_key_exists($tenantId, $cache)) {
return $cache[$tenantId];
}
try {
$stmt = $pdo->prepare(
"SELECT COUNT(*) FROM paypal_payments WHERE tenant_id = ? AND status = 'unmatched'"
);
$stmt->execute([$tenantId]);
$cache[$tenantId] = (int)$stmt->fetchColumn();
} catch (Throwable $e) {
// Fehlt die Tabelle, gibt es auch keine Warteschlange - die
// Navigation darf daran nicht scheitern.
$cache[$tenantId] = 0;
}
return $cache[$tenantId];
}
/**
* Darf die Zuordnungsseite geoeffnet werden? Die Funktion kennt drei Faelle:
* der Betreiber hat gesperrt (nein), der Mandant bietet PayPal an (ja) - und
* dazwischen der Fall, dass der Mandant PayPal gerade abgeschaltet hat,
* aber noch Zahlungen unzugeordnet in der Warteschlange liegen. Die waeren
* sonst weder ueber das Menue noch ueber die URL erreichbar; die Seite bleibt
* deshalb offen, bis die Warteschlange leer ist.
*/
function paypal_inbox_accessible(PDO $pdo, int $tenantId): bool
{
require_once __DIR__ . '/features.php';
if (!app_feature_enabled($pdo, $tenantId, 'paypal_inbox')) {
return false;
}
if (app_feature_available($pdo, $tenantId, 'paypal_inbox')) {
return true;
}
return paypal_count_unmatched($pdo, $tenantId) > 0;
}