From 6e9ee7cf814f7d8cba1e95b481abc6dbf7c9af89 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 3 May 2024 09:43:49 +0200 Subject: [PATCH 01/37] Notizcomponent: Api Controller for Notizzuordnungs_ids --- .../api/frontend/v1/notiz/Notiz.php | 384 ------------------ .../api/frontend/v1/notiz/NotizAnrechnung.php | 44 ++ .../api/frontend/v1/notiz/NotizBestellung.php | 43 ++ .../frontend/v1/notiz/NotizLehreinheit.php | 44 ++ .../frontend/v1/notiz/NotizMitarbeiter.php | 44 ++ .../api/frontend/v1/notiz/NotizPerson.php | 33 ++ .../api/frontend/v1/notiz/NotizPrestudent.php | 44 ++ .../api/frontend/v1/notiz/NotizProjekt.php | 32 ++ .../frontend/v1/notiz/NotizProjektphase.php | 32 ++ .../frontend/v1/notiz/NotizProjekttask.php | 32 ++ application/core/Notiz_Controller.php | 79 ++-- public/js/api/notiz.js | 22 +- public/js/api/notiz/anrechnung.js | 38 ++ public/js/api/notiz/bestellung.js | 38 ++ public/js/api/notiz/lehreinheit.js | 38 ++ public/js/api/notiz/mitarbeiter.js | 38 ++ public/js/api/notiz/person.js | 19 +- public/js/api/notiz/prestudent.js | 38 ++ public/js/api/notiz/projekt.js | 38 ++ public/js/api/notiz/projektphase.js | 38 ++ public/js/api/notiz/projekttask.js | 38 ++ .../Studentenverwaltung/Details/Notizen.js | 72 ++-- system/phrasesupdate.php | 22 + 23 files changed, 786 insertions(+), 464 deletions(-) delete mode 100644 application/controllers/api/frontend/v1/notiz/Notiz.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizBestellung.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizPerson.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizPrestudent.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizProjekt.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizProjektphase.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizProjekttask.php create mode 100644 public/js/api/notiz/anrechnung.js create mode 100644 public/js/api/notiz/bestellung.js create mode 100644 public/js/api/notiz/lehreinheit.js create mode 100644 public/js/api/notiz/mitarbeiter.js create mode 100644 public/js/api/notiz/prestudent.js create mode 100644 public/js/api/notiz/projekt.js create mode 100644 public/js/api/notiz/projektphase.js create mode 100644 public/js/api/notiz/projekttask.js diff --git a/application/controllers/api/frontend/v1/notiz/Notiz.php b/application/controllers/api/frontend/v1/notiz/Notiz.php deleted file mode 100644 index 2288766c4..000000000 --- a/application/controllers/api/frontend/v1/notiz/Notiz.php +++ /dev/null @@ -1,384 +0,0 @@ - ['admin:r', 'assistenz:r'], - 'getNotizen' => ['admin:r', 'assistenz:r'], - 'loadNotiz' => 'assistenz:r', // TODO(manu): self::PERM_LOGGED - 'addNewNotiz' => 'assistenz:r', // TODO(manu): self::PERM_LOGGED - 'updateNotiz' => 'assistenz:r', // TODO(manu): self::PERM_LOGGED - 'deleteNotiz' => ['admin:r', 'assistenz:r'], - 'loadDokumente' => ['admin:r', 'assistenz:r'], - 'getMitarbeiter' => ['admin:r', 'assistenz:r'] - ]); - - //Load Models - $this->load->model('person/Notiz_model', 'NotizModel'); - $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); - - // Load Libraries - $this->load->library('VariableLib', ['uid' => getAuthUID()]); - - // Load language phrases - $this->loadPhrases([ - 'ui' - ]); - } - - /* public function getUid() - { - $this->terminateWithSuccess(getAuthUID()); - }*/ - - - public function getNotizen($id, $type) - { - - //check if valid type - $result = $this->NotizzuordnungModel->isValidType($type); - if(isError($result)) - $this->terminateWithError($result->retval, self::ERROR_TYPE_GENERAL); - - //$this->terminateWithError(" after check type not valid", self::ERROR_TYPE_GENERAL); - $result = $this->NotizModel->getNotizWithDocEntries($id, $type); - - if (isError($result)) { - $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - return $this->terminateWithSuccess(getData($result) ?: []); - - // return $this->terminateWithError("type not valid", self::ERROR_TYPE_GENERAL); - - } - - /* public function loadNotiz() - { - $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); - - $notiz_id = $this->input->post('notiz_id'); - - //$this->load->model('person/Notiz_model', 'NotizModel'); - $this->NotizModel->addJoin('public.tbl_notiz_dokument', 'notiz_id', 'LEFT'); - $this->NotizModel->addSelect('*'); - $this->NotizModel->addSelect("TO_CHAR(CASE WHEN public.tbl_notiz.updateamum >= public.tbl_notiz.insertamum - THEN public.tbl_notiz.updateamum ELSE public.tbl_notiz.insertamum END::timestamp, 'DD.MM.YYYY HH24:MI:SS') AS lastUpdate"); - $this->NotizModel->addLimit(1); - - $result = $this->NotizModel->loadWhere( - array('notiz_id' => $notiz_id) - ); - if (isError($result)) - { - $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - elseif (!hasData($result)) - { - $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL); - } - else - { - $this->terminateWithSuccess(current(getData($result))); - } - } - - - public function updateNotiz() - { - $this->load->library('form_validation'); - $this->load->library('DmsLib'); - - if (isset($_POST['data'])) - { - $data = json_decode($_POST['data']); - unset($_POST['data']); - foreach ($data as $k => $v) { - $_POST[$k] = $v; - } - } - - $notiz_id = $this->input->post('notiz_id'); - - if(!$notiz_id) - { - $this->terminateWithError($this->p->t('ui','error_missingId',['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL); - } - - //Form Validation - $this->form_validation->set_rules('titel', 'Titel', 'required', [ - 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Titel']) - ]); - - $this->form_validation->set_rules('text', 'Text', 'required', [ - 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Text']) - ]); - - if ($this->form_validation->run() == false) - { - $this->terminateWithValidationErrors($this->form_validation->error_array()); - } - - //update Notiz - $uid = getAuthUID(); - $titel = $this->input->post('titel'); - $text = $this->input->post('text'); - $verfasser_uid = $this->input->post('verfasser'); - $bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid; - $erledigt = $this->input->post('erledigt'); - $start = $this->input->post('start'); - $ende = $this->input->post('ende'); - - $result = $this->NotizModel->update( - [ - 'notiz_id' => $notiz_id - ], - [ - 'titel' => $titel, - 'updatevon' => $uid, - 'updateamum' => date('c'), - 'text' => $text, - 'verfasser_uid' => $verfasser_uid, - 'bearbeiter_uid' => $bearbeiter_uid, - 'start' => $start, - 'ende' => $ende, - 'erledigt' => $erledigt - ] - ); - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - - //update(1) laden aller bereits mit dieser notiz_id verknüpften DMS-Einträge - $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); - $this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id'); - $dms_uploaded = null; - - $result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id)); - if (isError($result)) - { - $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - elseif (!hasData($result)) - { - $dms_id_arr = null; - } - else - { - $result = getData($result); - foreach($result as $doc) { - $dms_id_arr[] = array( - 'name' => $doc->name, - 'dms_id' => $doc->dms_id - ); - } - } - - foreach ($_FILES as $k => $file) - { - //update(2) alle neuen files (alle außer type application/x.fhc-dms+json) anhängen - if($file["type"] == 'application/x.fhc-dms+json') - { - $dms_uploaded[] = array( - 'name' => $file["name"] - ); - } - else - { - $dms = array( - 'kategorie_kurzbz' => 'notiz', - 'version' => 0, - 'name' => $file["name"], - 'mimetype' => $file["type"], - 'insertamum' => date('c'), - 'insertvon' => $uid - ); - - //Todo(manu) check if filetypes weiter eingeschränkt werden sollen - //Todo(manu)check name files: nicht gleiches file 2mal hochladen - $result = $this->dmslib->upload($dms, $k, array('*')); - - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - $dms_id = $result->retval['dms_id']; - - $result = $this->NotizdokumentModel->insert(array('notiz_id' => $notiz_id, 'dms_id' => $dms_id)); - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - } - } - - //update(3) check if Dateien gelöscht wurden - if(count($dms_uploaded) != count($dms_id_arr)) - { - if (count($dms_uploaded) == 0) - { - $filesDeleted = $dms_id_arr; - } - else - { - $upload_new_names = array_column($dms_uploaded, "name"); - - $filesDeleted = array_filter($dms_id_arr, function ($file) use ($upload_new_names) { - return !in_array($file["name"], $upload_new_names); - }); - } - - foreach ($filesDeleted as $file) - { - $result = $this->dmslib->removeAll($file['dms_id']); - - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - else - $this->outputJson($result); - } - } - return $this->terminateWithSuccess($result); - }*/ - - - /* public function deleteNotiz() - { - $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); - $notiz_id = $this->input->post('notiz_id'); - $type = $this->input->post('type_id'); - $id = $this->input->post('id'); - - //dms_id auslesen aus notizdokument wenn vorhanden - $dms_id_arr = []; - $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); - - $result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id)); - - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - - if(hasData($result)) - { - $result = getData($result); - foreach ($result as $doc) { - $dms_id_arr[] = $doc->dms_id; - } - } - - if($dms_id_arr) - { - $this->load->library('DmsLib'); - foreach($dms_id_arr as $dms_id) - { - $result = $this->dmslib->removeAll($dms_id); - - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - - $this->outputJson($result); - } - } - - //delete Notizzuordnung - if($type == "software_id") - { - // Loads extension Model - $this->load->model('extensions/FHC-Core-Softwarebereitstellung/Softwarenotizzuordnung_model', 'ExtensionnotizzuordnungModel'); - $result = $this->ExtensionnotizzuordnungModel->delete([ - 'notiz_id' => $notiz_id, - 'id' => strval($id) - ], - [ - 'type_id' => $type - ]); - - } - else - { - //notizzuordnungsid! - $result = $this->NotizzuordnungModel->delete(['notiz_id' => $notiz_id, $type => $id]); - } - - - $this->load->model('person/Notiz_model', 'NotizModel'); - //$this->NotizModel->addJoin('public.tbl_notizzuordnung', 'notiz_id'); - - //TODO (erweitern um Type_id) für Extensions, damit auch Notizzuordnung gelöscht werden kann - - //Löschen von Notiz - $result = $this->NotizModel->delete( - array('notiz_id' => $notiz_id) - ); - - if (isError($result)) - { - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - if(!hasData($result)) - { - return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); - } - - return $this->terminateWithSuccess(current(getData($result))); - }*/ - - /* public function loadDokumente() - { - $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); - $notiz_id = $this->input->post('notiz_id'); - - $this->NotizModel->addSelect('campus.tbl_dms_version.*'); - - $this->NotizModel->addJoin('public.tbl_notiz_dokument', 'ON (public.tbl_notiz_dokument.notiz_id = public.tbl_notiz.notiz_id)'); - $this->NotizModel->addJoin('campus.tbl_dms_version', 'ON (public.tbl_notiz_dokument.dms_id = campus.tbl_dms_version.dms_id)'); - - $result = $this->NotizModel->loadWhere( - array('public.tbl_notiz.notiz_id' => $notiz_id) - ); - if (isError($result)) { - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - - if(!hasData($result)) - { - return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); - } - return $this->terminateWithSuccess(getData($result)); - }*/ - - /* public function getMitarbeiter($searchString) - { - $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); - $result = $this->MitarbeiterModel->searchMitarbeiter($searchString); - if (isError($result)) { - $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - return $this->terminateWithSuccess($result); - }*/ - - public function isBerechtigt($id, $typeId) - { - if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) - { - $result = $this->p->t('lehre','error_keineSchreibrechte'); - - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - return success("berechtigt in überschreibender Funktion"); - /* return $this->terminateWithError('keine Berechtigung bro', self::ERROR_TYPE_GENERAL);*/ - } - -} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php b/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php new file mode 100644 index 000000000..b58020507 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php @@ -0,0 +1,44 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "anrechnung_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizBestellung.php b/application/controllers/api/frontend/v1/notiz/NotizBestellung.php new file mode 100644 index 000000000..483efd619 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizBestellung.php @@ -0,0 +1,43 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "bestellung_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php new file mode 100644 index 000000000..5c40af368 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -0,0 +1,44 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "lehreinheit_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php b/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php new file mode 100644 index 000000000..fd8ee3bbb --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php @@ -0,0 +1,44 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "mitarbeiter_uid") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizPerson.php b/application/controllers/api/frontend/v1/notiz/NotizPerson.php new file mode 100644 index 000000000..2cf1f2519 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizPerson.php @@ -0,0 +1,33 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "person_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + + return $this->outputJsonSuccess(true); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php new file mode 100644 index 000000000..d4f50e69c --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php @@ -0,0 +1,44 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "prestudent_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjekt.php b/application/controllers/api/frontend/v1/notiz/NotizProjekt.php new file mode 100644 index 000000000..180f58b1b --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizProjekt.php @@ -0,0 +1,32 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "projekt_kurzbz") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php b/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php new file mode 100644 index 000000000..071aae6a5 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php @@ -0,0 +1,32 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "projektphase_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php b/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php new file mode 100644 index 000000000..4d407051a --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php @@ -0,0 +1,32 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "projekttask_id") + { + return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/core/Notiz_Controller.php b/application/core/Notiz_Controller.php index 51d6854b7..8a93c4f0f 100644 --- a/application/core/Notiz_Controller.php +++ b/application/core/Notiz_Controller.php @@ -10,19 +10,20 @@ abstract class Notiz_Controller extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getUid' => ['admin:r', 'assistenz:r'], - 'getNotizen' => ['admin:r', 'assistenz:r'], - 'loadNotiz' => 'assistenz:r', // TODO(manu): self::PERM_LOGGED - 'addNewNotiz' => 'assistenz:r', // TODO(manu): self::PERM_LOGGED - 'updateNotiz' => 'assistenz:r', // TODO(manu): self::PERM_LOGGED - 'deleteNotiz' => ['admin:r', 'assistenz:r'], - 'loadDokumente' => ['admin:r', 'assistenz:r'], - 'getMitarbeiter' => ['admin:r', 'assistenz:r'], - 'isBerechtigt' => ['admin:r', 'assistenz:r'] + 'getUid' => self::PERM_LOGGED, + 'getNotizen' => self::PERM_LOGGED, + 'loadNotiz' => self::PERM_LOGGED, + 'addNewNotiz' => self::PERM_LOGGED, + 'updateNotiz' => self::PERM_LOGGED, + 'deleteNotiz' => ['admin:w', 'assistenz:w'], + 'loadDokumente' => ['admin:w', 'assistenz:w'], + 'getMitarbeiter' => self::PERM_LOGGED, + 'isBerechtigt' => self::PERM_LOGGED, ]); //Load Models $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); // Load Libraries $this->load->library('VariableLib', ['uid' => getAuthUID()]); @@ -39,7 +40,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller } - //Standardfall: für extensions überschreiben: speichern der Zuordnung in eigene Extensiontabelle angeben + //Override function for extensions protected function assignNotiz($notiz_id, $id, $type) { $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); @@ -55,7 +56,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller return success(getData($result)); } - //Standardfall: für extensions überschreiben: speichern der Zuordnung in eigene Extensiontabelle angeben + //Override function for extensions protected function deleteNotizzuordnung($notiz_id, $id, $type) { $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); @@ -72,11 +73,23 @@ abstract class Notiz_Controller extends FHCAPI_Controller } + //Override function for extensions + public function getNotizen($id, $type) + { + $result = $this->NotizzuordnungModel->isValidType($type); + if(isError($result)) + $this->terminateWithError($result->retval, self::ERROR_TYPE_GENERAL); - //TODO(manu) abstract - protected function getNotizen($id, $type) {} + $result = $this->NotizModel->getNotizWithDocEntries($id, $type); - //TODO(manu) to abstract + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess(getData($result) ?: []); + } + + + //Override function protected function isBerechtigt($id, $typeId){ return $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL); } @@ -144,7 +157,8 @@ abstract class Notiz_Controller extends FHCAPI_Controller $titel = $this->input->post('titel'); $text = $this->input->post('text'); $erledigt = $this->input->post('erledigt'); - $verfasser_uid = isset($_POST['verfasser_uid']) ? $_POST['verfasser_uid'] : $uid; + $verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid; + //$verfasser_uid = isset($_POST['verfasser_uid']) ? $_POST['verfasser_uid'] : $uid; $bearbeiter_uid = isset($_POST['bearbeiter_uid']) ? $_POST['bearbeiter_uid'] : null; $type = $this->input->post('typeId'); $start = $this->input->post('start'); @@ -153,7 +167,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller // Start DB transaction $this->db->trans_start(); - //Speichern der Notiz + //Save note $result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $verfasser_uid, "insertvon" => $verfasser_uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid)); @@ -165,7 +179,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $notiz_id = $result->retval; - //Speichern der Notizzuordnung + //save Notizzuordnung $result = $this->assignNotiz($notiz_id, $id, $type); if (isError($result)) @@ -174,7 +188,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } - //Speichern der Dokumente + //save Documents $dms_id_arr = []; foreach ($_FILES as $k => $file) { @@ -189,6 +203,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller //Todo(manu) check if filetypes weiter eingeschränkt werden sollen //Todo(manu)check name files: nicht gleiches file 2mal hochladen + //Todo define in dms component: readFile, downloadFile $result = $this->dmslib->upload($dms, $k, ['*']); /* $result = $this->dmslib->upload($dms, $k, ['application/pdf','application/x.fhc-dms+json']);*/ if (isError($result)) @@ -199,10 +214,9 @@ abstract class Notiz_Controller extends FHCAPI_Controller $dms_id_arr[] = $result->retval['dms_id']; } - //Eintrag in Notizdokument speichern + //save entry in Notizdokument if($dms_id_arr) { - // Loads model Notizdokument_model $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); foreach($dms_id_arr as $dms_id) { @@ -257,8 +271,8 @@ abstract class Notiz_Controller extends FHCAPI_Controller $uid = getAuthUID(); $titel = $this->input->post('titel'); $text = $this->input->post('text'); - $verfasser_uid = $this->input->post('verfasser_uid'); - $bearbeiter_uid = isset($_POST['bearbeiter_uid']) ? $_POST['bearbeiter_uid'] : $uid; + $verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid; + $bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid; $erledigt = $this->input->post('erledigt'); $start = $this->input->post('start'); $ende = $this->input->post('ende'); @@ -284,7 +298,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } - //update(1) laden aller bereits mit dieser notiz_id verknüpften DMS-Einträge + //update(1) loading all dms-entries with this notiz_id $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); $this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id'); $dms_uploaded = null; @@ -311,7 +325,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller foreach ($_FILES as $k => $file) { - //update(2) alle neuen files (alle außer type application/x.fhc-dms+json) anhängen + //update(2) attach all new files (except type application/x.fhc-dms+json) if($file["type"] == 'application/x.fhc-dms+json') { $dms_uploaded[] = array( @@ -331,6 +345,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller //Todo(manu) check if filetypes weiter eingeschränkt werden sollen //Todo(manu)check name files: nicht gleiches file 2mal hochladen + //Todo define in dms component: readFile, downloadFile $result = $this->dmslib->upload($dms, $k, array('*')); if (isError($result)) @@ -347,7 +362,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller } } - //update(3) check if Dateien gelöscht wurden + //update(3) check if all files have been deleted if(count($dms_uploaded) != count($dms_id_arr)) { if (count($dms_uploaded) == 0) @@ -387,12 +402,9 @@ abstract class Notiz_Controller extends FHCAPI_Controller $typeId = $this->input->post('type_id'); $id = $this->input->post('id'); - if(!$this->isBerechtigt($id, $typeId)) - { - $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), self::ERROR_TYPE_GENERAL); - } + //TODO(manu): define Permissions for deletion document if filecomponent finished - //dms_id auslesen aus notizdokument wenn vorhanden + //get dms_id from notizdokument $dms_id_arr = []; $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); @@ -416,7 +428,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller // Start DB transaction $this->db->trans_start(); - //return $this->terminateWithError("dms_id kommt: " . $notiz_id, self::ERROR_TYPE_GENERAL); $this->load->library('DmsLib'); @@ -444,7 +455,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->load->model('person/Notiz_model', 'NotizModel'); - //Löschen von Notiz + //Delete Note $result = $this->NotizModel->delete( array('notiz_id' => $notiz_id) ); @@ -465,10 +476,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller public function loadDokumente() { - if(!$this->isBerechtigt('$id', '$typeId')) - { - $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), self::ERROR_TYPE_GENERAL); - } $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); $notiz_id = $this->input->post('notiz_id'); diff --git a/public/js/api/notiz.js b/public/js/api/notiz.js index 9d210a8f9..b0a01e989 100644 --- a/public/js/api/notiz.js +++ b/public/js/api/notiz.js @@ -1,13 +1,29 @@ -//TODO(Manu) refactor with require or async +//TODO(Manu) refactor for extensions with require or async //sonst Error wenn extension file nicht vorhanden import person from "./notiz/person.js"; -import softwarenotiz from "../../extensions/FHC-Core-Softwarebereitstellung/js/api/softwarenotiz.js"; +import prestudent from "./notiz/prestudent.js"; +import mitarbeiter from "./notiz/mitarbeiter.js"; +import projekt from "./notiz/projekt.js"; +import anrechnung from "./notiz/anrechnung.js"; +import bestellung from "./notiz/bestellung.js"; +import lehreinheit from "./notiz/lehreinheit.js"; +import projektphase from "./notiz/projektphase.js"; +import projekttask from "./notiz/projekttask.js"; +//import softwarenotiz from "../../extensions/FHC-Core-Softwarebereitstellung/js/api/softwarenotiz.js"; //import pppnotiz from "../../extensions/FHC-Core-PEP/js/api/pppnotiz.js"; export default { person, - softwarenotiz, + prestudent, + mitarbeiter, + anrechnung, + bestellung, + lehreinheit, + projekt, + projektphase, + projekttask, +// softwarenotiz, // pppnotiz } \ No newline at end of file diff --git a/public/js/api/notiz/anrechnung.js b/public/js/api/notiz/anrechnung.js new file mode 100644 index 000000000..843017687 --- /dev/null +++ b/public/js/api/notiz/anrechnung.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizAnrechnung/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizAnrechnung/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizAnrechnung/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizAnrechnung/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/bestellung.js b/public/js/api/notiz/bestellung.js new file mode 100644 index 000000000..3f0f5268c --- /dev/null +++ b/public/js/api/notiz/bestellung.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizBestellung/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizBestellung/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizBestellung/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizBestellung/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/lehreinheit.js b/public/js/api/notiz/lehreinheit.js new file mode 100644 index 000000000..85b3187ae --- /dev/null +++ b/public/js/api/notiz/lehreinheit.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizLehreinheit/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizLehreinheit/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizLehreinheit/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizLehreinheit/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/mitarbeiter.js b/public/js/api/notiz/mitarbeiter.js new file mode 100644 index 000000000..ada9b0ae8 --- /dev/null +++ b/public/js/api/notiz/mitarbeiter.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizMitarbeiter/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizMitarbeiter/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizMitarbeiter/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizMitarbeiter/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/person.js b/public/js/api/notiz/person.js index be19b4ed9..62a3640f0 100644 --- a/public/js/api/notiz/person.js +++ b/public/js/api/notiz/person.js @@ -1,38 +1,41 @@ export default { getNotizen(url, config, params){ - return this.$fhcApi.get('api/frontend/v1/notiz/notiz/getNotizen/' + params.id + '/' + params.type); + return this.$fhcApi.get('api/frontend/v1/notiz/notizPerson/getNotizen/' + params.id + '/' + params.type); }, getUid(){ - return this.$fhcApi.get('api/frontend/v1/notiz/notiz/getUid/'); + return this.$fhcApi.get('api/frontend/v1/notiz/notizPerson/getUid/'); }, addNewNotiz(id, formData) { - return this.$fhcApi.post('api/frontend/v1/notiz/notiz/addNewNotiz/' + id, + return this.$fhcApi.post('api/frontend/v1/notiz/notizPerson/addNewNotiz/' + id, formData ); }, loadNotiz(notiz_id){ - return this.$fhcApi.post('api/frontend/v1/notiz/notiz/loadNotiz/', { + return this.$fhcApi.post('api/frontend/v1/notiz/notizPerson/loadNotiz/', { notiz_id }); }, loadDokumente(notiz_id){ - return this.$fhcApi.post('api/frontend/v1/notiz/notiz/loadDokumente/', { + return this.$fhcApi.post('api/frontend/v1/notiz/notizPerson/loadDokumente/', { notiz_id }); }, deleteNotiz(notiz_id, type_id, id){ - return this.$fhcApi.post('api/frontend/v1/notiz/notiz/deleteNotiz/', { + return this.$fhcApi.post('api/frontend/v1/notiz/notizPerson/deleteNotiz/', { notiz_id, type_id, id }); }, updateNotiz(notiz_id, formData){ - return this.$fhcApi.post('api/frontend/v1/notiz/notiz/updateNotiz/' + notiz_id, + return this.$fhcApi.post('api/frontend/v1/notiz/notizPerson/updateNotiz/' + notiz_id, formData ); }, getMitarbeiter(event){ - return this.$fhcApi.get('api/frontend/v1/notiz/notiz/getMitarbeiter/' + event); + return this.$fhcApi.get('api/frontend/v1/notiz/notizPerson/getMitarbeiter/' + event); + }, + isBerechtigt(id, type_id){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizPerson/isBerechtigt/'); } } \ No newline at end of file diff --git a/public/js/api/notiz/prestudent.js b/public/js/api/notiz/prestudent.js new file mode 100644 index 000000000..c529ea44e --- /dev/null +++ b/public/js/api/notiz/prestudent.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizPrestudent/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizPrestudent/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizPrestudent/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizPrestudent/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/projekt.js b/public/js/api/notiz/projekt.js new file mode 100644 index 000000000..ac8b71623 --- /dev/null +++ b/public/js/api/notiz/projekt.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/NotizProjekt/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/NotizProjekt/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/NotizProjekt/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/NotizProjekt/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/projektphase.js b/public/js/api/notiz/projektphase.js new file mode 100644 index 000000000..8b85106a3 --- /dev/null +++ b/public/js/api/notiz/projektphase.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizProjektphase/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizProjektphase/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjektphase/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizProjektphase/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/api/notiz/projekttask.js b/public/js/api/notiz/projekttask.js new file mode 100644 index 000000000..6b6db3c77 --- /dev/null +++ b/public/js/api/notiz/projekttask.js @@ -0,0 +1,38 @@ +export default { + getNotizen(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizProjekttask/getNotizen/' + params.id + '/' + params.type); + }, + getUid(){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizProjekttask/getUid/'); + }, + addNewNotiz(id, formData) { + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/addNewNotiz/' + id, + formData + ); + }, + loadNotiz(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/loadNotiz/', { + notiz_id + }); + }, + loadDokumente(notiz_id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/loadDokumente/', { + notiz_id + }); + }, + deleteNotiz(notiz_id, type_id, id){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/deleteNotiz/', { + notiz_id, + type_id, + id + }); + }, + updateNotiz(notiz_id, formData){ + return this.$fhcApi.post('api/frontend/v1/notiz/notizProjekttask/updateNotiz/' + notiz_id, + formData + ); + }, + getMitarbeiter(event){ + return this.$fhcApi.get('api/frontend/v1/notiz/notizProjekttask/getMitarbeiter/' + event); + } +} \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Notizen.js b/public/js/components/Stv/Studentenverwaltung/Details/Notizen.js index 4c128bfea..185b8d0d5 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Notizen.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Notizen.js @@ -11,20 +11,6 @@ export default {

