Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
<?php session_start(); ?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>timerec | Buchen</title>
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="shortcut icon" href="favicon.ico">
<link rel="stylesheet" href="DatePickerX.css">
<script src="DatePickerX.js"></script>
<script type="text/javascript">
//hidestatus versteckt das Statusfeld im Formular, falls nicht Typ Urlaub oder Gleittag ausgewählt wurde
function hidestatus(option){
if(option.value == 10 || option.value == 20){
document.getElementById('status').style = 'display: table-row;';
document.getElementsByName('status')[0].value = x;
}else{
x = document.getElementsByName('status')[0].value;
document.getElementById('status').style = 'display: none;';
document.getElementsByName('status')[0].value = '';
}
}
function check(feld){
if(feld.checkValidity()){
document.location.href="buchen.php?datum="+feld.value;
}else{
feld.reportValidity();
}
}
window.addEventListener('DOMContentLoaded', function(){
for(input of document.querySelectorAll('[type="date"]')){
input.DatePickerX.init({
// options here
format : 'yyyy-mm-dd',
weekDayLabels : ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
shortMonthLabels : ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],
singleMonthLabels: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
todayButtonLabel : 'Heute',
clearButton: false
});
}
});
</script>
</head>
<body>
<?php
include('dbconnect.php');
//Feiertag-Funktion, abgewandelt vom Kalender
function feiertag($datum){
global $dbc;
$tag = $datum->format('d');
$monat = $datum->format('m');
$jahr = $datum->format('Y');
//abfrage, um mehrere DB Querys zu verhindern
if(empty($feiertage)){
// Feste Feiertage werden nach dem Schema ddmm eingetragen
$feiertage[] = "0101"; // Neujahrstag
$feiertage[] = "0105"; // Tag der Arbeit
$feiertage[] = "0310"; // Tag der Deutschen Einheit
$feiertage[] = "2512"; // Erster Weihnachtstag
$feiertage[] = "2612"; // Zweiter Weihnachtstag
// Bewegliche Feiertage berechnen
$tage = 60 * 60 * 24;
$ostersonntag = easter_date($jahr);
$feiertage[] = date("dm", $ostersonntag - 2 * $tage); // Karfreitag
$feiertage[] = date("dm", $ostersonntag + 1 * $tage); // Ostermontag
$feiertage[] = date("dm", $ostersonntag + 39 * $tage); // Himmelfahrt
$feiertage[] = date("dm", $ostersonntag + 50 * $tage); // Pfingstmontag
//freie Tage FHI aus Datenbank nehmen
$getfree = $dbc->query("select daymon from feiertag where year = $jahr;");
foreach($getfree as $free){
$feiertage[] = $free['daymon'];
}
}
// Prüfen, ob Feiertag
$code = $tag.$monat;
return in_array($code, $feiertage);
}
//session_start(); //1. zeile
if(!$_SESSION['userid']){
session_destroy();
include('login.php');
exit;
}
//Rechte check
if(!$_SESSION['userarray']['admin'] && $_SESSION['userarray']['maID'] != $_SESSION['infoarray']['maID'] && !in_array($_SESSION['infoarray']['agID'], $_SESSION['userarray']['ag_array'])){
echo "<h3>keine Rechte, diese Seite einzusehen!</h3>";
exit;
}
$infoarray = $_SESSION['infoarray'];
$userarray = $_SESSION['userarray'];
$maID = $infoarray['maID'];
$name = $infoarray['nachname'].", ".$infoarray['vorname'];
$userid = $userarray['userid'];
if(isset($_GET['datum'])){
$datum = $_GET['datum'];
}else{
echo "kein Datum gegeben. Beende";
exit;
}
//Handler für neue Daten
if($_POST['eintragen'] === "true"){
$ab = new DateTime($_POST['ab']);
$bis = new DateTime($_POST['bis']);
$typ = $_POST['typ'];
$status = $_POST['status'];
$note = $_POST['note'];
$jahr = $ab->format('Y');
//komplettes jahr holen um urlaub genehmigt zu zählen
$getdata = $dbc->query("select * from kalender where maID = '$maID' and year(datum) = $jahr order by datum, k_id;");
foreach($getdata as $data){
$filtered[$data['datum']] = $data;
}
if($typ == 10){
$genehmigt = 0;
foreach($filtered as $filter){
if($filter['typ'] == 10 && $filter['status'] == 'genehmigt') $genehmigt++;
}
$geturlaub = $dbc->query("select tage from urlaub where maID = '$maID' and jahr = $jahr;");
$anspruch = $geturlaub->fetch_array()[0];
$verbleibend = $anspruch - $genehmigt;
}
if($typ == 9) $lastentry = $filtered[$bis->format('Y-m-d')]['typ'];
//Arbeitszeitmodell des Mitarbeiters abrufen, damit nur an den richtigen Tagen eingetragen wird
$getazm = "select * from az_data_copy
where maID = '$maID' and datum_ab <= '".$bis->format('Y-m-d')."'
order by azdID desc, datum_ab desc;";
$azm = $dbc->query($getazm);
foreach($azm as $az){
$getazt = $dbc->query("select * from az_time where azdID = $az[azdID];");
foreach($getazt as $aztime){
$azt[$aztime['azdID']][$aztime['tag']] = $aztime;
}
}
$diff = $ab->diff($bis); //Differenz zwischen ab und bis in Tagen
$gebucht = 0;
$insert = "insert into kalender (datum, maID, typ, status, note, userid) values ";
$firstinsert = true;
for($i = 0; $i <= $diff->days; $i++){ //Schleife, um SQL Insert aufzubauen
$date = new DateTime($ab->format('Y-m-d'));
$date->modify("+$i days");
$datestr = $date->format('Y-m-d');
$wochentag = $date->format('N');
foreach($azm as $az){ //Das für das aktuell behandelte Datum richtige AZModell benutzen
$az_ab = new DateTime($az['datum_ab']);
if($az_ab <= $date){
break;
}else{
$az = NULL;
}
}
if(isset($azt[$az['azdID']][$wochentag]) && feiertag($date) === false){ //insert string nur weiterbauen, wenn kein arbeitsfreier Tag
$insert .= "('$datestr', '$maID', $typ, '$status', '$note', '$userid'), ";
$gebucht++; //nur gültige Tage zählen
if($firstinsert){ //für Mail den ersten gültigen Tag sichern
$mail_ab = $date;
$firstinsert = false;
}
$mail_bis = $date; //für Mail letzten gültigen Tag sichern
}
}
if($typ == 10 && $status != 'abgelehnt' && $gebucht > $verbleibend){
$rest = abs($verbleibend - $gebucht);
header("Location: buchen.php?datum=$datum&zuwenig=$rest");
exit;
}
$insert = substr($insert, 0, -2);
$insert .= ";";
$dbc->query($insert); //insert ausführen
if($dbc->error){
echo "<span class='red'>Es ist ein Fehler aufgetreten:</span><br>";
echo $dbc->error;
echo "<br>";
exit;
}
//mail bei urlaub und gleittag
$datum = $mail_ab->format('Y-m-d');
if($typ == 10 || $typ == 20 || $typ == 9){ //Mail überhaupt nur verschicken, wenn Zeittyp == Urlaub (10), Gleittag(20) oder storniert(9)
$getag = "select if(gn = maID, userid, NULL) as gn,
if(gnv = maID, userid, NULL) as gnv,
if(pr = maID, userid, NULL) as pr,
if(prv = maID, userid, NULL) as prv
from ag
join mitarbeiter m on m.maID = ag.gn or m.maID = ag.gnv or m.maID = ag.pr or m.maID = ag.prv
where ag.ag_ID = ".$infoarray['agID'].";";
$resultag = $dbc->query($getag); //Rolleninhaber für den beantragenden Nutzer holen (userid, um später Email-Adresse zu bauen)
foreach($resultag as $agrow){
if($agrow['gn'] != NULL){
$ag['gn'] = $agrow['gn'];
}
if($agrow['gnv'] != NULL){
$ag['gnv'] = $agrow['gnv'];
}
if($agrow['pr'] != NULL){
$ag['pr'] = $agrow['pr'];
}
if($agrow['prv'] != NULL){
$ag['prv'] = $agrow['prv'];
}
}
isset($ag['gnv']) ? $gn = $ag['gnv'] : $gn = $ag['gn']; //wenn vertreter gesetzt ist, wird an den geschickt
isset($ag['prv']) ? $pr = $ag['prv'] : $pr = $ag['pr'];
if(!isset($ag['pr'])){ //wenn kein prüfer gesetzt ist, wird an den genhmiger geschickt
isset($ag['gnv']) ? $pr = $ag['gnv'] : $pr = $ag['gn'];
if($status == 'beantragt') $status = 'geprüft'; //wenn kein Prüfer gesetzt ist, können Anträge direkt ohne Prüfung per Email Link genehmigt werden.
}
switch ($status){
case "beantragt":
$empfaenger = $pr."@fhi-berlin.mpg.de";
$empfaengerohne = $infoarray['userid']."@fhi-berlin.mpg.de";
$newstatus = "geprüft";
break;
case "geprüft":
$empfaenger = $gn."@fhi-berlin.mpg.de";
$newstatus = "genehmigt";
break;
case "genehmigt":
$empfaenger = $infoarray['email']."@fhi-berlin.mpg.de";
$empfaengerohne = $infoarray['userid']."@fhi-berlin.mpg.de";
break;
case "abgelehnt":
$empfaengerohne = $infoarray['userid']."@fhi-berlin.mpg.de";
break;
}
//gleichzeitig abwesende MA ermitteln und an Mail anhängen
$getabwesend_str = "select k.maID, datum, concat(nachname, ', ',vorname) as name, zt_bez, status
from kalender k
join mitarbeiter m on k.maID = m.maID
join zeittyp zt on k.typ = zt.zt_ID
where agID = $infoarray[agID]
and datum between '".$mail_ab->format('Y-m-d')."' and '".$mail_bis->format('Y-m-d')."'
and k.maID != $maID
and zt_op != ''
order by datum, k_id asc;";
$getabwesend = $dbc->query($getabwesend_str);
foreach($getabwesend as $ma){
//filtert SQL ausgabe so, dass nur aktuelle werte pro MA und datum übrig bleiben
$abwesend[$ma['datum']][$ma['maID']] = $ma;
}
$abwesenheitsliste = "Zur gleichen Zeit in der AG abwesend:";
foreach($abwesend as $absentdate=>$absent){
//extended
$formatted = new DateTime($absentdate);
$abwesenheitsliste .= "<br><b>".$formatted->format('d.m.Y')."</b> -> <br>";
foreach($absent as $data){
//extended:
$abwesenheitsliste .= $data['name'].": ".$data['zt_bez']." (".$data['status'].")<br>";
//simple:
//$abwesenheitsliste .= $data['name']."<br>";
}
}
if($typ == 10){ //bei Urlaub eine leicht andere Email verschicken
$betreff = "Urlaub $status vom ".$mail_ab->format('d.m.Y')." bis ".$mail_bis->format('d.m.Y');
$nachricht = "<!DOCTYPE html>
<html>
<head>
<style type='text/css'>
*{
font-family: sans-serif;
}
</style>
</head>
<body>
<h3>Urlaub wurde $status:</h3>
<br>
Datum: ".$mail_ab->format('d.m.Y')." - ".$mail_bis->format('d.m.Y')."
<br>
Mitarbeiter: $name
<br>
Bemerkung: \"$note\"
<br><br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&tocal=$datum&status=$newstatus'>direkt bearbeiten / Status $newstatus setzen</a>
<br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&toyearcal=$jahr'>zum Kalender</a>
<br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&toagcal=$datum'>zum AG Kalender</a>
</body>
</html>";
}elseif($typ == 20){
$betreff = "Gleittag $status vom ".$mail_ab->format('d.m.Y')." bis ".$mail_bis->format('d.m.Y');
$nachricht = "<!DOCTYPE html>
<html>
<head>
<style type='text/css'>
*{
font-family: sans-serif;
}
</style>
</head>
<body>
<h3>Gleittag wurde $status:</h3>
<br>
Datum: ".$mail_ab->format('d.m.Y')." - ".$mail_bis->format('d.m.Y')."
<br>
Mitarbeiter: $name
<br>
Bemerkung: \"$note\"
<br><br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&tocal=$datum&status=$newstatus'>direkt bearbeiten / Status $newstatus setzen</a>
<br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&toyearcal=$jahr'>zum Kalender</a>
<br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&toagcal=$datum'>zum AG Kalender</a>
";
}elseif($typ == 9 && ($lastentry == 10 || $lastentry == 20)){ //storniert? -> Nur Email verschicken, wenn es vorher Urlaub oder Gleittag war, Bei Urlaub gehts zusätzlich an die Personalstelle.
if($lastentry == 10){
$last = "Urlaub";
}else{
$last = "Gleittag";
}
$personalstelle = $infoarray['email']."@fhi-berlin.mpg.de, ";
$empfaengerohne = $personalstelle.$infoarray['userid']."@fhi-berlin.mpg.de, ".$gn."@fhi-berlin.mpg.de";
$betreff = "$last storniert vom ".$ab->format('d.m.Y')." bis ".$bis->format('d.m.Y');
$nachricht = "<h3>$last storniert:</h3>
<br>
Datum: ".$mail_ab->format('d.m.Y')." - ".$mail_bis->format('d.m.Y')."
<br>
Mitarbeiter: $name
<br>
Bemerkung: \"$note\"
<br>
<a href='https://".$_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF'])."/index.php?ma=$maID&tocal=$datum'><button>Bearbeiten</button></a>";
}
//UTF-8 und Email (aka Steinzeit Technik) vertragen sich nicht gut
$betreff = '=?UTF-8?B?'.base64_encode($betreff).'?=';
$header = 'From: =?UTF-8?B?'.base64_encode($name).'?= <zeiterfassung@chronos.rz-berlin.mpg.de>' . "\r\n" .
'Reply-To: '.$infoarray['userid'].'@fhi-berlin.mpg.de' . "\r\n" .
'BCC: kirstaedter@fhi-berlin.mpg.de' . "\r\n" .
"MIME-Version: 1.0\r\n" .
"Content-type: text/html; charset=utf-8\r\n" .
'X-Mailer: PHP/' . phpversion();
//nur mailen, wenn betreff nicht leer
//erst mail ohne abwesenheitsliste an beantrager schicken,
//dann zweite mail mit abwesenheitsliste an prüfer oder genehmiger schicken
if($betreff != '=?UTF-8?B??=' && $empfaengerohne){
$nachricht .= "</body></html>";
mail ($empfaengerohne, $betreff, $nachricht, $header);
}
if($betreff != '=?UTF-8?B??=' && $empfaenger){
$nachricht .= "<br><br>" . $abwesenheitsliste . "</body></html>";
mail ($empfaenger, $betreff, $nachricht, $header);
}
}
//weiterleiten, um erneuten POST Submit per F5 zu verhindern.
header("Location: buchen.php?datum=$datum&success=true");
exit;
}
//ENDE Handler für neue Daten
//START der Website
if($_GET['success'] === 'true'){
echo "<h3 class='light-green'>ERFOLGREICH EINGETRAGEN!</h3>";
}
if($_GET['zuwenig']){
echo "<h3 class='red'>FEHLER: KEINE URLAUBSTAGE MEHR ÜBRIG: $_GET[zuwenig] zuviel gebucht.</h3>";
}
//Daten für geklicktes Datum laden
$querydata = "select * from kalender k join zeittyp z on typ = zt_ID where maID = '$maID' and datum = '$datum' order by k_id desc;";
$resultdata = $dbc->query($querydata);
foreach($resultdata as $data){
$alldata[] = $data;
}
//AZModelle laden
$getazm = "select * from az_data_copy
where maID = '$maID' and datum_ab <= '$datum'
order by azdID desc, datum_ab desc;";
$azm = $dbc->query($getazm);
foreach($azm as $az){
$getazt = $dbc->query("select * from az_time where azdID = $az[azdID];");
foreach($getazt as $aztime){
$azt[$aztime['azdID']][$aztime['tag']] = $aztime;
}
}
if(!empty($alldata)){ //Dieser IF befüllt das "bis"-Feld richtig (es soll immer ein kompletter Block dargestellt sein)
$nextdate = new DateTime($datum);
//für eintägige Urlaube / Gleittage ($bis wäre dann leer)
$bis = $nextdate->format('Y-m-d');
do { //Es werden alle kommenden Daten durchlaufen bis typ und Status unterschiedlich zum ab-Datum sind
if(isset($azt[$az['azdID']][$wochentag]) && feiertag($nextdate) === false){ //$ab nur aktualisieren, wenn letzter getesteter tag kein arbeitsfreier tag war
$bis = $nextdate->format('Y-m-d'); //muss vor modify passieren da die schleife prinzipiell eins zu weit läuft
}
$nextdate->modify('+1 day');
$nextdatestr = $nextdate->format('Y-m-d');
$wochentag = $nextdate->format('N');
foreach($azm as $az){
$az_ab = new DateTime($az['datum_ab']);
if($az_ab <= $nextdate){
break;
}else{
$az = NULL;
}
}
$query = "select typ, status from kalender where maID = $maID and datum = '$nextdatestr' order by k_id desc limit 1;";
$res = $dbc->query($query);
$next = $res->fetch_array();
} while (($alldata[0]['typ'] == $next['typ'] && $alldata[0]['status'] == $next['status']) || (!isset($azt[$az['azdID']][$wochentag]) || feiertag($nextdate) === true));
// Es wird solange gelaufen, wie typ und status gleich sind oder der nächste Tag frei ist
}else{
$bis = $datum;
}
//Darstellung
echo "<div id='content'>";
$jahr = substr($datum, 0, 4);
echo "<div id='home'>
<a href='kalender.php?jahr=$jahr'><button><< Kalender</button></a>
<br>
<a href='index.php?ma=".$infoarray['maID']."'><button id='home'><< Menü</button></a>
</div>";
//pattern für firefox der kein input type date kann
$pattern = '(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))';
echo "<form id='centered_form' action='#' method='post'>
<h3>Zeittyp ändern für [ $name ]</h3>
<table>
<tr>
<th class='rechts'>Datum ab:</th>
<td class='links'><input type='date' name='ab' pattern='$pattern' title='YYYY-MM-DD' value='$datum' onchange='check(this)'></td>
</tr>
<tr>
<th class='rechts'>Datum bis:</th>
<td class='links'><input type='date' name='bis' pattern='$pattern' title='YYYY-MM-DD' value='$bis'></td>
</tr>
<tr>
<th class='rechts'>Zeittyp:</th>
<td class='links'>
<select class='select' name='typ' onchange='hidestatus(this)'>"; //hidestatus = lokales javascript
$user = $userarray['maID'];
$getag = $dbc->query("select ag_ID from ag where $user in (gn, gnv) and ag_ID = $infoarray[agID];");
$gn_ag = $getag->fetch_array()[0];
if(!$gn_ag){
$getag = $dbc->query("select ag_ID from ag where $user in (pr, prv) and ag_ID = $infoarray[agID];");
$pr_ag = $getag->fetch_array()[0];
}
$options = "<option disabled selected hidden>bitte wählen...</option>";
if($userarray['admin']){
$query = "select * from zeittyp order by zt_bez asc;";
$res = $dbc->query($query);
foreach($res as $row){ //Typen-Liste aufbauen aus DB
$zt = $row['zt_ID'];
$bez = $row['zt_bez'];
$zt == $alldata[0]['typ'] ? $selected = 'selected' : $selected = ''; //Typ vorauswählen
$options .= "<option value='$zt' $selected>$bez</option>";
}
$allstatus = [
"beantragt",
"geprüft",
"genehmigt",
"abgelehnt"
];
}elseif($gn_ag){
$typen = [
9 => "storniert",
10 => "Urlaub"
];
if($infoarray['gleitzeit']) $typen[20] = "Gleittag";
$allstatus = [
"beantragt",
"geprüft",
"genehmigt",
"abgelehnt"
];
}elseif($pr_ag){
$typen = [
9 => "storniert",
10 => "Urlaub"
];
if($infoarray['gleitzeit']) $typen[20] = "Gleittag";
$allstatus = [
"beantragt",
"geprüft",
"abgelehnt"
];
}else{
$typen = [
9 => "storniert",
10 => "Urlaub"
];
if($infoarray['gleitzeit']) $typen[20] = "Gleittag";
$allstatus = [
"beantragt"
];
}
if($alldata[0]["typ"] == 10 || $alldata[0]["typ"] == 20){
$display = "style='display: table-row;'";
}
foreach($typen as $nr=>$typ){
$nr == $alldata[0]['typ'] ? $selected = "selected" : $selected = "";
$options .= "<option value='$nr' $selected>$typ</option>";
}
echo $options;
isset($_GET['status']) ? $green = "light-green" : $green = ''; //färbt status select grün wenn von mail verändert
echo "</select>
</td>
</tr>
<tr id='status' $display>
<th class='rechts'>Status:</th>
<td class='links'>
<select class='select $green' name='status' onmousedown='this.className=\"select\"'>
<option disabled selected hidden>bitte wählen...</option>";
foreach($allstatus as $status){
($status == $_GET['status'] || $status == $alldata[0]['status']) ? $selected2 = 'selected' : $selected2 = ''; //Status vorauswählen
echo "<option value='$status' $selected2>$status</option>";
}
echo "</select>
</tr>";
echo "<tr>
<th class='rechts'>Bemerkung:</th>
<td class='links'><input type='text' name='note' value='".$alldata[0]['note']."'></td>
</tr>";
echo "<tr>
<th></th>
<td id='knopf'>
<button type='submit' name='eintragen' value='true' onclick='return confirm(\"Sicher?\")'>OK</button>
<button onClick='window.location.reload()'>zurücksetzen</button>
</td>
</tr>
</table>
</form>";
echo "<div id='verlauf'>";
echo "<h3>Alle Einträge</h3>
<table>
<tr>
<th>Typ</th>
<th>Status</th>
<th>Bemerkung</th>
<th>geändert am</th>
<th>geändert durch</th>
</tr>";
foreach ($alldata as $index=>$data){
$farbe = $index == 0 ? "class='yellow'" : $farbe = '';
echo "<tr $farbe>";
echo "<td>".$data['zt_bez']."</td>";
echo "<td>".$data['status']."</td>";
echo "<td>".$data['note']."</td>";
echo "<td>".$data['timestamp']."</td>";
echo "<td>".$data['userid']."</td>";
echo "</tr>";
}
echo "</table>";
echo "</div>";
echo "</div>";
?>
</body>
</html>