Die Zugriffspruefung lief bisher in 19 Dateien auf einen Fallback gegen die Legacy-Tabelle kl_Mitarbeiter (checkKaffeelisteAdmin/-Access). Der Zugang haengt jetzt ausschliesslich an der SaaS-Anmeldung. - Fallback-Bloecke in allen 19 Dateien entfernt, ebenso getUserName/getUserId - functions.php besteht nur noch aus der SaaS-Anmeldung; die per String zusammengebaute Abfrage "WHERE Email like '<eingabe>'" ist damit weg - config.php baut keine sqlsrv-Verbindung mehr auf, der Kompatibilitaetslayer lib/sqlsrv_mysql_compat.php ist verwaist und entfaellt - Auto-Login per DEV_AUTH_EMAIL gibt es nicht mehr: er meldete jeden Besucher an und machte damit den Login-Schutz unpruefbar. Angemeldet wird auch lokal ueber login.php; die Variable dient nur noch scripts/init-mysql-dev.php http-smoke war an die Golden-Master-Daten des Default-Mandanten gebunden und hatte deshalb sechs dauerhaft rote Pruefungen. Der Test legt sich jetzt einen eigenen Mandanten mit bekannten Salden an, meldet sich per HTTP an und raeumt danach auf. Geschuetzte Seiten werden nicht mehr ueber das Wort "Login" im Text geprueft, sondern ueber die tatsaechliche 302-Umleitung. http-smoke 27 PASS / 6 FAIL -> 33 PASS / 0 FAIL role-matrix 55 PASS / 0 FAIL -> unveraendert tenant-isolation 9 PASS / 1 FAIL -> 11 PASS / 1 FAIL (Altfehler) Ausserdem "keine Zugang" -> "keinen Zugang" in zwei Fehlermeldungen; der Rollentest erkannte die Ablehnung an genau diesem Tippfehler und wurde mitgezogen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
172 lines
4.5 KiB
PHP
172 lines
4.5 KiB
PHP
<?php
|
|
|
|
include "functions.php";
|
|
require_once __DIR__ . "/app/ledger.php";
|
|
app_require_csrf();
|
|
include "header.php";
|
|
include "headerline.php";
|
|
include "nav.php";
|
|
|
|
|
|
|
|
?>
|
|
|
|
|
|
|
|
<!-- Banner -->
|
|
<section id="banner">
|
|
<div class="content">
|
|
|
|
<?php
|
|
|
|
$pdo = app_db_pdo();
|
|
$saasUser = saas_current_user($pdo);
|
|
$tenantId = 0;
|
|
$hasAccess = false;
|
|
|
|
if ($saasUser !== null && saas_user_has_role(['owner', 'admin', 'treasurer'], $saasUser)) {
|
|
$tenantId = (int)$saasUser['tenant_id'];
|
|
$hasAccess = true;
|
|
}
|
|
|
|
if (!$hasAccess) {
|
|
echo "<h2>Kein Zugriff</h2>";
|
|
include "footer.php";
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Liefert die Teilnehmerliste fuer die Vorder-/Rueckseiten- oder
|
|
* Alle-Auswahl. Vorderseite sind die Vieltrinker (>= 10 Striche im
|
|
* Listenfenster), Rueckseite der Rest.
|
|
*
|
|
* @return list<array>
|
|
*/
|
|
function stricheintragen_fetch_participants(PDO $pdo, int $tenantId, string $action): array
|
|
{
|
|
if ($action === 'vorderseite' || $action === 'rueckseite') {
|
|
$settings = saas_fetch_tenant_settings($pdo, $tenantId);
|
|
$windowDays = $settings['sheet_window_days'] ?? 100;
|
|
|
|
return ledger_fetch_participants_by_window_marks($pdo, $tenantId, $windowDays, $action === 'vorderseite');
|
|
}
|
|
|
|
return ledger_fetch_participant_summaries($pdo, $tenantId, ['active_only' => true]);
|
|
}
|
|
|
|
$eingetragen = 0;
|
|
$fehlgeschlagen = false;
|
|
$hatGespeichert = false;
|
|
|
|
// Verarbeitung des Formulars, wenn es gesendet wurde
|
|
if ($_SERVER["REQUEST_METHOD"] == "POST") {
|
|
$hatGespeichert = true;
|
|
$kostenproStrich = floatval($_POST["kostenproStrich"] ?? 0);
|
|
$unitPriceCents = (int)round($kostenproStrich * 100);
|
|
|
|
// Teilnehmer des Mandanten - dient der Zugehoerigkeitspruefung, damit ueber
|
|
// das Formular keine fremden IDs bebucht werden koennen.
|
|
$eigeneTeilnehmer = [];
|
|
$stmt = $pdo->prepare('SELECT id FROM participants WHERE tenant_id = ?');
|
|
$stmt->execute([$tenantId]);
|
|
foreach ($stmt->fetchAll(PDO::FETCH_COLUMN) as $id) {
|
|
$eigeneTeilnehmer[(int)$id] = true;
|
|
}
|
|
|
|
try {
|
|
$pdo->beginTransaction();
|
|
|
|
foreach ($_POST["anzahlStriche"] ?? [] as $participantId => $anzahlStriche) {
|
|
$participantId = (int)$participantId;
|
|
$anzahlStriche = (int)$anzahlStriche;
|
|
if ($participantId <= 0 || $anzahlStriche === 0 || !isset($eigeneTeilnehmer[$participantId])) {
|
|
continue;
|
|
}
|
|
|
|
ledger_record_consumption($pdo, $tenantId, $participantId, $anzahlStriche, $unitPriceCents, 'manual_bulk');
|
|
$eingetragen++;
|
|
}
|
|
|
|
$pdo->commit();
|
|
} catch (Throwable $e) {
|
|
if ($pdo->inTransaction()) {
|
|
$pdo->rollBack();
|
|
}
|
|
$fehlgeschlagen = true;
|
|
}
|
|
|
|
$action = 'alle';
|
|
} else {
|
|
$action = (string)($_GET['action'] ?? 'alle');
|
|
}
|
|
|
|
$mitarbeiter = stricheintragen_fetch_participants($pdo, $tenantId, $action);
|
|
$settings = saas_fetch_tenant_settings($pdo, $tenantId);
|
|
$kostenproStrichAnzeige = number_format(($settings['mark_price_cents'] ?? 20) / 100, 2, '.', '');
|
|
|
|
?>
|
|
|
|
<h2>Anzahl der Striche für alle Mitarbeiter</h2>
|
|
|
|
<?php if ($hatGespeichert): ?>
|
|
<?php if ($fehlgeschlagen): ?>
|
|
<div class="hint-box error"><p>Die Einträge 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; ?>
|
|
|
|
<ul class="actions">
|
|
<li>
|
|
<form action="stricheintragen.php" method="get">
|
|
<input type="hidden" name="action" value="vorderseite">
|
|
<button type="submit">Vorderseite</button>
|
|
</form>
|
|
</li>
|
|
<li>
|
|
<form action="stricheintragen.php" method="get">
|
|
<input type="hidden" name="action" value="rueckseite">
|
|
<button type="submit">Rückseite</button>
|
|
</form>
|
|
</li>
|
|
<li>
|
|
<form action="stricheintragen.php" method="get">
|
|
<input type="hidden" name="action" value="alle">
|
|
<button type="submit">Alle</button>
|
|
</form>
|
|
</li>
|
|
</ul>
|
|
|
|
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
|
|
<?php echo app_csrf_field(); ?>
|
|
<?php
|
|
|
|
echo "<label for='kostenproStrich'>Kosten pro Strich:</label>
|
|
<input type='number' name='kostenproStrich' step='0.01' value='" . saas_html($kostenproStrichAnzeige) . "'><br>";
|
|
|
|
echo "<table>";
|
|
echo " <tr>
|
|
<th>Mitarbeiter</th>
|
|
<th>Anzahl Striche</th>
|
|
</tr>";
|
|
|
|
foreach ($mitarbeiter as $teilnehmer) {
|
|
$participantId = $teilnehmer['participant_id'];
|
|
$name = saas_html($teilnehmer['display_name']);
|
|
echo "<tr>";
|
|
echo "<td><label for='anzahlStriche[$participantId]'>$name:</label></td>";
|
|
echo "<td><input type='number' name='anzahlStriche[$participantId]' ></td>";
|
|
echo "</tr>";
|
|
}
|
|
echo "</table>";
|
|
|
|
?>
|
|
|
|
<button type="submit">Eintragen</button>
|
|
</form>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<?php include "footer.php"; ?>
|