diff --git a/application/components/filters/Vertragsverwaltung.php b/application/components/filters/Vertragsverwaltung.php new file mode 100644 index 000000000..b96aee8ea --- /dev/null +++ b/application/components/filters/Vertragsverwaltung.php @@ -0,0 +1,36 @@ + 'core', + 'datasetName' => 'vertragsverwaltung', + 'query' => ' + SELECT + uid, + person_id, + vorname, + nachname, + gebdatum, + vertragsarten, + unternehmen, + ids, + aktiv + FROM + ( + SELECT + b.uid , p.person_id, + p.vorname, p.nachname, + gebdatum, + STRING_AGG(DISTINCT va.bezeichnung, \', \') AS Vertragsarten, + STRING_AGG(DISTINCT u.bezeichnung, \', \') AS Unternehmen, + STRING_AGG(d.dienstverhaeltnis_id::TEXT, \', \') AS ids, + b.aktiv + FROM + hr.tbl_dienstverhaeltnis d + JOIN public.tbl_benutzer b ON d.mitarbeiter_uid = b.uid + JOIN public.tbl_person p ON p.person_id = b.person_id + JOIN public.tbl_organisationseinheit u ON d.oe_kurzbz = u.oe_kurzbz + JOIN hr.tbl_vertragsart va ON d.vertragsart_kurzbz = va.vertragsart_kurzbz + GROUP BY b.uid, p.person_id, p.vorname, p.nachname, b.aktiv + ) as vertragsdaten + ', + 'requiredPermissions' => 'vertrag/mitarbeiter' + ); diff --git a/application/config/abgabe.php b/application/config/abgabe.php index 82782b043..90aedbd8b 100644 --- a/application/config/abgabe.php +++ b/application/config/abgabe.php @@ -41,3 +41,5 @@ $config['STG_MOODLE_LINK'] = 'https://moodle.technikum-wien.at/course/view.php?i $config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true; $config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true; + +$config['BETREUER_SAMMELMAIL_BUTTON_STUDENT'] = true; diff --git a/application/config/navigation.php b/application/config/navigation.php index f7ba8dca3..c70aba57c 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -163,6 +163,13 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 50, 'requiredPermissions' => 'lehre/gruppenmanager:r' + ), + 'vertragsverwaltung' => array( + 'link' => site_url('vertragsverwaltung'), + 'description' => 'Vertragsverwaltung', + 'expand' => true, + 'sort' => 51, + 'requiredPermissions' => 'vertrag/mitarbeiter:r' ) ) ), @@ -335,6 +342,18 @@ $config['navigation_menu']['system/issues/Issues/*'] = array( 'target' => '_blank', 'requiredPermissions' => array('admin:rw') ), + +); + +$config['navigation_menu']['vertragsverwaltung/*'] = array( + 'vertragsverwaltung' => array( + 'link' => site_url('vertragsverwaltung'), + 'description' => 'Vertragsverwaltung', + 'icon' => 'home', + 'sort' => 100, + 'target' => '_blank', + 'requiredPermissions' => array('vertrag/mitarbeiter:r') + ) ); $config['navigation_menu']['apps'] = [ diff --git a/application/config/stv.php b/application/config/stv.php index 8942c35e6..34a30a96e 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -130,3 +130,16 @@ $config['students_tab_order'] = [ 'combinePeople', 'archive', ]; + +$config['stv_prestudent_tags'] = [ + 'prioone' => ['readonly' => false], + 'priotwo' => ['readonly' => true], + 'hinweis' => ['readonly' => false], + 'hinweis_assistenz' => ['readonly' => true], + 'hinweis_kf' => ['readonly' => true], + 'hinweis_lehrende' => ['readonly' => false], + 'hinweis_stg_kf' => ['readonly' => true], + 'finished_stg' => ['readonly' => true], + 'finished_kf' => ['readonly' => true], + 'inwork_kf' => ['readonly' => true], +]; diff --git a/application/controllers/Studentenverwaltung.php b/application/controllers/Studentenverwaltung.php index 36c91d5f6..1699ba740 100644 --- a/application/controllers/Studentenverwaltung.php +++ b/application/controllers/Studentenverwaltung.php @@ -28,7 +28,7 @@ class Studentenverwaltung extends Auth_Controller 'basis/prestudentstatus' => $this->permissionlib->isBerechtigt('basis/prestudentstatus'), 'assistenz_stgs' => $this->permissionlib->getSTG_isEntitledFor('assistenz'), 'admin' => $this->permissionlib->isBerechtigt('admin'), - 'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'), + 'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz', 'suid'), 'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'), 'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht'), 'system/change_outputformat' => $this->permissionlib->getOE_isEntitledFor('system/change_outputformat'), @@ -43,3 +43,5 @@ class Studentenverwaltung extends Auth_Controller ]); } } + + diff --git a/application/controllers/Vertragsverwaltung.php b/application/controllers/Vertragsverwaltung.php new file mode 100644 index 000000000..f68ed1737 --- /dev/null +++ b/application/controllers/Vertragsverwaltung.php @@ -0,0 +1,30 @@ +method] = ['vertrag/mitarbeiter:r']; + #$permissions[$router->method] = ['admin:rw']; + parent::__construct($permissions); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + } + + /** + * @return void + */ + public function _remap() + { + $this->load->view('Vertragsverwaltung', [ + 'permissions' => [ + 'vertragsverwaltung_schreibrechte' => $this->permissionlib->isBerechtigt('vertrag/mitarbeiter', 'suid') + ] + ]); + } +} diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index d976cea15..af598a345 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -89,13 +89,15 @@ class Abgabe extends FHCAPI_Controller $abgabetypenBetreuer = $this->config->item('ALLOWED_ABGABETYPEN_BETREUER'); $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'); $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'); + $BETREUER_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('BETREUER_SAMMELMAIL_BUTTON_STUDENT'); $ret = array( 'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link, 'turnitin_link' => $turnitin_link, 'abgabetypenBetreuer' => $abgabetypenBetreuer, 'ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT' => $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT, - 'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER + 'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER, + 'BETREUER_SAMMELMAIL_BUTTON_STUDENT' => $BETREUER_SAMMELMAIL_BUTTON_STUDENT, ); $this->terminateWithSuccess($ret); diff --git a/application/controllers/api/frontend/v1/detailheader/Detailheader.php b/application/controllers/api/frontend/v1/detailheader/Detailheader.php new file mode 100644 index 000000000..ada10c5b6 --- /dev/null +++ b/application/controllers/api/frontend/v1/detailheader/Detailheader.php @@ -0,0 +1,53 @@ + ['vertrag/mitarbeiter:r'], + 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], + 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], + ]); + } + + public function getHeader($person_id) + { + $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); + + $result = $this->Mitarbeitermodel->getHeader($person_id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function getPersonAbteilung($mitarbeiter_uid) + { + $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); + + $result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function getLeitungOrg($oekurzbz) + { + $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); + + $result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + +} + + diff --git a/application/controllers/api/frontend/v1/fotoHandling/Foto.php b/application/controllers/api/frontend/v1/fotoHandling/Foto.php new file mode 100644 index 000000000..4945ddd85 --- /dev/null +++ b/application/controllers/api/frontend/v1/fotoHandling/Foto.php @@ -0,0 +1,237 @@ + ['admin:r', 'assistenz:r'], + 'deleteFoto' => ['admin:r', 'assistenz:r'], + ]); + + //Load Models and Libraries + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model("crm/Akte_model", "AkteModel"); + $this->load->model('person/Fotostatusperson_model', 'FotostatusPersonModel'); + + $this->loadPhrases([ + 'ui', + 'header' + ]); + } + + public function uploadFoto($person_id) + { + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL); + } + + $data = json_decode(file_get_contents("php://input"), true); + + if (!empty($data['image'])) + { + $base64 = $data['image']; + $resizedImage1 = $this->_resize($base64, 827, 1063); + + if (is_null($resizedImage1)) + return $this->terminateWithError($this->p->t('header', 'error_fotoupload'), self::ERROR_TYPE_GENERAL); + + $akte = $this->AkteModel->loadWhere(array('person_id' => $person_id, 'dokument_kurzbz' => 'Lichtbil')); + + $akteUpdateData = array( + 'dokument_kurzbz' => 'Lichtbil', + 'person_id' => $person_id, + 'inhalt' => $resizedImage1, + 'mimetype' => 'image/jpg', + 'erstelltam' => date('c'), + 'gedruckt' => false, + 'titel' => 'Lichtbild_' . $person_id . '.jpg', + 'bezeichnung' => 'Lichtbild gross', + 'insertamum' => date('c'), + 'insertvon' => getAuthUID(), + ); + + if (hasData($akte)) { + $akte_id = getData($akte)[0]->akte_id; + + $akteUpdateData['updateamum'] = date('c'); + $akteUpdateData['updatevon'] = getAuthUID(); + $akteResult = $this->AkteModel->update(array('akte_id' => $akte_id), $akteUpdateData); + } else { + $akteResult = $this->AkteModel->insert($akteUpdateData); + } + + if (isError($akteResult)) { + return $this->terminateWithError(getError($akteResult), self::ERROR_TYPE_GENERAL); + } + + $resizedImage2 = $this->_resize($base64, 101, 130); + + if (is_null($resizedImage2)) + return $this->terminateWithError($this->p->t('header', 'error_fotoupload'), self::ERROR_TYPE_GENERAL); + + $result = $this->_updateFoto($person_id, $resizedImage2); + + if (!isError($result)) { + $this->FotostatusPersonModel->insert(array( + 'person_id' => $person_id, + 'fotostatus_kurzbz' => 'hochgeladen', + 'datum' => date('Y-m-d'), + 'updateamum' => date('c'), + 'updatevon' => getAuthUID(), + 'insertamum' => date('c'), + 'insertvon' => getAuthUID(), + )); + + return $this->terminateWithSuccess($base64); + } + } + else + { + $this->terminateWithError($this->p->t('header', 'error_noPhoto'), self::ERROR_TYPE_GENERAL); + } + } + + public function deleteFoto($person_id) + { + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL); + } + + $result = $this->_deleteFoto($person_id); + + if (isError($result)) + { + return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess($result); + } + + private function _resize($imageData, $maxwidth, $maxheight, $quality = 90) + { + $meta = getimagesize($imageData); + if (!$meta) + { + return null; + } + + $src_width = $meta[0]; + $src_height = $meta[1]; + $mime = $meta['mime']; + + switch ($mime) { + case 'image/jpeg': + case 'image/jpg': + $imagecreated = imagecreatefromjpeg($imageData); + break; + case 'image/png': + $imagecreated = imagecreatefrompng($imageData); + break; + case 'image/gif': + $imagecreated = imagecreatefromgif($imageData); + break; + default: + return null; + } + + + if (!$imagecreated) + { + return null; + } + + $src_aspect_ratio = $src_width / $src_height; + $thu_aspect_ratio = $maxwidth / $maxheight; + + if ($src_width <= $maxwidth && $src_height <= $maxheight) + { + $thu_width = $src_width; + $thu_height = $src_height; + } + elseif ($thu_aspect_ratio > $src_aspect_ratio) + { + $thu_width = (int) ($maxheight * $src_aspect_ratio); + $thu_height = $maxheight; + } + else + { + $thu_width = $maxwidth; + $thu_height = (int) ($maxwidth / $src_aspect_ratio); + } + + $imageScaled = imagecreatetruecolor($thu_width, $thu_height); + + if ($mime === 'image/png') + { + $background = imagecolorallocate($imageScaled , 0, 0, 0); + imagecolortransparent($imageScaled, $background); + imagealphablending($imageScaled, false); + imagesavealpha($imageScaled, true); + } + + imagecopyresampled($imageScaled, $imagecreated, 0, 0, 0, 0, $thu_width, $thu_height, $src_width, $src_height); + + if ($mime === "image/gif") + { + $background = imagecolorallocate($imageScaled, 0, 0, 0); + imagecolortransparent($imageScaled, $background); + } + + if (!empty($imageScaled)) + { + ob_start(); + + if ($mime == 'image/png') + imagepng($imageScaled, NULL); + else if ($mime === 'image/gif') + imagegif($imageScaled, NULL); + else + imagejpeg($imageScaled, NULL, $quality); + + $resizedImageData = ob_get_contents(); + ob_end_clean(); + @imagedestroy($imagecreated); + @imagedestroy($imageScaled); + + + if (!empty($resizedImageData)) + { + return base64_encode($resizedImageData); + } + return null; + } + return null; + } + + private function _updateFoto($person_id, $foto) + { + $personJson['foto'] = $foto; + $result = $this->PersonModel->update($person_id, $personJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + return $result; + } + + private function _deleteFoto($person_id) + { + $personJson['foto'] = null; + $result = $this->PersonModel->update($person_id, $personJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + return $result; + } +} 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..30dae9a50 --- /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") + { + $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'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $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..e30628f33 --- /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") + { + $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'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $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 f8e1f816b..a3b96d477 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -17,5 +17,106 @@ class NotizLehreinheit extends Notiz_Controller 'getMitarbeiter' => ['admin:r', 'assistenz:r'], 'isBerechtigt' => ['admin:r', 'assistenz:r'], ]); + + //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') ?: []; + + 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([ + 'ui' + ]); } -} \ No newline at end of file + + 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") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } + + +} 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..f7de4b47b --- /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") + { + $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'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $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 23a8fd199..7f0645bc6 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizPerson.php +++ b/application/controllers/api/frontend/v1/notiz/NotizPerson.php @@ -20,33 +20,123 @@ class NotizPerson extends Notiz_Controller 'isBerechtigt' => ['admin:r', 'assistenz:r'], 'getCountNotes' => ['admin:r', 'assistenz:r'], ]); + + //Load Models + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + + //Permission checks for allowed Oes + if ($this->router->method == 'addNewNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $person_id = $post_data['id']; + + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkIfBerechtigungForOneUidExists($person_id, $allowedStgs); + } + + 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 person_id + $result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]); + + $data = $this->getDataOrTerminateWithError($result); + $person_id = current($data)->person_id; + + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + $this->_checkIfBerechtigungForOneUidExists($person_id, $allowedStgs); + } + + if ($this->router->method == 'deleteNotiz' ) + { + $notiz_id = $this->input->post('notiz_id'); + $person_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(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'person ID']), self::ERROR_TYPE_GENERAL); + } + + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + $this->_checkIfBerechtigungForOneUidExists($person_id, $allowedStgs); + } } public function isBerechtigt($id, $typeId) { 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() + //stv: if person has permission of one studiengang of person -> permission to add/update/delete Note + private function _checkIfBerechtigungForOneUidExists($person_id, $allowedStgs) { - $notiz_id = $this->input->post('notiz_id'); + //get all studentUids of person_id + $result = $this->BenutzerModel->loadWhere(['person_id' => $person_id]); + $data = $this->getDataOrTerminateWithError($result); - // TODO(chris): make CI variant of endpoint - $this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || campus.tbl_dms_version.dms_id AS preview'); - - return parent::loadDokumente(); + $checkarray = []; + foreach ($data as $item) + { + //check if isStudent + $result = $this->StudentModel->isStudent($item->uid); + + $isStudent = $this->getDataOrTerminateWithError($result); + if($isStudent) + { + $checkarray[] = $this->_checkAllowedStgsFromUid($item->uid, $allowedStgs); + } + + } + if (!in_array(1, $checkarray)) + return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL); } -} \ No newline at end of file + + private function _checkAllowedStgsFromUid($student_uid, $allowedStgs) + { + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]); + + $data = $this->getDataOrTerminateWithError($result); + $studiengang_kz = current($data)->studiengang_kz; + + if (!in_array($studiengang_kz, $allowedStgs)) + { + return 0; + } + else + { + return 1; + } + } +} 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..5e6cd747c --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php @@ -0,0 +1,117 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + + //Permission checks for Studiengangsarray + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + + if ($this->router->method == 'addNewNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $prestudent_id = $post_data['id']; + + if(!$prestudent_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs); + } + + 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 prestudent_id + $result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]); + + $data = $this->getDataOrTerminateWithError($result); + $prestudent_id = current($data)->prestudent_id; + + if(!$prestudent_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs); + } + + if ($this->router->method == 'deleteNotiz') + { + $notiz_id = $this->input->post('notiz_id'); + $prestudent_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(!$prestudent_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs); + } + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "prestudent_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } + + private function _checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs) + { + $student_uid = $this->StudentModel->getUID($prestudent_id); + + $result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]); + + $data = $this->getDataOrTerminateWithError($result); + $studiengang_kz = current($data)->studiengang_kz; + + if (!in_array($studiengang_kz, $allowedStgs)) + { + return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL); + } + } + +} \ 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..9cdde36ae --- /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") + { + $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'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $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..7a82c658e --- /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") + { + $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'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $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..aadb04f40 --- /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") + { + $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'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php b/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php index abf58cf4f..72d5dbccc 100644 --- a/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php +++ b/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php @@ -127,9 +127,9 @@ class Unterbrechung extends FHCAPI_Controller $this->form_validation->set_rules( 'datum_wiedereinstieg', 'Datum Wiedereinstieg', - 'required|callback_isValidDate|callback_isDateInFuture', + 'required|is_valid_date|callback_isDateInFuture', [ - 'isValidDate' => $this->p->t('ui', 'error_invalid_date'), + 'is_valid_date' => $this->p->t('ui', 'error_invalid_date'), 'isDateInFuture' => $this->p->t('ui', 'error_invalid_date') ] ); @@ -209,18 +209,9 @@ class Unterbrechung extends FHCAPI_Controller $this->terminateWithSuccess(getData($result)); } - public function isValidDate($date) - { - try { - new DateTime($date); - } catch (Exception $e) { - return false; - } - return true; - } - public function isDateInFuture($date) { return new DateTime() < new DateTime($date); } } + diff --git a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php index 26033908d..437ba42ad 100644 --- a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php +++ b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php @@ -36,15 +36,44 @@ class Aufnahmetermine extends FHCAPI_Controller // Load models $this->load->model('crm/Reihungstest_model', 'ReihungstestModel'); $this->load->model('crm/RtPerson_model', 'RtPersonModel'); + $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); + $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); } public function getAufnahmetermine($person_id) { $result = $this->ReihungstestModel->getReihungstestPerson($person_id); + $arrayRt = $this->getDataOrTerminateWithError($result); - $data = $this->getDataOrTerminateWithError($result); + foreach ($arrayRt as $item) { + //Studienplan + $result = $this->StudienplanModel->loadWhere([ + 'studienplan_id' => $item->studienplan_id + ]); + $data = $this->getDataOrTerminateWithError($result); + $studienordnung_id_ber = current($data)->studienordnung_id; - $this->terminateWithSuccess($data); + //Studienordnung + $result = $this->StudienordnungModel->loadWhere([ + 'studienordnung_id' => $studienordnung_id_ber + ]); + $data = $this->getDataOrTerminateWithError($result); + $studiengang_kz_ber = current($data)->studiengang_kz; + + //Studiengang von studiengang_kz_ber + $result = $this->StudiengangModel->load($studiengang_kz_ber); + $data = $this->getDataOrTerminateWithError($result); + + $studiengangkurzbzlang_ber = current($data)->kurzbzlang; + $typ_ber = current($data)->typ; + + //add to Array + $item->studiengang_kz_ber = $studiengang_kz_ber; + $item->studiengangkurzbzlang_ber = $studiengangkurzbzlang_ber; + $item->studiengangtyp_ber = $typ_ber; + } + $this->terminateWithSuccess($arrayRt); } public function insertAufnahmetermin() @@ -60,7 +89,6 @@ class Aufnahmetermine extends FHCAPI_Controller return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL); } - $rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null; $anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null; $teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false; @@ -224,7 +252,11 @@ class Aufnahmetermine extends FHCAPI_Controller ) ); - $data = $this->getDataOrTerminateWithError($result); + //check if existing placementtest + if(!hasData($result)) + $this->terminateWithSuccess([]); + else + $data = getData($result); $studienplan_arr = []; $include_ids = []; @@ -233,12 +265,18 @@ class Aufnahmetermine extends FHCAPI_Controller if($item->studienplan_id != null) $studienplan_arr[] = $item->studienplan_id; } + if(!hasData($studienplan_arr)) + $this->terminateWithSuccess([]); //get Placementtests Person $person_id = $this->_getPersonId($prestudent_id); $resultRt = $this->ReihungstestModel->getReihungstestPerson($person_id); - $dataRt = $this->getDataOrTerminateWithError($resultRt); + //check if existing placementtest + if(!hasData($result)) + $this->terminateWithSuccess([]); + else + $dataRt = getData($resultRt); foreach ($dataRt as $item) { @@ -354,6 +392,7 @@ class Aufnahmetermine extends FHCAPI_Controller $person_id = $this->input->get('person_id'); $punkte = $this->input->get('punkte'); $reihungstest_id = $this->input->get('reihungstest_id'); + $has_excluded_gebiete = $this->input->get('hasExcludedAreas'); if(!$reihungstest_id) { @@ -364,22 +403,27 @@ class Aufnahmetermine extends FHCAPI_Controller $studiengang_kz = $this->input->get('studiengang_kz'); $this->load->model('testtool/Ablauf_model', 'AblaufModel'); - $result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz); + $result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz, 1); $data = $this->getDataOrTerminateWithError($result); $weightedArray = []; + $basis_gebiet_id_arr = []; + $basis_gebiet_id_toString = ''; foreach ($data as $abl) { $weightedArray[$abl->gebiet_id] = $abl->gewicht; + $basis_gebiet_id_arr[]= $abl->gebiet_id; } + $basis_gebiet_id_toString = implode(', ', $basis_gebiet_id_arr); - $result = $this->ReihungstestModel->getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray); - -/* if (isError($result)) - { - $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - }*/ - + $result = $this->ReihungstestModel->getReihungstestErgebnisPerson( + $person_id, + $punkte, + $reihungstest_id, + $weightedArray, + $has_excluded_gebiete, + $basis_gebiet_id_toString + ); $this->terminateWithSuccess($result); } diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index c787381f0..bc1fbebfe 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/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index 2721bbd6f..7694807e7 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -108,6 +108,10 @@ class Student extends FHCAPI_Controller $this->PrestudentModel->addSelect('p.matr_nr'); $this->PrestudentModel->addSelect('p.anrede'); $this->PrestudentModel->addSelect('p.zugangscode'); + if($this->permissionlib->isBerechtigt('student/bpk')) + { + $this->PrestudentModel->addSelect('p.bpk'); + } if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) { $this->PrestudentModel->addSelect( @@ -542,6 +546,7 @@ class Student extends FHCAPI_Controller $this->_validate(); + // TODO(chris): This should be in a library $this->load->model('crm/Student_model', 'StudentModel'); $this->load->model('crm/Prestudent_model', 'PrestudentModel'); $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); @@ -793,8 +798,8 @@ class Student extends FHCAPI_Controller $this->form_validation->set_rules('geschlecht', 'Geschlecht', 'callback_requiredIfNotPersonId', [ 'requiredIfNotPersonId' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'geschlecht')]) ]); - $this->form_validation->set_rules('gebdatum', 'Geburtsdatum', ['isValidDate', function($value) { return isValidDate($value); }], [ - 'isValidDate' => $this->p->t('ui', 'error_invalid_date') + $this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_invalid_date') ]); //$this->form_validation->set_rules('address[checked]', 'Address', 'required'); $this->form_validation->set_rules('address[plz]', 'PLZ', 'callback_requiredIfAddressFunc', [ diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index acacca052..55f4b8976 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -611,7 +611,7 @@ class Students extends FHCAPI_Controller if (!$verband && !$gruppe && $orgform_kurzbz !== null) { $this->PrestudentModel->db->where( "( - SELECT orgform_kurzbz + SELECT orgform_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=tbl_prestudent.prestudent_id AND studiensemester_kurzbz=" . $this->PrestudentModel->escape($studiensemester_kurzbz) . " @@ -850,6 +850,41 @@ class Students extends FHCAPI_Controller { $stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL'; + $this->load->config('stv'); + $tags = $this->config->item('stv_prestudent_tags'); + + $whereTags = ''; + if (is_array($tags) && !isEmptyArray($tags)) { + $tags = array_keys($tags); + + foreach ($tags as $key => $tag) { + $tags[$key] = $this->db->escape($tag); + } + $whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")"; + } + $subQueryTag = " + ( + SELECT + tag.prestudent_id, + COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags + FROM ( + SELECT DISTINCT ON (n.notiz_id) + n.notiz_id AS id, + nt.typ_kurzbz, + array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung, + n.text AS notiz, + nt.style, + n.erledigt AS done, + nz.prestudent_id + FROM public.tbl_notizzuordnung AS nz + JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id + JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz " + . $whereTags . + " + ) AS tag + GROUP BY tag.prestudent_id + ) AS tag_data_agg + "; $this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT'); $this->PrestudentModel->addJoin('public.tbl_person p', 'person_id'); @@ -872,8 +907,11 @@ class Students extends FHCAPI_Controller AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ') AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT'); + $this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT'); + $this->PrestudentModel->addSelect("b.uid"); + $this->PrestudentModel->addSelect('tag_data_agg.tags'); $this->PrestudentModel->addSelect('titelpre'); $this->PrestudentModel->addSelect('nachname'); $this->PrestudentModel->addSelect('vorname'); @@ -931,6 +969,7 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('mentor'); $this->PrestudentModel->addSelect('b.aktiv AS bnaktiv'); + $this->PrestudentModel->addSelect('unruly'); $this->PrestudentModel->db->where_in('tbl_prestudent.studiengang_kz', $this->allowedStgs); 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..3004a1f3b --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Tags.php @@ -0,0 +1,48 @@ + self::BERECHTIGUNG_KURZBZ, + 'getTags' => self::BERECHTIGUNG_KURZBZ, + 'addTag' => self::BERECHTIGUNG_KURZBZ, + 'updateTag' => self::BERECHTIGUNG_KURZBZ, + 'doneTag' => self::BERECHTIGUNG_KURZBZ, + 'deleteTag' => self::BERECHTIGUNG_KURZBZ + ]); + + $this->config->load('stv'); + } + + public function getTag($readonly_tags = null) + { + parent::getTag($this->config->item('stv_prestudent_tags')); + } + public function getTags($tags = null) + { + 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/controllers/api/frontend/v1/vertraege/Config.php b/application/controllers/api/frontend/v1/vertraege/Config.php new file mode 100644 index 000000000..a4ebd8c48 --- /dev/null +++ b/application/controllers/api/frontend/v1/vertraege/Config.php @@ -0,0 +1,62 @@ +. + */ + +if (!defined('BASEPATH')) exit('No direct script access allowed'); + +use CI3_Events as Events; + +/** + * This controller operates between (interface) the JS (GUI) and the back-end + * Provides data to the ajax get calls about the VV Config + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Config extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'printDocument' => ['vertrag/mitarbeiter:r'], + ]); + } + + public function printDocument() + { + $params = []; + $menu = []; + + Events::trigger( + 'multiActionPrintHonorarvertrag', + // passing $menu per reference + function & () use (&$menu) { + return $menu; + }, + $params + ); + + if (is_array($menu) && isset($menu[0])) + { + $this->terminateWithSuccess($menu[0]); + } + else + { + // $this->terminateWithError('Error with Event 'multiActionPrintHonorarvertrag'); + $this->terminateWithSuccess(); + + } + } +} diff --git a/application/controllers/api/frontend/v1/vertraege/Vertraege.php b/application/controllers/api/frontend/v1/vertraege/Vertraege.php index bb14bc511..c0683e999 100644 --- a/application/controllers/api/frontend/v1/vertraege/Vertraege.php +++ b/application/controllers/api/frontend/v1/vertraege/Vertraege.php @@ -26,9 +26,6 @@ class Vertraege extends FHCAPI_Controller 'deleteLehrauftrag' =>['vertrag/mitarbeiter:w'], 'deleteBetreuung' =>['vertrag/mitarbeiter:w'], 'getMitarbeiter' => ['vertrag/mitarbeiter:r'], - 'getHeader' => ['vertrag/mitarbeiter:r'], - 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], - 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], ]); //Load Models and Libraries @@ -241,7 +238,7 @@ class Vertraege extends FHCAPI_Controller } } $this->db->trans_complete(); - $this->terminateWithSuccess(true); + $this->terminateWithSuccess($vertrag_id); } public function updateContract() @@ -358,7 +355,7 @@ class Vertraege extends FHCAPI_Controller } $this->db->trans_complete(); - $this->terminateWithSuccess(true); + $this->terminateWithSuccess($vertrag_id); } public function loadContract($vertrag_id) @@ -684,37 +681,4 @@ class Vertraege extends FHCAPI_Controller } return $this->terminateWithSuccess(getData($result)); } - - public function getPersonAbteilung($mitarbeiter_uid) - { - $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); - - $result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess(current($data)); - } - - public function getLeitungOrg($oekurzbz) - { - $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); - - $result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess(current($data)); - } - - public function getHeader($person_id) - { - $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); - - $result = $this->Mitarbeitermodel->getHeader($person_id); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess(current($data)); - } } diff --git a/application/core/CI3_Events.php b/application/core/CI3_Events.php index 37f6c3f21..ad4aea729 100644 --- a/application/core/CI3_Events.php +++ b/application/core/CI3_Events.php @@ -35,7 +35,7 @@ class CI3_Events }); self::$eventsSorted[$event] = true; } - + foreach (self::$events[$event] as $conf) { $conf[1](...$args); } diff --git a/application/core/Notiz_Controller.php b/application/core/Notiz_Controller.php index cfc54d5f5..923970923 100644 --- a/application/core/Notiz_Controller.php +++ b/application/core/Notiz_Controller.php @@ -8,7 +8,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller { const DEFAULT_PERMISSION_R = 'admin:r'; const DEFAULT_PERMISSION_RW = 'admin:rw'; - //public function __construct($zuordnung = 'person/Notizzuordnung_model') + public function __construct($permissions) { $default_permissions = [ @@ -97,13 +97,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() @@ -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 @@ -143,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', [ @@ -166,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; @@ -220,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']; } @@ -235,34 +228,28 @@ 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() { + $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', [ @@ -280,25 +267,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 @@ -306,7 +291,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 @@ -314,7 +299,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( @@ -351,7 +336,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); } @@ -365,7 +350,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->getDataOrTerminateWithError($result); } - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } public function deleteNotiz() @@ -416,15 +401,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() @@ -440,14 +425,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) @@ -457,7 +442,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); } public function getCountNotes($person_id) @@ -476,4 +461,4 @@ abstract class Notiz_Controller extends FHCAPI_Controller return $this->terminateWithSuccess($anzahl->anzahl ?: 0); } -} \ No newline at end of file +} diff --git a/application/helpers/hlp_common_helper.php b/application/helpers/hlp_common_helper.php index b13d9d44d..06cfa1cfd 100644 --- a/application/helpers/hlp_common_helper.php +++ b/application/helpers/hlp_common_helper.php @@ -91,7 +91,7 @@ function var_dump_to_error_log($parameter) var_dump($parameter); // KEEP IT!!! $ob_get_contents = ob_get_contents(); ob_end_clean(); - error_log(str_replace("\n", '', $ob_get_contents)); // KEEP IT!!! + error_log(str_replace("\n", '', $ob_get_contents) . ', referer: ' . "http".(!empty($_SERVER['HTTPS'])?"s":"")."://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']); // KEEP IT!!! } /** @@ -408,22 +408,6 @@ function findResource($path, $resource, $subdir = false, $extraDir = null) return null; } -/** - * check if String can be converted to a date - */ -function isValidDate($dateString) -{ - try - { - return (new DateTime($dateString)) !== false; - } - catch(Exception $e) - { - return false; - } -} - - // ------------------------------------------------------------------------ // PHP functions that don't exist in older versions // ------------------------------------------------------------------------ @@ -446,7 +430,8 @@ if (!function_exists('array_is_list')) { // ------------------------------------------------------------------------ /** - * check if string can be converted to a date + * Check if the provided parameter is a string containing a valid date + * NOTE: the name is in the "snake case" format because othewise the CI form validation _cannot_ use it */ function is_valid_date($dateString) { diff --git a/application/models/accounting/Vertrag_model.php b/application/models/accounting/Vertrag_model.php index 4c036369b..97b5c72b6 100644 --- a/application/models/accounting/Vertrag_model.php +++ b/application/models/accounting/Vertrag_model.php @@ -490,6 +490,175 @@ class Vertrag_model extends DB_Model return $bezeichnung; } + /** + * Loads all Contracts of a Person + * @param $person_id + * @return array of objects + */ + public function loadContractsOfPerson($person_id) + { + $query = " + SELECT + *, + tbl_vertrag.bezeichnung as bezeichnung, + tbl_vertragstyp.bezeichnung as vertragstyp_bezeichnung, + tbl_vertrag.vertragsdatum, + (SELECT bezeichnung FROM lehre.tbl_vertragsstatus + JOIN lehre.tbl_vertrag_vertragsstatus USING(vertragsstatus_kurzbz) + WHERE vertrag_id=tbl_vertrag.vertrag_id ORDER BY datum desc limit 1) as status, anmerkung, + CASE + WHEN EXISTS ( + SELECT 1 + FROM lehre.tbl_vertrag_vertragsstatus + WHERE vertrag_id = tbl_vertrag.vertrag_id + AND vertragsstatus_kurzbz = 'abgerechnet' + ) THEN true + ELSE false + END AS isAbgerechnet + FROM + lehre.tbl_vertrag + LEFT JOIN lehre.tbl_vertragstyp USING(vertragstyp_kurzbz) + WHERE person_id= ?"; + + + return $this->execQuery($query, array($person_id)); + } + + /** + * Loads all Contracts of a Person that are not assigned yet + * @param $person_id + * @return array of objects + */ + public function loadContractsOfPersonNotAssigned($person_id) + { + $query = " +SELECT + 'Lehrauftrag' as type, + lehreinheit_id, + mitarbeiter_uid, + null as pruefung_id, + null as projektarbeit_id, + (tbl_lehreinheitmitarbeiter.semesterstunden*tbl_lehreinheitmitarbeiter.stundensatz) as betrag1, + tbl_lehreinheit.studiensemester_kurzbz, + null as betreuerart_kurzbz, + ( SELECT + upper(tbl_studiengang.typ || tbl_studiengang.kurzbz) || tbl_lehrveranstaltung.semester || '-' || tbl_lehrveranstaltung.kurzbz || '-' || tbl_lehreinheit.lehrform_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE + lehrveranstaltung_id=tbl_lehreinheit.lehrveranstaltung_id) + as bezeichnung + FROM + lehre.tbl_lehreinheitmitarbeiter + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + mitarbeiter_uid IN (SELECT uid FROM public.tbl_benutzer WHERE person_id=?) + AND vertrag_id IS NULL + UNION + SELECT + 'Betreuung' as type, + tbl_projektarbeit.lehreinheit_id as lehreinheit_id, + null as mitarbeiter_uid, + null::integer as pruefung_id, + projektarbeit_id, + (tbl_projektbetreuer.stunden*tbl_projektbetreuer.stundensatz) as betrag1, + tbl_lehreinheit.studiensemester_kurzbz, + tbl_projektbetreuer.betreuerart_kurzbz, + (SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid) + as bezeichnung + FROM + lehre.tbl_projektbetreuer + JOIN lehre.tbl_projektarbeit USING(projektarbeit_id) + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + tbl_projektbetreuer.person_id=? + AND vertrag_id IS NULL + "; + + return $this->execQuery($query, array($person_id, $person_id)); + } + + /** + * Loads all Contracts of a Person that are assigned yet + * @param $person_id, $vertrag_id + * @return array of objects + */ + + public function loadContractsOfPersonAssigned($person_id, $vertrag_id) + { + $query = " + SELECT + 'Lehrauftrag' as type, + lehreinheit_id, + mitarbeiter_uid, + null as pruefung_id, + null as projektarbeit_id, + (tbl_lehreinheitmitarbeiter.semesterstunden * tbl_lehreinheitmitarbeiter.stundensatz) as betrag, + tbl_lehreinheit.studiensemester_kurzbz, + null as betreuerart_kurzbz, + ( SELECT + upper(tbl_studiengang.typ || tbl_studiengang.kurzbz) || tbl_lehrveranstaltung.semester || '-' || tbl_lehrveranstaltung.kurzbz || '-' || tbl_lehreinheit.lehrform_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE + lehrveranstaltung_id=tbl_lehreinheit.lehrveranstaltung_id) + as bezeichnung, vertrag_id + FROM + lehre.tbl_lehreinheitmitarbeiter + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + mitarbeiter_uid IN (SELECT uid FROM public.tbl_benutzer WHERE person_id=?) + AND vertrag_id = ? + UNION + SELECT + 'Betreuung' as type, + tbl_projektarbeit.lehreinheit_id as lehreinheit_id, + null as mitarbeiter_uid, + null::integer as pruefung_id, + projektarbeit_id, + (tbl_projektbetreuer.stunden * tbl_projektbetreuer.stundensatz) as betrag, + tbl_lehreinheit.studiensemester_kurzbz, + tbl_projektbetreuer.betreuerart_kurzbz, + (SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid) + as bezeichnung, vertrag_id + FROM + lehre.tbl_projektbetreuer + JOIN lehre.tbl_projektarbeit USING(projektarbeit_id) + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + tbl_projektbetreuer.person_id=? + AND vertrag_id = ? + "; + + return $this->execQuery($query, array($person_id, $vertrag_id, $person_id, $vertrag_id)); + } + + /** + * Returns all stati of a contract + * + * @param $vertrag_id + * @return array + */ + public function getStatiOfContract($vertrag_id) + { + $query = " + SELECT + *, + tbl_vertrag_vertragsstatus.datum, + tbl_vertrag_vertragsstatus.insertamum, + tbl_vertrag_vertragsstatus.updateamum + FROM + lehre.tbl_vertrag_vertragsstatus + JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz) + WHERE + tbl_vertrag_vertragsstatus.vertrag_id = ? + ORDER BY tbl_vertrag_vertragsstatus.datum DESC"; + + return $this->execQuery($query, array($vertrag_id)); + } + private function _updateVertragRelevant($vertrag_id) { $this->LehreinheitmitarbeiterModel->update( diff --git a/application/models/accounting/Vertragstyp_model.php b/application/models/accounting/Vertragstyp_model.php index 42d248217..a3275af6e 100644 --- a/application/models/accounting/Vertragstyp_model.php +++ b/application/models/accounting/Vertragstyp_model.php @@ -11,4 +11,5 @@ class Vertragstyp_model extends DB_Model $this->dbTable = 'lehre.tbl_vertragstyp'; $this->pk = 'vertragstyp_kurzbz'; } + } diff --git a/application/models/accounting/Vertragvertragsstatus_model.php b/application/models/accounting/Vertragvertragsstatus_model.php index 78a065540..75b0794cc 100644 --- a/application/models/accounting/Vertragvertragsstatus_model.php +++ b/application/models/accounting/Vertragvertragsstatus_model.php @@ -190,4 +190,6 @@ class Vertragvertragsstatus_model extends DB_Model return $this->loadWhere($condition); } + + } diff --git a/application/models/crm/Reihungstest_model.php b/application/models/crm/Reihungstest_model.php index a685b01cd..efef0a8fa 100644 --- a/application/models/crm/Reihungstest_model.php +++ b/application/models/crm/Reihungstest_model.php @@ -10,7 +10,7 @@ class Reihungstest_model extends DB_Model parent::__construct(); $this->dbTable = 'public.tbl_reihungstest'; $this->pk = 'reihungstest_id'; - } + } /** * Gets a test from a test id only if it is available @@ -42,8 +42,8 @@ class Reihungstest_model extends DB_Model /** * Checks if there are active studyplans which have no public placement tests assigned yet. * Only check assignment to studyplans that are - * - Bachelor, - * - active, + * - Bachelor, + * - active, * - set as online application * - valid for 1st terms * @return array Returns object array with studyplans that have no public placement tests assigned yet. @@ -97,7 +97,7 @@ class Reihungstest_model extends DB_Model USING (reihungstest_id) WHERE datum >= now() - AND + AND oeffentlich = \'t\' ) '; @@ -105,7 +105,7 @@ class Reihungstest_model extends DB_Model return $this->execQuery($query); } - /** + /** * Gets amount of free places. * @return array Returns object array with faculty and amount of free places * for each public actual placement test date. @@ -432,10 +432,10 @@ class Reihungstest_model extends DB_Model } /** - * Loads all applicants of a placement test - * @param integer $reihungstest_id ID of placement test - * @return array Returns object array with data of applicants. - */ + * Loads all applicants of a placement test + * @param integer $reihungstest_id ID of placement test + * @return array Returns object array with data of applicants. + */ public function getApplicantsOfPlacementTest($reihungstest_id) { $query = ' @@ -556,13 +556,22 @@ class Reihungstest_model extends DB_Model * Calculates Result of Placement Test for a given Person and given placementtest * and with taking account of weighting per area * - * @param $person_id ID of Person - * @param $punkte if true result is points else result is percentage of sum - * @param $reihungstest_id ID of Placementtest - * @param $weightedArray array of weighting per area (gewicht per gebiet_id) - * @return float result + * @param Number $person_id ID of Person + * @param Boolean $punkte if true result is points else result is percentage of sum + * @param Number $reihungstest_id ID of Placementtest + * @param Array $weightedArray array of weighting per area (gewicht per gebiet_id) + * @param Boolean $has_excluded_gebiete if true, areas in the configArray will be excluded + * @param Array $basis_gebiet_id_toString areas to exclude + * @return float result points of RT */ - public function getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray = null) + public function getReihungstestErgebnisPerson( + $person_id, + $punkte, + $reihungstest_id, + $weightedArray = null, + $has_excluded_gebiete = false, + $basis_gebiet_id_toString = null + ) { $parametersArray = array($reihungstest_id); @@ -577,6 +586,35 @@ class Reihungstest_model extends DB_Model WHERE reihungstest_id = ? "; + //areas of Studiengang + if (!empty($basis_gebiet_id_toString)) + { + $qry .= " + AND + gebiet_id IN (". $basis_gebiet_id_toString. ") + "; + } + + //areas to exclude + if($has_excluded_gebiete) + { + if (defined('FAS_REIHUNGSTEST_EXCLUDE_GEBIETE') && !empty(FAS_REIHUNGSTEST_EXCLUDE_GEBIETE)) + { + $excluded_gebiete = unserialize(FAS_REIHUNGSTEST_EXCLUDE_GEBIETE); + $exclude_gebiet_id_arr = $excluded_gebiete; + if (is_array($exclude_gebiet_id_arr) && count($exclude_gebiet_id_arr) > 0) + { + $exclude_gebiet_id_toString = implode(', ', $exclude_gebiet_id_arr); + $qry .= " + AND + gebiet_id NOT IN (". $exclude_gebiet_id_toString. ") + -- AND + -- typ = 'b' + "; + } + } + } + //using prestudent Status to avoid to get the sum of more than 1 placement tests $qry .= " AND prestudent_id = ( diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php index a650643f1..d8bbd7d63 100644 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -209,7 +209,7 @@ class Mitarbeiter_model extends DB_Model { $qry = " SELECT - titelpre, vorname, nachname, titelpost, foto, foto_sperre, person_id, alias, telefonklappe + titelpre, vorname, nachname, titelpost, foto, foto_sperre, person_id, alias, telefonklappe, personalnummer, mitarbeiter_uid FROM public.tbl_person JOIN public.tbl_benutzer b USING(person_id) @@ -363,14 +363,14 @@ class Mitarbeiter_model extends DB_Model $returnwert .= ", ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter"; $qry = " - SELECT " . $returnwert . " - FROM + SELECT " . $returnwert . " + FROM public.tbl_mitarbeiter ma - JOIN + JOIN public.tbl_benutzer b on (ma.mitarbeiter_uid = b.uid) - JOIN + JOIN public.tbl_person p on (p.person_id = b.person_id) - WHERE + WHERE lower (p.nachname) LIKE '%". $this->db->escape_like_str($filter)."%' OR lower (p.vorname) LIKE '%". $this->db->escape_like_str($filter)."%' @@ -393,14 +393,14 @@ class Mitarbeiter_model extends DB_Model public function getMitarbeiterFromLV($lehrveranstaltung_id) { $qry = "SELECT DISTINCT - lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid - FROM + lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid + FROM lehre.tbl_lehreinheitmitarbeiter, campus.vw_mitarbeiter, lehre.tbl_lehreinheit - WHERE + WHERE lehrveranstaltung_id= ? - AND - mitarbeiter_uid=uid - AND + AND + mitarbeiter_uid=uid + AND tbl_lehreinheitmitarbeiter.lehreinheit_id=tbl_lehreinheit.lehreinheit_id;"; $parametersArray = array($lehrveranstaltung_id); diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 19129b606..3e59d7250 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -276,6 +276,8 @@ class Message_model extends DB_Model s.message_id, s.person_id, MAX(s.insertamum) as lastinserted from public.tbl_msg_status s + join + filtered_messages fm on fm.message_id = s.message_id and fm.recipient_id = s.person_id group by s.message_id, s.person_id ) ls diff --git a/application/views/Studentenverwaltung.php b/application/views/Studentenverwaltung.php index 1cd28d735..8dd2dd93d 100644 --- a/application/views/Studentenverwaltung.php +++ b/application/views/Studentenverwaltung.php @@ -7,19 +7,21 @@ 'vue3' => true, 'primevue3' => true, #'filtercomponent' => true, - 'tabulator5' => true, + 'tabulator6' => true, 'tinymce5' => true, 'phrases' => array( 'global', '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/components/Detailheader.css' ], 'customJSs' => [ 'vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js', @@ -45,6 +47,8 @@ $configArray = [ 'showAufnahmegruppen' => !defined('FAS_REIHUNGSTEST_AUFNAHMEGRUPPEN') ? false : FAS_REIHUNGSTEST_AUFNAHMEGRUPPEN, 'allowUebernahmePunkte' => !defined('FAS_REIHUNGSTEST_PUNKTEUEBERNAHME') ? true : FAS_REIHUNGSTEST_PUNKTEUEBERNAHME, 'useReihungstestPunkte' => !defined('FAS_REIHUNGSTEST_PUNKTE') ? true : FAS_REIHUNGSTEST_PUNKTE, + 'hasExcludedAreas' => defined('FAS_REIHUNGSTEST_EXCLUDE_GEBIETE') && !empty(FAS_REIHUNGSTEST_EXCLUDE_GEBIETE), + 'stvTagsEnabled' => defined('STV_TAGS_ENABLED') ? STV_TAGS_ENABLED : false, ]; ?> diff --git a/application/views/Vertragsverwaltung.php b/application/views/Vertragsverwaltung.php new file mode 100644 index 000000000..8fa6dff27 --- /dev/null +++ b/application/views/Vertragsverwaltung.php @@ -0,0 +1,50 @@ + 'Vertragsverwaltung', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'primevue3' => true, + 'filtercomponent' => true, + 'navigationcomponent' => true, + 'tabulator6' => true, + 'tinymce5' => true, + 'phrases' => array( + 'global', + 'ui', + ), + 'customCSSs' => [ + 'public/css/components/vue-datepicker.css', + 'public/css/components/primevue.css', + 'public/css/Vertragsverwaltung.css', + 'public/css/components/Detailheader.css' + ], + 'customJSs' => [ + #'vendor/npm-asset/primevue/tree/tree.min.js', + #'vendor/npm-asset/primevue/toast/toast.min.js' + ], + 'customJSModules' => [ + 'public/js/apps/Vertragsverwaltung.js' + ] +); + +$this->load->view('templates/FHC-Header', $includesArray); +?> + + !defined('DOMAIN') ? 'notDefined' : DOMAIN, +]; +?> + +
+ + +
+ +load->view('templates/FHC-Footer', $includesArray); ?> + diff --git a/cis/public/coodle.php b/cis/public/coodle.php index 2b8421db0..05eaa41df 100644 --- a/cis/public/coodle.php +++ b/cis/public/coodle.php @@ -1041,7 +1041,7 @@ function sendEmail($coodle_id) ."END:STANDARD\r\n" ."END:VTIMEZONE\r\n" ."BEGIN:VEVENT\r\n" - .$coodle->foldContentLine("ORGANIZER:MAILTO:".$erstellername." <".$coodle->ersteller_uid."@".DOMAIN)."\r\n" + .$coodle->foldContentLine("ORGANIZER:MAILTO:".$erstellername." <".$coodle->ersteller_uid."@".DOMAIN).">\r\n" .rtrim($teilnehmer)."\r\n" ."DTSTART;TZID=Europe/Vienna:".$dtstart."\r\n" ."DTEND;TZID=Europe/Vienna:".$dtend."\r\n" diff --git a/config/global.config-default.inc.php b/config/global.config-default.inc.php index c43cb38d1..943363f6d 100644 --- a/config/global.config-default.inc.php +++ b/config/global.config-default.inc.php @@ -371,4 +371,6 @@ define('STATUS_VORRUECKEN_ANZEIGEN', true); //externe Ueberwachung im Testtool erlauben define('TESTTOOL_EXTERNE_UEBERWACHUNG_ALLOWED', false); +//enable tags in StudVW +define('STV_TAGS_ENABLED', false); ?> diff --git a/public/css/Studentenverwaltung.css b/public/css/Studentenverwaltung.css index eb6becc15..cb4b8f2e9 100644 --- a/public/css/Studentenverwaltung.css +++ b/public/css/Studentenverwaltung.css @@ -12,22 +12,22 @@ html { font-size: .875em; } html.fs_xx-small { - font-size: .5em; + font-size: .625em; } html.fs_x-small { - font-size: .625em; + font-size: .6875em; } html.fs_small { font-size: .75em; } html.fs_normal { - font-size: .875em; + font-size: .8125em; } html.fs_big { - font-size: 1em; + font-size: .875em; } html.fs_huge { - font-size: 1.125em; + font-size: 1em; } #appMenu { @@ -74,6 +74,12 @@ html.fs_huge { color: var(--gray-500); } +/* Aufnahme Termine: background color green*/ +.stv-details-admission-table .row-green{ + background-color: lightgreen !important; + //color: var(--green-200); +} + /* Dropdown Toolbar Interessent, submenu */ .dropend .dropdown-toggle.d-flex::after { height: 0; @@ -116,6 +122,15 @@ html.fs_huge { position: inherit; z-index: 1; } + + .sidebar-collapsed #sidebarMenu { + display: none !important; + } + + .sidebar-collapsed .container-fluid > .row > main { + flex: 0 0 100%; + max-width: 100%; + } } @@ -168,7 +183,7 @@ html.fs_huge { } .has-filter .fa-filter { - color: var(--bs-success); + color: var(--bs-danger); } .override_filtercmpt_actions_style div.d-flex.align-items-baseline { align-items: end !important; @@ -185,3 +200,84 @@ html.fs_huge { .tiny-90 div.tox.tox-tinymce { height: 90% !important; } + +/* slim begin */ +.stv .form-label { + margin-bottom: .15rem; + font-weight: bold; +} + +.stv .form-control, +.stv .form-select, +.stv .input-group-text { + padding-top: .15rem; + padding-bottom: .15rem; +} + +:root { + --bs-body-line-height: 1.2; +} + +.stv .tabulator-row .tabulator-cell, +.stv .tabulator-header-filter input { + padding-top: 1px !important; + padding-bottom: 1px !important; +} + +.stv .tabulator-row { + min-height: 18px; +} + +.stv .btn { + --bs-btn-padding-y: 0.25rem; + --bs-btn-line-height: 1.2; +} + +.stv .p-button.p-button-icon-only { + padding-top: 0; + padding-bottom: 0; +} + +.stv .p-tabview .p-tabview-nav li .p-tabview-nav-link { + padding: 0.25rem .5rem; +} +/* +.stv .p-tabview .p-tabview-panels { + background-color: #e5eff5; +} + +.stv .p-tabview .p-tabview-nav li.p-highlight .p-tabview-nav-link { + background: #e5eff5; + border-color: #dee2e6 #dee2e6 #e5eff5 #dee2e6; +} +*/ +.stv-details-details-foto img { + max-height: 120px; +} + +.stv .tabulator-row .tabulator-frozen, +.stv .tabulator-row .tabulator-cell { + border-bottom: none; +} + +/* +.stv .p-treetable .p-treetable-thead > tr > th, +.stv .p-treetable .p-treetable-tbody > tr { + background-color: #e5eff5; +} + +.stv .p-treetable .p-treetable-tbody > tr.p-highlight { + background: #007bff; + color: #fff; +} + +.stv .p-treetable.p-treetable-hoverable-rows .p-treetable-tbody > tr:not(.p-highlight):hover { + background: #fff; + color: #212529; +} + +.tabulator-row.tabulator-row-even .tabulator-cell { + background-color: #e5eff5; +} +*/ +/* slim ende */ diff --git a/public/css/Vertragsverwaltung.css b/public/css/Vertragsverwaltung.css new file mode 100644 index 000000000..7b2d71481 --- /dev/null +++ b/public/css/Vertragsverwaltung.css @@ -0,0 +1,20 @@ +@import './components/verticalsplit.css'; + +html { + font-size: .875em; +} +.vv{ + display: flex; + flex-direction: column; + height: 100vh; +} +.vv> header { + flex: 0 0 auto; +} +.vv> div { + flex: 1 1 auto; +} + +.vv { + margin-left: 0 !important; +} diff --git a/public/css/components/Detailheader.css b/public/css/components/Detailheader.css new file mode 100644 index 000000000..dcfcf6806 --- /dev/null +++ b/public/css/components/Detailheader.css @@ -0,0 +1,64 @@ +.foto-container:hover .fotoedit { + opacity: 1 !important; +} + +.bg-unruly { + background-color: #ad1010 !important; + color: white; +} + +/*.fotosperre { + z-index: 1; + font-size: 1rem; + width: 1.25rem; + height: 1.25rem; +}*/ + +.foto-container .fotoedit { + opacity: 0; + transition: opacity 0.3s; + backdrop-filter: blur(2px); +} + +.fotoedit { + background-color: rgba(0, 0, 0, 0.4); + color: white; + border: none; + z-index: 4; + font-size: 1rem; + width: 1.8rem; + height: 1.8rem; + opacity:0; + transition: opacity 0.2s; + top:20%; +} + +/* fotoeditMa { + background-color: rgba(0, 0, 0, 0.4); + color: white; + border: none; + z-index: 4; + font-size: 1rem; + opacity:0; + transition: opacity 0.2s; + top:20%; +}*/ + +.buttonleft { + margin-left: .25rem; +} + +.buttonright { + margin-right: .25rem; +} + +/*.fotoEditMa { + z-index: 104; + font-size: 1rem; + width: 2.5rem; + height: 2.5rem; + opacity:0; + transition: opacity 0.2s; + top:13%;" + z-index: 104; font-size: 1rem; width: 2.5rem; height: 2.5rem; opacity:0; transition: opacity 0.2s; top:13%;" +}*/ diff --git a/public/css/components/primevue.css b/public/css/components/primevue.css index ac1950334..97b918011 100644 --- a/public/css/components/primevue.css +++ b/public/css/components/primevue.css @@ -3578,6 +3578,12 @@ transition: box-shadow 0.15s; margin-right: 0.5rem; } + +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler > svg, +.p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler > svg * { + pointer-events: none; +} + .p-treetable .p-treetable-tbody > tr > td .p-treetable-toggler:enabled:hover { color: #495057; border-color: transparent; diff --git a/public/js/api/factory/detailHeader.js b/public/js/api/factory/detailHeader.js index 74563bd4b..3c7d95bb1 100644 --- a/public/js/api/factory/detailHeader.js +++ b/public/js/api/factory/detailHeader.js @@ -19,19 +19,19 @@ export default { getHeader(person_id){ return { method: 'get', - url: 'api/frontend/v1/vertraege/vertraege/getHeader/' + person_id, + url: 'api/frontend/v1/detailheader/detailheader/getHeader/' + person_id, }; }, getPersonAbteilung(mitarbeiter_uid){ return { method: 'get', - url: 'api/frontend/v1/vertraege/vertraege/getPersonAbteilung/' + mitarbeiter_uid, + url: 'api/frontend/v1/detailheader/detailheader/getPersonAbteilung/' + mitarbeiter_uid, }; }, getLeitungOrg(oekurzbz){ return { method: 'get', - url: 'api/frontend/v1/vertraege/vertraege/getLeitungOrg/' + oekurzbz, + url: 'api/frontend/v1/detailheader/detailheader/getLeitungOrg/' + oekurzbz, }; }, } \ No newline at end of file diff --git a/public/js/api/factory/fotoHandling.js b/public/js/api/factory/fotoHandling.js new file mode 100644 index 000000000..8fffaef07 --- /dev/null +++ b/public/js/api/factory/fotoHandling.js @@ -0,0 +1,32 @@ +/** + * 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 . + */ + +export default { + uploadFoto(person_id, params) { + return { + method: 'post', + url: 'api/frontend/v1/fotoHandling/Foto/uploadFoto/' + person_id, + params + }; + }, + deleteFoto(person_id){ + return { + method: 'post', + url: 'api/frontend/v1/fotoHandling/Foto/deleteFoto/' + person_id + }; + } +} \ No newline at end of file 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/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/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 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/api/factory/vertraege/vertraege.js b/public/js/api/factory/vertraege/vertraege.js new file mode 100644 index 000000000..afd5cb166 --- /dev/null +++ b/public/js/api/factory/vertraege/vertraege.js @@ -0,0 +1,136 @@ +/** + * 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 . + */ + +export default { + getAllVertraege(person_id) { + return { + method: 'get', + url: 'api/frontend/v1/vertraege/Vertraege/getAllVertraege/' + person_id + }; + }, + getAllContractsNotAssigned(person_id) { + return { + method: 'get', + url: 'api/frontend/v1/vertraege/Vertraege/getAllContractsNotAssigned/' + person_id + }; + }, + getAllContractsAssigned(person_id, vertrag_id) { + return { + method: 'get', + url: 'api/frontend/v1/vertraege/Vertraege/getAllContractsAssigned/' + person_id + '/' + vertrag_id + '' + }; + }, + getAllContractTypes() { + return { + method: 'get', + url: 'api/frontend/v1/vertraege/Vertraege/getAllContractTypes/' + }; + }, + getStatiOfContract(person_id, vertrag_id){ + return { + method: 'get', + url: 'api/frontend/v1/vertraege/Vertraege/getStatiOfContract/' + person_id + '/' + vertrag_id + }; + }, + configPrintDocument() { + return { + method: 'get', + url: 'api/frontend/v1/vertraege/Config/printDocument/' + }; + }, + getAllContractStati() { + return { + method: 'get', + url: 'api/frontend/v1/vertraege/vertraege/getAllContractStati/' + }; + }, + deleteContract(vertrag_id) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/deleteContract/' + vertrag_id + }; + }, + addNewContract(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/addNewContract/', + params + }; + }, + loadContract(vertrag_id){ + return { + method: 'get', + url: 'api/frontend/v1/vertraege/vertraege/loadContract/' + vertrag_id + }; + }, + updateContract(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/updateContract/', + params + }; + }, + loadContractStatus(params){ + return { + method: 'get', + url: 'api/frontend/v1/vertraege/vertraege/loadContractStatus/', + params + }; + }, + insertContractStatus(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/insertContractStatus/', + params + }; + }, + updateContractStatus(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/updateContractStatus/', + params + }; + }, + deleteContractStatus(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/deleteContractStatus/', + params + }; + }, + deleteLehrauftrag(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/deleteLehrauftrag/', + params + }; + }, + deleteBetreuung(params) { + return { + method: 'post', + url: 'api/frontend/v1/vertraege/vertraege/deleteBetreuung/', + params + }; + }, + //loaded by mitarbeiter_header_js + getMitarbeiter(){ + return { + method: 'get', + url: 'api/frontend/v1/vertraege/vertraege/getMitarbeiter/', + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/fhcapifactory.js b/public/js/api/fhcapifactory.js index 63ad680ad..a0f9b50df 100644 --- a/public/js/api/fhcapifactory.js +++ b/public/js/api/fhcapifactory.js @@ -39,6 +39,7 @@ import studiengang from "./studiengang.js"; import menu from "./menu.js"; import dashboard from "./dashboard.js"; import authinfo from "./authinfo.js"; +import vertraege from "./vertraege.js"; import studium from "./studium.js"; import language from "./language.js"; @@ -68,6 +69,7 @@ export default { studiengang, menu, authinfo, + vertraege, studium, - language + language }; diff --git a/public/js/api/notiz.js b/public/js/api/notiz.js index 0a1034703..a75eb6f2d 100644 --- a/public/js/api/notiz.js +++ b/public/js/api/notiz.js @@ -1,5 +1,22 @@ import person from "./notiz/person.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"; + export default { - person -} \ No newline at end of file + person, + prestudent, + mitarbeiter, + anrechnung, + bestellung, + lehreinheit, + projekt, + projektphase, + projekttask, +} 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 04812eacc..cce0ff8c0 100644 --- a/public/js/api/notiz/person.js +++ b/public/js/api/notiz/person.js @@ -38,4 +38,4 @@ export default { 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/api/vertraege.js b/public/js/api/vertraege.js new file mode 100644 index 000000000..a29fdf3b0 --- /dev/null +++ b/public/js/api/vertraege.js @@ -0,0 +1,8 @@ +import person from "./vertraege/person.js"; + +export default { + person, + configPrintDocument() { + return this.$fhcApi.get('api/frontend/v1/vertraege/config/printDocument'); + } +} \ No newline at end of file diff --git a/public/js/api/vertraege/person.js b/public/js/api/vertraege/person.js new file mode 100644 index 000000000..c2f82b9e7 --- /dev/null +++ b/public/js/api/vertraege/person.js @@ -0,0 +1,69 @@ +export default { + getAllVertraege(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getAllVertraege/' + params.person_id); + }, + getAllContractsNotAssigned(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getAllContractsNotAssigned/' + params.person_id); + }, + getAllContractsAssigned(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getAllContractsAssigned/' + params.person_id + '/' + params.vertrag_id); + }, + getAllContractsNotAssigned2(person_id){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getAllContractsNotAssigned/' + person_id); + }, + getStatiOfContract(url, config, params){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getStatiOfContract/' + params.vertrag_id); + }, + getAllContractTypes(){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getAllContractTypes/'); + }, + getAllContractStati(){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getAllContractStati/'); + }, + addNewContract(form, data) { + return this.$fhcApi.post(form,'api/frontend/v1/vertraege/vertraege/addNewContract/', data); + }, + loadContract(vertrag_id){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/loadContract/' + vertrag_id); + }, + updateContract(form, data) { + return this.$fhcApi.post(form,'api/frontend/v1/vertraege/vertraege/updateContract/', data); + }, + deleteContract(vertrag_id){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/deleteContract/' + vertrag_id); + }, + loadContractStatus(params){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/loadContractStatus/' + params.vertrag_id, params); + }, + insertContractStatus(form, params) { + return this.$fhcApi.post(form,'api/frontend/v1/vertraege/vertraege/insertContractStatus/' + params.vertrag_id, params); + }, + updateContractStatus(form, params) { + return this.$fhcApi.post(form,'api/frontend/v1/vertraege/vertraege/updateContractStatus/' + params.vertrag_id, params); + }, + deleteContractStatus(params) { + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/deleteContractStatus/' + params.vertrag_id, params); + }, + deleteLehrauftrag(params) { + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/deleteLehrauftrag/' + params.vertrag_id, params); + }, + deleteBetreuung(params) { + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/deleteBetreuung/' + params.vertrag_id, params); + }, + getMitarbeiter(params){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/getMitarbeiter/'); + }, + getHeader(person_id){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/getHeader/' + person_id); + }, + getPersonAbteilung(person_id){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/getPersonAbteilung/' + person_id); + }, + getLeitungOrg(oekurzbz){ + return this.$fhcApi.post('api/frontend/v1/vertraege/vertraege/getLeitungOrg/' + oekurzbz); + }, + getMitarbeiterUid(person_id){ + return this.$fhcApi.get('api/frontend/v1/vertraege/vertraege/getMitarbeiterUid/' + person_id); + }, + +} \ No newline at end of file diff --git a/public/js/apps/Vertragsverwaltung.js b/public/js/apps/Vertragsverwaltung.js new file mode 100644 index 000000000..59b1c8734 --- /dev/null +++ b/public/js/apps/Vertragsverwaltung.js @@ -0,0 +1,25 @@ +import Vertragsverwaltung from "../components/Vertraege/Vertragsverwaltung.js"; +import Phrasen from "../plugins/Phrasen.js"; + +const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + +const router = VueRouter.createRouter({ + history: VueRouter.createWebHistory(), + routes: [ + { path: `/${ciPath}/vertragsverwaltung`, component: Vertragsverwaltung }, + ] +}); + +const app = Vue.createApp({ + name: 'VertragsverwaltungApp' +}); + +app + .use(router) + .use(primevue.config.default, { + zIndex: { + overlay: 1100 + } + }) + .use(Phrasen) + .mount('#main'); diff --git a/public/js/components/Betriebsmittel/Betriebsmittel.js b/public/js/components/Betriebsmittel/Betriebsmittel.js index 148d7a83c..08d6a8947 100644 --- a/public/js/components/Betriebsmittel/Betriebsmittel.js +++ b/public/js/components/Betriebsmittel/Betriebsmittel.js @@ -43,12 +43,28 @@ export default { }, data() { return { - tabulatorOptions: { + listBetriebsmitteltyp: [], + formData: { + ausgegebenam : new Date(), + betriebsmitteltyp: 'Zutrittskarte' + }, + statusNew: true, + filteredInventar: [], + layout: 'fitColumns', + layoutColumnsOnNewData: false, + height: '550', + } + }, + computed: { + tabulatorOptions() { + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call( this.endpoint.getAllBetriebsmittel(this.typeId, this.id, (this.filterByProvidedTypes ? this.betriebsmittelTypes : null)) ), ajaxResponse: (url, params, response) => response.data, + persistenceID: 'core-betriebsmittel-20260217', + selectableRows: true, columns: [ {title: "Nummer", field: "nummer", width: 150}, {title: "PersonId", field: "person_id", visible: false}, @@ -115,7 +131,7 @@ export default { '/content/pdfExport.php?xml=betriebsmittelperson.rdf.php&xsl=Uebernahme&id=' + cellData.betriebsmittelperson_id + '&output=pdf'; window.open(linkToPdf, '_blank'); - }); + }); container.append(button); button = document.createElement('button'); @@ -143,64 +159,47 @@ export default { return container; }, frozen: true - }], - layout: 'fitColumns', - layoutColumnsOnNewData: false, - height: '550', - persistenceID: 'core-betriebsmittel' - }, - tabulatorEvents: [ + } + ], + }; + return options; + }, + tabulatorEvents() { + const events = [ { event: 'tableBuilt', handler: async() => { await this.$p.loadCategory(['wawi', 'global', 'infocenter', 'betriebsmittel', 'person']); - let cm = this.$refs.table.tabulator.columnManager; + const setHeader = (field, text) => { + const col = this.$refs.table.tabulator.getColumn(field); + if (!col) return; - cm.getColumnByField('nummer').component.updateDefinition({ - title: this.$p.t('wawi', 'nummer') - }); - cm.getColumnByField('betriebsmitteltyp').component.updateDefinition({ - title: this.$p.t('global', 'typ') - }); - cm.getColumnByField('anmerkung').component.updateDefinition({ - title: this.$p.t('global', 'anmerkung') - }); - cm.getColumnByField('retouram').component.updateDefinition({ - title: this.$p.t('wawi', 'retourdatum') - }); - cm.getColumnByField('beschreibung').component.updateDefinition({ - title: this.$p.t('global', 'beschreibung') - }); - cm.getColumnByField('kaution').component.updateDefinition({ - title: this.$p.t('infocenter', 'kaution') - }); - cm.getColumnByField('ausgegebenam').component.updateDefinition({ - title: this.$p.t('wawi', 'ausgabedatum') - }); - cm.getColumnByField('betriebsmittel_id').component.updateDefinition({ - title: this.$p.t('ui', 'betriebsmittel_id') - }); - cm.getColumnByField('betriebsmittelperson_id').component.updateDefinition({ - title: this.$p.t('ui', 'betriebsmittelperson_id') - }); - cm.getColumnByField('person_id').component.updateDefinition({ - title: this.$p.t('person', 'person_id') - }); - cm.getColumnByField('uid').component.updateDefinition({ - title: this.$p.t('person', 'uid') - }); + const el = col.getElement(); + if (!el || !el.querySelector) return; + + const titleEl = el.querySelector('.tabulator-col-title'); + if (titleEl) { + titleEl.textContent = text; + } + }; + + setHeader('nummer', this.$p.t('wawi', 'nummer')); + setHeader('betriebsmitteltyp', this.$p.t('global', 'typ')); + setHeader('anmerkung', this.$p.t('global', 'anmerkung')); + setHeader('retouram', this.$p.t('wawi', 'retourdatum')); + setHeader('beschreibung', this.$p.t('global', 'beschreibung')); + setHeader('kaution', this.$p.t('infocenter', 'kaution')); + setHeader('ausgegebenam', this.$p.t('wawi', 'ausgabedatum')); + setHeader('betriebsmittel_id', this.$p.t('ui', 'betriebsmittel_id')); + setHeader('betriebsmittelperson_id', this.$p.t('ui', 'betriebsmittelperson_id')); + setHeader('person_id', this.$p.t('person', 'person_id')); + setHeader('uid', this.$p.t('person', 'uid')); } } - ], - listBetriebsmitteltyp: [], - formData: { - ausgegebenam : new Date(), - betriebsmitteltyp: 'Zutrittskarte' - }, - statusNew: true, - filteredInventar: [] + ]; + return events; } }, watch: { @@ -466,5 +465,4 @@ export default { ` -} - +} \ No newline at end of file diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index a39aa364c..011e75145 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -17,6 +17,7 @@ export const AbgabeMitarbeiterDetail = { Message: primevue.message, VueDatePicker }, + emits: ['paUpdated'], inject: [ 'abgabeTypeOptions', 'abgabetypenBetreuer', @@ -132,8 +133,8 @@ export const AbgabeMitarbeiterDetail = { const noteOptExisting = this.allowedNotenOptions.find(opt => opt.note == existingTerminRes.note) existingTerminRes.note = noteOptExisting - const existingTerminResCurrObj = this.projektarbeit.abgabetermine.find(paa => paa.paabgabe_id == existingTerminRes.paabgabe_id) - existingTerminResCurrObj.noteBackend = noteOpt // do NOT take noteOptExisting -> should reflect the "yes the qgate grade is confirmed in backend ux behaviour" + termin.paabgabetyp_kurzbz = newTerminRes.paabgabetyp_kurzbz + termin.noteBackend = noteOpt // do NOT take noteOptExisting -> should reflect the "yes the qgate grade is confirmed in backend ux behaviour" termin.dateStyle = getDateStyleClass(termin, this.notenOptions) } @@ -174,6 +175,8 @@ export const AbgabeMitarbeiterDetail = { } else { this.showAutomagicModalPhrase = false } + + this.$emit("paUpdated", this.projektarbeit) } else if(res?.meta?.status == 'error'){ this.$fhcAlert.alertError() } @@ -257,6 +260,7 @@ export const AbgabeMitarbeiterDetail = { // this.$p.t('global/tooltipLektorDeleteKontrolle', [this.$entryParams.permissions.kontrolleDeleteMaxReach ]) const deletedTerminIndex = this.projektarbeit.abgabetermine.findIndex(t => t.paabgabe_id === termin.paabgabe_id) this.projektarbeit.abgabetermine.splice(deletedTerminIndex, 1) + this.$emit("paUpdated", this.projektarbeit) } else if(res?.meta?.status == 'error'){ this.$fhcAlert.alertError() } diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index 689bc6d02..d5caf97a6 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -210,12 +210,12 @@ export const AbgabetoolAssistenz = { headerFilter: dateFilter, headerFilterFunc: this.headerFilterTerminCol, sorter: this.sortFuncTerminCol, - field: 'prevTermin', formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false}, + field: 'prevTermin', formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin', headerFilter: dateFilter, headerFilterFunc: this.headerFilterTerminCol, sorter: this.sortFuncTerminCol, - formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false}, + formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))), headerFilter: 'list', headerFilterParams: { valuesLookup: this.getQGateStatusList }, @@ -226,7 +226,7 @@ export const AbgabetoolAssistenz = { field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false}, ], persistence: false, - persistenceID: "abgabetool_2026_02" + persistenceID: "abgabetool_2026_02_26" }, abgabeTableEventHandlers: [ { @@ -247,6 +247,10 @@ export const AbgabetoolAssistenz = { ]}; }, methods: { + handlePaUpdated(projektarbeit) { + this.checkAbgabetermineProjektarbeit(projektarbeit) + this.$refs.abgabeTable.tabulator.redraw(true) + }, getQGateStatusList() { return [ this.$p.t('abgabetool/c4keinTerminVorhanden'), @@ -309,11 +313,13 @@ export const AbgabetoolAssistenz = { return false }, sammelMailStudent(param) { - - const emails = this.selectedData - .map(row => `${row.student_uid}@${this.domain}`) - .join(','); - const uniqueRecipients = [...new Set(emails)]; + + const recipientList = []; + this.selectedData.forEach(d => { + recipientList.push(`${d.student_uid}@${this.domain}`) + }) + + const uniqueRecipients = [...new Set(recipientList)]; const subject = this.$p.t('abgabetool/c4sammelmailStudentBetreff', [this.selectedStudiengangOption?.bezeichnung]); splitMailsHelper(uniqueRecipients, param.originalEvent, subject, this.$fhcAlert, this.$p) }, @@ -362,7 +368,6 @@ export const AbgabetoolAssistenz = { return false; }, checkQualityGateStatus(projekt) { - // TODO: might refine the representation of these states and maybe refactor code a little const qgate1Termine = [] const qgate2Termine = [] @@ -382,7 +387,7 @@ export const AbgabetoolAssistenz = { // reuse luxon calculated diffMs (termin.datum in relation to today) from previous datestyle check qgate1Termine.forEach(qgate => { if(qgate.note != null && projekt.qgate1StatusRank <= 5) { - const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note) + const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note if(noteOpt.positiv) { projekt.qgate1Status = this.$p.t('abgabetool/c4positivBenotet') projekt.qgate1StatusRank = 5 @@ -404,7 +409,7 @@ export const AbgabetoolAssistenz = { qgate2Termine.forEach(qgate => { if(qgate.note != null && projekt.qgate1StatusRank <= 5) { - const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note) + const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note if(noteOpt.positiv) { projekt.qgate2Status = this.$p.t('abgabetool/c4positivBenotet') projekt.qgate2StatusRank = 5 @@ -1287,7 +1292,13 @@ export const AbgabetoolAssistenz = { diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js index 7d5888166..ee1d18942 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js @@ -6,6 +6,7 @@ import ApiAbgabe from '../../../api/factory/abgabe.js' import FhcOverlay from "../../Overlay/FhcOverlay.js"; import { getDateStyleClass } from "./getDateStyleClass.js"; import { dateFilter } from '../../../tabulator/filters/Dates.js'; +import {splitMailsHelper} from "../../../helpers/EmailHelpers.js"; export const AbgabetoolMitarbeiter = { name: "AbgabetoolMitarbeiter", @@ -16,6 +17,7 @@ export const AbgabetoolMitarbeiter = { Checkbox: primevue.checkbox, Dropdown: primevue.dropdown, Textarea: primevue.textarea, + TieredMenu: primevue.tieredmenu, VueDatePicker, FhcOverlay }, @@ -48,6 +50,7 @@ export const AbgabetoolMitarbeiter = { phrasenResolved: false, turnitin_link: null, old_abgabe_beurteilung_link: null, + BETREUER_SAMMELMAIL_BUTTON_STUDENT: null, saving: false, loading: false, abgabeTypeOptions: null, @@ -139,7 +142,6 @@ export const AbgabetoolMitarbeiter = { }, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, headerFilter: false, headerSort: false, widthGrow: 1, tooltip: false, cssClass: 'sticky-col'}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter, widthGrow: 1, tooltip: false}, - {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4kontakt'))), field: 'mail', formatter: this.mailFormatter, widthGrow: 1, tooltip: false, visible: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4vorname'))), field: 'vorname', headerFilter: true, formatter: this.centeredTextFormatter,widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nachname'))), field: 'nachname', headerFilter: true, formatter: this.centeredTextFormatter, widthGrow: 1}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, widthGrow: 1}, @@ -151,12 +153,12 @@ export const AbgabetoolMitarbeiter = { headerFilter: dateFilter, headerFilterFunc: this.headerFilterTerminCol, sorter: this.sortFuncTerminCol, - formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false}, + formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin', headerFilter: dateFilter, headerFilterFunc: this.headerFilterTerminCol, sorter: this.sortFuncTerminCol, - formatter: this.abgabterminFormatter, widthGrow: 1, width: 220, tooltip: false}, + formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false}, {title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))), headerFilter: 'list', headerFilterParams: { valuesLookup: this.getQGateStatusList }, @@ -167,7 +169,7 @@ export const AbgabetoolMitarbeiter = { field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false} ], persistence: false, - persistenceID: 'abgabeTableBetreuer2026-02-24' + persistenceID: 'abgabeTableBetreuer2026-02-26' }, abgabeTableEventHandlers: [{ event: "tableBuilt", @@ -203,6 +205,20 @@ export const AbgabetoolMitarbeiter = { ]}; }, methods: { + handlePaUpdated(projektarbeit) { + this.checkAbgabetermineProjektarbeit(projektarbeit) + this.$refs.abgabeTable.tabulator.redraw(true) + }, + sammelMailStudent(param) { + + const recipientList = []; + this.selectedData.forEach(d => { + recipientList.push(`${d.student_uid}@${this.domain}`) + }) + const uniqueRecipients = [...new Set(recipientList)]; + const subject = ""; // empty subject line + splitMailsHelper(uniqueRecipients, param.originalEvent, subject, this.$fhcAlert, this.$p) + }, getQGateStatusList() { return [ this.$p.t('abgabetool/c4keinTerminVorhanden'), @@ -375,7 +391,6 @@ export const AbgabetoolMitarbeiter = { }); }, checkQualityGateStatus(projekt) { - // TODO: might refine the representation of these states and maybe refactor code a little const qgate1Termine = [] const qgate2Termine = [] @@ -395,7 +410,7 @@ export const AbgabetoolMitarbeiter = { // reuse luxon calculated diffMs (termin.datum in relation to today) from previous datestyle check qgate1Termine.forEach(qgate => { if(qgate.note != null && projekt.qgate1StatusRank <= 5) { - const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note) + const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note if(noteOpt.positiv) { projekt.qgate1Status = this.$p.t('abgabetool/c4positivBenotet') projekt.qgate1StatusRank = 5 @@ -417,7 +432,7 @@ export const AbgabetoolMitarbeiter = { qgate2Termine.forEach(qgate => { if(qgate.note != null && projekt.qgate1StatusRank <= 5) { - const noteOpt = this.notenOptions.find(opt => opt.note == qgate.note) + const noteOpt = typeof qgate.note !== 'object' ? this.notenOptions.find(opt => opt.note == qgate.note) : qgate.note if(noteOpt.positiv) { projekt.qgate2Status = this.$p.t('abgabetool/c4positivBenotet') projekt.qgate2StatusRank = 5 @@ -677,12 +692,13 @@ export const AbgabetoolMitarbeiter = { } pa.abgabetermine.forEach(termin => { - termin.note = this.allowedNotenOptions.find(opt => opt.note == termin.note) + const noteOpt = this.allowedNotenOptions.find(opt => opt.note == termin.note) + if(noteOpt) termin.note = noteOpt termin.file = [] // only set this if it has not been set yet and abgabetermin has a note (qgate) - if(!termin.noteBackend && termin.note) { - termin.noteBackend = termin.note + if(!termin.noteBackend && noteOpt) { + termin.noteBackend = noteOpt } // update 08-01-2026: everybody is allowed to do everything in client, critical checks happen at backend level @@ -719,11 +735,6 @@ export const AbgabetoolMitarbeiter = { return '
' + '
' }, - mailFormatter(cell) { - const val = cell.getValue() - return '
' + - '
' - }, beurteilungFormatter(cell) { const val = cell.getValue() if(val) { @@ -828,6 +839,29 @@ export const AbgabetoolMitarbeiter = { }, }, computed: { + emailItems() { + const menu = [] + + if(this.BETREUER_SAMMELMAIL_BUTTON_STUDENT){ + menu.push({ + label: this.$p.t('abgabetool/c4sendEmailStudierendev2', [this.uniqueStudentEmailCount]), + command: this.sammelMailStudent + }) + } + + return menu + }, + uniqueStudentEmailCount() { + const emails = new Set(); + + this.selectedData.forEach(row => { + if (row.student_uid) { + emails.add(row.student_uid); // actually dont need domain for this + } + }); + + return emails.size; + }, getAllowedAbgabeTypeOptions() { return this.abgabeTypeOptions.filter(opt => this.abgabetypenBetreuer.includes(opt.paabgabetyp_kurzbz)) } @@ -840,6 +874,7 @@ export const AbgabetoolMitarbeiter = { this.turnitin_link = res.data?.turnitin_link this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link this.abgabetypenBetreuer = res.data?.abgabetypenBetreuer + this.BETREUER_SAMMELMAIL_BUTTON_STUDENT = res.data?.BETREUER_SAMMELMAIL_BUTTON_STUDENT }).catch(e => { this.loading = false }) @@ -952,7 +987,11 @@ export const AbgabetoolMitarbeiter = { @@ -988,7 +1027,17 @@ export const AbgabetoolMitarbeiter = { {{ $p.t('abgabetool/showDeadlines') }} - + + + diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 04c6d1835..0b846df9c 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -1,12 +1,11 @@ import ApiDetailHeader from "../../api/factory/detailHeader.js"; +import ApiHandleFoto from "../../api/factory/fotoHandling.js"; +import ModalUploadFoto from "./Modal/UploadFoto.js"; export default { name: 'DetailHeader', - inject: { - domain: { - from: 'configDomain', - default: 'technikum-wien.at' - }, + components: { + ModalUploadFoto }, props: { headerData: { @@ -17,6 +16,19 @@ export default { type: Number, required: false }, + mitarbeiter_uid: { + type: String, + required: false + }, + fotoEditable: { + type: Boolean, + required: false, + default: false + }, + domain: { + type: String, + required: false + }, typeHeader: { type: String, default: 'student', @@ -36,31 +48,40 @@ export default { if (this.typeHeader === 'student') return this.headerData; if (this.typeHeader === 'mitarbeiter') return this.person_id; return null; - } + }, + hasTileAlphaSlot() { + return !!this.$slots.titleAlphaTile + }, + hasTileBetaSlot() { + return !!this.$slots.titleBetaTile + }, + hasTileGammaSlot() { + return !!this.$slots.titleGammaTile + }, + hasTileUIDSlot() { + return !!this.$slots.uid + }, + }, created(){ - if(this.person_id) { - this.getHeader(this.person_id); - - this.loadDepartmentData(this.mitarbeiter_uid) - .then(() => { - // Call getLeitungOrg only after departmentData is loaded - this.getLeitungOrg(this.departmentData.oe_kurzbz); - }) - .catch((error) => { - console.error("Error loading department data:", error); - }); + if (this.typeHeader === 'student') { + if (!this.headerData) { + throw new Error('[DetailHeader] "headerData" is required.') + } + } else if (this.typeHeader === 'mitarbeiter') { + if (!this.person_id || !this.mitarbeiter_uid || !this.domain) { + throw new Error( + '[DetailHeader] "person_id", "mitarbeiter_uid", and "domain" are requried.' + ) + } + this.loadHeaderData(this.person_id, this.mitarbeiter_uid); } }, watch: { person_id: { handler(newVal) { if (newVal) { - this.getHeader(this.person_id); - this.loadDepartmentData(this.person_id). - then(() => { - this.getLeitungOrg(this.departmentData.oe_kurzbz); - }); + this.loadHeaderData(newVal, this.mitarbeiter_uid); } }, deep: true, @@ -71,9 +92,21 @@ export default { headerDataMa: {}, departmentData: {}, leitungData: {}, + isFetchingIssues: false }; }, methods: { + loadHeaderData(person_id, mitarbeiter_uid){ + this.getHeader(person_id); + this.loadDepartmentData(mitarbeiter_uid) + .then(() => { + // Call getLeitungOrg only after departmentData is loaded + this.getLeitungOrg(this.departmentData.oe_kurzbz); + }) + .catch((error) => { + console.error("Error loading header data: ", error); + }); + }, getHeader(person_id) { return this.$api .call(ApiDetailHeader.getHeader(person_id)) @@ -99,9 +132,46 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); }, - redirectToLeitung(){ + async goToLeitung() { + this.loadHeaderData(this.leitungData.person_id, this.leitungData.uid); + this.redirectToLeitung(); + }, + redirectToLeitung() { this.$emit('redirectToLeitung', { - person_id: this.leitungData.person_id}); + person_id: this.leitungData.person_id, + uid: this.leitungData.uid + }); + }, + showModal(person_id){ + this.$refs.modalFoto.open(person_id); + }, + showDeleteModal(person_id){ + this.$fhcAlert + .confirmDelete() + .then(result => result + ? person_id + : Promise.reject({handled: true})) + .then(this.deleteFoto) + .catch(this.$fhcAlert.handleSystemError); + }, + deleteFoto(person_id){ + return this.$api + .call(ApiHandleFoto.deleteFoto(person_id)) + .then(result => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(()=> { + this.reload(); + }); + }, + reload() { + if(this.person_id) { + this.loadHeaderData(this.person_id, this.mitarbeiter_uid); + } + else { + this.$emit('reload'); + } }, getFotoSrc(foto) { if(foto === null) { @@ -112,74 +182,127 @@ export default { } }, template: ` -
+
+ + + + +
` diff --git a/public/js/components/DetailHeader/Modal/UploadFoto.js b/public/js/components/DetailHeader/Modal/UploadFoto.js new file mode 100644 index 000000000..a04677c67 --- /dev/null +++ b/public/js/components/DetailHeader/Modal/UploadFoto.js @@ -0,0 +1,103 @@ +import BsModal from "../../Bootstrap/Modal.js"; +import FormForm from "../../Form/Form.js"; +import FormInput from "../../Form/Input.js"; + +import ApiHandleFoto from "../../../../js/api/factory/fotoHandling.js"; + +export default { + name: "modalUploadFoto", + components: { + BsModal, + FormForm, + FormInput, + }, + props: { + person_id: { + type: Number, + required: true + } + }, + data(){ + return{ + base64Image: null, + file: null, + preview: null, + } + }, + methods:{ + open(person_id){ + this.$refs.modalUploadFoto.show(person_id); + }, + onFileChange(e) { + this.file = e.target.files[0]; + if (!this.file) return; + + // convert File in base64 + const reader = new FileReader(); + + reader.onload = (event) => { + this.base64Image = event.target.result; + this.preview = this.base64Image; + }; + reader.readAsDataURL(this.file); + }, + + async uploadImage(person_id) { + if (!this.base64Image) { + this.$fhcAlert.alertInfo(this.$p.t('header', 'alert_chooseFoto')); + return; + } + + return this.$api + .call(ApiHandleFoto.uploadFoto(person_id, { + image: this.base64Image, + filename: this.file.name + })) + .then(result => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successFotoUpload')); + this.closeModal(); + this.$emit('reload'); + }) + .catch(this.$fhcAlert.handleSystemError); + }, + resetModal(){ + this.base64Image = []; + this.file = null; + }, + closeModal(){ + this.resetModal(); + this.$refs.modalUploadFoto.hide(); + } + }, + template: ` + + + + +
+ +
+
+ +
+
+
+
+ + + +
+ `, +} \ No newline at end of file diff --git a/public/js/components/Funktionen/Funktionen.js b/public/js/components/Funktionen/Funktionen.js index e83eca7e4..2c1bce445 100644 --- a/public/js/components/Funktionen/Funktionen.js +++ b/public/js/components/Funktionen/Funktionen.js @@ -33,26 +33,71 @@ export default { }, data(){ return { - tabulatorOptions: { + isFilterSet: true, + listOrgHeads: [], + listOrgUnits: [], //Old + listAllOrgUnits: [], + listOrgUnits_GST: [], + listOrgUnits_GMBH: [], + formData: { + head: 'gst', + oe_kurzbz: '', + funktion_kurzbz: null, + label:'', + //funktion_label: '', + funktion: null, + }, + statusNew: true, + listAllFunctions: [], + abortController: { + oes: null, + functions: null + }, + filteredOes: [], + filteredFunctions: [], + newBtnStyle: '', + selectedFunction: null, + selectedOe: null, + layout: 'fitDataFill', + layoutColumnsOnNewData: false, + height: '300' + } + }, + computed: { + tabulatorOptions() { + const options = { ajaxURL: 'dummy', ajaxRequestFunc: () => this.$api.call( ApiCoreFunktion.getAllUserFunctions(this.personUID) ), ajaxResponse: (url, params, response) => response.data, + persistenceID: 'core-functions-20260217', columns: [ { title: "dienstverhaeltnis_unternehmen", field: "dienstverhaeltnis_unternehmen", headerFilter: "list", - headerFilterParams: {valuesLookup: true, autocomplete: true, sort: "asc"}, + headerFilterParams: { + valuesLookup: true, autocomplete: true, sort: "asc" + }, + width: 140, + //Field Company: if visible show link to dv + visible: this.showDvCompany, + formatter: this.companyLinkFormatter }, { title: "funktion_beschreibung", field: "funktion_beschreibung", headerFilter: "list", - headerFilterParams: {valuesLookup: true, autocomplete: true, sort: "asc"}, + headerFilterParams: { + valuesLookup: true, autocomplete: true, sort: "asc" + }, + width: 140 }, { title: "funktion_oebezeichnung", field: "funktion_oebezeichnung", headerFilter: "list", - headerFilterParams: {valuesLookup: true, autocomplete: true, sort: "asc"} + headerFilterParams: { + valuesLookup: true, autocomplete: true, sort: "asc" + }, + width: 140 }, {title: "wochenstunden", field: "wochenstunden", headerFilter: true}, { @@ -87,7 +132,7 @@ export default { }); }, }, - {title: "bezeichnung", field: "bezeichnung", headerFilter: true}, + {title: "bezeichnung", field: "bezeichnung", headerFilter: true, width: 140}, {title: "aktiv", field: "aktiv", visible: false}, {title: "benutzerfunktion_id", field: "benutzerfunktion_id", visible: false}, {title: "uid", field: "uid", visible: false}, @@ -142,87 +187,41 @@ export default { frozen: true } ], - layout: 'fitDataFill', - layoutColumnsOnNewData: false, - height: '300', - persistenceID: 'core-functions', - }, - tabulatorEvents: [ + }; + return options; + }, + tabulatorEvents() { + const events = [ { event: 'tableBuilt', handler: async () => { await this.$p.loadCategory(['global', 'lehre', 'person', 'ui']); - let cm = this.$refs.table.tabulator.columnManager; - //Field Company: if visible show link to dv - const column = cm.getColumnByField('dienstverhaeltnis_unternehmen'); - const companyDv = { - title: this.$p.t('person', 'dv_unternehmen'), - width: 140, - visible: this.showDvCompany, - formatter: this.companyLinkFormatter - }; - column.component.updateDefinition(companyDv); + const setHeader = (field, text) => { + const col = this.$refs.table.tabulator.getColumn(field); + if (!col) return; - cm.getColumnByField('funktion_beschreibung').component.updateDefinition({ - title: this.$p.t('person', 'zuordnung_taetigkeit'), - width: 140 - }); - cm.getColumnByField('funktion_oebezeichnung').component.updateDefinition({ - title: this.$p.t('lehre', 'organisationseinheit'), - width: 140 - }); - cm.getColumnByField('wochenstunden').component.updateDefinition({ - title: this.$p.t('person', 'wochenstunden') - }); + const el = col.getElement(); + if (!el || !el.querySelector) return; - const columnDatumVon = cm.getColumnByField('datum_von'); - const fieldVonDatum = { - title: this.$p.t('ui', 'from') + const titleEl = el.querySelector('.tabulator-col-title'); + if (titleEl) { + titleEl.textContent = text; + } }; - columnDatumVon.component.updateDefinition(fieldVonDatum); - - const columnDatumBis = cm.getColumnByField('datum_bis'); - const fieldBisDatum = { - title: this.$p.t('global', 'bis'), - }; - columnDatumBis.component.updateDefinition(fieldBisDatum); - - cm.getColumnByField('bezeichnung').component.updateDefinition({ - title: this.$p.t('ui', 'bezeichnung'), - width: 140 - }); - + setHeader('dienstverhaeltnis_unternehmen', this.$p.t('person', 'dv_unternehmen')); + setHeader('funktion_beschreibung', this.$p.t('person', 'zuordnung_taetigkeit')); + setHeader('funktion_oebezeichnung', this.$p.t('lehre', 'organisationseinheit')); + setHeader('wochenstunden', this.$p.t('person', 'wochenstunden')); + setHeader('datum_von', this.$p.t('ui', 'from')); + setHeader('datum_bis', this.$p.t('global', 'bis')); + setHeader('bezeichnung', this.$p.t('ui', 'bezeichnung')); } } - ], - isFilterSet: true, - listOrgHeads: [], - listOrgUnits: [], //Old - listAllOrgUnits: [], - listOrgUnits_GST: [], - listOrgUnits_GMBH: [], - formData: { - head: 'gst', - oe_kurzbz: '', - funktion_kurzbz: null, - label:'', - //funktion_label: '', - funktion: null, - }, - statusNew: true, - listAllFunctions: [], - abortController: { - oes: null, - functions: null - }, - filteredOes: [], - filteredFunctions: [], - newBtnStyle: '', - selectedFunction: null, - selectedOe: null - } + ]; + return events; + }, }, watch: { selectedFunction(newVal) { @@ -340,6 +339,8 @@ export default { this.formData.head = 'gst'; this.formData.oe_kurzbz = ''; this.formData.funktion_kurzbz = ''; + this.selectedFunction = null; + this.selectedOe= null; }, filterFunctions(event) { const query = event.query.toLowerCase(); @@ -460,14 +461,12 @@ export default { -