diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php index d1f4f0958..c2e38385c 100644 --- a/application/config/anrechnung.php +++ b/application/config/anrechnung.php @@ -7,8 +7,8 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); $config['interval_blocking_application'] = 'P1M'; // Application submission period given by start- and enddate. -$config['submit_application_start'] = '01.02.2021'; -$config['submit_application_end'] = '22.02.2021'; +$config['submit_application_start'] = '05.09.2022'; +$config['submit_application_end'] = '22.09.2022'; // Lehrveranstaltungen with these grades will be blocked for application $config['grades_blocking_application'] = array( diff --git a/application/config/navigation.php b/application/config/navigation.php index 033a65f86..957bdbdae 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -119,6 +119,13 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 30, 'requiredPermissions' => 'system/issues_verwalten:r' + ), + 'gruppenmanagement' => array( + 'link' => site_url('person/Gruppenmanagement'), + 'description' => 'Gruppenmanagement', + 'expand' => true, + 'sort' => 40, + 'requiredPermissions' => 'lehre/gruppenmanager:r' ) ) ), diff --git a/application/controllers/api/v1/codex/Zgv.php b/application/controllers/api/v1/codex/Zgv.php index 670ffc190..3d1b64029 100644 --- a/application/controllers/api/v1/codex/Zgv.php +++ b/application/controllers/api/v1/codex/Zgv.php @@ -45,6 +45,14 @@ class Zgv extends API_Controller } } + /** + * @return zgv + */ + public function getAllZgv() + { + $this->response($this->Zgv_model->getAllZgv(), REST_Controller::HTTP_OK); + } + /** * @return void */ diff --git a/application/controllers/api/v1/codex/Zgvmaster.php b/application/controllers/api/v1/codex/Zgvmaster.php index ff737dd7f..7775724c2 100644 --- a/application/controllers/api/v1/codex/Zgvmaster.php +++ b/application/controllers/api/v1/codex/Zgvmaster.php @@ -45,6 +45,14 @@ class Zgvmaster extends API_Controller } } + /** + * @return zgvmaster + */ + public function getAllZgvmaster() + { + $this->response($this->Zgvmaster_model->getAllZgvmaster(), REST_Controller::HTTP_OK); + } + /** * @return void */ diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index 964dae246..fbaac9b3e 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -41,7 +41,7 @@ class requestAnrechnung extends Auth_Controller // Load configs $this->load->config('anrechnung'); - + // Load language phrases $this->loadPhrases( array( @@ -52,59 +52,59 @@ class requestAnrechnung extends Auth_Controller 'lehre' ) ); - + $this->_setAuthUID(); - + $this->setControllerId(); } - + public function index() { $studiensemester_kurzbz = $this->input->get('studiensemester'); $lehrveranstaltung_id = $this->input->get('lv_id'); - + if (isEmptyString($lehrveranstaltung_id) || isEmptyString($studiensemester_kurzbz)) { show_error('Missing correct parameter'); } - + // Exit if user is not a student $result = $this->StudentModel->load(array('student_uid' => $this->_uid)); - + if (!hasData($result)) { show_error('Cant load user'); } - + // Get Prestudent ID $prestudent_id = getData($result)[0]->prestudent_id; - + // Check if application deadline is expired $is_expired = self::_isExpired( $this->config->item('submit_application_start'), $this->config->item('submit_application_end'), $studiensemester_kurzbz ); - + // Check if Lehrveranstaltung was already graded with application blocking grades $is_blocked = self::_LVhasBlockingGrades($studiensemester_kurzbz, $lehrveranstaltung_id); - + // Get Anrechung data $anrechnungData = $this->anrechnunglib->getAnrechnungDataByLv($lehrveranstaltung_id, $studiensemester_kurzbz, $prestudent_id); // Get Antrag data $antragData = $this->anrechnunglib->getAntragData($prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id); - + $viewData = array( 'antragData' => $antragData, 'anrechnungData' => $anrechnungData, 'is_expired' => $is_expired, 'is_blocked' => $is_blocked ); - + $this->load->view('lehre/anrechnung/requestAnrechnung.php', $viewData); } - + /** * Apply Anrechnungsantrag and send to STGL */ @@ -129,35 +129,35 @@ class requestAnrechnung extends Auth_Controller { return $this->outputJsonError($this->p->t('ui', 'errorFelderFehlen')); } - + if (isEmptyString($bestaetigung)) { return $this->outputJsonError($this->p->t('ui', 'errorBestaetigungFehlt')); } - + // Exit if user is not a student $result = $this->StudentModel->load(array('student_uid' => $this->_uid)); - + if (!hasData($result)) { return $this->outputJsonError('Cant load user'); } - + // Get Prestudent ID $prestudent_id = getData($result)[0]->prestudent_id; - + // Exit if application already exists if (self::_applicationExists($lehrveranstaltung_id, $studiensemester_kurzbz, $prestudent_id)) { return $this->outputJsonError($this->p->t('anrechnung', 'antragBereitsGestellt')); } - + // Exit if application is not for actual studysemester if (!self::_applicationIsForActualSS($studiensemester_kurzbz)) { return $this->outputJsonError($this->p->t('anrechnung', 'antragNurImAktSS')); } - + // Upload document $result = self::_uploadFile(); @@ -165,10 +165,10 @@ class requestAnrechnung extends Auth_Controller { return $this->outputJsonError($result->retval); } - + // Hold just inserted DMS ID $lastInsert_dms_id = $result->retval['dms_id']; - + // Save Anrechnung and Anrechnungstatus $result = $this->AnrechnungModel->createAnrechnungsantrag( $prestudent_id, @@ -178,12 +178,12 @@ class requestAnrechnung extends Auth_Controller $lastInsert_dms_id, $anmerkung ); - + if (isError($result)) { $this->terminateWithJsonError(getError($result)); } - + // Output to AJAX $this->outputJsonSuccess(array( 'antragdatum' => (new DateTime())->format('d.m.Y'), diff --git a/application/controllers/person/Gruppenmanagement.php b/application/controllers/person/Gruppenmanagement.php new file mode 100644 index 000000000..8e8e22d41 --- /dev/null +++ b/application/controllers/person/Gruppenmanagement.php @@ -0,0 +1,254 @@ + 'lehre/gruppenmanager:r', + 'showBenutzergruppe' => 'lehre/gruppenmanager:r', + 'getBenutzer' => 'lehre/gruppenmanager:r', + 'getAllBenutzer' => 'lehre/gruppenmanager:r', + 'addBenutzer' => 'lehre/gruppenmanager:rw', + 'removeBenutzer' => 'lehre/gruppenmanager:rw' + ) + ); + + // Loads models + $this->load->model('person/benutzer_model', 'BenutzerModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('system/Log_model', 'LogModel'); + + $this->load->library('WidgetLib'); + $this->loadPhrases( + array( + 'global', + 'person', + 'lehre', + 'ui', + 'filter', + 'gruppenmanagement' + ) + ); + + $this->setControllerId(); // sets the controller id + $this->_setAuthUID(); // sets property uid + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Main page + */ + public function index() + { + $this->load->view( + 'person/gruppenmanagement/gruppenmanagement.php', + array('uid' => $this->_uid) + ); + } + + /** + * Shows Benutzergruppe overview page. + */ + public function showBenutzergruppe() + { + $this->_setNavigationMenuShowDetails(); + $gruppe_kurzbz = $this->input->get('gruppe_kurzbz'); + + $data[self::FHC_CONTROLLER_ID] = $this->getControllerId(); + + $this->load->view( + 'person/gruppenmanagement/benutzergruppe.php', + array('gruppe_kurzbz' => $gruppe_kurzbz) + ); + } + + /** + * Gets Benutzer assigned to a Gruppe + */ + public function getBenutzer() + { + $gruppe_kurzbz = $this->input->get('gruppe_kurzbz'); + + $this->BenutzergruppeModel->addSelect('uid, vorname, nachname, ben.aktiv'); + $this->BenutzergruppeModel->addJoin('public.tbl_benutzer ben', 'uid'); + $this->BenutzergruppeModel->addJoin('public.tbl_person', 'person_id'); + $benutzerRes = $this->BenutzergruppeModel->loadWhere(array('gruppe_kurzbz' => $gruppe_kurzbz)); + + $this->outputJson($benutzerRes); + } + + /** + * Gets all Benutzer for assignment to Gruppe + */ + public function getAllBenutzer() + { + $this->BenutzerModel->addSelect('uid, vorname, nachname'); + $this->BenutzerModel->addJoin('public.tbl_person', 'person_id'); + $benutzerRes = $this->BenutzerModel->loadWhere( + array('tbl_benutzer.aktiv' => true) + ); + $this->outputJson($benutzerRes); + } + + /** + * Adds a Benutzer to Gruppe + */ + public function addBenutzer() + { + $uid = $this->input->post('uid'); + $gruppe_kurzbz = $this->input->post('gruppe_kurzbz'); + + if (isEmptyString($uid)) + $result = error('Uid missing'); + else + { + $benutzerExistsRes = $this->BenutzergruppeModel->loadWhere( + array( + 'uid' => $uid, + 'gruppe_kurzbz' => $gruppe_kurzbz + ) + ); + + if (isError($benutzerExistsRes)) + { + $this->outputJsonError(getError($benutzerExistsRes)); + return; + } + + if (hasData($benutzerExistsRes)) + { + $this->outputJsonError($this->p->t('gruppenmanagement', 'benutzerSchonZugewiesen')); + return; + } + + $result = $this->BenutzergruppeModel->insert( + array( + 'uid' => $uid, + 'gruppe_kurzbz' => $gruppe_kurzbz, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => $this->_uid + ) + ); + + // log the group add + $lastQry = $this->db->last_query(); + + if (isSuccess($result)) + { + $beschreibung = 'Gruppenmanagement: Nutzer zu Gruppe hinzugefügt'; + $this->_writeLog($this->_uid, $beschreibung, $lastQry); + } + } + + $this->outputJson($result); + } + + /** + * Removes Benutzer from Gruppe + */ + public function removeBenutzer() + { + $uid = $this->input->post('uid'); + $gruppe_kurzbz = $this->input->post('gruppe_kurzbz'); + + if (isEmptyString($uid)) + $result = error('Uid missing'); + else + { + $result = $this->BenutzergruppeModel->delete( + array( + 'uid' => $uid, + 'gruppe_kurzbz' => $gruppe_kurzbz + ) + ); + } + + // log the group remove + $lastQry = $this->db->last_query(); + + if (isSuccess($result)) + { + $beschreibung = 'Gruppenmanagement: Nutzer aus Gruppe entfernt'; + $this->_writeLog($this->_uid, $beschreibung, $lastQry); + } + + $this->outputJson($result); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * Define the navigation menu for the showDetails page + */ + private function _setNavigationMenuShowDetails() + { + $this->load->library('NavigationLib', array('navigation_page' => 'person/Gruppenmanagement/showBenutzergruppe')); + + $link = site_url('person/Gruppenmanagement'); + + $this->navigationlib->setSessionMenu( + array( + 'back' => $this->navigationlib->oneLevel( + 'Zurück', // description + $link, // link + array(), // children + 'angle-left', // icon + true, // expand + null, // subscriptDescription + null, // subscriptLinkClass + null, // subscriptLinkValue + '', // target + 1 // sort + ) + ) + ); + } + + /** + * Set uid of authentificated user + */ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) show_error('User authentification failed'); + } + + /** + * Writes an entry in the log table + */ + private function _writeLog($uid, $beschreibung, $lastQry) + { + $mitarbeiterResult = $this->MitarbeiterModel->load(array('mitarbeiter_uid'=>$this->_uid)); + + if(!isSuccess($mitarbeiterResult) || !hasData($mitarbeiterResult)) + { + $uid = DUMMY_LEKTOR_UID; + $beschreibung .= ': '.$this->_uid; + $beschreibung = mb_substr($beschreibung, 0, 64); + } + + $this->LogModel->insert(array( + 'mitarbeiter_uid' => $uid, + 'beschreibung' => $beschreibung, + 'sql' => $lastQry + )); + } + +} diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 76011dc04..3bd08b7d1 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -88,6 +88,12 @@ class InfoCenter extends Auth_Controller 'message' => 'Type of Document %s was updated, set to %s', 'success' => null ), + 'deletedoc' => array( + 'logtype' => 'Action', + 'name' => 'Document deleted', + 'message' => 'Document %s deleted', + 'success' => null + ), ); // Name of Interessentenstatus @@ -131,6 +137,7 @@ class InfoCenter extends Auth_Controller 'reloadZgvPruefungen' => 'infocenter:r', 'reloadMessages' => 'infocenter:r', 'reloadDoks' => 'infocenter:r', + 'reloadUebersichtDoks' => 'infocenter:r', 'reloadNotizen' => array('infocenter:r', 'lehre/zgvpruefung:r'), 'reloadLogs' => 'infocenter:r', 'outputAkteContent' => array('infocenter:r', 'lehre/zgvpruefung:r'), @@ -142,7 +149,9 @@ class InfoCenter extends Auth_Controller 'getStudienjahrEnd' => array('infocenter:r', 'lehre/zgvpruefung:r'), 'setNavigationMenuArrayJson' => 'infocenter:r', 'getAbsageData' => 'infocenter:r', - 'saveAbsageForAll' => 'infocenter:rw' + 'saveAbsageForAll' => 'infocenter:rw', + 'deleteDoc' => 'infocenter:rw', + 'getStudienartData' => 'infocenter:rw' ) ); @@ -159,6 +168,10 @@ class InfoCenter extends Auth_Controller $this->load->model('system/Message_model', 'MessageModel'); $this->load->model('system/Filters_model', 'FiltersModel'); $this->load->model('system/PersonLock_model', 'PersonLockModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('codex/Zgv_model', 'ZgvModel'); + $this->load->model('codex/Zgvmaster_model', 'ZgvmasterModel'); + $this->load->model('codex/Nation_model', 'NationModel'); // Loads libraries $this->load->library('PersonLogLib'); @@ -398,6 +411,35 @@ class InfoCenter extends Auth_Controller $this->outputJsonSuccess(array($json)); } + public function deleteDoc($person_id) + { + $akte_id = $this->input->post('akteid'); + + if (isset($akte_id) && isset($person_id)) + { + $this->load->library('AkteLib'); + $akte = $this->aktelib->get($akte_id); + + if (hasData($akte)) + { + $akte = getData($akte); + if ($akte->person_id === (int)$person_id) + { + $result = $this->aktelib->remove($akte_id); + + if (isError($result)) + { + $this->terminateWithJsonError('Error deleting document'); + } + + $this->_log($person_id, 'deletedoc', array($akte->bezeichnung)); + + $this->outputJsonSuccess('success'); + } + } + } + } + /** * Gets prestudent data for a person in json format * @param $person_id @@ -1074,6 +1116,17 @@ class InfoCenter extends Auth_Controller $this->load->view('system/infocenter/dokNachzureichend.php', array('dokumente_nachgereicht' => $dokumente_nachgereicht->retval)); } + public function reloadUebersichtDoks($person_id) + { + $dokumente = $this->AkteModel->getAktenWithDokInfo($person_id, null, false); + + $this->DokumentModel->addOrder('bezeichnung'); + $dokumentdata = array('dokumententypen' => (getData($this->DokumentModel->load()))); + $data = array_merge($dokumentdata, ['dokumente' => $dokumente->retval]); + + $this->load->view('system/infocenter/dokpruefung.php', $data); + } + /** * Outputs content of an Akte, sends appropriate headers (so the document can be downloaded) * @param $akte_id @@ -1932,10 +1985,13 @@ class InfoCenter extends Auth_Controller $abwstatusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; $intstatusgruende = $this->StatusgrundModel->getStatus(self::INTERESSENTSTATUS)->retval; + $studienArtBerechtigung = array_column($this->getStudienArtBerechtigung(), 'typ'); + $data = array ( 'zgvpruefungen' => $zgvpruefungen, 'abwstatusgruende' => $abwstatusgruende, - 'intstatusgruende' => $intstatusgruende + 'intstatusgruende' => $intstatusgruende, + 'studienArtBerechtigung' => $studienArtBerechtigung ); return $data; @@ -2194,18 +2250,36 @@ class InfoCenter extends Auth_Controller public function getAbsageData() { - $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter'); + $stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, ['b', 'm']); - $statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; - $studienSemester = $this->variablelib->getVar('infocenter_studiensemester'); - $studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(['b', 'm'], $studienSemester); + if (hasData($stg_typ)) + { + $stg_typ = getData($stg_typ); + $statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; + $studienSemester = $this->variablelib->getVar('infocenter_studiensemester'); + $studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(array_column($stg_typ, 'typ'), $studienSemester); - $data = array ( - 'statusgruende' => $statusgruende, - 'studiengaenge' => $studiengaenge->retval - ); + $data = array ( + 'statusgruende' => $statusgruende, + 'studiengaenge' => $studiengaenge->retval + ); - $this->outputJsonSuccess($data); + $this->outputJsonSuccess($data); + } + else + $this->outputJsonSuccess(null); + } + + public function getStudienArtBerechtigung() + { + $studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter'); + $stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, ['b', 'm', 'l']); + return getData($stg_typ); + } + public function getStudienartData() + { + $this->outputJsonSuccess($this->getStudienArtBerechtigung()); } public function saveAbsageForAll() diff --git a/application/models/codex/Nation_model.php b/application/models/codex/Nation_model.php index 239639795..a66b77edb 100644 --- a/application/models/codex/Nation_model.php +++ b/application/models/codex/Nation_model.php @@ -3,7 +3,7 @@ class Nation_model extends DB_Model { /** - * + * */ public function __construct() { @@ -11,4 +11,14 @@ class Nation_model extends DB_Model $this->dbTable = 'bis.tbl_nation'; $this->pk = 'nation_code'; } -} \ No newline at end of file + + /** + * getAllForStyled Dropdown + */ + public function getAll() + { + $allNations = 'SELECT * FROM bis.tbl_nation ORDER BY bis.tbl_nation.langtext ASC;'; + + return $this->execQuery($allNations); + } +} diff --git a/application/models/codex/Zgv_model.php b/application/models/codex/Zgv_model.php index 1e1ba99ad..0206d1292 100644 --- a/application/models/codex/Zgv_model.php +++ b/application/models/codex/Zgv_model.php @@ -11,4 +11,16 @@ class Zgv_model extends DB_Model $this->dbTable = 'bis.tbl_zgv'; $this->pk = 'zgv_code'; } + + /** + * getAllForStyled Dropdown + */ + public function getAllZgv() + { + $allZgv = 'SELECT * FROM bis.tbl_zgv ORDER BY zgv_bez ASC;'; + + return $this->execQuery($allZgv); + } + + } diff --git a/application/models/codex/Zgvmaster_model.php b/application/models/codex/Zgvmaster_model.php index 38f8a0dcb..0f6305532 100644 --- a/application/models/codex/Zgvmaster_model.php +++ b/application/models/codex/Zgvmaster_model.php @@ -11,4 +11,14 @@ class Zgvmaster_model extends DB_Model $this->dbTable = 'bis.tbl_zgvmaster'; $this->pk = 'zgvmas_code'; } + + /** + * getAllForStyled Dropdown + */ + public function getAllZgvmaster() + { + $allZgvMaster = 'SELECT * FROM bis.tbl_zgvmaster ORDER BY zgvmas_bez ASC;'; + + return $this->execQuery($allZgvMaster); + } } diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 0d0c248a6..e848cb4c2 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -507,4 +507,14 @@ class Studiengang_model extends DB_Model return $this->execQuery($query, array($typ, $semester)); } + + public function getStudiengangTyp($studiengang_kz, $typ) + { + $query = "SELECT DISTINCT(sgt.*) + FROM tbl_studiengangstyp sgt JOIN tbl_studiengang sg on sgt.typ = sg.typ + WHERE studiengang_kz IN ? and sgt.typ IN ?"; + + return $this->execQuery($query, array($studiengang_kz, $typ)); + + } } diff --git a/application/views/person/gruppenmanagement/benutzergruppe.php b/application/views/person/gruppenmanagement/benutzergruppe.php new file mode 100644 index 000000000..0096f8d52 --- /dev/null +++ b/application/views/person/gruppenmanagement/benutzergruppe.php @@ -0,0 +1,75 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'Benutzer in Gruppe', + 'jquery' => true, + 'jqueryui' => true, + 'bootstrap' => true, + 'fontawesome' => true, + 'sbadmintemplate' => true, + 'tablesorter' => true, + 'ajaxlib' => true, + 'dialoglib' => true, + 'navigationwidget' => true, + 'phrases' => array( + 'gruppenmanagement', + 'ui' + ), + 'customCSSs' => 'public/css/sbadmin2/tablesort_bootstrap.css', + 'customJSs' => array('public/js/bootstrapper.js', 'public/js/tablesort/tablesort.js', 'public/js/person/benutzergruppe.js') + ) + ); +?> + + +
+ + widgetlib->widget('NavigationWidget'); ?> + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + + + + + + + + + +
Uidp->t('person', 'vorname')); ?>p->t('person', 'nachname')); ?>p->t('gruppenmanagement', 'aktiv')); ?>p->t('ui', 'entfernen')); ?>
+
+
+
+
+
+ + +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/person/gruppenmanagement/gruppenmanagement.php b/application/views/person/gruppenmanagement/gruppenmanagement.php new file mode 100644 index 000000000..32416eb86 --- /dev/null +++ b/application/views/person/gruppenmanagement/gruppenmanagement.php @@ -0,0 +1,46 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'Gruppenmanagement', + 'jquery' => true, + 'jqueryui' => true, + 'bootstrap' => true, + 'fontawesome' => true, + 'sbadmintemplate' => true, + 'tablesorter' => true, + 'ajaxlib' => true, + 'filterwidget' => true, + 'navigationwidget' => true, + 'phrases' => array( + 'ui' + ), + 'customCSSs' => 'public/css/sbadmin2/tablesort_bootstrap.css', + 'customJSs' => array('public/js/bootstrapper.js') + ) + ); +?> + + +
+ + widgetlib->widget('NavigationWidget'); ?> + +
+
+
+
+ +
+
+
+ load->view('person/gruppenmanagement/gruppenmanagementData.php'); ?> +
+
+
+
+ + +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/person/gruppenmanagement/gruppenmanagementData.php b/application/views/person/gruppenmanagement/gruppenmanagementData.php new file mode 100644 index 000000000..2a07f85f7 --- /dev/null +++ b/application/views/person/gruppenmanagement/gruppenmanagementData.php @@ -0,0 +1,66 @@ + ' + SELECT gruppe_kurzbz, grp.bezeichnung AS gruppe_bezeichnung, grp.beschreibung AS gruppe_beschreibung, + studiengang_kz, UPPER(stg.typ||stg.kurzbz) AS studiengang_kurzbz, semester, sichtbar, lehre, grp.aktiv, mailgrp, generiert + FROM public.tbl_gruppe grp + JOIN public.tbl_studiengang stg USING (studiengang_kz) + JOIN public.tbl_gruppe_manager grpmgr USING (gruppe_kurzbz) + WHERE grp.aktiv = TRUE + AND grpmgr.uid = \''.$uid.'\'', + 'requiredPermissions' => 'lehre/gruppenmanager', + 'datasetRepresentation' => 'tablesorter', + 'additionalColumns' => array('Teilnehmer'), + 'columnsAliases' => array( + ucfirst($this->p->t('gruppenmanagement', 'kurzbezeichnung')), + ucfirst($this->p->t('gruppenmanagement', 'bezeichnung')), + ucfirst($this->p->t('gruppenmanagement', 'beschreibung')), + ucfirst($this->p->t('lehre', 'studiengangskennzahlLehre')), + ucfirst($this->p->t('lehre', 'studiengang')), + ucfirst($this->p->t('lehre', 'semester')), + 'Sichtbar', + 'Lehre', + 'Aktiv', + 'Mailgrp', + 'Generiert' + ), + 'formatRow' => function($datasetRaw) { + + /* NOTE: Dont use $this here for PHP Version compatibility */ + $datasetRaw->{'Teilnehmer'} = sprintf( + ''.$this->p->t('gruppenmanagement', 'zuweisenloeschen').'', + site_url('person/Gruppenmanagement/showBenutzergruppe'), + $datasetRaw->{'gruppe_kurzbz'}, + 'index', + (isset($_GET['fhc_controller_id'])?$_GET['fhc_controller_id']:'') + ); + + if ($datasetRaw->{'gruppe_bezeichnung'} == null) + { + $datasetRaw->{'gruppe_bezeichnung'} = '-'; + } + if ($datasetRaw->{'gruppe_beschreibung'} == null) + { + $datasetRaw->{'gruppe_beschreibung'} = '-'; + } + if ($datasetRaw->{'semester'} == null) + { + $datasetRaw->{'semester'} = '-'; + } + $datasetRaw->{'sichtbar'} = $datasetRaw->{'sichtbar'} == 'true' ? 'ja' : 'nein'; + $datasetRaw->{'lehre'} = $datasetRaw->{'lehre'} == 'true' ? 'ja' : 'nein'; + $datasetRaw->{'aktiv'} = $datasetRaw->{'aktiv'} == 'true' ? 'ja' : 'nein'; + $datasetRaw->{'mailgrp'} = $datasetRaw->{'mailgrp'} == 'true' ? 'ja' : 'nein'; + $datasetRaw->{'generiert'} = $datasetRaw->{'generiert'} == 'true' ? 'ja' : 'nein'; + + return $datasetRaw; + } + ); + + $filterWidgetArray['app'] = 'core'; + $filterWidgetArray['datasetName'] = 'gruppenmanagement'; + $filterWidgetArray['filterKurzbz'] = 'gruppenmanagement'; + $filterWidgetArray['filter_id'] = $this->input->get('filter_id'); + + echo $this->widgetlib->widget('FilterWidget', $filterWidgetArray); +?> diff --git a/application/views/system/infocenter/dokpruefung.php b/application/views/system/infocenter/dokpruefung.php index b184b9a0b..633f3ec02 100644 --- a/application/views/system/infocenter/dokpruefung.php +++ b/application/views/system/infocenter/dokpruefung.php @@ -1,10 +1,11 @@ -
- +
+
+ akte_id ?>">titel) ? $dokument->bezeichnung : $dokument->titel ?> + variablelib->getVar('infocenter_studiensemester').'\''; $ORG_NAME = '\'InfoCenter\''; + $ONLINE = '\'online\''; $query = ' SELECT @@ -55,10 +56,13 @@ a.dokument_kurzbz in ('.$AKTE_TYP.') ) AS "AnzahlAkte", ( - SELECT CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END + SELECT CASE WHEN student.student_uid IS NULL THEN + (CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END) + ELSE '. $ONLINE .' END FROM system.tbl_log l LEFT JOIN public.tbl_benutzer on l.insertvon = tbl_benutzer.uid LEFT JOIN public.tbl_person sp on tbl_benutzer.person_id = sp.person_id + LEFT JOIN public.tbl_student student ON tbl_benutzer.uid = student.student_uid WHERE l.taetigkeit_kurzbz IN ('.$TAETIGKEIT_KURZBZ.') AND l.logdata->>\'name\' NOT IN ('.$LOGDATA_NAME.') AND l.person_id = p.person_id diff --git a/application/views/system/infocenter/infocenterFreigegebenData.php b/application/views/system/infocenter/infocenterFreigegebenData.php index 75d60a179..13e1d5549 100644 --- a/application/views/system/infocenter/infocenterFreigegebenData.php +++ b/application/views/system/infocenter/infocenterFreigegebenData.php @@ -12,6 +12,7 @@ $STUDIENSEMESTER = '\''.$this->variablelib->getVar('infocenter_studiensemester').'\''; $ORG_NAME = '\'InfoCenter\''; $IDENTITY = '\'identity\''; + $ONLINE = '\'online\''; $query = ' SELECT @@ -42,10 +43,13 @@ $query = ' LIMIT 1 ) AS "LastActionType", ( - SELECT CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END + SELECT CASE WHEN student.student_uid IS NULL THEN + (CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END) + ELSE '. $ONLINE .' END FROM system.tbl_log l LEFT JOIN public.tbl_benutzer on l.insertvon = tbl_benutzer.uid LEFT JOIN public.tbl_person sp on tbl_benutzer.person_id = sp.person_id + LEFT JOIN public.tbl_student student ON tbl_benutzer.uid = student.student_uid WHERE l.taetigkeit_kurzbz IN('.$TAETIGKEIT_KURZBZ.') AND l.logdata->>\'name\' NOT IN ('.$LOGDATA_NAME.') AND l.person_id = p.person_id @@ -178,7 +182,7 @@ $query = ' WHERE pss.status_kurzbz = '.$INTERESSENT_STATUS.' AND ps.person_id = p.person_id AND pss.studiensemester_kurzbz = '.$STUDIENSEMESTER.' - ORDER BY pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC + ORDER BY rtp.teilgenommen NULLS FIRST, pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC LIMIT 1 ) AS "ReihungstestAngetreten", ( @@ -199,7 +203,7 @@ $query = ' LIMIT 1 ) AS "ReihungstestApplied", ( - SELECT CONCAT(rtp.datum, rtp.uhrzeit) + SELECT (ARRAY_TO_STRING(array_agg(DISTINCT(CONCAT(rtp.datum, \' \', to_char(rtp.uhrzeit, \'HH24:MI\'), \' \', studiengang.kurzbzlang))), \', \')) FROM public.tbl_prestudentstatus pss JOIN public.tbl_prestudent ps USING(prestudent_id) LEFT JOIN ( @@ -207,14 +211,17 @@ $query = ' rt.studiensemester_kurzbz, rtp.teilgenommen, rt.datum, - rt.uhrzeit + rt.uhrzeit, + rt.studiengang_kz FROM public.tbl_rt_person rtp JOIN tbl_reihungstest rt ON(rtp.rt_id = rt.reihungstest_id) WHERE rt.stufe = 1 ) rtp ON(rtp.person_id = ps.person_id AND rtp.studiensemester_kurzbz = pss.studiensemester_kurzbz) + JOIN tbl_studiengang studiengang ON rtp.studiengang_kz = studiengang.studiengang_kz WHERE pss.status_kurzbz = '.$INTERESSENT_STATUS.' AND ps.person_id = p.person_id AND pss.studiensemester_kurzbz = '.$STUDIENSEMESTER.' + GROUP BY pss.datum, pss.insertamum, pss.ext_id ORDER BY pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC LIMIT 1 ) AS "ReihungstestDate", @@ -414,10 +421,6 @@ $query = ' { $datasetRaw->{'ReihungstestDate'} = '-'; } - else - { - $datasetRaw->{'ReihungstestDate'} = date_format(date_create($datasetRaw->{'ReihungstestDate'}),'Y-m-d H:i'); - } if ($datasetRaw->{'ZGVNation'} == null) { diff --git a/application/views/system/infocenter/zgvpruefungen.php b/application/views/system/infocenter/zgvpruefungen.php index 253145557..f6e8a845b 100644 --- a/application/views/system/infocenter/zgvpruefungen.php +++ b/application/views/system/infocenter/zgvpruefungen.php @@ -124,6 +124,32 @@
+ prestudentstatus->bewerbung_abgeschicktamum)) + { + $disabled = $disabledStg = 'disabled'; + $disabledTxt = $disabledStgTxt = $this->p->t('infocenter', 'bewerbungMussAbgeschickt'); + } + + if ($studiengangtyp !== 'b' && $studiengangtyp !== 'm') + { + $disabled = 'disabled'; + $disabledTxt = $this->p->t('infocenter', 'nurBachelorMasterFreigeben'); + + // FIT-Lehrgänge: exceptions, can be freigegeben in Infocenter + if (!in_array($studiengang_kz, $fit_programme_studiengaenge)) + { + $disabledStg = 'disabled'; + $disabledStgTxt = $this->p->t('infocenter', 'nurBachelorMasterFreigeben'); + } + } + + if (!in_array($studiengangtyp, $studienArtBerechtigung)) + $disabledPer = 'disabled'; + else + $disabledPer = ''; + ?>
@@ -318,17 +344,17 @@
- - statusZGV))) ?: print_r('data-info="need"')?>>
-
@@ -336,7 +362,7 @@
prestudentUdfs)) + if (isset($zgvpruefung->prestudentUdfs) && $studiengangtyp !== 'l') { echo $this->udflib->UDFWidget( array( @@ -362,6 +388,8 @@
+ required>
- @@ -489,6 +499,8 @@
' + - '' + - '' + - '' + ''; + InfocenterPersonDataset.getStudienartData(infocenter_studiengangstyp); + var auswahlAbsageToggle = 'Erweiterte Einstellungen'; @@ -90,11 +89,9 @@ var InfocenterPersonDataset = { "

" ); - InfocenterPersonDataset.selectStudiengangTyp(infocenter_studiengangstyp) - $('.auswahlStudienArt').change(function() { - InfocenterPersonDataset.changeStudengangsTyp($(this).find('option:selected').attr('data-id')); + InfocenterPersonDataset.changeStudengangsTyp($(this).find('option:selected').val()); }); $("#datasetActionsBottom").append( @@ -183,22 +180,6 @@ var InfocenterPersonDataset = { ); }, - selectStudiengangTyp: function(typ) - { - switch (typ) - { - case 'b, m' : - $('.auswahlStudienArt [data-id="all"]').attr('selected', 'selected'); - break; - case 'b' : - $('.auswahlStudienArt [data-id="bachelor"]').attr('selected', 'selected'); - break; - case 'm' : - $('.auswahlStudienArt [data-id="master"]').attr('selected', 'selected'); - break; - } - }, - /** * sets functionality for the actions above and beneath the person table */ @@ -257,20 +238,12 @@ var InfocenterPersonDataset = { }); }, - changeStudengangsTyp: function($typ) + changeStudengangsTyp: function(typ) { - switch ($typ) - { - case 'all' : - var change = 'b\', \'m'; - break; - case 'bachelor' : - var change = 'b'; - break; - case 'master' : - var change = 'm'; - break; - } + let change = typ; + + if (typ === 'all') + change = change = 'b\', \'m\', \'l'; FHC_AjaxClient.showVeil(); @@ -372,7 +345,8 @@ var InfocenterPersonDataset = { 'system/infocenter/InfoCenter/getAbsageData', {}, { - successCallback: function(data, textStatus, jqXHR) { + successCallback: function(data, textStatus, jqXHR) + { if (FHC_AjaxClient.hasData(data)) { data = FHC_AjaxClient.getData(data); @@ -397,6 +371,42 @@ var InfocenterPersonDataset = { } ); }, + getStudienartData: function(infocenter_studiengangstyp) + { + FHC_AjaxClient.ajaxCallGet( + 'system/infocenter/InfoCenter/getStudienartData', + {}, + { + successCallback: function(data, textStatus, jqXHR) + { + if (FHC_AjaxClient.hasData(data)) + { + data = FHC_AjaxClient.getData(data); + + let all = data.map(item => item.typ).join('\',\''); + $('.auswahlStudienArt').append($("
"+ + ""+ + ""+ + ""+ + ""+ + ""+ + "" + ); + + // add delete event to button + $("#"+benutzer.uid+"_benutzerLoeschen").click( + function() { + Benutzergruppe.removeBenutzer(benutzer.uid, gruppe_kurzbz); + } + ) + } + } + + // add tablesorter to benutzergruppe table + Benutzergruppe._setTablesorter(); + }, + errorCallback: function(jqXHR, textStatus, errorThrown) { + FHC_DialogLib.alertError(textStatus); + } + } + ); + }, + getAllBenutzer: function() { + FHC_AjaxClient.ajaxCallGet( + 'person/gruppenmanagement/getAllBenutzer', + null, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.isError(data)) + { + FHC_DialogLib.alertError(FHC_AjaxClient.getError(data)); + return; + } + + if (FHC_AjaxClient.hasData(data)) + { + benutzerArr = []; + + // save loaded data + let benutzerData = FHC_AjaxClient.getData(data); + + for (let i = 0; i < benutzerData.length; i++) + { + let ben = benutzerData[i]; + + benutzerArr.push( + { + vorname: ben.vorname, + nachname: ben.nachname, + uid: ben.uid, + label: ben.nachname + " " + ben.vorname + " (" + ben.uid + ")", + id: ben.uid + } + ); + } + + // callback for searching source mitarbeiter array correctly + let sourceCallback = function(request, response) + { + // case insensitive matcher + let matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i"); + + // match vorname nachname OR nachname vorname OR uid + response($.grep(benutzerArr, function (value) { + return matcher.test(value.nachname + ' '+value.vorname + ' ' + value.nachname) + || matcher.test(value.uid); + })); + } + + // fill autocomplete field with benutzer data + Benutzergruppe._fillAutocomplete( + 'teilnehmerSelect', + 'teilnehmer_uid', + sourceCallback + ); + } + }, + errorCallback: function(jqXHR, textStatus, errorThrown) { + FHC_DialogLib.alertError(textStatus); + } + } + ); + }, + addBenutzer: function(uid, gruppe_kurzbz) { + FHC_AjaxClient.ajaxCallPost( + 'person/gruppenmanagement/addBenutzer', + { + uid: uid, + gruppe_kurzbz: gruppe_kurzbz + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.isError(data)) + { + FHC_DialogLib.alertError(FHC_AjaxClient.getError(data)); + return; + } + + if (FHC_AjaxClient.hasData(data)) + { + // load Benutzer after add to show change + Benutzergruppe.getBenutzer(gruppe_kurzbz); + } + }, + errorCallback: function(jqXHR, textStatus, errorThrown) { + FHC_DialogLib.alertError(textStatus); + } + } + ); + }, + removeBenutzer: function(uid, gruppe_kurzbz) { + FHC_AjaxClient.ajaxCallPost( + 'person/gruppenmanagement/removeBenutzer', + { + uid: uid, + gruppe_kurzbz: gruppe_kurzbz + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.isError(data)) + { + FHC_DialogLib.alertError(FHC_AjaxClient.getError(data)); + return; + } + + if (FHC_AjaxClient.hasData(data)) + { + // load Benutzer after remove to show change + Benutzergruppe.getBenutzer(gruppe_kurzbz); + } + }, + errorCallback: function(jqXHR, textStatus, errorThrown) { + FHC_DialogLib.alertError(textStatus); + } + } + ); + }, + _fillAutocomplete: function(autocompleteId, idFieldId, source) { + // jQuery ui autocomplete for benutzer + $("#"+autocompleteId).autocomplete( + { + // custom matcher + source: source, + autoFocus: true, + select: function(event, ui) + { + // when autocmplete entry selected, display label text in autocomplete, fill hidden value field + $("#"+autocompleteId).val(ui.item.label); + $("#"+idFieldId).val(ui.item.id); + return false; + } + } + ); + }, + _setTablesorter: function() { + Tablesort.addTablesorter( + // sort by first and third column asc, show filters beggining with 2 Benutzer, exclude fifth column from filter + "benutzer-table", [[0,0], [2,0]], ["filter", "zebra"], 2, {headers: {4: {filter: false}}} + ) + } +}; + +/** + * When JQuery is up + */ +$(document).ready(function() { + // get the group name + let gruppe_kurzbz = $("#gruppe_kurzbz").val(); + + // load Benutzer for autocomplete selection + Benutzergruppe.getAllBenutzer(); + // load Benutzer for table + Benutzergruppe.getBenutzer(gruppe_kurzbz); + + // add click event to "add Benutzer" button + $("#teilnehmerHinzufuegen").click(function(){ + let uid = $("#teilnehmer_uid").val(); + Benutzergruppe.addBenutzer(uid, gruppe_kurzbz); + $("#teilnehmerSelect").val(''); + } + ); +}); diff --git a/rdf/zgv.rdf.php b/rdf/zgv.rdf.php index 89338c58b..a3ce1225d 100644 --- a/rdf/zgv.rdf.php +++ b/rdf/zgv.rdf.php @@ -53,6 +53,7 @@ if(isset($_GET['optional']) && $_GET['optional']=='true') -- keine Auswahl ---- keine Auswahl -- + '; @@ -70,6 +71,7 @@ if($db->db_query($qry)) zgv_code; ?>]]>zgv_bez; ?>]]>zgv_kurzbz; ?>]]> + aktiv; ?>]]>db_query($qry)) } ?> - \ No newline at end of file + diff --git a/rdf/zgvdoktor.rdf.php b/rdf/zgvdoktor.rdf.php index dc0b38ff7..38dcec500 100644 --- a/rdf/zgvdoktor.rdf.php +++ b/rdf/zgvdoktor.rdf.php @@ -19,7 +19,7 @@ * Andreas Oesterreicher and * Rudolf Hangl . */ -// header für no cache +// header f�r no cache header("Cache-Control: no-cache"); header("Cache-Control: post-check=0, pre-check=0",false); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); @@ -52,6 +52,7 @@ if(isset($_GET['optional']) && $_GET['optional']=='true') -- keine Auswahl -- -- keine Auswahl -- + '; @@ -69,6 +70,7 @@ if($db->db_query($qry)) zgvdoktor_code; ?>]]> zgvdoktor_bez; ?>]]> zgvdoktor_kurzbz; ?>]]> + aktiv; ?>]]> db_query($qry)) } ?> - \ No newline at end of file + diff --git a/rdf/zgvmaster.rdf.php b/rdf/zgvmaster.rdf.php index 5fc6c62ca..b84af2c71 100644 --- a/rdf/zgvmaster.rdf.php +++ b/rdf/zgvmaster.rdf.php @@ -52,6 +52,7 @@ if(isset($_GET['optional']) && $_GET['optional']=='true') -- keine Auswahl -- -- keine Auswahl -- + '; @@ -69,6 +70,7 @@ if($db->db_query($qry)) zgvmas_code; ?>]]> zgvmas_bez; ?>]]> zgvmas_kurzbz; ?>]]> + aktiv?>]]> db_query($qry)) } ?> - \ No newline at end of file + diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index c7c49c2dd..e0168aa28 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -6243,6 +6243,72 @@ if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berecht } } +// Creates table public.tbl_gruppe_manager if it doesn't exist and grants privileges +if (!$result = @$db->db_query('SELECT 1 FROM public.tbl_gruppe_manager LIMIT 1')) +{ + $qry = 'CREATE TABLE public.tbl_gruppe_manager ( + gruppe_manager_id integer, + gruppe_kurzbz varchar(32) NOT NULL, + uid varchar(32) NOT NULL, + insertamum timestamp DEFAULT NOW(), + insertvon varchar(32) + ); + + COMMENT ON TABLE public.tbl_gruppe_manager IS \'Table to save assignments groups to their managers.\'; + COMMENT ON COLUMN public.tbl_gruppe_manager.gruppe_kurzbz IS \'Name of group\'; + COMMENT ON COLUMN public.tbl_gruppe_manager.uid IS \'User id of group manager\'; + + CREATE SEQUENCE public.seq_gruppe_manager_gruppe_manager_id + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + ALTER TABLE public.tbl_gruppe_manager ALTER COLUMN gruppe_manager_id SET DEFAULT nextval(\'public.seq_gruppe_manager_gruppe_manager_id\'::regclass); + + GRANT SELECT, UPDATE ON SEQUENCE public.seq_gruppe_manager_gruppe_manager_id TO vilesci; + GRANT SELECT, UPDATE ON SEQUENCE public.seq_gruppe_manager_gruppe_manager_id TO fhcomplete; + + ALTER TABLE public.tbl_gruppe_manager ADD CONSTRAINT pk_gruppe_manager PRIMARY KEY (gruppe_manager_id); + + ALTER TABLE public.tbl_gruppe_manager ADD CONSTRAINT fk_gruppe_manager_gruppe_kurzbz FOREIGN KEY (gruppe_kurzbz) REFERENCES public.tbl_gruppe(gruppe_kurzbz) ON UPDATE CASCADE ON DELETE CASCADE; + ALTER TABLE public.tbl_gruppe_manager ADD CONSTRAINT fk_gruppe_manager_uid FOREIGN KEY (uid) REFERENCES public.tbl_benutzer(uid) ON UPDATE CASCADE ON DELETE RESTRICT; + + ALTER TABLE public.tbl_gruppe_manager ADD CONSTRAINT uk_gruppe_manager_gruppe_kurzbz_uid UNIQUE (gruppe_kurzbz, uid);'; + + if (!$db->db_query($qry)) + echo 'public.tbl_gruppe_manager: '.$db->db_last_error().'
'; + else + echo '
public.tbl_gruppe_manager table created'; + + $qry = 'GRANT SELECT ON TABLE public.tbl_gruppe_manager TO web;'; + if (!$db->db_query($qry)) + echo 'public.tbl_gruppe_manager: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to web on public.tbl_gruppe_manager'; + + $qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE public.tbl_gruppe_manager TO vilesci;'; + if (!$db->db_query($qry)) + echo 'public.tbl_gruppe_manager: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on public.tbl_gruppe_manager'; +} + +// Add permission for managing user groups +if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'lehre/gruppenmanager';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('lehre/gruppenmanager', 'Manager einer Gruppe werden und die Gruppe verwalten');"; + + if(!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo ' system.tbl_berechtigung: Added permission for lehre/gruppenmanager
'; + } +} + // NOTE(chris): Add "Template" to "Lehrtyp" if($result = @$db->db_query("SELECT 1 FROM lehre.tbl_lehrtyp WHERE bezeichnung = 'Template';")) { @@ -6327,18 +6393,18 @@ if(!@$db->db_query("SELECT public.get_ects_summe_schulisch('', 0, 0)")) DECLARE rec_quereinstiegs_studiensemester RECORD; DECLARE sum_quereinstiegs_ects numeric(4, 1) := 0; DECLARE sum_schulische_ects numeric(4, 1) := 0; - - + + BEGIN - + -- IF STUDENT IS QUEREINSTEIGER, GET ECTS SUMME OF ANGERECHNETE SEMESTER - -- Get Einstiegssemester - SELECT INTO var_einstiegsausbildungssemester , var_einstiegsstudiensemester_kurzbz, var_einstiegsorgform_kurzbz ausbildungssemester, studiensemester_kurzbz, orgform_kurzbz from public.tbl_prestudentstatus - WHERE prestudent_id = var_prestudent_id + -- Get Einstiegssemester + SELECT INTO var_einstiegsausbildungssemester , var_einstiegsstudiensemester_kurzbz, var_einstiegsorgform_kurzbz ausbildungssemester, studiensemester_kurzbz, orgform_kurzbz from public.tbl_prestudentstatus + WHERE prestudent_id = var_prestudent_id AND status_kurzbz = \'Student\' ORDER BY datum, insertamum, ext_id LIMIT 1; - + -- If Einstiegssemester > 1 (= Quereinsteiger) IF (var_einstiegsausbildungssemester > 1) THEN -- ...get all Quereinstiegssemester @@ -6357,66 +6423,66 @@ if(!@$db->db_query("SELECT public.get_ects_summe_schulisch('', 0, 0)")) JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) WHERE tbl_studienplan.studienplan_id = ( - SELECT + SELECT studienplan_id - FROM - lehre.tbl_studienordnung - JOIN lehre.tbl_studienplan USING (studienordnung_id) + FROM + lehre.tbl_studienordnung + JOIN lehre.tbl_studienplan USING (studienordnung_id) JOIN lehre.tbl_studienplan_semester USING (studienplan_id) - WHERE tbl_studienordnung.studiengang_kz = var_studiengang_kz + WHERE tbl_studienordnung.studiengang_kz = var_studiengang_kz AND tbl_studienplan_semester.semester = var_einstiegsausbildungssemester - 1 AND tbl_studienplan_semester.studiensemester_kurzbz = rec_quereinstiegs_studiensemester.studiensemester_kurzbz - AND tbl_studienplan.orgform_kurzbz = var_einstiegsorgform_kurzbz - + AND tbl_studienplan.orgform_kurzbz = var_einstiegsorgform_kurzbz + LIMIT 1 ) AND tbl_studienplan_lehrveranstaltung.semester = var_einstiegsausbildungssemester AND studienplan_lehrveranstaltung_id_parent IS NULL -- auf Modulebene AND tbl_studienplan_lehrveranstaltung.export = TRUE); - + var_einstiegsausbildungssemester = var_einstiegsausbildungssemester - 1; END LOOP; END IF; - - + + -- GET ECTS SUMME OF ALLE BISHER ANGERECHNETEN LEHRVERANSTALTUNGEN. ANRECHNUNGSGRUND: SCHULISCH. SELECT INTO sum_schulische_ects COALESCE(SUM(ects), 0) FROM ( - SELECT + SELECT lehrveranstaltung_id, studiensemester_kurzbz, ects - FROM - lehre.tbl_zeugnisnote - LEFT JOIN lehre.tbl_anrechnung USING(lehrveranstaltung_id, studiensemester_kurzbz) + FROM + lehre.tbl_zeugnisnote + LEFT JOIN lehre.tbl_anrechnung USING(lehrveranstaltung_id, studiensemester_kurzbz) JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) JOIN public.tbl_student USING(student_uid) - WHERE + WHERE tbl_zeugnisnote.note = 6 AND student_uid = var_student_uid AND lehre.tbl_anrechnung.prestudent_id IN (tbl_student.prestudent_id, NULL) AND begruendung_id != 5 -- universitäre ECTS nicht mitrechnen - AND begruendung_id != 4 -- berufliche ECTS nicht mitrechnen - AND (anrechnung_id IS NULL OR (anrechnung_id IS NOT NULL AND genehmigt_von IS NOT NULL )) -- Anrechnungen aus Zeit vor Anrechnungstool ODER digitale Anrechnungen mit Noteneintrag UND Genehmigung (wichtig, um zurückgenommene Genehmigungen, die in der Notentabelle noch als angerechnet eingetragen sind, rauszufiltern) - - UNION - - SELECT + AND begruendung_id != 4 -- berufliche ECTS nicht mitrechnen + AND (anrechnung_id IS NULL OR (anrechnung_id IS NOT NULL AND genehmigt_von IS NOT NULL )) -- Anrechnungen aus Zeit vor Anrechnungstool ODER digitale Anrechnungen mit Noteneintrag UND Genehmigung (wichtig, um zurückgenommene Genehmigungen, die in der Notentabelle noch als angerechnet eingetragen sind, rauszufiltern) + + UNION + + SELECT lehrveranstaltung_id, studiensemester_kurzbz, ects - FROM - lehre.tbl_anrechnung + FROM + lehre.tbl_anrechnung JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) JOIN public.tbl_student USING(prestudent_id) - WHERE + WHERE genehmigt_von IS NOT NULL - AND student_uid = var_student_uid + AND student_uid = var_student_uid AND begruendung_id != 5 -- universitäre ECTS nicht mitrechnen - AND begruendung_id != 4 -- berufliche ECTS nicht mitrechnen + AND begruendung_id != 4 -- berufliche ECTS nicht mitrechnen ) lvsangerechnet; - + -- BUILD ECTS SUMME OF QUEREINSTIEGSSEMESTER- + ANGERECHNETEN LVs-ECTS -- Summe aller bisher schulisch begründet angerechneten LVs + der Quereinstiegssemester sum_schulische_ects = sum_schulische_ects + sum_quereinstiegs_ects; - + RETURN sum_schulische_ects ; - + END; $_$; @@ -6436,40 +6502,40 @@ if(!@$db->db_query("SELECT public.get_ects_summe_beruflich('')")) AS $_$ DECLARE var_student_uid ALIAS FOR $1; DECLARE sum_berufliche_ects numeric(4, 1) := 0; - + BEGIN - + SELECT INTO sum_berufliche_ects COALESCE(SUM(ects), 0) FROM ( - SELECT + SELECT lehrveranstaltung_id, studiensemester_kurzbz, ects - FROM - lehre.tbl_zeugnisnote - LEFT JOIN lehre.tbl_anrechnung USING(lehrveranstaltung_id, studiensemester_kurzbz) + FROM + lehre.tbl_zeugnisnote + LEFT JOIN lehre.tbl_anrechnung USING(lehrveranstaltung_id, studiensemester_kurzbz) JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) JOIN public.tbl_student USING(student_uid) - WHERE + WHERE tbl_zeugnisnote.note = 6 AND student_uid = var_student_uid AND lehre.tbl_anrechnung.prestudent_id IN (tbl_student.prestudent_id, NULL) AND begruendung_id = 4 -- beruflich AND (anrechnung_id IS NULL OR (anrechnung_id IS NOT NULL AND genehmigt_von IS NOT NULL )) -- Anrechnungen aus Zeit vor Anrechnungstool ODER digitale Anrechnungen mit Noteneintrag UND Genehmigung (wichtig, um zurückgenommene Genehmigungen, die in der Notentabelle noch als angerechnet eingetragen sind, rauszufiltern) - - UNION - - SELECT + + UNION + + SELECT lehrveranstaltung_id, studiensemester_kurzbz, ects - FROM - lehre.tbl_anrechnung + FROM + lehre.tbl_anrechnung JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) JOIN public.tbl_student USING(prestudent_id) - WHERE + WHERE genehmigt_von is not null - AND student_uid = var_student_uid + AND student_uid = var_student_uid AND begruendung_id = 4 -- beruflich ) lvsangerechnet; - + RETURN sum_berufliche_ects; - + END; $_$; @@ -6509,6 +6575,40 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_dokument WHERE dokument_ku } } +//Spalte aktiv zu bis.tbl_zgv hinzufügen +if (!$result = @$db->db_query("SELECT aktiv FROM bis.tbl_zgv LIMIT 1")) +{ + $qry = "ALTER TABLE bis.tbl_zgv ADD COLUMN aktiv BOOLEAN NOT NULL DEFAULT true;"; + + if(!$db->db_query($qry)) + echo 'bis.tbl_zgv '.$db->db_last_error().'
'; + else + echo '
Spalte aktiv zu bis.tbl_zgv hinzugefügt'; +} + +//Spalte aktiv zu bis.tbl_zgvmaster hinzufügen +if (!$result = @$db->db_query("SELECT aktiv FROM bis.tbl_zgvmaster LIMIT 1")) +{ + $qry = "ALTER TABLE bis.tbl_zgvmaster ADD COLUMN aktiv BOOLEAN NOT NULL DEFAULT true;"; + + if(!$db->db_query($qry)) + echo 'bis.tbl_zgvmaster '.$db->db_last_error().'
'; + else + echo '
Spalte aktiv zu bis.tbl_zgvmaster hinzugefügt'; +} + +//Spalte aktiv zu bis.tbl_zgvdoktor hinzufügen +if (!$result = @$db->db_query("SELECT aktiv FROM bis.tbl_zgvdoktor LIMIT 1")) +{ + $qry = "ALTER TABLE bis.tbl_zgvdoktor ADD COLUMN aktiv BOOLEAN NOT NULL DEFAULT true;"; + + if(!$db->db_query($qry)) + echo 'bis.tbl_zgvdoktor '.$db->db_last_error().'
'; + else + echo '
Spalte aktiv zu bis.tbl_zgvdoktor hinzugefügt'; +} + + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -6544,9 +6644,9 @@ $tabellen=array( "bis.tbl_oehbeitrag" => array("oehbeitrag_id","studierendenbeitrag","versicherung","von_studiensemester_kurzbz","bis_studiensemester_kurzbz","insertamum","insertvon","updateamum","updatevon"), "bis.tbl_orgform" => array("orgform_kurzbz","code","bezeichnung","rolle","bisorgform_kurzbz","bezeichnung_mehrsprachig"), "bis.tbl_verwendung" => array("verwendung_code","verwendungbez"), - "bis.tbl_zgv" => array("zgv_code","zgv_bez","zgv_kurzbz","bezeichnung"), - "bis.tbl_zgvmaster" => array("zgvmas_code","zgvmas_bez","zgvmas_kurzbz","bezeichnung"), - "bis.tbl_zgvdoktor" => array("zgvdoktor_code", "zgvdoktor_bez", "zgvdoktor_kurzbz","bezeichnung"), + "bis.tbl_zgv" => array("zgv_code","zgv_bez","zgv_kurzbz","bezeichnung","aktiv"), + "bis.tbl_zgvmaster" => array("zgvmas_code","zgvmas_bez","zgvmas_kurzbz","bezeichnung","aktiv"), + "bis.tbl_zgvdoktor" => array("zgvdoktor_code", "zgvdoktor_bez", "zgvdoktor_kurzbz","bezeichnung","aktiv"), "bis.tbl_zweck" => array("zweck_code","kurzbz","bezeichnung","incoming","outgoing"), "bis.tbl_zgvgruppe" => array("gruppe_kurzbz","bezeichnung"), "bis.tbl_zgvgruppe_zuordnung" => array("zgvgruppe_id" ,"studiengang_kz","zgv_code","zgvmas_code","gruppe_kurzbz"), diff --git a/system/filtersupdate.php b/system/filtersupdate.php index abe8ac1a5..02c30b648 100644 --- a/system/filtersupdate.php +++ b/system/filtersupdate.php @@ -1112,6 +1112,27 @@ $filters = array( } ', 'oe_kurzbz' => null + ), + array( + 'app' => 'core', + 'dataset_name' => 'gruppenmanagement', + 'filter_kurzbz' => 'gruppenmanagement', + 'description' => '{Meine Gruppen}', + 'sort' => 1, + 'default_filter' => true, + 'filter' => ' + { + "name": "gruppenmanagement", + "columns": [ + {"name": "gruppe_kurzbz"}, + {"name": "gruppe_bezeichnung"}, + {"name": "gruppe_beschreibung"}, + {"name": "studiengang_kurzbz"} + ], + "filters": [] + } + ', + 'oe_kurzbz' => null, ) ); diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 2f62e4138..9e0a87b6e 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -16238,7 +16238,7 @@ array( 'sprache' => 'German', 'text' => 'Ab dem Studienjahr 2022/23 ist der Erwerb von internationalen und interkulturellen Kompetenzen Teil des Curriculums.
Auf der Grundlage der vorliegenden Maßnahmen absolvieren Sie im Laufe ihres Studiums Internationalisierungsaktivitäten, die mit unterschiedlichen ECTS-Punkten hinterlegt sind.
- In Summe müssen 5 ECTS erworben werden, die im 6. Semester wirksam werden.
+ In Summe müssen 5 ECTS erworben werden, die im 6. Semester wirksam werden.
Das Modul „International skills“ wird mit der Beurteilung „Mit Erfolg teilgenommen“ abgeschlossen.
Bitte wählen Sie die für Sie in Frage kommenden Maßnahmen aus und planen Sie das entsprechende Semester.
Sobald die 5 ECTS erreicht wurden, überprüft der Studiengang die von Ihnen hochgeladenen Dokumente.', @@ -16758,6 +16758,186 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'benutzerSchonZugewiesen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Benutzer ist bereits der Gruppe zugewiesen", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "User is already assigned to the group", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'gruppenmanagement', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Gruppenmanagement", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Group management", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'kurzbezeichnung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Kurzbezeichnung", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Short description", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'bezeichnung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Bezeichnung", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Name", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'beschreibung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Beschreibung", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Description", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'zuweisenloeschen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Zuweisen/Entfernen", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Assign/Remove", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'benutzergruppe', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Benutzergruppe", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "User group", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'benutzerHinzufuegen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Benutzer hinzufügen", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Add user", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'gruppenmanagement', + 'phrase' => 'aktiv', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "aktiv", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "active", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ) ); diff --git a/vilesci/lehre/einheit_menu.php b/vilesci/lehre/einheit_menu.php index bfb44e8d9..a6e09fe23 100644 --- a/vilesci/lehre/einheit_menu.php +++ b/vilesci/lehre/einheit_menu.php @@ -24,6 +24,7 @@ require_once('../../config/vilesci.config.inc.php'); require_once('../../include/functions.inc.php'); require_once('../../include/studiengang.class.php'); require_once('../../include/gruppe.class.php'); +require_once('../../include/gruppemanager.class.php'); require_once('../../include/person.class.php'); require_once('../../include/benutzer.class.php'); require_once('../../include/student.class.php'); @@ -82,17 +83,59 @@ if(!$rechte->isBerechtigt('lehre/gruppe', null, 's')) Gruppe-Verwaltung + - + %s - %s %s " + ."Manager entfernen" + ."" + .""; + ?> + @@ -158,8 +301,10 @@ else if (isset($_GET['type']) && $_GET['type']=='delete') if($rechte->isBerechtigt('lehre/gruppe', $oe_studiengang, 'suid')) { + $grp_kurzbz = $_GET['einheit_id']; + $e=new gruppe(); - if(!$e->delete($_GET['einheit_id'])) + if(!$e->delete($grp_kurzbz)) echo $e->errormsg; } else @@ -214,6 +359,7 @@ function printDropDown() echo ''; echo ''; } + function doSave() { global $rechte; @@ -241,8 +387,10 @@ function doSave() $e->new = false; } + $user = get_uid(); + $e->updateamum = date('Y-m-d H:i:s'); - $e->updatevon = get_uid(); + $e->updatevon = $user; $e->bezeichnung = $_POST['bezeichnung']; $e->beschreibung = $_POST['beschreibung']; $e->studiengang_kz = $_POST['studiengang_kz']; @@ -258,13 +406,66 @@ function doSave() $e->sort = $_POST['sort']; $e->content_visible = isset($_POST['content_visible']); + + // gruppemanager immer array, leer wenn keine angegeben + $gruppemanager_uids = isset($_POST['gruppemanager']) && is_array($_POST['gruppemanager']) ? $_POST['gruppemanager'] : array(); + + // Prüfung: generierte Gruppen haben keine Manager + if (count($gruppemanager_uids) > 0 && $e->generiert === true) + { + echo "Generierte Gruppen dürfen keine Administratoren haben!"; + return; + } + if(!$e->save()) - echo $e->errormsg; + echo "".$e->errormsg.""; + else // wenn Gruppe erfolgreich gespeichert, Gruppenmanager speichern + { + // Gruppe gemäss Konvention in Großbuchstaben + $gruppe_kurzbz = mb_strtoupper($_POST['kurzbz']); + + // bestehende Gruppenmanager laden + $bestehende_gruppemanager_uids = array(); + $gruppemanager_hlp = new gruppemanager(); + if ($gruppemanager_hlp->load_uids($gruppe_kurzbz)) + { + foreach ($gruppemanager_hlp->uids as $uid_obj) + { + $bestehende_gruppemanager_uids[] = $uid_obj->uid; + } + } + + foreach ($gruppemanager_uids as $gruppemanager_uid) + { + // wenn Gruppenmanager noch nicht zugewiesen + if (!in_array($gruppemanager_uid, $bestehende_gruppemanager_uids)) + { + // Gruppemanager speichern + $gruppemgr = new gruppemanager(); + $gruppemgr->uid = $gruppemanager_uid; + $gruppemgr->gruppe_kurzbz = $gruppe_kurzbz; + $gruppemgr->insertamum = date('Y-m-d H:i:s'); + $gruppemgr->insertvon = $user; + + if(!$gruppemgr->save()) + echo $gruppemgr->errormsg; + } + } + + // zu löschende Gruppemanager ermitteln + $geloeschte_gruppemanager_uids = array_diff($bestehende_gruppemanager_uids, $gruppemanager_uids); + + // Nicht mehr vorhandene Gruppenmanager löschen + $gruppemanager_hlp = new gruppemanager(); + foreach ($geloeschte_gruppemanager_uids as $geloeschte_uid) + { + if (!$gruppemanager_hlp->delete($geloeschte_uid, $gruppe_kurzbz)) + echo $gruppemanager_hlp->errormsg; + } + } } } - - function doEdit($kurzbz,$new=false) { global $db, $rechte, $studiengang, $searchItems; @@ -282,6 +483,9 @@ function doEdit($kurzbz,$new=false)

Gruppe

p->t('global','name')) ?> p->t('global','typ')) ?> p->t('global','uploaddatum')) ?>p->t('ui','loeschen')) ?> p->t('infocenter','ausstellungsnation')) ?> - autocomplete="off"> bezeichnung === $dokument->dokument_bezeichnung ? 'selected' : '') . " value = " . $dokumenttyp->dokument_kurzbz . ">" . $dokumenttyp->bezeichnung . "" @@ -30,7 +31,7 @@
- +
erstelltam), 'd.m.Y') ?>> langtext ?>
"+benutzer.uid+""+benutzer.vorname+""+benutzer.nachname+""+(benutzer.aktiv === true ? "Ja" : "Nein")+""+ + ""+ + "
+ + + @@ -341,6 +545,44 @@ function doEdit($kurzbz,$new=false) + + + load_uids($e->gruppe_kurzbz); + + // richtige Tabellenzeige Grösse wenn Administratoren vorhanden + if ($gruppemanager_uids_result === true) + { + $gruppemanagerCellClass = ' class="gruppenmanager-cell"'; + } + ?> + id="gruppenmanager-cell"> + + + Generierte Gruppen dürfen keine Administratoren haben. + + "; + // alle Manager der Gruppe anzeigen + if ($gruppemanager_uids_result === true) + { + $count = 1; + foreach ($gruppemanager_hlp->uids as $uid_obj) + { + $ben = new benutzer($uid_obj->uid); + // Vorlagestring durch Werte ersetzen und ausgeben + echo sprintf(MANAGER_HTML, $uid_obj->uid, $ben->vorname, $ben->nachname, $uid_obj->uid); + if ($count % 5 == 0) // neue Zeile nach 5 Elementen + echo "

"; + $count++; + } + } + ?> + +
+
Kurzbezeichnung
GruppenadministratorOptional, Administratoren, die Benutzer zur Gruppe entfernen/hinzufügen können
Semester