diff --git a/application/controllers/system/MigrateKalender.php b/application/controllers/system/MigrateKalender.php index 67de262dd..71a7d189f 100644 --- a/application/controllers/system/MigrateKalender.php +++ b/application/controllers/system/MigrateKalender.php @@ -32,6 +32,42 @@ class MigrateKalender extends CLI_Controller /** * Everything has a beginning */ + public function refreshTablesAndFullMigrateOfStundenplanReservierung($von, $bis = null, $studiengang_kz = null, $ort_kurzbz = null) + { + if (defined('CI_ENVIRONMENT') && CI_ENVIRONMENT === 'production') + { + echo "This script is not allowed to run in production environment.\n"; + return; + } + + echo "Refreshing calendar related tables...\n"; + $this->resetBeforeNewStundenplanReservierungImport(); + echo "Calendar related tables refreshed successfully.\n\n"; + + echo "Starting full migration of Stundenplan and Reservierung from $von to " . ($bis ?? '2100-12-31') . "...\n"; + $this->fullMigrateOfStundenplanReservierung($von, $bis, $studiengang_kz, $ort_kurzbz); + echo "Full migration of Stundenplan and Reservierung completed successfully.\n"; + } + + public function fullMigrateOfStundenplanReservierung($von, $bis = null, $studiengang_kz = null, $ort_kurzbz = null) + { + echo "Starting migration of Stundenplan from $von to " . ($bis ?? '2100-12-31') . "...\n"; + $this->migrateStundenplan($von, $bis, $studiengang_kz); + echo "Stundenplan migration completed successfully.\n\n"; + + echo "Starting migration of Reservierung from $von to " . ($bis ?? '2100-12-31') . "...\n"; + $this->migrateReservierung($von, $bis, $ort_kurzbz); + echo "Reservierung migration completed successfully.\n\n"; + + echo "Starting migration of Stundenplan Betriebsmittel entries...\n"; + $this->migrateStundenplanBetriebsmittelEntries(); + echo "Stundenplan Betriebsmittel entries migration completed successfully.\n\n"; + + echo "Starting to add title values as tags to calendar entries...\n"; + $this->addTitleValuesAsTagsToKalenderEntries(); + echo "Adding title values as tags to calendar entries completed successfully.\n\n"; + } + public function migrateStundenplan($von, $bis = null, $studiengang_kz = null) { if (is_null($von)) @@ -333,6 +369,121 @@ class MigrateKalender extends CLI_Controller $dbModel->db->query($query); } + public function addTitleValuesAsTagsToKalenderEntries() { + $dbModel = new DB_Model(); + + + $query = "SELECT + k.eindeutige_kalender_gruppen_id, + ARRAY_AGG(DISTINCT(spd.titel) ORDER BY spd.titel) AS titel, + MAX(spd.updateamum) AS updateamum + FROM lehre.tbl_stundenplandev spd + JOIN sync.tbl_stundenplandev_kalender spdk ON spd.stundenplandev_id = spdk.stundenplandev_id + JOIN lehre.tbl_kalender k ON k.kalender_id = spdk.kalender_id + WHERE k.typ = 'lehreinheit' AND k.eindeutige_kalender_gruppen_id IS NOT NULL AND spd.titel IS NOT NULL + GROUP BY k.eindeutige_kalender_gruppen_id"; + + $result = $dbModel->execReadOnlyQuery($query); + + if (isError($result)) { + error("Error while fetching title values for adding as tags: " . getError($result)); + return; + } + if (!hasData($result)) { + error("No title values found for adding as tags."); + return; + } + + $data = getData($result); + + foreach($data as $block) { + $eindeutige_kalender_gruppen_id = $block->eindeutige_kalender_gruppen_id; + $notizText = implode(' - ', array_filter($block->titel, function($titel) { + return !empty(trim($titel)); + })); + + if (!empty($notizText)) { + $this->addTag($eindeutige_kalender_gruppen_id, $notizText, $block->updateamum); + } + } + } + + private function resetBeforeNewStundenplanReservierungImport() + { + if (defined('CI_ENVIRONMENT') && CI_ENVIRONMENT === 'production') + { + echo "This script is not allowed to run in production environment.\n"; + return; + } + + $db = new DB_Model(); + + $db->db->trans_start(); + + $db->db->query('DELETE FROM sync.tbl_stundenplandev_kalender'); + $db->db->query('DELETE FROM sync.tbl_reservierung_kalender'); + + $db->db->query("DELETE FROM lehre.tbl_kalender_event_teilnehmer + WHERE kalender_id IN ( + SELECT kalender_id + FROM lehre.tbl_kalender + WHERE typ = 'reservierung' + )"); + + $db->db->query("DELETE FROM lehre.tbl_kalender_event + WHERE kalender_id IN ( + SELECT kalender_id + FROM lehre.tbl_kalender + WHERE typ = 'reservierung' + )"); + + $db->db->query("DELETE FROM lehre.tbl_kalender_lehreinheit + WHERE kalender_id IN ( + SELECT kalender_id + FROM lehre.tbl_kalender + WHERE typ = 'lehreinheit' OR typ = 'reservierung' + )"); + + $db->db->query("DELETE FROM lehre.tbl_kalender_ort + WHERE kalender_id IN ( + SELECT kalender_id + FROM lehre.tbl_kalender + WHERE typ IN ('lehreinheit', 'reservierung') + )"); + + $db->db->query("DELETE FROM public.tbl_notiz + WHERE notiz_id IN ( + SELECT notiz_id + FROM public.tbl_notizzuordnung + WHERE eindeutige_kalender_gruppen_id IN ( + SELECT eindeutige_kalender_gruppen_id + FROM lehre.tbl_kalender + ) + )"); + + $db->db->query("DELETE FROM public.tbl_notizzuordnung + WHERE eindeutige_kalender_gruppen_id IN ( + SELECT eindeutige_kalender_gruppen_id + FROM lehre.tbl_kalender + )"); + + $db->db->query("DELETE FROM lehre.tbl_betriebsmittel_kalender + WHERE eindeutige_kalender_gruppen_id IN ( + SELECT eindeutige_kalender_gruppen_id + FROM lehre.tbl_kalender + )"); + + $db->db->query("DELETE FROM lehre.tbl_kalender + WHERE typ IN ('lehreinheit', 'reservierung')"); + + $db->db->trans_complete(); + + if ($db->db->trans_status() === false) + return error('Reset before new import failed'); + + return success('Migration data reset successfully'); + } + private function setKalendarEntriesGroupIDs() { $dbModel = new DB_Model(); @@ -607,4 +758,129 @@ class MigrateKalender extends CLI_Controller ); } } + + private function addTag($eindeutige_kalender_gruppen_id, $notizText, $lastUpdatedInOldSystem): bool + { + $notizType = 'hinweis'; + $insertvonMockUser = 'oldToNewTempusMigration'; + + if (is_null($eindeutige_kalender_gruppen_id) || empty($eindeutige_kalender_gruppen_id)) { + var_dump("Error: eindeutige_kalender_gruppen_id is null or empty."); + return false; + } + + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('system/Notiztyp_model', 'NotiztypModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + $checkTyp = $this->NotiztypModel->loadWhere(array('typ_kurzbz' => $notizType)); + + if (isError($checkTyp)) + { + error("Error occurred while checking Notiztyp: " . $checkTyp->message); + return false; + } + + if (!hasData($checkTyp)) + { + error("Notiztyp 'hinweis' does not exist. Please create it before adding tags."); + return false; + } + + + $this->NotizzuordnungModel->addJoin('tbl_notiz', 'tbl_notiz.notiz_id = tbl_notizzuordnung.notiz_id', 'LEFT'); + $this->NotizzuordnungModel->db->where('tbl_notiz.typ', $notizType); + $this->NotizzuordnungModel->db->where('tbl_notiz.insertvon', $insertvonMockUser); + $oldNotizZuordnung = $this->NotizzuordnungModel->loadWhere(array('eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id)); + if (isError($oldNotizZuordnung)) + { + error("Error occurred while checking Notizzuordnung: " . $oldNotizZuordnung->message); + return false; + } + if (hasData($oldNotizZuordnung)) + { + return $this->updateTag($eindeutige_kalender_gruppen_id, $notizText, $lastUpdatedInOldSystem); + } + + + $insertResult = $this->NotizModel->insert(array( + 'titel' => 'TAG', + 'text' => $notizText, + 'verfasser_uid' => null, + 'erledigt' => false, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => $insertvonMockUser, + 'typ' => $notizType + )); + + if (isError($insertResult)) + { + error("Error occurred while inserting Notiz: " . $insertResult->message); + return false; + } + + $insertZuordnung = $this->NotizzuordnungModel->insert(array( + 'notiz_id' => $insertResult->retval, + 'eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id + )); + + if (isError($insertZuordnung)) + { + error("Error occurred while inserting Notizzuordnung: " . $insertZuordnung->message); + return false; + } + + return true; + } + + private function updateTag($eindeutige_kalender_gruppen_id, $notizText, $lastUpdatedInOldSystem) + { + $notizType = 'hinweis'; + $insertvonMockUser = 'oldToNewTempusMigration'; + + $this->NotizzuordnungModel->addJoin('tbl_notiz', 'tbl_notiz.notiz_id = tbl_notizzuordnung.notiz_id', 'LEFT'); + $this->NotizzuordnungModel->db->where('tbl_notiz.typ', $notizType); + $this->NotizzuordnungModel->db->where('tbl_notiz.insertvon', $insertvonMockUser); + $notizZuordnungRes = $this->NotizzuordnungModel->loadWhere(array('eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id)); + if (isError($notizZuordnungRes)) + { + error("Error occurred while loading Notizzuordnung: " . $notizZuordnungRes->message); + return false; + } + + + $tag = $this->NotizModel->loadWhere(array('notiz_id' => $notizZuordnungRes->retval[0]->notiz_id)); + if (isError($tag)) + { + error("Error occurred while loading Notiz: " . $tag->message); + return false; + } + + if (!hasData($tag)) + { + error("Error occurred while loading Notiz: " . $tag->message); + return false; + } + + $adjustedLastUpdatedInOldSystem = date('Y-m-d H:i:s', strtotime($lastUpdatedInOldSystem) + 5); + if ($tag->retval[0]->updateamum >= $adjustedLastUpdatedInOldSystem) + { + return true; + } + + $updateData = $this->NotizModel->update(array('notiz_id' => $tag->retval[0]->notiz_id), + array('text' => $notizText, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $insertvonMockUser, + 'bearbeiter_uid' => null, + ) + ); + if (isError($updateData)) + { + error("Error occurred while updating Notiz: " . $updateData->message); + return false; + } + + return true; + } } diff --git a/application/libraries/KalenderLib.php b/application/libraries/KalenderLib.php index 623784c9d..935dfebb6 100644 --- a/application/libraries/KalenderLib.php +++ b/application/libraries/KalenderLib.php @@ -34,13 +34,27 @@ class KalenderLib } - private function _getBasePlan($start_date, $end_date) + private function _buildFilteredKalenderCte($start_date, $end_date) + { + $end_date = date('Y-m-d', strtotime($end_date . ' +1 day')); + + return sprintf( + 'WITH filtered_kalender AS MATERIALIZED ( + SELECT * + FROM lehre.tbl_kalender + WHERE von >= timestamp %s + AND bis < timestamp %s + )', + $this->_ci->KalenderModel->db->escape(date('Y-m-d H:i:s', strtotime($start_date))), + $this->_ci->KalenderModel->db->escape(date('Y-m-d H:i:s', strtotime($end_date))) + ); + } + + private function _buildBasePlanQuery() { $language = $this->getLanguageIndex(); $index_bezeichnung_mehrsprachig = $language - 1; - $end_date = date('Y-m-d', strtotime($end_date . ' +1 day')); - $this->_ci->KalenderModel->addSelect('tbl_kalender.kalender_id, tbl_kalender.eindeutige_kalender_gruppen_id, tbl_kalender.status_kurzbz, @@ -139,6 +153,7 @@ class KalenderLib $this->_ci->KalenderModel->addJoin('public.tbl_benutzer resevierung_benutzer', 'reservierung_ma.mitarbeiter_uid = resevierung_benutzer.uid', 'LEFT'); $this->_ci->KalenderModel->addJoin('public.tbl_person reservierung_person', 'reservierung_person.person_id = resevierung_benutzer.person_id', 'LEFT'); + $this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitgruppe', 'tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id', 'LEFT'); $this->_ci->KalenderModel->addJoin('public.tbl_gruppe le_gruppe', 'tbl_lehreinheitgruppe.gruppe_kurzbz = le_gruppe.gruppe_kurzbz', 'LEFT'); $this->_ci->KalenderModel->addJoin('public.tbl_lehrverband le_lehrverband', @@ -216,12 +231,17 @@ class KalenderLib $this->_ci->KalenderModel->db->join('lehre.tbl_stunde vonstunde', 'tbl_kalender.von::time = vonstunde.beginn', 'LEFT', FALSE); $this->_ci->KalenderModel->db->join('lehre.tbl_stunde bisstunde', 'tbl_kalender.bis::time = bisstunde.ende', 'LEFT', FALSE); - $this->_ci->KalenderModel->db->where('tbl_kalender.von >=', $start_date); - $this->_ci->KalenderModel->db->where('tbl_kalender.bis <', $end_date); - $this->_ci->KalenderModel->addOrder('tbl_kalender.eindeutige_kalender_gruppen_id', 'DESC'); } + private function _loadFilteredBasePlan($start_date, $end_date) + { + $query = $this->_buildFilteredKalenderCte($start_date, $end_date) . "\n" . + $this->_ci->KalenderModel->db->get_compiled_select('filtered_kalender AS tbl_kalender'); + + return $this->_ci->KalenderModel->execReadOnlyQuery($query); + } + private function _mapEvents($data, $collisionCheck = true) { $stundenplan_data = []; @@ -369,10 +389,10 @@ class KalenderLib } public function getPlanByOrt($start_date, $end_date, $ort) { - $this->_getBasePlan($start_date, $end_date); + $this->_buildBasePlanQuery(); $this->_ci->KalenderModel->db->where('tbl_kalender_ort.ort_kurzbz', $ort); - $data = $this->_ci->KalenderModel->load(); + $data = $this->_loadFilteredBasePlan($start_date, $end_date); return $this->_mapEvents($data); } @@ -382,7 +402,7 @@ class KalenderLib $start_date = date('Y-m-d', strtotime($start_date)); $end_date = date('Y-m-d', strtotime($end_date . ' +1 day')); - $this->_getBasePlan($start_date, $end_date); + $this->_buildBasePlanQuery(); $this->_ci->KalenderModel->db->where('NOT EXISTS ( SELECT 1 FROM lehre.tbl_kalender nachfolger @@ -414,7 +434,7 @@ class KalenderLib $this->_ci->KalenderModel->db->group_end(); } - $data = $this->_ci->KalenderModel->load(); + $data = $this->_loadFilteredBasePlan($start_date, $end_date); return $this->_mapEvents($data, false); } @@ -430,14 +450,14 @@ class KalenderLib $kalender_entry = getData($kalender_entry)[0]; - $this->_getBasePlan($kalender_entry->von, $kalender_entry->bis); + $this->_buildBasePlanQuery(); $this->_ci->KalenderModel->db->where('tbl_kalender.kalender_id', $kalender_entry->kalender_id); - $data = $this->_ci->KalenderModel->load(); + $data = $this->_loadFilteredBasePlan($kalender_entry->von, $kalender_entry->bis); return $this->_mapEvents($data); } public function getPlanForPlanner($start_date, $end_date, $ort = null, $uids = null, $studiengaenge = null) { - $this->_getBasePlan($start_date, $end_date); + $this->_buildBasePlanQuery(); if (!is_null($ort)) { @@ -540,18 +560,18 @@ class KalenderLib ) AS has_assigned_resources" ]); - $data = $this->_ci->KalenderModel->load(); + $data = $this->_loadFilteredBasePlan($start_date, $end_date); return $this->_mapEvents($data); } public function getPlanForStudent($start_date, $end_date) { - $this->_getBasePlan($start_date, $end_date); + $this->_buildBasePlanQuery(); $this->_ci->KalenderModel->db->where_in('status_kurzbz', array('live', 'to_delete_live')); - $data = $this->_ci->KalenderModel->load(); + $data = $this->_loadFilteredBasePlan($start_date, $end_date); return $this->_mapEvents($data); } @@ -559,7 +579,7 @@ class KalenderLib public function getPlanForLecturer($start_date, $end_date) { - $this->_getBasePlan($start_date, $end_date); + $this->_buildBasePlanQuery(); $this->_ci->KalenderModel->addJoin( 'lehre.tbl_kalender neuerer', @@ -571,7 +591,7 @@ class KalenderLib OR (tbl_kalender.status_kurzbz = 'preview' AND neuerer.kalender_id IS NULL) OR (tbl_kalender.status_kurzbz = 'live' AND neuerer.kalender_id IS NULL) )", NULL, FALSE); - $data = $this->_ci->KalenderModel->load(); + $data = $this->_loadFilteredBasePlan($start_date, $end_date); return $this->_mapEvents($data); } @@ -1840,7 +1860,7 @@ class KalenderLib else { - if (!isEmptyArray($kalender_entry->ort_kurzbz)) + if (!isEmptyArray($kalender_entry->ort_kurzbz) || !isEmptyString($kalender_entry->location)) { $result = $this->_deleteOrtEntry($kalender_entry); if (isError($result)) diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 4b1468906..5e947ff25 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -101,7 +101,6 @@ require_once('dbupdate_3.4/68530_Dashboard_Cleanup.php'); require_once('dbupdate_3.4/77375_ressourcen.php'); require_once('dbupdate_3.4/78052_tempus_tag_events.php'); require_once('dbupdate_3.4/78318_rename_column_of_eindeutige_gruppen_id_to_eindeutige_kalender_gruppen_id_in_tbl_kalender.php'); -require_once('dbupdate_3.4/78318_rename_column_of_eindeutige_gruppen_id_to_eindeutige_kalender_gruppen_id_in_tbl_kalender.php'); require_once('dbupdate_3.4/75959_StudVw_Automatische_Tags.php'); require_once('dbupdate_3.4/76160_lvv_favorites.php'); require_once('dbupdate_3.4/77080_tabulator_presets_table.php');