Haerte Verwaltungsflows und Zahlungsabgleich

This commit is contained in:
2026-08-07 12:02:41 +02:00
parent 39f662d541
commit 0f263c3a19
9 changed files with 461 additions and 101 deletions
+34 -10
View File
@@ -1,5 +1,7 @@
<?php
ob_start();
include "functions.php";
require_once __DIR__ . "/app/ledger.php";
app_require_csrf();
@@ -55,13 +57,23 @@ function einzahlung_fetch_participants(PDO $pdo, int $tenantId, string $action):
$eingetragen = 0;
$fehlgeschlagen = false;
$hatGespeichert = false;
$erfolgsmeldung = null;
$validierungsFehler = [];
$eingaben = [];
if (isset($_SESSION['flash_einzahlung']) && is_array($_SESSION['flash_einzahlung'])) {
$flash = $_SESSION['flash_einzahlung'];
unset($_SESSION['flash_einzahlung']);
if (($flash['type'] ?? '') === 'success') {
$erfolgsmeldung = sprintf('%d Einträge erfolgreich hinzugefügt.', (int)($flash['count'] ?? 0));
}
}
// Obergrenze je Einzahlungszeile. Faengt Groessenordnungs-Tippfehler ab
// (z. B. 500 statt 5,00); groessere Betraege lassen sich in mehreren
// Schritten eintragen.
const EINZAHLUNG_MAX_BETRAG = 1000.00;
const EINZAHLUNG_MAX_BETRAG_CENTS = 100000;
// Verarbeitung des Formulars, wenn es gesendet wurde
if ($_SERVER["REQUEST_METHOD"] == "POST" ) {
@@ -89,6 +101,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST" ) {
$rohBetrag = trim((string)$anzahlBetrag);
$bemerkung = trim((string)($_POST['bemerkung'][$participantId] ?? ''));
$eingaben[$participantId] = ['betrag' => $rohBetrag, 'bemerkung' => $bemerkung];
$name = $namen[$participantId] ?? ('Teilnehmer ' . $participantId);
if ($rohBetrag === '') {
// Leere Zeile: nur meckern, wenn trotzdem eine Bemerkung dransteht
@@ -102,16 +115,23 @@ if ($_SERVER["REQUEST_METHOD"] == "POST" ) {
continue;
}
$anzahlBetrag = floatval(str_replace(',', '.', $rohBetrag));
if ($anzahlBetrag == 0.0) {
$betragCents = saas_parse_money_cents($rohBetrag);
if ($betragCents === null) {
$validierungsFehler[] = sprintf(
'%s: Der Betrag "%s" ist kein gültiger Geldbetrag.',
$name,
$rohBetrag
);
continue;
}
$name = $namen[$participantId] ?? ('Teilnehmer ' . $participantId);
if ($betragCents === 0) {
continue;
}
// Abzuege muessen begruendet werden, sonst ist spaeter nicht mehr
// nachvollziehbar, warum jemandem Geld abgezogen wurde.
if ($anzahlBetrag < 0 && $bemerkung === '') {
if ($betragCents < 0 && $bemerkung === '') {
$validierungsFehler[] = sprintf(
'%s: Bei einem Abzug (negativer Betrag) ist eine Bemerkung Pflicht.',
$name
@@ -120,18 +140,18 @@ if ($_SERVER["REQUEST_METHOD"] == "POST" ) {
}
// Groessenordnungs-Tippfehler abfangen (500 statt 5,00).
if (abs($anzahlBetrag) > EINZAHLUNG_MAX_BETRAG) {
if (abs($betragCents) > EINZAHLUNG_MAX_BETRAG_CENTS) {
$validierungsFehler[] = sprintf(
'%s: %s € übersteigt die Plausibilitätsgrenze von %s €. Bitte prüfen oder in mehreren Schritten eintragen.',
$name,
number_format($anzahlBetrag, 2, ',', '.'),
saas_format_money_cents($betragCents),
number_format(EINZAHLUNG_MAX_BETRAG, 2, ',', '.')
);
continue;
}
$zuBuchen[$participantId] = [
'betrag' => $anzahlBetrag,
'betrag_cents' => $betragCents,
'bemerkung' => $bemerkung !== '' ? $bemerkung : null,
];
}
@@ -147,7 +167,7 @@ if ($_SERVER["REQUEST_METHOD"] == "POST" ) {
$pdo,
$tenantId,
$participantId,
(int)round($zeile['betrag'] * 100),
(int)$zeile['betrag_cents'],
'manual_bulk',
$saasUser['user_id'] ?? null,
$zeile['bemerkung']
@@ -157,6 +177,9 @@ if ($_SERVER["REQUEST_METHOD"] == "POST" ) {
$pdo->commit();
$eingaben = []; // Erfolgreich gebucht: Formular wieder leeren.
$_SESSION['flash_einzahlung'] = ['type' => 'success', 'count' => $eingetragen];
header('Location: einzahlung.php');
exit;
} catch (Throwable $e) {
if ($pdo->inTransaction()) {
$pdo->rollBack();
@@ -188,10 +211,11 @@ $mitarbeiter = einzahlung_fetch_participants($pdo, $tenantId, $action);
</div>
<?php elseif ($fehlgeschlagen): ?>
<div class="hint-box error"><p>Die Einzahlungen konnten nicht gespeichert werden.</p></div>
<?php else: ?>
<div class="hint-box success"><p><?php echo (int)$eingetragen; ?> Einträge erfolgreich hinzugefügt.</p></div>
<?php endif; ?>
<?php endif; ?>
<?php if ($erfolgsmeldung !== null): ?>
<div class="hint-box success"><p><?php echo saas_html($erfolgsmeldung); ?></p></div>
<?php endif; ?>
<div class="hint-box">
<p>In der Bemerkung könnt ihr festhalten, worum es bei einer Buchung ging. Ein <b>negativer Betrag</b> bucht einen Abzug (z.&nbsp;B. Auszahlung bei Austritt oder eine Erstattung) und braucht deshalb immer eine Bemerkung.</p>