format('Y-m-d'); $stmt = mysqli_prepare($conn, " SELECT m.id AS meeting_id, m.meeting_date, mt.user_id, mt.wore_color, mt.paid FROM meetings m LEFT JOIN meeting_teilnehmer mt ON m.id = mt.meeting_id AND mt.attended = 1 WHERE m.meeting_date <= ? AND m.is_completed = 1 ORDER BY m.meeting_date "); mysqli_stmt_bind_param($stmt, 's', $bisDatum); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $alleMeetingsMitTeilnehmern = []; while ($row = mysqli_fetch_assoc($result)) { $alleMeetingsMitTeilnehmern[] = $row; } mysqli_stmt_close($stmt); // === 5. Meetings des Berichtsmonats mit Farben === $stmtMeta = mysqli_prepare($conn, " SELECT id, meeting_date, reason, color_id FROM meetings WHERE meeting_date >= ? AND meeting_date <= ? AND is_completed = 1 ORDER BY meeting_date "); $startDate = $berichtsMonatBeginn->format('Y-m-d'); $endDate = $berichtsMonatEnde->format('Y-m-d'); mysqli_stmt_bind_param($stmtMeta, 'ss', $startDate, $endDate); mysqli_stmt_execute($stmtMeta); $resultMeta = mysqli_stmt_get_result($stmtMeta); $berichtsMeetingsMeta = []; while ($row = mysqli_fetch_assoc($resultMeta)) { $color_id = (int)$row['color_id']; $colorStmt = mysqli_prepare($conn, "SELECT name FROM colors WHERE id = ?"); mysqli_stmt_bind_param($colorStmt, 'i', $color_id); mysqli_stmt_execute($colorStmt); $colorRes = mysqli_stmt_get_result($colorStmt); $colorName = '–'; if ($cRow = mysqli_fetch_assoc($colorRes)) { $colorName = $cRow['name']; } mysqli_stmt_close($colorStmt); $berichtsMeetingsMeta[] = [ 'id' => $row['id'], 'meeting_date' => $row['meeting_date'], 'reason' => $row['reason'], 'color_name' => $colorName ]; } mysqli_stmt_close($stmtMeta); // === 6. Für jedes Meeting: alle Benutzer mit allen Werten === $gruppiert = []; foreach ($berichtsMeetingsMeta as $meta) { $mid = $meta['id']; $meetingDatum = new DateTime($meta['meeting_date']); $gruppiert[$mid] = [ 'datum' => $meta['meeting_date'], 'reason' => $meta['reason'], 'color_name' => $meta['color_name'], 'teilnehmer' => [] ]; foreach ($userIds as $uid) { $username = $alleBenutzer[$uid]; $teilgenommen = false; $wore_color = null; $paid_this = false; foreach ($alleMeetingsMitTeilnehmern as $mt) { if ($mt['meeting_id'] == $mid && $mt['user_id'] == $uid) { $teilgenommen = true; $wore_color = !empty($mt['wore_color']); $paid_this = !empty($mt['paid']); break; } } // Kumulierte Werte bis zu diesem Meeting $strafenGesamt = 0; $offeneStrafen = 0; $teilnahmenGesamt = 0; $rechnungenGesamt = 0; foreach ($alleMeetingsMitTeilnehmern as $mt) { if ($mt['user_id'] != $uid || is_null($mt['user_id'])) continue; $mDatum = new DateTime($mt['meeting_date']); if ($mDatum > $meetingDatum) continue; $teilnahmenGesamt++; if (!$mt['wore_color']) { $strafenGesamt++; if ($mt['meeting_date'] >= $last_closing) { $offeneStrafen++; } } if (!empty($mt['paid'])) { $rechnungenGesamt++; } } $userNameAnzeige = htmlspecialchars($username); if ($paid_this) { $userNameAnzeige .= ' '; } if (!$teilgenommen) { $farbeSymbol = '–'; } else { $farbeSymbol = $wore_color ? '✓' : '✗'; } $gruppiert[$mid]['teilnehmer'][] = [ 'username' => $userNameAnzeige, 'farbe_symbol' => $farbeSymbol, 'teilgenommen' => $teilgenommen, 'offene_strafen' => $offeneStrafen, 'strafen_gesamt' => $strafenGesamt, 'teilnahmen_gesamt' => $teilnahmenGesamt, 'rechnungen_gesamt' => $rechnungenGesamt ]; } } // === 7. Gesamt offene Strafen === $gesamtOffen = 0; foreach ($alleMeetingsMitTeilnehmern as $mt) { if (!is_null($mt['user_id']) && !$mt['wore_color'] && $mt['meeting_date'] >= $last_closing) { $gesamtOffen++; } } // === 8. PDF-Pfad === @mkdir(__DIR__ . '/backups', 0755, true); $baseName = 'DoMiLi_Backup_' . $berichtsMonatBeginn->format('Y-m'); $counter = 0; $outputPath = __DIR__ . '/backups/' . $baseName . '.pdf'; while (file_exists($outputPath)) { $counter++; $outputPath = __DIR__ . '/backups/' . $baseName . '_' . $counter . '.pdf'; } // === 9. HTML mit allen Anforderungen === $html = '

DoMiLi – Monatliches Backup

Zeitraum: ' . $berichtsMonatBeginn->format('F Y') . '

Strafkasse: ' . $gesamtOffen . ' €
'; if (empty($berichtsMeetingsMeta)) { $html .= '

Keine abgeschlossenen Meetings im Berichtsmonat.

'; } else { $meetingCount = 0; foreach ($gruppiert as $meeting) { if ($meetingCount > 0 && $meetingCount % 3 === 0) { $html .= '
'; } $meetingCount++; $meetingDatum = new DateTime($meeting['datum']); $html .= '

' . $meetingDatum->format('d.m.Y') . ' – ' . htmlspecialchars($meeting['reason']) . ' (' . htmlspecialchars($meeting['color_name']) . ')

'; $html .= ''; foreach ($meeting['teilnehmer'] as $t) { if ($t['farbe_symbol'] === '✓') { $farbeHtml = ''; } elseif ($t['farbe_symbol'] === '✗') { $farbeHtml = ''; } else { $farbeHtml = $t['farbe_symbol']; } $html .= ''; } $html .= '
Benutzer* Farbe getragen offene Strafen (in €) Strafen gesamt Teilnahmen gesamt Rechnung gesamt
' . $t['username'] . ' ' . $farbeHtml . ' ' . $t['offene_strafen'] . ' ' . $t['strafen_gesamt'] . ' ' . $t['teilnahmen_gesamt'] . ' ' . $t['rechnungen_gesamt'] . '
'; } } $html .= '

Erstellt am: ' . date('d.m.Y') . '

* = "€" hat Restaurant-Rechnung bezahlt

'; // === 10. PDF erzeugen === $options = new Options(); $options->set('defaultFont', 'DejaVu Sans'); $dompdf = new Dompdf($options); $dompdf->loadHtml($html); $dompdf->setPaper('A4', 'portrait'); $dompdf->render(); file_put_contents($outputPath, $dompdf->output()); echo "✅ PDF erfolgreich gespeichert: " . $outputPath . "\n";