Notizen

- - - + - - diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index ba4dcfa01..e4d6d1870 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -27781,6 +27781,28 @@ array( ) ) ), + + //**************************** FHC-Core-Notizcomponent + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'error_typeNotizIdIncorrect', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Id-Typ der Notiz ist nicht korrekt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Id type of note is incorrect', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); From 4a8868a709b2f07c7ace3bb8772e9815fe55ad70 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Mon, 21 Jul 2025 15:29:57 +0200 Subject: [PATCH 02/37] verfasser nur noch readonly - wird im backend gesetzt --- .../api/frontend/v1/notiz/NotizAnrechnung.php | 6 +- .../api/frontend/v1/notiz/NotizBestellung.php | 6 +- .../frontend/v1/notiz/NotizLehreinheit.php | 6 +- .../frontend/v1/notiz/NotizMitarbeiter.php | 6 +- .../api/frontend/v1/notiz/NotizPerson.php | 6 +- .../api/frontend/v1/notiz/NotizPrestudent.php | 6 +- .../api/frontend/v1/notiz/NotizProjekt.php | 6 +- .../frontend/v1/notiz/NotizProjektphase.php | 6 +- .../frontend/v1/notiz/NotizProjekttask.php | 6 +- application/core/Notiz_Controller.php | 101 ++++++-------- public/js/components/Notiz/Notiz.js | 125 ++++++------------ .../Studentenverwaltung/Details/Notizen.js | 2 +- 12 files changed, 114 insertions(+), 168 deletions(-) diff --git a/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php b/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php index b58020507..30dae9a50 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php +++ b/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php @@ -29,7 +29,7 @@ class NotizAnrechnung extends Notiz_Controller { if($typeId != "anrechnung_id") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -37,8 +37,8 @@ class NotizAnrechnung extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizBestellung.php b/application/controllers/api/frontend/v1/notiz/NotizBestellung.php index 483efd619..e30628f33 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizBestellung.php +++ b/application/controllers/api/frontend/v1/notiz/NotizBestellung.php @@ -29,15 +29,15 @@ class NotizBestellung extends Notiz_Controller { if($typeId != "bestellung_id") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php index 5c40af368..a9c97532f 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -29,7 +29,7 @@ class NotizLehreinheit extends Notiz_Controller { if($typeId != "lehreinheit_id") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -37,8 +37,8 @@ class NotizLehreinheit extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php b/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php index fd8ee3bbb..f7de4b47b 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php +++ b/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php @@ -29,7 +29,7 @@ class NotizMitarbeiter extends Notiz_Controller { if($typeId != "mitarbeiter_uid") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -37,8 +37,8 @@ class NotizMitarbeiter extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizPerson.php b/application/controllers/api/frontend/v1/notiz/NotizPerson.php index e67f953d6..80db4d8eb 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizPerson.php +++ b/application/controllers/api/frontend/v1/notiz/NotizPerson.php @@ -25,17 +25,17 @@ class NotizPerson extends Notiz_Controller { if($typeId != "person_id") { - return $this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission if (!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) { $result = $this->p->t('lehre', 'error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->outputJsonSuccess(true); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } public function loadDokumente() diff --git a/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php index d4f50e69c..fc601770d 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php +++ b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php @@ -29,7 +29,7 @@ class NotizPrestudent extends Notiz_Controller { if($typeId != "prestudent_id") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -37,8 +37,8 @@ class NotizPrestudent extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjekt.php b/application/controllers/api/frontend/v1/notiz/NotizProjekt.php index 180f58b1b..9cdde36ae 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizProjekt.php +++ b/application/controllers/api/frontend/v1/notiz/NotizProjekt.php @@ -17,7 +17,7 @@ class NotizProjekt extends Notiz_Controller { if($typeId != "projekt_kurzbz") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -25,8 +25,8 @@ class NotizProjekt extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php b/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php index 071aae6a5..7a82c658e 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php +++ b/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php @@ -17,7 +17,7 @@ class NotizProjektphase extends Notiz_Controller { if($typeId != "projektphase_id") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -25,8 +25,8 @@ class NotizProjektphase extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php b/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php index 4d407051a..aadb04f40 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php +++ b/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php @@ -17,7 +17,7 @@ class NotizProjekttask extends Notiz_Controller { if($typeId != "projekttask_id") { - return $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } //TODO define permission @@ -25,8 +25,8 @@ class NotizProjekttask extends Notiz_Controller { $result = $this->p->t('lehre','error_keineSchreibrechte'); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } } \ No newline at end of file diff --git a/application/core/Notiz_Controller.php b/application/core/Notiz_Controller.php index fc8f79540..baf987abc 100644 --- a/application/core/Notiz_Controller.php +++ b/application/core/Notiz_Controller.php @@ -96,13 +96,13 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess(getData($result) ?: []); + $this->terminateWithSuccess(getData($result) ?: []); } //Override function protected function isBerechtigt($id, $typeId){ - return $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL); + $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL); } public function loadNotiz() @@ -142,14 +142,9 @@ abstract class Notiz_Controller extends FHCAPI_Controller $uid = getAuthUID(); - if (isset($_POST['data'])) - { - $data = json_decode($_POST['data']); - unset($_POST['data']); - foreach ($data as $k => $v) { - $_POST[$k] = $v; - } - } + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $this->form_validation->set_data($post_data); //Form Validation $this->form_validation->set_rules('titel', 'Titel', 'required', [ @@ -165,26 +160,25 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->terminateWithValidationErrors($this->form_validation->error_array()); } - $titel = $this->input->post('titel'); - $text = $this->input->post('text'); - $erledigt = $this->input->post('erledigt'); - $verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid; - $bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : null; - $type = $this->input->post('typeId'); - $start = $this->input->post('start'); - $ende = $this->input->post('ende'); + $titel = $post_data['titel']; + $text = $post_data['text']; + $erledigt = $post_data['erledigt']; + $bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : null; + $type = $post_data['typeId']; + $start = isset($post_data['start']) ? $post_data['start'] : null; + $ende = isset($post_data['ende']) ? $post_data['ende'] : null; // Start DB transaction $this->db->trans_start(); //Save note - $result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $verfasser_uid, - "insertvon" => $verfasser_uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid)); + $result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $uid, + "insertvon" => $uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid)); if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } $notiz_id = $result->retval; @@ -219,7 +213,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } $dms_id_arr[] = $result->retval['dms_id']; } @@ -234,12 +228,12 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } } } $this->db->trans_commit(); - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } public function updateNotiz() @@ -247,21 +241,14 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->load->library('form_validation'); $this->load->library('DmsLib'); - if (isset($_POST['data'])) - { - $data = json_decode($_POST['data']); - unset($_POST['data']); - foreach ($data as $k => $v) { - $_POST[$k] = $v; - } - } + $json = $this->input->post('data'); + $post_data = json_decode($json, true); - $notiz_id = $this->input->post('notiz_id'); + $this->form_validation->set_data($post_data); - if(!$notiz_id) - { - $this->terminateWithError($this->p->t('ui','error_missingId',['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL); - } + $this->form_validation->set_rules('notiz_id', 'Notiz ID', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'notiz_id']) + ]); //Form Validation $this->form_validation->set_rules('titel', 'Titel', 'required', [ @@ -279,25 +266,23 @@ abstract class Notiz_Controller extends FHCAPI_Controller //update Notiz $uid = getAuthUID(); - $titel = $this->input->post('titel'); - $text = $this->input->post('text'); - $verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid; - $bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid; - $erledigt = $this->input->post('erledigt'); - $start = $this->input->post('start'); - $ende = $this->input->post('ende'); + $titel = $post_data['titel']; + $text = $post_data['text']; + $bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : $post_data['bearbeiter_uid']; + $erledigt = $post_data['erledigt']; + $start = $post_data['start']; + $ende = $post_data['ende']; $result = $this->NotizModel->update( [ - 'notiz_id' => $notiz_id + 'notiz_id' => $post_data['notiz_id'], ], [ 'titel' => $titel, 'updatevon' => $uid, 'updateamum' => date('c'), 'text' => $text, - 'verfasser_uid' => $verfasser_uid, - 'bearbeiter_uid' => $bearbeiter_uid, + 'bearbeiter_uid' => isEmptyString($bearbeiter_uid) ? null : $bearbeiter_uid, 'start' => $start, 'ende' => $ende, 'erledigt' => $erledigt @@ -305,7 +290,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller ); if (isError($result)) { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } //update(1) loading all dms-entries with this notiz_id @@ -313,7 +298,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); $this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id'); - $result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id)); + $result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $post_data['notiz_id'])); $result = $this->getDataOrTerminateWithError($result); foreach ($result as $doc) { $dms_id_arr[$doc->dms_id] = array( @@ -350,7 +335,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $result = $this->getDataOrTerminateWithError($result); $dms_id = $result['dms_id']; - $result = $this->NotizdokumentModel->insert(array('notiz_id' => $notiz_id, 'dms_id' => $dms_id)); + $result = $this->NotizdokumentModel->insert(array('notiz_id' => $post_data['notiz_id'], 'dms_id' => $dms_id)); $this->getDataOrTerminateWithError($result); } @@ -364,7 +349,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->getDataOrTerminateWithError($result); } - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } public function deleteNotiz() @@ -415,15 +400,15 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } if(!hasData($result)) { - return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); } $this->db->trans_complete(); - return $this->terminateWithSuccess(getData($result)); + $this->terminateWithSuccess(getData($result)); } public function loadDokumente() @@ -439,14 +424,14 @@ abstract class Notiz_Controller extends FHCAPI_Controller array('public.tbl_notiz.notiz_id' => $notiz_id) ); if (isError($result)) { - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } if(!hasData($result)) { - return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess(getData($result)); + $this->terminateWithSuccess(getData($result)); } public function getMitarbeiter($searchString) @@ -456,7 +441,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } } diff --git a/public/js/components/Notiz/Notiz.js b/public/js/components/Notiz/Notiz.js index 13e969c50..00e66813f 100644 --- a/public/js/components/Notiz/Notiz.js +++ b/public/js/components/Notiz/Notiz.js @@ -1,5 +1,4 @@ import VueDatePicker from '../vueDatepicker.js.php'; -import PvAutoComplete from "../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js"; import FormUploadDms from '../Form/Upload/Dms.js'; import {CoreFilterCmpt} from "../filter/Filter.js"; import BsModal from "../Bootstrap/Modal.js"; @@ -11,7 +10,6 @@ export default { components: { CoreFilterCmpt, VueDatePicker, - PvAutoComplete, FormUploadDms, FormForm, FormInput, @@ -281,6 +279,7 @@ export default { showId: false, showLastupdate: false }, + currentVerfasserUid: null } }, methods: { @@ -308,8 +307,6 @@ export default { this.notizData.bis = this.notizen.ende; this.notizData.document = this.notizen.dms_id; this.notizData.erledigt = this.notizen.erledigt; - this.notizData.verfasser = this.notizen.verfasser_uid; - this.notizData.intVerfasser = this.notizen.verfasser_uid; this.notizData.intBearbeiter = this.notizen.bearbeiter_uid; this.notizData.bearbeiter = this.notizen.bearbeiter_uid; } @@ -373,6 +370,7 @@ export default { this.notizData = result.data; this.notizData.typeId = this.typeId; this.notizData.anhang = []; + this.currentVerfasserUid = result.data.verfasser_uid; return result; }) .catch(this.$fhcAlert.handleSystemError); @@ -425,16 +423,17 @@ export default { bis: null, document: null, erledigt: false, - verfasser: this.uid, bearbeiter: null, - anhang: [] + anhang: [], }; + this.currentVerfasserUid = this.uid }, getUid() { return this.$api .call(this.endpoint.getUid()) .then(result => { - this.notizData.intVerfasser = result.data; + this.currentVerfasserUid = result.data; + this.uid = result.data; }) .catch(this.$fhcAlert.handleSystemError); }, @@ -518,14 +517,7 @@ export default { }, deep: true }, - 'notizData.intVerfasser': { - handler(newVal) { - if (typeof newVal === 'object') { - this.notizData.verfasser = newVal.mitarbeiter_uid; - } - }, - deep: true - }, + id() { this.reload(); } @@ -627,24 +619,23 @@ export default {
-
- -
-
- +
+
- + > +
@@ -652,26 +643,35 @@ export default {
- +
- + +
- - + > +
@@ -811,28 +811,15 @@ export default {
- - - - + - - - @@ -1164,28 +1138,15 @@ export default {
- - - - + Date: Wed, 1 Oct 2025 13:13:41 +0200 Subject: [PATCH 03/37] add new api for notiz --- .../frontend/v1/notiz/NotizLehreinheit.php | 5 ++++ public/js/api/factory/notiz/anrechnung.js | 29 +++++++++++++++++++ public/js/api/factory/notiz/bestellung.js | 29 +++++++++++++++++++ public/js/api/factory/notiz/mitarbeiter.js | 29 +++++++++++++++++++ public/js/api/factory/notiz/prestudent.js | 29 +++++++++++++++++++ public/js/api/factory/notiz/projekt.js | 29 +++++++++++++++++++ public/js/api/factory/notiz/projektphase.js | 29 +++++++++++++++++++ public/js/api/factory/notiz/projekttask.js | 29 +++++++++++++++++++ 8 files changed, 208 insertions(+) create mode 100644 public/js/api/factory/notiz/anrechnung.js create mode 100644 public/js/api/factory/notiz/bestellung.js create mode 100644 public/js/api/factory/notiz/mitarbeiter.js create mode 100644 public/js/api/factory/notiz/prestudent.js create mode 100644 public/js/api/factory/notiz/projekt.js create mode 100644 public/js/api/factory/notiz/projektphase.js create mode 100644 public/js/api/factory/notiz/projekttask.js diff --git a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php index 4354562b6..e011c6d60 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -25,6 +25,11 @@ class NotizLehreinheit extends Notiz_Controller // Load Libraries $this->load->library('VariableLib', ['uid' => getAuthUID()]); + //Permission checks for allowed Oes +/* $allowedOes = $this->permissionlib->getOE_isEntitledFor('assistenz') ?: []; + + $this->terminateWithSuccess($allowedOes);*/ + // Load language phrases $this->loadPhrases([ 'ui' diff --git a/public/js/api/factory/notiz/anrechnung.js b/public/js/api/factory/notiz/anrechnung.js new file mode 100644 index 000000000..ba458abf5 --- /dev/null +++ b/public/js/api/factory/notiz/anrechnung.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizAnrechnung/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; diff --git a/public/js/api/factory/notiz/bestellung.js b/public/js/api/factory/notiz/bestellung.js new file mode 100644 index 000000000..3d94a7c25 --- /dev/null +++ b/public/js/api/factory/notiz/bestellung.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizBestellung/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/factory/notiz/mitarbeiter.js b/public/js/api/factory/notiz/mitarbeiter.js new file mode 100644 index 000000000..6ddb89af7 --- /dev/null +++ b/public/js/api/factory/notiz/mitarbeiter.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizMitarbeiter/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/factory/notiz/prestudent.js b/public/js/api/factory/notiz/prestudent.js new file mode 100644 index 000000000..f117a77ff --- /dev/null +++ b/public/js/api/factory/notiz/prestudent.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizPrestudent/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/factory/notiz/projekt.js b/public/js/api/factory/notiz/projekt.js new file mode 100644 index 000000000..f1dab754d --- /dev/null +++ b/public/js/api/factory/notiz/projekt.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizProjekt/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/factory/notiz/projektphase.js b/public/js/api/factory/notiz/projektphase.js new file mode 100644 index 000000000..6762e8456 --- /dev/null +++ b/public/js/api/factory/notiz/projektphase.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizProjektphase/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/factory/notiz/projekttask.js b/public/js/api/factory/notiz/projekttask.js new file mode 100644 index 000000000..27a74bb08 --- /dev/null +++ b/public/js/api/factory/notiz/projekttask.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizProjekttask/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; \ No newline at end of file From e79bb607d940412a4ba5647acaed8a9789196a99 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 3 Oct 2025 10:23:25 +0200 Subject: [PATCH 04/37] add permission validation oe for lehreinheit --- .../frontend/v1/notiz/NotizLehreinheit.php | 75 ++++++++++++++++++- application/core/Notiz_Controller.php | 2 +- public/js/api/factory/notiz/lehreinheit.js | 25 +++++++ public/js/components/Notiz/Notiz.js | 4 + 4 files changed, 101 insertions(+), 5 deletions(-) diff --git a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php index e011c6d60..a3b96d477 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -21,14 +21,67 @@ class NotizLehreinheit extends Notiz_Controller //Load Models $this->load->model('person/Notiz_model', 'NotizModel'); $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); // Load Libraries $this->load->library('VariableLib', ['uid' => getAuthUID()]); //Permission checks for allowed Oes -/* $allowedOes = $this->permissionlib->getOE_isEntitledFor('assistenz') ?: []; + $allowedOes = $this->permissionlib->getOE_isEntitledFor('assistenz') ?: []; - $this->terminateWithSuccess($allowedOes);*/ + if ($this->router->method == 'addNewNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $lehreinheit_id = $post_data['id']; + + if(!$lehreinheit_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes); + } + + if ($this->router->method == 'updateNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $notiz_id = $post_data['notiz_id']; + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + //get lehreinheit_id + $result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]); + + $data = $this->getDataOrTerminateWithError($result); + $lehreinheit_id = current($data)->lehreinheit_id; + + if(!$lehreinheit_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes); + } + + if ($this->router->method == 'deleteNotiz') + { + $notiz_id = $this->input->post('notiz_id'); + $lehreinheit_id = $this->input->post('id'); + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + if(!$lehreinheit_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes); + } // Load language phrases $this->loadPhrases([ @@ -36,14 +89,26 @@ class NotizLehreinheit extends Notiz_Controller ]); } + private function _checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes) + { + //get oe from lehreinheit + $result = $this->LehreinheitModel->getOes($lehreinheit_id); + $data = $this->getDataOrTerminateWithError($result); + $oes = current($data); + + if (!in_array($oes, $allowedOes)) + { + return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg') . " " . $oes, self::ERROR_TYPE_GENERAL); + } + } + public function isBerechtigt($id, $typeId) { - if($typeId != "lehreinheit_id") + if($typeId != "lehreinheit_id") { $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } - //TODO define permission if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) { $result = $this->p->t('lehre','error_keineSchreibrechte'); @@ -52,4 +117,6 @@ class NotizLehreinheit extends Notiz_Controller } $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } + + } diff --git a/application/core/Notiz_Controller.php b/application/core/Notiz_Controller.php index daee7c334..923970923 100644 --- a/application/core/Notiz_Controller.php +++ b/application/core/Notiz_Controller.php @@ -112,7 +112,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller $notiz_id = $this->input->post('notiz_id'); - //$this->load->model('person/Notiz_model', 'NotizModel'); $this->NotizModel->addJoin('public.tbl_notiz_dokument', 'notiz_id', 'LEFT'); $this->NotizModel->addSelect('*'); $this->NotizModel->addSelect("TO_CHAR(CASE WHEN public.tbl_notiz.updateamum >= public.tbl_notiz.insertamum @@ -239,6 +238,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller public function updateNotiz() { + $this->load->library('form_validation'); $this->load->library('DmsLib'); diff --git a/public/js/api/factory/notiz/lehreinheit.js b/public/js/api/factory/notiz/lehreinheit.js index d93bb50f9..762e5c596 100644 --- a/public/js/api/factory/notiz/lehreinheit.js +++ b/public/js/api/factory/notiz/lehreinheit.js @@ -26,4 +26,29 @@ export default { url: 'api/frontend/v1/notiz/notizLehreinheit/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) }; }, + addNewNotiz(lehreinheit_id, params) { + return { + method: 'post', + url: 'api/frontend/v1/notiz/notizLehreinheit/addNewNotiz/' + lehreinheit_id, + params + }; + }, + updateNotiz(notiz_id, params) { + return { + method: 'post', + url: 'api/frontend/v1/notiz/notizLehreinheit/updateNotiz/' + notiz_id, + params + }; + }, + deleteNotiz(notiz_id, type_id, id) { + return { + method: 'post', + url: 'api/frontend/v1/notiz/notizLehreinheit/deleteNotiz/', + params: { + notiz_id, + type_id, + id + } + }; + }, }; diff --git a/public/js/components/Notiz/Notiz.js b/public/js/components/Notiz/Notiz.js index a8038e774..c24402b33 100644 --- a/public/js/components/Notiz/Notiz.js +++ b/public/js/components/Notiz/Notiz.js @@ -267,6 +267,7 @@ export default { editor: null, notizData: { typeId: this.typeId, + id: this.id, titel: null, statusNew: true, text: '', @@ -344,6 +345,7 @@ export default { }, addNewNotiz() { const formData = new FormData(); + this.notizData.id = this.id; formData.append('data', JSON.stringify(this.notizData)); Object.entries(this.notizData.anhang).forEach(([k, v]) => formData.append(k, v)); @@ -1171,6 +1173,7 @@ export default { container-class="col-6" :label="$p.t('notiz', 'bearbeiter')" v-model="notizData.bearbeiter_uid" + name="bearbeiter" minlength="3" > @@ -1184,6 +1187,7 @@ export default { :suggestions="filteredMitarbeiter" @complete="search" optionLabel="mitarbeiter" + name="bearbeiter" minlength="3" > From 984d81edb6c4312afe332eb3e7deeeb01b9e11de Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 6 Oct 2025 16:37:17 +0200 Subject: [PATCH 05/37] add tag component to List.js, add column tags to table, add functionality add, delete and update --- application/config/stv.php | 7 + .../controllers/api/frontend/v1/stv/Tags.php | 80 +++++ application/views/Studentenverwaltung.php | 4 +- public/js/api/factory/stv/tag.js | 54 +++ .../Stv/Studentenverwaltung/List.js | 317 +++++++++++++++++- 5 files changed, 456 insertions(+), 6 deletions(-) create mode 100644 application/controllers/api/frontend/v1/stv/Tags.php create mode 100644 public/js/api/factory/stv/tag.js diff --git a/application/config/stv.php b/application/config/stv.php index 42afc318c..d9519bd6e 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -113,3 +113,10 @@ $config['students_tab_order'] = [ 'finalexam', 'archive', ]; + +$config['stv_prestudent_tags'] = [ + 'tag_1' => ['readonly' => false], + 'tag_2' => ['readonly' => true], + 'tag_3' => ['readonly' => false], + 'tag_4' => ['readonly' => true] +]; diff --git a/application/controllers/api/frontend/v1/stv/Tags.php b/application/controllers/api/frontend/v1/stv/Tags.php new file mode 100644 index 000000000..397b2abbe --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Tags.php @@ -0,0 +1,80 @@ + self::BERECHTIGUNG_KURZBZ, + 'getTags' => self::BERECHTIGUNG_KURZBZ, + 'addTag' => self::BERECHTIGUNG_KURZBZ, + 'updateTag' => self::BERECHTIGUNG_KURZBZ, + 'doneTag' => self::BERECHTIGUNG_KURZBZ, + 'deleteTag' => self::BERECHTIGUNG_KURZBZ, +/* 'updateLehre' => self::BERECHTIGUNG_KURZBZ, + 'doneLehre' => self::BERECHTIGUNG_KURZBZ, + 'deleteLehre' => self::BERECHTIGUNG_KURZBZ,*/ + ]); + + $this->config->load('lvverwaltung'); + } + public function getTag($readonly_tags = null) + { + parent::getTag($this->config->item('lvverwaltung_tags')); + } + public function getTags($tags = null) + { + parent::getTags($this->config->item('lvverwaltung_tags')); + } + public function addTag($withZuordnung = true, $updatable_tags = null) + { + parent::addTag(true, $this->config->item('lvverwaltung_tags')); + } + public function updateTag($updatable_tags = null) + { + parent::updateTag($this->config->item('lvverwaltung_tags')); + } + public function deleteTag($withZuordnung = true, $updatable_tags = null) + { + parent::deleteTag(true, $this->config->item('lvverwaltung_tags')); + } + public function doneTag($updatable_tags = null) + { + parent::doneTag($this->config->item('lvverwaltung_tags')); + } + + /*$this->config->load('stv'); + } + + public function getTag($readonly_tags = null) + { + // console.log("in this endpoint. getTags"); + parent::getTag($this->config->item('stv_prestudent_tags')); + } + public function getTags($tags = null) + { + // $this->terminateWithError(" IN TAGS.PHP ", self::ERROR_TYPE_GENERAL); + parent::getTags($this->config->item('stv_prestudent_tags')); + } + public function addTag($withZuordnung = true, $updatable_tags = null) + { + parent::addTag(true, $this->config->item('stv_prestudent_tags')); + } + public function updateTag($updatable_tags = null) + { + parent::updateTag($this->config->item('stv_prestudent_tags')); + } + public function deleteTag($withZuordnung = true, $updatable_tags = null) + { + parent::deleteTag(true, $this->config->item('stv_prestudent_tags')); + } + public function doneTag($updatable_tags = null) + { + parent::doneTag($this->config->item('stv_prestudent_tags')); + }*/ +} diff --git a/application/views/Studentenverwaltung.php b/application/views/Studentenverwaltung.php index 01e611657..3c4938c0d 100644 --- a/application/views/Studentenverwaltung.php +++ b/application/views/Studentenverwaltung.php @@ -14,12 +14,14 @@ 'ui', 'notiz', ), + 'tags' => true, 'customCSSs' => [ #datepicker fuer component functions 'public/css/components/vue-datepicker.css', 'public/css/components/primevue.css', 'public/css/Studentenverwaltung.css', - 'public/css/components/function.css' + 'public/css/components/function.css', + //'public/css/Lvverwaltung.css' //css tags? ], 'customJSs' => [ 'vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js' diff --git a/public/js/api/factory/stv/tag.js b/public/js/api/factory/stv/tag.js new file mode 100644 index 000000000..29675f6d4 --- /dev/null +++ b/public/js/api/factory/stv/tag.js @@ -0,0 +1,54 @@ +export default { + + getTag(data) + { + return { + method: 'get', + url: 'api/frontend/v1/stv/Tags/getTag', + params: data + }; + }, + + getTags(data) + { + return { + method: 'get', + url: 'api/frontend/v1/stv/Tags/getTags' + }; + }, + + addTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/stv/Tags/addTag', + params: data + }; + }, + + updateTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/stv/Tags/updateTag', + params: data + }; + }, + doneTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/stv/Tags/doneTag', + params: data + }; + }, + + deleteTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/stv/Tags/deleteTag', + params: data + }; + }, +}; \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 67cada523..3d46dc32f 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -1,12 +1,17 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import ListNew from './List/New.js'; +import CoreTag from '../../Tag/Tag.js'; +import { tagHeaderFilter } from "../../../tabulator/filters/extendedHeaderFilter.js"; +import { extendedHeaderFilter } from "../../../tabulator/filters/extendedHeaderFilter.js"; +import ApiTag from "../../../api/factory/stv/tag.js"; export default { name: "ListPrestudents", components: { CoreFilterCmpt, - ListNew + ListNew, + CoreTag }, inject: { 'lists': { @@ -45,6 +50,81 @@ export default { columns:[ {title:"UID", field:"uid", headerFilter: true}, {title:"TitelPre", field:"titelpre", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}}, + { + title: 'Tags', + field: 'tags', + tooltip: false, + headerFilter: "input", + headerFilterFunc: tagHeaderFilter, + headerFilterFuncParams: {field: 'tags'}, + formatter: (cell) => { + let tags = cell.getValue(); + if (!tags) return; + + let container = document.createElement('div'); + container.className = "d-flex gap-1"; + + let parsedTags = JSON.parse(tags); + let maxVisibleTags = 2; + + const rowData = cell.getRow().getData(); + if (rowData._tagExpanded === undefined) { + rowData._tagExpanded = false; + } + + const renderTags = () => { + container.innerHTML = ''; + parsedTags = parsedTags.filter(item => item !== null); + + parsedTags.sort((a, b) => { + let adone = a.done ? 1 : 0; + let bbone = b.done ? 1 : 0; + + if (adone !== bbone) + { + return adone - bbone; + } + return b.id - a.id; + }); + const tagsToShow = rowData._tagExpanded ? parsedTags : parsedTags.slice(0, maxVisibleTags); + + tagsToShow.forEach(tag => { + if (!tag) return; + let tagElement = document.createElement('span'); + tagElement.innerText = tag.beschreibung; + tagElement.title = tag.notiz; + tagElement.className = "tag " + tag.style; + if (tag.done) tagElement.className += " tag_done"; + + tagElement.addEventListener('click', (event) => { + event.stopPropagation(); + event.preventDefault(); + this.$refs.tagComponent.editTag(tag.id); + }); + + container.appendChild(tagElement); + }); + + if (parsedTags.length > maxVisibleTags) { + let toggle = document.createElement('button'); + toggle.innerText = (rowData._tagExpanded ? '- ' : '+ ') + (parsedTags.length - maxVisibleTags); + toggle.className = "display_all"; + toggle.title = rowData._tagExpanded ? "Tags ausblenden" : "Tags einblenden"; + + toggle.addEventListener('click', () => { + rowData._tagExpanded = !rowData._tagExpanded; + renderTags(); + }); + + container.appendChild(toggle); + } + }; + + renderTags(); + return container; + }, + width: 150, + }, {title:"Nachname", field:"nachname", headerFilter: true}, {title:"Vorname", field:"vorname", headerFilter: true}, {title:"Wahlname", field:"wahlname", visible:false, headerFilter: true}, @@ -131,7 +211,7 @@ export default { selectable: true, selectableRangeMode: 'click', index: 'prestudent_id', - persistenceID: 'stv-list' + persistenceID: 'stv-list', }, tabulatorEvents: [ { @@ -140,7 +220,11 @@ export default { }, { event: 'dataProcessed', - handler: this.autoSelectRows + //handler: this.autoSelectRows TODO(Manu) combine + handler: (data) => { + this.reexpandRows() + this.$emit('update:selected', {}) + } }, { event: 'dataLoaded', @@ -153,6 +237,18 @@ export default { { event: 'rowClick', handler: this.handleRowClick // TODO(chris): this should be in the filter component + }, + { + event: 'dataTreeRowExpanded', + handler: (data) => { + this.getExpandedRows() + } + }, + { + event: 'dataTreeRowCollapsed', + handler: (data) => { + this.getExpandedRows() + } } ], focusObj: null, // TODO(chris): this should be in the filter component @@ -162,7 +258,11 @@ export default { count: 0, filteredcount: 0, selectedcount: 0, - currentEndpointRawUrl: '' + currentEndpointRawUrl: '', + //tags + expanded: [], + selectedColumnValues: [], + tagEndpoint: ApiTag } }, methods: { @@ -175,6 +275,11 @@ export default { rowSelectionChanged(data) { this.selectedcount = data.length; this.lastSelected = this.selected; + + //for tags + this.selectedRows = this.$refs.table.tabulator.getSelectedRows(); + this.selectedColumnValues = this.selectedRows.filter(row => row.getData().uid !== undefined && row.getData().uid).map(row => row.getData().uid); + this.$emit('update:selected', data); }, autoSelectRows(data) { @@ -294,7 +399,194 @@ export default { if (el != this.focusObj) this.changeFocus(this.focusObj, el); } - } + }, + //methods tags + addedTag(addedTag) + { + console.log("addedTag"); + const table = this.$refs.table.tabulator; + + this.selectedRows.forEach(row => + { + if (Array.isArray(addedTag.response)) + { + addedTag.response.forEach(tag => { + const targetRow = this.allRows.find(row => row.getData().uid === tag.uid); + if (targetRow) + { + const rowData = targetRow.getData(); + let tags = []; + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + const tagExists = tags.some((t) => t.id === tag.id); + if (!tagExists) + { + addedTag.id = tag.id; + tags.unshift({ ...addedTag }); + targetRow.update({ tags: JSON.stringify(tags) }); + targetRow.reformat(); + } + } + }); + } + }); + }, + deletedTag(deletedTag) { + console.log("deletedTag"); + const targetRow = this.allRows.find(row => { + const rowData = row.getData(); + + let tags = []; + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + return tags.some(tag => tag.id === deletedTag); + }); + + if (targetRow) { + const rowData = targetRow.getData(); + let tags = []; + + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + const filteredTags = tags.filter(t => t.id !== deletedTag); + const updatedTags = JSON.stringify(filteredTags); + + if (updatedTags !== rowData.tags) { + targetRow.update({ + tags: updatedTags + }); + + targetRow.reformat(); + } + } + }, + updatedTag(updatedTag) { + console.log("updatedTag"); + const targetRow = this.allRows.find(row => { + const rowData = row.getData(); + let tags = []; + + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + return tags.some(t => t?.id === updatedTag.id); + }); + + if (targetRow) + { + const rowData = targetRow.getData(); + let tags = []; + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + let changed = false; + + const tagIndex = tags.findIndex(tag => tag?.id === updatedTag.id); + if (tagIndex !== -1) { + tags[tagIndex] = { ...updatedTag }; + changed = true; + } + + if (changed) + { + targetRow.update({ + tags: JSON.stringify(tags), + }); + targetRow.reformat(); + } + } + }, + resetTree() { + console.log("reset tree"); + this.allRows.forEach(row => { + row._row.modules.dataTree.open = false; + }); + + let rootRows = this.$refs.table.tabulator.getRows(true); + var lastRow = rootRows[rootRows.length - 1]; + lastRow?.treeCollapse(true) + + this.currentTreeLevel = 0; + }, + expandTree() + { + console.log("expandTree"); + this.currentTreeLevel = (this.currentTreeLevel || 0) + 1; + + let lastMatchingRow = null; + + this.allRows.forEach(row => { + const level = row._row.modules.dataTree?.index ?? 0; + + if (level === this.currentTreeLevel - 1 ) + { + row._row.modules.dataTree.open = true; + + if (row._row.data._children?.length > 0) + { + lastMatchingRow = row; + } + } + }); + + if (lastMatchingRow) + { + lastMatchingRow.treeExpand(); + } + this.$refs.table.tabulator.redraw(); + }, + getAllRows(rows) + { + let result = []; + rows.forEach(row => + { + result.push(row); + let children = row.getTreeChildren(); + if(children && children.length > 0) + { + result = result.concat(this.getAllRows(children)); + } + }); + return result; + }, + async getExpandedRows() { + this.expanded = []; + + this.allRows.forEach(row => { + if (row.getTreeChildren().length > 0 && row.isTreeExpanded()) + { + this.expanded.push(row.getData().uniqueindex); + } + }); + }, + reexpandRows() { + this.allRows = this.getAllRows(this.$refs.table.tabulator.getRows()); + + const matchingRows = this.allRows.filter(row => + this.expanded.includes(row.getData().uniqueindex) + ); + + if (matchingRows.length === 0) + this.currentTreeLevel = 0; + + matchingRows.forEach((row, index) => { + row._row.modules.dataTree.open = true; + + if (index === matchingRows.length - 1) + { + row.treeExpand(); + } + }); + }, + }, computed: { countsToHTML: function() { @@ -313,6 +605,7 @@ export default { // TODO(chris): filter component column chooser has no accessibilty features template: `
+ test manu {{selectedColumnValues}}
+ + +
` -} - +} \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js b/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js index d46e1f299..394c8784f 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js @@ -34,40 +34,58 @@ export default { default: false } }, - computed: { - studentUids() { - if (this.student.uid) - { - return [this.student.uid]; - } - return this.student.map(e => e.uid); - }, - studentKzs(){ - if (this.student.uid) - { - return [this.student.studiengang_kz]; - } - return this.student.map(e => e.studiengang_kz); - }, - stg_kz(){ - return this.studentKzs[0]; - }, - showAllFormats() { - if( this.isBerechtigtDocAndOdt === false - || !Array.isArray(this.isBerechtigtDocAndOdt) ) - { - return false; - } - let retval = this.isBerechtigtDocAndOdt.includes(this.stgInfo.oe_kurzbz); - return retval; - } - }, props: { student: Object }, data() { return { - tabulatorOptions: { + tabulatorData: [], + lastSelected: null, + formData: { + typStg: null, + pruefungstyp_kurzbz: null, + akadgrad_id: null, + vorsitz: null, + pruefungsantritt_kurzbz: null, + abschlussbeurteilung_kurzbz: null, + datum: null, + sponsion: null, + pruefer1: null, + pruefer2: null, + pruefer3: null, + anmerkung: null, + protokoll: null, + note: null, + link: null + }, + statusNew: true, + arrTypen: [], + arrAntritte: [], + arrBeurteilungen: [], + arrAkadGrad: [], + arrNoten: [], + selectedVorsitz: null, + filteredMitarbeiter: [], + filteredPersons: [], + selectedPruefer1: null, + selectedPruefer2: null, + selectedPruefer3: null, + stgInfo: { typ: '', oe_kurzbz: '' }, + abortController: { + mitarbeiter: null, + persons: null + }, + layout: 'fitDataStretchFrozen', + layoutColumnsOnNewData: false, + height: 'auto', + minHeight: '200', + index: 'abschlusspruefung_id', + persistenceID: 'stv-details-finalexam-2025112401' + } + }, + computed: { + tabulatorOptions() { + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call(ApiStvAbschlusspruefung.getAbschlusspruefung(this.student.uid)), ajaxResponse: (url, params, response) => response.data, @@ -163,14 +181,11 @@ export default { frozen: true }, ], - layout: 'fitDataStretchFrozen', - layoutColumnsOnNewData: false, - height: 'auto', - minHeight: '200', - index: 'abschlusspruefung_id', - persistenceID: 'stv-details-finalexam-2025112401' - }, - tabulatorEvents: [ + }; + return options; + }, + tabulatorEvents() { + const events = [ { event: 'dataLoaded', handler: data => this.tabulatorData = data.map(item => { @@ -225,50 +240,36 @@ export default { cm.getColumnByField('abschlusspruefung_id').component.updateDefinition({ title: this.$p.t('abschlusspruefung', 'abschlusspruefung_id') }); - /* - cm.getColumnByField('actions').component.updateDefinition({ - title: this.$p.t('global', 'aktionen') - }); - */ } } - ], - tabulatorData: [], - lastSelected: null, - formData: { - typStg: null, - pruefungstyp_kurzbz: null, - akadgrad_id: null, - vorsitz: null, - pruefungsantritt_kurzbz: null, - abschlussbeurteilung_kurzbz: null, - datum: null, - sponsion: null, - pruefer1: null, - pruefer2: null, - pruefer3: null, - anmerkung: null, - protokoll: null, - note: null, - link: null - }, - statusNew: true, - arrTypen: [], - arrAntritte: [], - arrBeurteilungen: [], - arrAkadGrad: [], - arrNoten: [], - selectedVorsitz: null, - filteredMitarbeiter: [], - filteredPersons: [], - selectedPruefer1: null, - selectedPruefer2: null, - selectedPruefer3: null, - stgInfo: { typ: '', oe_kurzbz: '' }, - abortController: { - mitarbeiter: null, - persons: null - }, + ]; + return events; + }, + studentUids() { + if (this.student.uid) + { + return [this.student.uid]; + } + return this.student.map(e => e.uid); + }, + studentKzs(){ + if (this.student.uid) + { + return [this.student.studiengang_kz]; + } + return this.student.map(e => e.studiengang_kz); + }, + stg_kz(){ + return this.studentKzs[0]; + }, + showAllFormats() { + if( this.isBerechtigtDocAndOdt === false + || !Array.isArray(this.isBerechtigtDocAndOdt) ) + { + return false; + } + let retval = this.isBerechtigtDocAndOdt.includes(this.stgInfo.oe_kurzbz); + return retval; } }, watch: { @@ -339,7 +340,7 @@ export default { }, getPersonLabel(titelpre, nachname, vorname, titelpost, uid) { return nachname + ' ' + vorname + (titelpre ? ' ' + titelpre : '') + (titelpost ? ' ' + titelpost : '') + (uid ? ' (' + uid + ')' : ''); - + }, actionDeleteAbschlusspruefung(abschlusspruefung_id) { this.$fhcAlert @@ -841,4 +842,3 @@ export default {
` } - diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Anrechnungen/Anrechnungen.js b/public/js/components/Stv/Studentenverwaltung/Details/Anrechnungen/Anrechnungen.js index a2029b0b9..32224062d 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Anrechnungen/Anrechnungen.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Anrechnungen/Anrechnungen.js @@ -31,7 +31,24 @@ export default { }, data() { return { - tabulatorOptions: { + formData: {}, + listBegruendungen: [], + listNewLehrveranstaltungen: [], + listLektoren: [], + listKompatibleLehrveranstaltungen: [], + statusNew: true, + showNotizen: false, + currentAnrechnung_id: null, + endpoint: ApiNotizPerson, + layout: 'fitDataStretchFrozen', + height: '500', + index: 'anrechnung_id', + persistenceID: 'stv-details-anrechnungen-2025112401' + } + }, + computed: { + tabulatorOptions() { + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call( ApiStvExemptions.getAnrechnungen(this.student.prestudent_id) @@ -107,12 +124,11 @@ export default { frozen: true }, ], - layout: 'fitDataStretchFrozen', - height: '500', - index: 'anrechnung_id', - persistenceID: 'stv-details-anrechnungen-2025112401' - }, - tabulatorEvents: [ + }; + return options; + }, + tabulatorEvents() { + const events = [ { event: 'tableBuilt', handler: async () => { @@ -154,16 +170,8 @@ export default { } } - ], - formData: {}, - listBegruendungen: [], - listNewLehrveranstaltungen: [], - listLektoren: [], - listKompatibleLehrveranstaltungen: [], - statusNew: true, - showNotizen: false, - currentAnrechnung_id: null, - endpoint: ApiNotizPerson + ]; + return events; } }, watch: { diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js b/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js index d03569df4..b2ba26a55 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js @@ -36,158 +36,19 @@ export default { }, data() { return { - tabulatorOptions: { - ajaxURL: 'dummy', - ajaxRequestFunc: () => this.$api.call( - ApiStvAdmissionDates.getAufnahmetermine(this.student.person_id) - ), - ajaxResponse: (url, params, response) => response.data, - columns: [ - {title: "rt_id", field: "rt_id", visible: false}, - {title: "rt_person_id", field: "rt_person_id", visible: false}, - {title: "person_id", field: "person_id", visible: false}, - {title: "datum", field: "datum", - formatter: function (cell) { - const dateStr = cell.getValue(); - if (!dateStr) return ""; - - const date = new Date(dateStr); - return date.toLocaleString("de-DE", { - day: "2-digit", - month: "2-digit", - year: "numeric", - }); - } - }, - {title: "stufe", field: "stufe"}, - {title: "studiensemester", field: "studiensemester"}, - {title: "anmerkung", field: "anmerkung", visible: false}, - {title: "anmeldedatum", field: "anmeldedatum", visible: false, - formatter: function (cell) { - const dateStr = cell.getValue(); - if (!dateStr) return ""; - - const date = new Date(dateStr); - return date.toLocaleString("de-DE", { - day: "2-digit", - month: "2-digit", - year: "numeric", - }); - } - }, - {title: "punkte", field: "punkte"}, - { - title: "teilgenommen", field: "teilgenommen", - formatter: "tickCross", - hozAlign: "center", - formatterParams: { - tickElement: '', - crossElement: '' - } - }, - {title: "ort", field: "ort", visible: false}, - {title: "studienplan", field: "studienplan", visible: false}, - {title: "studienplan_id", field: "studienplan_id", visible: false}, - {title: "stg", field: "studiengangkurzbzlang"}, - {title: "Stg", field: "stg_kuerzel"}, - { - title: 'Aktionen', field: 'actions', - minWidth: 150, // Ensures Action-buttons will be always fully displayed - formatter: (cell, formatterParams, onRendered) => { - let container = document.createElement('div'); - container.className = "d-flex gap-2"; - - let button = document.createElement('button'); - button.className = 'btn btn-outline-secondary btn-action'; - button.innerHTML = ''; - button.title = this.$p.t('ui', 'bearbeiten'); - button.addEventListener('click', (event) => - this.actionEditPlacementTest(cell.getData().rt_person_id) - ); - container.append(button); - - button = document.createElement('button'); - button.className = 'btn btn-outline-secondary btn-action'; - button.innerHTML = ''; - button.title = this.$p.t('ui', 'loeschen'); - button.addEventListener('click', () => - this.actionDeletePlacementTest(cell.getData().rt_person_id) - ); - container.append(button); - - return container; - }, - frozen: true - } - ], - layout: 'fitDataStretchFrozen', - layoutColumnsOnNewData: false, - height: 'auto', - minHeight: 200, - index: 'aufnahmetermin_id', - persistenceID: 'stv-details-table_admission-dates-2025112401' - }, - tabulatorEvents: [ - { - event: 'tableBuilt', - handler: async () => { - await this.$p.loadCategory(['admission', 'global', 'person', 'ui', 'projektarbeitsbeurteilung']); - let cm = this.$refs.table.tabulator.columnManager; - - cm.getColumnByField('rt_id').component.updateDefinition({ - title: this.$p.t('ui', 'reihungstest_id') - }); - cm.getColumnByField('rt_person_id').component.updateDefinition({ - title: this.$p.t('ui', 'reihungstest_person_id') - }); - cm.getColumnByField('person_id').component.updateDefinition({ - title: this.$p.t('person', 'person_id') - }); - cm.getColumnByField('datum').component.updateDefinition({ - title: this.$p.t('global', 'datum') - }); - cm.getColumnByField('stufe').component.updateDefinition({ - title: this.$p.t('admission', 'stufe') - }); - cm.getColumnByField('studiensemester').component.updateDefinition({ - title: this.$p.t('lehre', 'studiensemester') - }); - cm.getColumnByField('anmerkung').component.updateDefinition({ - title: this.$p.t('global', 'anmerkung') - }); - cm.getColumnByField('anmeldedatum').component.updateDefinition({ - title: this.$p.t('admission', 'anmeldedatum') - }); - cm.getColumnByField('punkte').component.updateDefinition({ - title: this.$p.t('exam', 'punkte') - }); - cm.getColumnByField('teilgenommen').component.updateDefinition({ - title: this.$p.t('admission', 'teilgenommen') - }); - cm.getColumnByField('ort').component.updateDefinition({ - title: this.$p.t('person', 'ort') - }); - cm.getColumnByField('studienplan').component.updateDefinition({ - title: this.$p.t('lehre', 'studienplan') - }); - cm.getColumnByField('studienplan_id').component.updateDefinition({ - title: this.$p.t('ui', 'studienplan_id') - }); - cm.getColumnByField('studiengangkurzbzlang').component.updateDefinition({ - title: this.$p.t('projektarbeitsbeurteilung', 'studiengang') - }); - cm.getColumnByField('stg_kuerzel').component.updateDefinition({ - title: this.$p.t('admission', 'stg_kurz') - }); - } - } - ], formData: {}, statusNew: true, listPlacementTests: [], listStudyPlans: [], filterOnlyFutureTestsSet: false, - filteredPlacementTests: [] + filteredPlacementTests: [], + //data after tabulator data + layout: 'fitDataStretchFrozen', + layoutColumnsOnNewData: false, + height: 'auto', + minHeight: 200, + index: 'aufnahmetermin_id', + persistenceID: 'stv-details-table_admission-dates-2025112401' } }, methods: { @@ -332,6 +193,155 @@ export default { this.formData = {}; }, }, + computed: { + tabulatorOptions() { + const options = { + ajaxURL: 'dummy', + ajaxRequestFunc: () => this.$api.call( + ApiStvAdmissionDates.getAufnahmetermine(this.student.person_id) + ), + ajaxResponse: (url, params, response) => response.data, + columns: [ + {title: "rt_id", field: "rt_id", visible: false}, + {title: "rt_person_id", field: "rt_person_id", visible: false}, + {title: "person_id", field: "person_id", visible: false}, + {title: "datum", field: "datum", + formatter: function (cell) { + const dateStr = cell.getValue(); + if (!dateStr) return ""; + + const date = new Date(dateStr); + return date.toLocaleString("de-DE", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }); + } + }, + {title: "stufe", field: "stufe"}, + {title: "studiensemester", field: "studiensemester"}, + {title: "anmerkung", field: "anmerkung", visible: false}, + {title: "anmeldedatum", field: "anmeldedatum", visible: false, + formatter: function (cell) { + const dateStr = cell.getValue(); + if (!dateStr) return ""; + + const date = new Date(dateStr); + return date.toLocaleString("de-DE", { + day: "2-digit", + month: "2-digit", + year: "numeric", + }); + } + }, + {title: "punkte", field: "punkte"}, + { + title: "teilgenommen", field: "teilgenommen", + formatter: "tickCross", + hozAlign: "center", + formatterParams: { + tickElement: '', + crossElement: '' + } + }, + {title: "ort", field: "ort", visible: false}, + {title: "studienplan", field: "studienplan", visible: false}, + {title: "studienplan_id", field: "studienplan_id", visible: false}, + {title: "stg", field: "studiengangkurzbzlang"}, + {title: "Stg", field: "stg_kuerzel"}, + { + title: 'Aktionen', field: 'actions', + minWidth: 150, // Ensures Action-buttons will be always fully displayed + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'); + container.className = "d-flex gap-2"; + + let button = document.createElement('button'); + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('ui', 'bearbeiten'); + button.addEventListener('click', (event) => + this.actionEditPlacementTest(cell.getData().rt_person_id) + ); + container.append(button); + + button = document.createElement('button'); + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('ui', 'loeschen'); + button.addEventListener('click', () => + this.actionDeletePlacementTest(cell.getData().rt_person_id) + ); + container.append(button); + + return container; + }, + frozen: true + } + ], + }; + return options; + }, + tabulatorEvents() { + const events = [ + { + event: 'tableBuilt', + handler: async () => { + await this.$p.loadCategory(['admission', 'global', 'person', 'ui', 'projektarbeitsbeurteilung']); + let cm = this.$refs.table.tabulator.columnManager; + + cm.getColumnByField('rt_id').component.updateDefinition({ + title: this.$p.t('ui', 'reihungstest_id') + }); + cm.getColumnByField('rt_person_id').component.updateDefinition({ + title: this.$p.t('ui', 'reihungstest_person_id') + }); + cm.getColumnByField('person_id').component.updateDefinition({ + title: this.$p.t('person', 'person_id') + }); + cm.getColumnByField('datum').component.updateDefinition({ + title: this.$p.t('global', 'datum') + }); + cm.getColumnByField('stufe').component.updateDefinition({ + title: this.$p.t('admission', 'stufe') + }); + cm.getColumnByField('studiensemester').component.updateDefinition({ + title: this.$p.t('lehre', 'studiensemester') + }); + cm.getColumnByField('anmerkung').component.updateDefinition({ + title: this.$p.t('global', 'anmerkung') + }); + cm.getColumnByField('anmeldedatum').component.updateDefinition({ + title: this.$p.t('admission', 'anmeldedatum') + }); + cm.getColumnByField('punkte').component.updateDefinition({ + title: this.$p.t('exam', 'punkte') + }); + cm.getColumnByField('teilgenommen').component.updateDefinition({ + title: this.$p.t('admission', 'teilgenommen') + }); + cm.getColumnByField('ort').component.updateDefinition({ + title: this.$p.t('person', 'ort') + }); + cm.getColumnByField('studienplan').component.updateDefinition({ + title: this.$p.t('lehre', 'studienplan') + }); + cm.getColumnByField('studienplan_id').component.updateDefinition({ + title: this.$p.t('ui', 'studienplan_id') + }); + cm.getColumnByField('studiengangkurzbzlang').component.updateDefinition({ + title: this.$p.t('projektarbeitsbeurteilung', 'studiengang') + }); + cm.getColumnByField('stg_kuerzel').component.updateDefinition({ + title: this.$p.t('admission', 'stg_kurz') + }); + } + } + ]; + + return events; + } + }, created() { this.$api .call(ApiStvAdmissionDates.getListPlacementTests(this.student.prestudent_id)) diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js b/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js index 20cb95fbd..2732a5707 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js @@ -11,22 +11,6 @@ export default { FormInput, FormForm }, - computed: { - downloadLink: function(){ - if(!this.dataSem.start || !this.dataSem.ende || !this.student.uid) return; - let start = new Date(this.dataSem.start); - start = Math.floor(start.getTime()/1000); - let ende = new Date(this.dataSem.ende); - ende = Math.floor(ende.getTime() / 1000); - - let link = - FHC_JS_DATA_STORAGE_OBJECT.app_root + "cis/private/lvplan/stpl_kalender.php?type=student&pers_uid=" + this.student.uid + "&begin=" + start + "&ende= " +ende + "&format=excel"; - return link; - }, - dbStundenplanTable: function (){ - return this.showStundenplanDev ? 'stundenplandev' : 'stundenplan'; - } - }, inject: { currentSemester: { from: 'currentSemester', @@ -44,6 +28,22 @@ export default { showStundenplanDev: false }; }, + computed: { + downloadLink: function(){ + if(!this.dataSem.start || !this.dataSem.ende || !this.student.uid) return; + let start = new Date(this.dataSem.start); + start = Math.floor(start.getTime()/1000); + let ende = new Date(this.dataSem.ende); + ende = Math.floor(ende.getTime() / 1000); + + let link = + FHC_JS_DATA_STORAGE_OBJECT.app_root + "cis/private/lvplan/stpl_kalender.php?type=student&pers_uid=" + this.student.uid + "&begin=" + start + "&ende= " +ende + "&format=excel"; + return link; + }, + dbStundenplanTable: function (){ + return this.showStundenplanDev ? 'stundenplandev' : 'stundenplan'; + }, + }, methods: { initTabulatorOptions(){ this.tabulatorOptions = { @@ -80,7 +80,7 @@ export default { {title: "farbe", field: "farbe", visible: false}, {title: "Gruppen", field: "gruppen_kuerzel"}, {title: "ort", field: "ort_kurzbz"}, - {title: "lektorIn", field: "lektorname"}, + {title: "lektorIn", field: "lektorname", sorter:"string"}, {title: "Lehrfach", field: "lehrfach_bez"} ], rowFormatter: function(row){ @@ -135,7 +135,7 @@ export default { }, getDatesOfSemester(studiensemester_kurzbz) { this.dataSem = this.listStudiensemester.find(item => item.studiensemester_kurzbz === studiensemester_kurzbz); - }, + }, exportToExcel(){ window.open(this.downloadLink, '_blank'); }, diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/History.js b/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/History.js index 44b318f5b..1fe96188f 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/History.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/History.js @@ -12,7 +12,16 @@ export default{ }, data() { return { - tabulatorOptions: { + layout: 'fitDataFill', + layoutColumnsOnNewData: false, + height: 'auto', + selectable: false, + persistenceID: 'stv-details-prestudent-history', + } + }, + computed: { + tabulatorOptions() { + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call(ApiStvPrestudent.getHistoryPrestudents(this.personId)), ajaxResponse: (url, params, response) => response.data, @@ -37,13 +46,11 @@ export default{ element.classList.add('fw-bold'); } }, - layout: 'fitDataFill', - layoutColumnsOnNewData: false, - height: 'auto', - selectable: false, - persistenceID: 'stv-details-prestudent-history' - }, - tabulatorEvents: [ + }; + return options; + }, + tabulatorEvents() { + const events = [ { event: 'tableBuilt', handler: async () => { @@ -64,8 +71,9 @@ export default{ }); } } - ] - } + ]; + return events; + }, }, watch: { personId() { diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/MultiStatus.js b/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/MultiStatus.js index e67f19ccf..8f381c330 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/MultiStatus.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Prestudent/MultiStatus.js @@ -26,37 +26,8 @@ export default{ } }, computed: { - prestudentIds() { - if (this.modelValue.prestudent_id) - { - return [this.modelValue.prestudent_id]; - } - return this.modelValue.map(e => e.prestudent_id); - }, - showToolbarStudent() { - if (Array.isArray(this.modelValue)) { - if (!this.modelValue.length) - return false; - return this.modelValue.every(item => item.uid); - } - return !!this.modelValue.uid; - }, - showToolbarInteressent() { - if (Array.isArray(this.modelValue)) { - if (!this.modelValue.length) - return false; - return !this.modelValue.some(item => item.uid); - } - return !this.modelValue.uid; - } - }, - props: { - modelValue: Object, - config: Object, - }, - data() { - return { - tabulatorOptions: { + tabulatorOptions() { + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call(ApiStvPrestudent.getHistoryPrestudent(this.modelValue.prestudent_id)), ajaxResponse: (url, params, response) => response.data, @@ -164,7 +135,7 @@ export default{ } }, {title: "UpdateVon", field: "updatevon", visible: false}, -/* {title: "Aufnahmestufe", field: "aufnahmestufe", visible: false},*/ + /* {title: "Aufnahmestufe", field: "aufnahmestufe", visible: false},*/ { title: 'Aktionen', field: 'actions', minWidth: 150, // Ensures Action-buttons will be always fully displayed @@ -207,8 +178,8 @@ export default{ button.addEventListener('click', () => this.actionEditStatus(data.status_kurzbz, data.studiensemester_kurzbz, data.ausbildungssemester) ); -/* if (this.dataMeldestichtag && this.dataMeldestichtag > data.datum && !this.hasPermissionToSkipStatusCheck) - button.disabled = true;*/ + /* if (this.dataMeldestichtag && this.dataMeldestichtag > data.datum && !this.hasPermissionToSkipStatusCheck) + button.disabled = true;*/ container.append(button); button = document.createElement('button'); @@ -240,8 +211,11 @@ export default{ selectable: false, index: 'statusId', persistenceID: 'stv-multistatus-2025112401' - }, - tabulatorEvents: [ + }; + return options; + }, + tabulatorEvents() { + const events = [ { event: 'tableBuilt', handler: async () => { @@ -250,8 +224,8 @@ export default{ let cm = this.$refs.table.tabulator.columnManager; cm.getColumnByField('lehrverband').component.updateDefinition({ - title: this.$p.t('lehre', 'lehrverband') - }); + title: this.$p.t('lehre', 'lehrverband') + }); cm.getColumnByField('bestaetigtam').component.updateDefinition({ title: this.$p.t('lehre', 'bestaetigt_am') @@ -298,7 +272,39 @@ export default{ }); } } - ], + ]; + return events; + }, + prestudentIds() { + if (this.modelValue.prestudent_id) + { + return [this.modelValue.prestudent_id]; + } + return this.modelValue.map(e => e.prestudent_id); + }, + showToolbarStudent() { + if (Array.isArray(this.modelValue)) { + if (!this.modelValue.length) + return false; + return this.modelValue.every(item => item.uid); + } + return !!this.modelValue.uid; + }, + showToolbarInteressent() { + if (Array.isArray(this.modelValue)) { + if (!this.modelValue.length) + return false; + return !this.modelValue.some(item => item.uid); + } + return !this.modelValue.uid; + } + }, + props: { + modelValue: Object, + config: Object, + }, + data() { + return { statusData: {}, statusId: {}, dataMeldestichtag: null, From 87ff7acef0c20f3e680ead47760b7e005b67bd8e Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Tue, 3 Feb 2026 14:27:02 +0100 Subject: [PATCH 33/37] use absoluteJsImportUrl helper instead of APP_ROOT constant to build js components file path --- application/controllers/api/frontend/v1/lv/Setup.php | 8 ++++---- application/controllers/api/frontend/v1/stv/Config.php | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/application/controllers/api/frontend/v1/lv/Setup.php b/application/controllers/api/frontend/v1/lv/Setup.php index a2c167dd6..eea4befa5 100644 --- a/application/controllers/api/frontend/v1/lv/Setup.php +++ b/application/controllers/api/frontend/v1/lv/Setup.php @@ -47,22 +47,22 @@ class Setup extends FHCAPI_Controller { $tabs['details'] = array ( 'title' => 'Details', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Details.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Details.js'), 'config' => [] ); $tabs['gruppen'] = array ( 'title' => 'Gruppen', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Gruppen.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Gruppen.js'), 'config' => [] ); $tabs['lektor'] = array ( 'title' => 'LektorInnenzuteilung', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Lektor.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Lektor.js'), 'config' => [] ); $tabs['notiz'] = array ( 'title' => 'Notizen', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Notiz.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Notiz.js'), 'config' => [] ); $this->terminateWithSuccess($tabs); diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index 17b360f8c..c787381f0 100644 --- a/application/controllers/api/frontend/v1/stv/Config.php +++ b/application/controllers/api/frontend/v1/stv/Config.php @@ -504,7 +504,7 @@ class Config extends FHCAPI_Controller { $result['combinePeople'] = [ 'title' => $this->p->t('stv', 'tab_combine_people'), - 'component' => './Stv/Studentenverwaltung/Details/CombinePeople.js', + 'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/CombinePeople.js'), 'config' => $config['combinePeople'] ]; } From e0082db7c99742fa2e4149d3f2f50e7a4c996338 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 3 Feb 2026 16:16:18 +0100 Subject: [PATCH 34/37] Tab Aufnahmetermine: add context self to computed properties and adapt name of 2 variables, Tab Lehrveranstaltungstermine: add space --- .../Details/Aufnahmetermine/Aufnahmetermine.js | 7 ++++--- .../ListLehrveranstaltungstermine.js | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js b/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js index 775b94364..81b55983f 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine/Aufnahmetermine.js @@ -211,6 +211,8 @@ export default { }, computed: { tabulatorOptions() { + const self = this; + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call( @@ -236,7 +238,6 @@ export default { }, rowFormatter: function(row) { let data = row.getData(); - if (data.studiengang_kz_ber === self.student.studiengang_kz && data.studiensemester === self.youngestSemester) { let cells = row.getCells(); @@ -378,10 +379,10 @@ export default { cm.getColumnByField('studienplan_id').component.updateDefinition({ title: this.$p.t('ui', 'studienplan_id') }); - cm.getColumnByField('studiengangkurzbzlang').component.updateDefinition({ + cm.getColumnByField('studiengangkurzbzlang_ber').component.updateDefinition({ title: this.$p.t('projektarbeitsbeurteilung', 'studiengang') }); - cm.getColumnByField('stg_kuerzel').component.updateDefinition({ + cm.getColumnByField('studiengang_kz_ber').component.updateDefinition({ title: this.$p.t('admission', 'stg_kurz') }); } diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js b/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js index 2732a5707..5b0c4e350 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js @@ -80,7 +80,7 @@ export default { {title: "farbe", field: "farbe", visible: false}, {title: "Gruppen", field: "gruppen_kuerzel"}, {title: "ort", field: "ort_kurzbz"}, - {title: "lektorIn", field: "lektorname", sorter:"string"}, + {title: "lektorIn", field: "lektorname", sorter: "string"}, {title: "Lehrfach", field: "lehrfach_bez"} ], rowFormatter: function(row){ From 30532891461716fcdcb4826519b3dd7abf515748 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 4 Feb 2026 11:33:54 +0100 Subject: [PATCH 35/37] Filter: change type filter Active, change position filter item, default values All Buchungstypen --- application/controllers/api/frontend/v1/stv/Config.php | 6 ++++-- public/js/components/Stv/Studentenverwaltung/List.js | 2 +- public/js/components/Stv/Studentenverwaltung/List/Filter.js | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index 17b360f8c..d633aefa2 100644 --- a/application/controllers/api/frontend/v1/stv/Config.php +++ b/application/controllers/api/frontend/v1/stv/Config.php @@ -200,7 +200,8 @@ class Config extends FHCAPI_Controller 'type' => 'select', 'values' => $buchungstyp_kurzbz_plus_all, 'value_key' => 'buchungstyp_kurzbz', - 'label_key' => 'beschreibung' + 'label_key' => 'beschreibung', + 'default' => 'all' ], 'samestg' => [ 'type' => 'bool', @@ -226,7 +227,8 @@ class Config extends FHCAPI_Controller 'type' => 'select', 'values' => $buchungstyp_kurzbz_plus_all, 'value_key' => 'buchungstyp_kurzbz', - 'label_key' => 'beschreibung' + 'label_key' => 'beschreibung', + 'default' => 'all' ], 'samestg' => [ 'type' => 'bool', diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 835bf9fec..c70d8de64 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -578,7 +578,7 @@ export default {