Files
domili/export.php
Borgal 1b9ba22bb5 1.3.0
2025-11-16 21:13:04 +01:00

278 lines
8.9 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// define('DOMILI_ALLOW_WEB', true); // Zum Testen im Browser einkommentieren
if (php_sapi_name() !== 'cli' && !defined('DOMILI_ALLOW_WEB')) {
die('Zugriff verweigert.');
}
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/inc/db.php';
use Dompdf\Dompdf;
use Dompdf\Options;
date_default_timezone_set('Europe/Berlin');
// === 1. Berichtsmonat ===
$berichtsMonatEnde = new DateTime('last day of last month');
$berichtsMonatBeginn = new DateTime('first day of last month');
// === 2. Letzter Jahresabschluss ===
$last_closing = '2020-01-01';
$res = mysqli_query($conn, "SELECT MAX(closing_date) AS last_date FROM penalty_closings");
if ($res && ($row = mysqli_fetch_assoc($res)) && !is_null($row['last_date'])) {
$last_closing = $row['last_date'];
}
// === 3. Alle Benutzer ===
$alleBenutzer = [];
$resUsers = mysqli_query($conn, "SELECT id, username FROM users ORDER BY username");
while ($row = mysqli_fetch_assoc($resUsers)) {
$alleBenutzer[$row['id']] = $row['username'];
}
$userIds = array_keys($alleBenutzer);
// === 4. Alle relevanten Daten (nur completed + attended=1) ===
$bisDatum = $berichtsMonatEnde->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 .= ' <span class="paid-symbol">€</span>';
}
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 = '
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
body { font-family: DejaVu Sans, Arial, sans-serif; font-size: 9pt; }
h1 { font-size: 14pt; margin-bottom: 14pt; }
h2 { font-size: 11pt; margin: 12pt 0 8pt 0; }
.strafkasse { font-weight: bold; margin: 0 0 14pt 0; padding: 6pt; background-color: #f9f9f9; border: 1px solid #ccc; }
table { width: 100%; border-collapse: collapse; margin-bottom: 12pt; }
th, td { border: 1px solid #333; padding: 4pt 6pt; text-align: left; }
th { background-color: #f0f0f0; font-weight: bold; }
.paid-symbol { color: red; font-weight: bold; }
.color-ok { color: green; }
.color-fail { color: red; }
.page-break { page-break-after: always; }
.meta { margin-top: 20pt; font-size: 8pt; color: #555; }
</style>
</head>
<body>
<h1>DoMiLi Monatliches Backup</h1>
<h2>Zeitraum: ' . $berichtsMonatBeginn->format('F Y') . '</h2>
<div class="strafkasse">Strafkasse: ' . $gesamtOffen . ' €</div>';
if (empty($berichtsMeetingsMeta)) {
$html .= '<p>Keine abgeschlossenen Meetings im Berichtsmonat.</p>';
} else {
$meetingCount = 0;
foreach ($gruppiert as $meeting) {
if ($meetingCount > 0 && $meetingCount % 3 === 0) {
$html .= '<div class="page-break"></div>';
}
$meetingCount++;
$meetingDatum = new DateTime($meeting['datum']);
$html .= '<h3>' . $meetingDatum->format('d.m.Y') . ' ' . htmlspecialchars($meeting['reason']) . ' (' . htmlspecialchars($meeting['color_name']) . ')</h3>';
$html .= '<table>
<thead>
<tr>
<th>Benutzer*</th>
<th>Farbe getragen</th>
<th>offene Strafen (in €)</th>
<th>Strafen gesamt</th>
<th>Teilnahmen gesamt</th>
<th>Rechnung gesamt</th>
</tr>
</thead>
<tbody>';
foreach ($meeting['teilnehmer'] as $t) {
if ($t['farbe_symbol'] === '✓') {
$farbeHtml = '<span class="color-ok">✓</span>';
} elseif ($t['farbe_symbol'] === '✗') {
$farbeHtml = '<span class="color-fail">✗</span>';
} else {
$farbeHtml = $t['farbe_symbol'];
}
$html .= '<tr>
<td>' . $t['username'] . '</td>
<td>' . $farbeHtml . '</td>
<td>' . $t['offene_strafen'] . '</td>
<td>' . $t['strafen_gesamt'] . '</td>
<td>' . $t['teilnahmen_gesamt'] . '</td>
<td>' . $t['rechnungen_gesamt'] . '</td>
</tr>';
}
$html .= '</tbody></table>';
}
}
$html .= '
<div class="meta">
<p>Erstellt am: ' . date('d.m.Y') . '</p>
<p><em>* = "€" hat Restaurant-Rechnung bezahlt</em></p>
</div>
</body>
</html>';
// === 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";