From 091fd3487f3b78b91bee32949d51e5bdfccfb62b Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 3 Mar 2022 15:59:16 +0100 Subject: [PATCH] refactoring: zeitaufzeichnung_import & zeitaufzeichnung_import_csv & zeitaufzeichnung_import_post --- cis/private/tools/zeitaufzeichnung.php | 94 +++- include/zeitaufzeichnung_csv_import.class.php | 455 ------------------ include/zeitaufzeichnung_import.class.php | 225 +++++++++ include/zeitaufzeichnung_import_csv.class.php | 429 +++++++++++++++++ .../zeitaufzeichnung_import_post.class.php | 222 +++++++++ 5 files changed, 945 insertions(+), 480 deletions(-) delete mode 100644 include/zeitaufzeichnung_csv_import.class.php create mode 100644 include/zeitaufzeichnung_import.class.php create mode 100644 include/zeitaufzeichnung_import_csv.class.php create mode 100644 include/zeitaufzeichnung_import_post.class.php diff --git a/cis/private/tools/zeitaufzeichnung.php b/cis/private/tools/zeitaufzeichnung.php index 39cd2935b..42780cc59 100644 --- a/cis/private/tools/zeitaufzeichnung.php +++ b/cis/private/tools/zeitaufzeichnung.php @@ -44,9 +44,10 @@ require_once('../../../include/globals.inc.php'); require_once('../../../include/bisverwendung.class.php'); require_once('../../../include/studiensemester.class.php'); require_once('../../../include/benutzerberechtigung.class.php'); -require_once('../../../include/zeitaufzeichnung_csv_import.class.php'); +require_once('../../../include/zeitaufzeichnung_import_csv.class.php'); +require_once('../../../include/zeitaufzeichnung_import_post.class.php'); -function checkZeitsperren($p, $uid, $day) +/*function checkZeitsperren($p, $uid, $day) { $zs = new zeitsperre(); $sperreVorhanden = false; @@ -76,7 +77,7 @@ function checkZeitsperren($p, $uid, $day) "msg" => $msg ); } -} +}*/ $sprache = getSprache(); $p=new phrasen($sprache); @@ -156,8 +157,8 @@ else $gesperrt_bis = '2015-08-31'; $sperrdatum = date('c', strtotime($gesperrt_bis)); -$datumjetzt = strtotime("+5 weeks"); -$limitdatum = date('c', $datumjetzt); +/*$datumjetzt = strtotime("+5 weeks"); +$limitdatum = date('c', $datumjetzt);*/ // Uses urlencode to avoid XSS issues $zeitaufzeichnung_id = urlencode(isset($_GET['zeitaufzeichnung_id'])?$_GET['zeitaufzeichnung_id']:''); @@ -870,40 +871,80 @@ if($kartennummer != '') if(isset($_POST['save']) || isset($_POST['edit']) || isset($_POST['import'])) { - $zeit = new zeitaufzeichnung(); + #$zeit = new zeitaufzeichnung(); // TODO(chris): make lokal - $projects_of_user = new projekt(); + // TODO(chris): make lokal + /*$projects_of_user = new projekt(); $projects= $projects_of_user->getProjekteListForMitarbeiter($user); - $project_kurzbz_array = array(); + $project_kurzbz_array = array();*/ + // TODO(chris): make lokal? $projektph_of_user = new projektphase(); - $projektphasen = $projektph_of_user->getProjectphaseForMitarbeiter($user); - $projectphasen_kurzbz_array = array(); + $projektphasen = $projektph_of_user->getProjectphaseForMitarbeiter($user); // TODO(chris): this seems to be used below + /*$projectphasen_kurzbz_array = array();*/ - foreach($projects as $prjct) + // TODO(chris): make lokal + /*foreach($projects as $prjct) { array_push($project_kurzbz_array, (string) $prjct->projekt_kurzbz); - } - foreach ($projektphasen as $pp) + }*/ + // TODO(chris): make lokal + /*foreach ($projektphasen as $pp) { array_push($projectphasen_kurzbz_array, (string) $pp->projektphase_id); - } + }*/ - $projectphase = new projektphase(); + // NOTE(chris): this is the same as projektph_of_user + /*$projectphase = new projektphase();*/ + // NOTE(chris): CSV Import if ($_FILES['csv']['error'] == 0 && isset($_POST['import'])) { - $zeit_csv_import = new zeitaufzeichnung_csv_import($p, $zeit, $project_kurzbz_array, $projectphasen_kurzbz_array, $sperrdatum, $limitdatum, $projects_of_user, $projektph_of_user, $datum, $user); - $zeit_csv_import->parseCSV(); - echo $zeit_csv_import->InfosToHTML(); - echo $zeit_csv_import->WarningsToHTML(); - echo $zeit_csv_import->ErrorsToHTML(); + $zeit_csv_import = new zeitaufzeichnung_import_csv($p, $user, $sperrdatum, $_FILES['csv']['tmp_name']); + $zeit_csv_import->import(); + echo $zeit_csv_import->OutputToHTML(); } else if ($datum->formatDatum($von, $format='Y-m-d H:i:s') < $sperrdatum) echo '' .$p->t("global/fehlerBeimSpeichernDerDaten").': Eingabe nicht möglich da vor dem Sperrdatum'; + // NOTE(chris): Save else if (isset($_POST['save']) || isset($_POST['edit'])) { + $zeit_post_import = new zeitaufzeichnung_import_post($p, $user, isset($_POST['edit']), [ + 'aktivitaet_kurzbz' => $aktivitaet_kurzbz, + 'beschreibung' => $beschreibung, + 'bis' => $bis, + 'bis_pause' => $bis_pause, + 'homeoffice' => $homeoffice, + 'kunde_uid' => $kunde_uid, + 'oe_kurzbz_1' => $oe_kurzbz_1, + 'oe_kurzbz_2' => $oe_kurzbz_2, + 'projekt_kurzbz' => $projekt_kurzbz, + 'projektphase_id' => $projektphase_id, + 'service_id' => $service_id, + 'von' => $von, + 'von_pause' => $von_pause, + 'zeitaufzeichnung_id' => $zeitaufzeichnung_id, + ]); + $zeit_post_import->import(); + echo $zeit_post_import->OutputToHTML(); + if (!$zeit_post_import->hasErrors() && !$zeit_post_import->hasWarnings()) { + // Nach dem Speichern in den neu Modus springen und als Von Zeit + // das Ende des letzten Eintrages eintragen + $zeitaufzeichnung_id = ''; + $uid = $user; + $aktivitaet_kurzbz = ''; + $von = date('d.m.Y H:i', $datum->mktime_fromtimestamp($datum->formatDatum($bis, $format = 'Y-m-d H:i:s'))); + $bis = date('d.m.Y H:i', $datum->mktime_fromtimestamp($datum->formatDatum($bis, $format = 'Y-m-d H:i:s'))+3600); + $beschreibung = ''; + $oe_kurzbz_1 = ''; + $oe_kurzbz_2 = ''; + $projekt_kurzbz = ''; + $projektphase_id = ''; + $service_id = ''; + $kunde_uid = ''; + } + /* if(isset($_POST['edit'])) { if(!$zeit->load($zeitaufzeichnung_id)) @@ -1048,8 +1089,10 @@ if(isset($_POST['save']) || isset($_POST['edit']) || isset($_POST['import'])) $zeitaufzeichnung_id = ''; $uid = $zeit->uid; $aktivitaet_kurzbz = ''; - $von = date('d.m.Y H:i', $datum->mktime_fromtimestamp($zeit->ende)); - $bis = date('d.m.Y H:i', $datum->mktime_fromtimestamp($zeit->ende)+3600); + #$von = date('d.m.Y H:i', $datum->mktime_fromtimestamp($zeit->ende)); + #$bis = date('d.m.Y H:i', $datum->mktime_fromtimestamp($zeit->ende)+3600); + $von = date('d.m.Y H:i', $datum->mktime_fromtimestamp($datum->formatDatum($bis, $format = 'Y-m-d H:i:s'))); + $bis = date('d.m.Y H:i', $datum->mktime_fromtimestamp($datum->formatDatum($bis, $format = 'Y-m-d H:i:s'))+3600); $beschreibung = ''; $oe_kurzbz_1 = ''; $oe_kurzbz_2 = ''; @@ -1058,6 +1101,7 @@ if(isset($_POST['save']) || isset($_POST['edit']) || isset($_POST['import'])) $service_id = ''; $kunde_uid = ''; } + */ } } @@ -1235,7 +1279,7 @@ if ($projekt->getProjekteMitarbeiter($user, true)) //Formular echo '
'; -/* echo ' + /*echo '
'; echo '';*/ @@ -1859,8 +1903,8 @@ if ($projekt->getProjekteMitarbeiter($user, true)) echo ''; echo ''; echo '\n"; echo "
'; -// if(!isset($_GET['filter']) && ($datumtag > $sperrdatum)) -// echo ''.$p->t("global/bearbeiten").''; + //if(!isset($_GET['filter']) && ($datumtag > $sperrdatum)) + // echo ''.$p->t("global/bearbeiten").''; echo ""; if(!isset($_GET['filter']) && ($datumtag > $sperrdatum)) diff --git a/include/zeitaufzeichnung_csv_import.class.php b/include/zeitaufzeichnung_csv_import.class.php deleted file mode 100644 index 290da70e6..000000000 --- a/include/zeitaufzeichnung_csv_import.class.php +++ /dev/null @@ -1,455 +0,0 @@ -p = $p; - $this->zeit = $zeit; - - $this->project_kurzbz_array = $project_kurzbz_array; - $this->projectphasen_kurzbz_array = $projectphasen_kurzbz_array; - - $this->sperrdatum = $sperrdatum; - $this->limitdatum = $limitdatum; - - $this->projects_of_user = $projects_of_user; - $this->projektph_of_user = $projektph_of_user; - - $this->datum = $datum; - - $this->user = $user; - $this->errors = array(); - $this->warnings = array(); - $this->infos = array(); - } - - public function parseCSV() { - $this->tmpname = $_FILES['csv']['tmp_name']; - try { - $this->checkMimeType(); - $this->openFileForReading(); - $this->checkEncoding(); - $this->iterateRows(); - $this->checkAndCleanup(); - } catch (Exception $ex) { - $this->addError($ex->getMessage()); - } - } - - public function hasErrors() { - return !empty($this->errors); - } - - public function hasWarnings() { - return !empty($this->warnings); - } - - public function hasInfos() { - return !empty($this->infos); - } - - public function ErrorsToHTML() { - $html = ''; - foreach ($this->errors as $msg) { - $html .= '' . $msg . '
' . "\n"; - } - return $html; - } - - public function WarningsToHTML() { - $html = ''; - foreach ($this->errors as $msg) { - $html .= '' . $msg . '
' . "\n"; - } - return $html; - } - - public function InfosToHTML() { - $html = ''; - foreach ($this->infos as $msg) { - $html .= '' . $msg . '
' . "\n"; - } - return $html; - } - - protected function addError($msg, $prepend_current_line=false) { - if( $prepend_current_line ) { - $msg = 'Zeile ' . $this->current_line . ' - ' . $msg; - } - $this->errors[] = $msg; - } - - protected function addWarning($msg, $prepend_current_line=false) { - if( $prepend_current_line ) { - $msg = 'Zeile ' . $this->current_line . ' - ' . $msg; - } - $this->warnings[] = $msg; - } - - protected function addInfo($msg) { - $this->infos[] = $msg; - } - - protected function checkMimeType() { - $mimeType = mime_content_type($this->tmpname); - if( $mimeType !== 'text/plain' ) { - throw new Exception('Datei ist nicht im CSV Format.'); - } - } - - protected function openFileForReading() { - if( false === ($this->fh = fopen($this->tmpname, 'r')) ) - { - throw new Exception('CSV - Datei konnte nicht zum lesen geöffnet werden.'); - } - } - - 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!'); - } - } - - protected function iterateRows() { - set_time_limit(0); - $this->anzahl = 0; - $this->importtage_array = array(); - $this->ende_vorher = date('Y-m-d H:i:s'); - - $this->data = null; - $this->current_line = 0; - while(($this->data = fgetcsv($this->fh, 1000, ';', '"')) !== FALSE) - { - if( false !== strpos($this->data[self::USER], '#') ) { - // ignore lines starting with # - continue; - } - $this->current_line++; - $this->processData(); - } - } - - protected function processData() { - try { - $this->checkUser(); - $this->checkProject(); - $this->checkPhase(); - $this->initData(); - $this->checkZeitsperren(); - $this->checkSperrdatum(); - $this->checkLimitdatum(); - $this->checkDienstreise(); - $this->checkTagesgenau(); - $this->checkProjectInterval(); - $this->checkPhaseInterval(); - $this->checkVals(); - $this->mapLehreIntern(); - $this->prepareZeitaufzeichnung(); - $this->checkImporttage(); - $this->saveZeit(); - } catch (Exception $ex) { - $this->addError($ex->getMessage(), true); - } - } - - protected function checkUser() { - if( $this->data[self::USER] !== $this->user && (strpos($this->data[self::USER],'#') !== false) ) - { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten").': Falsche UID nicht importiert ('.$this->data[self::USER].')'); - } - } - - protected function checkProject() { - if(!empty($this->data[self::PROJEKT]) && !in_array($this->data[self::PROJEKT], $this->project_kurzbz_array) && empty($this->data[self::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: ('.$this->data[self::PROJEKT].')'); - } - - } - - protected function checkPhase() { - if(!empty($this->data[self::PHASE]) && !in_array($this->data[self::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: ('.$this->data[self::PHASE].')'); - } - } - - protected function initData() { - if (!isset($this->data[self::OE])) { - $this->data[self::OE] = NULL; - } - if (!isset($this->data[self::PROJEKT])) { - $this->data[self::PROJEKT] = NULL; - } - if (!isset($this->data[self::PHASE])) { - $this->data[self::PHASE] = NULL; - } - if (!isset($this->data[self::SERVICE])) { - $this->data[self::SERVICE] = NULL; - } - } - - protected function checkZeitsperren() { - // NOTE(chris): checkZeitsperren() is defined in private/tools/zeitaufzeichnung.php - $zscheck = checkZeitsperren($this->p, $this->user, $this->datum->formatDatum($this->data[self::STARTDT], $format = 'Y-m-d')); - if ($zscheck['status'] === false) { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") . ": " . $zscheck['msg']); - } - } - - protected function checkSperrdatum() { - if ($this->datum->formatDatum($this->data[self::STARTDT], $format='Y-m-d H:i:s') < $this->sperrdatum) { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") - .': Eingabe nicht möglich da vor dem Sperrdatum ('.$this->data[self::STARTDT].')'); - } - - } - - protected function checkLimitdatum() { - if ($this->datum->formatDatum($this->data[self::STARTDT], $format='Y-m-d H:i:s') > $this->limitdatum) { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") - .': Eingabe nicht möglich da ('.$this->data[self::STARTDT].') zu weit in der Zukunft liegt.'); - } - } - - protected function checkDienstreise() { - $vonCSV = $this->datum->formatDatum($this->data[self::STARTDT], $format='Y-m-d'); - $bisCSV = $this->datum->formatDatum($this->data[self::ENDEDT], $format='Y-m-d'); - $dateVonCSV = new DateTime($vonCSV); - $dateBisCSV = new DateTime($bisCSV); - if ($dateVonCSV!=$dateBisCSV && $this->data[self::AKTIVITAET]!="DienstreiseMT") - { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") - .': Eingabe nicht möglich, da keine Zeitaufzeichnung über mehrere Tage erlaubt ist (ausgenommen Dienstreisen).'); - } - } - - protected function checkTagesgenau() { - $bisHour = $this->datum->formatDatum($this->data[self::ENDEDT], $format = 'H:i:s'); - if ($bisHour == '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!'); - } - } - - protected function checkProjectInterval() { - if (empty($this->data[self::PHASE]) && !empty($this->data[self::PROJEKT]) - && !$this->projects_of_user->checkProjectInCorrectTime($this->data[self::PROJEKT], $this->data[self::STARTDT], $this->data[self::ENDEDT])) - { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") - .': Eingabe nicht möglich, da angegebenes Anfangs und Enddatum nicht in den Projektzeitrahmen fällt: (' - .$this->data[self::STARTDT].') ('.$this->data[self::ENDEDT].')'); - } - } - - protected function checkPhaseInterval() { - if (!empty($this->data[self::PHASE]) && !$this->projektph_of_user->checkProjectphaseInCorrectTime($this->data[self::PHASE], $this->data[self::STARTDT], $this->data[self::ENDEDT])) - { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten") - .': Eingabe nicht möglich, da angegebenes Anfangs und Enddatum nicht in den Projektphasenzeitrahmen fällt: (' - .$this->data[self::STARTDT].') ('.$this->data[self::ENDEDT].')'); - } - } - - protected function checkVals() { - $failedvals = $this->_checkVals($this->data[self::OE],$this->data[self::PROJEKT],$this->data[self::PHASE],$this->data[self::SERVICE]); - if( count($failedvals) > 0 ) - { - throw new Exception($this->p->t("global/fehlerBeimSpeichernDerDaten").': Fehlerhafte Werte ('.implode(', ', $failedvals).')'); - } - } - - protected function _checkVals ($oe_val, $project_val, $phase_val, $service_val) { - $error = array(); - 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; - } - - protected function mapLehreIntern() { - if ($this->data[self::AKTIVITAET] == 'LehreIntern') { - $this->data[self::AKTIVITAET] = 'Lehre'; - } - } - - protected function prepareZeitaufzeichnung() { - $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 = $this->data[self::USER]; - $this->zeit->aktivitaet_kurzbz = $this->data[self::AKTIVITAET]; - $this->zeit->start = $this->datum->formatDatum($this->data[self::STARTDT], $format='Y-m-d H:i:s'); - $this->zeit->ende = $this->datum->formatDatum($this->data[self::ENDEDT], $format='Y-m-d H:i:s'); - if (isset($this->data[self::BESCHREIBUNG])) { - $this->zeit->beschreibung = $this->data[self::BESCHREIBUNG]; - } - if (isset($this->data[self::OE])) { - $this->zeit->oe_kurzbz_1 = $this->data[self::OE]; - } - if (isset($this->data[self::PROJEKT])) { - $this->zeit->projekt_kurzbz = $this->data[self::PROJEKT]; - } - if (isset($this->data[self::PHASE])) { - $this->zeit->projektphase_id = $this->data[self::PHASE]; - } - if (isset($this->data[self::SERVICE])) { - $this->zeit->service_id = $this->data[self::SERVICE]; - } - $this->zeit->homeoffice = false; - if (isset($this->data[self::HOMEOFFICE])) { - $this->zeit->homeoffice = (strtolower($this->data[self::HOMEOFFICE]) == 'true'); - if (strtolower($this->data[self::HOMEOFFICE]) == 'true') { - // check, ob homeoffice gemäß Bisverwendung - $vonCSV = $this->datum->formatDatum($this->data[self::STARTDT], $format = 'Y-m-d'); - $verwendung = new bisverwendung(); - $verwendung->getVerwendungDatum($this->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; - } - } - } - } - } - - protected function checkImporttage() { - $tag = $this->datum->formatDatum($this->data[self::STARTDT], $format='Y-m-d'); - - if(!in_array($tag, $this->importtage_array)) - { - $this->importtage_array[] = $tag; - $this->zeit->deleteEntriesForUser($this->user, $tag); - $tag_aktuell = $tag; - } - else if ($this->ende_vorher < $this->zeit->start) - { - $this->savePause(); - } - - $this->ende_vorher = $this->zeit->ende; - } - - 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); - } - } - - protected function saveZeit() { - if($this->data[self::STARTDT] != $this->data[self::ENDEDT]) - { - if(!$this->zeit->save()) - { - $this->addError($this->p->t("global/fehlerBeimSpeichernDerDaten").': '.$this->zeit->errormsg.'('.$this->zeit->start.')', true); - } - else { - $this->anzahl++; - } - } - else { - $this->anzahl++; - } - } - - 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.class.php b/include/zeitaufzeichnung_import.class.php new file mode 100644 index 000000000..e8e6a8b15 --- /dev/null +++ b/include/zeitaufzeichnung_import.class.php @@ -0,0 +1,225 @@ +errors = []; + $this->warnings = []; + $this->infos = []; + + $this->p = $p; + $this->datum = new datum(); + + $this->project = new projekt(); + $this->phase = new projektphase(); + $this->limitdate = date('c', strtotime("+5 weeks")); + + $this->zeit = new zeitaufzeichnung(); + } + + + /** + * @return boolean + */ + public function hasErrors() { + return !empty($this->errors); + } + + /** + * @return boolean + */ + public function hasWarnings() { + return !empty($this->warnings); + } + + /** + * @return boolean + */ + public function hasInfos() { + return !empty($this->infos); + } + + /** + * @return string + */ + public function ErrorsToHTML() { + $html = ''; + foreach ($this->errors as $msg) { + $html .= '' . $msg . '
' . "\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..7d4250ac9 --- /dev/null +++ b/include/zeitaufzeichnung_import_csv.class.php @@ -0,0 +1,429 @@ +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], '#') ) { + // 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->checkProject($data[self::PROJEKT], $data[self::PHASE]); + $this->checkPhase($data[self::PHASE]); + $this->initData($data); + $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; + } + + /** + * @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")); + } + } + +}