diff --git a/zeiterfassung/alleZeitenanzeige.php b/zeiterfassung/alleZeitenanzeige.php index 5e8af51..acb4b1e 100644 --- a/zeiterfassung/alleZeitenanzeige.php +++ b/zeiterfassung/alleZeitenanzeige.php @@ -17,6 +17,13 @@ if ($_SERVER["REQUEST_METHOD"] == "POST") { # echo "Location: createPDF.php?id=$userId&month=$month&year=$year"; header("Location: createPDF.php?id=$userId&month=$month&year=$year"); exit(); + } elseif ($_POST["action"] == "Alle PDFs anzeigen") { + $selectedMonth = $_POST["month"]; + $monthYear = explode("/", $selectedMonth); + $month = $monthYear[0]; + $year = $monthYear[1]; + header("Location: createAllPDF.php?month=$month&year=$year"); + exit(); } } @@ -120,6 +127,9 @@ if ($selectedMonth && $selectedUser) { + + + @@ -150,4 +160,4 @@ if ($selectedMonth && $selectedUser) { - \ No newline at end of file + diff --git a/zeiterfassung/createAllPDF.php b/zeiterfassung/createAllPDF.php new file mode 100644 index 0000000..859e000 --- /dev/null +++ b/zeiterfassung/createAllPDF.php @@ -0,0 +1,173 @@ +prepare(" + SELECT DISTINCT u.id, u.vorname, u.nachname + FROM users u + INNER JOIN timestamps t ON t.employee_id = u.id + WHERE u.zeiterfassung = '1' + AND MONTH(t.timestamp_datetime) = :month + AND YEAR(t.timestamp_datetime) = :year + ORDER BY u.nachname ASC, u.vorname ASC + "); + $usersStmt->bindValue(':month', (int)$selectedMonth, PDO::PARAM_INT); + $usersStmt->bindValue(':year', (int)$selectedYear, PDO::PARAM_INT); + $usersStmt->execute(); + $employees = $usersStmt->fetchAll(PDO::FETCH_ASSOC); + + $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); + $pdf->SetCreator(PDF_CREATOR); + $pdf->SetAuthor($currentUser['vorname'] . ' ' . $currentUser['nachname']); + $pdf->SetTitle('Arbeitszeiten aller Mitarbeiter'); + $pdf->SetSubject('Arbeitszeiten aller Mitarbeiter fuer ' . $selectedMonth . '/' . $selectedYear); + + $stempdate = $selectedYear . "-" . $selectedMonth . "-1"; + $date = new DateTime($stempdate); + $formatter = new IntlDateFormatter( + "de-DE", + IntlDateFormatter::LONG, + IntlDateFormatter::NONE, + "Europe/Berlin", + IntlDateFormatter::GREGORIAN, + "MMMM" + ); + $monthName = $formatter->format($date); + + $sequenceStmt = $pdo->prepare(" + SELECT + DATE(timestamp_datetime) AS datum, + GROUP_CONCAT(timestamp_type ORDER BY timestamp_datetime) AS day_sequence + FROM timestamps + WHERE employee_id = :employee_id + AND MONTH(timestamp_datetime) = :selectedMonth + AND YEAR(timestamp_datetime) = :selectedYear + GROUP BY DATE(timestamp_datetime) + "); + + $timesStmt = $pdo->prepare(" + SELECT + DATE(timestamp_datetime) AS day, + MIN(CASE WHEN timestamp_type = 'KOMMEN' THEN timestamp_datetime END) AS first_come, + MAX(CASE WHEN timestamp_type = 'GEHEN' THEN timestamp_datetime END) AS last_go, + SEC_TO_TIME(SUM( + CASE + WHEN timestamp_type = 'GEHEN' THEN UNIX_TIMESTAMP(timestamp_datetime) + WHEN timestamp_type = 'KOMMEN' THEN -UNIX_TIMESTAMP(timestamp_datetime) + ELSE 0 + END + )) AS total_time, + SEC_TO_TIME( + TIME_TO_SEC( + SEC_TO_TIME( + UNIX_TIMESTAMP(MAX(CASE WHEN timestamp_type = 'GEHEN' THEN timestamp_datetime END)) - + UNIX_TIMESTAMP(MIN(CASE WHEN timestamp_type = 'KOMMEN' THEN timestamp_datetime END)) + ) + ) - TIME_TO_SEC(SEC_TO_TIME(SUM( + CASE + WHEN timestamp_type = 'GEHEN' THEN UNIX_TIMESTAMP(timestamp_datetime) + WHEN timestamp_type = 'KOMMEN' THEN -UNIX_TIMESTAMP(timestamp_datetime) + ELSE 0 + END + ))) + ) AS difference_between_total_time_and_pause_time + FROM timestamps + WHERE employee_id = :employee_id + AND MONTH(timestamp_datetime) = :month + AND YEAR(timestamp_datetime) = :year + GROUP BY DATE(timestamp_datetime) + "); + + foreach ($employees as $employee) { + $employeeId = (int)$employee['id']; + $employeeName = trim($employee['vorname'] . ' ' . $employee['nachname']); + + $sequenceStmt->bindValue(':employee_id', $employeeId, PDO::PARAM_INT); + $sequenceStmt->bindValue(':selectedMonth', (int)$selectedMonth, PDO::PARAM_INT); + $sequenceStmt->bindValue(':selectedYear', (int)$selectedYear, PDO::PARAM_INT); + $sequenceStmt->execute(); + $sequenceRows = $sequenceStmt->fetchAll(PDO::FETCH_ASSOC); + + $fehlerhafteTage = []; + foreach ($sequenceRows as $row) { + if (!isValidSequence((string)$row['day_sequence'])) { + $fehlerhafteTage[] = (string)$row['datum']; + } + } + + $pdf->AddPage(); + $html = '

Arbeitszeiten - ' . $firmaName . '

'; + $html .= '

Mitarbeiter: ' . htmlspecialchars($employeeName, ENT_QUOTES, 'UTF-8') . '

'; + $html .= '

Monat: ' . htmlspecialchars((string)$monthName, ENT_QUOTES, 'UTF-8') . ' ' . htmlspecialchars((string)$selectedYear, ENT_QUOTES, 'UTF-8') . '

'; + + if (!empty($fehlerhafteTage)) { + $html .= '

Fehlzeiten erkannt. Bitte erst beheben.

'; + $html .= '

Betroffene Tage: ' . htmlspecialchars(implode(', ', array_map(static function (string $day): string { + return date('d.m.Y', strtotime($day)); + }, $fehlerhafteTage)), ENT_QUOTES, 'UTF-8') . '

'; + $pdf->writeHTML($html, true, false, true, false, ''); + continue; + } + + $timesStmt->bindValue(':employee_id', $employeeId, PDO::PARAM_INT); + $timesStmt->bindValue(':month', (int)$selectedMonth, PDO::PARAM_INT); + $timesStmt->bindValue(':year', (int)$selectedYear, PDO::PARAM_INT); + $timesStmt->execute(); + + $timesData = []; + while ($row = $timesStmt->fetch(PDO::FETCH_ASSOC)) { + $day = date('d', strtotime($row['day'])); + $timesData[$day] = $row; + } + + $html .= ''; + $html .= ''; + + $totalSeconds = 0; + for ($day = 1; $day <= 31; $day++) { + $daytwo = str_pad((string)$day, 2, '0', STR_PAD_LEFT); + if (isset($timesData[$daytwo])) { + $row = $timesData[$daytwo]; + $html .= ''; + + if (!empty($row['total_time'])) { + [$hours, $minutes, $seconds] = explode(':', $row['total_time']); + $totalSeconds += ((int)$hours * 3600) + ((int)$minutes * 60) + (int)$seconds; + } + } else { + $html .= ''; + } + } + + $hours = floor($totalSeconds / 3600); + $mins = floor(($totalSeconds / 60) % 60); + $secs = floor($totalSeconds % 60); + $totalTime = sprintf('%02d:%02d:%02d', $hours, $mins, $secs); + + $html .= ''; + $html .= '
TagStartPauseEndeGesamtzeitaufgezeichnet am:Bemerkung
' . $day . '' . date('H:i:s', strtotime($row['first_come'])) . '' . $row['difference_between_total_time_and_pause_time'] . '' . date('H:i:s', strtotime($row['last_go'])) . '' . $row['total_time'] . '' . date('d.m.Y', strtotime($row['day'])) . '
' . $day . '
Gesamt' . $totalTime . '
'; + + $pdf->writeHTML($html, true, false, true, false, ''); + } + + $pdf->Output('Arbeitszeiten_alle_' . $selectedYear . '_' . str_pad((string)$selectedMonth, 2, '0', STR_PAD_LEFT) . '.pdf', 'I'); +} catch (PDOException $e) { + echo "Datenbankfehler: " . $e->getMessage(); +} +?>