diff --git a/cis/private/profile/zeitsperre_resturlaub.php b/cis/private/profile/zeitsperre_resturlaub.php index 6ceaff350..aba828241 100644 --- a/cis/private/profile/zeitsperre_resturlaub.php +++ b/cis/private/profile/zeitsperre_resturlaub.php @@ -45,7 +45,7 @@ $uid = get_uid(); $PHP_SELF = $_SERVER['PHP_SELF']; -$typen_arr = array("Urlaub", "PflegeU", "ZA", "Krank", "DienstF", "DienstV"); +$typen_arr = array("Urlaub", "PflegeU", "ZA", "Krank", "DienstF", "DienstV", "CovidSB", "CovidKS"); if(isset($_GET['type'])) $type=$_GET['type']; @@ -69,8 +69,8 @@ $datum_obj = new datum(); $ma= new mitarbeiter(); // definiert bis zu welchem Datum die Eintragung nicht mehr möglich ist -$zasperre = new zeitaufzeichnung(); -if ($sperrdat = $zasperre->getEintragungGesperrtBisForUser($uid)) +$zaufzeichnung = new zeitaufzeichnung(); +if ($sperrdat = $zaufzeichnung->getEintragungGesperrtBisForUser($uid)) $gesperrt_bis = $sperrdat; else if (defined('CIS_ZEITAUFZEICHNUNG_GESPERRT_BIS') && CIS_ZEITAUFZEICHNUNG_GESPERRT_BIS != '') $gesperrt_bis = CIS_ZEITAUFZEICHNUNG_GESPERRT_BIS; @@ -138,7 +138,15 @@ $( document ).ready(function() rows: 4, }); + $("#vondatum").change( + function() + { + $(".error").text(""); + } + ) + }); + // set holidays function which is configured in beforeShowDay function setHoliDays(date) { for (i = 0; i < holiDays.length; i++) { @@ -302,7 +310,9 @@ function showHideStudeDropDown() || dd.options[dd.selectedIndex].value == 'Urlaub' || dd.options[dd.selectedIndex].value == 'Krank' || dd.options[dd.selectedIndex].value == 'DienstF' - || dd.options[dd.selectedIndex].value == 'DienstV') + || dd.options[dd.selectedIndex].value == 'DienstV' + || dd.options[dd.selectedIndex].value == 'CovidSB' + || dd.options[dd.selectedIndex].value == 'CovidKS') { document.getElementById('vonStd').style.visibility = 'hidden'; document.getElementById('bisStd').style.visibility = 'hidden'; @@ -350,6 +360,40 @@ if(isset($_GET['type']) && ($_GET['type']=='edit_sperre' || $_GET['type']=='new_ $error_msg .= $p->t('zeitsperre/bisDatumUngueltig').' '; } + //Prüfen auf vorhandene Zeitaufzeichnung + if (isset($_POST['bisdatum']) && isset($_POST['vondatum']) + && $zaufzeichnung->existsZeitaufzeichnung($uid, $_POST['vondatum'], $_POST['bisdatum']) + // Nur Zeitaufzeichnungsrelevante Typen sollen das speichern blockieren + && in_array($_POST['zeitsperretyp_kurzbz'], zeitsperre::getBlockierendeZeitsperren())) + { + $error = true; + $error_msg .= $p->t('zeitsperre/zeitaufzeichnungVorhanden'); + } + + //Prüfen auf vorhandene Zeitsperre + if (isset($_POST['bisdatum']) && isset($_POST['vondatum']) + && in_array($_POST['zeitsperretyp_kurzbz'], zeitsperre::getBlockierendeZeitsperren())) + { + $von = $_POST['vondatum']; + $von2 = new DateTime($von); + $von2 = $von2->format('Y-m-d'); + $zeitsperre = new zeitsperre(); + + if ($zeitsperre->getSperreByDate($uid, $von2, null, zeitsperre::NUR_BLOCKIERENDE_ZEITSPERREN)) + { + foreach ($zeitsperre->result as $z) + { + // Beim editieren nicht mit dem eigenen Eintrag kollidieren + if($_GET['type'] == 'edit_sperre' && $z->zeitsperre_id == $_GET['id']) + continue; + + $typ = $z->zeitsperretyp_kurzbz; + $error = true; + $error_msg .= $p->t('zeitsperre/zeitsperreEingetragen', [$von, $typ]); + } + } + } + //von - bis-datum pruefen von darf nicht groesser als bis sein // 09.02.2009 simane $vondatum=0; diff --git a/cis/private/tools/zeitaufzeichnung.php b/cis/private/tools/zeitaufzeichnung.php index 1e91aec20..ba57b442f 100644 --- a/cis/private/tools/zeitaufzeichnung.php +++ b/cis/private/tools/zeitaufzeichnung.php @@ -1,5 +1,5 @@ getBerechtigungen($user); +$mas = new mitarbeiter(); +$mas->getUntergebene($user, true); +$untergebenen_arr = array(); +$untergebenen_arr = $mas->untergebene; +$adminView = false; + //Wenn User Administrator ist und UID uebergeben wurde, dann die Zeitaufzeichnung //des uebergebenen Users anzeigen if(isset($_GET['uid'])) { - if($rechte->isBerechtigt('admin') || $rechte->isBerechtigt('mitarbeiter/urlaube', null, 'suid')) + if ($rechte->isBerechtigt('admin') || $rechte->isBerechtigt('mitarbeiter/urlaube', null, 'suid') || + (in_array($_GET['uid'], $untergebenen_arr))) { $user = $_GET['uid']; $rechte = new benutzerberechtigung(); $rechte->getBerechtigungen($user); $passuid = true; + $adminView = true; } else { @@ -116,8 +125,6 @@ else $gesperrt_bis = '2015-08-31'; $sperrdatum = date('c', strtotime($gesperrt_bis)); -$datumjetzt = strtotime("+5 weeks"); -$limitdatum = date('c', $datumjetzt); // Uses urlencode to avoid XSS issues $zeitaufzeichnung_id = urlencode(isset($_GET['zeitaufzeichnung_id'])?$_GET['zeitaufzeichnung_id']:''); @@ -174,7 +181,7 @@ if(isset($_POST['export'])) } //CSV export für Übersicht zugeteilter Projekte - Konflikt mit normalen HTML headern deshalb weiter vorne -if(isset($_POST['projektübersichtexport'])) +if(isset($_GET['projektübersichtexport'])) { exportProjectOverviewAsCSV($user, ','); } @@ -291,11 +298,13 @@ echo ' { var uid = $("#uidpass").val(); var Datum = $(this).val(); + $("#triggerPhasenReset").text(""); Tag=Datum.substring(0,2); Monat=Datum.substring(3,5); Jahr=Datum.substring(6,10); var day = Jahr + "-" + Monat + "-" + Tag; checkBisverwendung(day,uid); + checkZeitsperre(day,uid); } ) @@ -347,6 +356,7 @@ echo ' document.getElementById("von_datum").value=ret_datum; document.getElementById("von_uhrzeit").value=ret_uhrzeit; + $("#von_datum").trigger("change"); } function foo(val) @@ -454,6 +464,7 @@ echo ' { document.getElementById("von_datum").value=document.getElementById("bis_datum").value; document.getElementById("von_uhrzeit").value=document.getElementById("bis_uhrzeit").value; + $("#von_datum").trigger("change"); } function checkdatum() @@ -642,7 +653,6 @@ echo ' } projphasenhtml += "<\/option>"; } - $("#projektphase").append(projphasenhtml); $("#projektphaseformgroup").show(); } @@ -747,6 +757,7 @@ echo ' Jahr=Datum.substring(6,10); var checkedDay = Jahr + "-" + Monat + "-" + Tag; checkBisverwendung(checkedDay, uid); + checkZeitsperre(checkedDay, uid); } function checkBisverwendung(day, uid) @@ -766,17 +777,51 @@ echo ' else { $("#homeofficeBlock").hide(); - } } }); } + function checkZeitsperre(day, uid) + { + $.ajax + ({ + type: "GET", + url: "zeitaufzeichnung_zeitsperren.php", + dataType: "json", + data: + { + day: day, + uid: uid + }, + success: function (json) + { + var output = ""; + if (json.length > 0) + { + output = "' . $p->t("zeitaufzeichnung/zeitsperreVorhanden", ['{day}', '{typ}']) . '"; + output = output.replace(\'{day}\', json[0].day); + output = output.replace(\'{typ}\', json[0].typ); + $("#errZeitsperren").show(); + $("#buttonSave").prop("disabled",true); + } + else + { + $("#errZeitsperren").hide(); + $("#buttonSave").prop("disabled",false); + output = ""; + } + $("#outputZeitsperren").html(output); + } + }); + } +
'; + echo ''.$p->t("global/fehlerBeimSpeichernDerDaten").': - Eingabe nicht möglich, da angegebenes Anfangs und Enddatum nicht in den Projektphasenzeitrahmen fällt.
| - ".$p->t("zeitaufzeichnung/neu")." | + ".$p->t("zeitaufzeichnung/neu")." | "; - CSV Import | + if (!$adminView) + { + echo + " + CSV Import | - CSV Export | + CSV Export | + "; + } - Projektübersichtexport"; + echo " Projektübersichtexport"; if($anzprojekte > 0) echo " | ".$p->t("zeitaufzeichnung/projektexport").""; echo " | @@ -1291,13 +1004,32 @@ if ($projekt->getProjekteMitarbeiter($user, true)) } echo ''; echo $p->t("zeitaufzeichnung/supportAnfragen"); - echo ' -
| ';
echo ' ' . "\n"; + } + return $html; + } + + /** + * @return string + */ + public function WarningsToHTML() { + $html = ''; + foreach ($this->warnings as $msg) { + $html .= '' . $msg . ' ' . "\n"; + } + return $html; + } + + /** + * @return string + */ + public function InfosToHTML() { + $html = ''; + foreach ($this->infos as $msg) { + $html .= '' . $msg . ' ' . "\n"; + } + return $html; + } + + /** + * @return string + */ + public function OutputToHTML() { + return $this->InfosToHTML() . $this->WarningsToHTML() . $this->ErrorsToHTML(); + } + + /** + * @param string $msg + * @return void + */ + protected function addError($msg) { + $this->errors[] = $msg; + } + + /** + * @param string $msg + * @return void + */ + protected function addWarning($msg) { + $this->warnings[] = $msg; + } + + /** + * @param string $msg + * @return void + */ + protected function addInfo($msg) { + $this->infos[] = $msg; + } + + + /** + * @param string $uid The user id + * @param string $day "Y-m-d" formatted datestring + * @return void + * + * @throws Exception + */ + protected function checkZeitsperren($uid, $day) { + $zs = new zeitsperre(); + + if (!$zs->getSperreByDate($uid, $day, null, zeitsperre::NUR_BLOCKIERENDE_ZEITSPERREN)) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ": Fehler beim Überprüfen der Zeitsperren"); + } + + if (count($zs->result) !== 0) { + $zsdate = new DateTime($day); + $zsdate = $zsdate->format('d.m.Y'); + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ": " . $this->p->t("zeitaufzeichnung/zeitsperreVorhanden", [$zsdate, $zs->result[0]->zeitsperretyp_kurzbz])); + } + } + + /** + * @param string $date datetimestring + * @return void + * + * @throws Exception + */ + protected function checkLimitdatum($date) { + if ($this->datum->formatDatum($date, 'Y-m-d H:i:s') > $this->limitdate) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': Eingabe nicht möglich da (' . $date . ') zu weit in der Zukunft liegt.'); + } + } + + /** + * @param string $start datestring + * @param string $end datestring + * @param string $aktivitaet_kurzbz + * @return void + * + * @throws Exception + */ + protected function checkDienstreise($start, $end, $aktivitaet_kurzbz) { + $startDate = $this->datum->formatDatum($start, 'Y-m-d'); + $endDate = $this->datum->formatDatum($end, 'Y-m-d'); + if ($startDate != $endDate && $aktivitaet_kurzbz != "DienstreiseMT") { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") + .': Eingabe nicht möglich, da keine Zeitaufzeichnung über mehrere Tage erlaubt ist (ausgenommen Dienstreisen).'); + } + } + + /** + * @param string $end timestring + * @return void + * + * @throws Exception + */ + protected function checkTagesgenau($end) { + $endTime = $this->datum->formatDatum($end, 'H:i:s'); + if ($endTime == '00:00:00') { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") + .': Bitte Arbeitszeiten gemäß Arbeitsaufzeichnung Leitfaden tagesgenau abgrenzen: Nur Eingaben von 00:00 bis 23:59 erlaubt!'); + } + } + + /** + * @param string $projekt_kurzbz + * @param string $start datestring + * @param string $end datestring + * @return void + * + * @throws Exception + */ + protected function checkProjectInterval($projekt_kurzbz, $start, $end) { + if (!$this->project->checkProjectInCorrectTime($projekt_kurzbz, $start, $end)) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': Eingabe nicht möglich, da angegebenes Anfangs und Enddatum nicht in den Projektzeitrahmen fällt: (' . $start . ') (' . $end . ')'); + } + } + + /** + * @param string $phase The Projektphase ID + * @param string $start datestring + * @param string $end datestring + * @return void + * + * @throws Exception + */ + protected function checkPhaseInterval($phase, $start, $end) { + if (!$this->phase->checkProjectphaseInCorrectTime($phase, $start, $end)) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': Eingabe nicht möglich, da angegebenes Anfangs und Enddatum nicht in den Projektphasenzeitrahmen fällt: (' . $start . ') (' . $end . ')'); + } + } + +} diff --git a/include/zeitaufzeichnung_import_csv.class.php b/include/zeitaufzeichnung_import_csv.class.php new file mode 100644 index 000000000..27a240e45 --- /dev/null +++ b/include/zeitaufzeichnung_import_csv.class.php @@ -0,0 +1,435 @@ +user = $user; + $this->tmpname = $filename; + $this->sperrdatum = $sperrdatum; + + $this->project_kurzbz_array = []; + $projects = $this->project->getProjekteListForMitarbeiter($user); + foreach ($projects as $pp) + $this->project_kurzbz_array[] = (string) $pp->projekt_kurzbz; + + $this->projectphasen_kurzbz_array = []; + $projektphasen = $this->phase->getProjectphaseForMitarbeiter($user); + foreach ($projektphasen as $pp) + $this->projectphasen_kurzbz_array[] = (string) $pp->projektphase_id; + } + + + /** + * @param string $msg + * @param boolean $prepend_current_line + * @return void + */ + protected function addError($msg, $prepend_current_line = false) { + if( $prepend_current_line ) { + $msg = 'Zeile ' . $this->current_line . ' - ' . $msg; + } + $this->errors[] = $msg; + } + + + /** + * @return void + */ + public function import() { + try { + $this->checkMimeType(); + $this->openFileForReading(); + $this->checkEncoding(); + $this->iterateRows(); + $this->checkAndCleanup(); + } catch (Exception $ex) { + $this->addError($ex->getMessage()); + } + } + + + /** + * @return void + * + * @throws Exception + */ + protected function checkMimeType() { + $mimeType = mime_content_type($this->tmpname); + if ($mimeType !== 'text/plain' ) { + throw new Exception('Datei ist nicht im CSV Format.'); + } + } + + /** + * @return void + * + * @throws Exception + */ + protected function openFileForReading() { + if (false === ($this->fh = fopen($this->tmpname, 'r')) ) + { + throw new Exception('CSV - Datei konnte nicht zum lesen geöffnet werden.'); + } + } + + /** + * @return void + * + * @throws Exception + */ + protected function checkEncoding() { + $filecontent = file_get_contents($this->tmpname); + if (!mb_detect_encoding($filecontent, 'UTF-8', true) ) { + throw new Exception('Datei konnte nicht importiert werden. Encoding ist nicht UTF-8!'); + } + } + + /** + * @return void + */ + protected function iterateRows() { + set_time_limit(0); + + $this->anzahl = 0; + $this->importtage_array = array(); + $this->ende_vorher = date('Y-m-d H:i:s'); + + $data = null; + $this->current_line = 0; + while (($data = fgetcsv($this->fh, 1000, ';', '"')) !== FALSE) { + if ((false !== strpos($data[self::USER], '#')) + || count($data) < self::ANZAHL_PFLICHTFELDER) { + // ignore lines starting with # + continue; + } + $this->current_line++; + $this->processData($data); + } + } + + /** + * @param array $data + * @return void + */ + protected function processData($data) { + try { + $this->checkUser($data[self::USER]); + $this->initData($data); + $this->checkProject($data[self::PROJEKT], $data[self::PHASE]); + $this->checkPhase($data[self::PHASE]); + + $this->checkZeitsperren($this->user, $this->datum->formatDatum($data[self::STARTDT], 'Y-m-d')); + $this->checkSperrdatum($data[self::STARTDT]); + $this->checkLimitdatum($data[self::STARTDT]); + $this->checkDienstreise($data[self::STARTDT], $data[self::ENDEDT], $data[self::AKTIVITAET]); + $this->checkTagesgenau($data[self::ENDEDT]); + if(empty($data[self::PHASE])) + $this->checkProjectInterval($data[self::PROJEKT], $data[self::STARTDT], $data[self::ENDEDT]); + $this->checkPhaseInterval($data[self::PHASE], $data[self::STARTDT], $data[self::ENDEDT]); + $this->checkVals($data[self::OE],$data[self::PROJEKT],$data[self::PHASE],$data[self::SERVICE]); + $this->mapLehreIntern($data); + $this->prepareZeitaufzeichnung($data); + $this->checkImporttage($data[self::STARTDT]); + $this->saveZeit($data[self::STARTDT], $data[self::ENDEDT]); + } catch (Exception $ex) { + $this->addError($ex->getMessage(), true); + } + } + + /** + * @param string $user The User ID + * @return void + * + * @throws Exception + */ + protected function checkUser($user) { + if ($user !== $this->user || (strpos($user, '#') !== false)) + { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten").': Falsche UID nicht importiert (' . $user . ')'); + } + } + + /** + * @param string $project The Project ID or empty string + * @param string $phase The Phase ID or empty string + * @return void + * + * @throws Exception + */ + protected function checkProject($project, $phase) { + if(!empty($project) && !in_array($project, $this->project_kurzbz_array) && empty($phase)) + { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten").': Eingabe nicht möglich, da Sie folgendem Projekt entweder nicht zugewiesen sind oder das Projekt schon abgeschlossen wurde: (' . $project . ')'); + } + + } + + /** + * @param string $phase The Phase ID or empty string + * @return void + * + * @throws Exception + */ + protected function checkPhase($phase) { + if(!empty($phase) && !in_array($phase, $this->projectphasen_kurzbz_array)) + { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten").': Eingabe nicht möglich, da Sie folgender Projektphase entweder nicht zugewiesen sind oder die Projektphase schon abgeschlossen wurde: (' . $phase . ')'); + } + } + + /** + * @param array $data + * @return void + */ + protected function initData(&$data) { + foreach ([self::OE, self::PROJEKT, self::PHASE, self::SERVICE] as $key) + if (!isset($data[$key])) + $data[$key] = NULL; + + if (!isset($data[self::HOMEOFFICE])) + $data[$key] = false; + } + + /** + * @param string $start datetimestring + * @return void + * + * @throws Exception + */ + protected function checkSperrdatum($start) { + if ($this->datum->formatDatum($start, 'Y-m-d H:i:s') < $this->sperrdatum) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': Eingabe nicht möglich da vor dem Sperrdatum (' . $start . ')'); + } + + } + + /** + * @param string $oe_val + * @param string $project_val + * @param string $phase_val + * @param string $service_val + * @return void + * + * @throws Exception + */ + protected function checkVals($oe_val, $project_val, $phase_val, $service_val) { + $failedvals = $this->_checkVals($oe_val, $project_val, $phase_val, $service_val); + if( count($failedvals) > 0 ) + { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten").': Fehlerhafte Werte ('.implode(', ', $failedvals).')'); + } + } + + /** + * @param string $oe_val + * @param string $project_val + * @param string $phase_val + * @param string $service_val + * @return array + */ + protected function _checkVals ($oe_val, $project_val, $phase_val, $service_val) { + $error = []; + if ($service_val && ( filter_var($service_val, FILTER_VALIDATE_INT) === false )) { + $error[] = 'service'; + } + if ($phase_val && ( filter_var($phase_val, FILTER_VALIDATE_INT) === false )) { + $error[] = 'phase'; + } + if ($oe_val) { + $oecheck = new organisationseinheit($oe_val); + if ($oecheck->errormsg) { + $error[] = 'OE'; + } + } + if ($project_val) { + $procheck = new projekt($project_val); + if ($procheck->errormsg) { + $error[] = 'projekt'; + } + } + return $error; + } + + /** + * @param array $data + * @return void + */ + protected function mapLehreIntern(&$data) { + if ($data[self::AKTIVITAET] == 'LehreIntern') { + $data[self::AKTIVITAET] = 'Lehre'; + } + } + + /** + * @param array $data + * @return void + */ + protected function prepareZeitaufzeichnung($data) { + $this->zeit->new = true; + $this->zeit->beschreibung = NULL; + $this->zeit->oe_kurzbz_1 = NULL; + $this->zeit->projekt_kurzbz = NULL; + $this->zeit->projektphase_id = NULL; + $this->zeit->service_id = NULL; + + $this->zeit->insertamum = date('Y-m-d H:i:s'); + $this->zeit->updateamum = date('Y-m-d H:i:s'); + $this->zeit->updatevon = $this->user; + $this->zeit->insertvon = $this->user; + $this->zeit->uid = $data[self::USER]; + $this->zeit->aktivitaet_kurzbz = $data[self::AKTIVITAET]; + $this->zeit->start = $this->datum->formatDatum($data[self::STARTDT], 'Y-m-d H:i:s'); + $this->zeit->ende = $this->datum->formatDatum($data[self::ENDEDT], 'Y-m-d H:i:s'); + if (isset($data[self::BESCHREIBUNG])) { + $this->zeit->beschreibung = $data[self::BESCHREIBUNG]; + } + if (isset($data[self::OE])) { + $this->zeit->oe_kurzbz_1 = $data[self::OE]; + } + if (isset($data[self::PROJEKT])) { + $this->zeit->projekt_kurzbz = $data[self::PROJEKT]; + } + if (isset($data[self::PHASE])) { + $this->zeit->projektphase_id = $data[self::PHASE]; + } + if (isset($data[self::SERVICE])) { + $this->zeit->service_id = $data[self::SERVICE]; + } + $this->zeit->homeoffice = false; + if (isset($data[self::HOMEOFFICE])) { + $this->zeit->homeoffice = (strtolower($data[self::HOMEOFFICE]) == 'true'); + if (strtolower($data[self::HOMEOFFICE]) == 'true') { + // check, ob homeoffice gemäß Bisverwendung + $vonCSV = $this->datum->formatDatum($data[self::STARTDT], 'Y-m-d'); + $verwendung = new bisverwendung(); + $verwendung->getVerwendungDatum($data[self::USER], $vonCSV); + + foreach ($verwendung->result as $v) { + if ($v->homeoffice) { + $this->zeit->homeoffice = true; + } else { + $this->addWarning($this->p->t("zeitaufzeichnung/homeofficeNichtErlaubt", [$vonCSV])); + $this->zeit->homeoffice = false; + } + } + } + } + } + + /** + * @param string $start datestring + * @return void + * + * @throws Exception + */ + protected function checkImporttage($start) { + $tag = $this->datum->formatDatum($start, 'Y-m-d'); + + if (!in_array($tag, $this->importtage_array)) { + $this->importtage_array[] = $tag; + $this->zeit->deleteEntriesForUser($this->user, $tag); + } else if ($this->ende_vorher < $this->zeit->start) { + $this->savePause(); + } + + $this->ende_vorher = $this->zeit->ende; + } + + /** + * @return void + */ + protected function savePause() { + $pause = new zeitaufzeichnung(); + $pause->new = true; + $pause->insertamum = date('Y-m-d H:i:s'); + $pause->updateamum = date('Y-m-d H:i:s'); + $pause->updatevon = $this->user; + $pause->insertvon = $this->user; + $pause->uid = $this->user; + $pause->aktivitaet_kurzbz = 'Pause'; + $pause->start = $this->ende_vorher; + $pause->ende = $this->zeit->start; + $pause->beschreibung = ''; + $pause->homeoffice = $this->zeit->homeoffice; + if(!$pause->save()) + { + $this->addError($this->p->t("global/fehlerBeimSpeichernDerDaten").': '.$pause->errormsg, true); + } + } + + /** + * @param string $start datetimestring + * @param string $end datetimestring + * @return void + */ + protected function saveZeit($start, $end) { + if ($start != $end) { + if (!$this->zeit->save()) { + $this->addError($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': ' . $this->zeit->errormsg . '(' . $this->zeit->start . ')', true); + } else { + $this->anzahl++; + } + } else { + $this->anzahl++; + } + } + + /** + * @return void + */ + protected function checkAndCleanup() { + if ($this->anzahl > 0) { + $this->addInfo($this->p->t("global/datenWurdenGespeichert") . ' (' . $this->anzahl . ')'); + foreach ($this->importtage_array as $ptag) { + $this->zeit->cleanPausenForUser($this->user, $ptag); + } + } + } + +} diff --git a/include/zeitaufzeichnung_import_post.class.php b/include/zeitaufzeichnung_import_post.class.php new file mode 100644 index 000000000..dc6381ecb --- /dev/null +++ b/include/zeitaufzeichnung_import_post.class.php @@ -0,0 +1,222 @@ +user = $user; + $this->edit = $edit; + $this->data = $data; + } + + + /** + * @return string + */ + public function ErrorsToHTML() { + $html = ''; + foreach ($this->errors as $msg) { + $html .= '' . $msg . ' ' . "\n"; + } + return $html; + } + + + /** + * @return void + */ + public function import() { + try { + $this->checkNew($this->data['zeitaufzeichnung_id']); + $this->prepareZeitaufzeichnung($this->data['aktivitaet_kurzbz'], $this->data['von'], $this->data['bis'], $this->data['beschreibung'], $this->data['oe_kurzbz_1'], $this->data['oe_kurzbz_2'], $this->data['projekt_kurzbz'], $this->data['projektphase_id'], $this->data['homeoffice'], $this->data['service_id'], $this->data['kunde_uid']); + $this->checkZeitsperren($this->user, $this->datum->formatDatum($this->data['von'], 'Y-m-d')); + $this->checkProjectInterval($this->data['projekt_kurzbz'], $this->data['von'], $this->data['bis']); + $this->checkLimitdatum($this->data['von']); + $this->checkLimitdatum($this->data['bis']); + $this->checkPhaseInterval($this->data['projektphase_id'], $this->data['von'], $this->data['bis']); + $this->checkDienstreise($this->data['von'], $this->data['bis'], $this->data['aktivitaet_kurzbz']); + $this->checkTagesgenau($this->data['bis']); + $this->processPause($this->data['von_pause'], $this->data['bis_pause']); + $this->saveZeit(); + } catch (Exception $ex) { + $this->addError($ex->getMessage()); + } + } + + /** + * @param string $zeitaufzeichnung_id + * @return void + */ + protected function checkNew($zeitaufzeichnung_id) { + if($this->edit) { + if(!$this->zeit->load($zeitaufzeichnung_id)) + die($this->p->t("global/fehlerBeimLadenDesDatensatzes")); + + $this->zeit->new = false; + } else { + $this->zeit->new = true; + $this->zeit->insertamum = date('Y-m-d H:i:s'); + $this->zeit->insertvon = $this->user; + } + } + + /** + * @param string $aktivitaet_kurzbz + * @param string $von datetime + * @param string $bis datetime + * @param string $beschreibung + * @param string $oe_kurzbz_1 + * @param string $oe_kurzbz_2 + * @param string $projekt_kurzbz + * @param string $projektphase_id + * @param boolean $homeoffice + * @param string $service_id + * @param string $kunde_uid + * @return void + */ + protected function prepareZeitaufzeichnung($aktivitaet_kurzbz, $von, $bis, $beschreibung, $oe_kurzbz_1, $oe_kurzbz_2, $projekt_kurzbz, $projektphase_id, $homeoffice, $service_id, $kunde_uid) { + $this->zeit->uid = $this->user; + $this->zeit->aktivitaet_kurzbz = $aktivitaet_kurzbz; + $this->zeit->start = $this->datum->formatDatum($von, 'Y-m-d H:i:s'); + $this->zeit->ende = $this->datum->formatDatum($bis, 'Y-m-d H:i:s'); + $this->zeit->beschreibung = $beschreibung; + $this->zeit->oe_kurzbz_1 = $oe_kurzbz_1; + $this->zeit->oe_kurzbz_2 = $oe_kurzbz_2; + $this->zeit->updateamum = date('Y-m-d H:i:s'); + $this->zeit->updatevon = $this->user; + $this->zeit->projekt_kurzbz = $projekt_kurzbz; + $this->zeit->projektphase_id = $projektphase_id; + $this->zeit->homeoffice = $homeoffice; + $this->zeit->service_id = $service_id; + $this->zeit->kunde_uid = $kunde_uid; + } + + /** + * @param string $start datetime + * @param string $end datetime + * @return void + */ + protected function processPause($start, $end) { + if (isset($_POST['genPause'])) { + $p_start = $this->datum->formatDatum($start, 'Y-m-d H:i:s'); + $p_end = $this->datum->formatDatum($end, 'Y-m-d H:i:s'); + $this->checkPauseInArbeitszeit($p_start, $p_end); + $this->checkPauseValid($p_start, $p_end); + $this->savePause($start, $end); + } + } + + /** + * @param string $start "Y-m-d H:i:s" formatted datetime + * @param string $end "Y-m-d H:i:s" formatted datetime + * @return void + * + * @throws Exception + */ + protected function checkPauseInArbeitszeit($start, $end) { + if ($this->zeit->start > $start || $this->zeit->ende < $end) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': Pause außerhalb der Arbeitszeit'); + } + } + + /** + * @param string $start "Y-m-d H:i:s" formatted datetime + * @param string $end "Y-m-d H:i:s" formatted datetime + * @return void + * + * @throws Exception + */ + protected function checkPauseValid($start, $end) { + if ($start > $end) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': Fehlerhafte Pausenzeiten'); + } + } + + /** + * @param string $start datetime + * @param string $end datetime + * @return void + */ + protected function savePause($start, $end) { + //Eintrag Arbeit bis zur Pause + $ende = $this->zeit->ende; + $this->zeit->ende = $this->datum->formatDatum($start, 'Y-m-d H:i:s'); + if (!$this->zeit->save()) { + $this->addError($p->t("global/fehlerBeimSpeichernDerDaten") . ': ' . $this->zeit->errormsg); + } + //Eintrag für die Pause + $pause = new zeitaufzeichnung(); + $pause->new = true; + $pause->insertamum = date('Y-m-d H:i:s'); + $pause->updateamum = date('Y-m-d H:i:s'); + $pause->updatevon = $this->user; + $pause->insertvon = $this->user; + $pause->uid = $this->user; + $pause->aktivitaet_kurzbz = 'Pause'; + $pause->homeoffice = $this->zeit->homeoffice; + $pause->start = $this->datum->formatDatum($start, 'Y-m-d H:i:s'); + $pause->ende = $this->datum->formatDatum($end, 'Y-m-d H:i:s'); + $pause->beschreibung = ''; + if (!$pause->save()) { + $this->addError($p->t("global/fehlerBeimSpeichernDerDaten") . ': ' . $pause->errormsg); + } + // Eintrag Arbeit ab der Pause + if ($this->zeit->new == false) { + $this->zeit->new = true; + $this->zeit->insertamum = date('Y-m-d H:i:s'); + $this->zeit->insertvon = $this->user; + } + + $this->zeit->start = $this->datum->formatDatum($end, 'Y-m-d H:i:s'); + $this->zeit->ende = $ende; + } + + /** + * @return void + * + * @throws Exception + */ + protected function saveZeit() { + if (!$this->zeit->save()) { + throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ': ' . $this->zeit->errormsg); + } else if (!$this->hasErrors()) { + $this->addInfo($this->p->t("global/datenWurdenGespeichert")); + } + } + +} diff --git a/include/zeitsperre.class.php b/include/zeitsperre.class.php index 681916c26..57d2ba09a 100644 --- a/include/zeitsperre.class.php +++ b/include/zeitsperre.class.php @@ -23,6 +23,9 @@ require_once(dirname(__FILE__).'/basis_db.class.php'); class zeitsperre extends basis_db { + const NUR_BLOCKIERENDE_ZEITSPERREN = true; + const BLOCKIERENDE_ZEITSPERREN = "'Krank','Urlaub','ZA','DienstV','PflegeU','DienstF','CovidSB','CovidKS'"; + public $new; // boolean public $result = array(); // news Objekt @@ -57,6 +60,11 @@ class zeitsperre extends basis_db $this->load($zeitsperre_id); } + public static function getBlockierendeZeitsperren() + { + return explode("','",trim(self::BLOCKIERENDE_ZEITSPERREN, '\'')); + } + /** * Laedt alle Zeitsperren eines Benutzers wo ende>=now() ist * @param $uid @@ -368,11 +376,13 @@ class zeitsperre extends basis_db * * @param $user * @param $datum - * @param $stunde + * @param $stunde optional, wird nur abgefragt, wenn != null + * @param $nurblockierend boolean default false * @return true wenn ok, false im Fehlerfall */ - public function getSperreByDate($user, $datum, $stunde) + public function getSperreByDate($user, $datum, $stunde=null, $nurblockierend=false) { + $this->result = array(); $qry = " SELECT * @@ -380,16 +390,23 @@ class zeitsperre extends basis_db campus.tbl_zeitsperre WHERE vondatum<=".$this->db_add_param($datum)." - AND bisdatum>=".$this->db_add_param($datum)." AND - ((vondatum=".$this->db_add_param($datum)." AND vonstunde<=".$this->db_add_param($stunde).") OR vonstunde is null OR vondatum<>".$this->db_add_param($datum).") AND - ((bisdatum=".$this->db_add_param($datum)." AND bisstunde>=".$this->db_add_param($stunde).") OR bisstunde is null OR bisdatum<>".$this->db_add_param($datum).") AND - mitarbeiter_uid=".$this->db_add_param($user); + AND bisdatum>=".$this->db_add_param($datum); + + if( $nurblockierend ) { + $qry .= " AND zeitsperretyp_kurzbz in (" . self::BLOCKIERENDE_ZEITSPERREN . ")"; + } + + if(!is_null($stunde)) + $qry.=" AND + ((vondatum=".$this->db_add_param($datum)." AND vonstunde<=".$this->db_add_param($stunde).") OR vonstunde is null OR vondatum<>".$this->db_add_param($datum).") AND + ((bisdatum=".$this->db_add_param($datum)." AND bisstunde>=".$this->db_add_param($stunde).") OR bisstunde is null OR bisdatum<>".$this->db_add_param($datum).")"; + + $qry .= "AND mitarbeiter_uid=".$this->db_add_param($user); if($result = $this->db_query($qry)) { while($row = $this->db_fetch_object($result)) { - $obj = new zeitsperre(); $obj->zeitsperre_id = $row->zeitsperre_id; @@ -482,7 +499,7 @@ class zeitsperre extends basis_db $qry = "select datum::date, freigabevon, zeitsperretyp_kurzbz from (SELECT generate_series(vondatum::timestamp, bisdatum::timestamp, '1 day') as datum, freigabevon, mitarbeiter_uid, zeitsperretyp_kurzbz FROM campus.tbl_zeitsperre where vonstunde is null and bisstunde is null) a - where a.mitarbeiter_uid = ".$this->db_add_param($uid)." and datum>(now() - interval '".$anz_tage." Days') and zeitsperretyp_kurzbz in ('Krank','Urlaub', 'ZA', 'DienstV','PflegeU', 'DienstF','CovidSB','CovidKS')"; + where a.mitarbeiter_uid = ".$this->db_add_param($uid)." and datum>(now() - interval '".$anz_tage." Days') and zeitsperretyp_kurzbz in (" . self::BLOCKIERENDE_ZEITSPERREN . ")"; diff --git a/locale/de-AT/zeitaufzeichnung.php b/locale/de-AT/zeitaufzeichnung.php index ad9a4de0c..8e9969856 100644 --- a/locale/de-AT/zeitaufzeichnung.php +++ b/locale/de-AT/zeitaufzeichnung.php @@ -65,3 +65,5 @@ $this->phrasen['zeitaufzeichnung/pauseEinfuegen']='Pause automatisch einfügen'; $this->phrasen['zeitaufzeichnung/zeitraumZuKurz']='Zeitraum zu kurz für automatische Pause'; $this->phrasen['zeitaufzeichnung/supportAnfragen']=' Supportanfragen unter zeiterfassung@technikum-wien.at'; $this->phrasen['zeitaufzeichnung/homeofficeNichtErlaubt']='Homeoffice für den Tag %s nicht erlaubt'; +$this->phrasen['zeitaufzeichnung/zeitsperreVorhanden']='Achtung: Für den Tag %s existiert eine ganztägige Zeitsperre vom Typ %s!'; +$this->phrasen['zeitaufzeichnung/zeitsperreVorhanden1']='Für diesen Tag ist bereits eine ganztägige Zeitsperre eingetragen!'; diff --git a/locale/de-AT/zeitsperre.php b/locale/de-AT/zeitsperre.php index 06476e33d..463c092cf 100644 --- a/locale/de-AT/zeitsperre.php +++ b/locale/de-AT/zeitsperre.php @@ -44,4 +44,7 @@ $this->phrasen['zeitsperre/legendeDurchwahl']='(123)...Durchwahl'; $this->phrasen['zeitsperre/vertretungNichtKorrekt']='Die angegebene Vertretung kann nicht gefunden werden. Bitte prüfen Sie die Vertretung und versuchen Sie es erneut.'; $this->phrasen['zeitsperre/vorSperrdatum']='Datum liegt vor dem Sperrdatum der Zeitliste'; $this->phrasen['zeitsperre/abwesend']='Abwesend'; +$this->phrasen['zeitsperre/zeitaufzeichnungVorhanden']='Es existiert mindestens eine Zeitaufzeichnung im angegebenen Zeitraum.'; +$this->phrasen['zeitsperre/zeitsperreEingetragen']='Für den %s existiert bereits eine Zeitsperre vom Typ %s. + Bitte löschen Sie diese bevor Sie eine neue für diesen Tag eintragen!'; ?> diff --git a/locale/en-US/zeitaufzeichnung.php b/locale/en-US/zeitaufzeichnung.php index 9e0b84ec1..9b06303d4 100644 --- a/locale/en-US/zeitaufzeichnung.php +++ b/locale/en-US/zeitaufzeichnung.php @@ -65,3 +65,4 @@ $this->phrasen['zeitaufzeichnung/pauseEinfuegen']='insert break automatically'; $this->phrasen['zeitaufzeichnung/zeitraumZuKurz']='Timeslot too short for automatic break.'; $this->phrasen['zeitaufzeichnung/supportAnfragen']=' Contact for support zeiterfassung@technikum-wien.at'; $this->phrasen['zeitaufzeichnung/homeofficeNichtErlaubt']='Homeoffice for day %s not allowed'; +$this->phrasen['zeitaufzeichnung/zeitsperreVorhanden']=' Please note: There is a timeout for the day %s: %s! '; diff --git a/locale/en-US/zeitsperre.php b/locale/en-US/zeitsperre.php index 43909358e..44123529f 100644 --- a/locale/en-US/zeitsperre.php +++ b/locale/en-US/zeitsperre.php @@ -44,4 +44,7 @@ $this->phrasen['zeitsperre/legendeDurchwahl']='(123)...Extension'; $this->phrasen['zeitsperre/vertretungNichtKorrekt']='The selected substitute is invalid. Please check the substitute an try again.'; $this->phrasen['zeitsperre/vorSperrdatum']='Date is before last open timesheet date'; $this->phrasen['zeitsperre/abwesend']='absent'; +$this->phrasen['zeitsperre/zeitaufzeichnungVorhanden']='It exists at least one time record in the specified period.'; +$this->phrasen['zeitsperre/zeitsperreEingetragen']='There already exists an unavailability on the %s of the type %s. + Please delete the existing before creating a new one for this date!'; ?> |