diff --git a/application/controllers/api/frontend/v1/tempus/Config.php b/application/controllers/api/frontend/v1/tempus/Config.php index 27a4958cb..a79af95cb 100644 --- a/application/controllers/api/frontend/v1/tempus/Config.php +++ b/application/controllers/api/frontend/v1/tempus/Config.php @@ -56,6 +56,7 @@ class Config extends FHCAPI_Controller $this->_ci->KalenderStatusModel->addSelect('*, array_to_json(bezeichnung_mehrsprachig::varchar[])->>' . $language .' AS status'); $this->_ci->KalenderStatusModel->addOrder('sort'); + $this->_ci->KalenderStatusModel->db->where_not_in('status_kurzbz', array('archived', 'deleted')); $visible_status = $this->_ci->KalenderStatusModel->load(); $visible_status = getData($visible_status); diff --git a/application/controllers/api/frontend/v1/tempus/Kalender.php b/application/controllers/api/frontend/v1/tempus/Kalender.php index ca8471a9a..b0f1bcfda 100644 --- a/application/controllers/api/frontend/v1/tempus/Kalender.php +++ b/application/controllers/api/frontend/v1/tempus/Kalender.php @@ -14,17 +14,22 @@ class Kalender extends FHCAPI_Controller */ public function __construct() { - parent::__construct([ 'getStunden' => self::PERM_LOGGED, 'getPlan' => self::PERM_LOGGED, - 'getPlanNew' => self::PERM_LOGGED, 'getPlanByOrt' => self::PERM_LOGGED, 'getRaumvorschlag' => self::PERM_LOGGED, + 'getHistory' => 'lehre/lvplan:rw', + 'deleteEntry' => 'lehre/lvplan:rw', + 'syncToLecturer' => 'lehre/lvplan:rw', + 'syncToStudent' => 'lehre/lvplan:rw', + 'getPlanLecturer' =>'lehre/lvplan:rw', + 'getPlanStudent' => 'lehre/lvplan:rw', 'getZeitwuensche' => self::PERM_LOGGED, 'getZeitsperren' => self::PERM_LOGGED, 'updateKalenderEvent' => 'lehre/lvplan:rw', - 'addKalenderEvent' => 'lehre/lvplan:rw' + 'addKalenderEvent' => 'lehre/lvplan:rw', + 'sync' => 'lehre/lvplan:rw', ]); $this->_ci =& get_instance(); @@ -64,6 +69,7 @@ class Kalender extends FHCAPI_Controller $this->terminateWithSuccess($stunden); } + public function getPlan() { $this->_ci->form_validation->set_data($_GET); @@ -78,7 +84,7 @@ class Kalender extends FHCAPI_Controller $filter = $this->_checkFilter(self::ALLOWED_PLAN_FILTER); - $stundenplan_data = $this->_ci->kalenderlib->getPlan( + $stundenplan_data = $this->_ci->kalenderlib->getPlanForPlanner( $start_date, $end_date, isset($filter->ort) ? $filter->ort : null, @@ -89,7 +95,7 @@ class Kalender extends FHCAPI_Controller $this->terminateWithSuccess($stundenplan_data); } - public function getPlanNew() + public function getPlanStudent() { $this->_ci->form_validation->set_data($_GET); $this->_ci->form_validation->set_rules('start_date',"start_date","required"); @@ -101,14 +107,29 @@ class Kalender extends FHCAPI_Controller $start_date = $this->_ci->input->get('start_date', TRUE); $end_date = $this->_ci->input->get('end_date', TRUE); - $filter = $this->_checkFilter(self::ALLOWED_PLAN_FILTER); - - $stundenplan_data = $this->_ci->kalenderlib->getPlanNew( + $stundenplan_data = $this->_ci->kalenderlib->getPlanForStudent( $start_date, - $end_date, - isset($filter->ort) ? $filter->ort : null, - isset($filter->uid) ? $filter->uid : null, - isset($filter->stg) ? $filter->stg : null + $end_date + ); + + $this->terminateWithSuccess($stundenplan_data); + } + + public function getPlanLecturer() + { + $this->_ci->form_validation->set_data($_GET); + $this->_ci->form_validation->set_rules('start_date',"start_date","required"); + $this->_ci->form_validation->set_rules('end_date',"end_date","required"); + + if($this->_ci->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); + + $start_date = $this->_ci->input->get('start_date', TRUE); + $end_date = $this->_ci->input->get('end_date', TRUE); + + $stundenplan_data = $this->_ci->kalenderlib->getPlanForLecturer( + $start_date, + $end_date ); $this->terminateWithSuccess($stundenplan_data); @@ -238,6 +259,81 @@ class Kalender extends FHCAPI_Controller $this->terminateWithSuccess(getData($result)); } + public function getHistory() + { + $this->_ci->form_validation->set_data($_GET); + $this->_ci->form_validation->set_rules('kalender_id',"kalender_id","required"); + + if($this->_ci->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); + + $kalender_id = $this->_ci->input->get('kalender_id', TRUE); + + $result = $this->_ci->kalenderlib->getHistory($kalender_id); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess(getData($result)); + } + + public function deleteEntry() + { + $this->_ci->form_validation->set_data($_POST); + $this->_ci->form_validation->set_rules('kalender_id', "kalender_id", "required"); + + if($this->_ci->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); + + $kalender_id = $this->_ci->input->post('kalender_id', TRUE); + + $result = $this->_ci->kalenderlib->deleteEntry($kalender_id); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + public function sync() + { + $result = $this->_ci->kalenderlib->sync(); + $this->terminateWithSuccess($result); + } + public function syncToLecturer() + { + $this->_ci->form_validation->set_data($_POST); + $this->_ci->form_validation->set_rules('kalender_id', "kalender_id", "required"); + + if($this->_ci->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); + + $kalender_id = $this->_ci->input->post('kalender_id', TRUE); + + $result = $this->_ci->kalenderlib->updateStatus($kalender_id, 'tosync_lektor'); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + public function syncToStudent() + { + $this->_ci->form_validation->set_data($_POST); + $this->_ci->form_validation->set_rules('kalender_id', "kalender_id", "required"); + + if($this->_ci->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->_ci->form_validation->error_array()); + + $kalender_id = $this->_ci->input->post('kalender_id', TRUE); + + $result = $this->_ci->kalenderlib->updateStatus($kalender_id, 'tosync_student'); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } public function addKalenderEvent() { $this->_ci->form_validation->set_data($_POST); diff --git a/application/controllers/jobs/TempusJob.php b/application/controllers/jobs/TempusJob.php new file mode 100644 index 000000000..92901aa33 --- /dev/null +++ b/application/controllers/jobs/TempusJob.php @@ -0,0 +1,27 @@ +_ci =& get_instance(); + + $this->_ci->load->helper('hlp_sancho_helper'); + $this->_ci->load->library('KalenderLib'); + } + + + public function sync() + { + $this->_ci->logInfo('Start job FHC-Core->Tempus->sync'); + $this->_ci->kalenderlib->sync(); + $this->_ci->logInfo('End job FHC-Core->Tempus->sync'); + } + +} diff --git a/application/libraries/KalenderLib.php b/application/libraries/KalenderLib.php index 5e33d40e1..b4799cc6c 100644 --- a/application/libraries/KalenderLib.php +++ b/application/libraries/KalenderLib.php @@ -38,7 +38,7 @@ class KalenderLib lehrfach.farbe, tbl_lehreinheitmitarbeiter.mitarbeiter_uid, tbl_person.vorname, - tbl_paddKalenderEventerson.nachname, + tbl_person.nachname, tbl_mitarbeiter.kurzbz AS ma_kurzbz'); $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit', 'tbl_kalender.kalender_id = tbl_kalender_lehreinheit.kalender_id'); $this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheit', 'tbl_kalender_lehreinheit.lehreinheit_id = tbl_lehreinheit.lehreinheit_id'); @@ -186,7 +186,7 @@ class KalenderLib return $this->_ci->OrtModel->load(); } - public function getPlanNew($start_date, $end_date, $ort = null, $uids = null, $stg = null) + public function getPlanForPlanner($start_date, $end_date, $ort = null, $uids = null, $stg = null) { $this->_getBasePlan($start_date, $end_date); @@ -199,114 +199,55 @@ class KalenderLib if (!is_null($stg)) $this->_ci->KalenderModel->db->where('tbl_lehrveranstaltung.studiengang_kz', $stg); + $this->_ci->KalenderModel->db->where('NOT EXISTS ( + SELECT 1 FROM lehre.tbl_kalender nachfolger + WHERE nachfolger.vorgaenger_kalender_id = tbl_kalender.kalender_id)', null, false); + + $this->_ci->KalenderModel->db->where_not_in('status_kurzbz', array('deleted')); $data = $this->_ci->KalenderModel->load(); return $this->_mapEvents($data); } - public function getPlan($start_date, $end_date, $ort = null, $uids = null, $stg = null) + + public function getPlanForStudent($start_date, $end_date) { - $end_date = date('Y-m-d', strtotime($end_date . ' +1 day')); + $this->_getBasePlan($start_date, $end_date); - $this->_ci->KalenderModel->addSelect('tbl_kalender.kalender_id, - tbl_kalender.status_kurzbz, - tbl_kalender.von, - tbl_kalender.bis, - tbl_kalender_ort.ort_kurzbz, - tbl_lehreinheit.lehreinheit_id, - tbl_lehreinheit.lehrveranstaltung_id, - tbl_lehreinheit.lehrfach_id, - tbl_lehreinheit.lehrform_kurzbz, - tbl_lehrveranstaltung.oe_kurzbz, - lehrfach.kurzbz AS lehrfach_kurzbz, - lehrfach.bezeichnung AS lehrfach_bezeichnung, - lehrfach.farbe, - tbl_lehreinheitmitarbeiter.mitarbeiter_uid, - tbl_person.vorname, - tbl_person.nachname, - tbl_mitarbeiter.kurzbz AS ma_kurzbz'); - $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit', 'tbl_kalender.kalender_id = tbl_kalender_lehreinheit.kalender_id'); - $this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheit', 'tbl_kalender_lehreinheit.lehreinheit_id = tbl_lehreinheit.lehreinheit_id'); - $this->_ci->KalenderModel->addJoin('lehre.tbl_lehrveranstaltung', 'tbl_lehreinheit.lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id'); - $this->_ci->KalenderModel->addJoin('lehre.tbl_lehrveranstaltung lehrfach', 'tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id', 'LEFT'); - $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_ort', 'tbl_kalender.kalender_id = tbl_kalender_ort.kalender_id', 'LEFT'); - $this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitmitarbeiter', 'tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitmitarbeiter.lehreinheit_id', 'LEFT'); - $this->_ci->KalenderModel->addJoin('public.tbl_mitarbeiter', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_lehreinheitmitarbeiter.mitarbeiter_uid', 'LEFT'); - $this->_ci->KalenderModel->addJoin('public.tbl_benutzer', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid', 'LEFT'); - $this->_ci->KalenderModel->addJoin('public.tbl_person', 'tbl_person.person_id = tbl_benutzer.person_id', 'LEFT'); - - $this->_ci->KalenderModel->db->where('tbl_kalender.von >=', $start_date); - $this->_ci->KalenderModel->db->where('tbl_kalender.bis <', $end_date); - - if (!is_null($ort)) - $this->_ci->KalenderModel->db->where('tbl_kalender_ort.ort_kurzbz', $ort); - - if (!is_null($uids)) - $this->_ci->KalenderModel->db->where_in('tbl_lehreinheitmitarbeiter.mitarbeiter_uid', $uids); - - if (!is_null($stg)) - $this->_ci->KalenderModel->db->where('tbl_lehrveranstaltung.studiengang_kz', $stg); + $this->_ci->KalenderModel->db->where('status_kurzbz', 'visible_student'); $data = $this->_ci->KalenderModel->load(); - $stundenplan_data = []; + return $this->_mapEvents($data); + } - if (!isSuccess($data) || !hasData($data)) - return $stundenplan_data; - $events = []; + public function getPlanForLecturer($start_date, $end_date) + { + $this->_getBasePlan($start_date, $end_date); - foreach (getData($data) as $row) - { - $id = $row->kalender_id; + $this->_ci->KalenderModel->addJoin( + 'lehre.tbl_kalender neuerer', + "neuerer.vorgaenger_kalender_id = tbl_kalender.kalender_id AND neuerer.status_kurzbz IN ('visible_lektor', 'tosync_student')", + 'LEFT' + ); + $this->_ci->KalenderModel->db->where("( + tbl_kalender.status_kurzbz = 'tosync_student' + OR (tbl_kalender.status_kurzbz = 'visible_lektor' AND neuerer.kalender_id IS NULL) + OR (tbl_kalender.status_kurzbz = 'visible_student' AND neuerer.kalender_id IS NULL) + )", NULL, FALSE); + $data = $this->_ci->KalenderModel->load(); - if (!isset($events[$id])) - { - $von = new DateTime($row->von); - $bis = new DateTime($row->bis); + return $this->_mapEvents($data); + } + public function getPlanForLecturer2($start_date, $end_date) + { + $this->_getBasePlan($start_date, $end_date); - $events[$id] = (object) [ - 'type' => 'lehreinheit', - 'beginn' => $von->format('H:i:s'), - 'ende' => $bis->format('H:i:s'), - 'datum' => $von->format('Y-m-d'), - 'isostart' => $von->format('c'), - 'isoend' => $bis->format('c'), - 'tooltip' => 'tip', - 'status_kurzbz' => $row->status_kurzbz, - 'ort_kurzbz' => isset($row->ort_kurzbz) ? $row->ort_kurzbz : '', - 'lehrform' => isset($row->lehrform_kurzbz) ? $row->lehrform_kurzbz : '', - 'lehrfach' => isset($row->lehrfach_kurzbz) ? $row->lehrfach_kurzbz : '', - 'lehrfach_bez' => isset($row->lehrfach_bezeichnung) ? $row->lehrfach_bezeichnung : '', - 'farbe' => isset($row->farbe) ? $row->farbe : '', - 'lehrveranstaltung_id' => $row->lehrveranstaltung_id, - 'organisationseinheit' => isset($row->oe_kurzbz) ? $row->oe_kurzbz : '', - 'kalender_id' => $id, - 'lehreinheit_id' => [], - 'lektor' => [], - 'gruppe' => [], - 'titel' => '', - 'topic' => (isset($row->lehrfach_kurzbz) ? $row->lehrfach_kurzbz : '') . ' ' . (isset($row->lehrform_kurzbz) ? $row->lehrform_kurzbz : ''), - ]; - } + $this->_ci->KalenderModel->db->where_in('status_kurzbz', array('visible_student', 'visible_lektor')); - if ($row->lehreinheit_id && !in_array($row->lehreinheit_id, $events[$id]->lehreinheit_id)) - $events[$id]->lehreinheit_id[] = $row->lehreinheit_id; + $data = $this->_ci->KalenderModel->load(); - if ($row->mitarbeiter_uid) - { - if (!in_array($row->mitarbeiter_uid, array_column($events[$id]->lektor, 'mitarbeiter_uid'))) - { - $events[$id]->lektor[] = [ - 'mitarbeiter_uid' => $row->mitarbeiter_uid, - 'vorname' => $row->vorname, - 'nachname' => $row->nachname, - 'kurzbz' => $row->ma_kurzbz, - ]; - } - } - } - - return array_values($events); + return $this->_mapEvents($data); } public function getZeitsperren($start_date, $end_date, $emp) { @@ -456,42 +397,336 @@ class KalenderLib ); } + public function updateZeit($kalender_id, $start_date, $end_date) + { + $entryResult = $this->_loadKalenderEntry($kalender_id); + if (isError($entryResult)) return $entryResult; + + $kalender_entry = getData($entryResult); + + if (in_array($kalender_entry->status_kurzbz, array('todelete', 'deleted'))) + return error('Eintrag kann nicht mehr bearbeitet werden'); + + if (in_array($kalender_entry->status_kurzbz, array('visible_student', 'visible_lektor'))) + return $this->_createHistoryEntry($kalender_entry, $start_date, $end_date); + + return $this->_ci->KalenderModel->update( + array('kalender_id' => $kalender_id), + array( + 'von' => $start_date, + 'bis' => $end_date, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => getAuthUID() + ) + ); + } + public function updateOrt($kalender_id, $ort_kurzbz) { - $exist = $this->_ci->KalenderOrtModel->load(array('kalender_id' => $kalender_id)); + $entryResult = $this->_loadKalenderEntry($kalender_id); + if (isError($entryResult)) return $entryResult; + $kalender_entry = getData($entryResult); + + if (in_array($kalender_entry->status_kurzbz, array('todelete', 'deleted'))) + return error('Eintrag kann nicht mehr bearbeitet werden'); + + if (in_array($kalender_entry->status_kurzbz, array('visible_student', 'visible_lektor'))) + return $this->_createHistoryEntry($kalender_entry, null, null, $ort_kurzbz); + + $exist = $this->_ci->KalenderOrtModel->load(array('kalender_id' => $kalender_id)); if (hasData($exist)) { - return $this->_ci->KalenderOrtModel->update(array('kalender_id' => $kalender_id), - array ( - 'ort_kurzbz' => $ort_kurzbz - ) + return $this->_ci->KalenderOrtModel->update( + array('kalender_id' => $kalender_id), + array('ort_kurzbz' => $ort_kurzbz) ); } else { return $this->_addKalenderOrt($kalender_id, $ort_kurzbz); } - } - public function updateZeit($kalender_id, $start_date, $end_date) - { - /*TODO Checks: - Von-Tag muss gleich dem Bis-Tag sein - Bis darf nicht vor von liegen - History erstellen - Sync Status setzen - */ - $this->_ci->KalenderModel->update($kalender_id, - array ( - 'von' => $start_date, - 'bis' => $end_date, - 'updateamum'=> date('Y-m-d H:i:s'), - 'updatevon' => getAuthUID() - ) + public function updateStatus($kalender_id, $status_kurzbz) + { + $entryResult = $this->_loadKalenderEntry($kalender_id); + if (isError($entryResult)) return $entryResult; + + $kalender_entry = getData($entryResult); + + $allowed = array( + 'planning' => array('tosync_lektor', 'tosync_student'), + 'tosync_lektor' => array('tosync_student'), + 'tosync_student' => array('tosync_lektor'), + 'visible_lektor' => array('tosync_student'), ); + if (!isset($allowed[$kalender_entry->status_kurzbz]) || !in_array($status_kurzbz, $allowed[$kalender_entry->status_kurzbz])) + return error('Statuswechsel nicht erlaubt'); + + $result = $this->_ci->KalenderModel->update( + array('kalender_id' => $kalender_entry->kalender_id), + array('status_kurzbz' => $status_kurzbz) + ); + + if (isError($result)) return $result; + return success(); } + + private function _createHistoryEntry($kalender_entry, $start_date = null, $end_date = null, $ort_kurzbz = null) + { + $old_id = $kalender_entry->kalender_id; + + $kalenderresult = $this->_ci->KalenderModel->insert( + array( + 'von' => $start_date ? $start_date : $kalender_entry->von, + 'bis' => $end_date ? $end_date : $kalender_entry->bis, + 'typ' => 'lehreinheit', + 'status_kurzbz' => 'planning', + 'vorgaenger_kalender_id' => $old_id, + 'insertvon' => getAuthUID(), + 'insertamum' => date('Y-m-d H:i:s') + ) + ); + + if (!isSuccess($kalenderresult) || !hasData($kalenderresult)) + return $kalenderresult; + + $new_kalender_id = getData($kalenderresult); + + $kalenderlehreinheitresult = $this->_ci->KalenderLehreinheitModel->insert( + array( + 'kalender_id' => $new_kalender_id, + 'lehreinheit_id' => $kalender_entry->lehreinheit_id + ) + ); + + if (!isSuccess($kalenderlehreinheitresult)) + return $kalenderlehreinheitresult; + + $new_ort = $ort_kurzbz ? $ort_kurzbz : $kalender_entry->ort_kurzbz; + if (!is_null($new_ort) || !is_null($kalender_entry->location)) + { + $ortresult = $this->_ci->KalenderOrtModel->insert( + array( + 'kalender_id' => $new_kalender_id, + 'ort_kurzbz' => $new_ort, + 'location' => $kalender_entry->location + ) + ); + + if (!isSuccess($ortresult)) + return $ortresult; + } + + return success($new_kalender_id); + } + + private function _loadKalenderEntry($kalender_id) + { + $this->_ci->KalenderModel->addSelect('tbl_kalender.*, tbl_kalender_lehreinheit.lehreinheit_id, tbl_kalender_ort.ort_kurzbz, tbl_kalender_ort.location'); + $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_lehreinheit', 'tbl_kalender.kalender_id = tbl_kalender_lehreinheit.kalender_id'); + $this->_ci->KalenderModel->addJoin('lehre.tbl_kalender_ort', 'tbl_kalender.kalender_id = tbl_kalender_ort.kalender_id', 'LEFT'); + + $result = $this->_ci->KalenderModel->load(array('tbl_kalender.kalender_id' => $kalender_id)); + + if (isError($result)) return $result; + if (!hasData($result)) return error("Not found"); + + return success(getData($result)[0]); + } + + + + public function deleteEntry($kalender_id) + { + $result = $this->_ci->KalenderModel->load(array('tbl_kalender.kalender_id' => $kalender_id)); + + if (isError($result)) return $result; + + if (!hasData($result)) return error("Not found"); + + $entry = getData($result)[0]; + + if ($entry->typ === 'lehreinheit') + return $this->_deleteTypLehreinheit($entry); + } + + private function _deleteTypLehreinheit($entry) + { + $result_lehreinheit = $this->_ci->KalenderLehreinheitModel->loadWhere(array('kalender_id' => $entry->kalender_id)); + if (isError($result_lehreinheit)) return $result_lehreinheit; + $has_lehreinheit = hasData($result_lehreinheit) ? getData($result_lehreinheit)[0] : false; + + $result_ort = $this->_ci->KalenderOrtModel->loadWhere(array('kalender_id' => $entry->kalender_id)); + if (isError($result_ort)) return $result_ort; + $has_ort = hasData($result_ort) ? getData($result_ort)[0] : false; + + if ($entry->status_kurzbz === 'planning') + { + if ($has_ort) + $this->_deleteOrtEntry($has_ort); + + if ($has_lehreinheit) + $this->_deleteLehreinheitEntry($has_lehreinheit); + + $this->_ci->KalenderModel->delete(array('tbl_kalender.kalender_id' => $entry->kalender_id)); + } + else if ($entry->status_kurzbz === 'tosync_lektor' || $entry->status_kurzbz === 'tosync_student') + { + $history = $this->getHistory($entry->kalender_id); + $history = hasData($history) ? getData($history) : false; + + if ($has_ort) + $result = $this->_deleteOrtEntry($has_ort); + + if ($has_lehreinheit) + $result = $this->_deleteLehreinheitEntry($has_lehreinheit); + + $this->_ci->KalenderModel->delete(array('tbl_kalender.kalender_id' => $entry->kalender_id)); + } + else if ($entry->status_kurzbz === 'visible_lektor' || $entry->status_kurzbz === 'visible_student') + { + //TODO (david) überprüfen ob sinnvoll, verschwindet direkt in den ansichten (student, lecturer) + $result = $this->_ci->KalenderModel->update( + array('kalender_id' => $entry->kalender_id), + array('status_kurzbz' => 'todelete') + ); + } + + return success(); + } + + private function _deleteOrtEntry($entry) + { + return $this->_ci->KalenderOrtModel->delete(array('kalender_id' => $entry->kalender_id)); + + } + + private function _deleteLehreinheitEntry($entry) + { + return $this->_ci->KalenderLehreinheitModel->delete(array('kalender_id' => $entry->kalender_id)); + } + + public function getHistory($kalender_id, $only_previous = false) + { + $dbModel = new DB_Model(); + $history_entries = $dbModel->execReadOnlyQuery(' + WITH RECURSIVE + vorgaenger(kalender_id, vorgaenger_kalender_id) AS ( + SELECT kalender_id, vorgaenger_kalender_id + FROM lehre.tbl_kalender + WHERE kalender_id = ? + + UNION ALL + + SELECT k.kalender_id, k.vorgaenger_kalender_id + FROM lehre.tbl_kalender k + JOIN vorgaenger ON k.kalender_id = vorgaenger.vorgaenger_kalender_id + ), + nachfolger(kalender_id, vorgaenger_kalender_id) AS ( + SELECT kalender_id, vorgaenger_kalender_id + FROM lehre.tbl_kalender + WHERE kalender_id = ? + + UNION ALL + + SELECT k.kalender_id, k.vorgaenger_kalender_id + FROM lehre.tbl_kalender k + JOIN nachfolger ON k.vorgaenger_kalender_id = nachfolger.kalender_id + ) + SELECT tbl_kalender.*, + TO_CHAR(von, \'DD.MM.YYYY HH24:MI:SS\') as von, + TO_CHAR(bis, \'DD.MM.YYYY HH24:MI:SS\') as bis, + COALESCE(tbl_kalender_ort.ort_kurzbz, location) as ort + FROM ( + SELECT kalender_id FROM vorgaenger + UNION + SELECT kalender_id FROM nachfolger + ) combined + JOIN lehre.tbl_kalender USING(kalender_id) + LEFT JOIN lehre.tbl_kalender_ort USING(kalender_id) + ORDER BY kalender_id DESC + + ' . ($only_previous ? ' LIMIT 1' : ''), array($kalender_id, $kalender_id)); + + return $history_entries; + } + + //TODO in eine eigen Lib? + public function sync() + { + + $this->_ci->load->model('ressource/Kalender_model', 'KalenderModel'); + + $this->_ci->KalenderModel->db->where_in('status_kurzbz', array('tosync_student', 'tosync_lektor', 'todelete', 'planning', 'visible_lektor')); + $this->_ci->KalenderModel->addOrder('kalender_id', 'DESC'); + $to_update = $this->_ci->KalenderModel->load(); + + if (!hasData($to_update)) + return success(); + foreach (getData($to_update) as $entry) + { + if ($entry->status_kurzbz === 'todelete') + { + $this->_ci->KalenderModel->update(array('kalender_id' => $entry->kalender_id), array('status_kurzbz' => 'deleted')); + } + if ($entry->status_kurzbz === 'tosync_lektor') + { + $this->_ci->KalenderModel->update(array('kalender_id' => $entry->kalender_id), array('status_kurzbz' => 'visible_lektor')); + $this->_archiveVorgaenger($entry->vorgaenger_kalender_id, true); + } + + if ($entry->status_kurzbz === 'tosync_student' || $entry->status_kurzbz === 'planning') + { + $this->_ci->KalenderModel->update(array('kalender_id' => $entry->kalender_id), array('status_kurzbz' => 'visible_student')); + $this->_archiveVorgaenger($entry->vorgaenger_kalender_id, false); + } + + if ($entry->status_kurzbz === 'visible_lektor') + { + $current = getData($this->_ci->KalenderModel->load(array('kalender_id' => $entry->kalender_id)))[0]; + if ($current->status_kurzbz === 'archived') + continue; + + $this->_ci->KalenderModel->update(array('kalender_id' => $entry->kalender_id), array('status_kurzbz' => 'visible_student')); + $this->_archiveVorgaenger($entry->vorgaenger_kalender_id, false); + } + } + + return success(); + + + } + + private function _archiveVorgaenger($vorgaenger_kalender_id, $stop_at_visible_student = false) + { + if (!$vorgaenger_kalender_id) return; + + $current_id = $vorgaenger_kalender_id; + + while ($current_id) + { + $vorgaenger = $this->_ci->KalenderModel->load(array('kalender_id' => $current_id)); + if (!hasData($vorgaenger)) return; + + $vorgaenger = getData($vorgaenger)[0]; + + if ($stop_at_visible_student && $vorgaenger->status_kurzbz === 'visible_student') + return; + + if (in_array($vorgaenger->status_kurzbz, array('visible_lektor', 'visible_student'))) + { + $this->_ci->KalenderModel->update( + array('kalender_id' => $current_id), + array('status_kurzbz' => 'archived') + ); + } + + $current_id = $vorgaenger->vorgaenger_kalender_id; + } + } + } diff --git a/public/js/api/factory/tempus/kalender.js b/public/js/api/factory/tempus/kalender.js index 61d555db6..ff5d6ff88 100644 --- a/public/js/api/factory/tempus/kalender.js +++ b/public/js/api/factory/tempus/kalender.js @@ -8,6 +8,46 @@ export default { params: { ...filter, start_date, end_date } }; }, + getPlanLecturer(start_date, end_date) + { + return { + method: 'get', + url: '/api/frontend/v1/tempus/Kalender/getPlanLecturer', + params: { start_date, end_date } + }; + }, + getPlanStudent(start_date, end_date) + { + return { + method: 'get', + url: '/api/frontend/v1/tempus/Kalender/getPlanStudent', + params: { start_date, end_date } + }; + }, + + syncToLecturer(kalender_id) + { + return { + method: 'post', + url: '/api/frontend/v1/tempus/Kalender/syncToLecturer', + params: { kalender_id } + }; + }, + syncToStudent(kalender_id) + { + return { + method: 'post', + url: '/api/frontend/v1/tempus/Kalender/syncToStudent', + params: { kalender_id } + }; + }, + sync() + { + return { + method: 'post', + url: '/api/frontend/v1/tempus/Kalender/sync', + }; + }, getLektorZeitsperren(emp, start_date, end_date) { return { method: 'get', @@ -50,4 +90,19 @@ export default { }; }, + getHistory(kalender_id) { + return { + method: 'get', + url: '/api/frontend/v1/tempus/Kalender/getHistory', + params: { kalender_id } + }; + }, + deleteEntry(kalender_id) { + return { + method: 'post', + url: '/api/frontend/v1/tempus/Kalender/deleteEntry', + params: { kalender_id } + }; + }, + }; diff --git a/public/js/components/Calendar/Base/Grid/Line/Event.js b/public/js/components/Calendar/Base/Grid/Line/Event.js index 2ee172e76..9ed4d80df 100644 --- a/public/js/components/Calendar/Base/Grid/Line/Event.js +++ b/public/js/components/Calendar/Base/Grid/Line/Event.js @@ -86,7 +86,6 @@ export default { }); }, onRightClick(evt) { - this.contextMenu.show = true; this.contextMenu.x = evt.clientX; this.contextMenu.y = evt.clientY; diff --git a/public/js/components/Tempus/Tempus.js b/public/js/components/Tempus/Tempus.js index afd37c846..a9e2612b5 100644 --- a/public/js/components/Tempus/Tempus.js +++ b/public/js/components/Tempus/Tempus.js @@ -148,6 +148,8 @@ export default { visibleStatus: ['all'], selectedStudiensemester: this.studiensemester_kurzbz ?? this.defaultSemester, calendarDate: luxon.DateTime.now().setZone(this.config.timezone).toISODate(), + historyEntries: [], + previewRole: 'planer' } }, computed: { @@ -158,7 +160,27 @@ export default { label: 'Raumauswahl', icon: 'fa-solid fa-door-open', action: this.openRaumauswahl - } + }, + { + label: 'Sync to Lektor', + icon: 'fa-solid fa-chalkboard-user', + action: (orig) => this.$api.call(ApiKalender.syncToLecturer(orig.kalender_id)).then(() => this.$refs.calendar.resetEventLoader()) + }, + { + label: 'Sync to Student', + icon: 'fa-solid fa-user-graduate', + action: (orig) => this.$api.call(ApiKalender.syncToStudent(orig.kalender_id)).then(() => this.$refs.calendar.resetEventLoader()) + }, + { + label: 'History', + icon: 'fa-solid fa-clock-rotate-left', + action: this.openHistory + }, + { + label: 'Delete', + icon: 'fa-solid fa-calendar-xmark', + action: this.deleteEntry + }, ] }; }, @@ -196,9 +218,29 @@ export default { this.raumVorschlaege = result.data ?? []; this.$refs.raumModal.show(); - }); + }, + async deleteEntry(orig) + { + if (!orig?.kalender_id) + return; + await this.$api.call(ApiKalender.deleteEntry( + orig?.kalender_id + )).then(result => { + this.$refs.calendar.resetEventLoader(); + }); + }, + async openHistory(orig) + { + if (!orig?.kalender_id) + return; + await this.$api.call(ApiKalender.getHistory( + orig.kalender_id + )).then(result => { + this.historyEntries = result.data ?? []; + this.$refs.historyModel.show(); + }); }, async selectRaum(ort_kurzbz) { const orig = this.raumModal; @@ -308,6 +350,12 @@ export default { if (hasLektoren) filter.uid = this.lecturers.map(l => l.uid); + if (this.previewRole === 'lektor') + return [this.$api.call(ApiKalender.getPlanLecturer(start.toISODate(), end.toISODate()))]; + + if (this.previewRole === 'student') + return [this.$api.call(ApiKalender.getPlanStudent(start.toISODate(), end.toISODate()))]; + return [this.$api.call(ApiKalender.getPlan(filter, start.toISODate(), end.toISODate()))]; }, toDateTime(value, timezone){ @@ -396,6 +444,8 @@ export default { }, resizeHandler(payload) { + if (this.previewRole !== 'planer') //TODO (david) testzweck + return; const { item, start, end } = payload; const obj = item[0]; if (!obj?.orig?.kalender_id) @@ -412,6 +462,8 @@ export default { }, dropHandler(payload) { + if (this.previewRole !== 'planer') //TODO (david) testzweck + return; const { item, start, end } = payload; if (!item?.length) return alert("Keine Daten gedroppt"); @@ -568,6 +620,10 @@ export default { this.stg = null; this.show_stg = null; this.$refs.calendar.resetEventLoader(); + }, + triggerSync() + { + this.$api.call(ApiKalender.sync()).then(this.$refs.calendar.resetEventLoader()) } }, watch: { @@ -752,6 +808,36 @@ export default { :show-toggle-all="false" class="w-100" /> + +
+ + + + +
@@ -846,5 +932,29 @@ export default {

Keine freien Räume gefunden.

+ + + + +
` }; \ No newline at end of file diff --git a/system/dbupdate_3.4/46975_tempus.php b/system/dbupdate_3.4/46975_tempus.php index 3b6f85355..975c61a03 100644 --- a/system/dbupdate_3.4/46975_tempus.php +++ b/system/dbupdate_3.4/46975_tempus.php @@ -78,12 +78,15 @@ if(!$result = @$db->db_query("SELECT kalender_id FROM lehre.tbl_kalender LIMIT 1 COMMENT ON TABLE lehre.tbl_kalender_status IS 'Calender visibility Status'; INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'planning', E'planning', E'{\"In Planung\", \"Planning\"}', 1); - INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'tosync', E'tosync', E'{\"Zu synchronisieren\", \"To sync\"}', 2); - INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'todelete', E'todelete', E'{\"Zu löschen\", \"To delete\"}', 3); - INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'visible_lektor', E'Sichtbar für Lektoren', E'{\"Sichtbar für Lektoren\", \"Visible for lecturers\"}', 4); - INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'deleted', E'deleted', E'{\"Gelöscht\", \"Deleted\"}', 5); - INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'archived', E'archived', E'{\"Archiviert\", \"Archived\"}', 6); - INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'visible_student', E'Sichtbar für Studierende', E'{\"Sichtbar für Studierende\", \"Visible for students\"}', 7); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'tosync_lektor', E'tosync_lektor', E'{\"Zu synchronisieren Lektoren\", \"To sync lecturers\"}', 2); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'visible_lektor', E'Sichtbar für Lektoren', E'{\"Sichtbar für Lektoren\", \"Visible for lecturers\"}', 3); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'tosync_student', E'tosync_lektor', E'{\"Zu synchronisieren Studierende\", \"To sync students\"}', 4); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'visible_student', E'Sichtbar für Studierende', E'{\"Sichtbar für Studierende\", \"Visible for students\"}', 5); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'todelete', E'todelete', E'{\"Zu löschen\", \"To delete\"}', 6); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'deleted', E'deleted', E'{\"Gelöscht\", \"Deleted\"}', 7); + INSERT INTO lehre.tbl_kalender_status (status_kurzbz, bezeichnung, bezeichnung_mehrsprachig, sort) VALUES (E'archived', E'archived', E'{\"Archiviert\", \"Archived\"}', 8); + + ALTER TABLE lehre.tbl_kalender ADD CONSTRAINT tbl_kalender_status_fk FOREIGN KEY (status_kurzbz) REFERENCES lehre.tbl_kalender_status (status_kurzbz) MATCH FULL