1.3.0
This commit is contained in:
277
export.php
Executable file
277
export.php
Executable file
@@ -0,0 +1,277 @@
|
||||
<?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";
|
||||
Reference in New Issue
Block a user