= htmlspecialchars($_SESSION['success_message']) ?>
@@ -501,7 +252,6 @@ $german_weekdays = [
-
= htmlspecialchars($_SESSION['error_message']) ?>
@@ -518,12 +268,10 @@ $german_weekdays = [
@@ -533,7 +281,6 @@ $german_weekdays = [
nächster Termin:
= $german_weekday . ' ' . date('d.m.Y H:i', strtotime($row['meeting_date'])) ?>
-
-
+
Rechnung wird bezahlt von:
= htmlspecialchars($next_payer_username); ?>
@@ -581,6 +328,7 @@ $german_weekdays = [
Teilnahme eintragen
+
-
-
-
-
-
Aktive Verschiebungsvorschläge
-
-
-
-
- Vorschlag von = htmlspecialchars($proposal['proposer_name']) ?>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Neuer Termin: = date('d.m.Y H:i', strtotime($proposal['proposed_date'])) ?>
- Grund: = htmlspecialchars($proposal['reason']) ?>
- Erstellt: = date('d.m.Y H:i', strtotime($proposal['created_at'])) ?>
-
-
-
-
-
- Für mich OK:
-
-
-
-
-
-
-
-
-
-
- Verschiebung zustimmen:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
- Keine anstehenden Termine gefunden.
-
+
Keine anstehenden Termine gefunden.
-
+
diff --git a/teilnahme.php b/teilnahme.php
new file mode 100755
index 0000000..d50e425
--- /dev/null
+++ b/teilnahme.php
@@ -0,0 +1,151 @@
+ [], 'declined_users' => [], 'maybe_users' => [], 'total_accepted' => 0, 'total_declined' => 0, 'total_maybe' => 0];
+
+ mysqli_stmt_bind_param($stmt, "i", $meeting_id);
+ mysqli_stmt_execute($stmt);
+ $result = mysqli_stmt_get_result($stmt);
+
+ $accepted = $declined = $maybe = [];
+ while ($row = mysqli_fetch_assoc($result)) {
+ $username = htmlspecialchars($row['username']);
+ switch ($row['rsvp_status']) {
+ case 'accepted':
+ $accepted[] = $username;
+ break;
+ case 'declined':
+ $declined[] = $username;
+ break;
+ case 'maybe':
+ $maybe[] = $username;
+ break;
+ }
+ }
+ mysqli_stmt_close($stmt);
+
+ return [
+ 'accepted_users' => $accepted,
+ 'declined_users' => $declined,
+ 'maybe_users' => $maybe,
+ 'total_accepted' => count($accepted),
+ 'total_declined' => count($declined),
+ 'total_maybe' => count($maybe)
+ ];
+}
diff --git a/verschiebung.php b/verschiebung.php
new file mode 100755
index 0000000..2aef8b7
--- /dev/null
+++ b/verschiebung.php
@@ -0,0 +1,369 @@
+ [], 'user_votes' => [], 'yes_voters' => [], 'no_voters' => []];
+ }
+
+ $proposal_ids = array_column($active_proposals, 'id');
+ $ids_list = implode(',', array_map('intval', $proposal_ids));
+
+ $vote_stmt = mysqli_prepare($conn, "SELECT proposal_id, user_id, vote FROM meeting_reschedule_votes WHERE proposal_id IN ($ids_list)");
+ mysqli_stmt_execute($vote_stmt);
+ $votes = mysqli_fetch_all(mysqli_stmt_get_result($vote_stmt), MYSQLI_ASSOC);
+ mysqli_stmt_close($vote_stmt);
+
+ $user_ids = array_unique(array_column($votes, 'user_id'));
+ $user_names = [];
+ if (!empty($user_ids)) {
+ $user_ids_list = implode(',', array_map('intval', $user_ids));
+ $user_stmt = mysqli_prepare($conn, "SELECT id, username FROM users WHERE id IN ($user_ids_list)");
+ mysqli_stmt_execute($user_stmt);
+ $users = mysqli_fetch_all(mysqli_stmt_get_result($user_stmt), MYSQLI_ASSOC);
+ mysqli_stmt_close($user_stmt);
+ foreach ($users as $u) {
+ $user_names[$u['id']] = htmlspecialchars($u['username']);
+ }
+ }
+
+ $user_votes = [];
+ $yes_voters = array_fill_keys($proposal_ids, []);
+ $no_voters = array_fill_keys($proposal_ids, []);
+
+ foreach ($votes as $v) {
+ if ($v['user_id'] == $user_id) {
+ $user_votes[$v['proposal_id']] = $v['vote'];
+ }
+ $username = $user_names[$v['user_id']] ?? 'Unbekannt';
+ if ($v['vote'] === 'yes') {
+ $yes_voters[$v['proposal_id']][] = $username;
+ } elseif ($v['vote'] === 'no') {
+ $no_voters[$v['proposal_id']][] = $username;
+ }
+ }
+
+ foreach ($active_proposals as &$p) {
+ $p['yes_votes'] = count($yes_voters[$p['id']] ?? []);
+ $p['no_votes'] = count($no_voters[$p['id']] ?? []);
+ }
+
+ return compact('active_proposals', 'user_votes', 'yes_voters', 'no_voters');
+}
+
+function handle_reschedule_actions($conn, $meeting_id, $user_id)
+{
+ // Vorschlag einreichen
+ if (isset($_POST['propose_reschedule']) && isset($_POST['new_date']) && isset($_POST['reason'])) {
+ $new_date = $_POST['new_date'];
+ $reason = $_POST['reason'];
+
+ $check = mysqli_prepare($conn, "SELECT id FROM meeting_reschedule_proposals WHERE meeting_id = ? AND proposed_by_user_id = ? AND status = 'pending'");
+ mysqli_stmt_bind_param($check, "ii", $meeting_id, $user_id);
+ mysqli_stmt_execute($check);
+ $exists = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
+ mysqli_stmt_close($check);
+
+ if ($exists) {
+ $_SESSION['error_message'] = "Du hast bereits einen Verschiebungsvorschlag eingereicht.";
+ return;
+ }
+
+ $ins = mysqli_prepare($conn, "INSERT INTO meeting_reschedule_proposals (meeting_id, proposed_by_user_id, proposed_date, reason) VALUES (?, ?, ?, ?)");
+ mysqli_stmt_bind_param($ins, "iiss", $meeting_id, $user_id, $new_date, $reason);
+ mysqli_stmt_execute($ins);
+ $proposal_id = mysqli_insert_id($conn);
+ mysqli_stmt_close($ins);
+
+ // 🔥 Automatisch "Ja"-Stimme für den Ersteller
+ $auto_vote = mysqli_prepare($conn, "INSERT INTO meeting_reschedule_votes (proposal_id, user_id, vote) VALUES (?, ?, 'yes')");
+ mysqli_stmt_bind_param($auto_vote, "ii", $proposal_id, $user_id);
+ mysqli_stmt_execute($auto_vote);
+ mysqli_stmt_close($auto_vote);
+
+ // ✉️ E-Mail bei Vorschlag
+ if (file_exists(__DIR__ . '/vendor/autoload.php')) {
+ require_once __DIR__ . '/vendor/autoload.php';
+ $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
+ $mail->CharSet = 'UTF-8';
+ $mail->isHTML(false);
+
+ $orig_date = null;
+ $orig_stmt = mysqli_prepare($conn, "SELECT meeting_date FROM meetings WHERE id = ?");
+ mysqli_stmt_bind_param($orig_stmt, "i", $meeting_id);
+ mysqli_stmt_execute($orig_stmt);
+ $orig_row = mysqli_fetch_assoc(mysqli_stmt_get_result($orig_stmt));
+ mysqli_stmt_close($orig_stmt);
+ $orig_str = $orig_row ? date('d.m.Y', strtotime($orig_row['meeting_date'])) : 'einem Termin';
+
+ try {
+ $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);
+
+ $proposer = $_SESSION['username'] ?? 'Ein Benutzer';
+ $new_fmt = date('d.m.Y H:i', strtotime($new_date));
+ $subject = "DoMiLi: Neuer Terminvorschlag für den ursprünglichen Termin vom $orig_str";
+ $body = "Hallo %s,\n\n%s hat einen neuen Vorschlag zur Verschiebung des Termins eingereicht.\nNeuer vorgeschlagener Termin: %s\nGrund: %s\n\nBitte stimme erneut ab, ob du teilnehmen möchtest.\n\nZur Abstimmung: DoMiLi-APP\n%s\n\nDein DoMiLi-Team";
+
+ $users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE email IS NOT NULL AND email != ''");
+ while ($u = mysqli_fetch_assoc($users_stmt)) {
+ if (isset($_SESSION['email']) && $u['email'] === $_SESSION['email']) continue;
+ $mail->addAddress($u['email']);
+ $mail->Subject = $subject;
+ $mail->Body = sprintf($body, $u['username'], $proposer, $new_fmt, $reason, APP_URL . '/index.php');
+ $mail->send();
+ $mail->clearAddresses();
+ }
+ $_SESSION['success_message'] = "Vorschlag eingereicht! Alle Benutzer wurden benachrichtigt.";
+ } catch (Exception $e) {
+ $_SESSION['error_message'] = "Fehler beim Senden der E-Mails.";
+ error_log("PHPMailer Error: " . $mail->ErrorInfo);
+ }
+ } else {
+ $_SESSION['success_message'] = "Vorschlag eingereicht! (E-Mail nicht verfügbar)";
+ }
+ return;
+ }
+
+ // Abstimmen
+ if (isset($_POST['vote_proposal']) && isset($_POST['proposal_id'])) {
+ $pid = intval($_POST['proposal_id']);
+ $vote = $_POST['vote_proposal'];
+ if (!in_array($vote, ['yes', 'no', 'maybe'])) return;
+
+ $check = mysqli_prepare($conn, "SELECT id FROM meeting_reschedule_votes WHERE proposal_id = ? AND user_id = ?");
+ mysqli_stmt_bind_param($check, "ii", $pid, $user_id);
+ mysqli_stmt_execute($check);
+ $existing = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
+ mysqli_stmt_close($check);
+
+ if ($existing) {
+ $upd = mysqli_prepare($conn, "UPDATE meeting_reschedule_votes SET vote = ? WHERE id = ?");
+ mysqli_stmt_bind_param($upd, "si", $vote, $existing['id']);
+ mysqli_stmt_execute($upd);
+ mysqli_stmt_close($upd);
+ } else {
+ $ins = mysqli_prepare($conn, "INSERT INTO meeting_reschedule_votes (proposal_id, user_id, vote) VALUES (?, ?, ?)");
+ mysqli_stmt_bind_param($ins, "iis", $pid, $user_id, $vote);
+ mysqli_stmt_execute($ins);
+ mysqli_stmt_close($ins);
+ }
+ return;
+ }
+
+ // Löschen (nur Ersteller)
+ if (isset($_POST['delete_proposal']) && isset($_POST['proposal_id'])) {
+ $pid = intval($_POST['proposal_id']);
+ $check = mysqli_prepare($conn, "SELECT proposed_by_user_id FROM meeting_reschedule_proposals WHERE id = ? AND meeting_id = ?");
+ mysqli_stmt_bind_param($check, "ii", $pid, $meeting_id);
+ mysqli_stmt_execute($check);
+ $owner = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
+ mysqli_stmt_close($check);
+ if ($owner && $owner['proposed_by_user_id'] == $user_id) {
+ mysqli_query($conn, "DELETE FROM meeting_reschedule_votes WHERE proposal_id = $pid");
+ mysqli_query($conn, "DELETE FROM meeting_reschedule_proposals WHERE id = $pid");
+ }
+ return;
+ }
+
+ // Bearbeiten (nur Ersteller)
+ if (isset($_POST['edit_proposal']) && isset($_POST['proposal_id']) && isset($_POST['new_date']) && isset($_POST['reason'])) {
+ $pid = intval($_POST['proposal_id']);
+ $new_date = $_POST['new_date'];
+ $reason = $_POST['reason'];
+ $check = mysqli_prepare($conn, "SELECT proposed_by_user_id FROM meeting_reschedule_proposals WHERE id = ? AND meeting_id = ?");
+ mysqli_stmt_bind_param($check, "ii", $pid, $meeting_id);
+ mysqli_stmt_execute($check);
+ $owner = mysqli_fetch_assoc(mysqli_stmt_get_result($check));
+ mysqli_stmt_close($check);
+ if ($owner && $owner['proposed_by_user_id'] == $user_id) {
+ mysqli_query($conn, "DELETE FROM meeting_reschedule_votes WHERE proposal_id = $pid");
+ $upd = mysqli_prepare($conn, "UPDATE meeting_reschedule_proposals SET proposed_date = ?, reason = ? WHERE id = ?");
+ mysqli_stmt_bind_param($upd, "ssi", $new_date, $reason, $pid);
+ mysqli_stmt_execute($upd);
+ mysqli_stmt_close($upd);
+ }
+ return;
+ }
+
+ // Admin: Vorschlag annehmen → MEETING AKTUALISIEREN + E-MAIL
+ if (isset($_SESSION['role']) && $_SESSION['role'] === 'admin') {
+ if (isset($_POST['accept_proposal']) && isset($_POST['proposal_id'])) {
+ $proposal_id = intval($_POST['proposal_id']);
+
+ $proposal_stmt = mysqli_prepare($conn, "
+ SELECT p.proposed_date, p.reason, p.meeting_id,
+ m.meeting_date AS original_date
+ FROM meeting_reschedule_proposals p
+ JOIN meetings m ON p.meeting_id = m.id
+ WHERE p.id = ?
+ ");
+ mysqli_stmt_bind_param($proposal_stmt, "i", $proposal_id);
+ mysqli_stmt_execute($proposal_stmt);
+ $proposal = mysqli_fetch_assoc(mysqli_stmt_get_result($proposal_stmt));
+ mysqli_stmt_close($proposal_stmt);
+
+ if ($proposal) {
+ $new_date = $proposal['proposed_date'];
+ $new_reason = $proposal['reason'];
+ $meeting_id = $proposal['meeting_id'];
+ $original_date = $proposal['original_date'];
+
+ // Meeting aktualisieren
+ $update_meeting = mysqli_prepare($conn, "
+ UPDATE meetings
+ SET meeting_date = ?, reason = ?
+ WHERE id = ?
+ ");
+ mysqli_stmt_bind_param($update_meeting, "ssi", $new_date, $new_reason, $meeting_id);
+ mysqli_stmt_execute($update_meeting);
+ mysqli_stmt_close($update_meeting);
+
+ // Vorschlag akzeptieren
+ $accept_stmt = mysqli_prepare($conn, "
+ UPDATE meeting_reschedule_proposals
+ SET status = 'accepted'
+ WHERE id = ?
+ ");
+ mysqli_stmt_bind_param($accept_stmt, "i", $proposal_id);
+ mysqli_stmt_execute($accept_stmt);
+ mysqli_stmt_close($accept_stmt);
+
+ // Andere ablehnen
+ $reject_others = mysqli_prepare($conn, "
+ UPDATE meeting_reschedule_proposals
+ SET status = 'rejected'
+ WHERE meeting_id = ? AND id != ?
+ ");
+ mysqli_stmt_bind_param($reject_others, "ii", $meeting_id, $proposal_id);
+ mysqli_stmt_execute($reject_others);
+ mysqli_stmt_close($reject_others);
+
+ // ✉️ E-Mail nach Akzeptanz
+ if (file_exists(__DIR__ . '/vendor/autoload.php')) {
+ require_once __DIR__ . '/vendor/autoload.php';
+ $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
+ $mail->CharSet = 'UTF-8';
+ $mail->isHTML(false);
+
+ try {
+ $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);
+
+ $orig_fmt = date('d.m.Y H:i', strtotime($original_date));
+ $new_fmt = date('d.m.Y H:i', strtotime($new_date));
+ $subject = "DoMiLi: Termin wurde verschoben!";
+ $body = "Hallo %s,\n\nDer Termin wurde vom Admin verschoben.\n\nUrsprünglicher Termin: %s\nNeuer Termin: %s\nGrund: %s\n\nBitte stimme erneut ab, ob du teilnehmen möchtest.\n\nZur Abstimmung: DoMiLi-APP\n%s\n\nDein DoMiLi-Team";
+
+ $users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE email IS NOT NULL AND email != ''");
+ while ($u = mysqli_fetch_assoc($users_stmt)) {
+ $mail->addAddress($u['email']);
+ $mail->Subject = $subject;
+ $mail->Body = sprintf($body, $u['username'], $orig_fmt, $new_fmt, $new_reason, APP_URL . '/index.php');
+ $mail->send();
+ $mail->clearAddresses();
+ }
+ } catch (Exception $e) {
+ error_log("Fehler bei Akzeptanz-E-Mail: " . $mail->ErrorInfo);
+ }
+ }
+ }
+
+ header("Location: index.php");
+ exit;
+ }
+
+ // Admin: Vorschlag ablehnen → MIT KURZER E-MAIL
+ if (isset($_POST['reject_proposal']) && isset($_POST['proposal_id'])) {
+ $proposal_id = intval($_POST['proposal_id']);
+
+ // Vorschlagdaten laden
+ $proposal_stmt = mysqli_prepare($conn, "
+ SELECT p.proposed_by_user_id, u.username AS proposer_name,
+ m.meeting_date AS original_date
+ FROM meeting_reschedule_proposals p
+ JOIN users u ON p.proposed_by_user_id = u.id
+ JOIN meetings m ON p.meeting_id = m.id
+ WHERE p.id = ?
+ ");
+ mysqli_stmt_bind_param($proposal_stmt, "i", $proposal_id);
+ mysqli_stmt_execute($proposal_stmt);
+ $proposal = mysqli_fetch_assoc(mysqli_stmt_get_result($proposal_stmt));
+ mysqli_stmt_close($proposal_stmt);
+
+ // Vorschlag ablehnen
+ $reject_stmt = mysqli_prepare($conn, "
+ UPDATE meeting_reschedule_proposals
+ SET status = 'rejected'
+ WHERE id = ?
+ ");
+ mysqli_stmt_bind_param($reject_stmt, "i", $proposal_id);
+ mysqli_stmt_execute($reject_stmt);
+ mysqli_stmt_close($reject_stmt);
+
+ // ✉️ Kurze E-Mail nach Ablehnung
+ if ($proposal && file_exists(__DIR__ . '/vendor/autoload.php')) {
+ require_once __DIR__ . '/vendor/autoload.php';
+ $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
+ $mail->CharSet = 'UTF-8';
+ $mail->isHTML(false);
+
+ try {
+ $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);
+
+ $proposer = $proposal['proposer_name'];
+ $original_fmt = date('d.m.Y H:i', strtotime($proposal['original_date']));
+ $subject = "DoMiLi: Verschiebungsvorschlag abgelehnt";
+ $body = "Hallo %s,\n\nDer Verschiebungsvorschlag von {$proposer} wurde vom Admin abgelehnt.\nDer Termin bleibt daher unverändert beim ursprünglichen Termin am {$original_fmt}.\n\nDein DoMiLi-Team";
+
+ $users_stmt = mysqli_query($conn, "SELECT username, email FROM users WHERE email IS NOT NULL AND email != ''");
+ while ($u = mysqli_fetch_assoc($users_stmt)) {
+ $mail->addAddress($u['email']);
+ $mail->Subject = $subject;
+ $mail->Body = sprintf($body, $u['username']);
+ $mail->send();
+ $mail->clearAddresses();
+ }
+ } catch (Exception $e) {
+ error_log("Fehler bei Ablehnungs-E-Mail: " . $mail->ErrorInfo);
+ }
+ }
+
+ header("Location: index.php");
+ exit;
+ }
+ }
+}
diff --git a/zahler.php b/zahler.php
new file mode 100755
index 0000000..0527740
--- /dev/null
+++ b/zahler.php
@@ -0,0 +1,35 @@
+