num_rows > 0; mysqli_stmt_close($check); if (!$exists) { // 1. Abschluss in penalty_closings protokollieren $insert = mysqli_prepare($conn, "INSERT INTO penalty_closings (closing_date, closed_by) VALUES (?, ?)"); mysqli_stmt_bind_param($insert, "si", $today, $user_id); mysqli_stmt_execute($insert); mysqli_stmt_close($insert); // 2. E-Mail-Daten: Strafen seit letztem Abschluss (für Benachrichtigung) $penalty_summary = []; $stmt_email = mysqli_prepare($conn, " SELECT u.username, COUNT(*) AS penalty_count FROM meeting_teilnehmer mt JOIN meetings m ON mt.meeting_id = m.id JOIN users u ON mt.user_id = u.id WHERE m.meeting_date > ? AND m.meeting_date <= ? AND mt.attended = 1 AND mt.wore_color = 0 AND m.is_completed = 1 GROUP BY u.username "); mysqli_stmt_bind_param($stmt_email, "ss", $last_closing_date, $today); mysqli_stmt_execute($stmt_email); $result_email = mysqli_stmt_get_result($stmt_email); while ($row = mysqli_fetch_assoc($result_email)) { $penalty_summary[] = $row; } mysqli_stmt_close($stmt_email); // 3. NEU: Kumulierte Strafen JEDES Benutzers bis heute in penalty_history speichern $stmt_save = mysqli_prepare($conn, " INSERT INTO penalty_history (closing_date, user_id, username_at_close, penalty_count) SELECT ?, u.id, u.username, COUNT(mt.id) FROM users u LEFT JOIN meeting_teilnehmer mt ON u.id = mt.user_id LEFT JOIN meetings m ON mt.meeting_id = m.id AND m.meeting_date <= ? AND mt.attended = 1 AND mt.wore_color = 0 AND m.is_completed = 1 GROUP BY u.id, u.username "); mysqli_stmt_bind_param($stmt_save, "ss", $today, $today); mysqli_stmt_execute($stmt_save); mysqli_stmt_close($stmt_save); // 4. E-Mail-Versand (unverändert) $all_users = []; $stmt_users = mysqli_prepare($conn, "SELECT id, username, email FROM users WHERE email IS NOT NULL AND email != ''"); mysqli_stmt_execute($stmt_users); $result_users = mysqli_stmt_get_result($stmt_users); while ($row = mysqli_fetch_assoc($result_users)) { $all_users[] = $row; } mysqli_stmt_close($stmt_users); if (!empty($all_users) && file_exists(__DIR__ . '/vendor/autoload.php')) { require_once __DIR__ . '/vendor/autoload.php'; $today_formatted = date('d.m.Y', strtotime($today)); $last_closing_formatted = date('d.m.Y', strtotime($last_closing_date)); foreach ($all_users as $recipient) { $recipient_email = $recipient['email']; $recipient_name = $recipient['username'] ?? 'Benutzer'; try { $mail = new \PHPMailer\PHPMailer\PHPMailer(true); $mail->CharSet = 'UTF-8'; $mail->isSMTP(); $mail->Host = SMTP_HOST; $mail->SMTPAuth = true; $mail->Username = SMTP_USERNAME; $mail->Password = SMTP_PASSWORD; $mail->SMTPSecure = SMTP_ENCRYPTION; $mail->Port = SMTP_PORT; $mail->setFrom(MAIL_FROM_ADDRESS, MAIL_FROM_NAME); $text_body = "Hallo $recipient_name,\n\n"; $text_body .= "Der Jahresabschluss wurde am $today_formatted durchgeführt.\n"; $text_body .= "Strafen der abgeschlossenen Periode (vom $last_closing_formatted bis $today_formatted):\n\n"; if (empty($penalty_summary)) { $text_body .= "Keine Strafen in diesem Zeitraum.\n"; } else { foreach ($penalty_summary as $row) { $text_body .= "- " . $row['username'] . ": " . (int)$row['penalty_count'] . " Strafen (1 € pro Strafe)\n"; } } $text_body .= "\nDein DoMiLi-Admin."; $html_table_rows = ''; if (empty($penalty_summary)) { $html_table_rows = 'Keine Strafen in diesem Zeitraum.'; } else { foreach ($penalty_summary as $row) { $html_table_rows .= sprintf( ' %s %d %s ', htmlspecialchars($row['username']), (int)$row['penalty_count'], number_format((float)($row['penalty_count']), 2, ',', '.') . ' €' ); } } $html_body = "

Hallo $recipient_name,

der Jahresabschluss wurde am $today_formatted durchgeführt.

Strafen der abgeschlossenen Periode (vom $last_closing_formatted bis $today_formatted):

$html_table_rows
Mitglied Anzahl Strafen Betrag

Dein DoMiLi-Admin.

"; $mail->isHTML(true); $mail->Subject = "DoMiLi – Jahresabschluss abgeschlossen am $today_formatted"; $mail->Body = $html_body; $mail->AltBody = $text_body; $mail->addAddress($recipient_email); $mail->send(); } catch (Exception $e) { error_log("PHPMailer Fehler: " . $mail->ErrorInfo); } } } $close_success = "Jahresabschluss erfolgreich durchgeführt!"; } else { $close_error = "Heute wurde bereits ein Abschluss durchgeführt."; } } // --- DATEN FÜR ANZEIGE --- // Letztes Abschlussdatum ermitteln $last_closing_date = '2020-01-01'; $result_last = mysqli_query($conn, "SELECT MAX(closing_date) AS last_date FROM penalty_closings"); if ($result_last) { $row = mysqli_fetch_assoc($result_last); if ($row && !is_null($row['last_date'])) { $last_closing_date = $row['last_date']; } } $penalty_amount = 1; // 🔹 Alle Mitglieder initialisieren $penalties_data = []; $stmt_members = mysqli_prepare($conn, "SELECT username FROM users ORDER BY username"); mysqli_stmt_execute($stmt_members); $result_members = mysqli_stmt_get_result($stmt_members); while ($row = mysqli_fetch_assoc($result_members)) { $penalties_data[$row['username']] = [ 'username' => $row['username'], 'total_penalty_count' => 0, 'open_penalty_count' => 0 ]; } mysqli_stmt_close($stmt_members); // 🔹 "Strafen gesamt" = KUMULIERT seit Beginn (nur echte Strafen) $stmt_total = mysqli_prepare($conn, " SELECT u.username, COUNT(penalty.meeting_id) AS total_penalty_count FROM users u LEFT JOIN ( SELECT mt.user_id, mt.meeting_id FROM meeting_teilnehmer mt INNER JOIN meetings m ON mt.meeting_id = m.id WHERE mt.attended = 1 AND mt.wore_color = 0 AND m.is_completed = 1 ) AS penalty ON u.id = penalty.user_id GROUP BY u.id, u.username "); mysqli_stmt_execute($stmt_total); $result_total = mysqli_stmt_get_result($stmt_total); while ($row = mysqli_fetch_assoc($result_total)) { if (isset($penalties_data[$row['username']])) { $penalties_data[$row['username']]['total_penalty_count'] = (int)$row['total_penalty_count']; } } mysqli_stmt_close($stmt_total); // 🔹 "offener Betrag" = Strafen SEIT letztem Abschluss (>) $stmt_open = mysqli_prepare($conn, " SELECT u.username, COUNT(*) AS open_penalty_count FROM meeting_teilnehmer mt JOIN meetings m ON mt.meeting_id = m.id JOIN users u ON mt.user_id = u.id WHERE m.meeting_date > ? AND mt.attended = 1 AND mt.wore_color = 0 AND m.is_completed = 1 GROUP BY u.username "); mysqli_stmt_bind_param($stmt_open, "s", $last_closing_date); mysqli_stmt_execute($stmt_open); $result_open = mysqli_stmt_get_result($stmt_open); while ($row = mysqli_fetch_assoc($result_open)) { if (isset($penalties_data[$row['username']])) { $penalties_data[$row['username']]['open_penalty_count'] = (int)$row['open_penalty_count']; } } mysqli_stmt_close($stmt_open); // 🔹 Sortieren $penalties_data = array_values($penalties_data); usort($penalties_data, function ($a, $b) { if ($b['open_penalty_count'] !== $a['open_penalty_count']) { return $b['open_penalty_count'] <=> $a['open_penalty_count']; } return strcmp($a['username'], $b['username']); }); $total_open = array_sum(array_column($penalties_data, 'open_penalty_count')); $total_due = $total_open * $penalty_amount; // 🔹 Historische Strafen: pro Abschluss-Zeitraum $historical_periods = []; $closing_dates = []; $result_closings = mysqli_query($conn, "SELECT closing_date FROM penalty_closings ORDER BY closing_date"); while ($row = mysqli_fetch_assoc($result_closings)) { $closing_dates[] = $row['closing_date']; } if (count($closing_dates) >= 2) { for ($i = 1; $i < count($closing_dates); $i++) { $start_date = $closing_dates[$i - 1]; $end_date = $closing_dates[$i]; $period_label = date('d.m.Y', strtotime($start_date)) . ' – ' . date('d.m.Y', strtotime($end_date)); $stmt_hist = mysqli_prepare($conn, " SELECT u.username, COUNT(*) AS penalty_count FROM meeting_teilnehmer mt JOIN meetings m ON mt.meeting_id = m.id JOIN users u ON mt.user_id = u.id WHERE m.meeting_date > ? AND m.meeting_date <= ? AND mt.attended = 1 AND mt.wore_color = 0 AND m.is_completed = 1 GROUP BY u.username "); mysqli_stmt_bind_param($stmt_hist, "ss", $start_date, $end_date); mysqli_stmt_execute($stmt_hist); $result_hist = mysqli_stmt_get_result($stmt_hist); while ($row = mysqli_fetch_assoc($result_hist)) { $historical_periods[] = [ 'username' => $row['username'], 'period' => $period_label, 'count' => (int)$row['penalty_count'] ]; } mysqli_stmt_close($stmt_hist); } } elseif (count($closing_dates) === 1) { $end_date = $closing_dates[0]; $period_label = '17.07.2025 – ' . date('d.m.Y', strtotime($end_date)); $stmt_hist = mysqli_prepare($conn, " SELECT u.username, COUNT(*) AS penalty_count FROM meeting_teilnehmer mt JOIN meetings m ON mt.meeting_id = m.id JOIN users u ON mt.user_id = u.id WHERE m.meeting_date <= ? AND mt.attended = 1 AND mt.wore_color = 0 AND m.is_completed = 1 GROUP BY u.username "); mysqli_stmt_bind_param($stmt_hist, "s", $end_date); mysqli_stmt_execute($stmt_hist); $result_hist = mysqli_stmt_get_result($stmt_hist); while ($row = mysqli_fetch_assoc($result_hist)) { $historical_periods[] = [ 'username' => $row['username'], 'period' => $period_label, 'count' => (int)$row['penalty_count'] ]; } mysqli_stmt_close($stmt_hist); } // --- Rechnungs-Statistik (unverändert) --- $paid_stats = []; $sql_paid = " SELECT u.username, COUNT(mt.user_id) AS paid_count FROM meeting_teilnehmer mt JOIN meetings m ON mt.meeting_id = m.id JOIN users u ON mt.user_id = u.id WHERE mt.paid = 1 AND mt.birthday_pay = 0 AND m.is_completed = 1 GROUP BY u.username ORDER BY paid_count ASC, u.username ASC "; $result_paid = mysqli_query($conn, $sql_paid); while ($row = mysqli_fetch_assoc($result_paid)) { $paid_stats[] = $row; } require_once 'inc/header.php'; ?>

Kasse

Strafen

Strafkasse:

Keine Mitglieder gefunden.
Benutzer Strafen gesamt offener Betrag

Historische Strafen

Benutzer Zeitraum Strafen

Rechnungen

Ranking – Rechnung übernommen

Position 1 = nächster Zahler