diff --git a/.gitignore b/.gitignore index 96af3e5dc..84957a801 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ documents/ vendor/ /nbproject/ +.vscode +composer.phar /.idea/ .settings .project diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php index 2466d2bb1..6713ef37d 100644 --- a/application/config/anrechnung.php +++ b/application/config/anrechnung.php @@ -1,6 +1,6 @@ TRUE, + 'referenzbeispiele_ects' => TRUE, + 'voraussetzungen' => TRUE, + 'nachweisdokumente' => TRUE, + 'herkunft_kenntnisse' => TRUE +]; diff --git a/application/config/cis.php b/application/config/cis.php new file mode 100644 index 000000000..82655f244 --- /dev/null +++ b/application/config/cis.php @@ -0,0 +1,9 @@ + array( 'fhcomplete' => array( @@ -50,7 +56,7 @@ $config['navigation_header'] = array( 'requiredPermissions' => 'basis/vilesci:r', 'children' => array( 'cis' => array( - 'link' => CIS_ROOT, + 'link' => $root, 'icon' => '', 'description' => 'CIS', 'sort' => 10 @@ -223,7 +229,7 @@ $config['navigation_menu']['organisation/Reihungstest/index'] = array( 'target' => '_blank' ), 'auswertung' => array( - 'link' => CIS_ROOT.'/cis/testtool/admin/auswertung.php', + 'link' => $root.'/cis/testtool/admin/auswertung.php', 'description' => 'Auswertung', 'icon' => 'list-alt', 'sort' => 1, @@ -319,5 +325,4 @@ $config['navigation_menu']['system/issues/Issues/*'] = array( 'target' => '_blank', 'requiredPermissions' => array('admin:rw') ), -); - +); \ No newline at end of file diff --git a/application/config/routes.php b/application/config/routes.php index 15da5698f..eb4c267ce 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed'); | Examples: my-controller/index -> my_controller/index | my-controller/my-method -> my_controller/my_method */ -$route['default_controller'] = 'Vilesci'; +$route['default_controller'] = defined('CIS4') && CIS4 ? 'Cis4' : 'Vilesci'; $route['translate_uri_dashes'] = FALSE; // Class name conflicts @@ -61,6 +61,8 @@ $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisa $route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/betriebsmittelperson2/$1'; $route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1'; +$route['Cis/Stundenplan/.*'] = 'Cis/Stundenplan/index/$1'; + // load routes from extensions $subdir = 'application/config/extensions'; $dirlist = scandir($subdir); @@ -81,5 +83,4 @@ if ($dirlist) } } } -} - +} \ No newline at end of file diff --git a/application/config/stv.php b/application/config/stv.php new file mode 100644 index 000000000..31ce3f521 --- /dev/null +++ b/application/config/stv.php @@ -0,0 +1,76 @@ + [ + //all fields can be configured to be hidden, see class attribute stv-details-details-name for name + 'hiddenFields' => [], + 'hideUDFs' => false + ], + + 'prestudent' => [ + + //all fields can be configured to be hidden, see class attribute stv-details-prestudent-name for name + 'hiddenFields' => [ + + //propably used by FH-Communities + 'aufnahmeschluessel', 'standort_code', 'facheinschlaegigBerufstaetig' + + ], + 'hideUDFs' => false + ], + 'finalexam' => [ + 'documents' => [ + 'pruefungsprotokoll' => [ + 'de' => [ + 'Bakk' => 'PrProtBA', + 'Master' => 'PrProtMA', + ], + 'en' => [ + 'Bakk' => 'PrProtBAEng', + 'Master' => 'PrProtMAEng', + ], + ], + 'pruefungszeugnis' => [ + 'de' => [ + 'Bakk' => 'Bakkzeugnis', + 'Master' => 'Diplomzeugnis', + ], + 'en' => [ + 'Bakk' => 'BakkzeugnisEng', + 'Master' => 'DiplomzeugnisEng', + ], + ], + 'urkunde' => [ + 'de' => [ + 'Bakk' => 'Bakkurkunde', + 'Master' => 'Diplomurkunde', + ], + 'en' => [ + 'Bakk' => 'BakkurkundeEng', + 'Master' => 'DiplomurkundeEng', + ], + ], + ], + ] + ]; + +// List of fields to show when ZGV_DOKTOR_ANZEIGEN is defined +$fieldsZgvDoktor = ['zgvdoktorort', 'zgvdoktordatum', 'zgvdoktornation', 'zgvdoktor_erfuellt', 'zgvdoktor_code']; + +// List of fields to show when ZGV_ERFUELLT_ANZEIGEN is defined +$fieldsZgvErfuellt = ['zgv_erfuellt', 'zgvmas_erfuellt','zgvdoktor_erfuellt']; + +//order important: to show zgf_erfuellt_doktor just in case visibility of doktor is true +if (!defined('ZGV_ERFUELLT_ANZEIGEN') || !ZGV_ERFUELLT_ANZEIGEN) { + $config['tabs']['prestudent']['hiddenFields'] = array_merge( + $config['tabs']['prestudent']['hiddenFields'], $fieldsZgvErfuellt + ); +} + +if (!defined('ZGV_DOKTOR_ANZEIGEN') || !ZGV_DOKTOR_ANZEIGEN) { + $config['tabs']['prestudent']['hiddenFields'] = array_merge( + $config['tabs']['prestudent']['hiddenFields'], + $fieldsZgvDoktor + ); +} diff --git a/application/controllers/Cis/Auth.php b/application/controllers/Cis/Auth.php new file mode 100644 index 000000000..59dab1568 --- /dev/null +++ b/application/controllers/Cis/Auth.php @@ -0,0 +1,77 @@ +load->helper('form'); + $this->load->helper('hlp_authentication'); + + // Loads phrases system + $this->loadPhrases([ + 'global' + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function login() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('username', 'Username', 'required|trim|callback_validation'); + $this->form_validation->set_rules('password', 'Password', 'required|trim'); + + + if ($this->form_validation->run()) + { + redirect($this->authlib->getLandingPage('/CisVue/Dashboard')); + } + else + { + $this->load->view('Cis/Login'); + } + } + + /** + * @return boolean + */ + public function validation() + { + $username = $this->input->post('username'); + $password = $this->input->post('password'); + + $this->load->library('AuthLib', [false]); // without authentication otherwise loooooop! + + $login = $this->authlib->loginLDAP($username, $password); + if (isSuccess($login)) + return true; + $this->form_validation->set_message('validation', 'Incorrect username/password.'); + return false; + } + + /** + * @return void + */ + public function logout() + { + $this->load->library('AuthLib'); + $this->authlib->logout(); + redirect('/Cis/Auth/login', 'refresh'); + } +} diff --git a/application/controllers/Cis/Documents.php b/application/controllers/Cis/Documents.php new file mode 100644 index 000000000..c5a6684d3 --- /dev/null +++ b/application/controllers/Cis/Documents.php @@ -0,0 +1,192 @@ + [self::PERM_LOGGED], + 'student' => ['admin:r'], + 'download' => [self::PERM_LOGGED] + ]); + + $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + + $this->loadPhrases([ + 'global', + 'tools' + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + return $this->showDocuments(getAuthUID()); + } + + /** + * @param string $uid Administratoren dürfen die UID als Parameter übergeben um die Dokumente von anderen Personen anzuzeigen + * @return void + */ + public function student($uid) + { + return $this->showDocuments($uid); + } + + /** + * @param string $uid + * @return void + */ + protected function showDocuments($uid) + { + $this->load->model('crm/Konto_model', 'KontoModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $stati = $this->PrestudentstatusModel->loadWhereUid($uid, null, true); + if (isError($stati)) + return $this->load->view('errors/html/error_db.php', [ + 'heading' => 'Database Error', + 'message' => getError($stati) + ]); + $stati = getData($stati); + if (!$stati) + return $this->load->view('errors/html/error_general.php', [ + 'heading' => 'User ist kein Student', + 'message' => 'Es konnten keine Studiensemester gefunden werden in denen der User als Student inskripiert ist' + ]); + + $stgs = []; + $stsemArray = []; + $buchungstypen = implode('\',\'', defined("CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN") ? unserialize(CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN) : []); + $person_ids = []; + foreach ($stati as $status) { + $person_ids[] = $status->person_id; + + if(!in_array($status->studiensemester_kurzbz, $stsemArray)) { + $stsemArray[] = $status->studiensemester_kurzbz; + } + + if (!isset($stgs[$status->studiengang_kz])) { + $stg = $this->StudiengangModel->load($status->studiengang_kz); + if (isError($stg)) + return $this->load->view('errors/html/error_db.php', [ + 'heading' => 'Database Error', + 'message' => getError($stg) + ]); + $stg = getData($stg); + if (!$stg) + return $this->load->view('errors/html/error_db.php', [ + 'heading' => 'Database Error', + 'message' => 'No Studiengang found for studiengang_kz ' . $status->studiengang_kz + ]); + $stgs[$status->studiengang_kz] = current($stg); + $stgs[$status->studiengang_kz]->studiensemester = []; + } + if (!isset($stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz])) { + $stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz] = new stdClass(); + $stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz]->inskriptionsbestaetigung = (boolean)getData( + $this->KontoModel->checkStudienbeitragFromPrestudent( + $status->prestudent_id, + $status->studiensemester_kurzbz, + $buchungstypen + ) + ); + } + } + $person_ids = array_unique($person_ids); + + $selfservice = null; + if (!defined('CIS_DOKUMENTE_SELFSERVICE') || CIS_DOKUMENTE_SELFSERVICE) { + $this->load->model('crm/Akte_model', 'AkteModel'); + $selfservice = []; + foreach ($person_ids as $person_id) { + $result = $this->AkteModel->getArchiv($person_id, null, true); + if (isError($result)) + return $this->load->view('errors/html/error_db.php', [ + 'heading' => 'Database Error', + 'message' => getError($result) + ]); + $selfservice = array_merge($selfservice, getData($result) ?: []); + } + } + + + $this->load->view('Cis/Documents', [ + 'stsemArray' => $stsemArray, + 'stgs' => $stgs, + 'uid' => $uid, + 'studienbuchblatt' => defined('CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN') && CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN, + 'studienerfolgsbestaetigung' => defined('CIS_DOKUMENTE_STUDIENERFOLGSBESTAETIGUNG_DRUCKEN') && CIS_DOKUMENTE_STUDIENERFOLGSBESTAETIGUNG_DRUCKEN, + 'selfservice' => $selfservice + ]); + } + + /** + * @param integer $akte_id + * @param string $uid (optional) Administratoren dürfen die UID als Parameter übergeben um die Dokumente von anderen Personen anzuzeigen + * + * @return void + */ + public function download($akte_id, $uid = null) + { + if (!is_numeric($akte_id)) + return show_404(); + + $this->load->model('crm/Akte_model', 'AkteModel'); + $result = $this->AkteModel->load($akte_id); + if (isError($result)) + return show_error(getError($result)); + $akte = getData($result); + if (!$akte) + return show_404(); + $akte = current($akte); + + $admin_access = false; + if ($uid !== null && $this->permissionlib->isBerechtigt('admin')) { + $stati = $this->PrestudentstatusModel->loadWhereUid($uid, null, true); + if (hasData($stati)) { + $person_ids = array_map(function ($status) { + return $status->person_id; + }, getData($stati)); + $person_ids = array_unique($person_ids); + if (count($person_ids) == 1 && current($person_ids) == $akte->person_id) { + $admin_access = true; + } + } + } + + if (!$admin_access && ($akte->person_id != getAuthPersonId() || !$akte->stud_selfservice)) + return show_error('Forbidden', 403); + + // NOTE(chris): Log bei einem Download vom Becheid + if (isset($akte->dokument_kurzbz) && ($akte->dokument_kurzbz === 'Bescheid' || $akte->dokument_kurzbz === 'BescheidEng')) { + $this->load->model('system/Webservicelog_model', 'WebservicelogModel'); + $this->WebservicelogModel->insert([ + 'webservicetyp_kurzbz' => 'content', + 'request_id' => (isset($akte->akte_id) && !empty($akte->akte_id)) ? $akte->akte_id : null, + 'beschreibung' => 'Bescheidbestaetigungsdownload', + 'request_data' => $_SERVER['QUERY_STRING'], + 'execute_time' => date('c'), + 'execute_user' => getAuthUID() + ]); + } + + $this->output->set_content_type($akte->mimetype); + $this->output->set_output(base64_decode($akte->inhalt)); + } +} diff --git a/application/controllers/system/TestVBform.php b/application/controllers/Cis/InfoTerminal.php similarity index 58% rename from application/controllers/system/TestVBform.php rename to application/controllers/Cis/InfoTerminal.php index 9923bf05b..13dea1367 100644 --- a/application/controllers/system/TestVBform.php +++ b/application/controllers/Cis/InfoTerminal.php @@ -3,30 +3,28 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** - * Test VBform Vue Component + * */ -class TestVBform extends Auth_Controller +class InfoTerminal extends Auth_Controller { /** * Constructor */ public function __construct() { - parent::__construct( - array( - 'index' => 'system/developer:r' - ) - ); + parent::__construct([ + 'index' => ['basis/cis:r'], + ]); } // ----------------------------------------------------------------------------------------------------------------- // Public methods /** - * Everything has a beginning + * @return void */ public function index() { - $this->load->view('system/logs/testVBform.php'); + $this->load->view('Cis/InfoTerminal.php', []); } } diff --git a/application/controllers/Cis/MyLv.php b/application/controllers/Cis/MyLv.php new file mode 100644 index 000000000..49a938553 --- /dev/null +++ b/application/controllers/Cis/MyLv.php @@ -0,0 +1,41 @@ + ['basis/cis:r'], + 'Info' => [self::PERM_LOGGED] + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $viewData = array( + + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']); + } + + public function Info($studien_semester,$lvid) + { + $this->load->view('Cis/LvInfo',['lvid'=> $lvid, 'studien_semester' => $studien_semester]); + } +} diff --git a/application/controllers/Cis/Profil.php b/application/controllers/Cis/Profil.php new file mode 100644 index 000000000..8c3088bd7 --- /dev/null +++ b/application/controllers/Cis/Profil.php @@ -0,0 +1,742 @@ + ['basis/cis:r'], + 'foto_sperre_function' => ['basis/cis:r'], + 'getView' => ['basis/cis:r'], + 'View' => ['basis/cis:r'], + 'isMitarbeiter' => ['basis/cis:r'], + 'isStudent' => ['basis/cis:r'], + 'getZustellAdresse' => ['basis/cis:r'], + 'getZustellKontakt' => ['basis/cis:r'], + 'getAllNationen' => ['basis/cis:r'], + 'getGemeinden' => ['basis/cis:r'], + + ]); + + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('person/Adresse_model', 'AdresseModel'); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); + $this->load->model('content/DmsVersion_model', 'DmsVersionModel'); + + + //? put the uid and pid inside the controller for reusability + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + + /** + * index loads the Profil view + * @access public + * @return void + */ + public function index() + { + $viewData = array( + + ); + $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilIndex']); + } + + /** + * redirects to the index function (needed to allow calling this URI) + * @access public + * @return void + */ + public function View($uid) + { + $viewData = array ('uid' => $uid); + + $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilViewUid']); + } + + /** + * checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php) + * @access public + * @param $uid the userID used to check if it is a mitarbeiter + * @return boolean + */ + public function isStudent($uid) + { + $result = $this->StudentModel->isStudent($uid); + if (isError($result)) { + show_error("error when calling Student_model function isStudent with uid " . $uid); + } + $result = getData($result); + echo json_encode($result); + } + + /** + * checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php) + * @access public + * @param $uid the userID used to check if it is a mitarbeiter + * @return boolean + */ + public function isMitarbeiter($uid) + { + $result = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($result)) { + show_error("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid); + } + $result = getData($result); + echo json_encode($result); + } + + /** + * gets the adressen that are marked as zustell from the currenlty logged in user + * @access public + * @return array a list of adresse_id's + */ + public function getZustellAdresse() + { + $this->AdresseModel->addSelect(["adresse_id"]); + $adressen_res = $this->AdresseModel->loadWhere(['person_id' => $this->pid, 'zustelladresse' => true]); + $adressen_res = hasData($adressen_res) ? getData($adressen_res) : null; + $adressen_res = array_map(function ($item) { + return $item->adresse_id; + }, $adressen_res); + echo json_encode($adressen_res); + } + + /** + * gets the kontakte that are marked as zustell from the currenlty logged in user + * @access public + * @return array a list of kontakt_id's + */ + public function getZustellKontakt() + { + $this->KontaktModel->addSelect(["kontakt_id"]); + $kontakt_res = $this->KontaktModel->loadWhere(['person_id' => $this->pid, 'zustellung' => true]); + $kontakt_res = hasData($kontakt_res) ? getData($kontakt_res) : null; + $kontakt_res = array_map(function ($item) { + return $item->kontakt_id; + }, $kontakt_res); + echo json_encode($kontakt_res); + } + + /** + * function that returns the data used for the corresponding view + * the client side parses the @param $uid and calls this function to get the data to the correct view + * @access public + * @param boolean $uid the userID used to identify which information should be retrieved for which view + * @return stdClass all the data corresponding to a view of a user + */ + public function getView($uid) + { + $res = new stdClass(); + + // if parsing the URL did not found a UID then the UID of the logged in user is used + if ($uid == "Profil" || $uid == $this->uid) { + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid); + if (isError($isMitarbeiter)) { + show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter"); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "MitarbeiterProfil"; + $res->data = $this->mitarbeiterProfil(); + $res->data->pid = $this->pid; + } else { + $res->view = "StudentProfil"; + $res->data = $this->studentProfil(); + $res->data->pid = $this->pid; + } + } + // UID is availabe when accessing Profil/View/:uid + else { + $this->PersonModel->addSelect(["person_id"]); + $pid = $this->PersonModel->getByUid($uid); + if (isError($pid)) { + show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid); + } + $pid = hasData($pid) ? getData($pid)[0] : null; + if (!$pid) { + show_error("Person with UID: " . $uid . " does not exist"); + } + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($isMitarbeiter)) { + show_error("error while checking if UID: " . $uid . " is a mitarbeiter"); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "ViewMitarbeiterProfil"; + $res->data = $this->viewMitarbeiterProfil($uid); + + } else { + $res->view = "ViewStudentProfil"; + $res->data = $this->viewStudentProfil($uid); + } + } + echo json_encode($res); + } + + /** + * update column foto_sperre in public.tbl_person + * @access public + * @param boolean $value new value for the column + * @return boolean the new value added to the column in public.tbl_person + */ + public function foto_sperre_function($value) + { + $res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]); + if (isError($res)) { + show_error("error while trying to update table public.tbl_person"); + } + $this->PersonModel->addSelect("foto_sperre"); + $res = $this->PersonModel->load($this->pid); + if (isError($res)) { + show_error("error while trying to query table public.tbl_person"); + } + $res = hasData($res) ? getData($res)[0] : null; + echo json_encode($res); + } + + /** + * gets all nations in the table bis.tbl_nation + * + * @access public + * @return array all the nations in table bis.tbl_nation + */ + public function getAllNationen() + { + $this->load->model('codex/Nation_model', "NationModel"); + $this->NationModel->addSelect(["nation_code as code", "langtext"]); + $nation_res = $this->NationModel->load(); + if (isError($nation_res)) { + show_error("error while trying to query table codex.tbl_nation"); + } + $nation_res = hasData($nation_res) ? getData($nation_res) : null; + echo json_encode($nation_res); + } + + /** + * gets specific gemeinden which are related to the ZIP and the Nation passed in the body of the get request + * @access public + * @var $_GET function uses GET request payload + * @return boolean the new value added to the column in public.tbl_person + */ + public function getGemeinden() + { + /** @var $nation value parsed out of the body of the get request */ + $nation = $this->input->get('nation', true); + /** @var $zip value parsed out of the body of the get request and converted to a php integer with json_decode */ + $zip = json_decode($this->input->get('zip', true)); + + $this->load->model('codex/Gemeinde_model', "GemeindeModel"); + $this->GemeindeModel->addDistinct(); + $this->GemeindeModel->addSelect(["name"]); + if ($nation == "A") { + if (isset($zip) && $zip > 999 && $zip < 32000) { + + $gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]); + if (isError($gemeinde_res)) { + show_error("error while trying to query bis.tbl_gemeinde"); + } + $gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null; + $gemeinde_res = array_map(function ($obj) { + return $obj->name; + }, $gemeinde_res); + echo json_encode($gemeinde_res); + + } else { + echo json_encode(error("ortschaftskennziffer code was not valid")); + } + } else { + echo json_encode(error("Nation was not 'A' (Austria)")); + } + } + + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * function that returns the data used for viewing another mitarbeiter profile + * @access private + * @param integer $uid the userID to retrieve the mitarbeiter data + * @return stdClass restricted mitarbeiter data + */ + private function viewMitarbeiterProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $benutzer_funktion_res = $this->getBenutzerFunktion($uid); + $benutzer_res = $this->getBenutzerAlias($uid); + $person_res = $this->getPersonInfo($uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($uid); + $telefon_res = $this->getTelefonInfo($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Info + foreach ($person_res as $key => $val) { + $res->$key = $val; + } + + //? Mitarbeiter Info + foreach ($mitarbeiter_res as $key => $val) { + $res->$key = $val; + + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $uid . "@" . DOMAIN; + $extern_email = array(); + $extern_email["type"] = "alias"; + $extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN; + $res->emails = array($intern_email, $extern_email); + + $res->funktionen = $benutzer_funktion_res; + $res->mailverteiler = $mailverteiler_res; + $res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null; + + return $res; + } + + /** + * function that returns the data used for viewing another student profile + * @access private + * @param integer $uid the userID to retrieve the student data + * @return stdClass restricted student data + */ + private function viewStudentProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $person_res = $this->getPersonInfo($uid); + $student_res = $this->getStudentInfo($uid); + $matr_res = $this->getMatrikelNummer($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = $value; + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $uid . "@" . DOMAIN; + + $res->emails = [$intern_email]; + $res->matrikelnummer = $matr_res->matr_nr; + $res->mailverteiler = $mailverteiler_res; + + return $res; + } + + /** + * function that returns the data used for the mitarbeiter profile + * @access private + * @return stdClass mitarbeiter data + */ + private function mitarbeiterProfil() + { + + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); + $adresse_res = $this->getAdressenInfo($this->pid); + $kontakte_res = $this->getKontaktInfo($this->pid); + $mailverteiler_res = $this->getMailverteiler($this->uid); + $person_res = $this->getPersonInfo($this->uid, true); + $benutzer_funktion_res = $this->getBenutzerFunktion($this->uid); + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); + $profilUpdates = $this->getProfilUpdates($this->uid); + $telefon_res = $this->getTelefonInfo($this->uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($this->uid); + + $res = new stdClass(); + $res->username = $this->uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Mitarbeiter Information + foreach ($mitarbeiter_res as $key => $value) { + $res->$key = $value; + } + + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->mailverteiler = $mailverteiler_res; + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $this->uid . "@" . DOMAIN; + $extern_email = array(); + $extern_email["type"] = "alias"; + $extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN; + $res->emails = [$intern_email, $extern_email]; + + $res->funktionen = $benutzer_funktion_res; + $res->standort_telefon = $telefon_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * function that returns the data used for the student profile + * @access private + * @return stdClass student data + */ + private function studentProfil() + { + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); + $kontakte_res = $this->getKontaktInfo($this->pid); + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); + $adresse_res = $this->getAdressenInfo($this->pid); + $mailverteiler_res = $this->getMailverteiler($this->uid); + $person_res = $this->getPersonInfo($this->uid, true); + $zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid); + $student_res = $this->getStudentInfo($this->uid); + $matr_res = $this->getMatrikelNummer($this->uid); + $profilUpdates = $this->getProfilUpdates($this->uid); + + $res = new stdClass(); + $res->username = $this->uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = trim($value); + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $this->uid . "@" . DOMAIN; + + $res->emails = [$intern_email]; + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->matrikelnummer = $matr_res->matr_nr; + $res->zuttritsgruppen = $zutrittsgruppe_res; + $res->mailverteiler = $mailverteiler_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe + * @access private + * @param integer $uid the userID used to retrieve the mailverteiler + * @return array returns the mailvertailer corresponding to a userID + */ + private function getMailverteiler($uid) + { + $this->PersonModel->addSelect('gruppe_kurzbz, beschreibung'); + $this->PersonModel->addJoin('tbl_benutzer', 'person_id'); + $this->PersonModel->addJoin('tbl_benutzergruppe', 'uid'); + $this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid)); + if (isError($mailverteiler_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res)); + } + $mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null; + $mailverteiler_res = array_map(function ($element) { + $element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN; + return $element; + }, $mailverteiler_res); + return $mailverteiler_res; + } + + /** + * gets all the Benutzerfunktionen of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Benutzerfunktionen + * @return array returns the Benutzerfunktionen corresponding to a userID + */ + private function getBenutzerFunktion($uid) + { + $this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]); + $this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz"); + + $benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid)); + if (isError($benutzer_funktion_res)) { + show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res)); + } + $benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null; + return $benutzer_funktion_res; + } + + /** + * gets all the Betriebsmittel of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Betriebsmittel + * @return array returns the Betriebsmittel corresponding to a userID + */ + private function getBetriebsmittelInfo($pid) + { + $this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]); + + //? betriebsmittel are not needed in a view + $betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid); + if (isError($betriebsmittelperson_res)) { + show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res)); + } + $betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null; + return $betriebsmittelperson_res; + } + + /** + * gets the alias of a corresponding user + * @access private + * @param integer $uid the userID used to get the alias + * @return string the alias of the userID + */ + private function getBenutzerAlias($uid) + { + $this->BenutzerModel->addSelect(["alias"]); + $benutzer_res = $this->BenutzerModel->load([$uid]); + if (isError($benutzer_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res)); + } else { + $benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null; + } + + return $benutzer_res; + } + + /** + * gets the person information corresponding to a user + * @access private + * @param integer $uid the userID used to get the person information + * @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not + * @return array all the person informaion corresponding to a userID + */ + private function getPersonInfo($uid, $geburtsInfo = null) + { + $selectClause = ["foto", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"]; + /** @param integer $geburtsInfo */ + if ($geburtsInfo) { + array_push($selectClause, "gebort"); + array_push($selectClause, "gebdatum"); + array_push($selectClause, "foto_sperre"); + } + $this->BenutzerModel->addSelect($selectClause); + $this->BenutzerModel->addJoin("tbl_person", "person_id"); + + $person_res = $this->BenutzerModel->load([$uid]); + if (isError($person_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res)); + } else { + $person_res = hasData($person_res) ? getData($person_res)[0] : null; + } + + return $person_res; + } + + /** + * gets the mitarbeiter information corresponding to a user + * @access private + * @param integer $uid the userID used to get the mitarbeiter information + * @return array all the mitarbeiter informaion corresponding to a userID + */ + private function getMitarbeiterInfo($uid) + { + $this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]); + $this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid"); + $mitarbeiter_res = $this->MitarbeiterModel->load($uid); + if (isError($mitarbeiter_res)) { + show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res)); + } else { + $mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null; + } + + return $mitarbeiter_res; + } + + /** + * gets the telefon information corresponding to a user + * @access private + * @param integer $uid the userID used to get the telefon information + * @return array all the telefon informaion corresponding to a userID + */ + private function getTelefonInfo($uid) + { + $this->MitarbeiterModel->addSelect(["kontakt"]); + $this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id"); + $this->MitarbeiterModel->addLimit(1); + $telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]); + if (isError($telefon_res)) { + show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res)); + } + $telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null; + return $telefon_res; + } + + /** + * gets the student information corresponding to a user + * @access private + * @param integer $uid the userID used to get the student information + * @return array all the student informaion corresponding to a userID + */ + private function getStudentInfo($uid) + { + $this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']); + $this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz"); + + $student_res = $this->StudentModel->load([$uid]); + if (isError($student_res)) { + show_error("was not able to query the table public.tbl_student:" . getData($student_res)); + } + $student_res = hasData($student_res) ? getData($student_res)[0] : null; + return $student_res; + } + + /** + * gets the profil updates corresponding to a user + * @access private + * @param integer $uid the userID used to get the profil updates + * @return array all the profil updates corresponding to a userID + */ + private function getProfilUpdates($uid) + { + $profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]); + if (isError($profilUpdates)) { + show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates)); + } + $profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null; + return $profilUpdates; + } + + /** + * gets the Matrikelnummer corresponding to a user + * @access private + * @param integer $uid the userID used to get the Matrikelnummer + * @return integer the Matrikelnummer corresponding to a userID + */ + private function getMatrikelNummer($uid) + { + $this->BenutzerModel->addSelect(["matr_nr"]); + $this->BenutzerModel->addJoin("tbl_person", "person_id"); + + $matr_res = $this->BenutzerModel->load([$uid]); + if (isError($matr_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res)); + } + $matr_res = hasData($matr_res) ? getData($matr_res)[0] : []; + return $matr_res; + } + + /** + * gets the Zutrittsgruppen corresponding to a user + * @access private + * @param integer $uid the userID used to get the Zutrittsgruppen + * @return array all the Zutrittsgruppen corresponding to a userID + */ + private function getZutrittsgruppen($uid) + { + $this->BenutzergruppeModel->addSelect(['bezeichnung']); + $this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true)); + if (isError($zutrittsgruppe_res)) { + show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res)); + } + $zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null; + return $zutrittsgruppe_res; + } + + /** + * gets the address information corresponding to a user + * @access private + * @param integer $uid the userID used to get the address information + * @return array all the address information corresponding to a userID + */ + private function getAdressenInfo($pid) + { + $adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]); + $adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC"); + $adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"); + + $adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]); + if (isError($adresse_res)) { + show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res)); + } + $adresse_res = hasData($adresse_res) ? getData($adresse_res) : null; + return $adresse_res; + } + + /** + * gets the kontakt information corresponding to a user + * @access private + * @param integer $uid the userID used to get the kontakt information + * @return array all the kontakt information corresponding to a userID + */ + private function getKontaktInfo($pid) + { + $this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']); + $this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT'); + $this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT'); + $this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum'); + + $kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]); + if (isError($kontakte_res)) { + show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res)); + } + $kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null; + return $kontakte_res; + } + + /** + * gets the date of issue of the FH access card corresponding to a user + * @access private + * @param integer $uid the userID used to get the date of issue of the FH access card + * @return string the date of issue of the FH access card corresponding to a userID + */ + private function getZutrittskarteDatum($uid) + { + $zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte"); + if (isError($zutrittskarte_ausgegebenam)) { + show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam)); + } + $zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null; + + //? formats date from 01-01-2000 to 01.01.2000 + $zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam); + return $zutrittskarte_ausgegebenam; + } + + +} diff --git a/application/controllers/Cis/ProfilUpdate.php b/application/controllers/Cis/ProfilUpdate.php new file mode 100644 index 000000000..c47b7540b --- /dev/null +++ b/application/controllers/Cis/ProfilUpdate.php @@ -0,0 +1,814 @@ + ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'], + 'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'], + 'show' => ['basis/cis:r'], + + 'insertProfilRequest' => ['basis/cis:rw'], + 'updateProfilRequest' => ['basis/cis:rw'], + 'deleteProfilRequest' => ['basis/cis:rw'], + 'selectProfilRequest' => ['basis/cis:r'], + 'insertFile' => ['basis/cis:rw'], + 'getProfilRequestFiles' => ['basis/cis:r'], + 'getStatus' => ['basis/cis:r'], + 'getTopic' => ['basis/cis:r'], + ]); + + $this->load->config('cis'); + + $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Adresse_model', 'AdresseModel'); + $this->load->model('person/Adressentyp_model', 'AdressenTypModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel'); + $this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel'); + + // Load language phrases + $this->loadPhrases( + array( + 'ui', + 'global', + 'person', + 'profil', + 'profilUpdate' + ) + ); + + $this->load->library('DmsLib'); + $this->load->library('PermissionLib'); + + //? put the uid and pid inside the controller for reusability + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + + // setup the ProfilUpdate states + $this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']); + $status_kurzbz = $this->ProfilUpdateStatusModel->load(); + if (hasData($status_kurzbz)) { + list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz); + + self::$STATUS_PENDING = $status_pending->status_kurzbz; + self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz; + self::$STATUS_REJECTED = $status_rejected->status_kurzbz; + } + // setup the ProfilUpdate topics + $this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']); + $topic_kurzbz = $this->ProfilUpdateTopicModel->load(); + + if (hasData($topic_kurzbz)) { + foreach (getData($topic_kurzbz) as $topic) { + self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz; + } + } + } + + + public function index() + { + $this->load->view('Cis/ProfilUpdate'); + } + + public function id($profil_update_id = null) + { + $this->load->view('Cis/ProfilUpdate', ['profil_update_id' => $profil_update_id]); + } + + public function getStatus() + { + echo json_encode([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]); + } + + public function getTopic() + { + echo json_encode(self::$TOPICS); + } + + private function sendEmail_onProfilUpdate_response($uid, $topic, $status) + { + if($this->config->item('cis_send_profil_update_mails') === false) + { + return; + } + + $this->load->helper('hlp_sancho_helper'); + $email = $uid . "@" . DOMAIN; + + + function languageQuery($language) + { + return "select index from public.tbl_sprache where sprache = '" + $language + "'"; + } + $this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]); + $status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]); + if (isError($status_translation)) { + show_error($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError')); + } + $status_translation = hasData($status_translation) ? getData($status_translation)[0] : null; + if (isset($status_translation)) { + $mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending'))); + if (!$mail_res) { + show_error($this->p->t('profilUpdate', 'profilUpdate_email_error')); + } + } + + } + + + private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic) + { + if($this->config->item('cis_send_profil_update_mails') === false) + { + return; + } + + $this->load->helper('hlp_sancho_helper'); + $emails = []; + + $isMitarbeiter_res = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($isMitarbeiter_res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error')); + } + $isMitarbeiter_res = getData($isMitarbeiter_res); + + //! if the $uid is a mitarbeiter and student, only the hr is notified by email + if ($isMitarbeiter_res) { + //? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung + //? use constant variable MAIL_GST to mail to the personalverwaltung + $this->MitarbeiterModel->addSelect([TRUE]); + $this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid"); + //? check if the the userID is a mitarbeiter and if the benutzer is active + $res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]); + if (isError($res)) { + show_error("was not able to query the mitarbeiter and benutzer by the uid: " . $uid); + } + if (hasData($res)) { + array_push($emails, MAIL_GST); + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error')); + } + } else { + //? if it is not a mitarbeiter, check whether it is a student and send email to studiengang + $isStudent_res = $this->StudentModel->isStudent($uid); + if (isError($isStudent_res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error')); + } + $isStudent_res = getData($isStudent_res); + if ($isStudent_res) { + //? Send email to the Studiengangsassistentinnen + $this->StudentModel->addSelect(["public.tbl_studiengang.email"]); + $this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid"); + $this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id"); + $this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id"); + $this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz"); + //* check if the benutzer itself is active + //* check if the student status is Student or Diplomand (active students) + $this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']); + $res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]); + if (isError($res)) { + show_error(getData($res)); + } else { + $res = hasData($res) ? getData($res) : []; + foreach ($res as $emailObj) { + array_push($emails, $emailObj->email); + } + } + } + } + $mail_res = []; + //? sending email + foreach ($emails as $email) { + array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid))); + } + foreach ($mail_res as $m_res) { + if (!$m_res) { + show_error($this->p->t('profilUpdate', 'profilUpdate_email_error')); + } + } + + } + + + public function show($dms_id) + { + + $profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]); + $profil_update = hasData($profil_update) ? getData($profil_update)[0] : null; + + //? checks if an profil update exists with the dms_id requested from the user + if ($profil_update) { + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid)); + + if ( + $this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update || + $this->uid == $profil_update->uid + ) { + // Get file to be downloaded from DMS + $newFilename = $this->uid . "/document_" . $dms_id; + $download = $this->dmslib->download($dms_id); + if (isError($download)) + return $download; + + // Download file + $this->outputFile(getData($download)); + + + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + return; + } + + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_dms_error')); + return; + } + + } + + + public function insertFile($replace) + { + $replace = json_decode($replace); + + if (!count($_FILES)) { + echo json_encode([]); + return; + } + + //? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced + if (isset($replace)) { + $this->ProfilUpdateModel->addSelect(["attachment_id"]); + $profilUpdate = $this->ProfilUpdateModel->load([$replace]); + if (isError($profilUpdate)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error'))); + } + //? get the attachmentID + $dms_id = hasData($profilUpdate) ? getData($profilUpdate)[0]->attachment_id : null; + + //? delete old dms_file of Profil Update + $this->deleteOldVersionFile($dms_id); + } + + + $files = $_FILES['files']; + $file_count = count($files['name']); + + $res = []; + + for ($i = 0; $i < $file_count; $i++) { + $_FILES['files']['name'] = $files['name'][$i]; + $_FILES['files']['type'] = $files['type'][$i]; + $_FILES['files']['tmp_name'] = $files['tmp_name'][$i]; + $_FILES['files']['error'] = $files['error'][$i]; + $_FILES['files']['size'] = $files['size'][$i]; + + $dms = [ + "kategorie_kurzbz" => "profil_aenderung", + "version" => 0, + "name" => $_FILES['files']['name'], + "mimetype" => $_FILES['files']['type'], + "beschreibung" => $this->uid . " Profil Änderung", + "insertvon" => $this->uid, + "insertamum" => "NOW()", + ]; + + $tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf")); + + $tmp_res = hasData($tmp_res) ? getData($tmp_res) : null; + array_push($res, $tmp_res); + } + + echo json_encode($res); + } + + + public function selectProfilRequest() + { + $_GET = json_decode($this->input->raw_input_stream, true); + $uid = $this->input->get('uid'); + $id = $this->input->get('id'); + $whereClause = ['uid' => $this->uid]; + + if (isset($uid)) + $whereClause['uid'] = $uid; + if (isset($id)) + $whereClause['id'] = $id; + + $res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause); + $res = hasData($res) ? getData($res) : null; + echo json_encode($res); + + } + + + public function getProfilRequestFiles() + { + $id = json_decode($this->input->raw_input_stream); + + $this->ProfilUpdateModel->addSelect(["attachment_id"]); + $attachmentID = $this->ProfilUpdateModel->load([$id]); + if (isError($attachmentID)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error'))); + } + //? get the attachmentID + $dms_id = hasData($attachmentID) ? getData($attachmentID)[0]->attachment_id : null; + + //? get the name to the file + $this->DmsVersionModel->addSelect(["name", "dms_id"]); + $attachment = $this->DmsVersionModel->load([$dms_id, 0]); + if (isError($attachment)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'))); + } + $attachment = hasData($attachment) ? getData($attachment) : null; + //? returns {name:..., dms_id:...} + echo json_encode($attachment); + } + + public function insertProfilRequest() + { + + $json = json_decode($this->input->raw_input_stream); + + $payload = $json->payload; + $identifier = property_exists($json->payload, "kontakt_id") ? "kontakt_id" : (property_exists($json->payload, "adresse_id") ? "adresse_id" : null); + + $data = ["topic" => $json->topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending']; + + //? insert fileID in the dataset if sent with post request + if (isset($json->fileID)) { + $data['attachment_id'] = $json->fileID; + + } + + //? loops over all updateRequests from a user to validate if the new request is valid + $res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]); + if (isError($res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_loading_error')); + } + $res = hasData($res) ? getData($res) : null; + + //? the user cannot delete a zustelladresse/kontakt + if (isset($payload->delete) && $payload->{$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"}) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'))); + return; + } + + //? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised + if (isset($payload->delete) && $identifier == "adresse_id") { + $adr = $this->AdresseModel->load($payload->$identifier); + $adr = getData($adr)[0]; + if ($adr->heimatadresse) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'))); + return; + } + } + + if ($res) { + $pending_changes = array_filter($res, function ($element) { + return $element->status == (self::$STATUS_PENDING ?: "Pending"); + }); + + foreach ($pending_changes as $update_request) { + $existing_change = $update_request->requested_change; + + //? the user can add as many new kontakte/adressen as he likes + if (!isset($payload->add) && property_exists($existing_change, $identifier) && property_exists($payload, $identifier) && $existing_change->$identifier == $payload->$identifier) { + //? the kontakt_id / adresse_id of a change has to be unique + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error'))); + return; + } + + //? if it is not updating any kontakt/adresse, the topic has to be unique + elseif (!$identifier && $update_request->topic == $json->topic) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic]))); + return; + } + } + } + + $insertID = $this->ProfilUpdateModel->insert($data); + + if (isError($insertID)) { + show_error(getData($insertID)); + } else { + $insertID = hasData($insertID) ? getData($insertID) : null; + + //? sends emails to the correspondents of the $uid + $this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $json->topic); + echo json_encode(success($insertID)); + } + } + + public function updateProfilRequest() + { + $json = json_decode($this->input->raw_input_stream); + + $updateData = ["requested_change" => json_encode($json->payload), "updateamum" => "NOW()", "updatevon" => $this->uid]; + if (isset($json->fileID)) { + $updateData['attachment_id'] = json_decode($json->fileID); + } + $updateID = $this->ProfilUpdateModel->update([$json->ID], $updateData); + //? insert fileID in the dataset if sent with post request + + if (isError($updateID)) { + //catch error + } else { + $updateID = hasData($updateID) ? getData($updateID)[0] : null; + //TODO: should an email be sent to the responsable people when the user changes his profil update + echo json_encode(success($updateID)); + } + } + + public function deleteProfilRequest() + { + + $json = json_decode($this->input->raw_input_stream); + $delete_res = $this->ProfilUpdateModel->delete([$json]); + echo json_encode($delete_res); + } + + + public function getProfilUpdateWithPermission($status = null) + { + // early return if no status has been passed as argument + if (!isset($status)) { + echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission()); + return; + } + + // get the sprache of the user + $sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]); + $sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null; + + if (isset($sprachenIndex) && isset($status)) { + // get the corresponding status kurz_bz primary key out of the translation + $status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]); + $status = hasData($status) ? getData($status)[0]->status_kurzbz : null; + $res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null); + + echo json_encode($res); + } + } + + + + private function getOE_from_student($student_uid) + { + + //? returns the oe_einheit eines Studenten + $query = "SELECT public.tbl_studiengang.oe_kurzbz + FROM public.tbl_student + JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz + WHERE public.tbl_student.student_uid = ?;"; + + $res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]); + if (!isSuccess($res)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_loadingOE_error')); + } + $res = hasData($res) ? getData($res) : []; + $res = array_map( + function ($item) { + return $item->oe_kurzbz; + }, + $res + ); + return $res; + } + + + public function acceptProfilRequest() + { + $_POST = json_decode($this->input->raw_input_stream, true); + $id = $this->input->post('profil_update_id', true); + $uid = $this->input->post('uid', true); + + //? fetching person_id using UID + $personID = $this->PersonModel->getByUid($uid); + $personID = hasData($personID) ? getData($personID)[0]->person_id : null; + $status_message = $this->input->post('status_message', true); + $topic = $this->input->post('topic', true); + + //! somehow the xss check converted boolean false to empty string + $requested_change = $this->input->post('requested_change'); + + //! check for required information + if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) { + return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error'))); + } + + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($uid)); + + + //? check if the permissions are set correctly + if ( + $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update + ) { + + if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) { + $insertID = $this->handleAdresse($requested_change, $personID); + $insertID = hasData($insertID) ? getData($insertID) : null; + if (isset($insertID)) { + $requested_change['adresse_id'] = $insertID; + $update_res = $this->updateRequestedChange($id, $requested_change); + if (isError($update_res)) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID]))); + return; + } + } + + } else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) { + $insertID = $this->handleKontakt($requested_change, $personID); + $insertID = hasData($insertID) ? getData($insertID) : null; + if (isset($insertID)) { + $requested_change['kontakt_id'] = $insertID; + $update_res = $this->updateRequestedChange($id, $requested_change); + if (isError($update_res)) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID]))); + return; + } + } + + + } else { + switch ($topic) { + // mapping phrasen to database columns to make the update with the correct column names + case self::$TOPICS['Titel']: + $topic = "titelpre"; + break; + case self::$TOPICS['Postnomen']: + $topic = "titelpost"; + break; + case self::$TOPICS['Vorname']: + $topic = "vorname"; + break; + case self::$TOPICS['Nachname']: + $topic = "nachname"; + break; + default: + show_error($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic])); + return; + } + + $result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]); + if (isError($result)) { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_insert_error'))); + return; + } + } + $this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED); + + echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change)); + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + } + + + } + + public function denyProfilRequest() + { + + $_POST = json_decode($this->input->raw_input_stream, true); + $id = $this->input->post('profil_update_id', true); + $uid = $this->input->post('uid', true); + $topic = $this->input->post('topic', true); + $status_message = $this->input->post('status_message', true); + + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($uid)); + + + if ( + $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update + ) { + $this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED); + echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message)); + } else { + show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + } + + + } + + private function updateRequestedChange($id, $requested_change) + { + return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]); + } + + private function setStatusOnUpdateRequest($id, $status, $status_message) + { + return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]); + } + + private function deleteOldVersionFile($dms_id) + { + if (!isset($dms_id)) { + return; + } + + //? collect all the results of the deleted versions in an array + $res = array(); + + //? delete all the different versions of the dms_file + $dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]); + $dmsVersions = hasData($dmsVersions) ? getData($dmsVersions) : null; + if (isset($dmsVersions)) { + $zwischen_res = array_map(function ($item) { + return $item->version; + }, $dmsVersions); + foreach ($zwischen_res as $version) { + array_push($res, $this->DmsVersionModel->delete([$dms_id, $version])); + } + } else { + echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'))); + } + + //? returns a result for each deleted dms_file + return $res; + } + + + private function handleKontakt($requested_change, $personID) + { + $kontakt_id = $requested_change["kontakt_id"]; + //? removes the kontakt_id because we don't want to update the kontakt_id in the database + unset($requested_change["kontakt_id"]); + + + //! ADD + if (array_key_exists('add', $requested_change) && $requested_change['add']) { + //? removes add flag + unset($requested_change['add']); + $requested_change['person_id'] = $personID; + $requested_change['insertamum'] = "NOW()"; + $requested_change['insertvon'] = getAuthUID(); + $insertID = $this->KontaktModel->insert($requested_change); + $insert_kontakt_id = $insertID; + if (isError($insert_kontakt_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error')); + } + $insert_kontakt_id = hasData($insert_kontakt_id) ? getData($insert_kontakt_id) : null; + if ($insert_kontakt_id) { + $this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id); + } + + + } + //! DELETE + elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) { + $this->KontaktModel->delete($kontakt_id); + } + //! UPDATE + else { + $requested_change['updateamum'] = "NOW()"; + $requested_change['updatevon'] = getAuthUID(); + + $update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change); + + if (isError($update_kontakt_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error')); + } + $update_kontakt_id = hasData($update_kontakt_id) ? getData($update_kontakt_id) : null; + if ($update_kontakt_id) { + $this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id); + } + } + return isset($insertID) ? $insertID : null; + } + + private function handleAdresse($requested_change, $personID) + { + + $this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]); + $adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]); + $adr_kurzbz = hasData($adr_kurzbz) ? getData($adr_kurzbz)[0]->adressentyp_kurzbz : null; + //? replace the address_typ with its correct kurzbz foreign key + $requested_change['typ'] = $adr_kurzbz; + + $adresse_id = $requested_change["adresse_id"]; + //? removes the adresse_id because we don't want to update the kontakt_id in the database + unset($requested_change["adresse_id"]); + + + //! ADD + if (array_key_exists('add', $requested_change) && $requested_change['add']) { + + //? removes add flag + unset($requested_change['add']); + $requested_change['insertamum'] = "NOW()"; + $requested_change['insertvon'] = getAuthUID(); + $requested_change['person_id'] = $personID; + //TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet + $insertID = $this->AdresseModel->insert($requested_change); + $insert_adresse_id = $insertID; + if (isError($insert_adresse_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error')); + } + $insert_adresse_id = hasData($insert_adresse_id) ? getData($insert_adresse_id) : null; + if ($insert_adresse_id) { + $this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id); + } + + } + //! DELETE + elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) { + $this->AdresseModel->delete($adresse_id); + } + //! UPDATE + else { + $requested_change['updateamum'] = "NOW()"; + $requested_change['updatevon'] = getAuthUID(); + $update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change); + if (isError($update_adresse_id)) { + show_error($this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error')); + } + $update_adresse_id = hasData($update_adresse_id) ? getData($update_adresse_id) : null; + if ($update_adresse_id) { + $this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id); + } + } + return isset($insertID) ? $insertID : null; + } + + + private function handleDupplicateZustellKontakte($zustellung, $kontakt_id) + { + if ($zustellung) { + $this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id"); + $this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id"); + $zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]); + if (!isSuccess($zustellKontakteArray)) { + return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error')); + } + $zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null; + + if ($zustellung && count($zustellKontakteArray) > 0) { + $zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) { + return $kontakt->kontakt_id != $kontakt_id; + }); + foreach ($zustellKontakteArray as $kontakt) { + $this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]); + } + + } + } + } + + private function handleDupplicateZustellAdressen($zustellung, $adresse_id) + { + if ($zustellung) { + $this->PersonModel->addSelect("public.tbl_adresse.adresse_id"); + $this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id"); + $zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]); + if (!isSuccess($zustellAdressenArray)) { + return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error')); + } + $zustellAdressenArray = hasData($zustellAdressenArray) ? getData($zustellAdressenArray) : null; + + if ($zustellung && count($zustellAdressenArray) > 0) { + + $zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) { + + return $adresse->adresse_id != $adresse_id; + }); + foreach ($zustellAdressenArray as $adresse) { + $this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]); + } + + } + } + } + + +} \ No newline at end of file diff --git a/application/controllers/Cis/Pub.php b/application/controllers/Cis/Pub.php new file mode 100644 index 000000000..bebc844ab --- /dev/null +++ b/application/controllers/Cis/Pub.php @@ -0,0 +1,167 @@ + ['basis/cis:r'] + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @param string $source [person|akte] + * @param integer $id + * @return void + */ + public function bild($source, $id) + { + $this->load->model('person/Person_model', 'PersonModel'); + + $person_id_user = ''; + $serverzugriff = false; + + // Wenn das Bild direkt aufgerufen wird, ist eine Authentifizierung erforderlich + // Wenn es vom Server selbst aufgerufen wird, ist keine Auth. notwendig + // (z.B. fuer die Erstellung von PDFs) + if ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) { + // Wenn Session gesetzt ist, keine Abfrage, da diese Personen noch keine UID haben + + if (isset($_SESSION['incoming/user'])) { // Von Incomingtool + $result = $this->PersonModel->loadWhere([ + 'zugangscode' => $_SESSION['incoming/user'] + ]); + if (hasData($result)) + $person_id_user = current(getData($result))->person_id; + } elseif (isset($_SESSION['prestudent/user'])) { // Von Prestudententool + $result = $this->PersonModel->loadWhere([ + 'zugangscode' => $_SESSION['prestudent/user'] + ]); + if (hasData($result)) + $person_id_user = current(getData($result))->person_id; + } elseif (isset($_SESSION['bewerbung/personId'])) { // Von Bewerbungstool + $person_id_user = $_SESSION['bewerbung/personId']; + } else { + $person_id_user = getAuthPersonId(); + } + } else { + $serverzugriff = true; + } + + // Default Bild (Dummy Profilbild) + $cTmpHEX = base64_encode(file_get_contents(FHCPATH . 'skin/images/profilbild_dummy.jpg')); + + if ($source == 'person' && $id) { + $foto_gesperrt = false; + // Person laden und Fotosperre überprüfen + $result = $this->PersonModel->load($id); + if (hasData($result)) { + $person = current(getData($result)); + if ($person->foto_sperre) { + // Wenn der User selbst darauf zugreift darf er das Bild sehen + $foto_gesperrt = ($person_id_user != $id); + } elseif (!$person_id_user && !$serverzugriff) { + $foto_gesperrt = true; + } + + if ($person->foto && !$foto_gesperrt) { + $cTmpHEX = base64_decode($person->foto); + } + } + } + if($source == 'akte' && $id != '') + { + $this->load->model('crm/Akte_model', 'AkteModel'); + + $this->AkteModel->addJoin('public.tbl_person', 'person_id'); + $result = $this->AkteModel->loadWhere([ + 'person_id' => $id, + 'dokument_kurzbz' => 'Lichtbil' + ]); + + if (hasData($result)) { + $foto_gesperrt = false; + + $akte = current(getData($result)); + if ($akte->foto_sperre) { + // Wenn der User selbst darauf zugreift darf er das Bild sehen + $foto_gesperrt = ($person_id_user != $id); + } elseif (!$person_id_user && !$serverzugriff) { + $foto_gesperrt = true; + } + + // Wenn das Foto nicht im Inhalt steht wird aus aus dem DMS geladen + if (!$akte->inhalt && $akte->dms_id) { + $this->load->model('content/Dms_model', 'DmsModel'); + $this->load->model('content/DmsVersion_model', 'DmsVersionModel'); + + $this->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id'); + $this->DmsModel->addOrder('version', 'DESC'); + $this->DmsModel->addLimit(1); + $result = $this->DmsModel->load($akte->dms_id); + + if (!hasData($result)) + die('Kein Dokument vorhanden'); + + $dms = current(getData($result)); + + $filename = DMS_PATH . $dms->filename; + + $this->DmsVersionModel->update([ + 'dms_id' => $dms->dms_id, + 'version' => $dms->version + ], [ + 'letzterzugriff' => date('c') + ]); + + if (file_exists($filename)) { + $handle = fopen($filename, "r"); + if ($handle) { + while (!feof($handle)) { + $akte->inhalt .= fread($handle, 8192); + } + fclose($handle); + } else { + echo 'Fehler: Datei konnte nicht geoeffnet werden'; + } + } else { + echo 'Die Datei existiert nicht'; + } + } + + if ($akte->inhalt && !$foto_gesperrt) { + $cTmpHEX = $akte->inhalt; + } + } + } + + // die bilder werden, sofern es funktioniert, in jpg umgewandelt da es sonst zu fehlern beim erstellen + // von pdfs kommen kann. + + $im = @imagecreatefromstring(base64_decode($cTmpHEX)); + if ($im) { + @ob_clean(); + header("Content-type: image/jpeg"); + exit(imagejpeg($im)); + } else { + // bei manchen Bildern funktioniert die konvertierung nicht + // diese werden dann einfach so angezeigt. + @ob_clean(); + header("Content-type: image/gif"); + exit($cTmpHEX); + } + } +} diff --git a/application/controllers/Cis/Stundenplan.php b/application/controllers/Cis/Stundenplan.php new file mode 100644 index 000000000..71e01be8b --- /dev/null +++ b/application/controllers/Cis/Stundenplan.php @@ -0,0 +1,35 @@ + ['basis/cis:r'] + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $viewData = array( + 'uid'=>getAuthUID(), + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Stundenplan']); + } +} diff --git a/application/controllers/Cis4.php b/application/controllers/Cis4.php new file mode 100644 index 000000000..c0ca8d503 --- /dev/null +++ b/application/controllers/Cis4.php @@ -0,0 +1,41 @@ + 'basis/cis:r' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + $this->load->model('person/Person_model','PersonModel'); + $personData = getData($this->PersonModel->getByUid(getAuthUID()))[0]; + + $viewData = array( + 'uid' => getAuthUID(), + 'name' => $personData->vorname, + 'person_id' => $personData->person_id + ); + + $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'FhcDashboard']); + } +} \ No newline at end of file diff --git a/application/controllers/CisVue/Cms.php b/application/controllers/CisVue/Cms.php new file mode 100644 index 000000000..a9ff13c53 --- /dev/null +++ b/application/controllers/CisVue/Cms.php @@ -0,0 +1,96 @@ + 'basis/cis:r', + 'getNews' => 'basis/cis:r', + 'getNewsRowCount' => 'basis/cis:r', + 'getRoomInformation' => 'basis/cis:r', + 'news' => 'basis/cis:r' + ) + ); + + // Loads Libraries + $this->load->library('CmsLib'); + + // Loads phrases system + $this->loadPhrases([ + 'global' + ]); + + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @param int $content_id + * @param int $version + * @param string $sprache + * @param boolean $sichtbar + * + * @return void + */ + public function content($content_id, $version = null, $sprache = null, $sichtbar = true) + { + // return early if the content_id for the content is missing + if (!isset($content_id)) + $this->terminateWithError("content_id is missing"); + + $content = $this->ContentModel->load($content_id); + if (isError($content)) + $this->terminateWithError(getError($content)); + + $content = getData($content); + if (NULL === $content) + $this->terminateWithError("Content not found"); + + $content = current($content); + + $viewData = array( + 'content_id' => $content_id, + 'template_kurzbz' => $content->template_kurzbz, + 'version' => $version, + 'sichtbar' => $sichtbar + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Content']); + } + + /** + * @param boolean $infoscreen + * @param string | null $studiengang_kz + * @param int | null $semester + * @param boolean $mischen + * @param string $titel + * @param boolean $edit + * @param boolean $sichtbar + * + * @return void + */ + public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) + { + $viewData = array(); + $this->load->view('CisRouterView/CisRouterView.php', ['viewData'=>$viewData, 'route' => 'News']); + } + + public function getRoomInformation($ort_kurzbz){ + $viewData = array( + 'ort_kurzbz' => $ort_kurzbz + ); + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'CmsRoom']); + } +} diff --git a/application/controllers/CisVue/Dashboard.php b/application/controllers/CisVue/Dashboard.php new file mode 100644 index 000000000..ee830cb8b --- /dev/null +++ b/application/controllers/CisVue/Dashboard.php @@ -0,0 +1,43 @@ + 'dashboard/benutzer:r' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $this->load->model('person/Person_model','PersonModel'); + $personData = getData($this->PersonModel->getByUid(getAuthUID()))[0]; + + $viewData = array( + 'uid' => getAuthUID(), + 'name' => $personData->vorname, + 'person_id' => $personData->person_id + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData]); + + } +} \ No newline at end of file diff --git a/application/controllers/Documents.php b/application/controllers/Documents.php new file mode 100644 index 000000000..47aae7ed1 --- /dev/null +++ b/application/controllers/Documents.php @@ -0,0 +1,294 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller handles output and access to documents. + * It creates a XML file, transforms it with the XSL-FO Vorlage from the + * database and generates a PDF file with unoconv or docsbox. + * This file is then outputted as download. + * + * It is the CodeIgniter version of content/pdfExport.php when not using the + * get paremeters: "archivdokument" and "archive". + * Use exportSigned() instead of providing the "sign" get parameter and + * export() otherwise. + */ +class Documents extends Auth_Controller +{ + public function __construct() + { + parent::__construct([ + 'export' => self::PERM_LOGGED, + 'exportSigned' => self::PERM_LOGGED + ]); + + // Load Phrases + $this->loadPhrases([ + 'stv' + ]); + } + + /** + * Download a not signed document. + * + * @param string $xml + * @param string $xsl + * + * @return void + */ + public function export($xml, $xsl) + { + return $this->_export($xml, $xsl); + } + + /** + * Download a signed document. + * + * @param string $xml + * @param string $xsl + * + * @return void + */ + public function exportSigned($xml, $xsl) + { + return $this->_export($xml, $xsl, getAuthUID()); + } + + /** + * Helper function for export() and exportSigned() + * + * @param string $xml + * @param string $xsl + * @param string $sign_user (optional) + * + * @return void + */ + protected function _export($xml, $xsl, $sign_user = null) + { + $xsl_oe_kurzbz = null; + $version = $this->input->post_get('version') ?: null; + + // Get the OE or STG of the document + $xsl_oe_kurzbz = $this->input->post_get('xsl_oe_kurzbz') + ?: $this->input->post_get('xsl_stg_kz') + ?: $this->input->post_get('stg_kz'); + if (is_null($xsl_oe_kurzbz)) { + $uid = $this->input->post_get('uid'); + if ($uid) { + $uid = current(explode(';', $uid)); + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$uid]); + if (!isError($result) && hasData($result)) + $xsl_oe_kurzbz = current(getData($result))->studiengang_kz; + } + } + if (is_null($xsl_oe_kurzbz)) { + $prestudent_id = $this->input->post_get('prestudent_id'); + if ($prestudent_id) { + $prestudent_id = current(explode(';', $prestudent_id)); + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $result = $this->PrestudentModel->load($prestudent_id); + if (!isError($result) && hasData($result)) + $xsl_oe_kurzbz = current(getData($result))->studiengang_kz; + } + } + if (is_null($xsl_oe_kurzbz)) + $xsl_oe_kurzbz = 0; + + // Access rights + if ($xsl == 'AccountInfo') { + $this->load->model('resource/Mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $uids = $this->input->post_get('uid'); + if ($uids) { + $uids = explode(';', $uids); + foreach ($uids as $uid) { + $result = $this->MitarbeiterModel->load($uid); + if (!isError($result) && hasData($result)) { + if (!$this->permissionlib->isBerechtigt('admin', 'suid', 0) + && !$this->permissionlib->isBerechtigt('mitarbeiter', 'suid', 0)) + return $this->_outputAuthError([$this->router->method => ['admin:rw', 'mitarbeiter:rw']]); + } else { + $result = $this->StudentModel->load([$uid]); + if (!isError($result) && hasData($result)) { + $student = current(getData($result)); + if (!$this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz) + && !$this->permissionlib->isBerechtigt('admin', 'suid', 0) + && !$this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz) + && !$this->permissionlib->isBerechtigt('assistenz', 'suid', 0) + && !$this->permissionlib->isBerechtigt('support', 'suid', 0)) + return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw', 'support:rw']]); + } + } + } + } + } else { + $this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel'); + + $result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version); + if (isError($result)) + return show_error(getError($result)); + if (!hasData($result)) + return show_404(); + + $access_rights = current(getData($result))->berechtigung; + if (!$access_rights) + return show_404(); + $allowed = false; + foreach ($access_rights as $access_right) { + if ($this->permissionlib->isBerechtigt($access_right)) { + $allowed = true; + break; + } + } + if (!$allowed) + return $this->_outputAuthError([$this->router->method => $access_rights]); + } + + // Output format + $outputformat = $this->input->post_get('output') ?: 'pdf'; + if ($outputformat != 'pdf' + // An der FHTW darf das Studienblatt und das Prüfungsprotokoll auch in anderen Formaten exportiert werden + && !(CAMPUS_NAME == 'FH Technikum Wien' + && ($xsl == 'Studienblatt' + || $xsl == 'StudienblattEng' + || $xsl == 'PrProtBA' + || $xsl == 'PrProtBAEng' + || $xsl == 'PrProtMA' + || $xsl == 'PrProtMAEng' + ) + ) + && !$this->permissionlib->isBerechtigt('system/change_outputformat', null, $xsl_oe_kurzbz) + ) { + $outputformat = 'pdf'; + } + + // XML Params + $params = 'xmlformat=xml'; + foreach ([ + 'uid', + 'stg_kz', + 'person_id', + 'id', + 'prestudent_id', + 'buchungsnummern', + 'ss', + 'abschlusspruefung_id', + 'typ', + 'all', + 'preoutgoing_id', + 'lvid', + 'projekt_kurzbz', + 'von', + 'bis', + 'stundevon', + 'stundebis', + 'sem', + 'lehreinheit', + 'mitarbeiter_uid', + 'studienordnung_id', + 'fixangestellt', + 'standort', + 'abrechnungsmonat', + 'form', + 'projektarbeit_id', + 'betreuerart_kurzbz', + 'studiensemester_kurzbz' + ] as $key) { + $value = $this->input->post_get($key); + if ($value !== null) + $params .= '&' . $key . '=' . urlencode($value); + } + $value = $this->input->post_get('vertrag_id'); + if ($value !== null) { + foreach ($value as $id) + $params .= '&vertrag_id[]=' . urlencode($id); + } + + $this->load->library('DocumentExportLib'); + $this->load->model('system/Vorlage_model', 'VorlageModel'); + + $result = $this->VorlageModel->load($xsl); + if (isError($result)) + return show_error(getError($result)); + if (!hasData($result)) + show_404(); + + $vorlage = current(getData($result)); + if ($sign_user && !$vorlage->signierbar) + return show_error($this->p->t("stv", "grades_error_sign")); + + + // Filename + $filename = ($vorlage->bezeichnung ?: $vorlage->vorlage_kurzbz); + switch ($xsl) { + case 'LV_Informationen': + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $result = $this->StudiengangModel->load($this->input->post_get('stg_kz')); + if (!isError($result) && hasData($result)) + $filename .= '_' . sanitizeProblemChars(current(getData($result))->kurzbzlang); + + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $result = $this->StudiensemesterModel->load($this->input->post_get('ss')); + if (!isError($result) && hasData($result)) + $filename .= '_' . sanitizeProblemChars(current(getData($result))->studiensemester_kurzbz); + break; + case 'Honorarvertrag': + $uid = str_replace(';', '', $this->input->post_get('uid') ?: ''); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT'); + $result = $this->BenutzerModel->load([$uid]); + if (!isError($result) && hasData($result)) { + $user = current(getData($result)); + $filename .= '_' . sanitizeProblemChars($user->nachname) . '_' . sanitizeProblemChars($user->vorname); + } + break; + case 'Studienordnung': + $filename = 'Studienordnung-Studienplan-'; + + $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel'); + $result = $this->StudienordnungModel->load($this->input->post_get('studienordnung_id')); + if (!isError($result) && hasData($result)) { + $so = current(getData($result)); + $filename .= sprintf("%'.04d", $so->studiengang_kz) . '-' . $so->studiengangkurzbzlang; + } + break; + default: + $uid = str_replace(';', '', $this->input->post_get('uid') ?: ''); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT'); + $result = $this->BenutzerModel->load([$uid]); + if (!isError($result) && hasData($result)) { + $user = current(getData($result)); + $filename .= '_' . sanitizeProblemChars($user->nachname); + } + break; + } + + // XML Data + $result = $this->documentexportlib->getDataURL($xml, $params); + if (isError($result)) + return show_error(getError($result)); + + $data = getData($result); + + // Output + $this->documentexportlib->showContent($filename, $vorlage, $data, $xsl_oe_kurzbz, $version, $outputformat, $sign_user); + } +} diff --git a/application/controllers/Studentenverwaltung.php b/application/controllers/Studentenverwaltung.php index e09d04c6a..2ce19c58a 100644 --- a/application/controllers/Studentenverwaltung.php +++ b/application/controllers/Studentenverwaltung.php @@ -30,7 +30,8 @@ class Studentenverwaltung extends Auth_Controller 'admin' => $this->permissionlib->isBerechtigt('admin'), 'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'), 'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'), - 'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht') + 'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht'), + 'system/change_outputformat' => $this->permissionlib->getOE_isEntitledFor('system/change_outputformat'), ], 'variables' => [ 'semester_aktuell' => $this->variablelib->getVar('semester_aktuell') diff --git a/application/controllers/Test.php b/application/controllers/Test.php deleted file mode 100644 index 2a7aa4e4e..000000000 --- a/application/controllers/Test.php +++ /dev/null @@ -1,16 +0,0 @@ -. + */ + +if (!defined('BASEPATH')) exit('No direct script access allowed'); + +class Ampeln extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'open' => self::PERM_LOGGED, + 'all' => self::PERM_LOGGED, + 'confirm' => self::PERM_LOGGED, + 'alleAmpeln' => self::PERM_LOGGED, + ]); + + $this->load->model('content/Ampel_model', 'AmpelModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * confirms ampel and inserts ampel_id in public.tbl_ampel_benutzer_bestaetigt + * @access public + * + */ + public function confirm($ampel_id) + { + $this->load->library('form_validation'); + $this->form_validation->set_data(['ampel_id'=> $ampel_id]); + $this->form_validation->set_rules('ampel_id', 'Ampel ID', 'required|integer'); + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // load Ampel_benutzer_bestaetigt_model to confirm the ampel + $this->load->model('content/Ampel_Benutzer_Bestaetigt_model', 'AmpelBenutzerBestaetigtModel'); + $insert_into_result = $this->AmpelBenutzerBestaetigtModel->insert(["ampel_id"=> $ampel_id, "uid"=> $this->uid]); + + $insert_into_result = $this->getDataOrTerminateWithError($insert_into_result); + + $this->terminateWithSuccess($insert_into_result); + } + + /** + * queries active and not confirmed ampeln by the user + * @access public + * + */ + public function open() + { + $userAmpeln = array(); + + // fetch active ampeln + $activeAmpeln = $this->AmpelModel->openActive($this->uid, false); + + $activeAmpeln = $this->getDataOrTerminateWithError($activeAmpeln); + + foreach ($activeAmpeln as $ampel) { + // only include non confirmed active ampeln in the result + if (!$ampel->bestaetigt) { + // check if the user was assigned to the ampel + $zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select); + + $zugeteilt = $this->getDataOrTerminateWithError($zugeteilt); + + if($zugeteilt) $userAmpeln[] = $ampel; + } + } + + $this->terminateWithSuccess($userAmpeln); + } + + /** + * queries all ampeln of the user + * @access public + * + */ + public function all() + { + $userAmpeln = array(); + + $ampel_result = $this->AmpelModel->active(false, $this->uid); + + $ampel_result = $this->getDataOrTerminateWithError($ampel_result); + + foreach ($ampel_result as $ampel) { + // check if the ampel was assigned to the user + $zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select); + + $zugeteilt = $this->getDataOrTerminateWithError($zugeteilt); + + if ($zugeteilt) $userAmpeln[] = $ampel; + } + + $this->terminateWithSuccess($userAmpeln); + } + + /** + * queries all ampeln that were assigned to the user until start of first work day + * @access public + * + */ + public function alleAmpeln() + { + + //fetch all ampeln + $alle_ampeln = $this->AmpelModel->alleAmpeln($this->uid); + + $alle_ampeln = $this->getDataOrTerminateWithError($alle_ampeln); + + $alle_ampeln = array_map(function ($ampel) { + // check if ampel is confirmed by user + $confirmedByUser = $this->AmpelModel->isConfirmed($ampel->ampel_id, $this->uid); + $ampel->bestaetigt = $confirmedByUser; + return $ampel; + }, $alle_ampeln); + + $this->terminateWithSuccess($alle_ampeln); + } +} + diff --git a/application/controllers/api/frontend/v1/AuthInfo.php b/application/controllers/api/frontend/v1/AuthInfo.php new file mode 100644 index 000000000..1362aee18 --- /dev/null +++ b/application/controllers/api/frontend/v1/AuthInfo.php @@ -0,0 +1,52 @@ +. + */ + +if (!defined('BASEPATH')) exit('No direct script access allowed'); + +class AuthInfo extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getAuthUID' => self::PERM_LOGGED, + ]); + + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * returns the uid of the currently logged in user + * @access public + * + */ + public function getAuthUID() + { + $this->terminateWithSuccess(['uid'=>$this->uid]); + } + + +} + diff --git a/application/controllers/api/frontend/v1/Bookmark.php b/application/controllers/api/frontend/v1/Bookmark.php new file mode 100644 index 000000000..3e646bb51 --- /dev/null +++ b/application/controllers/api/frontend/v1/Bookmark.php @@ -0,0 +1,138 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +class Bookmark extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getBookmarks' => self::PERM_LOGGED, + 'delete' => self::PERM_LOGGED, + 'insert' => self::PERM_LOGGED, + 'update' => self::PERM_LOGGED, + ]); + + $this->load->model('dashboard/Bookmark_model', 'BookmarkModel'); + + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + + /** + * gets the bookmarks associated to a user + * @access public + * @return void + */ + public function getBookmarks() + { + $this->BookmarkModel->addOrder("bookmark_id"); + $bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]); + + $bookmarks = $this->getDataOrTerminateWithError($bookmarks); + + $this->terminateWithSuccess($bookmarks); + } + + /** + * deletes bookmark from associated user + * @access public + * @return void + */ + public function delete($bookmark_id) + { + $bookmark = $this->BookmarkModel->load($bookmark_id); + + $bookmark = current($this->getDataOrTerminateWithError($bookmark)); + + // only delete bookmark if the user is the owner of the bookmark + if($bookmark->uid == $this->uid || $this->permissionlib->isBerechtigt('admin')){ + + $delete_result = $this->BookmarkModel->delete($bookmark_id); + + $delete_result = $this->getDataOrTerminateWithError($delete_result); + + $this->terminateWithSuccess($delete_result); + }else{ + $this->_outputAuthError(['delete' => ['admin:rw']]); + } + } + + /** + * inserts new bookmark into the bookmark table + * @access public + * @return void + */ + public function insert() + { + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]'); + $this->form_validation->set_rules('title', 'Title', 'required|max_length[255]'); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $url = $this->input->post('url',true); + $title = $this->input->post('title',true); + $tag = $this->input->post('tag', true); + + $insert_into_result = $this->BookmarkModel->insert(['uid'=>$this->uid, 'url'=>$url, 'title'=>$title,'tag'=>$tag, 'insertvon'=>$this->uid, 'updateamum'=>NULL, 'updatevon'=>NULL]); + + $insert_into_result = $this->getDataOrTerminateWithError($insert_into_result); + + $this->terminateWithSuccess($insert_into_result); + + } + + /** + * updates bookmark in the bookmark table + * @access public + * @return void + */ + public function update($bookmark_id) + { + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]'); + $this->form_validation->set_rules('title', 'Title', 'required|max_length[255]'); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $url = $this->input->post('url',true); + $title = $this->input->post('title',true); + + $now = new DateTime(); + $now = $now->format('Y-m-d H:i:s'); + + $update_result = $this->BookmarkModel->update($bookmark_id,['url'=>$url, 'title'=>$title,'updateamum'=>$now]); + + $update_result = $this->getDataOrTerminateWithError($update_result); + + $this->terminateWithSuccess($update_result); + + } +} + diff --git a/application/controllers/api/frontend/v1/Cis4FhcApi.php b/application/controllers/api/frontend/v1/Cis4FhcApi.php new file mode 100644 index 000000000..372e4bfaa --- /dev/null +++ b/application/controllers/api/frontend/v1/Cis4FhcApi.php @@ -0,0 +1,58 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +class Cis4FhcApi extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getViewData' => self::PERM_LOGGED, + ]); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * fetches ViewData + */ + public function getViewData() + { + $this->load->model('person/Person_model','PersonModel'); + $personData = getData($this->PersonModel->getByUid(getAuthUID()))[0]; + + $viewData = array( + 'uid' => getAuthUID(), + 'name' => $personData->vorname, + 'person_id' => $personData->person_id + ); + + $this->terminateWithSuccess($viewData); + } + + + +} + diff --git a/application/controllers/api/frontend/v1/CisMenu.php b/application/controllers/api/frontend/v1/CisMenu.php new file mode 100644 index 000000000..4f4f2573e --- /dev/null +++ b/application/controllers/api/frontend/v1/CisMenu.php @@ -0,0 +1,58 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + + +class CisMenu extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getMenu' => self::PERM_LOGGED, + ]); + + + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * fetches the menu for CIS from the database based on the userLanguage + */ + public function getMenu() + { + $this->load->model('content/Content_model', 'ContentModel'); + $this->load->config('cis'); + $cis4_content_id =$this->config->item('cis_menu_root_content_id'); + $result = $this->ContentModel->getMenu($cis4_content_id, getAuthUID(),getUserLanguage()); + $result = $this->getDataOrTerminateWithError($result); + $menu = $result->childs ?? []; + $this->terminateWithSuccess($menu); + } + + + +} + diff --git a/application/controllers/api/frontend/v1/Cms.php b/application/controllers/api/frontend/v1/Cms.php new file mode 100644 index 000000000..b8937a1f4 --- /dev/null +++ b/application/controllers/api/frontend/v1/Cms.php @@ -0,0 +1,207 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end) + * Provides data to the ajax get calls about the searchbar component + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class Cms extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + // NOTE(chris): additional permission checks will be done in SearchBarLib + parent::__construct([ + 'ContentID' => self::PERM_LOGGED, + 'getOrtKurzbzContent' => self::PERM_LOGGED, + 'content' => self::PERM_LOGGED, + 'news' => self::PERM_LOGGED, + 'getNewsRowCount' => self::PERM_LOGGED, + 'getNews' => self::PERM_LOGGED, + + ]); + + $this->load->model('content/News_model', 'NewsModel'); + + // setting up the papgination_size + $this->page_size = 10; + + $this->load->library('CmsLib'); + + // Loads phrases system + $this->loadPhrases([ + 'global' + ]); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * fetches the content with the content_id and additional parameters + */ + public function content() + { + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('content_id','Content ID','required|is_natural'); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // getting the get parameters + $content_id = $this->input->get("content_id",TRUE); + $version = $this->input->get("version",TRUE); + $sprache = $this->input->get("sprache",TRUE); + $sichtbar = $this->input->get("sichtbar",TRUE); + + $content = $this->cmslib->getContent($content_id, $version, $sprache, $sichtbar); + $content = $this->getDataOrTerminateWithError($content); + + $this->terminateWithSuccess($content); + } + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + public function ContentID() + { + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('ort_kurzbz', 'Ort', 'required'); + if ($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $ort_kurzbz = $this->input->get('ort_kurzbz',TRUE); + + $content_id = $this->OrtModel->getContentID($ort_kurzbz); + + $content_id = current($this->getDataOrTerminateWithError($content_id))->content_id; + + $this->terminateWithSuccess($content_id); + } + + public function news() + { + + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('limit','Limit','required|is_natural_no_zero'); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $this->load->model('content/news_model', 'NewsModel'); + + $limit = $this->input->get('limit',TRUE); + + //query the news + $news = $this->NewsModel->getAll($limit); + + //get the data or terminate with error + $news = $this->getDataOrTerminateWithError($news); + // array that keeps track of which news don't have a betreff and have to be removed from the news array + $newsToRemove = array(); + // collect the content of the news + foreach($news as $index=>$news_element){ + + $this->NewsModel->resetQuery(); + $content = $this->cmslib->getContent($news_element->content_id); + if(isError($content)) + { + // removes the news from the news array, so that the response does not include a invalid news + array_push($newsToRemove,$index); + //add the error to the api response? visual feedback + //$this->addError(print_r($content->retval,true)); + continue; + } + $content = getData($content); + $news_element->content_obj = $content; + } + + //removes all news that don't have a betreff + foreach($newsToRemove as $removeNewsIndex) + { + unset($news[$removeNewsIndex]); + } + + $withContent = function($news) { + return $news->content_obj != null; + }; + $newsWithContent = array_filter($news, $withContent); + $this->terminateWithSuccess($newsWithContent); + + } + + public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10) + { + list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester); + $all = $edit; + + $this->load->model('content/News_model','NewsModel'); + + $num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + + $num_rows = $this->getDataOrTerminateWithError($num_rows); + + $this->terminateWithSuccess($num_rows); + + } + + + public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true) + { + //form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('page','Page','required|is_natural'); + $this->form_validation->set_rules('page_size', 'PageSize', 'is_natural'); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // getting the GET parameters + $page = intval($this->input->get('page', true)); + $page_size = intval($this->input->get('page_size', true)); + $sprache = $this->input->get('sprache', true); + if(!$sprache) + { + $sprache = getUserLanguage(); + } + + // default value for the page_size is 10 + $page_size = $page_size ?? 10; + + $news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size, $sprache); + $news = $this->getDataOrTerminateWithError($news); + + $this->addMeta('phrases', json_decode($this->p->getJson())); + $this->terminateWithSuccess($news); + + } + + +} + diff --git a/application/controllers/api/frontend/v1/Documents.php b/application/controllers/api/frontend/v1/Documents.php new file mode 100644 index 000000000..60010e14d --- /dev/null +++ b/application/controllers/api/frontend/v1/Documents.php @@ -0,0 +1,422 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the back-end + * Provides data to the ajax get calls about documents + * Listens to ajax post calls to change the documents data + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + * + * This controller handles output and access to documents. + * It checks permissions to render documents in an alternative format + * or it creates a XML file, transforms it with the XSL-FO Vorlage from the + * database and generates a PDF file with unoconv or docsbox. + * This file is then archivated in the database. + * + * The last part is the CodeIgniter version of content/pdfExport.php when not + * using the get paremeter: "archivdokument" but using the get parameter: + * "archive". + * Use archiveSigned() instead of providing the "sign" get parameter and + * archive() otherwise. + */ +class Documents extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'permissionAlternativeFormat' => self::PERM_LOGGED, + 'archive' => ['admin:rw', 'assistenz:rw'], + 'archiveSigned' => ['admin:rw', 'assistenz:rw'] + ]); + + // Load Phrases + $this->loadPhrases([ + 'stv' + ]); + } + + /** + * Checks if the current user has permission to render documents in an + * alternative format. + * + * @param string $oe_kurzbz Or studiengang_kz + * + * @return void + */ + public function permissionAlternativeFormat($oe_kurzbz) + { + $this->terminateWithSuccess($this->permissionlib->isBerechtigt('system/change_outputformat', null, $oe_kurzbz)); + } + + /** + * Download a not signed document. + * + * @param string $xml (optional) + * @param string $xsl (optional) + * + * @return void + */ + public function archive($xml = null, $xsl = null) + { + return $this->_archive($xml, $xsl); + } + + /** + * Download a signed document. + * + * @param string $xml (optional) + * @param string $xsl (optional) + * + * @return void + */ + public function archiveSigned($xml = null, $xsl = null) + { + return $this->_archive($xml, $xsl, getAuthUID()); + } + + /** + * Helper function for archive() and archiveSigned() + * + * @param string $xml + * @param string $xsl + * @param string $sign_user (optional) + * + * @return void + */ + public function _archive($xml, $xsl, $sign_user = null) + { + if (!$xml || !$xsl) { + $this->load->library('form_validation'); + if (!$xml) { + $xml = $this->input->post_get('xml'); + $this->form_validation->set_rules('xml', 'xml', 'required'); + } + if (!$xsl) { + $xsl = $this->input->post_get('xsl'); + $this->form_validation->set_rules('xsl', 'xsl', 'required'); + } + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $xsl_oe_kurzbz = null; + $version = $this->input->post_get('version') ?: null; + + // Get the OE or STG of the document + $xsl_oe_kurzbz = $this->input->post_get('xsl_oe_kurzbz') + ?: $this->input->post_get('xsl_stg_kz') + ?: $this->input->post_get('stg_kz'); + if (is_null($xsl_oe_kurzbz)) { + $uid = $this->input->post_get('uid'); + if ($uid) { + $uid = current(explode(';', $uid)); + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$uid]); + if (!isError($result) && hasData($result)) + $xsl_oe_kurzbz = current(getData($result))->studiengang_kz; + } + } + if (is_null($xsl_oe_kurzbz)) { + $prestudent_id = $this->input->post_get('prestudent_id'); + if ($prestudent_id) { + $prestudent_id = current(explode(';', $prestudent_id)); + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $result = $this->PrestudentModel->load($prestudent_id); + if (!isError($result) && hasData($result)) + $xsl_oe_kurzbz = current(getData($result))->studiengang_kz; + } + } + if (is_null($xsl_oe_kurzbz)) + $xsl_oe_kurzbz = 0; + + // Vorlage + $this->load->model('system/Vorlage_model', 'VorlageModel'); + + $result = $this->VorlageModel->load($xsl); + $vorlage = current($this->getDataOrTerminateWithError($result)); + if (!$vorlage) + show_404(); + + // Akte Data + $akteData = [ + 'dokument_kurzbz' => $vorlage->dokument_kurzbz ?: 'Zeugnis', + 'mimetype' => 'application/pdf', + 'erstelltam' => date('Y-m-d'), + 'gedruckt' => true, + 'insertamum' => date('c'), + 'insertvon' => getAuthUID(), + 'uid' => $this->input->post_get('uid') ?: '', + 'archiv' => true, + 'signiert' => !!$sign_user, + 'stud_selfservice' => $vorlage->stud_selfservice + ]; + $studiengang_kz = null; + if ($akteData['uid']) { + $this->load->model('crm/Student_model', 'StudentModel'); + $this->StudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT'); + $result = $this->StudentModel->load([$akteData['uid']]); + $student = current($this->getDataOrTerminateWithError($result)); + + $ss = $this->input->post_get('ss'); + + if ($ss !== null) { + $this->load->model('crm/prestudentstatus_model', 'PrestudentstatusModel'); + $result = $this->PrestudentstatusModel->getLastStatus($student->prestudent_id, $ss); + $status = current($this->getDataOrTerminateWithError($result)); + if (!$status) + $this->terminateWithError($this->p->t("stv", "grades_error_prestudentstatus")); + $semester = $status->ausbildungssemester; + + $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); + $this->StudentlehrverbandModel->addJoin('public.tbl_benutzer', 'uid = student_uid'); + $this->StudentlehrverbandModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); + $result = $this->StudentlehrverbandModel->load([ + 'studiensemester_kurzbz' => $ss, + 'student_uid' => $akteData['uid'] + ]); + $res = current($this->getDataOrTerminateWithError($result)); + + $studiengang_kz = $res->studiengang_kz; + $akteData['person_id'] = $res->person_id; + switch ($xsl) { + case 'Ausbildungsver': + case 'AusbVerEng': + $akteData['titel'] = mb_substr($xsl . + "_" . + strtoupper($res->typ) . + strtoupper($res->kurzbz) . + "_" . + $semester . + "_" . + $ss, 0, 64); + $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64); + break; + case 'LVZeugnisEng': + case 'LVZeugnis': + case 'Zertifikat': + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $result = $this->LehrveranstaltungModel->load($this->input->post_get('lvid')); + $lv = current($this->getDataOrTerminateWithError($result)); + $akteData['dokument_kurzbz'] = $xsl; + $akteData['titel'] = mb_substr($xsl . + "_" . + strtoupper($res->typ) . + strtoupper($res->kurzbz) . + "_" . + $semester . + '_' . + $ss . + '_' . + str_replace(' ', '_', $lv->bezeichnung), 0, 60); + $akteData['bezeichnung'] = mb_substr($xsl . + " " . + strtoupper($res->typ) . + strtoupper($res->kurzbz) . + " " . + $semester . + ". Semester" . + ' ' . + $ss . + ' ' . + $lv->bezeichnung, 0, 64); + break; + case 'SZeugnis': + $akteData['titel'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64); + $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64); + break; + default: + $akteData['titel'] = mb_substr($xsl . + "_" . + strtoupper($res->typ) . + strtoupper($res->kurzbz) . + "_" . + $semester . + "_" . + $ss, 0, 64); + $akteData['bezeichnung'] = mb_substr($xsl . + " " . + strtoupper($res->typ) . + strtoupper($res->kurzbz) . + " " . + $semester . + ". Semester" . + ' ' . + $ss, 0, 64); + break; + } + } else { + $studiengang_kz = $student->studiengang_kz; + $akteData['person_id'] = $student->person_id; + $akteData['titel'] = $vorlage->bezeichnung . '_' . $student->kuerzel; + $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64); + } + } else { + $prestudent_id = $this->input->post_get('prestudent_id'); + if ($prestudent_id) { + $this->load->model('crm/prestudent_model', 'PrestudentModel'); + $this->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT'); + $result = $this->PrestudentModel->load($prestudent_id); + $prestudent = current($this->getDataOrTerminateWithError($result)); + + $studiengang_kz = $prestudent->studiengang_kz; + $akteData['person_id'] = $prestudent->person_id; + $akteData['titel'] = mb_substr($xsl . "_" . $prestudent->kuerzel, 0, 64); + $akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $prestudent->kuerzel, 0, 64); + } + } + + // Access rights + if (!$this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz) + && !$this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz)) + return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]); + if ($xsl == 'AccountInfo') { + $this->load->model('resource/Mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $uids = $this->input->post_get('uid'); + if ($uids) { + $uids = explode(';', $uids); + foreach ($uids as $uid) { + $result = $this->MitarbeiterModel->load($uid); + if (!isError($result) && hasData($result)) { + if (!$this->permissionlib->isBerechtigt('admin', 'suid', 0) + && !$this->permissionlib->isBerechtigt('mitarbeiter', 'suid', 0)) + return $this->_outputAuthError([$this->router->method => ['admin:rw', 'mitarbeiter:rw']]); + } else { + $result = $this->StudentModel->load([$uid]); + if (!isError($result) && hasData($result)) { + $student = current(getData($result)); + if (!$this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz) + && !$this->permissionlib->isBerechtigt('admin', 'suid', 0) + && !$this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz) + && !$this->permissionlib->isBerechtigt('assistenz', 'suid', 0) + && !$this->permissionlib->isBerechtigt('support', 'suid', 0)) + return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw', 'support:rw']]); + } + } + } + } + } else { + $this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel'); + + $result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version); + $access_rights = current($this->getDataOrTerminateWithError($result)); + if (!$access_rights || !$access_rights->berechtigung) + return show_404(); + + $allowed = false; + foreach ($access_rights->berechtigung as $access_right) { + if ($this->permissionlib->isBerechtigt($access_right)) { + $allowed = true; + break; + } + } + if (!$allowed) + return $this->_outputAuthError([$this->router->method => $access_rights]); + } + + // Output format + $outputformat = $this->input->post_get('output') ?: 'pdf'; + if ($outputformat != 'pdf' + // An der FHTW darf das Studienblatt und das Prüfungsprotokoll auch in anderen Formaten exportiert werden + && !(CAMPUS_NAME == 'FH Technikum Wien' + && ($xsl == 'Studienblatt' + || $xsl == 'StudienblattEng' + || $xsl == 'PrProtBA' + || $xsl == 'PrProtBAEng' + || $xsl == 'PrProtMA' + || $xsl == 'PrProtMAEng' + ) + ) + && !$this->permissionlib->isBerechtigt('system/change_outputformat', null, $xsl_oe_kurzbz) + ) { + $outputformat = 'pdf'; + } + + // XML Params + $params = 'xmlformat=xml'; + foreach ([ + 'uid', + 'stg_kz', + 'person_id', + 'id', + 'prestudent_id', + 'buchungsnummern', + 'ss', + 'abschlusspruefung_id', + 'typ', + 'all', + 'preoutgoing_id', + 'lvid', + 'projekt_kurzbz', + 'von', + 'bis', + 'stundevon', + 'stundebis', + 'sem', + 'lehreinheit', + 'mitarbeiter_uid', + 'studienordnung_id', + 'fixangestellt', + 'standort', + 'abrechnungsmonat', + 'form', + 'projektarbeit_id', + 'betreuerart_kurzbz', + 'studiensemester_kurzbz' + ] as $key) { + $value = $this->input->post_get($key); + if ($value !== null) + $params .= '&' . $key . '=' . urlencode($value); + } + $value = $this->input->post_get('vertrag_id'); + if ($value !== null) { + foreach ($value as $id) + $params .= '&vertrag_id[]=' . urlencode($id); + } + + if (!$vorlage->archivierbar) + $this->terminateWithError($this->p->t("stv", "grades_error_archive")); + + if ($sign_user && !$vorlage->signierbar) + $this->terminateWithError($this->p->t("stv", "grades_error_sign")); + + + $this->load->library('DocumentExportLib'); + + // XML Data + $result = $this->documentexportlib->getDataURL($xml, $params); + $data = $this->getDataOrTerminateWithError($result); + $this->documentexportlib->addArchiveToData($data); + + // Output + $result = $this->documentexportlib->getContent($vorlage, $data, $xsl_oe_kurzbz, $version, $outputformat, $sign_user); + + $content = $this->getDataOrTerminateWithError($result); + $akteData['titel'] .= '.pdf'; + $akteData['inhalt'] = base64_encode($content); + + $this->load->model('crm/Akte_model', 'AkteModel'); + $result = $this->AkteModel->insert($akteData); + $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(true); + } +} diff --git a/application/controllers/api/frontend/v1/Filter.php b/application/controllers/api/frontend/v1/Filter.php index 45838fc5f..b195e0012 100644 --- a/application/controllers/api/frontend/v1/Filter.php +++ b/application/controllers/api/frontend/v1/Filter.php @@ -113,7 +113,7 @@ class Filter extends FHCAPI_Controller */ public function applyFilterFields() { - $this->form_validation->set_rules('filterFields', 'filterFields', 'required'); + $this->form_validation->set_rules('filterFields[]', 'filterFields', 'required'); if (!$this->form_validation->run()) $this->terminateWithValidationErrors($this->form_validation->error_array()); diff --git a/application/controllers/api/frontend/v1/Lehre.php b/application/controllers/api/frontend/v1/Lehre.php new file mode 100644 index 000000000..f079a5b37 --- /dev/null +++ b/application/controllers/api/frontend/v1/Lehre.php @@ -0,0 +1,103 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + + +class Lehre extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'lvStudentenMail' => self::PERM_LOGGED, + 'LV' => self::PERM_LOGGED, + 'Pruefungen' => self::PERM_LOGGED, + ]); + + + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * constructs the emails of the groups from a lehrveranstaltung + */ + public function lvStudentenMail() + { + $lehreinheit_id = $this->input->get("lehreinheit_id",TRUE); + + // return early if the required parameter is missing + if(!isset($lehreinheit_id)) + { + $this->terminateWithError('Missing required parameter', self::ERROR_TYPE_GENERAL); + } + + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + $studentenMails = $this->LehreinheitModel->getStudentenMail($lehreinheit_id); + + $studentenMails = $this->getDataOrTerminateWithError($studentenMails); + + //convert array of objects into array of strings + $studentenMails = array_map(function($element){ + return $element->mail; + }, $studentenMails); + + $this->terminateWithSuccess($studentenMails); + } + + public function LV($studiensemester_kurzbz, $lehrveranstaltung_id) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage(), $lehrveranstaltung_id); + + $result = current($this->getDataOrTerminateWithError($result)); + + $this->terminateWithSuccess($result); + } + + /** + * fetches all Pruefungen of a student for a specific lehrveranstaltung + * if the student passed the Pruefung on the first attempt, no information about the Pruefungen is stored in the database + * @param mixed $lehrveranstaltung_id + * @return void + */ + public function Pruefungen($lehrveranstaltung_id) + { + $this->load->model('education/Pruefung_model', 'PruefungModel'); + + $result = $this->PruefungModel->getByStudentAndLv(getAuthUID(), $lehrveranstaltung_id, getUserLanguage()); + + $result = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($result); + } + + + + + +} + diff --git a/application/controllers/api/frontend/v1/LvMenu.php b/application/controllers/api/frontend/v1/LvMenu.php new file mode 100644 index 000000000..393c4d5c3 --- /dev/null +++ b/application/controllers/api/frontend/v1/LvMenu.php @@ -0,0 +1,534 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + + +use CI3_Events as Events; + +/** + * This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end) + * Provides data to the ajax get calls about the searchbar component + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class LvMenu extends FHCAPI_Controller +{ + + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getLvMenu' => self::PERM_LOGGED + ]); + + $this->load->model("ressource/Mitarbeiter_model"); + $this->load->model("education/Lehreinheit_model"); + $this->load->model("education/Lehrveranstaltung_model"); + $this->load->model("organisation/Studiengang_model"); + $this->load->model("accounting/Vertrag_model"); + $this->load->model("system/Variable_model"); + $this->load->model("person/Benutzergruppe_model"); + $this->load->model("education/Lvangebot_model"); + $this->load->model("ressource/Lehretools_model"); + + $this->load->library("PermissionLib", null, 'PermissionLib'); + + $this->load->library("PhrasesLib"); + $this->loadPhrases(array('global', 'lehre')); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + + /** + * alternative function to get multiple lvMenus with a single http request + */ + public function getMultipleLvMenu($lvMenuOptionList){ + $result =[]; + foreach($lvMenuOptionList as $lvMenuOptions){ + $lvMenu = $this->getLvMenu($lvMenuOptions['lvid'],$lvMenuOptions['studiensemester_kurzbz']); + if(isError($lvMenu)){ + // TODO: some lvMenu threw an error, handle error here + } + $result[$lvMenuOptions['lvid']]=$lvMenu; + } + $this->terminateWithSuccess($result); + } + + /** + * + */ + public function getLvMenu($lvid, $studiensemester_kurzbz) + { + + // return early if parameters are missing + if(!isset($lvid) || !isset($studiensemester_kurzbz)) + $this->terminateWithError('Missing parameters', self::ERROR_TYPE_GENERAL); + + // get the sprache + $sprache = getUserLanguage(); + + // get the user + if (!$user=getAuthUID()) + $this->terminateWithError($this->p->t('global', 'nichtAngemeldet')); + + // check if is_lector + $is_lector = false; + $mares = $this->Mitarbeiter_model->isMitarbeiter($user); + if(hasData($mares)) + { + $is_lector = getData($mares); + } + + // definition of user_is_allowed_to_upload + $user_is_allowed_to_upload=false; + $angezeigtes_stsem = $studiensemester_kurzbz; + + // load lehrveranstaltung + $lvres = $this->Lehrveranstaltung_model->load($lvid); + if(!hasData($lvres)) + { + $this->terminateWithError('LV ' . $lvid . ' not found.'); + } + $lv = (getData($lvres))[0]; + $this->addMeta('lvInfo',$lv); + // define studiengang_kz / semester / lehrverzeichnis + $studiengang_kz = $lv->studiengang_kz; + $semester = $lv->semester; + $short = $lv->lehreverzeichnis; + // return empty menu for studiengang_kz = 0 + if($studiengang_kz == 0){ + $this->terminateWithSuccess("organisatorische_einheit"); + } + + // load studiengang + $stgres = $this->Studiengang_model->load(strval($studiengang_kz)); + if(!hasData($stgres)) + { + $this->terminateWithError('Stg ' . $lv->studiengang_kz . ' not found.'); + } + $stg = (getData($stgres))[0]; + $kurzbz = strtoupper($stg->typ . $stg->kurzbz); + + $short_name = $lv->bezeichnung; + $short_short_name = $lv->lehreverzeichnis; + + // angemeldet + $angemeldet = true; + if(defined('CIS_LEHRVERANSTALTUNG_WENNANGEMELDET_DETAILS_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_WENNANGEMELDET_DETAILS_ANZEIGEN && !$is_lector) + { + $angemeldet = false; + + $lesres = $this->Lehreinheit_model->getLehreinheitenForStudentAndStudienSemester( + $lvid, $user, $angezeigtes_stsem + ); + + if(hasData($lesres) && count(getData($lesres)) > 0) + $angemeldet = true; + } + + // lehrfach + $lehrfach_id=''; + + if(defined('CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN) + { + // Wenn der eingeloggte User zu einer der Lehreinheiten zugeteilt ist + // wird zusätzlich das Lehrfach der Lehreinheit angezeigt. + if($is_lector ) + { + $result = $this->Lehreinheit_model->getLehrfachIdMitarbeiter($angezeigtes_stsem,$user,$lvid); + } + else + { + $result = $this->Lehreinheit_model->getLehrfachIdStudierender($angezeigtes_stsem,$user,$lvid); + } + + // Wenn die LV mehrere verschiedenen Lehrfaecher hat, und der User zu mehreren davon zugeteilt ist + // wird das Lehrfach nicht angezeigt damit es nicht zu verwirrungen kommt. + if( ($lehrfaecher = getData($result)) && count($lehrfaecher)==1 && ($lehrfach = $lehrfaecher[0])) + { + $lehrfach_id=$lehrfach->lehrfach_id; + } + } + + // lektor der lv + $lektor_der_lv=false; + + $leinfores = $this->Lehreinheit_model->getLehreinheitInfo($lvid,$angezeigtes_stsem,$lehrfach_id); + $db_result = hasData($leinfores) ? getData($leinfores) : array(); + + foreach($db_result as $row_lector) + { + + // Lektor wird erst angezeigt wenn der Auftrag erteilt wurde + if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON') + && CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '') + { + if (!$this->Vertrag_model->isVertragErteiltLV($lvid, $angezeigtes_stsem, $row_lector->uid)) + { + continue; + } + } + + + if($user == $row_lector->uid) + { + $lektor_der_lv=true; + $user_is_allowed_to_upload=true; + } + + // style of the link + if($row_lector->lvleiter === true) + $style='style="font-weight: bold"'; + else + $style=''; + + } + + //Berechtigungen auf Fachbereichsebene + $lehrfach_oe_kurzbz_arr = array(); + $fbres = $this->Lehrveranstaltung_model->getBerechtigungenAufFachberechsebene($lvid, $angezeigtes_stsem); + $fbs = (hasData($fbres)) ? getData($fbres) : array(); + foreach($fbs as $row) + { + $lehrfach_oe_kurzbz_arr[] = $row->oe_kurzbz; + if($this->PermissionLib->isBerechtigt('lehre', null, $row->oe_kurzbz) + || $this->PermissionLib->isBerechtigt('assistenz', null, $stg->oe_kurzbz)) + { + $user_is_allowed_to_upload=true; + } + } + + // FH-Core Menu Logic + // ########################################################################################## + + $menu = array(); + + $this->fhc_menu_lvinfo($menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr); + + $this->fhc_menu_feedback($menu, $angemeldet, $lvid); + + $this->fhc_menu_gesamtnote($menu, $angemeldet, $lvid, $lv, $is_lector, $angezeigtes_stsem); + + $this->fhc_menu_emailStudierende($menu, $user, $angemeldet, $lvid, $angezeigtes_stsem); + + $this->fhc_menu_abmeldung($menu, $user, $is_lector, $lvid, $angezeigtes_stsem); + + $this->fhc_menu_lehretools($menu, $lvid, $angezeigtes_stsem, $sprache); + + $this->fhc_menu_anrechnungStudent($menu, $lvid, $angezeigtes_stsem); + + $this->fhc_menu_anrechnungLector($menu, $angezeigtes_stsem); + + + // Addons Menu Logic + // ########################################################################################## + + $params = [ + 'sprache'=>$sprache, + //'p'=>$p, + 'ci_p'=> $this->p, + //'db'=>$db, + 'user'=>$user, + 'is_lector'=>$is_lector, + 'user_is_allowed_to_upload'=>$user_is_allowed_to_upload, + //'rechte'=>$rechte, + 'angezeigtes_stsem'=>$angezeigtes_stsem, + //'lehreinheit'=>$lehreinheit, + 'lv_obj'=>$lv, + 'lv'=>$lv, + 'lvid'=>$lvid, + 'studiengang_kz'=>$studiengang_kz, + 'semester'=>$semester, + 'short'=>$short, + 'stg_obj'=>$stg, + 'kurzbz'=>$kurzbz, + 'short_name'=>$short_name, + 'short_short_name'=>$short_short_name, + //'dir_name'=>$dir_name, + 'angemeldet'=>$angemeldet, + 'lehrfach_id'=>$lehrfach_id, + 'lektor_der_lv'=>$lektor_der_lv, + 'lehrfach_oe_kurzbz_arr'=>$lehrfach_oe_kurzbz_arr, + ]; + + Events::trigger('lvMenuBuild', + // passing $menu per reference + function & () use (&$menu) { + return $menu; + }, + $params + ); + + // Menu sortieren + // ########################################################################################## + + foreach ($menu as $key => $row){ + + // removes menu points that are not needed in the c4 lvUebersicht + if( !array_key_exists('c4_link',$row) || !array_key_exists('c4_icon',$row)){ + unset($menu[$key]); + continue; + } + + // fills pos array to sort the menu + $pos[$key] = $row['position']; + + } + + array_multisort($pos, SORT_ASC, SORT_NUMERIC, $menu); + + // HTTP response + // ########################################################################################## + + $this->terminateWithSuccess($menu); + + } + + private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr){ + + // LVINFO + if(!defined('CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN) + { + $c4_linkList=array(); + + // Bearbeiten Button anzeigen wenn Lektor der LV und bearbeiten fuer Lektoren aktiviert ist + // Oder Berechtigung zum Bearbeiten eingetragen ist + if((!defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && $lektor_der_lv) + || (defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT==true && $lektor_der_lv) + || $this->PermissionLib->isBerechtigt('lehre/lvinfo',$studiengang_kz) + || $this->PermissionLib->isBerechtigtMultipleOe('lehre/lvinfo', $lehrfach_oe_kurzbz_arr) + ) + { + $c4_linkList[]= [$this->p->t('lehre', 'lvInfoBearbeiten'), 'ects/index.php?lvid='.$lvid]; + } + elseif ($is_lector) + { + $c4_linkList[]= ["Bearbeiten der LV-Infos derzeit gesperrt",'#']; + } + + $menu[]=array + ( + 'id'=>'core_menu_lvinfo', + 'position'=>'10', + 'name'=>$this->p->t('lehre', 'lehrveranstaltungsinformation'), + 'icon'=>'../../../skin/images/button_lvinfo.png', + 'link'=>'', + 'c4_icon'=> base_url('skin/images/button_lvinfo.png'), + 'c4_link'=>'', + 'c4_linkList'=>$c4_linkList + ); + } + } + + private function fhc_menu_feedback(&$menu, $angemeldet, $lvid){ + //FEEDBACK + if((!defined('CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN) && $angemeldet) + { + $menu[]=array + ( + 'id'=>'core_menu_feedback', + 'position'=>'60', + 'name'=>$this->p->t('lehre', 'feedback'), + 'c4_icon'=> base_url('skin/images/button_feedback.png'), + 'c4_link'=> base_url('feedback.php?lvid='.$lvid), + ); + } + } + + private function fhc_menu_gesamtnote(&$menu, $angemeldet, $lvid, $lv_obj, $is_lector, $angezeigtes_stsem){ + //Gesamtnote + if($is_lector && ((!defined('CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN) && $angemeldet)) + { + if($lv_obj->benotung) + { + $menu[]=array + ( + 'id'=>'core_menu_gesamtnote', + 'position'=>'80', + 'name'=>$this->p->t('lehre', 'gesamtnote'), + 'c4_icon'=> base_url('skin/images/button_endnote.png'), + 'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)) + //'c4_link'=> base_url('benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)) + ); + } + else + { + $menu[]=array + ( + 'id'=>'core_menu_gesamtnote', + 'position'=>'80', + 'name'=>$this->p->t('lehre', 'gesamtnote'), + 'c4_icon'=>base_url('skin/images/button_endnote.png'), + 'c4_link'=>'#', + 'c4_linkList'=>[[$this->p->t('lehre', 'noteneingabedeaktiviert'),'#']], + ); + } + } + } + + + + private function fhc_menu_emailStudierende(&$menu, $user, $angemeldet, $lvid, $angezeigtes_stsem){ + // Email an Studierende + if((!defined('CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN) && $angemeldet) + { + $mailto='mailto:'; + $c4_linkList=array(); + + $studentMailsRes = $this->Lehrveranstaltung_model->getStudentEMail($lvid, $angezeigtes_stsem); + + // get the data of the database result and map the array of objects to their object property + $studentMails = $this->getDataOrTerminateWithError($studentMailsRes, 'No student mails found'); + + + $nomail=''; + $variablesres = $this->Variable_model->getVariables($user); + $variables = (hasData($variablesres)) ? getData($variablesres) : array(); + + foreach ($studentMails as $row) + { + if($row->gruppe_kurzbz != '') + { + $bngrp_uids = $this->Benutzergruppe_model->getUids($row->gruppe_kurzbz, $angezeigtes_stsem); + if(count($bngrp_uids) > 0) + { + if(!$row->mailgrp) + { + $nomail = $row->gruppe_kurzbz . ' '; + } + else + { + $mailto .= mb_strtolower($row->gruppe_kurzbz . '@' + . DOMAIN . $variables['emailadressentrennzeichen']); + } + } + } + else + { + $mailto .= mb_strtolower($row->stg_typ . $row->stg_kurzbz + . $row->semester . trim($row->verband) . trim($row->gruppe) + . '@' . DOMAIN . $variables['emailadressentrennzeichen']); + } + } + + if($nomail != '') + { + $c4_linkList[] = array( + $this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)), + '#' + ); + $link_onclick = 'alert(\''.$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)) . '\');'; + } + else + { + $link_onclick = ''; + } + + + $menu[]=array + ( + 'id'=>'core_menu_mailanstudierende', + 'position'=>'100', + 'name'=>$this->p->t('lehre', 'mail'), + 'c4_icon'=>base_url('skin/images/button_feedback.png'), + 'c4_icon2' => 'fa-regular fa-envelope', + 'c4_link'=>$mailto, + 'c4_linkList'=>$c4_linkList, + 'link_onclick'=>$link_onclick + ); + } + } + + + + private function fhc_menu_abmeldung(&$menu, $user, $is_lector, $lvid, $angezeigtes_stsem){ + if(!defined('CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN) + { + if(!$is_lector) + { + $gruppen = $this->Lvangebot_model->AbmeldungMoeglich($lvid, $angezeigtes_stsem, $user); + if(count($gruppen) > 0) + { + $menu[]=array + ( + 'id'=>'core_menu_abmeldung', + 'position'=>'120', + 'name'=>$this->p->t('lehre', 'abmelden'), + 'c4_icon'=>base_url('skin/images/button_studiupload.png'), + 'c4_link'=>base_url('abmeldung.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)), + ); + + } + } + } + } + + private function fhc_menu_lehretools(&$menu, $lvid, $angezeigtes_stsem, $sprache){ + //Anzeigen von zusaetzlichen Lehre-Tools + $lehretools = $this->Lehretools_model->getTools($lvid, $angezeigtes_stsem, $sprache); + foreach($lehretools as $row) + { + $menu[] = array( + 'id' => 'core_menu_lehretools_' . $row->lehre_tools_id, + 'position' => '1000', + 'name' => $row->bezeichnung, + 'c4_icon' => base_url('cms/dms.php?id='.$row->logo_dms_id), + 'c4_link' => $row->basis_url, + ); + } + } + + private function fhc_menu_anrechnungStudent(&$menu, $lvid, $angezeigtes_stsem){ + // Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer Studenten + if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN) + && $this->PermissionLib->isBerechtigt('student/anrechnung_beantragen')) + { + $menu[]=array + ( + 'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse', + 'position' => '128', + 'name' => $this->p->t('lehre', 'anrechnung'), + 'c4_icon' => base_url('skin/images/button_listen.png'), + 'c4_icon2' => 'fa-regular fa-folder-open', + 'c4_link' => base_url('cis.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid)) + ); + } + } + + private function fhc_menu_anrechnungLector(&$menu, $angezeigtes_stsem){ + // Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer LektorInnen + if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN) + && $this->PermissionLib->isBerechtigt('lehre/anrechnung_empfehlen')) + { + $menu[]=array + ( + 'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen', + 'position' => '128', + 'name' => $this->p->t('lehre', 'anrechnungen'), + 'c4_icon'=> base_url('skin/images/button_listen.png'), + 'c4_icon2' => 'fa-regular fa-folder-open', + 'c4_link' => base_url('cis.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem)) + ); + } + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/Ort.php b/application/controllers/api/frontend/v1/Ort.php new file mode 100644 index 000000000..8c4059824 --- /dev/null +++ b/application/controllers/api/frontend/v1/Ort.php @@ -0,0 +1,95 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end) + * Provides data to the ajax get calls about the searchbar component + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class Ort extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + // NOTE(chris): additional permission checks will be done in SearchBarLib + parent::__construct([ + 'ContentID' => self::PERM_LOGGED, + 'getOrtKurzbzContent' => self::PERM_LOGGED, + ]); + + $this->load->model('ressource/Ort_model', 'OrtModel'); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + public function ContentID() + { + // if error + //$this->terminateWithError(SearchBarLib::ERROR_WRONG_JSON, self::ERROR_TYPE_GENERAL); + + $ort_kurzbz = $this->input->get('ort_kurzbz',TRUE); + + if(!$ort_kurzbz){ + $this->terminateWithError("missing ort_kurzbz parameter", self::ERROR_TYPE_GENERAL); + } + + $result = $this->OrtModel->getContentID($ort_kurzbz); + + if(isError($result)){ + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + + $result = hasData($result) ? current(getData($result)) : null; + + $this->terminateWithSuccess($result->content_id ?? NULL); + } + + /** + * @param int $version + * @param string $sprache + * @param boolean $sichtbar + * + * @return $content + */ + public function getOrtKurzbzContent($version = null, $sprache = null, $sichtbar = true) + { + $content_id = $this->input->get("content_id",TRUE); + + $this->load->library('CmsLib'); + + $content = $this->cmslib->getContent($content_id, $version, $sprache, $sichtbar); + + if (isError($content)) + $this->terminateWithError(getError($content), self::ERROR_TYPE_GENERAL); + + $content = hasData($content) ? getData($content) : null; + + $this->terminateWithSuccess($content); + } +} + diff --git a/application/controllers/api/frontend/v1/Phrasen.php b/application/controllers/api/frontend/v1/Phrasen.php index 472308d2b..7cc652c71 100644 --- a/application/controllers/api/frontend/v1/Phrasen.php +++ b/application/controllers/api/frontend/v1/Phrasen.php @@ -28,8 +28,13 @@ class Phrasen extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'loadModule' => self::PERM_ANONYMOUS + 'loadModule' => self::PERM_ANONYMOUS, + 'setLanguage' => self::PERM_ANONYMOUS, + 'getLanguage' => self::PERM_ANONYMOUS, + 'getAllLanguages' => self::PERM_ANONYMOUS, ]); + + $this->load->helper('hlp_language'); } //------------------------------------------------------------------------------------------------------------------ @@ -43,4 +48,48 @@ class Phrasen extends FHCAPI_Controller $this->load->library('PhrasesLib', [$module], 'pj'); $this->terminateWithSuccess(json_decode($this->pj->getJSON())); } -} + + public function setLanguage() + { + $postParams = $this->getPostJSON(); + $language = $postParams->language; + $categories = $postParams->categories; + + setUserLanguage($language); + + $this->load->library('PhrasesLib', array($categories, $language), 'p'); + + $phrases = $this->p->setPhrases($categories, $language); + $this->terminateWithSuccess($phrases); + } + + // gets the langauge of the currently logged in user session and otherwhise the system language + public function getLanguage() + { + $lang = getUserLanguage(); + $this->terminateWithSuccess($lang); + } + + // gets all languages that are set as active in the database + public function getAllLanguages() + { + $this->load->model('system/Sprache_model', 'SprachenModel'); + + // Add order clause by index and select the sprache,bezeichnung and index column + $this->SprachenModel->addOrder('index'); + $this->SprachenModel->addSelect('sprache, bezeichnung, index'); + + // Retrieves from public.tbl_sprache + $langs = $this->SprachenModel->loadWhere(array('content' => true)); + $langs = $this->getDataOrTerminateWithError($langs); + $langs = array_map(function($lang){ + $data = new stdClass(); + $data->sprache = $lang->sprache; + $data->bezeichnung = $lang->bezeichnung[($lang->index-1)]; + return $data; + }, $langs); + + $this->terminateWithSuccess($langs); + } + +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/Profil.php b/application/controllers/api/frontend/v1/Profil.php new file mode 100644 index 000000000..c52d8bae5 --- /dev/null +++ b/application/controllers/api/frontend/v1/Profil.php @@ -0,0 +1,695 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +class Profil extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getView' => self::PERM_LOGGED, + 'fotoSperre' => self::PERM_LOGGED, + 'getGemeinden' => self::PERM_LOGGED, + 'getAllNationen' => self::PERM_LOGGED, + 'isMitarbeiter' => self::PERM_LOGGED, + + ]); + + $this->load->library('PermissionLib'); + + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('person/Adresse_model', 'AdresseModel'); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); + $this->load->model('content/DmsVersion_model', 'DmsVersionModel'); + + + //? put the uid and pid inside the controller for reusability + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + + /** + * function that returns the data used for the corresponding view + * the client side parses the @param $uid and calls this function to get the data to the correct view + * @access public + * @param boolean $uid the userID used to identify which information should be retrieved for which view + * @return stdClass all the data corresponding to a view of a user + */ + public function getView($uid) + { + $res = new stdClass(); + $editAllowed = getAuthUID() == $uid || $this->permissionlib->isBerechtigt('admin'); + + // if parsing the URL did not found a UID then the UID of the logged in user is used + if ($uid == "Profil" || $uid == $this->uid) { + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid); + if (isError($isMitarbeiter)) { + show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter"); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "MitarbeiterProfil"; + $res->data = $this->mitarbeiterProfil(); + $res->data->pid = $this->pid; + } else { + $res->view = "StudentProfil"; + $res->data = $this->studentProfil(); + $res->data->pid = $this->pid; + } + // editing your own profil - true + $editAllowed = true; + } + // UID is availabe when accessing Profil/View/:uid + else { + $this->PersonModel->addSelect(["person_id"]); + $pid = $this->PersonModel->getByUid($uid); + if (isError($pid)) { + show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid); + } + $pid = hasData($pid) ? getData($pid)[0] : null; + if (!$pid) { + show_error("Person with UID: " . $uid . " does not exist"); + } + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($isMitarbeiter)) { + show_error("error while checking if UID: " . $uid . " is a mitarbeiter"); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "ViewMitarbeiterProfil"; + $res->data = $this->viewMitarbeiterProfil($uid); + + } else { + $res->view = "ViewStudentProfil"; + $res->data = $this->viewStudentProfil($uid); + } + } + $res->data->editAllowed = $editAllowed; + $this->terminateWithSuccess($res); + } + + /** + * update column foto_sperre in public.tbl_person + * @access public + * @param boolean $value new value for the column + * @return boolean the new value added to the column in public.tbl_person + */ + public function fotoSperre($value) + { + if(!isset($value)){ + $this->terminateWithError("Missing parameter", self::ERROR_TYPE_GENERAL); + } + + $res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]); + if (isError($res)) { + show_error("error while trying to update table public.tbl_person"); + } + $this->PersonModel->addSelect("foto_sperre"); + $res = $this->PersonModel->load($this->pid); + if (isError($res)) { + show_error("error while trying to query table public.tbl_person"); + } + + $res = $this->getDataOrTerminateWithError($res); + + $this->terminateWithSuccess(current($res)); + } + + /** + * gets all nations in the table bis.tbl_nation + * + * @access public + * @return array all the nations in table bis.tbl_nation + */ + public function getAllNationen() + { + // load the nationen from the database + $this->load->model('codex/Nation_model', "NationModel"); + $this->NationModel->addSelect(["nation_code as code", "langtext"]); + $nation_res = $this->NationModel->load(); + + if (isError($nation_res)) { + $this->terminateWithError("error while trying to query table codex.tbl_nation", self::ERROR_TYPE_GENERAL); + } + + $nation_res = $this->getDataOrTerminateWithError($nation_res); + + $this->terminateWithSuccess($nation_res); + } + + public function getGemeinden($nation, $zip) + { + if(!isset($nation) || !isset($zip)){ + echo json_encode(error("Missing parameters")); + return; + } + + $this->load->model('codex/Gemeinde_model', "GemeindeModel"); + + + $gemeinde_res = $this->GemeindeModel->getGemeindeByPlz($zip); + + if (isError($gemeinde_res)) { + $this->terminateWithError(getError($gemeinde_res),self::ERROR_TYPE_GENERAL); + } + $gemeinde_res = $this->getDataOrTerminateWithError($gemeinde_res); + + /* $gemeinde_res = array_map(function ($obj) { + return $obj->ortschaftsname; + }, $gemeinde_res); */ + + $this->terminateWithSuccess($gemeinde_res); + + } + + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * function that returns the data used for viewing another mitarbeiter profile + * @access private + * @param integer $uid the userID to retrieve the mitarbeiter data + * @return stdClass restricted mitarbeiter data + */ + private function viewMitarbeiterProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $benutzer_funktion_res = $this->getBenutzerFunktion($uid); + $benutzer_res = $this->getBenutzerAlias($uid); + $person_res = $this->getPersonInfo($uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($uid); + $telefon_res = $this->getTelefonInfo($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Info + foreach ($person_res as $key => $val) { + $res->$key = $val; + } + + //? Mitarbeiter Info + foreach ($mitarbeiter_res as $key => $val) { + $res->$key = $val; + + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $uid . "@" . DOMAIN; + $extern_email = array(); + $extern_email["type"] = "alias"; + $extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN; + $res->emails = array($intern_email, $extern_email); + + $res->funktionen = $benutzer_funktion_res; + $res->mailverteiler = $mailverteiler_res; + $res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null; + + return $res; + } + + /** + * function that returns the data used for viewing another student profile + * @access private + * @param integer $uid the userID to retrieve the student data + * @return stdClass restricted student data + */ + private function viewStudentProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $person_res = $this->getPersonInfo($uid); + $student_res = $this->getStudentInfo($uid); + $matr_res = $this->getMatrikelNummer($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = $value; + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $uid . "@" . DOMAIN; + + $res->emails = [$intern_email]; + $res->matrikelnummer = $matr_res->matr_nr; + $res->mailverteiler = $mailverteiler_res; + + return $res; + } + + /** + * checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php) + * @access public + * @param $uid the userID used to check if it is a mitarbeiter + * @return boolean + */ + public function isMitarbeiter($uid) + { + + if(!$uid) $this->terminateWithError("No uid provided", self::ERROR_TYPE_GENERAL); + + + $result = $this->MitarbeiterModel->isMitarbeiter($uid); + + if (isError($result)) { + $this->terminateWithError("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid, self::ERROR_TYPE_GENERAL); + } + + $result = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($result); + } + + /** + * function that returns the data used for the mitarbeiter profile + * @access private + * @return stdClass mitarbeiter data + */ + private function mitarbeiterProfil() + { + + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); + $adresse_res = $this->getAdressenInfo($this->pid); + $kontakte_res = $this->getKontaktInfo($this->pid); + $mailverteiler_res = $this->getMailverteiler($this->uid); + $person_res = $this->getPersonInfo($this->uid, true); + $benutzer_funktion_res = $this->getBenutzerFunktion($this->uid); + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); + $profilUpdates = $this->getProfilUpdates($this->uid); + $telefon_res = $this->getTelefonInfo($this->uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($this->uid); + + $res = new stdClass(); + $res->username = $this->uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Mitarbeiter Information + foreach ($mitarbeiter_res as $key => $value) { + $res->$key = $value; + } + + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->mailverteiler = $mailverteiler_res; + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $this->uid . "@" . DOMAIN; + $extern_email = array(); + $extern_email["type"] = "alias"; + $extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN; + $res->emails = [$intern_email, $extern_email]; + + $res->funktionen = $benutzer_funktion_res; + $res->standort_telefon = $telefon_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * function that returns the data used for the student profile + * @access private + * @return stdClass student data + */ + private function studentProfil() + { + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); + $kontakte_res = $this->getKontaktInfo($this->pid); + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); + $adresse_res = $this->getAdressenInfo($this->pid); + $mailverteiler_res = $this->getMailverteiler($this->uid); + $person_res = $this->getPersonInfo($this->uid, true); + $zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid); + $student_res = $this->getStudentInfo($this->uid); + $matr_res = $this->getMatrikelNummer($this->uid); + $profilUpdates = $this->getProfilUpdates($this->uid); + + $res = new stdClass(); + $res->username = $this->uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = trim($value); + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = $this->uid . "@" . DOMAIN; + + $res->emails = [$intern_email]; + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->matrikelnummer = $matr_res->matr_nr; + $res->zuttritsgruppen = $zutrittsgruppe_res; + $res->mailverteiler = $mailverteiler_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + + /** + * gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe + * @access private + * @param integer $uid the userID used to retrieve the mailverteiler + * @return array returns the mailvertailer corresponding to a userID + */ + private function getMailverteiler($uid) + { + $this->PersonModel->addSelect('gruppe_kurzbz, beschreibung'); + $this->PersonModel->addJoin('tbl_benutzer', 'person_id'); + $this->PersonModel->addJoin('tbl_benutzergruppe', 'uid'); + $this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid)); + if (isError($mailverteiler_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res)); + } + $mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null; + $mailverteiler_res = array_map(function ($element) { + $element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN; + return $element; + }, $mailverteiler_res); + return $mailverteiler_res; + } + + /** + * gets all the Benutzerfunktionen of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Benutzerfunktionen + * @return array returns the Benutzerfunktionen corresponding to a userID + */ + private function getBenutzerFunktion($uid) + { + $this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]); + $this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz"); + + $benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid)); + if (isError($benutzer_funktion_res)) { + show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res)); + } + $benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null; + return $benutzer_funktion_res; + } + + /** + * gets all the Betriebsmittel of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Betriebsmittel + * @return array returns the Betriebsmittel corresponding to a userID + */ + private function getBetriebsmittelInfo($pid) + { + $this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]); + + //? betriebsmittel are not needed in a view + $betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid); + if (isError($betriebsmittelperson_res)) { + show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res)); + } + $betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null; + return $betriebsmittelperson_res; + } + + /** + * gets the alias of a corresponding user + * @access private + * @param integer $uid the userID used to get the alias + * @return string the alias of the userID + */ + private function getBenutzerAlias($uid) + { + $this->BenutzerModel->addSelect(["alias"]); + $benutzer_res = $this->BenutzerModel->load([$uid]); + if (isError($benutzer_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res)); + } else { + $benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null; + } + + return $benutzer_res; + } + + /** + * gets the person information corresponding to a user + * @access private + * @param integer $uid the userID used to get the person information + * @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not + * @return array all the person informaion corresponding to a userID + */ + private function getPersonInfo($uid, $geburtsInfo = null) + { + $selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"]; + /** @param integer $geburtsInfo */ + if ($geburtsInfo) { + array_push($selectClause, "gebort"); + array_push($selectClause, "TO_CHAR(gebdatum, 'DD.MM.YYYY') as gebdatum"); + } + $this->BenutzerModel->addSelect($selectClause); + $this->BenutzerModel->addJoin("tbl_person", "person_id"); + + $person_res = $this->BenutzerModel->load([$uid]); + if (isError($person_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res)); + } else { + $person_res = hasData($person_res) ? getData($person_res)[0] : null; + } + + if( ($person_res->foto === null) || (($this->uid !== $uid) && ($person_res->foto_sperre !== false)) ) + { + $dummy_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg')); + $person_res->foto = $dummy_foto; + } + + return $person_res; + } + + /** + * gets the mitarbeiter information corresponding to a user + * @access private + * @param integer $uid the userID used to get the mitarbeiter information + * @return array all the mitarbeiter informaion corresponding to a userID + */ + private function getMitarbeiterInfo($uid) + { + $this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]); + $this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid"); + $mitarbeiter_res = $this->MitarbeiterModel->load($uid); + if (isError($mitarbeiter_res)) { + show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res)); + } else { + $mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null; + } + + return $mitarbeiter_res; + } + + /** + * gets the telefon information corresponding to a user + * @access private + * @param integer $uid the userID used to get the telefon information + * @return array all the telefon informaion corresponding to a userID + */ + private function getTelefonInfo($uid) + { + $this->MitarbeiterModel->addSelect(["kontakt"]); + $this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id"); + $this->MitarbeiterModel->addLimit(1); + $telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]); + if (isError($telefon_res)) { + show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res)); + } + $telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null; + return $telefon_res; + } + + /** + * gets the student information corresponding to a user + * @access private + * @param integer $uid the userID used to get the student information + * @return array all the student informaion corresponding to a userID + */ + private function getStudentInfo($uid) + { + $this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_studiengang.studiengang_kz as studiengang_kz', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']); + $this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz"); + + $student_res = $this->StudentModel->load([$uid]); + if (isError($student_res)) { + show_error("was not able to query the table public.tbl_student:" . getData($student_res)); + } + $student_res = hasData($student_res) ? getData($student_res)[0] : null; + return $student_res; + } + + /** + * gets the profil updates corresponding to a user + * @access private + * @param integer $uid the userID used to get the profil updates + * @return array all the profil updates corresponding to a userID + */ + private function getProfilUpdates($uid) + { + $profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]); + if (isError($profilUpdates)) { + show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates)); + } + $profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null; + return $profilUpdates; + } + + /** + * gets the Matrikelnummer corresponding to a user + * @access private + * @param integer $uid the userID used to get the Matrikelnummer + * @return integer the Matrikelnummer corresponding to a userID + */ + private function getMatrikelNummer($uid) + { + $this->BenutzerModel->addSelect(["matr_nr"]); + $this->BenutzerModel->addJoin("tbl_person", "person_id"); + + $matr_res = $this->BenutzerModel->load([$uid]); + if (isError($matr_res)) { + show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res)); + } + $matr_res = hasData($matr_res) ? getData($matr_res)[0] : []; + return $matr_res; + } + + /** + * gets the Zutrittsgruppen corresponding to a user + * @access private + * @param integer $uid the userID used to get the Zutrittsgruppen + * @return array all the Zutrittsgruppen corresponding to a userID + */ + private function getZutrittsgruppen($uid) + { + $this->BenutzergruppeModel->addSelect(['bezeichnung']); + $this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true)); + if (isError($zutrittsgruppe_res)) { + show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res)); + } + $zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null; + return $zutrittsgruppe_res; + } + + /** + * gets the address information corresponding to a user + * @access private + * @param integer $uid the userID used to get the address information + * @return array all the address information corresponding to a userID + */ + private function getAdressenInfo($pid) + { + $adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]); + $adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC"); + $adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"); + + $adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]); + if (isError($adresse_res)) { + show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res)); + } + $adresse_res = hasData($adresse_res) ? getData($adresse_res) : null; + return $adresse_res; + } + + /** + * gets the kontakt information corresponding to a user + * @access private + * @param integer $uid the userID used to get the kontakt information + * @return array all the kontakt information corresponding to a userID + */ + private function getKontaktInfo($pid) + { + $this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']); + $this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT'); + $this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT'); + $this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum'); + + $kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]); + if (isError($kontakte_res)) { + show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res)); + } + $kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null; + return $kontakte_res; + } + + /** + * gets the date of issue of the FH access card corresponding to a user + * @access private + * @param integer $uid the userID used to get the date of issue of the FH access card + * @return string the date of issue of the FH access card corresponding to a userID + */ + private function getZutrittskarteDatum($uid) + { + $zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte"); + if (isError($zutrittskarte_ausgegebenam)) { + show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam)); + } + $zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null; + + //? formats date from 01-01-2000 to 01.01.2000 + $zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam); + return $zutrittskarte_ausgegebenam; + } +} + diff --git a/application/controllers/api/frontend/v1/ProfilUpdate.php b/application/controllers/api/frontend/v1/ProfilUpdate.php new file mode 100644 index 000000000..827654d21 --- /dev/null +++ b/application/controllers/api/frontend/v1/ProfilUpdate.php @@ -0,0 +1,837 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +class ProfilUpdate extends FHCAPI_Controller +{ + + public static $STATUS_PENDING = NULL; + public static $STATUS_ACCEPTED = NULL; + public static $STATUS_REJECTED = NULL; + + public static $TOPICS = []; + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getStatus' => self::PERM_LOGGED, + 'getTopic' => self::PERM_LOGGED, + 'getProfilRequestFiles' => self::PERM_LOGGED, + 'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'], + 'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'], + 'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'], + 'selectProfilRequest' => self::PERM_LOGGED, + 'insertProfilRequest' => self::PERM_LOGGED, + 'updateProfilRequest' => self::PERM_LOGGED, + 'deleteProfilRequest' => self::PERM_LOGGED, + 'insertFile' => self::PERM_LOGGED, + 'show' => self::PERM_LOGGED, + ]); + + $this->load->config('cis'); + + // Load language phrases + $this->loadPhrases( + array( + 'ui', + 'global', + 'person', + 'profil', + 'profilUpdate' + ) + ); + + $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Adresse_model', 'AdresseModel'); + $this->load->model('person/Adressentyp_model', 'AdressenTypModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel'); + $this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel'); + + $this->load->library('DmsLib'); + $this->load->library('PermissionLib'); + + //? put the uid and pid inside the controller for reusability + $this->uid = getAuthUID(); + $this->pid = getAuthPersonID(); + + // setup the ProfilUpdate states + $this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']); + $status_kurzbz = $this->ProfilUpdateStatusModel->load(); + if (hasData($status_kurzbz)) { + list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz); + + self::$STATUS_PENDING = $status_pending->status_kurzbz; + self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz; + self::$STATUS_REJECTED = $status_rejected->status_kurzbz; + } + // setup the ProfilUpdate topics + $this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']); + $topic_kurzbz = $this->ProfilUpdateTopicModel->load(); + + if (hasData($topic_kurzbz)) { + foreach (getData($topic_kurzbz) as $topic) { + self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz; + } + } + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getStatus() + { + $this->terminateWithSuccess([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]); + } + + + public function getTopic() + { + if(!count(self::$TOPICS)){ + $this->terminateWithError('No topics found'); + } + $this->terminateWithSuccess(self::$TOPICS); + } + + public function show($dms_id) + { + + $profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]); + $profil_update = hasData($profil_update) ? getData($profil_update)[0] : null; + + //? checks if an profil update exists with the dms_id requested from the user + if ($profil_update) { + $is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid)); + $is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid)); + + if ( + $this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update || + $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update || + $this->uid == $profil_update->uid + ) { + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id); + $download = $this->getDataOrTerminateWithError($download); + // Download file + $this->outputFile($download); + + + } else { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + } + + } else { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_dms_error')); + } + + } + + public function selectProfilRequest() + { + + $uid = $this->input->get('uid',true); + $id = $this->input->get('id',true); + $whereClause = ['uid' => $this->uid]; + + if (isset($uid)) + $whereClause['uid'] = $uid; + if (isset($id)) + $whereClause['id'] = $id; + + $res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause); + $res = $this->getDataOrTerminateWithError($res); + $this->terminateWithSuccess($res); + + } + + public function insertProfilRequest() + { + + $payload = $this->input->post('payload'); + $topic = $this->input->post('topic',true); + $fileID = $this->input->post('fileID',true); + + if(!isset($payload) || !isset($topic)){ + $this->terminateWithError("required parameters are missing"); + } + + $identifier = array_key_exists("kontakt_id", $payload) ? "kontakt_id" : (array_key_exists("adresse_id", $payload) ? "adresse_id" : null); + + $data = ["topic" => $topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending']; + + //? insert fileID in the dataset if sent with post request + if (isset($fileID)) { + $data['attachment_id'] = $fileID; + } + + //? loops over all updateRequests from a user to validate if the new request is valid + $res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]); + $res = $this->getDataOrTerminateWithError($res); + + //? the user cannot delete a zustelladresse/kontakt + if (isset($payload["delete"]) && $payload[$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"]) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')); + } + + //? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised + if (isset($payload["delete"]) && $identifier == "adresse_id") { + $adr = $this->AdresseModel->load($payload[$identifier]); + $adr = $this->getDataOrTerminateWithError($adr)[0]; + if ($adr->heimatadresse) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')); + } + } + + if ($res) { + $pending_changes = array_filter($res, function ($element) { + return $element->status == (self::$STATUS_PENDING ?: "Pending"); + }); + foreach ($pending_changes as $update_request) { + $existing_change = $update_request->requested_change; + //? the user can add as many new kontakte/adressen as he likes + if (!isset($payload["add"]) && property_exists($existing_change, $identifier) && array_key_exists($identifier,$payload) && $existing_change->$identifier == $payload[$identifier]) { + //? the kontakt_id / adresse_id of a change has to be unique + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error')); + } + + //? if it is not updating any kontakt/adresse, the topic has to be unique + elseif (!$identifier && $update_request->topic == $topic) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic])); + } + } + } + + $insertID = $this->ProfilUpdateModel->insert($data); + + if (isError($insertID)) { + $this->terminateWithError(getError($insertID)); + } else { + + $insertID = hasData($insertID) ? getData($insertID) : null; + //? sends emails to the correspondents of the $uid + $this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $topic); + $this->terminateWithSuccess(success($insertID)); + } + } + + public function updateProfilRequest() + { + $topic = $this->input->post('topic', true); + $payload = $this->input->post('payload', true); + $ID = $this->input->post('ID', true); + $fileID = $this->input->post('fileID', true);//optional + + if(!isset($topic) || !isset($payload) || !isset($ID)){ + $this->terminateWithError("required parameters are missing"); + } + + $updateData = ["requested_change" => json_encode($payload), "updateamum" => "NOW()", "updatevon" => $this->uid]; + if (isset($fileID)) { + $updateData['attachment_id'] = json_decode($fileID); + } + $updateID = $this->ProfilUpdateModel->update([$ID], $updateData); + //? insert fileID in the dataset if sent with post request + + if (isError($updateID)) { + $this->terminateWithError(getError($updateID)); + } + + $updateID = $this->getDataOrTerminateWithError($updateID)[0]; + + $this->terminateWithSuccess(success($updateID)); + } + + public function deleteProfilRequest() + { + + $requestID = $this->input->post('requestID', true); + $result = $this->ProfilUpdateModel->delete([$requestID]); + if (isError($result)) { + $this->terminateWithError(getError($result)); + } + $this->terminateWithSuccess($result); + } + + public function getProfilRequestFiles($id) + { + if(!$id){ + $this->terminateWithError("parameter id is missing"); + } + + $this->ProfilUpdateModel->addSelect(["attachment_id"]); + $attachmentID = $this->ProfilUpdateModel->load([$id]); + if (isError($attachmentID)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loading_error'),self::ERROR_TYPE_GENERAL); + } + //? get the attachmentID + $dms_id = $this->getDataOrTerminateWithError($attachmentID)[0]->attachment_id; + + //? get the name to the file + $this->DmsVersionModel->addSelect(["name", "dms_id"]); + $attachment = $this->DmsVersionModel->load([$dms_id, 0]); + if (isError($attachment)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'),self::ERROR_TYPE_GENERAL); + } + $attachment = $this->getDataOrTerminateWithError($attachment); + //? returns {name:..., dms_id:...} + $this->terminateWithSuccess($attachment); + } + + public function denyProfilRequest() + { + $id = $this->input->post('profil_update_id', true); + $uid = $this->input->post('uid', true); + $topic = $this->input->post('topic', true); + $status_message = $this->input->post('status_message', true); //optional + + if(!isset($id) || !isset($uid) || !isset($topic)){ + $this->terminateWithError("parameter id, uid, topic or status_message is missing"); + } + + $is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); + $is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter); + + $is_student = $this->StudentModel->isStudent($uid); + $is_student = $this->getDataOrTerminateWithError($is_student); + + if ( + $is_student && $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) || + $is_mitarbeiter && $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") + ) { + $this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED); + $this->terminateWithSuccess($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message)); + } else { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'),self::ERROR_TYPE_GENERAL); + } + } + + public function acceptProfilRequest() + { + $id = $this->input->post('profil_update_id', true); + $uid = $this->input->post('uid', true); + $topic = $this->input->post('topic', true); + $requested_change = $this->input->post('requested_change'); + $status_message = $this->input->post('status_message', true); //optional + + //? fetching person_id using UID + $personID = $this->PersonModel->getByUid($uid); + $personID = $this->getDataOrTerminateWithError($personID)[0]->person_id; + + //! check for required information + if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error')); + } + + $is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); + $is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter); + + $is_student = $this->StudentModel->isStudent($uid); + $is_student = $this->getDataOrTerminateWithError($is_student); + + + //? check if the permissions are set correctly + if ( + $is_student && $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) || + $is_mitarbeiter && $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") + ) { + + if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) { + $insertID = $this->handleAdresse($requested_change, $personID); + $insertID = getData($insertID); + if (isset($insertID)) { + $requested_change['adresse_id'] = $insertID; + $update_res = $this->updateRequestedChange($id, $requested_change); + if (isError($update_res)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID])); + } + } + + } else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) { + $insertID = $this->handleKontakt($requested_change, $personID); + $insertID = getData($insertID); + if (isset($insertID)) { + $requested_change['kontakt_id'] = $insertID; + $update_res = $this->updateRequestedChange($id, $requested_change); + if (isError($update_res)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID])); + } + } + + + } else { + switch ($topic) { + // mapping phrasen to database columns to make the update with the correct column names + case self::$TOPICS['Titel']: + $topic = "titelpre"; + break; + case self::$TOPICS['Postnomen']: + $topic = "titelpost"; + break; + case self::$TOPICS['Vorname']: + $topic = "vorname"; + break; + case self::$TOPICS['Nachname']: + $topic = "nachname"; + break; + default: + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic])); + } + + $result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]); + if (isError($result)) $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_insert_error')); + + } + $this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED); + + $this->terminateWithSuccess($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change)); + } else { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error')); + } + + + } + + public function insertFile($replace) + { + $replace = json_decode($replace); + + if (!count($_FILES)) { + $this->terminateWithError("No file available for upload"); + } + + //? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced + if (isset($replace)) { + + $this->ProfilUpdateModel->addSelect(["attachment_id"]); + $profilUpdate = $this->ProfilUpdateModel->load([$replace]); + if (isError($profilUpdate)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loading_error')); + } + //? get the attachmentID + $dms_id = $this->getDataOrTerminateWithError($profilUpdate)[0]->attachment_id; + + //? delete old dms_file of Profil Update + $deleteOldFile_result = $this->deleteOldVersionFile($dms_id); + if(!$deleteOldFile_result){ + $this->terminateWithError("error while deleting the old file"); + } + } + + + $files = $_FILES['files']; + $file_count = count($files['name']); + + $res = []; + + for ($i = 0; $i < $file_count; $i++) { + $_FILES['files']['name'] = $files['name'][$i]; + $_FILES['files']['type'] = $files['type'][$i]; + $_FILES['files']['tmp_name'] = $files['tmp_name'][$i]; + $_FILES['files']['error'] = $files['error'][$i]; + $_FILES['files']['size'] = $files['size'][$i]; + + $dms = [ + "kategorie_kurzbz" => "profil_aenderung", + "version" => 0, + "name" => $_FILES['files']['name'], + "mimetype" => $_FILES['files']['type'], + "beschreibung" => $this->uid . " Profil Änderung", + "insertvon" => $this->uid, + "insertamum" => "NOW()", + ]; + + $tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf")); + + if(isError($tmp_res)){ + $this->addError(getError($tmp_res)); + } + + $tmp_res = $this->getDataOrTerminateWithError($tmp_res); + array_push($res, $tmp_res); + } + + $this->terminateWithSuccess($res); + } + + public function getProfilUpdateWithPermission($status = null) + { + // early return if no status has been passed as argument + if (!isset($status)) { + echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission()); + return; + } + + // get the sprache of the user + $sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]); + $sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null; + + if (isset($sprachenIndex) && isset($status)) { + // get the corresponding status kurz_bz primary key out of the translation + $status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]); + $status = hasData($status) ? getData($status)[0]->status_kurzbz : null; + $res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null); + + echo json_encode($res); + } + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + + private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic) + { + if($this->config->item('cis_send_profil_update_mails') === false) + { + return; + } + + $this->load->helper('hlp_sancho_helper'); + $emails = []; + + $is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); + if (isError($is_mitarbeiter)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error')); + } + $is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter); + + //! if the $uid is a mitarbeiter and student, only the hr is notified by email + if ($is_mitarbeiter) { + //? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung + //? use constant variable MAIL_GST to mail to the personalverwaltung + $this->MitarbeiterModel->addSelect([TRUE]); + $this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid"); + //? check if the the userID is a mitarbeiter and if the benutzer is active + $res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]); + if (isError($res)) { + $this->terminateWithError("was not able to query the mitarbeiter and benutzer by the uid: " . $uid); + } + if (hasData($res)) { + array_push($emails, MAIL_GST); + } else { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error')); + } + } else { + //? if it is not a mitarbeiter, check whether it is a student and send email to studiengang + $is_student = $this->StudentModel->isStudent($uid); + if (isError($is_student)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error')); + } + $is_student = $this->getDataOrTerminateWithError($is_student); + if ($is_student) { + //? Send email to the Studiengangsassistentinnen + $this->StudentModel->addSelect(["public.tbl_studiengang.email"]); + $this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid"); + $this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id"); + $this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id"); + $this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz"); + //* check if the benutzer itself is active + //* check if the student status is Student or Diplomand (active students) + $this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']); + $res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]); + if (isError($res)) { + $this->terminateWithError(getError($res)); + } else { + $res = $this->getDataOrTerminateWithError($res); + foreach ($res as $emailObj) { + array_push($emails, $emailObj->email); + } + } + } + } + $mail_res = []; + //? sending email + foreach ($emails as $email) { + array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid))); + } + foreach ($mail_res as $m_res) { + if (!$m_res) { + $this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error')); + } + } + + } + + private function sendEmail_onProfilUpdate_response($uid, $topic, $status) + { + if($this->config->item('cis_send_profil_update_mails') === false) + { + return; + } + + $this->load->helper('hlp_sancho_helper'); + $email = $uid . "@" . DOMAIN; + + + function languageQuery($language) + { + return "select index from public.tbl_sprache where sprache = '" + $language + "'"; + } + + $this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]); + + $status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]); + + if (isError($status_translation)) { + $this->terminateWithError($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError')); + } + + $status_translation = hasData($status_translation) ? getData($status_translation)[0] : null; + + if (isset($status_translation)) { + $mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending'))); + if (!$mail_res) { + $this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error')); + } + } + } + + private function setStatusOnUpdateRequest($id, $status, $status_message) + { + return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]); + } + + private function updateRequestedChange($id, $requested_change) + { + return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]); + } + + private function deleteOldVersionFile($dms_id) + { + // starting the transaction + $this->db->trans_start(); + + + if (!isset($dms_id)) { + return; + } + + //? delete the file from the profilUpdate first + $profilUpdateFileDelete = $this->ProfilUpdateModel->removeFileFromProfilUpdate($dms_id); + if(isError($profilUpdateFileDelete)){ + $this->terminateWithError(getError($profilUpdateFileDelete)); + } + + //? delete all the different versions of the dms_file + $dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]); + $dmsVersions = $this->getDataOrTerminateWithError($dmsVersions); + + + + $dms_versions = array_map(function ($item) { + return $item->version; + }, $dmsVersions); + + + $test_array = array(); + foreach ($dms_versions as $version) { + + $delete_result = $this->dmslib->removeVersion($dms_id, $version); + array_push($test_array, $delete_result); + + if(isError($delete_result)){ + $this->addError(getError($delete_result)); + } + } + + // transaction complete + $this->db->trans_complete(); + + if ($this->db->trans_status() === FALSE) + { + return false; + } + else + { + return true; + } + + } + + + private function getOE_from_student($student_uid) + { + //? returns the oe_einheit eines Studenten + $query = "SELECT public.tbl_studiengang.oe_kurzbz + FROM public.tbl_student + JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz + WHERE public.tbl_student.student_uid = ?;"; + + $res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]); + $res = $this->getDataOrTerminateWithError($res, $this->p->t('profilUpdate', 'profilUpdate_loadingOE_error')); + $res = array_map( + function ($item) { + return $item->oe_kurzbz; + }, + $res + ); + return $res; + } + + private function handleAdresse($requested_change, $personID) + { + $this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]); + $adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]); + $adr_kurzbz = $this->getDataOrTerminateWithError($adr_kurzbz)[0]->adressentyp_kurzbz; + + //? replace the address_typ with its correct kurzbz foreign key + $requested_change['typ'] = $adr_kurzbz; + + $adresse_id = $requested_change["adresse_id"]; + + //? removes the adresse_id because we don't want to update the kontakt_id in the database + unset($requested_change["adresse_id"]); + + //! ADD + if (array_key_exists('add', $requested_change) && $requested_change['add']) { + + //? removes add flag + unset($requested_change['add']); + $requested_change['insertamum'] = "NOW()"; + $requested_change['insertvon'] = getAuthUID(); + $requested_change['person_id'] = $personID; + //TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet + $insertID = $this->AdresseModel->insert($requested_change); + $insert_adresse_id = $insertID; + $insert_adresse_id = $this->getDataOrTerminateWithError($insert_adresse_id, $this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error')); + if ($insert_adresse_id) { + $this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id); + } + } + //! DELETE + elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) { + $result = $this->AdresseModel->delete($adresse_id); + if (isError($result)) { + $this->terminateWithError(getError($result)); + } + } + //! UPDATE + else { + $requested_change['updateamum'] = "NOW()"; + $requested_change['updatevon'] = getAuthUID(); + $update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change); + $update_adresse_id = $this->getDataOrTerminateWithError($update_adresse_id, $this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error')); + $this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id); + + } + return $insertID ?? null; + } + + private function handleKontakt($requested_change, $personID) + { + $kontakt_id = $requested_change["kontakt_id"]; + //? removes the kontakt_id because we don't want to update the kontakt_id in the database + unset($requested_change["kontakt_id"]); + + //! ADD + if (array_key_exists('add', $requested_change) && $requested_change['add']) { + //? removes add flag + unset($requested_change['add']); + $requested_change['person_id'] = $personID; + $requested_change['insertamum'] = "NOW()"; + $requested_change['insertvon'] = getAuthUID(); + $insertID = $this->KontaktModel->insert($requested_change); + $insert_kontakt_id = $insertID; + $insert_kontakt_id = $this->getDataOrTerminateWithError($insert_kontakt_id, $this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error')); + if ($insert_kontakt_id) { + $this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id); + } + } + //! DELETE + elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) { + $result = $this->KontaktModel->delete($kontakt_id); + if (isError($result)) { + $this->terminateWithError(getError($result)); + } + } + //! UPDATE + else { + $requested_change['updateamum'] = "NOW()"; + $requested_change['updatevon'] = getAuthUID(); + $update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change); + $update_kontakt_id = $this->getDataOrTerminateWithError($update_kontakt_id, $this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error')); + if ($update_kontakt_id) { + $this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id); + } + } + return isset($insertID) ? $insertID : null; + } + + private function handleDupplicateZustellAdressen($zustellung, $adresse_id) + { + if ($zustellung) { + $this->PersonModel->addSelect("public.tbl_adresse.adresse_id"); + $this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id"); + $zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]); + if (isError($zustellAdressenArray)) { + $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error')); + } + $zustellAdressenArray = $this->getDataOrTerminateWithError($zustellAdressenArray); + + if (count($zustellAdressenArray) > 0) { + + $zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) { + + return $adresse->adresse_id != $adresse_id; + }); + + // remove the zustelladresse from all other zustelladressen + foreach ($zustellAdressenArray as $adresse) { + $this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]); + } + + } + } + } + + private function handleDupplicateZustellKontakte($zustellung, $kontakt_id) + { + if ($zustellung) { + $this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id"); + $this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id"); + $zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]); + if (!isSuccess($zustellKontakteArray)) { + return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error')); + } + $zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null; + + if ($zustellung && count($zustellKontakteArray) > 0) { + $zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) { + return $kontakt->kontakt_id != $kontakt_id; + }); + foreach ($zustellKontakteArray as $kontakt) { + $this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]); + } + + } + } + } + +} + + diff --git a/application/controllers/api/frontend/v1/Studgang.php b/application/controllers/api/frontend/v1/Studgang.php new file mode 100644 index 000000000..82aebb666 --- /dev/null +++ b/application/controllers/api/frontend/v1/Studgang.php @@ -0,0 +1,65 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); +class Studgang extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getStudiengangInfo'=> self::PERM_LOGGED, + + ]); + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + + // Loads phrases system + $this->loadPhrases([ + 'global' + ]); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getStudiengangInfo(){ + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID()); + $isMitarbeiter = $this->getDataOrTerminateWithError($isMitarbeiter); + if($isMitarbeiter) { + $this->terminateWithSuccess(null); + } + + // fetches the Studiengang Information which is used next to the news + $studiengangInfo = $this->StudiengangModel->getStudiengangInfoForNews(); + $studiengangInfo= $this->getDataOrTerminateWithError($studiengangInfo); + $this->terminateWithSuccess($studiengangInfo); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + + +} + diff --git a/application/controllers/api/frontend/v1/Stundenplan.php b/application/controllers/api/frontend/v1/Stundenplan.php new file mode 100644 index 000000000..2ec02fea9 --- /dev/null +++ b/application/controllers/api/frontend/v1/Stundenplan.php @@ -0,0 +1,618 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +class Stundenplan extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + + parent::__construct([ + 'getRoomplan' => self::PERM_LOGGED, + 'Stunden' => self::PERM_LOGGED, + 'Reservierungen' => self::PERM_LOGGED, + 'getStundenplan' => self::PERM_LOGGED, + 'getLehreinheitStudiensemester' => self::PERM_LOGGED, + 'studiensemesterDateInterval' => self::PERM_LOGGED, + ]); + + $this->load->library('LogLib'); + $this->loglib->setConfigs(array( + 'classIndex' => 5, + 'functionIndex' => 5, + 'lineIndex' => 4, + 'dbLogType' => 'API', // required + 'dbExecuteUser' => 'RESTful API' + )); + + $this->load->library('form_validation'); + + //load models + $this->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + $this->load->model('ressource/Reservierung_model', 'ReservierungModel'); + + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + //TODO: delete this function if we don't use the old calendar export endpoints anymore + public function studiensemesterDateInterval($date){ + $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + $studiensemester =$this->StudiensemesterModel->getByDate(date_format(date_create($date),'Y-m-d')); + $studiensemester =current($this->getDataOrTerminateWithError($studiensemester)); + $this->terminateWithSuccess($studiensemester); + } + + + /** + * fetches Stunden layout from database + * @access public + * + */ + public function Stunden() + { + $this->load->model('ressource/Stunde_model', 'StundeModel'); + + $stunden = $this->StundeModel->load(); + + $stunden = $this->getDataOrTerminateWithError($stunden); + + $this->terminateWithSuccess($stunden); + } + + /** + * fetches room events from a certain date + * @access public + * + */ + public function getRoomplan() + { + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('ort_kurzbz',"Ort","required"); + $this->form_validation->set_rules('start_date',"start_date","required"); + $this->form_validation->set_rules('end_date',"end_date","required"); + if($this->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the get parameter in local variables + $ort_kurzbz = $this->input->get('ort_kurzbz', TRUE); + $start_date = $this->input->get('start_date', TRUE); + $end_date = $this->input->get('end_date', TRUE); + + $roomplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date)); + + $roomplan_data = $this->getDataOrTerminateWithError($roomplan_data); + + $this->expand_object_information($roomplan_data); + + $this->terminateWithSuccess($roomplan_data); + + } + + /** + * fetches stundenplan events from a UID and start/end date + * @access public + * + */ + + public function getStundenplan(){ + + $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); + $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); + $this->load->model('person/Benutzergruppe_model','BenutzergruppeModel'); + + // form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('start_date', "start_date", "required"); + $this->form_validation->set_rules('end_date', "end_date", "required"); + if ($this->form_validation->run() === FALSE) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the get parameter in local variables + $start_date = $this->input->get('start_date', TRUE); + $end_date = $this->input->get('end_date', TRUE); + $lv_id = $this->input->get('lv_id', TRUE); + + $student_uid = getAuthUID(); + if(is_null($student_uid)) + { + $this->terminateWithError("No UID"); + } + + $semester_range = $this->studienSemesterErmitteln($start_date,$end_date); + $this->sortStudienSemester($semester_range); + $this->applyLoadUeberSemesterHaelfte($semester_range); + + if($lv_id) { // fetch Stundenplan for lva, irrelevant of who is requesting it (for now) + + $stundenplan_data = $this->StundenplanModel->getStundenplanLVA($start_date, $end_date, $lv_id); + $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; + $this->expand_object_information($stundenplan_data); + + // query lv itself in case its Stundenplan is being queried and it has no entries + $this->load->model('education/Lehrveranstaltung_model','LehrveranstaltungModel'); + $lv = getData($this->LehrveranstaltungModel->load($lv_id))[0]; + $this->addMeta('lv', $lv); + $this->terminateWithSuccess($stundenplan_data); + + } + + $is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($student_uid)); + if($is_mitarbeiter) + { + + $stundenplan_data = $this->StundenplanModel->getStundenplanMitarbeiter($start_date, $end_date, $student_uid); + $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; + $this->expand_object_information($stundenplan_data); + $this->terminateWithSuccess($stundenplan_data); + } else { + // getting the gruppen_kurzbz of the student in the different studiensemester + $benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range); + + // getting the student_lehrverbaende of the student in the different studiensemester + $student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range); + + $stundenplan_query = $this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband); + if(!$stundenplan_query) + { + $this->terminateWithSuccess([]); + } + $stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query); + $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; + + $this->expand_object_information($stundenplan_data); + + $this->returnObj['$stundenplan_query'] = $stundenplan_query; + $this->returnObj['$student_lehrverband'] = $student_lehrverband; + $this->returnObj['$benutzer_gruppen'] = $benutzer_gruppen; + $this->terminateWithSuccess($stundenplan_data); + } + + } + + // gets the reservierungen of a room if the ort_kurzbz parameter is supplied otherwise gets the reservierungen of the stundenplan of a student + public function Reservierungen($ort_kurzbz = null) + { + //form validation + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('start_date', "StartDate", "required"); + $this->form_validation->set_rules('end_date', "EndDate", "required"); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); + + // storing the get parameter in local variables + $start_date = $this->input->get('start_date', TRUE); + $end_date = $this->input->get('end_date', TRUE); + + $is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter(getAuthUID())); + if($is_mitarbeiter) + { + $reservierungen = $this->ReservierungModel->getReservierungenMitarbeiter($start_date, $end_date, $ort_kurzbz); + } else { + // querying the reservierungen + $reservierungen = $this->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz); + } + + $reservierungen = $this->getDataOrTerminateWithError($reservierungen) ?? []; + $this->expand_object_information($reservierungen); + $this->terminateWithSuccess($reservierungen); + + } + + public function getLehreinheitStudiensemester($lehreinheit_id){ + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + $this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]); + $result = $this->LehreinheitModel->load($lehreinheit_id); + $result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz; + $this->terminateWithSuccess($result); + } + + // ################# Private Functions + + private function expand_object_information($data){ + + foreach ($data as $item) + { + + $lektor_obj_array = array(); + $gruppe_obj_array = array(); + + // load lektor object + foreach ($item->lektor as $lv_lektor) + { + $this->StundenplanModel->addLimit(1); + $lektor_object = $this->StundenplanModel->execReadOnlyQuery(" + SELECT mitarbeiter_uid, vorname, nachname, kurzbz + FROM public.tbl_mitarbeiter + JOIN public.tbl_benutzer benutzer ON benutzer.uid = mitarbeiter_uid + JOIN public.tbl_person person ON person.person_id = benutzer.person_id + WHERE kurzbz = ?", [$lv_lektor]); + if (isError($lektor_object)) { + $this->show_error(getError($lektor_object)); + } + $lektor_object = $this->getDataOrTerminateWithError($lektor_object); + if(count($lektor_object) == 0) + { + $this->terminateWithError("No lektor object"); + } + $lektor_object = current($lektor_object); + // only provide needed information of the mitarbeiter object + $lektor_obj_array[] = $lektor_object; + } + + // load gruppe object + foreach ($item->gruppe as $lv_gruppe) + { + $lv_gruppe = strtr($lv_gruppe, ['(' => '', ')' => '', '"' => '']); + $lv_gruppe_array = explode(",", $lv_gruppe); + list($gruppe, $verband, $semester, $studiengang_kz, $gruppen_kuerzel) = $lv_gruppe_array; + + $lv_gruppe_object = new stdClass(); + $lv_gruppe_object->gruppe = $gruppe; + $lv_gruppe_object->verband = $verband; + $lv_gruppe_object->semester = $semester; + $lv_gruppe_object->studiengang_kz = $studiengang_kz; + $lv_gruppe_object->kuerzel = $gruppen_kuerzel; + + $gruppe_obj_array[] = $lv_gruppe_object; + } + + if($item->ort_kurzbz) { + + $ort_content_object = $this->StundenplanModel->execReadOnlyQuery(" + SELECT content_id + FROM public.tbl_ort + WHERE ort_kurzbz = ?", [$item->ort_kurzbz]); + if (isError($ort_content_object)) { + $this->show_error(getError($ort_content_object)); + } + $ort_content_object = getData($ort_content_object)[0]; + if($ort_content_object) { + $item->ort_content_id = $ort_content_object->content_id; + } + + + } + + $item->gruppe = $gruppe_obj_array; + $item->lektor = $lektor_obj_array; + + } + } + + // function used to sort an array of studiensemester strings + private function sortStudienSemester(&$semester_range){ + usort( + $semester_range, + function($first,$second) + { + $sem_first = null; + $year_first = null; + $match_first = null; + + $sem_second = null; + $year_second = null; + $match_second = null; + + preg_match('/([WS]+)([0-9]+)/',$first,$match_first); + preg_match('/([WS]+)([0-9]+)/',$second,$match_second); + + $sem_first = $match_first[1]; + $year_first = intval($match_first[2]); + + $sem_second = $match_second[1]; + $year_second = intval($match_second[2]); + + if($year_first < $year_second) + { + return -1; + } + else if($year_first > $year_second) + { + return 1; + } + else if($year_first == $year_second && $sem_first > $sem_second) + { + return 1; + } + else if($year_first == $year_second && $sem_first < $sem_second) + { + return -1; + } + return 0; + } + ); + } + + + + private function fetchBenutzerGruppenFromStudiensemester($semester_range){ + $student_uid = getAuthUID(); + $benutzer_gruppen = []; + // for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array + /* + [ + ['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']], + ['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']], + ['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']], + ] + */ + foreach($semester_range as $semester_key => $semester_array) + { + $benutzer_gruppen[$semester_key] = []; + // each semester could have ajoint semesters that need to be checked + foreach($semester_array as $semester=>$semester_date_range) + { + // for each active semester query the benutzer_gruppen associated to the semester + $benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery(" + SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]); + $benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query); + array_push( + $benutzer_gruppen[$semester_key], + array_map( + function($item) + { + return "'".$item->gruppe_kurzbz. "'"; + }, + $benutzer_query_result + ) + ); + } + } + + // merge the gruppen of each studiensemester together for the original studiensemester + /* + [ + ['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'], + ['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'], + ['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'], + ] + */ + $benutzer_gruppen = array_map( + function($gruppe) + { + $merged_gruppe = []; + foreach($gruppe as $gruppen_array) + { + $merged_gruppe = array_merge($merged_gruppe, $gruppen_array); + } + return $merged_gruppe; + }, + $benutzer_gruppen + ); + + return $benutzer_gruppen; + } + + private function fetchStudentlehrverbandFromStudiensemester($semester_range){ + $student_uid = getAuthUID(); + $student_lehrverband = []; + // for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array + /* + [ + ['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ], + ['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ], + ['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ], + ] + */ + foreach($semester_range as $semester_key => $semester_array) + { + $student_lehrverband[$semester_key] = []; + foreach($semester_array as $semester=>$semester_date_range) + { + // for each active semester query the student_lehrverband associated to the semester + $lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery(" + SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]); + $lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query); + array_push($student_lehrverband[$semester_key], array_map( + function ($item) + { + $result = new stdClass(); + $result->studiengang_kz = $item->studiengang_kz; + $result->semester = $item->semester; + $result->verband = $item->verband; + $result->gruppe = $item->gruppe; + return $result; + }, + $lehrverband_query_result)); + } + } + + // merge the studentlehrverband of each studiensemester together for the original studiensemester + /* + [ + ['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], + ['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], + ['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ], + ] + */ + $student_lehrverband = array_map( + function($studentlehrverband) + { + $merged_studentlehrverband = []; + foreach($studentlehrverband as $studentlehrverband_array) + { + $merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array); + } + return $merged_studentlehrverband; + }, + $student_lehrverband + ); + + return $student_lehrverband; + } + + private function applyLoadUeberSemesterHaelfte(&$semester_range){ + /* + @var($semester_collection) + convert the array of studiensemester into an associative array with the studiensemester as the key + and the values of each key are the studiensemester needed for the query associated to that studiensemester + example: + + #INPUT: + ['WS2023','SS2024','WS2024'] + #OUTPUT: + [ + 'WS2023' => ['SS2023','WS2023'] + 'SS2024' => ['WS2023','SS2024'] + 'WS2024' => ['SS2024','WS2024'] + ] + */ + $semester_collection = []; + foreach($semester_range as $studiensemester) + { + $previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($studiensemester); + $previous_studiensemester = $this->getDataOrTerminateWithError($previous_studiensemester); + if (count($previous_studiensemester) == 0) { + $this->terminateWithError("No previous semester"); + } + $previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz; + $semester_collection[$studiensemester] = [$previous_studiensemester, $studiensemester]; + } + + /* + @var($studienSemesterDateRanges) + fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak + based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range + or the semester with the full date range and the previous semester with the half date range: + + #INPUT: + [ + 'WS2023' => ['SS2023','WS2023'] + 'SS2024' => ['WS2023','SS2024'] + 'WS2024' => ['SS2024','WS2024'] + ] + #OUTPUT: depends whether LVPLAN_LOAD_UEBER_SEMESTERHAELFTE is true or false + ~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == true + [ + "SS2024": [ + "WS2023": [ + "start"=> "2024-02-03", + "ende"=> "2024-08-31" + ], + "SS2024": [ + "start"=> "2024-02-03", + "ende"=> "2024-08-31" + ] + ] + ] + ~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == false + [ + "SS2024": [ + "WS2023": [ + "start"=> "2024-02-03", + "ende"=> "2024-05-17" + ], + "SS2024": [ + "start"=> "2024-02-03", + "ende"=> "2024-08-31" + ] + ] + ] + */ + $studienSemesterDateRanges=[]; + foreach($semester_collection as $semester_original => $semester_adjoint) + { + $semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original); + $semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende)); + + // initialize empty arrays to add key value pairs + $studienSemesterDateRanges[$semester_original] = []; + + // check if the studiensemester is a summer semester and add 1 month to bridge the school summer break + $match = null; + preg_match("/^(SS)([0-9]+)/",$semester_original,$match); + if(count($match) >0) + { + $one_month = new DateInterval('P1M'); + $one_day = DateInterval::createFromDateString('1 days'); + $summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende); + $summer_studiensemester_end_date->add($one_month); + $summer_studiensemester_end_date->sub($one_day); + $semester_start_ende->ende = date_format($summer_studiensemester_end_date,'Y-m-d'); + } + if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true) + { + foreach($semester_adjoint as $adjoint) + { + $studienSemesterDateRanges[$semester_original][$adjoint]=$semester_start_ende; + } + } + else + { + //TODO: half of a DateInterval might not be correctly calculated + // calculate the half of the studiensemester + $studiensemester_start_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->start); + $studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende); + $studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date); + $half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2); + $half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D'); + $studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval),'Y-m-d'); + + $first_half = new stdClass(); + $first_half->start = $semester_start_ende->start; + $first_half->ende = $studiensemester_half; + + $studienSemesterDateRanges[$semester_original][$semester_adjoint[0]] = $first_half; + $studienSemesterDateRanges[$semester_original][$semester_adjoint[1]] = $semester_start_ende; + } + $semester_range = $studienSemesterDateRanges; + } + } + + private function studienSemesterErmitteln($start_date,$end_date){ + + // gets all studiensemester from the student from start_date to end_date + $semester_range = $this->StudiensemesterModel->getByDateRange($start_date,$end_date); + $semester_range = array_map( + function($sem) + { + return $sem->studiensemester_kurzbz; + }, + $this->getDataOrTerminateWithError($semester_range) + ); + + // if no studiensemester is found for the given timespan, get the nearest studiensemester + if(count($semester_range) == 0) + { + $aktuelle_studiensemester = $this->StudiensemesterModel->getNearest(); + $aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester); + if (count($aktuelle_studiensemester) == 0) { + $this->terminateWithError("No aktuelles semester"); + } + $aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz; + // push aktuelles semester in active semester array + array_push($semester_range, $aktuelle_studiensemester); + + } + return $semester_range; + } + +} diff --git a/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php b/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php index 8e44b2326..8e9d931f2 100644 --- a/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php +++ b/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php @@ -342,7 +342,7 @@ class BetriebsmittelP extends FHCAPI_Controller $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Betriebsmittelperson_id']), self::ERROR_TYPE_GENERAL); } - $this->terminateWithSuccess(current(getData($result))); + return $this->terminateWithSuccess(current(getData($result))); } public function deleteBetriebsmittel($betriebsmittelperson_id) @@ -358,7 +358,7 @@ class BetriebsmittelP extends FHCAPI_Controller if (!hasData($result)) { return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Betriebsmittelperson_id']), self::ERROR_TYPE_GENERAL); } - return $this->outputJsonSuccess(current(getData($result))); + $this->terminateWithSuccess(current(getData($result))); } public function getTypenBetriebsmittel() diff --git a/application/controllers/api/frontend/v1/organisation/StudiengangEP.php b/application/controllers/api/frontend/v1/organisation/StudiengangEP.php new file mode 100644 index 000000000..463243f57 --- /dev/null +++ b/application/controllers/api/frontend/v1/organisation/StudiengangEP.php @@ -0,0 +1,57 @@ + self::PERM_LOGGED + ) + ); + // Load model StudiengangModel + $this->load->model('organisation/studiengang_model', 'StudiengangModel'); + } + + /** + * @return void + */ + public function getStudiengangByKz() + { + $studiengang_kz = intval($this->input->get('studiengang_kz')); + + $this->StudiengangModel->addSelect('studiengang_kz, kurzbz, kurzbzlang, ' + . 'typ, bezeichnung, english, aktiv, orgform_kurzbz, sprache, ' + . 'oe_kurzbz'); + $result = $this->StudiengangModel->load($studiengang_kz); + + if (isError($result)) + { + $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + } + + $stg = null; + if(hasData($result)) + { + $stg = (getData($result))[0]; + } + $this->terminateWithSuccess($stg); + } +} diff --git a/application/controllers/api/frontend/v1/organisation/Studienjahr.php b/application/controllers/api/frontend/v1/organisation/Studienjahr.php new file mode 100644 index 000000000..cdbb524c7 --- /dev/null +++ b/application/controllers/api/frontend/v1/organisation/Studienjahr.php @@ -0,0 +1,80 @@ + self::PERM_LOGGED, + 'getNext' => self::PERM_LOGGED + ) + ); + // Load model StudiensemesterModel + $this->load->model('organisation/studienjahr_model', 'StudienjahrModel'); + } + + /** + * Get all Studienjahre. + * + * @param null|string $order Sorting order for the Studienjahr, 'asc' or 'desc'. Defaults to 'asc'. + * @param null|string $start Starting Studienjahre with given studienjahr_kurzbz + */ + public function getAll() + { + $order = $this->input->get('order'); + $start = $this->input->get('studienjahr_kurzbz'); + + if (strcasecmp($order, 'DESC') == 0) { + $this->StudienjahrModel->addOrder('studienjahr_kurzbz', 'DESC'); + } else { + $this->StudienjahrModel->addOrder('studienjahr_kurzbz', 'ASC'); + } + + if ($start) { + $result = $this->StudienjahrModel->loadWhere([ + 'studienjahr_kurzbz >= ' => $start + ]); + } else { + $result = $this->StudienjahrModel->load(); + } + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + } + + $this->terminateWithSuccess((getData($result) ?: [])); + } + + public function getNext() + { + $this->StudienjahrModel->addJoin('public.tbl_studiensemester', 'studienjahr_kurzbz'); + $this->StudienjahrModel->addOrder('start'); + $this->StudienjahrModel->addLimit(1); + + $result = $this->StudienjahrModel->loadWhere(['start >' => 'NOW()']); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + } + + $this->terminateWithSuccess(current(getData($result))); + } +} diff --git a/application/controllers/api/frontend/v1/organisation/Studiensemester.php b/application/controllers/api/frontend/v1/organisation/Studiensemester.php index 72a449aaa..bb56ea71a 100644 --- a/application/controllers/api/frontend/v1/organisation/Studiensemester.php +++ b/application/controllers/api/frontend/v1/organisation/Studiensemester.php @@ -24,7 +24,8 @@ class Studiensemester extends FHCAPI_Controller parent::__construct( array( 'getAll' => self::PERM_LOGGED, - 'getAktNext' => self::PERM_LOGGED + 'getAktNext' => self::PERM_LOGGED, + 'getStudienjahrByStudiensemester' => self::PERM_LOGGED ) ); // Load model StudiensemesterModel @@ -115,4 +116,40 @@ class Studiensemester extends FHCAPI_Controller $this->terminateWithSuccess((getData($result) ?: '')); } + + /** + * Get Studienjahr by Studiensemester. + * input param semester: studiensemester_kurzbz + */ + public function getStudienjahrByStudiensemester() + { + $semester = $this->input->get('semester'); + + $studienjahrObj = null; + + if (!is_numeric($semester)) + { + $this->StudiensemesterModel->addSelect('studienjahr_kurzbz'); + $result = $this->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz =' => $semester)); + } + + if (hasData($result)) + { + $studienjahr = getData($result)[0]->studienjahr_kurzbz; + $startstudienjahr = substr($studienjahr, 0, 4); + $endstudienjahr = substr($studienjahr, 0, 2) . substr($studienjahr, -2); + + $studienjahrObj = new StdClass(); + + $studienjahrObj->studienjahr_kurzbz = $studienjahr; + $studienjahrObj->startstudienjahr = $startstudienjahr; + $studienjahrObj->endstudienjahr= $endstudienjahr; + } + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_DB); + } + + $this->terminateWithSuccess((getData(success($studienjahrObj)))); + } } diff --git a/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php b/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php new file mode 100644 index 000000000..daaf043b5 --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php @@ -0,0 +1,420 @@ + ['admin:r', 'assistenz:r'], + 'loadAbschlusspruefung' => ['admin:r', 'assistenz:r'], + 'insertAbschlusspruefung' => ['admin:rw', 'assistenz:rw'], + 'updateAbschlusspruefung' => ['admin:rw', 'assistenz:rw'], + 'deleteAbschlusspruefung' => ['admin:rw', 'assistenz:rw'], + 'getTypenAbschlusspruefung' => ['admin:rw', 'assistenz:rw'], + 'getNoten' => ['admin:rw', 'assistenz:rw'], + 'getTypenAntritte' => ['admin:rw', 'assistenz:rw'], + 'getBeurteilungen' => ['admin:rw', 'assistenz:rw'], + 'getAkadGrade' => ['admin:rw', 'assistenz:rw'], + 'getMitarbeiter' => ['admin:rw', 'assistenz:rw'], + 'getPruefer' => ['admin:rw', 'assistenz:rw'], + 'getTypStudiengang' => ['admin:rw', 'assistenz:rw'], + 'checkForExistingExams' => ['admin:rw', 'assistenz:rw'], + ]); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $this->load->library('form_validation'); + + // Load language phrases + $this->loadPhrases([ + 'ui', + 'person', + 'abschlusspruefung' + ]); + + // Load models + $this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel'); + } + + public function getAbschlusspruefung($student_uid) + { + $result = $this->AbschlusspruefungModel->getAbschlusspruefungForPrestudent($student_uid); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + + $this->terminateWithSuccess((getData($result) ?: [])); + } + + public function loadAbschlusspruefung() + { + $abschlusspruefung_id = $this->input->post('id'); + + $this->AbschlusspruefungModel->addSelect('lehre.tbl_abschlusspruefung.*'); + $this->AbschlusspruefungModel->addSelect(" + CASE + WHEN pruefer1 IS NOT NULL + THEN CONCAT(p1.nachname, ' ', p1.vorname, COALESCE(' ' || p1.titelpre, '')) + ELSE NULL + END AS p1 + "); + $this->AbschlusspruefungModel->addSelect(" + CASE + WHEN pruefer2 IS NOT NULL + THEN CONCAT(p2.nachname, ' ', p2.vorname, COALESCE(' ' || p2.titelpre, '')) + ELSE NULL + END AS p2 + "); + $this->AbschlusspruefungModel->addSelect(" + CASE + WHEN pruefer3 IS NOT NULL + THEN CONCAT(p3.nachname, ' ', p3.vorname, COALESCE(' ' || p3.titelpre, '')) + ELSE NULL + END AS p3 + "); + $this->AbschlusspruefungModel->addSelect(" + CASE + WHEN vorsitz IS NOT NULL + THEN CONCAT(pv.nachname, ' ', pv.vorname, COALESCE(' ' || pv.titelpre, ''), ' (', ben.uid , ')' ) + ELSE NULL + END AS pv + "); + $this->AbschlusspruefungModel->addJoin('public.tbl_benutzer ben', 'ON (ben.uid = lehre.tbl_abschlusspruefung.vorsitz)', 'LEFT'); + $this->AbschlusspruefungModel->addJoin('public.tbl_person pv', 'ON (pv.person_id = ben.person_id)', 'LEFT'); + $this->AbschlusspruefungModel->addJoin('public.tbl_person p1', 'ON (p1.person_id = lehre.tbl_abschlusspruefung.pruefer1)', 'LEFT'); + $this->AbschlusspruefungModel->addJoin('public.tbl_person p2', 'ON (p2.person_id = lehre.tbl_abschlusspruefung.pruefer2)', 'LEFT'); + $this->AbschlusspruefungModel->addJoin('public.tbl_person p3', 'ON (p3.person_id = lehre.tbl_abschlusspruefung.pruefer3)', 'LEFT'); + $result = $this->AbschlusspruefungModel->loadWhere( + array('abschlusspruefung_id' => $abschlusspruefung_id) + ); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function getTypenAbschlusspruefung() + { + $this->load->model('education/Pruefungstyp_model', 'PruefungstypModel'); + + $result = $this->PruefungstypModel->loadWhere( + array('abschluss' => true) + ); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getTypenAntritte() + { + $this->load->model('education/Pruefungsantritt_model', 'PruefungsantrittModel'); + + $result = $this->PruefungsantrittModel->load(); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getBeurteilungen() + { + $this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel'); + + $result = $this->AbschlussbeurteilungModel->load(); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getAkadGrade() + { + $studiengang_kz= $this->input->post('studiengang_kz'); + + + $this->load->model('education/Akadgrad_model', 'AkadgradModel'); + + $result = $this->AkadgradModel->loadWhere( + array('studiengang_kz' => $studiengang_kz) + ); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getTypStudiengang() + { + $studiengang_kz= $this->input->post('studiengang_kz'); + +/* if (!$studiengang_kzs || !is_array($studiengang_kzs)) { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('studiengang_kzs', '', 'required|is_null', [ + 'is_null' => $this->p->t('ui', 'error_fieldMustBeArray') + ]); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + }*/ + + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $result = $this->StudiengangModel->loadWhere( + array('studiengang_kz' => $studiengang_kz) + ); + $data = $this->getDataOrTerminateWithError($result); + + $typStudiengang = current($data)->typ; + + $this->terminateWithSuccess($typStudiengang); + } + + public function getMitarbeiter($searchString) + { + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'mitAkadGrad'); + + if (isError($result)) { + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess($result ?: []); + } + + public function getPruefer($searchString) + { + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid'); + + if (isError($result)) { + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + + $this->terminateWithSuccess($result ?: []); + } + + public function getNoten() + { + $this->load->model('education/Note_model', 'NoteModel'); + + $this->NoteModel->addOrder('note', 'ASC'); + $result = $this->NoteModel->load(); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess(getData($result) ?: []); + } + + public function insertAbschlusspruefung() + { + $this->load->library('form_validation'); + + $student_uid = $this->input->post('uid'); + + if(!$student_uid) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL); + } + + $formData = $this->input->post('formData'); + + $_POST['pruefungstyp_kurzbz'] = $formData['pruefungstyp_kurzbz']; + $_POST['akadgrad_id']= $formData['akadgrad_id']; + $_POST['vorsitz'] = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz']; + $_POST['pruefer1'] = isset($formData['pruefer1']['person_id']) ? $formData['pruefer1']['person_id'] : $formData['pruefer1']; + $_POST['pruefer2'] = isset($formData['pruefer2']['person_id']) ? $formData['pruefer2']['person_id'] : $formData['pruefer2']; + $_POST['pruefer3'] = isset($formData['pruefer3']['person_id']) ? $formData['pruefer3']['person_id'] : $formData['pruefer3']; + $_POST['pruefungsantritt_kurzbz'] = $formData['pruefungsantritt_kurzbz']; + $_POST['abschlussbeurteilung_kurzbz'] = $formData['abschlussbeurteilung_kurzbz']; + $_POST['datum']= $formData['datum']; + $_POST['sponsion']= $formData['sponsion']; + $_POST['anmerkung'] = $formData['anmerkung']; + $_POST['protokoll']= $formData['protokoll']; + $_POST['note'] = $formData['note']; + + $this->form_validation->set_rules('pruefungstyp_kurzbz', 'Typ', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ']) + ]); + + $this->form_validation->set_rules('akadgrad_id', 'AkadGrad', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'AkadGrad']) + ]); + + $this->form_validation->set_rules('datum', 'Datum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum']) + ]); + + $this->form_validation->set_rules('sponsion', 'Sponsion', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Sponsion']) + ]); + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $result = $this->AbschlusspruefungModel->insert([ + 'student_uid' => $student_uid, + 'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'), + 'akadgrad_id' => $this->input->post('akadgrad_id'), + 'vorsitz' => $this->input->post('vorsitz'), + 'pruefungsantritt_kurzbz' => $this->input->post('pruefungsantritt_kurzbz'), + 'abschlussbeurteilung_kurzbz' => $this->input->post('abschlussbeurteilung_kurzbz'), + 'datum' => $this->input->post('datum'), //TODO(Manu) check if minute format like FAS + 'sponsion' => $this->input->post('sponsion'), + 'pruefer1' => $this->input->post('pruefer1'), + 'pruefer2' => $this->input->post('pruefer2'), + 'pruefer3' => $this->input->post('pruefer3'), + 'protokoll' => $this->input->post('protokoll'), + 'note' => $this->input->post('note'), + 'anmerkung' => $this->input->post('anmerkung'), + 'insertamum' => date('c'), + 'insertvon' => getAuthUID() + ]); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function updateAbschlusspruefung() + { + $this->load->library('form_validation'); + + $abschlusspruefung_id = $this->input->post('id'); + + if(!$abschlusspruefung_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Abschlussprüfung ID']), self::ERROR_TYPE_GENERAL); + } + + $formData = $this->input->post('formData'); + $_POST['student_uid'] = $formData['student_uid']; + $_POST['pruefungstyp_kurzbz'] = $formData['pruefungstyp_kurzbz']; + $_POST['akadgrad_id']= $formData['akadgrad_id']; + $_POST['vorsitz'] = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz']; + $_POST['pruefer1'] = isset($formData['pruefer1']['person_id']) ? $formData['pruefer1']['person_id'] : $formData['pruefer1']; + $_POST['pruefer2'] = isset($formData['pruefer2']['person_id']) ? $formData['pruefer2']['person_id'] : $formData['pruefer2']; + $_POST['pruefer3'] = isset($formData['pruefer3']['person_id']) ? $formData['pruefer3']['person_id'] : $formData['pruefer3']; + $_POST['pruefungsantritt_kurzbz'] = $formData['pruefungsantritt_kurzbz']; + $_POST['abschlussbeurteilung_kurzbz'] = $formData['abschlussbeurteilung_kurzbz']; + $_POST['datum']= $formData['datum']; + $_POST['sponsion']= $formData['sponsion']; + $_POST['anmerkung'] = $formData['anmerkung']; + $_POST['protokoll']= $formData['protokoll']; + $_POST['note'] = $formData['note']; + + $this->form_validation->set_rules('pruefungstyp_kurzbz', 'Typ', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ']) + ]); + + $this->form_validation->set_rules('akadgrad_id', 'AkadGrad', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'AkadGrad']) + ]); + + $this->form_validation->set_rules('datum', 'Datum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum']) + ]); + + $this->form_validation->set_rules('sponsion', 'Sponsion', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Sponsion']) + ]); + + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $result = $this->AbschlusspruefungModel->update( + [ + 'abschlusspruefung_id' => $abschlusspruefung_id + ], + [ + 'student_uid' => $this->input->post('student_uid'), + 'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'), + 'akadgrad_id' => $this->input->post('akadgrad_id'), + 'vorsitz' => $this->input->post('vorsitz'), + 'pruefungsantritt_kurzbz' => $this->input->post('pruefungsantritt_kurzbz'), + 'abschlussbeurteilung_kurzbz' => $this->input->post('abschlussbeurteilung_kurzbz'), + 'datum' => $this->input->post('datum'), + 'sponsion' => $this->input->post('sponsion'), + 'pruefer1' => $this->input->post('pruefer1'), + 'pruefer2' => $this->input->post('pruefer2'), + 'pruefer3' => $this->input->post('pruefer3'), + 'protokoll' => $this->input->post('protokoll'), + 'note' => $this->input->post('note'), + 'anmerkung' => $this->input->post('anmerkung'), + 'insertamum' => date('c'), + 'insertvon' => getAuthUID() + ] + ); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function deleteAbschlusspruefung() + { + $abschlusspruefung_id = $this->input->post('id'); + + $result = $this->AbschlusspruefungModel->delete( + array('abschlusspruefung_id' => $abschlusspruefung_id) + ); + + if (isError($result)) + { + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + if (!hasData($result)) + { + $this->outputJson($result); + } + return $this->terminateWithSuccess(current(getData($result)) ? : null); + } + + public function checkForExistingExams() + { + $warning = false; + $output = []; + + $student_uids = $this->input->post('uids'); + + if (empty($student_uids)) { + throw new InvalidArgumentException("Keine UID(s) übergeben."); + } + + if( !is_array($student_uids) ) + { + $student_uids = array($student_uids); + } + + foreach ($student_uids as $uid) + { + $result = $this->AbschlusspruefungModel->loadWhere( + array('student_uid' => $uid) + ); + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + if (!hasData($result)) + { + $warning = true; + $output[] = $uid; + } + } + if($warning) + { + $uids = is_array($output) ? implode(", ", $output) : $output; + return $this->terminateWithError($this->p->t('abschlusspruefung', 'error_studentOhneFinalExam', ['id'=> $uids]), self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess('step3'); + } +} diff --git a/application/controllers/api/frontend/v1/stv/Address.php b/application/controllers/api/frontend/v1/stv/Address.php index 7685fcd04..324e306f3 100644 --- a/application/controllers/api/frontend/v1/stv/Address.php +++ b/application/controllers/api/frontend/v1/stv/Address.php @@ -45,7 +45,7 @@ class Address extends FHCAPI_Controller $this->terminateWithSuccess($data); } - public function getPlaces($plz) + public function getPlaces($plz = null) { $this->load->model('codex/Gemeinde_model', 'GemeindeModel'); @@ -53,7 +53,7 @@ class Address extends FHCAPI_Controller $this->form_validation->set_data(['address.plz' => $plz]); - $this->form_validation->set_rules('address.plz', 'PLZ', 'numeric|less_than[10000]'); + $this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]'); if (!$this->form_validation->run()) $this->terminateWithValidationErrors($this->form_validation->error_array()); diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index c28c49485..42de1b02f 100644 --- a/application/controllers/api/frontend/v1/stv/Config.php +++ b/application/controllers/api/frontend/v1/stv/Config.php @@ -44,16 +44,23 @@ class Config extends FHCAPI_Controller 'person', 'lehre', 'stv', - 'konto' + 'konto', + 'abschlusspruefung' ]); + + // Load Config + $this->load->config('stv'); } public function student() { $result = []; + $config = $this->config->item('tabs'); + $result['details'] = [ 'title' => $this->p->t('stv', 'tab_details'), - 'component' => './Stv/Studentenverwaltung/Details/Details.js' + 'component' => './Stv/Studentenverwaltung/Details/Details.js', + 'config' => $config['details'] ]; $result['notes'] = [ 'title' => $this->p->t('stv', 'tab_notes'), @@ -69,7 +76,8 @@ class Config extends FHCAPI_Controller ]; $result['prestudent'] = [ 'title' => $this->p->t('stv', 'tab_prestudent'), - 'component' => './Stv/Studentenverwaltung/Details/Prestudent.js' + 'component' => './Stv/Studentenverwaltung/Details/Prestudent.js', + 'config' => $config['prestudent'] ]; $result['status'] = [ 'title' => 'Status', @@ -91,12 +99,34 @@ class Config extends FHCAPI_Controller 'title' => $this->p->t('stv', 'tab_resources'), 'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js' ]; - /* TODO(chris): Ausgeblendet für Testing $result['grades'] = [ 'title' => $this->p->t('stv', 'tab_grades'), - 'component' => './Stv/Studentenverwaltung/Details/Noten.js' + 'component' => './Stv/Studentenverwaltung/Details/Noten.js', + 'showOnlyWithUid' => true, + 'config' => [ + 'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE, + 'edit' => 'both', // Possible values: both|header|inline + 'delete' => 'both', // Possible values: both|header|inline + 'documents' => 'both', // Possible values: both|header|inline + 'documentslist' => $this->gradesDocumentsList() + ] + ]; + + $result['exam'] = [ + 'title' => $this->p->t('stv', 'tab_exam'), + 'component' => './Stv/Studentenverwaltung/Details/Pruefung.js' + ]; + + $result['finalexam'] = [ + 'title' => $this->p->t('stv', 'tab_finalexam'), + 'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js', + 'config' => $config['finalexam'] + ]; + + $result['mobility'] = [ + 'title' => $this->p->t('stv', 'tab_mobility'), + 'component' => './Stv/Studentenverwaltung/Details/Mobility.js' ]; - */ Events::trigger('stv_conf_student', function & () use (&$result) { return $result; @@ -108,6 +138,7 @@ class Config extends FHCAPI_Controller public function students() { $result = []; + $config = $this->config->item('tabs'); $result['banking'] = [ 'title' => $this->p->t('stv', 'tab_banking'), 'component' => './Stv/Studentenverwaltung/Details/Konto.js', @@ -131,6 +162,11 @@ class Config extends FHCAPI_Controller 'changeStatusToAbsolvent' => $this->permissionlib->isBerechtigt('admin') ] ]; + $result['finalexam'] = [ + 'title' => $this->p->t('stv', 'tab_finalexam'), + 'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js', + 'config' => $config['finalexam'] + ]; Events::trigger('stv_conf_students', function & () use (&$result) { return $result; @@ -230,4 +266,186 @@ class Config extends FHCAPI_Controller ] ] + $this->kontoColumns(); } + + /** + * Helper function to generate the default documentslist config for the + * grades tab. + * + * The resulting array consists of elements which are associative arrays + * that can have the following entries: + * title (required) on the first level this can be HTML code. + * permissioncheck (optional) an URL to an FHCAPI endpoint which returns + * true or false. + * link (optional) an URL that will be called if "action" and + * "children" are not defined. + * action (optional) an associative array that describes an + * POST action that will be called if "children" is + * not defined. + * It can have the following entries: + * - url (required) an URL to an FHCAPI endpoint. + * - post (optional) an associative array with the POST data to + * be sent. + * - response (optional) a string that will be displayed on success. + * children (optional) an array of child elements + * + * All strings that start with { and end with } in the URLs and the + * actions post parameter will be replaced with the corresponding + * attribute of the current dataset (e.G: {uid} will be replaced with the + * uid of the current dataset) + * + * @return array + */ + protected function gradesDocumentsList() + { + $permissioncheck = site_url("api/frontend/v1/documents/permissionAlternativeFormat/{studiengang_kz}"); + + $title_ger = $this->p->t("global", "deutsch"); + $title_eng = $this->p->t("global", "englisch"); + $title_ff = $this->p->t("stv", "document_certificate"); + $title_lv = $this->p->t("stv", "document_coursecertificate"); + + $link_ff = "documents/export/" . + "zertifikat.rdf.php/" . + "Zertifikat" . + "?stg_kz={studiengang_kz_lv}" . + "&uid={uid}" . + "&ss={studiensemester_kurzbz}" . + "&lvid={lehrveranstaltung_id}"; + $link_lv_ger = "documents/export/" . + "lehrveranstaltungszeugnis.rdf.php/" . + "LVZeugnis" . + "?stg_kz={studiengang_kz}" . + "&uid={uid}" . + "&ss={studiensemester_kurzbz}" . + "&lvid={lehrveranstaltung_id}"; + $link_lv_eng = "documents/export/" . + "lehrveranstaltungszeugnis.rdf.php/" . + "LVZeugnisEng" . + "?stg_kz={studiengang_kz}" . + "&uid={uid}" . + "&ss={studiensemester_kurzbz}" . + "&lvid={lehrveranstaltung_id}"; + + $archive_url = "api/frontend/v1/documents/archiveSigned"; + $archive_response = $this->p->t("stv", "document_signed_and_archived"); + $archive_post_ff = [ + "xml" => "zertifikat.rdf.php", + "xsl" => "Zertifikat", + "stg_kz" => "{studiengang_kz_lv}", + "uid" => "{uid}", + "ss" => "{studiensemester_kurzbz}", + "lvid" => "{lehrveranstaltung_id}" + ]; + $archive_post_lv_ger = [ + "xml" => "lehrveranstaltungszeugnis.rdf.php", + "xsl" => "LVZeugnis", + "stg_kz" => "{studiengang_kz}", + "uid" => "{uid}", + "ss" => "{studiensemester_kurzbz}", + "lvid" => "{lehrveranstaltung_id}" + ]; + $archive_post_lv_eng = [ + "xml" => "lehrveranstaltungszeugnis.rdf.php", + "xsl" => "LVZeugnisEng", + "stg_kz" => "{studiengang_kz}", + "uid" => "{uid}", + "ss" => "{studiensemester_kurzbz}", + "lvid" => "{lehrveranstaltung_id}" + ]; + + $list = [ + [ + 'title' => '', + 'children' => [ + [ + 'title' => $title_ff, + 'link' => site_url($link_ff) + ], + [ + 'title' => $title_lv, + 'children' => [ + [ + 'title' => $title_ger, + 'link' => site_url($link_lv_ger), + 'children' => [ + [ + 'title' => 'PDF', + 'permissioncheck' => $permissioncheck, + 'link' => site_url($link_lv_ger) + ], + [ + 'title' => 'DOC', + 'permissioncheck' => $permissioncheck, + 'link' => site_url($link_lv_ger . "&output=doc") + ], + [ + 'title' => 'ODT', + 'permissioncheck' => $permissioncheck, + 'link' => site_url($link_lv_ger . "&output=odt") + ] + ] + ], + [ + 'title' => $title_eng, + 'link' => site_url($link_lv_eng), + 'children' => [ + [ + 'title' => 'PDF', + 'permissioncheck' => $permissioncheck, + 'link' => site_url($link_lv_eng) + ], + [ + 'title' => 'DOC', + 'permissioncheck' => $permissioncheck, + 'link' => site_url($link_lv_eng . "&output=doc") + ], + [ + 'title' => 'ODT', + 'permissioncheck' => $permissioncheck, + 'link' => site_url($link_lv_eng . "&output=odt") + ] + ] + ] + ] + ] + ] + ], + [ + 'title' => '', + 'children' => [ + [ + 'title' => $title_ff, + 'action' => [ + 'url' => site_url($archive_url), + 'post' => $archive_post_ff, + 'response' => $archive_response + ] + ], + [ + 'title' => $title_lv, + 'children' => [ + [ + 'title' => $title_ger, + 'action' => [ + 'url' => site_url($archive_url), + 'post' => $archive_post_lv_ger, + 'response' => $archive_response + ] + ], + [ + 'title' => $title_eng, + 'action' => [ + 'url' => site_url($archive_url), + 'post' => $archive_post_lv_eng, + 'response' => $archive_response + ] + ] + ] + ] + ] + ] + ]; + + return $list; + } } diff --git a/application/controllers/api/frontend/v1/stv/Favorites.php b/application/controllers/api/frontend/v1/stv/Favorites.php index 8d7a6cd14..b8fe6f3d7 100644 --- a/application/controllers/api/frontend/v1/stv/Favorites.php +++ b/application/controllers/api/frontend/v1/stv/Favorites.php @@ -48,7 +48,7 @@ class Favorites extends FHCAPI_Controller if (!$data) $this->terminateWithSuccess(null); else - $this->terminateWithSuccess($data['stv_favorites']); + $this->terminateWithSuccess($data['stv_favorites'] ?? null); } public function set() diff --git a/application/controllers/api/frontend/v1/stv/Grades.php b/application/controllers/api/frontend/v1/stv/Grades.php new file mode 100644 index 000000000..61d797495 --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Grades.php @@ -0,0 +1,685 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the back-end + * Provides data to the ajax get calls about grades + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Grades extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'list' => 'student/noten:r', + 'getCertificate' => 'student/noten:r', + 'getTeacherProposal' => 'student/noten:r', + 'getRepeaterGrades' => 'student/noten:r', + 'updateCertificate' => ['admin:w', 'assistenz:w'], + 'deleteCertificate' => ['admin:w', 'assistenz:w'], + 'copyTeacherProposalToCertificate' => 'student/noten:w', + 'copyRepeaterGradeToCertificate' => 'student/noten:w', + 'getGradeFromPoints' => 'student/noten:r' + ]); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load Phrases + $this->loadPhrases([ + 'stv', + 'person', + 'lehre' + ]); + } + + /** + * List all possible grades + * (Entries in lehre.tbl_note) + * + * @return void + */ + public function list() + { + $this->load->model('codex/Note_model', 'NoteModel'); + + $this->NoteModel->addOrder('note'); + + $result = $this->NoteModel->load(); + + $grades = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($grades); + } + + /** + * List grades for the certificate of a prestudent. + * (Entries in lehre.tbl_zeugnisnote) + * + * @param string $prestudent_id + * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded. + * + * @return void + */ + public function getCertificate($prestudent_id, $all = null) + { + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $result = $this->StudentModel->loadWhere([ + 'prestudent_id' => $prestudent_id + ]); + + $student = $this->getDataOrTerminateWithError($result); + if (!$student) + $this->terminateWithSuccess([]); + + + $student_uid = current($student)->student_uid; + + $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null; + + + $result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz); + + $grades = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($grades); + } + + /** + * List grades of a prestudent that teachers gave. + * (Entries in campus.tbl_lvgesamtnote) + * + * @param string $prestudent_id + * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded. + * + * @return void + */ + public function getTeacherProposal($prestudent_id, $all = null) + { + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel'); + + $result = $this->StudentModel->loadWhere([ + 'prestudent_id' => $prestudent_id + ]); + + $student = $this->getDataOrTerminateWithError($result); + if (!$student) + $this->terminateWithSuccess([]); + + + $student_uid = current($student)->student_uid; + + $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null; + + + $result = $this->LvgesamtnoteModel->getLvGesamtNoten(null, $student_uid, $studiensemester_kurzbz); + + $grades = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($grades); + } + + /** + * List grades of a prestudent that an assistant marked as already done + * or as not allowed because of the repeating of a semester. + * + * @param string $prestudent_id + * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded. + * + * @return void + */ + public function getRepeaterGrades($prestudent_id, $all = null) + { + $this->load->library('AntragLib'); + + $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : false; + + + $result = $this->antraglib->getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz); + + $grades = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($grades); + } + + /** + * Update or Insert a grade for the certificate of a prestudent. + * (Entry in lehre.tbl_zeugnisnote) + * + * @return void + */ + public function updateCertificate() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer"); + $this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required"); + $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required"); + $this->form_validation->set_rules('note', $this->p->t('lehre', 'note'), 'required|numeric'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + $student_uid = $this->input->post('student_uid'); + $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id'); + $note = $this->input->post('note'); + $authUID = getAuthUID(); + $now = date('c'); + + // NOTE(chris): Stg Permissions + if (!$this->hasPermissionUpdate($lehrveranstaltung_id, $student_uid)) + return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]); + + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $result = $this->ZeugnisnoteModel->load([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ]); + $current = $this->getDataOrTerminateWithError($result); + + if ($current) { + $result = $this->ZeugnisnoteModel->update([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ], [ + 'note' => $note, + 'benotungsdatum' => $now, + 'updateamum' => $now, + 'updatevon' => $authUID + ]); + } else { + $result = $this->ZeugnisnoteModel->insert([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + 'lehrveranstaltung_id' => $lehrveranstaltung_id, + 'note' => $note, + 'benotungsdatum' => $now, + 'insertamum' => $now, + 'insertvon' => $authUID + ]); + } + $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(true); + } + + /** + * Delete a grade from the certificate of a prestudent. + * (Entry in lehre.tbl_zeugnisnote) + * + * @return void + */ + public function deleteCertificate() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer"); + $this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required"); + $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + $student_uid = $this->input->post('student_uid'); + $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id'); + + // NOTE(chris): Stg Permissions + if (!$this->hasPermissionDelete($lehrveranstaltung_id, $student_uid)) + return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]); + + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $result = $this->ZeugnisnoteModel->delete([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ]); + $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(true); + } + + /** + * Copy a grade that teachers gave to the certificate of a prestudent. + * (Entry in campus.tbl_lvgesamtnote to an entry in lehre.tbl_zeugnisnote) + * + * @return void + */ + public function copyTeacherProposalToCertificate() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer"); + $this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required"); + $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id'); + $student_uid = $this->input->post('student_uid'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + $authUID = getAuthUID(); + + // NOTE(chris): Stg Permissions + if (!$this->hasPermissionCopy($lehrveranstaltung_id, $student_uid)) + return $this->_outputAuthError([$this->router->method => 'student/noten']); + + $this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel'); + + $result = $this->LvgesamtnoteModel->load([ + 'student_uid' => $student_uid, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ]); + $teacherGrade = $this->getDataOrTerminateWithError($result); + + if (!$teacherGrade) + show_404(); + + $teacherGrade = current($teacherGrade); + + $data = [ + 'note' => $teacherGrade->note, + 'punkte' => $teacherGrade->punkte, + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $teacherGrade->benotungsdatum, + 'bemerkung' => $teacherGrade->bemerkung + ]; + + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $this->ZeugnisnoteModel->addJoin('lehre.tbl_note n', 'note'); + $result = $this->ZeugnisnoteModel->load([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ]); + $certificateGrade = $this->getDataOrTerminateWithError($result); + + if ($certificateGrade) { + $certificateGrade = current($certificateGrade); + + if (!$certificateGrade->lkt_ueberschreibbar) + $this->terminateWithError($this->p->t("stv", "grades_error_overwrite")); + + // NOTE(chris): update + $data['updateamum'] = $data['uebernahmedatum']; + $data['updatevon'] = $authUID; + + $this->ZeugnisnoteModel->update([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ], $data); + } else { + // NOTE(chris): insert + $data['insertamum'] = $data['uebernahmedatum']; + $data['insertvon'] = $authUID; + $data['lehrveranstaltung_id'] = $lehrveranstaltung_id; + $data['student_uid'] = $student_uid; + $data['studiensemester_kurzbz'] = $studiensemester_kurzbz; + + $this->ZeugnisnoteModel->insert($data); + + if (defined('FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN') + && FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN) { + $result = $this->addTestsForGrade( + $studiensemester_kurzbz, + $student_uid, + $lehrveranstaltung_id, + $teacherGrade->note, + $teacherGrade->punkte + ); + $this->getDataOrTerminateWithError($result); + } + } + + + $this->terminateWithSuccess(true); + } + + /** + * Copy a grade that was marked by an assistant as already done or not + * allowed because of the repeating of a semester to the certificate of a + * prestudent. + * + * @return void + */ + public function copyRepeaterGradeToCertificate() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules("studierendenantrag_lehrveranstaltung_id", "studierendenantrag_lehrveranstaltung_id", "required|integer"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $id = $this->input->post('studierendenantrag_lehrveranstaltung_id'); + $authUID = getAuthUID(); + + $this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel'); + + $this->StudierendenantraglehrveranstaltungModel->addSelect("tbl_studierendenantrag_lehrveranstaltung.*"); + $this->StudierendenantraglehrveranstaltungModel->addSelect("student_uid"); + $this->StudierendenantraglehrveranstaltungModel->addJoin("campus.tbl_studierendenantrag", "studierendenantrag_id"); + $this->StudierendenantraglehrveranstaltungModel->addJoin("public.tbl_student", "prestudent_id", "LEFT"); + + $result = $this->StudierendenantraglehrveranstaltungModel->load($id); + $repeaterGrade = $this->getDataOrTerminateWithError($result); + + if (!$repeaterGrade) + show_404(); + + $repeaterGrade = current($repeaterGrade); + + // NOTE(chris): Stg Permissions + if (!$this->hasPermissionCopy($repeaterGrade->lehrveranstaltung_id, $repeaterGrade->student_uid)) + return $this->_outputAuthError([$this->router->method => 'student/noten']); + + $data = [ + 'note' => $repeaterGrade->note, + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $repeaterGrade->insertamum, + 'bemerkung' => $repeaterGrade->anmerkung + ]; + + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $result = $this->ZeugnisnoteModel->load([ + $repeaterGrade->studiensemester_kurzbz, + $repeaterGrade->student_uid, + $repeaterGrade->lehrveranstaltung_id + ]); + $certificateGrade = $this->getDataOrTerminateWithError($result); + + if ($certificateGrade) { + // NOTE(chris): update + $data['updateamum'] = $data['uebernahmedatum']; + $data['updatevon'] = $authUID; + + $this->ZeugnisnoteModel->update([ + $repeaterGrade->studiensemester_kurzbz, + $repeaterGrade->student_uid, + $repeaterGrade->lehrveranstaltung_id + ], $data); + } else { + // NOTE(chris): insert + $data['insertamum'] = $data['uebernahmedatum']; + $data['insertvon'] = $authUID; + $data['lehrveranstaltung_id'] = $repeaterGrade->lehrveranstaltung_id; + $data['student_uid'] = $repeaterGrade->student_uid; + $data['studiensemester_kurzbz'] = $repeaterGrade->studiensemester_kurzbz; + + $this->ZeugnisnoteModel->insert($data); + } + + + $this->terminateWithSuccess(true); + } + + /** + * Loads the grade from the points using the gradingkey + * + * @return void + */ + public function getGradeFromPoints() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer"); + $this->form_validation->set_rules("points", $this->p->t("stv", "grades_points"), "required|numeric"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $this->load->model('education/Notenschluesselaufteilung_model', 'NotenschluesselaufteilungModel'); + + $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + + $result = $this->NotenschluesselaufteilungModel->getNote( + $this->input->post('points'), + $this->input->post('lehrveranstaltung_id'), + $studiensemester_kurzbz + ); + + $note = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($note); + } + + /** + * Helper function that adds tests for a student + * (Entries in lehre.tbl_pruefung) + * + * @param string $studiensemester_kurzbz + * @param string $student_uid + * @param integer $lehrveranstaltung_id + * @param integer $note + * @param numeric $punkte + * + * @return stdClass + */ + protected function addTestsForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $note, $punkte) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + // Get Lehreinheit + $result = $this->LehrveranstaltungModel->getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id); + + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->p->t("stv", "grades_error_lehreinheit_id")); + $le = current(getData($result)); + + // Prepare + $this->load->model('education/LePruefung_model', 'LePruefungModel'); + $data = [ + "student_uid" => $student_uid, + "lehreinheit_id" => $le->lehreinheit_id, + "datum" => date('Y-m-d'), + "pruefungstyp_kurzbz" => "Termin1", + "note" => $note + ]; + + if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + $data["punkte"] = $punkte; + + // Get Anwesenheit + $this->load->model('education/Anwesenheit_model', 'AnwesenheitModel'); + $result = $this->AnwesenheitModel->loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id); + if (isError($result)) + return $result; + $anwesenheit = getData($result); + + if ($anwesenheit && (float)current($anwesenheit)->prozent < FAS_ANWESENHEIT_ROT) { + // Get Anwesenheitsbefreiung + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $result = $this->BenutzerfunktionModel->getBenutzerFunktionByUidInStdsem($student_uid, $studiensemester_kurzbz, 'awbefreit'); + + if (isError($result)) + return $result; + + $anwesenheitsbefreit = hasData($result); + + // Wenn nicht Anwesenheitsbefreit und Anwesenheit unter einem bestimmten Prozentsatz fällt dann wird ein Pruefungsantritt abgezogen + if (!$anwesenheitsbefreit) { + $data2 = $data; + $data2["note"] = 7; + if (isset($data2["punkte"])) + unset($data2["punkte"]); + + $result = $this->LePruefungModel->insert($data2); + + if (isError($result)) + return $result; + + $data["pruefungstyp_kurzbz"] = "Termin2"; + } + } + + return $this->LePruefungModel->insert($data); + } + + /** + * Helper function to check permissions for updateCertificate() + * + * @param integer $lehrveranstaltung_id + * @param string $student_uid + * + * @return boolean + */ + protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid) + { + if ($lehrveranstaltung_id === null || $student_uid === null) + return true; + + $this->load->model('crm/Student_model', 'StudentModel'); + + $result = $this->StudentModel->load([$student_uid]); + if (isError($result) || !hasData($result)) + return false; + + $student = current(getData($result)); + + if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)) + return true; + if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)) + return true; + + $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); + + $result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id); + if (isError($result)) + return false; + + $oes = getData($result) ?: []; + + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id); + if (isError($result)) + return false; + + if (hasData($result)) + $oes[] = current(getData($result)); + + foreach ($oes as $oe) { + if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz)) + return true; + if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz)) + return true; + } + + return false; + } + + /** + * Helper function to check permissions for deleteCertificate() + * + * @param integer $lehrveranstaltung_id + * @param string $student_uid + * + * @return boolean + */ + protected function hasPermissionDelete($lehrveranstaltung_id, $student_uid) + { + if ($lehrveranstaltung_id === null || $student_uid === null) + return true; + + $this->load->model('crm/Student_model', 'StudentModel'); + + $result = $this->StudentModel->load([$student_uid]); + if (isError($result) || !hasData($result)) + return false; + + $student = current(getData($result)); + + if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)) + return true; + if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)) + return true; + + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id); + if (isError($result) || !hasData($result)) + return false; + + $oe = current(getData($result)); + + if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz)) + return true; + if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz)) + return true; + + return false; + } + + /** + * Helper function to check permissions for + * copyTeacherProposalToCertificate() and copyRepeaterGradeToCertificate() + * + * @param integer $lehrveranstaltung_id + * @param string $student_uid + * + * @return boolean + */ + protected function hasPermissionCopy($lehrveranstaltung_id, $student_uid) + { + if ($lehrveranstaltung_id === null || $student_uid === null) + return true; + + $this->load->model('crm/Student_model', 'StudentModel'); + + $result = $this->StudentModel->load([$student_uid]); + if (isError($result) || !hasData($result)) + return false; + + $student = current(getData($result)); + + if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $student->studiengang_kz)) + return true; + + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id); + if (isError($result) || !hasData($result)) + return false; + + $oe = current(getData($result)); + + if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->oe_kurzbz)) + return true; + + return false; + } +} diff --git a/application/controllers/api/frontend/v1/stv/Kontakt.php b/application/controllers/api/frontend/v1/stv/Kontakt.php index 379184ee0..bcd38853c 100644 --- a/application/controllers/api/frontend/v1/stv/Kontakt.php +++ b/application/controllers/api/frontend/v1/stv/Kontakt.php @@ -85,7 +85,10 @@ class Kontakt extends FHCAPI_Controller || $this->router->method == 'addNewBankverbindung' ) { $person_id = current(array_slice($this->uri->rsegments, 2)); - + + if (is_null($person_id) || !ctype_digit((string)$person_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + $this->checkPermissionsForPerson($person_id, $permsMa, $permsStud); } elseif ($this->router->method == 'loadAddress' || $this->router->method == 'loadContact' @@ -97,7 +100,14 @@ class Kontakt extends FHCAPI_Controller || $this->router->method == 'deleteContact' || $this->router->method == 'deleteBankverbindung' ) { - $id = current(array_slice($this->uri->rsegments, 2)); + if($this->input->post('address_id')) + $id = $this->input->post('address_id'); + if($this->input->post('adresse_id')) + $id = $this->input->post('adresse_id'); + if($this->input->post('bankverbindung_id')) + $id = $this->input->post('bankverbindung_id'); + if($this->input->post('kontakt_id')) + $id = $this->input->post('kontakt_id'); $model = 'person/Adresse_model'; if ($this->router->method == 'loadContact' @@ -112,6 +122,9 @@ class Kontakt extends FHCAPI_Controller $model = 'person/Bankverbindung_model'; } + if (!isset($id) || !ctype_digit((string)$id)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + $this->load->model($model, 'TempModel'); $result = $this->TempModel->load($id); $data = $this->getDataOrTerminateWithError($result); @@ -125,7 +138,12 @@ class Kontakt extends FHCAPI_Controller } public function getAdressen($person_id) { - $this->AdresseModel->addSelect('public.tbl_adresse.*'); + $this->AdresseModel->addSelect("public.tbl_adresse.*, + (CASE + WHEN public.tbl_adresse.updateamum >= public.tbl_adresse.insertamum + THEN public.tbl_adresse.updateamum + ELSE public.tbl_adresse.insertamum + END) AS lastUpdate"); $this->AdresseModel->addSelect('t.*'); $this->AdresseModel->addSelect('f.firma_id'); $this->AdresseModel->addSelect('f.name as firmenname'); @@ -143,15 +161,26 @@ class Kontakt extends FHCAPI_Controller public function addNewAddress($person_id) { - $this->form_validation->set_rules('plz', 'PLZ', 'required|numeric', [ + $this->form_validation->set_data(['address.plz' => $_POST['plz']]); + + $this->form_validation->set_rules('address.plz', 'PLZ', 'required', [ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']), - 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']) ]); - if(isset($_POST['gemeinde']) && isset($_POST['ort'])) - $this->form_validation->set_rules('plz', 'Postleitzahl', 'callback_validateLocationCombination', [ - 'validateLocationCombination' => $this->p->t('ui', 'error_location_combination') - ]); + if(isset($_POST['nation']) && $_POST['nation'] == 'A') + { + $this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']), + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']) + ]); + } + + if(isset($_POST['gemeinde']) && isset($_POST['ort']) && isset($_POST['nation']) && $_POST['nation'] == 'A') + { + $this->form_validation->set_rules('address.plz', 'Postleitzahl', 'callback_validateLocationCombination', [ + 'validateLocationCombination' => $this->p->t('ui', 'error_location_combination') + ]); + } if ($this->form_validation->run() == false) { @@ -196,25 +225,37 @@ class Kontakt extends FHCAPI_Controller ] ); - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - return $this->outputJsonSuccess(true); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); } - public function updateAddress($address_id) + public function updateAddress() { + $address_id = $this->input->post('adresse_id'); + + $this->form_validation->set_data(['address.plz' => $_POST['plz']]); + $uid = getAuthUID(); - $this->form_validation->set_rules('plz', 'PLZ', 'required|numeric', [ + + $this->form_validation->set_rules('address.plz', 'PLZ', 'required', [ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']), - 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']) ]); - if(isset($_POST['gemeinde']) && isset($_POST['ort'])) - $this->form_validation->set_rules('plz', 'Postleitzahl', 'callback_validateLocationCombination', [ + if(isset($_POST['nation']) && $_POST['nation'] == 'A') + { + $this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']), + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']) + ]); + } + + if(isset($_POST['gemeinde']) && isset($_POST['ort']) && isset($_POST['nation']) && $_POST['nation'] == 'A') + { + $this->form_validation->set_rules('address.plz', 'Postleitzahl', 'callback_validateLocationCombination', [ 'validateLocationCombination' => $this->p->t('ui', 'error_location_combination') ]); + } if ($this->form_validation->run() == false) { @@ -272,15 +313,15 @@ class Kontakt extends FHCAPI_Controller ] ); - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - return $this->outputJsonSuccess(true); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); } - public function loadAddress($adresse_id) + public function loadAddress() { + $adresse_id = $this->input->post('address_id'); + $this->load->model('person/Adresse_model', 'AdresseModel'); $this->AdresseModel->addSelect('public.tbl_adresse.*'); @@ -306,8 +347,10 @@ class Kontakt extends FHCAPI_Controller $this->terminateWithSuccess(current(getData($result)) ? : null); } - public function deleteAddress($adresse_id) + public function deleteAddress() { + $adresse_id = $this->input->post('address_id'); + $this->load->model('person/Adresse_model', 'AdresseModel'); $result = $this->AdresseModel->load([ 'adresse_id'=> $adresse_id, @@ -350,8 +393,11 @@ class Kontakt extends FHCAPI_Controller $this->terminateWithSuccess(getData($result) ?: []); } - public function getFirmen($searchString) + public function getFirmen($searchString = null) { + if (is_null($searchString)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + $this->load->model('ressource/firma_model', 'FirmaModel'); $result = $this->FirmaModel->searchFirmen($searchString); @@ -361,19 +407,25 @@ class Kontakt extends FHCAPI_Controller $this->terminateWithSuccess($result ?: []); } - public function getStandorte($searchString) + public function getStandorte($searchString = null) { + if (is_null($searchString)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + $this->load->model('organisation/standort_model', 'StandortModel'); $result = $this->StandortModel->searchStandorte($searchString); - if (isError($result)) { - $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - $this->terminateWithSuccess($result ?: []); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); } - public function getStandorteByFirma($firma_id) + public function getStandorteByFirma($firma_id = null) { + if (is_null($firma_id) || !ctype_digit((string)$firma_id)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + $this->load->model('organisation/standort_model', 'StandortModel'); $result = $this->StandortModel->getStandorteByFirma($firma_id); @@ -386,11 +438,11 @@ class Kontakt extends FHCAPI_Controller public function getKontakte($person_id) { $this->KontaktModel->addSelect("public.tbl_kontakt.*, - TO_CHAR (CASE - WHEN public.tbl_kontakt.updateamum >= public.tbl_kontakt.insertamum - THEN public.tbl_kontakt.updateamum - ELSE public.tbl_kontakt.insertamum - END::timestamp, 'DD.MM.YYYY HH24:MI:SS') AS lastUpdate, st.bezeichnung, f.name"); + (CASE + WHEN public.tbl_kontakt.updateamum >= public.tbl_kontakt.insertamum + THEN public.tbl_kontakt.updateamum + ELSE public.tbl_kontakt.insertamum + END) AS lastUpdate, st.bezeichnung, f.name"); $this->StandortModel->addJoin('public.tbl_standort st', 'ON (public.tbl_kontakt.standort_id = st.standort_id)', 'LEFT'); $this->FirmaModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = st.firma_id)', 'LEFT'); $result = $this->KontaktModel->loadWhere( @@ -418,8 +470,9 @@ class Kontakt extends FHCAPI_Controller } } - public function loadContact($kontakt_id) + public function loadContact() { + $kontakt_id = $this->input->post('kontakt_id'); $this->load->model('person/Kontakt_model', 'KontaktModel'); $this->KontaktModel->addSelect('*, public.tbl_kontakt.*'); @@ -439,7 +492,6 @@ class Kontakt extends FHCAPI_Controller { return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Kontakt_id']), self::ERROR_TYPE_GENERAL); } - // $this->outputJsonSuccess(current(getData($result))); $this->terminateWithSuccess(current(getData($result))); } @@ -492,11 +544,12 @@ class Kontakt extends FHCAPI_Controller { return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->outputJsonSuccess(true); + $this->terminateWithSuccess($result); } - public function updateContact($kontakt_id) + public function updateContact() { + $kontakt_id = $this->input->post('kontakt_id'); $this->load->model('person/Kontakt_model', 'KontaktModel'); if(!$kontakt_id) @@ -523,13 +576,6 @@ class Kontakt extends FHCAPI_Controller $this->terminateWithValidationErrors($this->form_validation->error_array()); } -/* if(isset($_POST['standort'])) - { - $standort_id = $_POST['standort']['standort_id']; - } - else - $standort_id = null;*/ - $uid = getAuthUID(); $kontakttyp = $this->input->post('kontakttyp'); $anmerkung = $this->input->post('anmerkung'); @@ -538,8 +584,6 @@ class Kontakt extends FHCAPI_Controller $person_id = $this->input->post('person_id'); $standort_id = $this->input->post('standort_id'); - //return $this->terminateWithError("in update " . $standort_id, self::ERROR_TYPE_GENERAL); - $result = $this->KontaktModel->update( [ 'kontakt_id' => $kontakt_id @@ -557,15 +601,14 @@ class Kontakt extends FHCAPI_Controller ] ); - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - return $this->outputJsonSuccess(true); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); } - public function deleteContact($kontakt_id) + public function deleteContact() { + $kontakt_id = $this->input->post('kontakt_id'); $this->load->model('person/Kontakt_model', 'KontaktModel'); $result = $this->KontaktModel->delete( @@ -624,6 +667,9 @@ class Kontakt extends FHCAPI_Controller $bic = $this->input->post('bic'); $blz = $this->input->post('blz'); $kontonr = $this->input->post('kontonr'); + $iban = $this->input->post('iban'); + $typ = $this->input->post('typ'); + $verrechnung = $this->input->post('verrechnung'); $result = $this->BankverbindungModel->insert( [ @@ -631,27 +677,27 @@ class Kontakt extends FHCAPI_Controller 'name' => $name, 'anschrift' => $anschrift, 'bic' => $bic, - 'iban' => $_POST['iban'], + 'iban' => $iban, 'blz' => $blz, 'kontonr' => $kontonr, 'insertvon' => 'uid', 'insertamum' => date('c'), - 'typ' => $_POST['typ'], - 'verrechnung' => $_POST['verrechnung'], + 'typ' => $typ, + 'verrechnung' => $verrechnung, 'ext_id' => $ext_id, 'oe_kurzbz' => $oe_kurzbz, 'orgform_kurzbz' => $orgform_kurzbz ] ); - if (isError($result)) - { - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - return $this->outputJsonSuccess(true); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); } - public function loadBankverbindung($bankverbindung_id) + public function loadBankverbindung() { + $bankverbindung_id = $this->input->post('bankverbindung_id'); + $this->load->model('person/Bankverbindung_model', 'BankverbindungModel'); $this->BankverbindungModel->addSelect('*'); @@ -719,15 +765,15 @@ class Kontakt extends FHCAPI_Controller ] ); - if (isError($result)) - { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - return $this->outputJsonSuccess(true); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); } - public function deleteBankverbindung($bankverbindung_id) + public function deleteBankverbindung() { + $bankverbindung_id = $this->input->post('bankverbindung_id'); + $this->load->model('person/Bankverbindung_model', 'BankverbindungModel'); $result = $this->BankverbindungModel->delete( @@ -740,7 +786,7 @@ class Kontakt extends FHCAPI_Controller } if (!hasData($result)) { - $this->outputJson($result); + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Bankverbindung_id']), self::ERROR_TYPE_GENERAL); } return $this->terminateWithSuccess(current(getData($result)) ? : null); } diff --git a/application/controllers/api/frontend/v1/stv/Mobility.php b/application/controllers/api/frontend/v1/stv/Mobility.php new file mode 100644 index 000000000..2ab0ac682 --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Mobility.php @@ -0,0 +1,528 @@ + ['admin:r', 'assistenz:r'], + 'loadMobility' => ['admin:r', 'assistenz:r'], + 'insertMobility' => ['admin:rw', 'assistenz:rw'], + 'updateMobility' => ['admin:rw', 'assistenz:rw'], + 'deleteMobility' => ['admin:rw', 'assistenz:rw'], + 'getProgramsMobility' => ['admin:r', 'assistenz:r'], + 'getLVList' => ['admin:r', 'assistenz:r'], + 'getAllLehreinheiten' => ['admin:r', 'assistenz:r'], + 'getLvsandLesByStudent' => ['admin:r', 'assistenz:r'], + 'getPurposes' => ['admin:r', 'assistenz:r'], + 'getSupports' => ['admin:r', 'assistenz:r'], + 'getListPurposes' => ['admin:r', 'assistenz:r'], + 'getListSupports' => ['admin:r', 'assistenz:r'], + 'deleteMobilityPurpose' => ['admin:r', 'assistenz:r'], + 'addMobilityPurpose' => ['admin:r', 'assistenz:r'], + 'deleteMobilitySupport' => ['admin:r', 'assistenz:r'], + 'addMobilitySupport' => ['admin:r', 'assistenz:r'], + ]); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $this->load->library('form_validation'); + + // Load language phrases + $this->loadPhrases([ + 'ui', + 'mobility' + ]); + + // Load models + $this->load->model('codex/Bisio_model', 'BisioModel'); + } + + public function getMobilitaeten($student_uid) + { + $this->BisioModel->addSelect("*"); + $this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT'); + $this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)','LEFT'); + $this->BisioModel->addOrder('von', 'DESC'); + $this->BisioModel->addOrder('bis', 'DESC'); + $this->BisioModel->addOrder('bisio_id', 'DESC'); + $result = $this->BisioModel->loadWhere( + array('student_uid' => $student_uid) + ); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getProgramsMobility() + { + $this->load->model('codex/Mobilitaetsprogramm_model', 'MobilitaetsprogrammModel'); + + $result = $this->MobilitaetsprogrammModel->load(); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function insertMobility() + { + $this->load->library('form_validation'); + $authUID = getAuthUID(); + + $student_uid = $this->input->post('uid'); + + if(!$student_uid) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL); + } + + $formData = $this->input->post('formData'); + + $_POST['von'] = (isset($formData['von']) && !empty($formData['von'])) ? $formData['von'] : null; + $_POST['bis'] = (isset($formData['bis']) && !empty($formData['bis'])) ? $formData['bis'] : null; + $_POST['nation_code'] = (isset($formData['nation_code']) && !empty($formData['nation_code'])) ? $formData['nation_code'] : 'A'; + $_POST['mobilitaetsprogramm_code'] = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code'])) ? $formData['mobilitaetsprogramm_code'] : null; + $_POST['herkunftsland_code'] = (isset($formData['herkunftsland_code']) && !empty($formData['herkunftsland_code'])) ? $formData['herkunftsland_code'] : 'A'; + $_POST['ects_erworben'] = (isset($formData['ects_erworben']) && !empty($formData['ects_erworben'])) ? $formData['ects_erworben'] : null; + $_POST['ects_angerechnet'] = (isset($formData['ects_angerechnet']) && !empty($formData['ects_angerechnet'])) ? $formData['ects_angerechnet'] : null; + $_POST['lehreinheit_id'] = (isset($formData['lehreinheit_id']) && !empty($formData['lehreinheit_id'])) ? $formData['lehreinheit_id'] : null; + + $this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code']) + ]); + $this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code']) + ]); + $this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code']) + ]); + $this->form_validation->set_rules('von', 'VonDatum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum']) + ]); + + $this->form_validation->set_rules('bis', 'VBisDatum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VBisDatum']) + ]); + + $this->form_validation->set_rules('ects_erworben', 'Ects_erworben', 'numeric', [ + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_erworben']) + ]); + + $this->form_validation->set_rules('ects_angerechnet', 'Ects_angerechnet', 'numeric', [ + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_angerechnet']) + ]); + + $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'numeric', [ + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit']) + ]); + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $ort = (isset($formData['ort']) && !empty($formData['ort'])) ? $formData['ort'] : null; + $universitaet = (isset($formData['universitaet']) && !empty($formData['universitaet'])) ? $formData['universitaet'] : null; + $localPurposes = (isset($formData['localPurposes']) && !empty($formData['localPurposes'])) ? $formData['localPurposes'] : null; + $localSupports = (isset($formData['localSupports']) && !empty($formData['localSupports'])) ? $formData['localSupports'] : null; + + $result = $this->BisioModel->insert([ + 'student_uid' => $student_uid, + 'von' => $_POST['von'], + 'bis' => $_POST['bis'], + 'mobilitaetsprogramm_code' => $_POST['mobilitaetsprogramm_code'], + 'nation_code' => $_POST['nation_code'], + 'herkunftsland_code' => $_POST['herkunftsland_code'], + 'lehreinheit_id' => $_POST['lehreinheit_id'], + 'ort' => $ort, + 'universitaet' => $universitaet, + 'ects_erworben' => $_POST['ects_erworben'] , + 'ects_angerechnet' => $_POST['ects_angerechnet'], + 'insertamum' => date('c'), + 'insertvon' => $authUID, + ]); + + $bisio_id = $this->getDataOrTerminateWithError($result); + + //check if localData (purposes) + if(count($localPurposes) > 0){ + foreach ($localPurposes as $zweck){ + $zweck = (int)$zweck; + $this->addMobilityPurpose($bisio_id, $zweck); + } + } + + //check if localData (supports) + if(count($localSupports) > 0){ + foreach ($localSupports as $support){ + $this->addMobilitySupport($bisio_id, $support); + } + } + + $this->terminateWithSuccess($bisio_id); + } + + public function loadMobility($bisio_id) + { + $this->BisioModel->addSelect("*"); + $this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT'); + $this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)','LEFT'); + $result = $this->BisioModel->loadWhere( + array('bisio_id' => $bisio_id) + ); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function updateMobility() + { + + $this->load->library('form_validation'); + $authUID = getAuthUID(); + + $student_uid = $this->input->post('uid'); + + if(!$student_uid) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL); + } + $formData = $this->input->post('formData'); + + $_POST['von'] = (isset($formData['von']) && !empty($formData['von'])) ? $formData['von'] : null; + $_POST['bis'] = (isset($formData['bis']) && !empty($formData['bis'])) ? $formData['bis'] : null; + $_POST['nation_code'] = (isset($formData['nation_code']) && !empty($formData['nation_code'])) ? $formData['nation_code'] : 'A'; + $_POST['mobilitaetsprogramm_code'] = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code'])) ? $formData['mobilitaetsprogramm_code'] : null; + $_POST['herkunftsland_code'] = (isset($formData['herkunftsland_code']) && !empty($formData['herkunftsland_code'])) ? $formData['herkunftsland_code'] : 'A'; + $_POST['ects_erworben'] = (isset($formData['ects_erworben']) && !empty($formData['ects_erworben'])) ? $formData['ects_erworben'] : null; + $_POST['ects_angerechnet'] = (isset($formData['ects_angerechnet']) && !empty($formData['ects_angerechnet'])) ? $formData['ects_angerechnet'] : null; + $_POST['lehreinheit_id'] = (isset($formData['lehreinheit_id']) && !empty($formData['lehreinheit_id'])) ? $formData['lehreinheit_id'] : null; + + $this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code']) + ]); + $this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code']) + ]); + $this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code']) + ]); + $this->form_validation->set_rules('von', 'VonDatum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum']) + ]); + + $this->form_validation->set_rules('bis', 'VBisDatum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VBisDatum']) + ]); + + $this->form_validation->set_rules('ects_erworben', 'Ects_erworben', 'numeric', [ + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_erworben']) + ]); + + $this->form_validation->set_rules('ects_angerechnet', 'Ects_angerechnet', 'numeric', [ + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_angerechnet']) + ]); + + $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'numeric', [ + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit']) + ]); + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $result = $this->BisioModel->update( + [ + 'bisio_id' => $formData['bisio_id'] + ], + [ + 'student_uid' => $student_uid, + 'von' => $_POST['von'], + 'bis' => $_POST['bis'], + 'mobilitaetsprogramm_code' => $_POST['mobilitaetsprogramm_code'], + 'nation_code' => $_POST['nation_code'], + 'herkunftsland_code' => $_POST['herkunftsland_code'], + 'lehreinheit_id' => $_POST['lehreinheit_id'], + 'ort' => $formData['ort'], + 'universitaet' => $formData['universitaet'], + 'ects_erworben' => $_POST['ects_erworben'] , + 'ects_angerechnet' => $_POST['ects_angerechnet'], + 'updateamum' => date('c'), + 'updatevon' => $authUID, + ] + ); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function deleteMobility($bisio_id) + { + //check if extension table exists + $result = $this->BisioModel->tableExists('extension', 'tbl_mo_bisioidzuordnung'); + $data = $this->getDataOrTerminateWithError($result); + + //if table exists check if existing entry + if(!empty($data)) + { + $this->BisioModel->addSelect("count(*)"); + $this->BisioModel->addJoin('extension.tbl_mo_bisioidzuordnung mo', 'ON (mo.bisio_id = bis.tbl_bisio.bisio_id)', 'LEFT'); + + $resultCheckMo = $this->BisioModel->loadWhere( + array('mo.bisio_id' => $bisio_id) + ); + + $resultCheckMo = $this->getDataOrTerminateWithError($resultCheckMo); + $count = current($resultCheckMo)->count; + + $existsInExtension = $count > 0 ? true : false; + + if($existsInExtension) + $this->terminateWithError($this->p->t('mobility', 'error_existingEntryInExtension'), self::ERROR_TYPE_GENERAL); + } + + $result = $this->BisioModel->delete( + array('bisio_id' => $bisio_id) + ); + + $data = $this->getDataOrTerminateWithError($result); + $this->terminateWithSuccess($data); + } + + public function getLVList($studiengang_kz) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudiengangkz($studiengang_kz); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getAllLehreinheiten() + { + $lv_id = $this->input->post('lv_id'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + $result = $this->LehreinheitModel->getLesFromLvIds($lv_id, $studiensemester_kurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getLvsandLesByStudent($student_uid) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid); + + $data = $this->getDataOrTerminateWithError($result); + + $lv_ids = array(); + $allData = array(); + + foreach ($data as $lehrveranstaltung) { + $lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id; + } + + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + foreach ($lv_ids as $id) + { + $result = $this->LehreinheitModel->getLesFromLvIds($id); + $data = $this->getDataOrTerminateWithError($result); + + if (is_array($data)) { + $allData = array_merge($allData, $data); + } + } + + return $this->terminateWithSuccess($allData); + } + + public function getPurposes($bisio_id) + { + $bisio_id = (int)$bisio_id; + + $this->load->model('codex/Bisiozweck_model', 'BisiozweckModel'); + + $this->BisiozweckModel->addSelect("*"); + $this->BisiozweckModel->addJoin('bis.tbl_zweck zw', 'ON (zw.zweck_code = bis.tbl_bisio_zweck.zweck_code)'); + + $result = $this->BisiozweckModel->loadWhere( + array('bisio_id' => $bisio_id) + ); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getSupports($bisio_id) + { + $bisio_id = (int)$bisio_id; + + $this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel'); + + $this->BisioaufenthaltfoerderungModel->addSelect("*"); + $this->BisioaufenthaltfoerderungModel->addJoin('bis.tbl_aufenthaltfoerderung af', 'ON (af.aufenthaltfoerderung_code = bis.tbl_bisio_aufenthaltfoerderung.aufenthaltfoerderung_code)'); + + $result = $this->BisioaufenthaltfoerderungModel->loadWhere( + array('bisio_id' => $bisio_id) + ); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getListPurposes() + { + $this->load->model('codex/Zweck_model', 'ZweckModel'); + + $result = $this->ZweckModel->load(); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getListSupports() + { + $this->load->model('codex/Aufenthaltfoerderung_model', 'AufenthaltfoerderungModel'); + + $result = $this->AufenthaltfoerderungModel->load(); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function addMobilityPurpose($bisio_id, $local_purpose = null) + { + $zweck_code = $this->input->post('zweck_code'); + + if($local_purpose){ + $zweck_code = $local_purpose; + } + + $this->load->model('codex/Bisiozweck_model', 'BisiozweckModel'); + if(!$local_purpose) + { + $check = $this->BisiozweckModel->loadWhere( + [ + 'bisio_id' => $bisio_id, + 'zweck_code' => $zweck_code, + ] + ); + if (hasData($check)) + { + $this->terminateWithError($this->p->t('ui', 'error_entryExisting'), self::ERROR_TYPE_GENERAL); + } + } + + $result = $this->BisiozweckModel->insert( + array( + 'bisio_id' => $bisio_id, + 'zweck_code' => $zweck_code + ) + ); + + $data = $this->getDataOrTerminateWithError($result); + + if($local_purpose) + { + return $data; + } + + return $this->terminateWithSuccess(current($data)); + } + + public function deleteMobilityPurpose($bisio_id) + { + $zweck_code = $this->input->post('zweck_code'); + + $this->load->model('codex/Bisiozweck_model', 'BisiozweckModel'); + + + $result = $this->BisiozweckModel->delete( + array( + 'bisio_id' => $bisio_id, + 'zweck_code' => $zweck_code + ) + ); + + $data = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess(current($data)); + } + + public function addMobilitySupport($bisio_id, $local_support = null) + { + $aufenthaltfoerderung_code = $this->input->post('aufenthaltfoerderung_code'); + + if($local_support){ + $aufenthaltfoerderung_code = $local_support; + } + + $this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel'); + + if(!$local_support) + { + $check = $this->BisioaufenthaltfoerderungModel->loadWhere( + [ + 'bisio_id' => $bisio_id, + 'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code, + ] + ); + if (hasData($check)) + { + $this->terminateWithError($this->p->t('ui', 'error_entryExisting'), self::ERROR_TYPE_GENERAL); + } + } + + $result = $this->BisioaufenthaltfoerderungModel->insert( + array( + 'bisio_id' => $bisio_id, + 'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code + ) + ); + + $data = $this->getDataOrTerminateWithError($result); + + if($local_support) + { + return $data; + } + + return $this->terminateWithSuccess(current($data)); + } + + public function deleteMobilitySupport($bisio_id) + { + $aufenthaltfoerderung_code = $this->input->post('aufenthaltfoerderung_code'); + + $this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel'); + + $result = $this->BisioaufenthaltfoerderungModel->delete( + array( + 'bisio_id' => $bisio_id, + 'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code + ) + ); + $data = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess(current($data)); + } +} diff --git a/application/controllers/api/frontend/v1/stv/Prestudent.php b/application/controllers/api/frontend/v1/stv/Prestudent.php index ef9aeb111..0b06b9667 100644 --- a/application/controllers/api/frontend/v1/stv/Prestudent.php +++ b/application/controllers/api/frontend/v1/stv/Prestudent.php @@ -19,6 +19,7 @@ class Prestudent extends FHCAPI_Controller 'getAufmerksamdurch' => ['admin:r', 'assistenz:r'], 'getBerufstaetigkeit' => ['admin:r', 'assistenz:r'], 'getTypenStg' => ['admin:r', 'assistenz:r'], + 'getBisstandort' => ['admin:r', 'assistenz:r'], 'getStudienplaene' => ['admin:r', 'assistenz:r'], 'getStudiengang' => ['admin:r', 'assistenz:r'] ]); @@ -265,6 +266,17 @@ class Prestudent extends FHCAPI_Controller return $this->terminateWithSuccess(getData($result) ?: []); } + public function getBisstandort() + { + $this->load->model('codex/Bisstandort_model', 'BisstandortModel'); + + $result = $this->BisstandortModel->load(); + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess(getData($result) ?: []); + } + public function getStudienplaene($prestudent_id) { $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); diff --git a/application/controllers/api/frontend/v1/stv/Pruefung.php b/application/controllers/api/frontend/v1/stv/Pruefung.php new file mode 100644 index 000000000..e205c85b8 --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Pruefung.php @@ -0,0 +1,577 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the back-end + * Provides data to the ajax get calls about addresses + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Pruefung extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'getPruefungen' => ['admin:r', 'assistenz:r'], + 'loadPruefung' => ['admin:r', 'assistenz:r'], + 'getTypenPruefungen' => ['admin:r', 'assistenz:r'], + 'getLehreinheiten' => ['admin:r', 'assistenz:r'], + 'getAllLehreinheiten' => ['admin:r', 'assistenz:r'], + 'getLvsByStudent' => ['admin:r', 'assistenz:r'], + 'getLvsandLesByStudent' => ['admin:r', 'assistenz:r'], + 'getLvsAndMas' => ['admin:r', 'assistenz:r'], + 'getMitarbeiterLv' => ['admin:r', 'assistenz:r'], + 'getNoten' => ['admin:r', 'assistenz:r'], + 'checkZeugnisnoteLv' => ['admin:r', 'assistenz:r'], + 'checkTermin1' => ['admin:r', 'assistenz:r'], + 'insertPruefung' => self::PERM_LOGGED, + 'updatePruefung' =>self::PERM_LOGGED, + 'deletePruefung' =>self::PERM_LOGGED, + ]); + + //Load Models + $this->load->model('education/LePruefung_model', 'PruefungModel'); + + //version with postParameter + if ($this->router->method == 'insertPruefung') + { + $student_uid = $this->input->post('student_uid'); + + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$student_uid]); + $student = $this->getDataOrTerminateWithError($result); + + $prestudent_id = current($student)->prestudent_id; + $this->checkPermissionsForPrestudent($prestudent_id, ['admin:w', 'assistenz:w']); + } + + // parameter from uri + if ($this->router->method == 'updatePruefung' || $this->router->method == 'deletePruefung') + { + $pruefung_id = current(array_slice($this->uri->rsegments, 2)); + + $result = $this->PruefungModel->load($pruefung_id); + $pruefung = $this->getDataOrTerminateWithError($result); + $student_uid = current($pruefung)->student_uid; + + + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$student_uid]); + $student = $this->getDataOrTerminateWithError($result); + $prestudent_id = current($student)->prestudent_id; + + $this->checkPermissionsForPrestudent($prestudent_id, ['admin:rw', 'assistenz:rw']); + } + + if ($this->router->method == 'loadPruefung') + { + $pruefung_id = current(array_slice($this->uri->rsegments, 2)); + + $result = $this->PruefungModel->load($pruefung_id); + $pruefung = $this->getDataOrTerminateWithError($result); + + + $student_uid = current($pruefung)->student_uid; + + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$student_uid]); + $student = $this->getDataOrTerminateWithError($result); + $prestudent_id = current($student)->prestudent_id; + + $this->checkPermissionsForPrestudent($prestudent_id, ['admin:r', 'assistenz:r']); + } + + if ($this->router->method == 'getPruefungen') + { + $student_uid = current(array_slice($this->uri->rsegments, 2)); + + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$student_uid]); + $student = $this->getDataOrTerminateWithError($result); + $prestudent_id = current($student)->prestudent_id; + + $this->checkPermissionsForPrestudent($prestudent_id, ['admin:r', 'assistenz:r']); + } + + // Load language phrases + $this->loadPhrases([ + 'global', 'ui','lehre' + ]); + } + + public function getPruefungen($student_uid, $studiensemester_kurzbz = null) + { + $result = $this->PruefungModel->getPruefungenByStudentuid($student_uid); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function loadPruefung($pruefung_id) + { + $this->PruefungModel->addSelect('tbl_pruefung.datum'); + $this->PruefungModel->addSelect("TO_CHAR(tbl_pruefung.datum::timestamp, 'DD.MM.YYYY') AS format_datum"); + $this->PruefungModel->addSelect('tbl_pruefung.anmerkung'); + $this->PruefungModel->addSelect('tbl_pruefung.pruefungstyp_kurzbz'); + $this->PruefungModel->addSelect('tbl_pruefung.pruefung_id'); + $this->PruefungModel->addSelect('tbl_pruefung.lehreinheit_id'); + $this->PruefungModel->addSelect('tbl_pruefung.student_uid'); + $this->PruefungModel->addSelect('tbl_pruefung.mitarbeiter_uid'); + $this->PruefungModel->addSelect('tbl_pruefung.punkte'); + $this->PruefungModel->addSelect('tbl_pruefung.note'); + + $this->PruefungModel->addSelect('tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung'); + $this->PruefungModel->addSelect('tbl_lehrveranstaltung.lehrveranstaltung_id'); + $this->PruefungModel->addSelect('tbl_lehrveranstaltung.semester'); + $this->PruefungModel->addSelect('tbl_lehrveranstaltung.lehrform_kurzbz'); + $this->PruefungModel->addSelect('tbl_note.bezeichnung as note_bezeichnung'); + $this->PruefungModel->addSelect('tbl_pruefungstyp.beschreibung as typ_beschreibung'); + $this->PruefungModel->addSelect('tbl_lehreinheit.studiensemester_kurzbz as studiensemester_kurzbz'); + + $this->PruefungModel->addJoin('lehre.tbl_lehreinheit', 'lehre.tbl_pruefung.lehreinheit_id = lehre.tbl_lehreinheit.lehreinheit_id'); + $this->PruefungModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $this->PruefungModel->addJoin('lehre.tbl_note', 'note'); + $this->PruefungModel->addJoin('lehre.tbl_pruefungstyp', 'pruefungstyp_kurzbz'); + + + $this->PruefungModel->addLimit(1); + + $result = $this->PruefungModel->loadWhere( + array('pruefung_id' => $pruefung_id) + ); + if (isError($result)) { + return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + + if (!hasData($result)) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Pruefung_id']), self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess(current(getData($result)) ? : null); + } + + /** + * Inserts a pruefung + * + * @param lehrveranstaltung_id, student_uid, lehreinheit_id + * + * @return values on success + * retval 0: pruefung inserted + * reval 1: pruefung and zeugnisnote inserted + * retval 2: pruefung inserted, no insert Zeugnisnote + * (change after date of examination) + * retval 3: pruefung of type Termin2 inserted + * and pruefung of type Termin1 as well + * retval 5: prueufungen Termin 2 and 1 inserted + * and no insert Zeugnisnote (change after date of examination) + */ + public function insertPruefung() + { + $authUID = getAuthUID(); + + $this->load->library('form_validation'); + + $this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung'), 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehrveranstaltung')]), + ]); + $this->form_validation->set_rules('lehreinheit_id', $this->p->t('lehre', 'lehreinheit'), 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehreinheit')]), + ]); + $this->form_validation->set_rules('pruefungstyp_kurzbz', $this->p->t('lehre', 'pruefung'), 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('global', 'typ')]), + ]); + $this->form_validation->set_rules( + 'datum', + $this->p->t('global', 'datum'), + ['is_valid_date'] + ); + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + //calculate studiensemester_kurzbz this from lehreinheit (case newPruefung) + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + if (!$studiensemester_kurzbz) + { + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + $result = $this->LehreinheitModel->load($this->input->post('lehreinheit_id')); + + $lehreinheit = $this->getDataOrTerminateWithError($result); + $studiensemester_kurzbz = current($lehreinheit)->studiensemester_kurzbz; + + if (isError($result)) + { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + } + + $result = $this->PruefungModel->insert([ + 'lehreinheit_id' => $this->input->post('lehreinheit_id'), + 'student_uid' => $this->input->post('student_uid'), + 'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'), + 'datum' => $this->input->post('datum'), + 'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'), + 'note' => $this->input->post('note'), + 'anmerkung' => $this->input->post('anmerkung'), + 'insertamum' => date('c'), + 'insertvon' => $authUID, + ]); + + $this->getDataOrTerminateWithError($result); + + //check if existing zeugnisnote + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $result = $this->ZeugnisnoteModel->loadWhere(array( + 'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'), + 'student_uid' => $this->input->post('student_uid'), + 'studiensemester_kurzbz' => $studiensemester_kurzbz)); + + if (isError($result)) + { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + + if (!hasData($result)) + { + //insert zeugnisnote, if not existing + $result = $this->ZeugnisnoteModel->insert(array( + 'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'), + 'student_uid' => $this->input->post('student_uid'), + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'note' => $this->input->post('note'), + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $this->input->post('datum'), + 'insertamum' => date('c'), + 'insertvon' => $authUID + )); + + if (isError($result)) + { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess(1); + } + + $return_code = 0; + + //handling Termin1 if not existing + if($this->input->post('pruefungstyp_kurzbz') == "Termin2") + { + $resultP = $this->PruefungModel->loadWhere(array( + 'lehreinheit_id' => $this->input->post('lehreinheit_id'), + 'student_uid' => $this->input->post('student_uid'), + 'pruefungstyp_kurzbz' => 'Termin1')); + + if (isError($resultP)) + { + $this->terminateWithError(getError($resultP), self::ERROR_TYPE_GENERAL); + } + if(!hasData($resultP)) + { + //check if existing Zeugnisnote + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + $this->ZeugnisnoteModel->addJoin('lehre.tbl_lehreinheit', 'lehrveranstaltung_id'); + + $resultP = $this->ZeugnisnoteModel->loadWhere(array( + 'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'), + 'student_uid' => $this->input->input->post('student_uid'), + 'lehre.tbl_zeugnisnote.studiensemester_kurzbz' => $studiensemester_kurzbz)); + if (isError($resultP)) + { + $this->terminateWithError(getError($resultP), self::ERROR_TYPE_GENERAL); + } + if (!hasData($resultP)) + { + $this->terminateWithError("Zeugnisnote existiert nicht", self::ERROR_TYPE_GENERAL); + } + $dataNote = current(getData($resultP)); + + $resultN = $this->PruefungModel->insert([ + 'lehreinheit_id' => $this->input->post('lehreinheit_id'), + 'student_uid' => $this->input->post('student_uid'), + 'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'), + 'datum' => $dataNote->benotungsdatum, + 'pruefungstyp_kurzbz' => 'Termin1', + 'note' => $dataNote->note, + 'punkte' => $dataNote->punkte, + 'anmerkung' => 'automatisiert aus Zeugnisnote erstellt', + 'insertamum' => date('c'), + 'insertvon' => $authUID, + ]); + + if (isError($resultN)) { + $this->terminateWithError(getError($resultN), self::ERROR_TYPE_GENERAL); + } + $return_code = 3; + } + } + + $note = current(getData($result)); + $uebernahmedatum = new DateTime($note->uebernahmedatum); + $benotungsdatum = new DateTime($note->benotungsdatum); + + $checkDate = $uebernahmedatum === '' || $benotungsdatum > $uebernahmedatum + ? $benotungsdatum + : $uebernahmedatum; + + if ($checkDate >= $this->input->post('datum') && $note !== $note->note) + { + $this->terminateWithSuccess($return_code + 2); + } + $this->terminateWithSuccess($return_code + 2); + } + + /** + * Updates a pruefung + * + * @param pruefung_id + * + * @return success or error + * + * no impact on lehre.tbl_zeugnisnote + */ + public function updatePruefung($pruefung_id) + { + $result = $this->PruefungModel->load($pruefung_id); + + $oldpruefung = $this->getDataOrTerminateWithError($result); + if (!$oldpruefung) + show_404(); // Pruefung that should be updated does not exist + + $authUID = getAuthUID(); + + $this->load->library('form_validation'); + + $this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung'), 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehrveranstaltung')]), + ]); + $this->form_validation->set_rules('lehreinheit_id', $this->p->t('lehre', 'lehreinheit'), 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehreinheit')]), + ]); + $this->form_validation->set_rules('pruefungstyp_kurzbz', $this->p->t('lehre', 'pruefung'), 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('global', 'typ')]), + ]); + $this->form_validation->set_rules( + 'datum', + $this->p->t('global', 'datum'), + ['is_valid_date'] + ); + + if ($this->form_validation->run() == false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $result = $this->PruefungModel->update( + [ + 'pruefung_id' => $pruefung_id + ], + [ 'lehreinheit_id' => $this->input->post('lehreinheit_id'), + 'student_uid' => $this->input->post('student_uid'), + 'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'), + 'note' => $this->input->post('note'), + 'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'), + 'datum' => $this->input->post('datum'), + 'anmerkung' => $this->input->post('anmerkung'), + 'updatevon' => $authUID, + 'updateamum' => date('c'), + ] + ); + $this->getDataOrTerminateWithError($result); + + return $this->outputJsonSuccess(true); + } + + /** + * Deletes a pruefung + * + * @param pruefung_id + * + * @return success or error + * + * no impact on lehre.tbl_zeugnisnote + */ + public function deletePruefung($pruefung_id) + { + $result = $this->PruefungModel->load($pruefung_id); + + $oldpruefung = $this->getDataOrTerminateWithError($result); + if (!$oldpruefung) + show_404(); // Pruefung that should be deleted does not exist + + $result = $this->PruefungModel->delete( + [ + 'pruefung_id' => $pruefung_id + ] + ); + + $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess(true); + } + + public function getTypenPruefungen() + { + $this->load->model('education/Pruefungstyp_model', 'PruefungtypModel'); + + //TODO(Manu) sort Termin3 + $this->PruefungtypModel->addOrder('sort', 'ASC'); + $result = $this->PruefungtypModel->loadWhere( + array('abschluss' => 'false') + ); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess(getData($result) ?: []); + } + + public function getAllLehreinheiten() + { + $lv_id = $this->input->post('lv_id'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + $result = $this->LehreinheitModel->getLesFromLvIds($lv_id, $studiensemester_kurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + public function getLvsandLesByStudent($student_uid, $semester_kurzbz=null) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid, $semester_kurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + $lv_ids = array(); + $allData = array(); + + foreach ($data as $lehrveranstaltung) { + $lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id; + } + + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + foreach ($lv_ids as $id) + { + $result = $this->LehreinheitModel->getLesFromLvIds($id, $semester_kurzbz); + $data = $this->getDataOrTerminateWithError($result); + + if (is_array($data)) { + $allData = array_merge($allData, $data); + } + } + + return $this->terminateWithSuccess($allData); + } + + public function getLvsAndMas($student_uid) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid); + + $data = $this->getDataOrTerminateWithError($result); + + $lv_ids = array(); + $allDataMa = array(); + + foreach ($data as $lehrveranstaltung) + { + $lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id; + } + + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + foreach ($lv_ids as $id) + { + $resultMa = $this->MitarbeiterModel->getMitarbeiterFromLV($id); + $dataMa = $this->getDataOrTerminateWithError($resultMa); + + if (is_array($dataMa)) + { + $allDataMa = array_merge($allDataMa, $dataMa); + } + } + return $this->terminateWithSuccess($allDataMa); + } + + public function getLvsByStudent($student_uid, $studiensemester_kurzbz = null) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid, $studiensemester_kurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($data); + } + + public function getMitarbeiterLv($lv_id) + { + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $result = $this->MitarbeiterModel->getMitarbeiterFromLV($lv_id); + + $data = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($data); + } + + public function getNoten() + { + $this->load->model('education/Note_model', 'NoteModel'); + + $this->NoteModel->addOrder('note', 'ASC'); + $result = $this->NoteModel->load(); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess(getData($result) ?: []); + } + + public function checkZeugnisnoteLv() + { + $student_uid = $this->input->post('student_uid'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id'); + + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $result = $this->ZeugnisnoteModel->loadWhere(array( + 'lehrveranstaltung_id' => $lehrveranstaltung_id, + 'student_uid' => $student_uid, + 'studiensemester_kurzbz' => $studiensemester_kurzbz)); + + $data = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess($data); + } +} diff --git a/application/controllers/api/frontend/v1/stv/Status.php b/application/controllers/api/frontend/v1/stv/Status.php index 074f4029e..8167bd90f 100644 --- a/application/controllers/api/frontend/v1/stv/Status.php +++ b/application/controllers/api/frontend/v1/stv/Status.php @@ -647,15 +647,8 @@ class Status extends FHCAPI_Controller return $this->outputJsonSuccess(true); } - public function loadStatus() + public function loadStatus($prestudent_id, $status_kurzbz, $studiensemester_kurzbz, $ausbildungssemester) { - $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); - - $prestudent_id = $this->input->post('prestudent_id'); - $status_kurzbz = $this->input->post('status_kurzbz'); - $ausbildungssemester = $this->input->post('ausbildungssemester'); - $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); - $result = $this->PrestudentstatusModel->loadWhere( array( 'prestudent_id' => $prestudent_id, @@ -1344,13 +1337,13 @@ class Status extends FHCAPI_Controller 'updatevon' => $authUID ]; foreach ([ - 'orgform_kurzbz', - 'anmerkung', - 'bewerbung_abgeschicktamum', - 'studienplan_id', - 'rt_stufe', - 'statusgrund_id' - ] as $key) + 'orgform_kurzbz', + 'anmerkung', + 'bewerbung_abgeschicktamum', + 'studienplan_id', + 'rt_stufe', + 'statusgrund_id' + ] as $key) if ($this->input->post($key)) $updateData[$key] = $this->input->post($key); diff --git a/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index 89c317ae4..f24ef62bb 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -55,7 +55,7 @@ class Student extends FHCAPI_Controller // Load language phrases $this->loadPhrases([ - 'ui' + 'ui', 'lehre' ]); } @@ -156,6 +156,8 @@ class Student extends FHCAPI_Controller $uid = $student ? current($student)->student_uid : null; + $studiengang_kz = $student ? current($student)->studiengang_kz : null; + $result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]); $person = $this->getDataOrTerminateWithError($result); @@ -223,20 +225,35 @@ class Student extends FHCAPI_Controller // Check PKs if (count($update_lehrverband) + count($update_student) && $uid === null) { - // TODO(chris): phrase - $this->terminateWithValidationErrors(['' => "Kein/e StudentIn vorhanden!"]); + $this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_student')]); } if (count($update_person) && $person_id === null) { - // TODO(chris): phrase - $this->terminateWithValidationErrors(['' => "Keine Person vorhanden!"]); + $this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_person')]); } // Do Updates if (count($update_lehrverband)) { - $result = $this->StudentlehrverbandModel->update([ + $curstudlvb = $this->StudentlehrverbandModel->load([ 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'student_uid' => $uid - ], $update_lehrverband); + ]); + + if(hasData($curstudlvb) && count(getData($curstudlvb)) > 0 ) + { + $result = $this->StudentlehrverbandModel->update([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $uid + ], $update_lehrverband); + } + else + { + $result = $this->StudentlehrverbandModel->insert(array_merge([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $uid, + 'studiengang_kz' => $studiengang_kz + ], $update_lehrverband)); + } + $this->getDataOrTerminateWithError($result); } diff --git a/application/controllers/components/Cis/Mylv.php b/application/controllers/components/Cis/Mylv.php new file mode 100644 index 000000000..1fdb7e2a1 --- /dev/null +++ b/application/controllers/components/Cis/Mylv.php @@ -0,0 +1,213 @@ + ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? + 'Studiensemester' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? + 'Lvs' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? + 'Info' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions? + 'Pruefungen' => ['student/anrechnung_beantragen:r','user:r'] // TODO(chris): permissions? + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + */ + public function Student() + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + + /** + */ + public function Studiensemester() + { + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + $result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + + /** + */ + public function Lvs($studiensemester_kurzbz) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage()); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + + /** + */ + public function Info($studiensemester_kurzbz, $lehrveranstaltung_id) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + $lv = current(getData($result) ?: []); + + if (!$lv) + return $this->outputJsonError('Could\'t find Lehrveranstaltung with id: ' . $lehrveranstaltung_id); + + + $this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel'); + + $result = $this->LehreinheitmitarbeiterModel->getForLv($lehrveranstaltung_id, $studiensemester_kurzbz); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $lvinfo = []; + $lvinfo['lektoren'] = getData($result) ?: []; + + $kollisionsfreie_user = unserialize(KOLLISIONSFREIE_USER); + $lvinfo['lektoren'] = array_values(array_filter($lvinfo['lektoren'], function ($v) use ($kollisionsfreie_user) { + return !in_array($v->uid, $kollisionsfreie_user); + })); + + $lvinfo['lvLeitung'] = array_values(array_filter($lvinfo['lektoren'], function ($v) { + return $v->lehrfunktion_kurzbz == 'LV-Leitung'; + })); + + + $this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); + $result = $this->OrganisationseinheitModel->getWithType($lv->oe_kurzbz); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $lvinfo['oe'] = current(getData($result) ?: []); + + + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $result = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('Leitung', $lv->oe_kurzbz); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $lvinfo['oeLeitung'] = getData($result) ?: []; + + + $result = $this->LehrveranstaltungModel->getKoordinator($lehrveranstaltung_id, $studiensemester_kurzbz); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $lvinfo['koordinator'] = getData($result) ?: []; + + if (defined('ACTIVE_ADDONS') && in_array('lvinfo', explode(';', ACTIVE_ADDONS)) && file_exists(FHCPATH . 'addons/lvinfo/include/lvinfo.class.php')) + { + require_once(FHCPATH . 'addons/lvinfo/include/lvinfo.class.php'); + $lvinfoObj = new lvinfo(); + $lvinfoObj->loadLVinfo($lehrveranstaltung_id, $studiensemester_kurzbz, null, true); + if (is_array($lvinfoObj->result)) + { + $oldP = property_exists($this, 'p') ? $this->p : null; + $result = []; + $lvinfos = $lvinfoObj->result; + $lvinfoSet = new lvinfo(); + $lvinfoSet->load_lvinfo_set($studiensemester_kurzbz); + foreach ($lvinfos as $lvi) + { + $this->p = null; + $this->loadPhrases('ui', $lvi->sprache); + $result[$lvi->sprache] = []; + foreach ($lvinfoSet->result as $set) + { + $key = $set->lvinfo_set_kurzbz; + if (!isset($lvi->data[$key])) + continue; + $info = [ + 'header' => $set->lvinfo_set_bezeichnung[$lvi->sprache] + ]; + if (isset($set->einleitungstext[$lvi->sprache])) + $info['subheader'] = $set->einleitungstext[$lvi->sprache]; + switch ($set->lvinfo_set_typ) + { + case 'boolean': + $info['body'] = $this->p->t('ui', $lvi->data[$key] === true ? 'ja' : 'nein'); + break; + case 'array': + $info['body'] = array_map('htmlspecialchars', $lvi->data[$key]); + break; + case 'editor': + $info['body'] = $lvi->data[$key]; + break; + default: + $info['body'] = htmlspecialchars($lvi->data[$key]); + } + if ($info['body']) + $result[$lvi->sprache][] = $info; + } + } + if ($result) + { + $lvinfo['lvinfo'] = $result; + $lvinfo['lvinfoDefaultLang'] = getUserLanguage(); + + $this->load->model('system/Sprache_model', 'SpracheModel'); + $result = $this->SpracheModel->loadMultiple(array_keys($result)); + if (!isError($result)) + { + $result = getData($result); + $lvinfo['sprachen'] = []; + foreach ($result as $sprache) { + $lvinfo['sprachen'][$sprache->sprache] = $sprache; + } + } + } + $this->p = $oldP; + } + } + + + $this->outputJsonSuccess($lvinfo); + } + + /** + */ + public function Pruefungen($lehrveranstaltung_id) + { + $this->load->model('education/Pruefung_model', 'PruefungModel'); + + $result = $this->PruefungModel->getByStudentAndLv(getAuthUID(), $lehrveranstaltung_id, getUserLanguage()); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + +} diff --git a/application/controllers/components/Cis/Stundenplan.php b/application/controllers/components/Cis/Stundenplan.php new file mode 100644 index 000000000..a9f35c651 --- /dev/null +++ b/application/controllers/components/Cis/Stundenplan.php @@ -0,0 +1,73 @@ + ['basis/cis'], + 'Reservierungen' => ['basis/cis'], + 'Stunden' => ['basis/cis'], + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + */ + public function index() + { + $this->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + /* $result = $this->StundenplanModel->loadForUid(getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + */ + $res = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getStundenplanQuery(getAuthUID())); + + $res = getData($res); + + $this->outputJsonSuccess($res); + } + + /** + */ + public function Reservierungen() + { + $this->load->model('ressource/Reservierung_model', 'ReservierungModel'); + + $result = $this->ReservierungModel->loadForUid(getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + + /** + */ + public function Stunden() + { + $this->load->model('ressource/Stunde_model', 'StundeModel'); + + $result = $this->StundeModel->load(); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + + +} diff --git a/application/controllers/components/stv/Noten.php b/application/controllers/components/stv/Noten.php deleted file mode 100644 index fb61de065..000000000 --- a/application/controllers/components/stv/Noten.php +++ /dev/null @@ -1,168 +0,0 @@ - 'student/noten:r', - 'getZeugnis' => 'student/noten:r', - 'update' => ['admin:w', 'assistenz:w'] - ]); - - // Load Libraries - $this->load->library('VariableLib', ['uid' => getAuthUID()]); - } - - public function get() - { - $this->load->model('codex/Note_model', 'NoteModel'); - - $result = $this->NoteModel->addOrder('note'); - - $result = $this->NoteModel->load(); - if (isError($result)) { - $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); - } - - return $this->outputJson($result); - } - - public function getZeugnis($prestudent_id, $all = null) - { - $this->load->model('crm/Student_model', 'StudentModel'); - $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); - - $result = $this->StudentModel->loadWhere([ - 'prestudent_id' => $prestudent_id - ]); - if (isError($result)) { - $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); - return $this->outputJson($result); - } - if (!hasData($result)) - return $this->outputJsonSuccess(null); - - $student_uid = current(getData($result))->student_uid; - - $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null; - - $result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz); - if (isError($result)) { - $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); - } - - return $this->outputJson($result); - } - - public function update() - { - $this->load->model('crm/Student_model', 'StudentModel'); - $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); - $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); - $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); - - $this->load->library('form_validation'); - - $_POST = json_decode(utf8_encode($this->input->raw_input_stream), true); - - if (empty($_POST) || !is_array(current($_POST))) { - $result = $this->hasPermissionUpdate($this->input->post('lehrveranstaltung_id'), $this->input->post('student_uid')); - if (isError($result)) { - $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); - return $this->outputJson($result); - } - - $this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrverantaltung ID', 'required|numeric'); - $this->form_validation->set_rules('student_uid', 'Student UID', 'required'); - $this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester Kurzbezeichnung', 'required'); - $this->form_validation->set_rules('note', 'Note', 'required|numeric'); - $post = [$_POST]; - } else { - foreach ($_POST as $i => $data) { - $lvid = isset($data['lehrveranstaltung_id']) ? $data['lehrveranstaltung_id'] : null; - $uid = isset($data['student_uid']) ? $data['student_uid'] : null; - $result = $this->hasPermissionUpdate($lvid, $uid); - if (isError($result)) { - $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); - return $this->outputJson($result); - } - - $this->form_validation->set_rules($i . '[lehrveranstaltung_id]', '#' . $i . ' Lehrverantaltung ID', 'required|numeric'); - $this->form_validation->set_rules($i . '[student_uid]', '#' . $i . ' Student UID', 'required'); - $this->form_validation->set_rules($i . '[studiensemester_kurzbz]', '#' . $i . ' Studiensemester Kurzbezeichnung', 'required'); - $this->form_validation->set_rules($i . '[note]', '#' . $i . ' Note', 'required|numeric'); - } - $post = $_POST; - } - if ($this->form_validation->run() == false) { - $this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST); - return $this->outputJsonError($this->form_validation->error_array()); - } - - $final_result = success(); - $this->ZeugnisnoteModel->db->trans_start(); - - foreach ($post as $i => $data) { - $note = $data['note']; - unset($data['note']); - $result = $this->ZeugnisnoteModel->update($data, [ - 'note' => $note, - 'benotungsdatum' => date('c'), - 'updateamum' => date('c'), - 'updatevon' => getAuthUID() - ]); - if (isError($result)) { - $final_result = $result; - break; - } - } - - $this->ZeugnisnoteModel->db->trans_complete(); - - if (isError($final_result)) { - $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); - } - - $this->outputJson($final_result); - } - - protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid) - { - // TODO(chris): error phrases! - if ($lehrveranstaltung_id === null || $student_uid === null) - return success(); - $result = $this->StudentModel->load([$student_uid]); - if (isError($result)) - return $result; - if (!hasData($result)) - return error('Fehler beim Ermitteln des Studenten'); - $student = current(getData($result)); - - if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)) - return success(); - if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)) - return success(); - - $result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id); - if (isError($result)) - return $result; - $oes = getData($result) ?: []; - $result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id); - if (isError($result)) - return $result; - if (hasData($result)) - $oes[] = current(getData($result)); - - foreach ($oes as $oe) { - if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz)) - return success(); - if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz)) - return success(); - } - - return error('Forbidden'); - } -} diff --git a/application/controllers/dashboard/Api.php b/application/controllers/dashboard/Api.php new file mode 100644 index 000000000..422bf0675 --- /dev/null +++ b/application/controllers/dashboard/Api.php @@ -0,0 +1,76 @@ + 'dashboard/admin:rw', + 'getNews' => 'dashboard/benutzer:r', + 'getAmpeln' => 'dashboard/benutzer:r', + ) + ); + + $this->load->library('AuthLib', null, 'AuthLib'); + + $this->_setAuthUID(); + } + + public function index() + { + echo 'Dashboard API Controller'; + } + + /** + * Get News. + */ + public function getNews() + { + $limit = $this->input->get('limit'); + + $this->load->model('content/News_model', 'NewsModel'); + + $result = $this->NewsModel->getAll($limit); + + if (hasData($result)) + { + $this->outputJson(getData($result), REST_Controller::HTTP_OK); + } + else + { + $this->terminateWithJsonError('fehler entdeckt'); + } + } + + + /** + * Get Ampeln. + */ + public function getAmpeln() + { + + $this->load->model('content/Ampel_model', 'AmpelModel'); + $result = $this->AmpelModel->getByUser($this->_uid); + + if (hasData($result)) + { + $this->outputJson(getData($result), REST_Controller::HTTP_OK); + } + else + { + $this->terminateWithJsonError('fehler entdeckt'); + } + } + + /** + * Retrieve the UID of the logged user and checks if it is valid + */ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) show_error('User authentification failed'); + } +} diff --git a/application/controllers/dashboard/Config.php b/application/controllers/dashboard/Config.php new file mode 100644 index 000000000..2c0cf5fca --- /dev/null +++ b/application/controllers/dashboard/Config.php @@ -0,0 +1,216 @@ + 'dashboard/benutzer:r', + 'dummy' => 'dashboard/benutzer:r', + 'genWidgetId' => 'dashboard/benutzer:rw', + 'addWidgetsToPreset' => 'dashboard/admin:rw', + 'removeWidgetFromPreset' => 'dashboard/admin:rw', + 'addWidgetsToUserOverride' => 'dashboard/benutzer:rw', + 'removeWidgetFromUserOverride' => 'dashboard/benutzer:rw', + 'funktionen' => 'dashboard/admin:r', + 'preset' => 'dashboard/admin:r', + 'presetBatch' => 'dashboard/admin:r' + ) + ); + + $this->load->library('dashboard/DashboardLib', null, 'DashboardLib'); + $this->load->library('AuthLib', null, 'AuthLib'); + $this->load->model('ressource/Funktion_model', 'FunktionModel'); + } + + public function index() + { + $dashboard_kurzbz = $this->input->get('db'); + $uid = $this->AuthLib->getAuthObj()->username; + + $dashboard = $this->DashboardLib->getDashboardByKurzbz($dashboard_kurzbz); + if(!$dashboard) { + http_response_code(404); + $this->terminateWithJsonError(array( + 'error' => 'Dashboard ' . $dashboard_kurzbz . ' not found.' + )); + } + + $mergedconfig = $this->DashboardLib->getMergedConfig($dashboard->dashboard_id, $uid); + $this->outputJsonSuccess($mergedconfig); + } + + public function genWidgetId() + { + $dashboard_kurzbz = $this->input->get('db'); + $widgetid = $this->DashboardLib->generateWidgetId($dashboard_kurzbz); + $this->outputJsonSuccess(array( + 'widgetid' => $widgetid + )); + } + + public function addWidgetsToPreset() + { + $input = json_decode($this->input->raw_input_stream); + $dashboard_kurzbz = $input->db; + $funktion_kurzbz = $input->funktion_kurzbz; + + $preset = $this->DashboardLib->getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz); + + $preset_decoded = json_decode($preset->preset, true); + + $this->DashboardLib->addWidgetsToWidgets($preset_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets); + + $preset->preset = json_encode($preset_decoded); + + $result = $this->DashboardLib->insertOrUpdatePreset($preset); + if (isError($result)) { + http_response_code(500); + $this->terminateWithJsonError('preset could not be saved'); + } + + $this->outputJsonSuccess(array('msg' => 'preset successfully stored.', 'data' => $preset_decoded)); + } + + public function removeWidgetFromPreset() + { + $input = json_decode($this->input->raw_input_stream); + $dashboard_kurzbz = $input->db; + $funktion_kurzbz = $input->funktion_kurzbz; + $widgetid = $input->widgetid; + + $preset = $this->DashboardLib->getPreset($dashboard_kurzbz, $funktion_kurzbz); + if ($preset === null) { + http_response_code(404); + $this->terminateWithJsonError('preset for dashboard ' . $dashboard_kurzbz . ' and funktion ' . $funktion_kurzbz . ' not found.'); + } + + $preset_decoded = json_decode($preset->preset, true); + if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded['widgets'], $funktion_kurzbz, $widgetid)) + { + http_response_code(404); + $this->terminateWithJsonError('widgetid ' . $widgetid . ' not found'); + } + + $preset->preset = json_encode($preset_decoded); + $result = $this->DashboardLib->insertOrUpdatePreset($preset); + if (isError($result)) + { + http_response_code(500); + $this->terminateWithJsonError('failed to remove widget'); + } + $this->outputJsonSuccess(array('msg' => 'preset successfully updated.')); + } + + public function addWidgetsToUserOverride() + { + $input = json_decode($this->input->raw_input_stream); + $dashboard_kurzbz = $input->db; + $funktion_kurzbz = $input->funktion_kurzbz; + $uid = $this->AuthLib->getAuthObj()->username; + + $override = $this->DashboardLib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid); + + $override_decoded = json_decode($override->override, true); + + $this->DashboardLib->addWidgetsToWidgets($override_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets); + + $override->override = json_encode($override_decoded); + + $result = $this->DashboardLib->insertOrUpdateOverride($override); + if (isError($result)) { + http_response_code(500); + $this->terminateWithJsonError('override could not be saved'); + } + + $this->outputJsonSuccess(array('msg' => 'override successfully stored.', 'data' => $override_decoded)); + } + + public function removeWidgetFromUserOverride() + { + $input = json_decode($this->input->raw_input_stream); + $dashboard_kurzbz = $input->db; + $funktion_kurzbz = $input->funktion_kurzbz; + $uid = $this->AuthLib->getAuthObj()->username; + $widgetid = $input->widgetid; + + $override = $this->DashboardLib->getOverride($dashboard_kurzbz, $uid); + if (empty($override)) { + http_response_code(404); + $this->terminateWithJsonError('userconfig for dashboard ' . $dashboard_kurzbz . ' not found.'); + } + + $override_decoded = json_decode($override->override, true); + + if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded['widgets'], $funktion_kurzbz, $widgetid)) + { + http_response_code(404); + $this->terminateWithJsonError('widgetid ' . $widgetid . ' not found'); + } + + $override->override = json_encode($override_decoded); + $result = $this->DashboardLib->insertOrUpdateOverride($override, $uid); + if (isError($result)) + { + http_response_code(500); + $this->terminateWithJsonError('failed to remove widget'); + } + $this->outputJsonSuccess(array('msg' => 'override successfully updated.')); + } + + public function funktionen() + { + $funktionen = $this->FunktionModel->load(); + + if (isError($funktionen)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($funktionen) + ]); + } + + return $this->outputJsonSuccess(getData($funktionen) ?: []); + } + + public function preset() + { + $db = $this->input->get('db'); + $funktion = $this->input->get('funktion'); + + $conf = $this->DashboardLib->getPreset($db, $funktion); + + if (!$conf) + return $this->outputJsonSuccess(['widgets' => [$funktion => []]]); + + return $this->outputJsonSuccess(json_decode($conf->preset, true)); + } + + public function presetBatch() + { + $db = $this->input->get('db'); + $funktionen = $this->input->get('funktionen'); + $result = []; + + foreach ($funktionen as $funktion) { + $conf = $this->DashboardLib->getPreset($db, $funktion); + if ($conf) + { + $preset = json_decode($conf->preset, true); + if (!isset($preset['widgets']) || !isset($preset['widgets'][$funktion])) + $result[$funktion] = []; + else + $result[$funktion] = $preset['widgets'][$funktion]; + } + else + $result[$funktion] = []; + } + + return $this->outputJsonSuccess($result); + } +} diff --git a/application/controllers/dashboard/Dashboard.php b/application/controllers/dashboard/Dashboard.php new file mode 100644 index 000000000..3773a6d73 --- /dev/null +++ b/application/controllers/dashboard/Dashboard.php @@ -0,0 +1,86 @@ + 'dashboard/admin:r', + 'create' => 'dashboard/admin:rw', + 'update' => 'dashboard/admin:rw', + 'delete' => 'dashboard/admin:rw' + ) + ); + + $this->load->library('dashboard/DashboardLib', null, 'DashboardLib'); + $this->load->model('dashboard/Dashboard_model', 'DashboardModel'); + } + + public function index() + { + $result = $this->DashboardModel->load(); + + if (isError($result)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($result) + ]); + } + + return $this->outputJsonSuccess(getData($result) ?: []); + } + + public function create() + { + $input = $this->getPostJSON(); + + $result = $this->DashboardModel->insert($input); + + if (isError($result)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($result) + ]); + } + + return $this->outputJsonSuccess(getData($result) ?: []); + } + + public function update() + { + $input = $this->getPostJSON(); + + $result = $this->DashboardModel->update($input->dashboard_id, $input); + + if (isError($result)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($result) + ]); + } + + return $this->outputJsonSuccess(getData($result) ?: []); + } + + public function delete() + { + $input = $this->getPostJSON(); + + $result = $this->DashboardModel->delete($input->dashboard_id); + + if (isError($result)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($result) + ]); + } + + return $this->outputJsonSuccess(getData($result) ?: []); + } +} diff --git a/application/controllers/dashboard/DashboardDemo.php b/application/controllers/dashboard/DashboardDemo.php new file mode 100644 index 000000000..35d530384 --- /dev/null +++ b/application/controllers/dashboard/DashboardDemo.php @@ -0,0 +1,58 @@ + 'dashboard/benutzer:r', + 'admin' => 'dashboard/admin:rw' + ) + ); + + $this->load->library('AuthLib'); + $this->load->library('WidgetLib'); + + $this->_setAuthUID(); // sets property uid + + $this->setControllerId(); // sets the controller id + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + public function index() + { + $this->load->view('dashboard/dashboard_demo.php', []); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + public function admin() + { + $this->load->view('dashboard/dashboard_demo_admin.php', []); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * Retrieve the UID of the logged user and checks if it is valid + */ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) show_error('User authentification failed'); + } +} diff --git a/application/controllers/dashboard/Widget.php b/application/controllers/dashboard/Widget.php new file mode 100644 index 000000000..0da6fe8da --- /dev/null +++ b/application/controllers/dashboard/Widget.php @@ -0,0 +1,109 @@ + ['dashboard/benutzer:r', 'dashboard/admin:r'], + 'getAll' => 'dashboard/admin:r', + 'getWidgetsForDashboard' => ['dashboard/benutzer:rw', 'dashboard/admin:r'], + 'setAllowed' => 'dashboard/admin:rw' + ) + ); + + $this->load->library('dashboard/DashboardLib', null, 'DashboardLib'); + $this->load->model('dashboard/Widget_model', 'WidgetModel'); + $this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel'); + } + + public function index() + { + $widget_id = $this->input->get('id'); + + $widget = $this->WidgetModel->load($widget_id); + + if (isError($widget) || !getData($widget)) + return $this->outputJsonSuccess([ + "widget_id" => 0, + "widget_kurzbz" => "notfound", + "arguments" => json_encode([ + "className" => 'alert-danger', + "title" => 'Widget Not Found', + "msg" => 'The widget with the id ' . $widget_id . ' could not be found' + ]), + "setup" => json_encode([ + "name" => 'Widget Not Found', + "file" => 'DashboardWidget/Default.js', + "width" => 1, + "height" => 1 + ]) + ]); + return $this->outputJsonSuccess(current(getData($widget))); + } + + public function getAll() + { + $dashboard_id = $this->input->get('dashboard_id'); + $result = $this->WidgetModel->getWithAllowedForDashboard($dashboard_id); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result) ?: []); + } + + public function getWidgetsForDashboard() + { + $db = $this->input->get('db'); + $result = $this->WidgetModel->getForDashboard($db); + + if (isError($result)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($result) + ]); + } + + $this->outputJsonSuccess(getData($result) ?: []); + } + + public function setAllowed() + { + $input = $this->getPostJSON(); + + $dashboard_id = $input->dashboard_id; + $widget_id = $input->widget_id; + $action = $input->action; + + if ($action == 'add') { + $result = $this->DashboardWidgetModel->insert([ + 'dashboard_id' => $dashboard_id, + 'widget_id' => $widget_id + ]); + } elseif ($action == 'delete') { + $result = $this->DashboardWidgetModel->delete([ + 'dashboard_id' => $dashboard_id, + 'widget_id' => $widget_id + ]); + } else { + http_response_code(404); // TODO(chris): 400? + $this->terminateWithJsonError([ + 'error' => 'action value invalid' + ]); + } + if (isError($result)) { + http_response_code(404); + $this->terminateWithJsonError([ + 'error' => getError($result) + ]); + } + return $this->outputJsonSuccess(getData($result)); + } +} diff --git a/application/controllers/jobs/AnrechnungJob.php b/application/controllers/jobs/AnrechnungJob.php index 5784830b6..52bf972e3 100644 --- a/application/controllers/jobs/AnrechnungJob.php +++ b/application/controllers/jobs/AnrechnungJob.php @@ -195,10 +195,10 @@ class AnrechnungJob extends JOB_Controller $studiengang_bezeichnung = $this->StudiengangModel->load($studiengang_kz)->retval[0]->stg_bezeichnung; // Get STGL mail address - $stglMailReceiver_arr = self::_getSTGLMailAddress($studiengang_kz); + $stglMailReceiver_arr = $this->_getSTGLMailAddress($studiengang_kz); // Get HTML table with new Anrechnungen of that STG plus amount of them - list ($anrechnungen_amount, $anrechnungen_table) = self::_getSTGLMailDataTable($studiengang_kz, $anrechnungen); + list ($anrechnungen_amount, $anrechnungen_table) = $this->_getSTGLMailDataTable($studiengang_kz, $anrechnungen); // Link to Antrag genehmigen dashboard $url = @@ -514,8 +514,6 @@ html; 'vorname' => $stgl->vorname ); } - - return $stglMailAdress_arr; } // If not available, get assistance mail address else @@ -524,12 +522,13 @@ html; if (hasData($result)) { - return array( - $result->retval[0]->email, - '' + $stglMailAdress_arr[]= array( + 'to' => $result->retval[0]->email, + 'vorname' => '' ); } } + return $stglMailAdress_arr; } // Build HTML table with yesterdays new Anrechnungen of the given STG diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 46a31f3d6..11b950174 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -183,8 +183,8 @@ class AntragJob extends JOB_Controller $data, $to, 'Anträge - Aktion(en) erforderlich', - DEFAULT_SANCHO_HEADER_IMG, - DEFAULT_SANCHO_FOOTER_IMG, + '', + '', '', $cc )) diff --git a/application/controllers/jobs/IssueResolver.php b/application/controllers/jobs/IssueResolver.php index ca07439c3..fe7ee21f5 100755 --- a/application/controllers/jobs/IssueResolver.php +++ b/application/controllers/jobs/IssueResolver.php @@ -48,7 +48,9 @@ class IssueResolver extends IssueResolver_Controller 'CORE_PERSON_0001' => 'CORE_PERSON_0001', 'CORE_PERSON_0002' => 'CORE_PERSON_0002', 'CORE_PERSON_0003' => 'CORE_PERSON_0003', - 'CORE_PERSON_0004' => 'CORE_PERSON_0004' + 'CORE_PERSON_0004' => 'CORE_PERSON_0004', + 'CORE_PERSON_0005' => 'CORE_PERSON_0005', + 'CORE_PERSON_0006' => 'CORE_PERSON_0006' ); // fehler which are resolved by the job the same way as they are produced diff --git a/application/controllers/jobs/OneTimeMessages.php b/application/controllers/jobs/OneTimeMessages.php index 525f63c3b..0e49ca8a5 100644 --- a/application/controllers/jobs/OneTimeMessages.php +++ b/application/controllers/jobs/OneTimeMessages.php @@ -52,6 +52,7 @@ class OneTimeMessages extends JOB_Controller JOIN public.tbl_prestudentstatus ps USING (prestudent_id) JOIN public.tbl_studiengang s USING (studiengang_kz) WHERE get_rolle_prestudent(ps.prestudent_id, NULL) = \'Wartender\' + AND ps.status_kurzbz = \'Wartender\' AND ps.studiensemester_kurzbz = ? AND ps.datum <= NOW() - \''.$days.' days\'::interval AND s.typ = ? diff --git a/application/controllers/jobs/ReihungstestJob.php b/application/controllers/jobs/ReihungstestJob.php index b55287439..6dd214fbb 100644 --- a/application/controllers/jobs/ReihungstestJob.php +++ b/application/controllers/jobs/ReihungstestJob.php @@ -431,8 +431,8 @@ class ReihungstestJob extends JOB_Controller $mailcontent_data_arr, $applicant->email, 'Ihre Anmeldung zum Reihungstest - Reminder / Your registration for the placement test - Reminder', - DEFAULT_SANCHO_HEADER_IMG, - DEFAULT_SANCHO_FOOTER_IMG, + '', + '', $from, '', $bcc); @@ -821,7 +821,7 @@ class ReihungstestJob extends JOB_Controller JOIN lehre.tbl_studienordnung USING (studienordnung_id) JOIN PUBLIC.tbl_studiengang ON (tbl_studienordnung.studiengang_kz = tbl_studiengang.studiengang_kz) WHERE get_rolle_prestudent (tbl_prestudent.prestudent_id, ?) IN ('Aufgenommener','Bewerber','Wartender','Abgewiesener') - AND studiensemester_kurzbz = ? + AND studiensemester_kurzbz = ? AND tbl_studiengang.typ IN ('b', 'm') ) SELECT * FROM prst @@ -861,7 +861,7 @@ class ReihungstestJob extends JOB_Controller { // Alle niedrigeren Prios laden $qryNiedrPrios = " - SELECT DISTINCT + SELECT DISTINCT ON(prestudent_id) get_rolle_prestudent (tbl_prestudent.prestudent_id, '".$row_ps->studiensemester_kurzbz."') AS laststatus, tbl_studienplan.orgform_kurzbz, tbl_person.nachname, @@ -876,11 +876,11 @@ class ReihungstestJob extends JOB_Controller JOIN PUBLIC.tbl_studiengang ON (tbl_prestudent.studiengang_kz = tbl_studiengang.studiengang_kz) WHERE tbl_prestudent.person_id = ".$row_ps->person_id." AND tbl_prestudent.prestudent_id != ".$row_ps->prestudent_id." - AND get_rolle_prestudent (tbl_prestudent.prestudent_id, '".$row_ps->studiensemester_kurzbz."') IN ('Aufgenommener','Bewerber','Wartender') + AND get_rolle_prestudent (tbl_prestudent.prestudent_id, '".$row_ps->studiensemester_kurzbz."') IN ('Aufgenommener','Bewerber','Wartender', 'Student') AND studiensemester_kurzbz = '".$row_ps->studiensemester_kurzbz."' AND tbl_studiengang.typ IN ('b', 'm') AND priorisierung > ".$row_ps->priorisierung." - ORDER BY studiengang_kz, laststatus + ORDER BY prestudent_id, studiengang_kz, laststatus, tbl_prestudentstatus.datum DESC "; // Wenn der letzte Status "Aufgenommener" ist, alle niedrigeren Prios auf "Abgewiesen" setzen @@ -894,12 +894,22 @@ class ReihungstestJob extends JOB_Controller { foreach ($resultNiedrPrios->retval as $rowNiedrPrios) { - // nur Info wenn aufgenommen oder master - if ($rowNiedrPrios->laststatus == 'Aufgenommener' || $rowNiedrPrios->studiengang_typ == 'm') + // nur Info wenn aufgenommen/student oder master + if ($rowNiedrPrios->laststatus == 'Aufgenommener' || $rowNiedrPrios->laststatus == 'Student' || $rowNiedrPrios->studiengang_typ == 'm') { - // Mail zur Info an Assistenz schicken, dass in höherer Prio aufgenommen wurde - $mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['AufnahmeHoeherePrio'][] - = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; + + if ($rowNiedrPrios->laststatus == 'Aufgenommener') + { + // Mail zur Info an Assistenz schicken, dass in höherer Prio aufgenommen wurde + $mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['AufnahmeHoeherePrio'][] + = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; + } + else if ($rowNiedrPrios->laststatus == 'Student') + { + $mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['StudentHoeherePrio'][] + = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; + } + } elseif ($rowNiedrPrios->laststatus == 'Bewerber' && $row_ps->prestudenstatus_datum > $rowNiedrPrios->datum) { @@ -966,7 +976,7 @@ class ReihungstestJob extends JOB_Controller FROM public.tbl_konto WHERE person_id = " . $row_ps->person_id . " AND studiensemester_kurzbz = '" . $row_ps->studiensemester_kurzbz . "' - AND buchungstyp_kurzbz = 'StudiengebuehrAnzahlung'"; + AND buchungstyp_kurzbz IN ('StudiengebuehrAnzahlung','KautionDrittStaat')"; $resultKautionExists = $db->execReadOnlyQuery($qryKautionExists); if (hasdata($resultKautionExists)) @@ -1061,6 +1071,20 @@ class ReihungstestJob extends JOB_Controller $mailcontent .= ''; $content = true; } + if (isset($value['StudentHoeherePrio']) && !isEmptyArray($value['StudentHoeherePrio'])) + { + $mailcontent .= '

+ Folgende Studenten wurden in einem höher priorisierten Studiengang aufgenommen:

'; + $mailcontent .= ''; + $mailcontent .= ' '; + sort($value['StudentHoeherePrio']); + foreach ($value['StudentHoeherePrio'] AS $key=>$bewerber) + { + $mailcontent .= ''; + } + $mailcontent .= '
'.$bewerber.'
'; + $content = true; + } if (isset($value['AbgewiesenHoeherePrio']) && !isEmptyArray($value['AbgewiesenHoeherePrio'])) { $mailcontent .= '

diff --git a/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php b/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php deleted file mode 100644 index d22ddb85f..000000000 --- a/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php +++ /dev/null @@ -1,114 +0,0 @@ -load->library('vertragsbestandteil/VertragsbestandteilLib', - null, 'VertragsbestandteilLib'); - $this->load->library('vertragsbestandteil/GehaltsbestandteilLib', - null, 'GehaltsbestandteilLib'); - } - - public function testFetch() - { - $dienstverhaeltnis_id = 1; - $stichtag = null; - - foreach($this->VertragsbestandteilLib->fetchVertragsbestandteile( - $dienstverhaeltnis_id, $stichtag) as $vertragsbestandteil) - { - //print_r($vertragsbestandteil); - echo $vertragsbestandteil . "\n"; - } - } - - public function testUpdate() - { - $now = new DateTime(); - - $data = new stdClass(); - $data->vertragsbestandteil_id = 32; - $data->von = '2022-12-05'; - - $data->wochenstunden = 45.0; - $data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN; - - $vb = VertragsbestandteilFactory::getVertragsbestandteil($data); - - try - { - $this->VertragsbestandteilLib->storeVertragsbestandteil($vb); - echo "Update successful.\n"; - } - catch( Exception $ex ) - { - echo "Update failed.\n"; - } - } - - - public function testInsert() - { - $now = new DateTime(); - - $data = new stdClass(); - $data->dienstverhaeltnis_id = 1; - $data->von = '2022-12-01'; - $data->insertamum = $now->format(DateTime::ATOM); - $data->insertvon = 'ma0080'; - $data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION; - - $data->benutzerfunktion_id = 112667; - $data->anmerkung = 'test funkton'; - $data->kuendigungsrelevant = false; - - $vb = VertragsbestandteilFactory::getVertragsbestandteil($data); - - try - { - $this->VertragsbestandteilLib->storeVertragsbestandteil($vb); - echo "Insert successful.\n"; - } - catch( Exception $ex ) - { - echo "Insert failed.\n"; - } - } - - public function testGehaltsbestandteilInsert() - { - $data = new stdClass(); - $data->gehaltsbestandteil_id = 2; - /* - $data->dienstverhaeltnis_id = 39; - $data->vertragsbestandteil_id = 123; - $data->gehaltstyp_kurzbz = 'zulage'; - $data->von = '2023-04-01'; - $data->bis = '2023-08-31'; - $data->anmerkung = 'test anmerkung'; - $data->grundbetrag = 100; - $data->betrag_valorisiert = 100; - $data->valorisierung = true; - */ - $data->auszahlungen = 12; - - $gb = new \vertragsbestandteil\Gehaltsbestandteil(); - $gb->hydrateByStdClass($data); - - print_r($gb->toStdClass()); - - $this->GehaltsbestandteilLib->storeGehaltsbestandteil($gb); - } -} diff --git a/application/controllers/lehre/Pruefungsprotokoll.php b/application/controllers/lehre/Pruefungsprotokoll.php index 21f50acca..4d34b08ca 100644 --- a/application/controllers/lehre/Pruefungsprotokoll.php +++ b/application/controllers/lehre/Pruefungsprotokoll.php @@ -6,58 +6,59 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); */ class Pruefungsprotokoll extends Auth_Controller { - private $_uid; // uid of the logged user + private $_uid; // uid of the logged user - /** - * Constructor - */ - public function __construct() - { - // Set required permissions - parent::__construct( - array( - 'index' => 'lehre/pruefungsbeurteilung:r', - 'Protokoll' => 'lehre/pruefungsbeurteilung:r', - 'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw', - ) - ); + /** + * Constructor + */ + public function __construct() + { + // Set required permissions + parent::__construct( + array( + 'index' => 'lehre/pruefungsbeurteilung:r', + 'Protokoll' => 'lehre/pruefungsbeurteilung:r', + 'showProtokoll' => 'lehre/pruefungsbeurteilung:r', + 'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw', + ) + ); - // Load models - $this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel'); - $this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel'); + // Load models + $this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel'); + $this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel'); - $this->load->library('PermissionLib'); - $this->load->library('AuthLib'); + $this->load->library('PermissionLib'); + $this->load->library('AuthLib'); - // Load language phrases - $this->loadPhrases( - array( - 'ui', - 'global', - 'person', - 'abschlusspruefung', + // Load language phrases + $this->loadPhrases( + array( + 'ui', + 'global', + 'person', + 'abschlusspruefung', 'password', 'lehre' - ) - ); + ) + ); - $this->_setAuthUID(); // sets property uid + $this->_setAuthUID(); // sets property uid - $this->setControllerId(); // sets the controller id - } + $this->setControllerId(); // sets the controller id + } - // ----------------------------------------------------------------------------------------------------------------- - // Public methods + // ----------------------------------------------------------------------------------------------------------------- + // Public methods public function index() { $this->load->library('WidgetLib'); - + // Protokolle anzeigen seit heute / letzte Woche / alle $period = $this->input->post('period'); $period = (!is_null($period)) ? $period : 'today'; - + $data = array('period' => $period); - + $this->load->view('lehre/pruefungsprotokollUebersicht.php', $data); } @@ -66,47 +67,15 @@ class Pruefungsprotokoll extends Auth_Controller */ public function Protokoll() { - $abschlusspruefung_id = $this->input->get('abschlusspruefung_id'); + $this->load->view('lehre/pruefungsprotokoll.php', $this->_getPruefungsprotokollData()); + } - if (!is_numeric($abschlusspruefung_id)) - show_error('invalid abschlusspruefung'); - - $abschlusspruefung_saved = false; - $abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id); - - if (isError($abschlusspruefung)) - show_error(getError($abschlusspruefung)); - else - { - $abschlusspruefung = getData($abschlusspruefung); - $abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz); - } - - $this->AbschlussbeurteilungModel->addOrder("sort", "ASC"); - $this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1 - WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2 - WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3 - WHEN abschlussbeurteilung_kurzbz = 'angerechnet' THEN 4 - ELSE 5 - END - )"); - $abschlussbeurteilung = $this->AbschlussbeurteilungModel->load(); - - if (isError($abschlussbeurteilung)) - show_error(getError($abschlussbeurteilung)); - else - $abschlussbeurteilung = getData($abschlussbeurteilung); - - $language = getUserLanguage(); - - $data = array( - 'abschlusspruefung' => $abschlusspruefung, - 'abschlussbeurteilung' => $abschlussbeurteilung, - 'abschlusspruefung_saved' => $abschlusspruefung_saved, - 'language' => $language - ); - - $this->load->view('lehre/pruefungsprotokoll.php', $data); + /** + * Show Pruefungsprotokoll. + */ + public function showProtokoll() + { + $this->load->view('lehre/pruefungsprotokoll.php', array_merge($this->_getPruefungsprotokollData(), array('readonly' => true))); } /** @@ -168,18 +137,66 @@ class Pruefungsprotokoll extends Auth_Controller $this->outputJsonError($this->p->t('ui', 'ungueltigeParameter')); } - // ----------------------------------------------------------------------------------------------------------------- - // Private methods + // ----------------------------------------------------------------------------------------------------------------- + // Private methods - /** - * Retrieve the UID of the logged user and checks if it is valid - */ - private function _setAuthUID() - { - $this->_uid = getAuthUID(); + /** + * Retrieve the UID of the logged user and checks if it is valid + */ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); - if (!$this->_uid) show_error('User authentification failed'); - } + if (!$this->_uid) show_error('User authentification failed'); + } + + /** + * + * @param + * @return object success or error + */ + private function _getPruefungsprotokollData() + { + $abschlusspruefung_id = $this->input->get('abschlusspruefung_id'); + + if (!is_numeric($abschlusspruefung_id)) + show_error('invalid abschlusspruefung'); + + $abschlusspruefung_saved = false; + $abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id); + + if (isError($abschlusspruefung)) + show_error(getError($abschlusspruefung)); + else + { + $abschlusspruefung = getData($abschlusspruefung); + $abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz); + } + + $this->AbschlussbeurteilungModel->addOrder("sort", "ASC"); + $this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1 + WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2 + WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3 + WHEN abschlussbeurteilung_kurzbz = 'angerechnet' THEN 4 + ELSE 5 + END + )"); + $abschlussbeurteilung = $this->AbschlussbeurteilungModel->load(); + + if (isError($abschlussbeurteilung)) + show_error(getError($abschlussbeurteilung)); + else + $abschlussbeurteilung = getData($abschlussbeurteilung); + + $language = getUserLanguage(); + + return array( + 'abschlusspruefung' => $abschlusspruefung, + 'abschlussbeurteilung' => $abschlussbeurteilung, + 'abschlusspruefung_saved' => $abschlusspruefung_saved, + 'language' => $language + ); + } /** * Retrieves an Abschlussprüfung, with permission check @@ -187,7 +204,7 @@ class Pruefungsprotokoll extends Auth_Controller * @param $abschlusspruefung_id * @return object success or error */ - private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id) + private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id) { $result = error('Error when getting Abschlusspruefung'); diff --git a/application/controllers/person/Gruppenmanagement.php b/application/controllers/person/Gruppenmanagement.php index 1a4c341a4..099871676 100644 --- a/application/controllers/person/Gruppenmanagement.php +++ b/application/controllers/person/Gruppenmanagement.php @@ -29,6 +29,7 @@ class Gruppenmanagement extends Auth_Controller $this->load->model('person/benutzer_model', 'BenutzerModel'); $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); $this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('person/gruppe_manager_model', 'GruppemanagerModel'); $this->load->model('system/Log_model', 'LogModel'); $this->load->library('WidgetLib'); @@ -117,6 +118,27 @@ class Gruppenmanagement extends Auth_Controller $result = error('Uid missing'); else { + $this->GruppemanagerModel->addSelect('1'); + $isManagerRes = $this->GruppemanagerModel->loadWhere( + array( + 'uid' => $this->_uid, + 'gruppe_kurzbz' => $gruppe_kurzbz + ) + ); + + if (isError($isManagerRes)) + { + $this->outputJsonError(getError($isManagerRes)); + return; + } + + if (!hasData($isManagerRes)) + { + $this->outputJsonError($this->p->t('gruppenmanagement', 'nichtZumEditierenDerGruppeBerechtigt')); + return; + } + + $this->BenutzergruppeModel->addSelect('1'); $benutzerExistsRes = $this->BenutzergruppeModel->loadWhere( array( 'uid' => $uid, @@ -170,6 +192,26 @@ class Gruppenmanagement extends Auth_Controller $result = error('Uid missing'); else { + $this->GruppemanagerModel->addSelect('1'); + $isManagerRes = $this->GruppemanagerModel->loadWhere( + array( + 'uid' => $this->_uid, + 'gruppe_kurzbz' => $gruppe_kurzbz + ) + ); + + if (isError($isManagerRes)) + { + $this->outputJsonError(getError($isManagerRes)); + return; + } + + if (!hasData($isManagerRes)) + { + $this->outputJsonError($this->p->t('gruppenmanagement', 'nichtZumEditierenDerGruppeBerechtigt')); + return; + } + $result = $this->BenutzergruppeModel->delete( array( 'uid' => $uid, diff --git a/application/controllers/system/TestSearch.php b/application/controllers/system/TestSearch.php deleted file mode 100644 index 1f5c66a1d..000000000 --- a/application/controllers/system/TestSearch.php +++ /dev/null @@ -1,44 +0,0 @@ - 'system/developer:r' - ) - ); - - // Loads WidgetLib - $this->load->library('WidgetLib'); - - // Loads phrases system - $this->loadPhrases( - array( - 'global', - 'ui', - 'filter' - ) - ); - } - - // ----------------------------------------------------------------------------------------------------------------- - // Public methods - - /** - * Everything has a beginning - */ - public function index() - { - $this->load->view('system/logs/testSearch.php'); - } -} diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index f6e41d2e6..57aca0876 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -2375,16 +2375,50 @@ class InfoCenter extends Auth_Controller if ($statusgrund === 'null' || $studiengang === 'null' || $abgeschickt === 'null' || empty($personen)) $this->terminateWithJsonError("Bitte füllen Sie alle Felder aus"); - foreach($personen as $person) + if ($studiengang === 'all' && $abgeschickt === 'all') { - $prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt); + foreach($personen as $person) + { + $prestudenten = $this->PrestudentModel->getByPersonWithoutLehrgang($person, $studienSemester); - if (!hasData($prestudent)) - continue; + if (!hasData($prestudenten)) + continue; - $prestudentData = getData($prestudent); + $prestudentenData = getData($prestudenten); + + foreach ($prestudentenData as $prestudent) + { + $this->saveAbsage($prestudent->prestudent_id, $statusgrund); + } + } + } + else + { + $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); + + $this->StudienplanModel->addSelect('1'); + $this->StudienplanModel->addJoin('lehre.tbl_studienordnung so', 'studienordnung_id'); + $escaped = $this->StudienplanModel->db->escape(strtoupper($studiengang)); + $this->StudienplanModel->db->where("UPPER(so.studiengangkurzbzlang || ':' || tbl_studienplan.orgform_kurzbz) = $escaped"); + $this->StudienplanModel->addLimit(1); + $studiengangResult = $this->StudienplanModel->load(); + + if (hasData($studiengangResult)) + { + foreach($personen as $person) + { + $prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt, $abgeschickt === 'all'); + + if (!hasData($prestudent)) + continue; + + $prestudentData = getData($prestudent); + $this->saveAbsage($prestudentData[0]->prestudent_id, $statusgrund); + } + } + else + $this->terminateWithJsonError("Falschen Studiengang übergeben!"); - $this->saveAbsage($prestudentData[0]->prestudent_id, $statusgrund); } $this->outputJsonSuccess("Success"); diff --git a/application/controllers/system/infocenter/Rueckstellung.php b/application/controllers/system/infocenter/Rueckstellung.php index 62af633ca..b1f2b60b7 100644 --- a/application/controllers/system/infocenter/Rueckstellung.php +++ b/application/controllers/system/infocenter/Rueckstellung.php @@ -14,7 +14,8 @@ class Rueckstellung extends Auth_Controller 'get' => array('infocenter:r', 'lehre/zgvpruefung:r'), 'set' => array('infocenter:r', 'lehre/zgvpruefung:r'), 'delete' => array('infocenter:r', 'lehre/zgvpruefung:r'), - 'getStatus' => array('infocenter:rw', 'lehre/zgvpruefung:rw') + 'getStatus' => array('infocenter:rw', 'lehre/zgvpruefung:rw'), + 'setForPersonen' => array('infocenter:rw', 'lehre/zgvpruefung:rw'), ) ); @@ -79,7 +80,34 @@ class Rueckstellung extends Auth_Controller $this->outputJson($result); } - + + public function setForPersonen() + { + $personen = $this->input->post('personen'); + $datum_bis = $this->input->post('datum_bis'); + $status_kurzbz = $this->input->post('status_kurzbz'); + + foreach ($personen as $person) + { + $rueckstellung = $this->_ci->RueckstellungModel->loadWhere(array('person_id' => $person)); + if (hasData($rueckstellung)) + continue; + + $result = $this->_ci->RueckstellungModel->insert( + array('person_id' => $person, + 'status_kurzbz' => $status_kurzbz, + 'datum_bis' => date_format(date_create($datum_bis), 'Y-m-d'), + 'insertvon' => $this->_uid + ) + ); + + if (isError($result)) + $this->terminateWithJsonError(getError($result)); + $this->_log($person, $status_kurzbz); + } + $this->outputJsonSuccess("Erfolgreich gespeichert!"); + } + public function delete() { $person_id = $this->input->post('person_id'); diff --git a/application/controllers/system/issues/Issues.php b/application/controllers/system/issues/Issues.php index 44c2ff5d3..27a928fb4 100644 --- a/application/controllers/system/issues/Issues.php +++ b/application/controllers/system/issues/Issues.php @@ -6,7 +6,6 @@ class Issues extends Auth_Controller { private $_uid; - const FUNKTION_KURZBZ = 'ass'; // user having this funktion can see issues for oes assigned with this funktion const BERECHTIGUNG_KURZBZ = 'system/issues_verwalten'; // user having this permission can see issues for oes assigned with this permission public function __construct() @@ -28,6 +27,9 @@ class Issues extends Auth_Controller $this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); $this->load->model('system/Sprache_model', 'SpracheModel'); + // load config + $this->load->config('issueList'); + $this->loadPhrases( array( 'global', @@ -47,10 +49,12 @@ class Issues extends Auth_Controller { $oes_for_issues = $this->_getOesForIssues(); $language_index = $this->_getLanguageIndex(); + $apps = $this->config->item('issues_list_apps'); + $status = $this->config->item('issues_list_status'); $this->load->view( 'system/issues/issues', - array_merge($oes_for_issues, array('language_index' => $language_index)) + array_merge($oes_for_issues, array('language_index' => $language_index, 'apps' => $apps, 'status' => $status)) ); } @@ -121,6 +125,8 @@ class Issues extends Auth_Controller $oe_kurzbz_for_funktion = array(); $benutzerfunktionRes = $this->BenutzerfunktionModel->getBenutzerFunktionByUid($this->_uid, null, date('Y-m-d'), date('Y-m-d')); + $functions = $this->config->item('issues_list_functions'); + if (isError($benutzerfunktionRes)) show_error(getError($benutzerfunktionRes)); @@ -130,8 +136,8 @@ class Issues extends Auth_Controller { $all_funktionen_oe_kurzbz[$benutzerfunktion->oe_kurzbz][] = $benutzerfunktion->funktion_kurzbz; - // separate oes for the additional funktion which enables displaying issues - if ($benutzerfunktion->funktion_kurzbz == self::FUNKTION_KURZBZ) + // separate oes for the additional functions which enables displaying issues + if (in_array($benutzerfunktion->funktion_kurzbz, $functions)) { $oe_kurzbz_for_funktion[] = $benutzerfunktion->oe_kurzbz; diff --git a/application/core/CI3_Events.php b/application/core/CI3_Events.php index 33a96b89e..37f6c3f21 100644 --- a/application/core/CI3_Events.php +++ b/application/core/CI3_Events.php @@ -46,6 +46,20 @@ class CI3_Events * NOTE(chris): Autoload Events config */ require_once(APPPATH.'config/Events.php'); + +$active_addons_array = explode(";", ACTIVE_ADDONS); + foreach (scandir(APPPATH.'config/extensions') as $dir) if ($dir[0] != '.' && file_exists(APPPATH.'config/extensions/'.$dir.'/Events.php')) require_once APPPATH.'config/extensions/'.$dir.'/Events.php'; + +foreach (scandir(FHCPATH.'addons') as $dir) + if ($dir[0] != '.' && file_exists(FHCPATH.'addons/'.$dir.'/Events.php')) + { + // only includes the Events of the addon if the addon is one of the active addons in the cis config + if(in_array($dir,$active_addons_array)) + { + require_once FHCPATH . 'addons/' . $dir . '/Events.php'; + } + } + diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index c799de516..2f33bc82e 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -60,6 +60,9 @@ class DB_Model extends CI_Model protected $pk; // Name of the PrimaryKey for DB-Update, Load, ... protected $hasSequence; // False if this table has a composite primary key that is not using a sequence // True if this table has a primary key that uses a sequence + //protected $paginationOptions; // $page and $page_size together in an associative array + protected $page; + protected $page_size; private $executedQueryMetaData; private $executedQueryListFields; @@ -531,7 +534,7 @@ class DB_Model extends CI_Model if (!is_numeric($start) || (is_numeric($start) && $start <= 0)) return error('The start parameter is not valid', EXIT_MODEL); - if (is_numeric($end) && $end > $start) + if (is_numeric($end)) { $this->db->limit($start, $end); } @@ -988,14 +991,17 @@ class DB_Model extends CI_Model // Find and replace all the occurrences of the provided encrypted columns // with the postgresql decryption function - $query = str_replace( - $encryptedColumn, - sprintf( - self::CRYPT_WHERE_TEMPLATE, - $encryptedColumn, - $decryptionPassword, - $definition[self::CRYPT_CAST] - ), + $query = preg_replace_callback( + '/(? 0 && $page_size > 0) { + + if (isset($num_rows) && is_numeric($num_rows) && $num_rows > 0) { + $floatMaxPageCount = $num_rows / $page_size; + $maxPageCount = ceil($floatMaxPageCount); + if($page > $maxPageCount){ + $page = $maxPageCount; + } + } + $offset = (($page-1) * $page_size); + $this->addLimit($page_size, $offset); + + } else { + $this->addLimit($page_size); + } + } + + /** + * getQueryNumRows + * returns the number of rows of the current build query of the codeigniter query builder instance + * @param bool $reset resets the select of the query + * + * @return Result_object $num_rows + */ + function getNumRows($reset=false) + { + // returns the number of rows when executing the current query without reseting the select statement of the query + $num_rows = $this->db->count_all_results($this->dbTable,$reset); + if($num_rows){ + return success($num_rows); + }else{ + return error($this->db->error(), EXIT_DATABASE); + } + } } diff --git a/application/core/FHCAPI_Controller.php b/application/core/FHCAPI_Controller.php index 197f4757f..90c83cc43 100644 --- a/application/core/FHCAPI_Controller.php +++ b/application/core/FHCAPI_Controller.php @@ -151,6 +151,19 @@ class FHCAPI_Controller extends Auth_Controller $this->returnObj['meta'][$key] = $value; } + /** + * @param string $key + * @return mixed + */ + public function getMeta($key) + { + if (!isset($this->returnObj['meta'])) + return null; + if (!isset($this->returnObj['meta'][$key])) + return null; + return $this->returnObj['meta'][$key]; + } + /** * @param string $status * @return void @@ -189,7 +202,7 @@ class FHCAPI_Controller extends Auth_Controller } /** - * @param array $error + * @param string|array|object $error * @param string $type (optional) * @param integer $status (optional) * @return void @@ -205,7 +218,7 @@ class FHCAPI_Controller extends Auth_Controller /** * @param stdclass $result * @param string $errortype - * @return void + * @return mixed */ protected function getDataOrTerminateWithError($result, $errortype = self::ERROR_TYPE_GENERAL) { diff --git a/application/core/Notiz_Controller.php b/application/core/Notiz_Controller.php index 05f70ee85..472ac7669 100644 --- a/application/core/Notiz_Controller.php +++ b/application/core/Notiz_Controller.php @@ -309,6 +309,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller } //update(1) loading all dms-entries with this notiz_id + $dms_id_arr = []; $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); $this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id'); diff --git a/application/core/Tag_Controller.php b/application/core/Tag_Controller.php new file mode 100644 index 000000000..10e54780e --- /dev/null +++ b/application/core/Tag_Controller.php @@ -0,0 +1,212 @@ + self::BERECHTIGUNG_KURZBZ, + 'getTags' => self::BERECHTIGUNG_KURZBZ, + 'addTag' => self::BERECHTIGUNG_KURZBZ, + + 'updateTag' => self::BERECHTIGUNG_KURZBZ, + 'doneTag' => self::BERECHTIGUNG_KURZBZ, + 'deleteTag' => self::BERECHTIGUNG_KURZBZ, + ]; + + $merged_permissions = array_merge($default_permissions, $permissions); + + parent::__construct($merged_permissions); + + $this->_setAuthUID(); + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('system/Notiztyp_model', 'NotiztypModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + } + + public function getTag() + { + $language = $this->_getLanguageIndex(); + $id = $this->input->get('id'); + + $this->NotizModel->addSelect( + "tbl_notiz.titel, + tbl_notiz.text, + array_to_json(bezeichnung_mehrsprachig::varchar[])->>". $language. " as bezeichnung, + tbl_notiz.notiz_id, + tbl_notiz_typ.style, + tbl_notiz.erledigt as done, + tbl_notiz.insertamum, + tbl_notiz.updateamum, + (verfasserperson.vorname || ' ' || verfasserperson.nachname || ' ' || '(' || verfasserbenutzer.uid || ')') as verfasser, + (bearbeiterperson.vorname || ' ' || bearbeiterperson.nachname || ' ' || '(' || bearbeiterbenutzer.uid || ')') as bearbeiter + " + ); + $this->NotizModel->addJoin('public.tbl_notiz_typ', 'public.tbl_notiz.typ = public.tbl_notiz_typ.typ_kurzbz'); + + $this->NotizModel->addJoin('public.tbl_benutzer verfasserbenutzer', 'tbl_notiz.verfasser_uid = verfasserbenutzer.uid', 'LEFT'); + $this->NotizModel->addJoin('public.tbl_person verfasserperson', 'verfasserbenutzer.person_id = verfasserperson.person_id', 'LEFT'); + + $this->NotizModel->addJoin('public.tbl_benutzer bearbeiterbenutzer', 'tbl_notiz.verfasser_uid = bearbeiterbenutzer.uid', 'LEFT'); + $this->NotizModel->addJoin('public.tbl_person bearbeiterperson', 'bearbeiterbenutzer.person_id = bearbeiterperson.person_id', 'LEFT'); + + $notiz = $this->NotizModel->loadWhere(array('notiz_id' => $id)); + + $this->terminateWithSuccess(hasData($notiz) ? getData($notiz)[0] : array()); + } + + public function getTags() + { + $this->NotiztypModel->addSelect( + 'typ_kurzbz as tag_typ_kurzbz, + array_to_json(bezeichnung_mehrsprachig::varchar[])->>0 as bezeichnung, + style, + beschreibung, + tag + ' + ); + $this->NotiztypModel->addOrder('prioritaet'); + $notiztypen = $this->NotiztypModel->loadWhere(array('aktiv' => true)); + $this->terminateWithSuccess(hasData($notiztypen) ? getData($notiztypen) : array()); + } + + public function addTag($withZuordnung = true) + { + $postData = $this->getPostJson(); + + $checkTyp = $this->NotiztypModel->loadWhere(array('typ_kurzbz' => $postData->tag_typ_kurzbz)); + + if (!hasData($checkTyp)) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + + if ($withZuordnung) + { + $return = array(); + $checkZuordnungType = $this->NotizzuordnungModel->isValidType($postData->zuordnung_typ); + if (!isSuccess($checkZuordnungType)) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $values = array_unique($postData->values); + + foreach ($values as $value) + { + $insertResult = $this->addNotiz($postData); + + if (isError($insertResult)) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $insertZuordnung = $this->NotizzuordnungModel->insert(array( + 'notiz_id' => $insertResult->retval, + $postData->zuordnung_typ => $value + )); + + if (isError($insertZuordnung)) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + $return[] = [$postData->zuordnung_typ => $value, 'id' => $insertResult->retval]; + } + $this->terminateWithSuccess($return); + } + else + { + $insertResult = $this->addNotiz($postData); + if (isError($insertResult)) + $this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL); + + return $insertResult->retval; + } + } + + private function addNotiz($postData) + { + return $this->NotizModel->insert(array( + 'titel' => 'TAG', //TODO klären + 'text' => $postData->notiz, + 'verfasser_uid' => $this->_uid, + 'erledigt' => false, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => $this->_uid, + 'typ' => $postData->tag_typ_kurzbz + )); + + } + public function updateTag() + { + $postData = $this->getPostJson(); + $updateData = $this->NotizModel->update(array('notiz_id' => $postData->id), + array('text' => $postData->notiz, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_uid, + 'bearbeiter_uid' => $this->_uid, + ) + ); + $this->terminateWithSuccess($updateData); + } + public function doneTag() + { + $postData = $this->getPostJson(); + $updateData = $this->NotizModel->update(array('notiz_id' => $postData->id), + array('erledigt' => !$postData->done, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_uid, + 'bearbeiter_uid' => $this->_uid, + ) + ); + + $this->terminateWithSuccess($updateData); + } + + public function deleteTag($withZuordnung = true) + { + $postData = $this->getPostJson(); + + $deleteNotiz = ""; + if ($withZuordnung) + { + $deleteZuordnung = $this->NotizzuordnungModel->delete(array( + 'notiz_id' => $postData->id + )); + + if (isSuccess($deleteZuordnung)) + { + $deleteNotiz = $this->NotizModel->delete(array( + 'notiz_id' => $postData->id + )); + } + } + else + { + $deleteNotiz = $this->NotizModel->delete(array( + 'notiz_id' => $postData->id + )); + } + $this->terminateWithSuccess($deleteNotiz); + } + + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } + + private function _getLanguageIndex() + { + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->SpracheModel->addSelect('index'); + $result = $this->SpracheModel->loadWhere(array('sprache' => getUserLanguage())); + + return hasData($result) ? getData($result)[0]->index : 1; + } + + +} \ No newline at end of file diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index ea1795ad5..de7e866f4 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -87,18 +87,32 @@ function generateCSSsInclude($CSSs) */ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod) { + $ci =& get_instance(); + $ci->load->model('system/Sprache_model','SpracheModel'); + $server_language = getData($ci->SpracheModel->loadWhere(['content' => true])); + $server_language = array_map(function($language){ + return ['sprache'=>$language->sprache, 'LC_Time'=>$language->locale, 'bezeichnung'=>$language->bezeichnung[$language->index-1]]; + }, $server_language); $user_language = getUserLanguage(); + $ci->load->config('javascript'); + $systemerror_mailto = $ci->config->item('systemerror_mailto'); + + $FHC_JS_DATA_STORAGE_OBJECT = array( + 'app_root' => APP_ROOT, + 'ci_router' => $indexPage, + 'called_path' => $calledPath, + 'called_method' => $calledMethod, + 'server_languages' => $server_language, + 'user_language' => $user_language, + 'timezone' => date_default_timezone_get(), + 'systemerror_mailto' => $systemerror_mailto, + ); + $toPrint = "\n"; $toPrint .= ''; $toPrint .= "\n\n"; diff --git a/application/helpers/hlp_return_object_helper.php b/application/helpers/hlp_return_object_helper.php index cc896856d..602008d3b 100644 --- a/application/helpers/hlp_return_object_helper.php +++ b/application/helpers/hlp_return_object_helper.php @@ -25,6 +25,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** * Used to create a return object, should not be used directly + * @return stdClass */ function _createReturnObject($code, $error, $retval) { @@ -39,7 +40,7 @@ function _createReturnObject($code, $error, $retval) /** * Success * - * @return array + * @return stdClass */ function success($retval = null, $code = null) { @@ -49,7 +50,7 @@ function success($retval = null, $code = null) /** * Error * - * @return array + * @return stdClass */ function error($retval = null, $code = null) { diff --git a/application/helpers/hlp_sancho_helper.php b/application/helpers/hlp_sancho_helper.php index d599e40bc..9a32f5e1a 100644 --- a/application/helpers/hlp_sancho_helper.php +++ b/application/helpers/hlp_sancho_helper.php @@ -23,9 +23,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); // Functions needed in the view FHC-Header // ------------------------------------------------------------------------ -const DEFAULT_SANCHO_HEADER_IMG = 'sancho_header_DEFAULT.jpg'; -const DEFAULT_SANCHO_FOOTER_IMG = 'sancho_footer_DEFAULT.jpg'; - /** * Send single Mail with Sancho Design and Layout. * @param string $vorlage_kurzbz Name of the template for specific mail content. @@ -38,27 +35,88 @@ const DEFAULT_SANCHO_FOOTER_IMG = 'sancho_footer_DEFAULT.jpg'; * @param string $bcc Sets BCC of mail. * @return void */ -function sendSanchoMail($vorlage_kurzbz, $vorlage_data, $to, $subject, $headerImg = DEFAULT_SANCHO_HEADER_IMG, $footerImg = DEFAULT_SANCHO_FOOTER_IMG, $from = null, $cc = null, $bcc = null) +function sendSanchoMail( + $vorlage_kurzbz, + $vorlage_data, + $to, + $subject, + $headerImg = '', + $footerImg = '', + $from = null, + $cc = null, + $bcc = null +) { $ci =& get_instance(); $ci->load->library('email'); $ci->load->library('MailLib'); - $sanchoHeader_img = 'skin/images/sancho/'. $headerImg; - $sanchoFooter_img = 'skin/images/sancho/'. $footerImg; + $sancho_mail_config = $ci->config->item('mail'); + if ($from == '') { - $from = 'sancho@'.DOMAIN; + $from = ((isset($sancho_mail_config['sancho_mail_default_sender']) + && $sancho_mail_config['sancho_mail_default_sender']) + ? $sancho_mail_config['sancho_mail_default_sender'] + : 'noreply') + . '@' . DOMAIN; } // Embed sancho header and footer image // reset important to ensure embedding of images when called in a loop $ci->email->clear(true); // clear vars and attachments - $ci->email->attach($sanchoHeader_img); - $ci->email->attach($sanchoFooter_img); - $cid_header = $ci->email->attachment_cid($sanchoHeader_img); // sets unique content id for embedding - $cid_footer = $ci->email->attachment_cid($sanchoFooter_img); // sets unique content id for embedding + + $cid_header = ''; + $cid_footer = ''; + + if (isset($sancho_mail_config['sancho_mail_use_images']) && $sancho_mail_config['sancho_mail_use_images']) + { + $sanchoHeader_img = ''; + $sanchoFooter_img = ''; + + if (isset($headerImg) && $headerImg != '') + { + // use provided header image + $sanchoHeader_img = $headerImg; + } + elseif (isset($sancho_mail_config['sancho_mail_header_img']) && $sancho_mail_config['sancho_mail_header_img']) + { + // use default header image + $sanchoHeader_img = $sancho_mail_config['sancho_mail_header_img']; + } + + if (isset($footerImg) && $footerImg != '') + { + // use provided footer image + $sanchoFooter_img = $footerImg; + } + elseif (isset($sancho_mail_config['sancho_mail_footer_img']) && $sancho_mail_config['sancho_mail_footer_img']) + { + // use default footer image + $sanchoFooter_img = $sancho_mail_config['sancho_mail_footer_img']; + } + + // add image file paths + if (isset($sancho_mail_config['sancho_mail_img_path'])) + { + if ($sanchoHeader_img != '') + { + $sanchoHeader_img = $sancho_mail_config['sancho_mail_img_path'].$sanchoHeader_img; + } + + if ($sanchoFooter_img != '') + { + $sanchoFooter_img = $sancho_mail_config['sancho_mail_img_path'].$sanchoFooter_img; + } + } + + // attach header and footer + $ci->email->attach($sanchoHeader_img, 'inline'); + $ci->email->attach($sanchoFooter_img, 'inline'); + $cid_header = $ci->email->attachment_cid($sanchoHeader_img); // sets unique content id for embedding + $cid_footer = $ci->email->attachment_cid($sanchoFooter_img); // sets unique content id for embedding + } // Set specific mail content into specific content template $content = _parseMailContent($vorlage_kurzbz, $vorlage_data); @@ -74,7 +132,18 @@ function sendSanchoMail($vorlage_kurzbz, $vorlage_data, $to, $subject, $headerIm $body = _parseMailContent('Sancho_Mail_Template', $layout); // Send mail - return $ci->maillib->send($from, $to, $subject, $body, $alias = '', $cc, $bcc, $altMessage = '', $bulk = true, $autogenerated = true); + return $ci->maillib->send( + $from, + $to, + $subject, + $body, + '', // alias + $cc, + $bcc, + '', // altMessage + true, // bulk + true // autogenerated + ); } /** diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index 885acac90..d90a98241 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -77,7 +77,9 @@ class AntragLib 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester ], [ - 'statusgrund_id' => null + 'statusgrund_id' => null, + 'updateamum' => date('c'), + 'updatevon' => $insertvon ]); } } @@ -335,7 +337,10 @@ class AntragLib 'status_kurzbz'=>$prestudentstatus->status_kurzbz, 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester - ], []); + ], [ + 'updateamum' => $insertam, + 'updatevon' => $insertvon + ]); if (isError($result)) { $errors[] = getError($result); diff --git a/application/libraries/CmsLib.php b/application/libraries/CmsLib.php new file mode 100644 index 000000000..355cf7c56 --- /dev/null +++ b/application/libraries/CmsLib.php @@ -0,0 +1,309 @@ +ci =& get_instance(); + + // Load Models + $this->ci->load->model('content/Content_model', 'ContentModel'); + $this->ci->load->model('content/Contentgruppe_model', 'ContentgruppeModel'); + $this->ci->load->model('content/Template_model', 'TemplateModel'); + if (defined('LOG_CONTENT') && LOG_CONTENT) + $this->ci->load->model('system/Webservicelog_model', 'WebservicelogModel'); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @param int $content_id + * @param int $version + * @param string $sprache + * @param boolean $sichtbar + * + * @return stdClass + */ + public function getContent($content_id, $version = null, $sprache = null, $sichtbar = true) + { + if (!is_numeric($content_id)) + return error('ContentID ist ungueltig'); + + if ($sprache === null) + $sprache = getUserLanguage(); + + $islocked = $this->ci->ContentgruppeModel->loadWhere(['content_id' => $content_id]); + if (isError($islocked)) + return $islocked; + + if (getData($islocked)) { + $uid = getAuthUID(); + $isberechtigt = $this->ci->ContentgruppeModel->berechtigt($content_id, $uid); + if (isError($isberechtigt)) + return $isberechtigt; + + if (!getData($isberechtigt)) + return error('global/keineBerechtigungFuerDieseSeite'); + } + $content = $this->ci->ContentModel->getContent($content_id, $sprache, $version, $sichtbar, true); + + if (isError($content)) + return $content; + + // Legt einen Logeintrag für die Klickstatistik an + if (defined('LOG_CONTENT') && LOG_CONTENT) { + // Nur eingeloggte User werden geloggt, das sonst auch alle Infoscreenaufrufe und dgl. mitgeloggt werden + if (isLogged()) { + $request_data = 'content_id=' . $content_id; + if ($version !== null) + $request_data .= '&version=' . $version; + if ($sichtbar !== true) + $request_data .= '&sichtbar=' . $sichtbar; + $this->ci->WebservicelogModel->insert([ + 'webservicetyp_kurzbz' => 'content', + 'request_id' => $content_id, + 'beschreibung' => 'content', + 'request_data' => $request_data . '&sprache=' . $sprache, + 'execute_time' => 'now()', + 'execute_user' => getAuthUID() + ]); + } + } + + $content = getData($content); + + //XSLT Vorlage laden + $template = $this->ci->TemplateModel->load($content->template_kurzbz); + if (isError($template)) + return $template; + $template = current(getData($template)); + + $XML = new DOMDocument(); + $XML->loadXML($content->content); + + if($content->titel){ + $betreff = $content->titel; + }else{ + //DomDocument getElementsByTagName returns a DomNodeList + $betreff = $XML->getElementsByTagName('betreff'); + //check if any betreff was found and if it is not empty + if($betreff->length > 0 && !empty($betreff->item(0)->nodeValue)) + { + //DomNodeList item() return a DomNode, property nodeValue contains the value of the node + $betreff = $betreff->item(0)->nodeValue; + + } + else + { + return error('no betreff found for the content'); + } + } + + $xsltemplate = new DOMDocument(); + $xsltemplate->loadXML($template->xslt_xhtml_c4); + + //Transformation + $processor = new XSLTProcessor(); + $processor->importStylesheet($xsltemplate); + + + $transformed_content = $processor->transformToXML($XML); + //replaces all the dms.php with the new CIS4 Controller + $transformed_content = str_replace('dms.php', APP_ROOT . 'cms/dms.php', $transformed_content); + //replaces all the cms.php with the new CIS4 Controller + $transformed_content = preg_replace('/content\.php\?content\_id\=([0-9]+)/', APP_ROOT.'cis.php/CisVue/Cms/content/$1', $transformed_content); + + return success([ + "betreff"=>$betreff, + "type"=>$content->template_kurzbz, + "content"=>$transformed_content + ]); + } + + /** + * @param stdClass $stg_obj + * + * @return stdClass + */ + protected function getNewsExtras($stg_obj, $semester) + { + $this->ci->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + + $stg_ltg = $this->ci->StudiengangModel->getLeitungDetailed($stg_obj->studiengang_kz); + if (isError($stg_ltg)) + return $stg_ltg; + $stg_ltg = getData($stg_ltg) ?: []; + + $gf_ltg = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('gLtg', $stg_obj->oe_kurzbz); + if (isError($gf_ltg)) + return $gf_ltg; + $gf_ltg = getData($gf_ltg) ?: []; + + $stv_ltg = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stvLtg', $stg_obj->oe_kurzbz); + if (isError($stv_ltg)) + return $stv_ltg; + $stv_ltg = getData($stv_ltg) ?: []; + + $ass = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('ass', $stg_obj->oe_kurzbz); + if (isError($ass)) + return $ass; + $ass = getData($ass) ?: []; + + $hochschulvertr = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('hsv'); + if (isError($hochschulvertr)) + return $hochschulvertr; + $hochschulvertr = getData($hochschulvertr) ?: []; + + $stdv = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stdv', $stg_obj->oe_kurzbz); + if (isError($stdv)) + return $stdv; + $stdv = getData($stdv) ?: []; + + $jahrgangsvertr = $this->ci->BenutzerfunktionModel->getBenutzerFunktionenDetailed('jgv', $stg_obj->oe_kurzbz, $semester); + if (isError($jahrgangsvertr)) + return $jahrgangsvertr; + $jahrgangsvertr = getData($jahrgangsvertr) ?: []; + + return success($this->ci->load->view('Cis/Cms/News/Xml/NewsExtras', [ + 'studiengang' => $stg_obj, + 'semester' => $semester, + 'stg_ltg' => $stg_ltg, + 'gf_ltg' => $gf_ltg, + 'stv_ltg' => $stv_ltg, + 'ass' => $ass, + 'hochschulvertr' => $hochschulvertr, + 'stdv' => $stdv, + 'jahrgangsvertr' => $jahrgangsvertr + ], true)); + } + + /** + * @param string $studiengang_kz + * @param string $semester + * + * @return array queried studiengang_kz and semester + */ + public function getStgAndSem($studiengang_kz, $semester) + { + $this->ci->load->model('crm/Student_model', 'StudentModel'); + + //Zum anzeigen der Studiengang-Details neben den News + $student = $this->ci->StudentModel->loadWhere(['student_uid' => getAuthUID()]); + if (isError($student)) + return $student; + if (getData($student)) { + $student = current(getData($student)); + if ($studiengang_kz === null) + $studiengang_kz = $student->studiengang_kz; + if ($semester === null) + $semester = $student->semester; + } + return [$studiengang_kz, $semester]; + } + + /** + * @param boolean $infoscreen + * @param string | null $studiengang_kz + * @param int | null $semester + * @param boolean $mischen + * @param string $titel + * @param boolean $edit + * @param boolean $sichtbar + * + * @return void + */ + public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true, $page = 1, $page_size = 10, $sprache) + { + $this->ci->load->model('organisation/Studiengang_model', 'StudiengangModel'); + list($studiengang_kz, $semester) = $this->getStgAndSem($studiengang_kz, $semester); + $all = $edit; + + $xml = ''; + + $this->ci->load->model('content/News_model', 'NewsModel'); + $news = $this->ci->NewsModel->getNewsWithContent($sprache, $studiengang_kz, $semester, null, $sichtbar, 0, $page, $page_size, $all, $mischen); + + if (isError($news)) + return $news; + + $news = getData($news); + + foreach ($news as $newsobj) { + if ($studiengang_kz && $edit && !$newsobj->studiengang_kz) + continue; + $date = new DateTime($newsobj->datum); + $datum = 'format('d.m.Y') . ']]>'; + $datum .= 'format('Y-m-d H:i') . ']]>'; + $id = $edit ? 'news_id . ']]>' : ''; + $xml .= "" . $newsobj->content . $datum . $id . ""; + } + + /* if ($studiengang_kz != 0) { + $stg_obj = $this->ci->StudiengangModel->load($studiengang_kz); + if (isError($stg_obj)) + return $stg_obj; + $stg_obj = current(getData($stg_obj) ?: []); + + if ($stg_obj) { + if (!$edit && !$infoscreen) { + $extras = $this->getNewsExtras($stg_obj, $semester); + if (isError($extras)) + return $extras; + $xml .= getData($extras); + } + $xml .= 'bezeichnung . ']]>'; + } + } */ + + if ($titel != '') { + $xml .= '' . $titel . ''; + } + + $xml .= ''; + + //XSLT Vorlage laden + $template = $this->ci->TemplateModel->load($infoscreen ? 'news_infoscreen' : 'news'); + if (isError($template)) + return $template; + $template = current(getData($template)); + + $XML = new DOMDocument(); + $XML->loadXML($xml); + + $xsltemplate = new DOMDocument(); + $xsltemplate->loadXML($template->xslt_xhtml_c4); + + //Transformation + $processor = new XSLTProcessor(); + $processor->importStylesheet($xsltemplate); + + $content = $processor->transformToDoc($XML); + $content->formatOutput = true; + + $content = $content->saveHTML(); + $content = str_replace('dms.php', APP_ROOT . 'cms/dms.php', $content); + + return success($content); + } +} diff --git a/application/libraries/DocumentExportLib.php b/application/libraries/DocumentExportLib.php new file mode 100644 index 000000000..595ac461a --- /dev/null +++ b/application/libraries/DocumentExportLib.php @@ -0,0 +1,714 @@ +vorlage_kurzbz, $oe_kurzbz, $version); + * $doc->setFilename($filename); + * $doc->addDataXML($data); + * $doc->addImage($imagepath, $imagename, $imagecontenttype); + * $doc->create($outputformat); + * $doc->output(true); + * $doc->close(); + * + * New: + * $xml_data = $this->documentexportlib->getDataXML($data); + * $images = [[ + * 'path' => $imagepath, + * 'name' => $imagename, + * 'contenttype' => $imagecontenttype + * ]]; + * $this->documentexportlib->showContent( + * $filename, + * $vorlage, + * $xml_data, + * $oe_kurzbz, + * $version, + * $outputformat, + * null, + * null, + * $images + * ); + */ +class DocumentExportLib +{ + private $unoconv_version; + + /** + * Constructor + */ + public function __construct() + { + // Gets CI instance + $this->ci =& get_instance(); + + // Load Phrases + $this->ci->load->library('PhrasesLib', ['document_export', null], 'documentExportPhrases'); + + // Which document converter has to be used + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) + { + // Use docsbox!! + } + else + { + exec('unoconv --version', $ret_arr); + + if(isset($ret_arr[0])) + { + $hlp = explode(' ', $ret_arr[0]); + if(isset($hlp[1])) + { + $this->unoconv_version = $hlp[1]; + } + else + show_error($this->ci->documentExportPhrases->t("document_export", "error_unoconv_version")); + } + else + show_error($this->ci->documentExportPhrases->t("document_export", "error_unoconv")); + } + } + + /** + * Laedt die XML Daten fuer die XSL Transformation anhand eines Arrays + * + * @param array $data Array mit Daten + * @param string $root Bezeichnung des Root Nodes + * + * @return DOMDocument + */ + public function getDataArray($data, $root) + { + $xml_data = new DOMDocument(); + $xml_data->loadXML($this->convertArrayToXML($data, $root)); + return $xml_data; + } + + /** + * XML Daten fuer die XSL Transformation + * + * @param string $xml + * + * @return DOMDocument + */ + public function getDataXML($xml) + { + $xml_data = new DOMDocument(); + $xml_data->loadXML($xml); + return $xml_data; + } + + /** + * URL zu XML Datei die fuer XSLTransformation verwendet werden soll + * + * @param string $xml URL to XML + * @param string $params GET parameter + * + * @return stdClass + */ + public function getDataURL($xml, $params) + { + $xml_found = false; + + $aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS))); + foreach($aktive_addons as $addon) { + $xmlfile = DOC_ROOT . 'addons/' . $addon . '/rdf/' . $xml; + if (file_exists($xmlfile)) { + $xml_found = true; + $xml_url = XML_ROOT . '../addons/' . $addon . '/rdf/' . $xml . '?' . $params; + break; + } + } + if (!$xml_found) + $xml_url = XML_ROOT . $xml . '?' . $params; + + + // Load the XML source + $xml_data = new DOMDocument; + + if (!$xml_data->load($xml_url)) + return error($this->ci->documentExportPhrases->t("document_export", "error_xml_load", [ + "url" => $xml_url, + "xml" => $xml, + "params" => $params + ])); + + return success($xml_data); + } + + /** + * Adds a XML Tag for signatur to the document + * + * @param DomDocument $xml_data + * + * @return void + */ + protected function addSignToData($xml_data) + { + $signblock = $xml_data->createElement("signed", "true"); + $xml_data->documentElement->appendChild($signblock); + } + + /** + * Adds a XML Tag for archive to the document + * + * @param DomDocument $xml_data + * + * @return void + */ + public function addArchiveToData($xml_data) + { + $archiv = $xml_data->createElement("archivierbar", "true"); + $xml_data->documentElement->appendChild($archiv); + } + + /** + * Get the contents of a Document + * + * @param stdClass $vorlage A db entry from tbl_vorlage + * @param DomDocument $xml_data + * @param string $oe_kurzbz + * @param integer|null $version (optional) + * @param string $outputformat (optional) + * @param string $sign_user (optional) Must be a valid uid + * @param string $sign_profile (optional) Signatureprofile for signing + * @param array $images (optional) Each element should have a property path, name & contenttype which are all strings + * + * @return stdClass + */ + public function getContent( + $vorlage, + $xml_data, + $oe_kurzbz, + $version = null, + $outputformat = null, + $sign_user = null, + $sign_profile = null, + $images = [] + ) { + $source_folder = getcwd(); + $temp_folder = sys_get_temp_dir() . '/fhcunoconv-' . uniqid(); + + $outputformat = $this->getDefaultOutputFormat($outputformat, $vorlage->mimetype); + + $result = $this->createAndSignContent( + $temp_folder, + $outputformat, + $vorlage, + $oe_kurzbz, + $version, + $xml_data, + $images, + $sign_user, + $sign_profile + ); + if (isError($result)) { + $this->close($temp_folder, $source_folder); + return $result; + } + $temp_filename = getData($result); + + $fsize = filesize($temp_filename); + $handle = fopen($temp_filename, 'r'); + if (!$handle) + return error($this->ci->documentExportPhrases->t("document_export", "error_file_load")); + $result = fread($handle, $fsize); + fclose($handle); + + $this->close($temp_folder, $source_folder); + + return success($result); + } + + /** + * Sets the headers and displays the Document. + * On failure the exit() function will be called + * + * @param string $filename + * @param stdClass $vorlage A db entry from tbl_vorlage + * @param DomDocument $xml_data + * @param string $oe_kurzbz + * @param integer|null $version (optional) + * @param string $outputformat (optional) + * @param string $sign_user (optional) Must be a valid uid + * @param string $sign_profile (optional) Signatureprofile for signing + * @param array $images (optional) Each element should have a property path, name & contenttype which are all strings + * + * @return void + */ + public function showContent( + $filename, + $vorlage, + $xml_data, + $oe_kurzbz, + $version = null, + $outputformat = null, + $sign_user = null, + $sign_profile = null, + $images = [] + ) { + $source_folder = getcwd(); + $temp_folder = sys_get_temp_dir() . '/fhcunoconv-' . uniqid(); + + $outputformat = $this->getDefaultOutputFormat($outputformat, $vorlage->mimetype); + + $result = $this->createAndSignContent( + $temp_folder, + $outputformat, + $vorlage, + $oe_kurzbz, + $version, + $xml_data, + $images, + $sign_user, + $sign_profile + ); + if (isError($result)) { + $this->close($temp_folder, $source_folder); + exit(getError($result)); + } + $temp_filename = getData($result); + + $fsize = filesize($temp_filename); + $handle = fopen($temp_filename, 'r'); + if (!$handle) { + $this->close($temp_folder, $source_folder); + exit($this->ci->documentExportPhrases->t("document_export", "error_file_load")); + } + + if (headers_sent()) { + $this->close($temp_folder, $source_folder); + exit($this->ci->documentExportPhrases->t("document_export", "error_headers")); + } + + switch ($outputformat) { + case 'pdf': + header('Content-type: application/pdf'); + header('Content-Disposition: attachment; filename="' . $filename . '.pdf"'); + header('Content-Length: ' . $fsize); + break; + + case 'doc': + header('Content-type: application/vnd.ms-word'); + header('Content-Disposition: attachment; filename="' . $filename . '.doc"'); + header('Content-Length: ' . $fsize); + break; + + case 'odt': + header('Content-type: application/vnd.oasis.opendocument.text'); + header('Content-Disposition: attachment; filename="' . $filename . '.odt"'); + header('Content-Length: ' . $fsize); + break; + default: + $this->close($temp_folder, $source_folder); + exit($this->ci->documentExportPhrases->t("document_export", "error_outputformat_missing")); + } + + while (!feof($handle)) { + echo fread($handle, 8192); + } + fclose($handle); + + $this->close($temp_folder, $source_folder); + } + + /** + * Helper function for getContent and showContent. + * Creates the temp folder and calls create and sign functions. + * + * @param string $temp_folder + * @param string $outputformat + * @param stdClass $vorlage + * @param string $oe_kurzbz + * @param integer $version + * @param DomDocument $xml_data + * @param array $images Each element should have a property path, name and contenttype which are all strings + * @param string $sign_user Must be a valid uid + * @param string $sign_profile Signatureprofile for signing + * + * @return stdClass + */ + protected function createAndSignContent( + $temp_folder, + $outputformat, + $vorlage, + $oe_kurzbz, + $version, + $xml_data, + $images, + $sign_user, + $sign_profile + ) { + mkdir($temp_folder); + chdir($temp_folder); + + $this->ci->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel'); + + $result = $this->ci->VorlagestudiengangModel->getCurrent($vorlage->vorlage_kurzbz, $oe_kurzbz, $version); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->ci->documentExportPhrases->t("document_export", "error_template_missing")); + $vorlage_stg = current(getData($result)); + foreach ($vorlage_stg as $k => $v) + $vorlage->$k = $v; + + $result = $this->create($temp_folder, $outputformat, $vorlage, $xml_data, $images); + if (isError($result)) + return $result; + + $temp_filename = getData($result); + + if ($sign_user) { + $this->addSignToData($xml_data); + + $result = $this->sign($temp_folder, $temp_filename, $outputformat, $sign_user, $sign_profile); + if (isError($result)) + return $result; + + $temp_filename = getData($result); + } + + return success($temp_filename); + } + + /** + * Helper function for createAndSignContent. + * Creates the files in the temp folder. + * + * @param string $temp_folder + * @param string $outputformat + * @param stdClass $vorlage + * @param DomDocument $xml_data + * @param array $images Each element should have a property path, name and contenttype which are all strings + * + * @return stdClass + */ + protected function create($temp_folder, $outputformat, $vorlage, $xml_data, $images) + { + $content_xsl = new DOMDocument(); + if (!$content_xsl->loadXML($vorlage->text)) + return error($this->ci->documentExportPhrases->t("document_export", "error_xsl_load")); + + $proc = new XSLTProcessor(); + $proc->importStyleSheet($content_xsl); + + $contentbuffer = $proc->transformToXml($xml_data); + + file_put_contents($temp_folder . '/content.xml', $contentbuffer); + + if ($xml_data->firstChild->tagName == 'error') + return error($xml_data->firstChild->textContent); + + // styles.xml erstellen + if ($vorlage->style) { + $styles_xsl = new DOMDocument(); + if (!$styles_xsl->loadXML($vorlage->style)) + return error($this->ci->documentExportPhrases->t("document_export", "error_styles_load")); + $style_proc = new XSLTProcessor(); + $style_proc->importStyleSheet($styles_xsl); + + $stylesbuffer = $style_proc->transformToXml($xml_data); + + file_put_contents($temp_folder . '/styles.xml', $stylesbuffer); + } + + // Template holen + $vorlage_found = false; + $vorlage_filename = $vorlage->vorlage_kurzbz . ($vorlage->mimetype == 'application/vnd.oasis.opendocument.spreadsheet' ? '.ods' : '.odt'); + + $aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS))); + foreach($aktive_addons as $addon) { + $zipfile = DOC_ROOT . 'addons/' . $addon . '/system/vorlage_zip/' . $vorlage_filename; + + if (file_exists($zipfile)) { + $vorlage_found = true; + break; + } + } + if (!$vorlage_found) + $zipfile = DOC_ROOT . 'system/vorlage_zip/' . $vorlage_filename; + + $tempname_zip = $temp_folder . '/out.zip'; + + if (!copy($zipfile, $tempname_zip)) + return error($this->ci->documentExportPhrases->t("document_export", "error_file_copy")); + + exec("zip $tempname_zip content.xml"); + if (!is_null($styles_xsl)) + exec("zip $tempname_zip styles.xml"); + + // bilder hinzufuegen + if (count($images) > 0) + { + // Unterordner fuer die Bilder erstellen + mkdir('Pictures'); + + // Manifest Datei holen + exec('unzip ' . $tempname_zip . ' META-INF/manifest.xml'); + + // Bild zur Manifest Datei hinzufuegen + $manifest = file_get_contents('META-INF/manifest.xml'); + + $manifest_xml = new DOMDocument; + if (!$manifest_xml->loadXML($manifest)) + return error($this->ci->documentExportPhrases->t("document_export", "error_manifest")); + + //root-node holen + $root = $manifest_xml->getElementsByTagName('manifest')->item(0); + + foreach ($images as $bild) { + copy($bild['path'], 'Pictures/' . $bild['name']); + + //Neues Element unterhalb des Root Nodes anlegen + $node = $manifest_xml->createElement("manifest:file-entry"); + $node->setAttribute("manifest:full-path", 'Pictures/' . $bild['name']); + $node->setAttribute("manifest:media-type", $bild['contenttype']); + $root->appendChild($node); + } + + $out = $manifest_xml->saveXML(); + + //geaenderte Manifest Datei speichern und wieder ins Zip packen + file_put_contents('META-INF/manifest.xml', $out); + exec('zip ' . $tempname_zip . ' META-INF/*'); + + // Bilder zum ZIP-File hinzufuegen + exec('zip ' . $tempname_zip . ' Pictures/*'); + } + + clearstatcache(); + + switch ($outputformat) { + case 'pdf': + case 'doc': + $ret = 0; + $temp_filename = $temp_folder . '/out.' . $outputformat; + + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) { + // Use docsbox + + $this->ci->load->library("DocsboxLib"); + + $docboxlib = get_class($this->ci->docboxlib); + + $ret = $docboxlib::convert($tempname_zip, $temp_filename, $outputformat); + } else { + // Use unoconv + + // Unoconv Version 0.6 hat eine Bug wodurch die Berechtigungen des PDF/Doc nicht korrekt gesetzt + // werden. Deshalb wird dies hier speziell behandelt. + // Die 2. Variante hat den Vorteil dass hier eine bessere Fehlerbehandlung moeglich ist + if ($this->unoconv_version == '0.6') + $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $outputformat . ' %2$s > %1$s'; + else + $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $outputformat . ' --output %s %s 2>&1'; + + $command = sprintf($command, $temp_filename, $tempname_zip); + + exec($command, $out, $ret); + } + + if ($ret) + return error($this->ci->documentExportPhrases->t("document_export", "error_conv_timeout")); + break; + case 'odt': + default: + $temp_filename = $tempname_zip; + } + + return success($temp_filename); + } + + /** + * Helper function for createAndSignContent. + * Signs the main file in the temp folder. + * + * @param string $temp_folder + * @param string $temp_filename + * @param string $outputformat + * @param string $user Must be a valid uid + * @param string $profile Signatureprofile for signing + * + * @return stdClass + */ + protected function sign($temp_folder, $temp_filename, $outputformat, $user, $profile) + { + if ($outputformat != 'pdf') + return error($this->ci->documentExportPhrases->t("document_export", "error_sign_pdf")); + + // Load the File + $file_data = file_get_contents($temp_filename); + + $data = new stdClass(); + $data->document = base64_encode($file_data); + + // Signatur Profil + if (!is_null($profile)) + $data->profile = $profile; + else + $data->profile = SIGNATUR_DEFAULT_PROFILE; + + // Username des Endusers der die Signatur angefordert hat + $data->user = $user; + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, SIGNATUR_URL . '/' . SIGNATUR_SIGN_API); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); + curl_setopt($ch, CURLOPT_USERAGENT, "FH-Complete"); + + // SSL Zertifikatsprüfung deaktivieren + // Besser ist es das Zertifikat am Server zu installieren! + //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); + //curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $data_string = json_encode($data, JSON_FORCE_OBJECT); + + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); + curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, [ + 'Content-Type: application/json', + 'Content-Length:' . mb_strlen($data_string), + 'Authorization: Basic ' . base64_encode(SIGNATUR_USER . ":" . SIGNATUR_PASSWORD) + ]); + + $result = curl_exec($ch); + if (curl_errno($ch)) { + curl_close($ch); + return error($this->ci->documentExportPhrases->t("document_export", "error_sign_timeout")); + } + curl_close($ch); + $resultdata = json_decode($result); + + // If it is success + if (isset($resultdata->error) && $resultdata->error == 0) { + $signed_filename = $temp_folder . '/signed.pdf'; + file_put_contents($signed_filename, base64_decode($resultdata->retval)); + return success($signed_filename); + } + + // otherwise if it is an error + return error($resultdata->retval ?? $this->ci->documentExportPhrases->t("global", "unknown_error", ["error" => $result])); + } + + /** + * Deletes all files in the $temp_folder and changes back to the source_folder + * + * @param string $temp_folder + * @param string $source_folder + * + * @return void + */ + protected function close($temp_folder, $source_folder) + { + $files = glob($temp_folder . '/*'); // get all file names + foreach ($files as $file) + if (is_file($file)) + unlink($file); + + chdir($source_folder); + rmdir($temp_folder); + } + + /** + * Convert an array to XML + * + * @param array $data + * @param string $root + * @param SimpleXMLElement $xml_data + * + * @return string|boolean + */ + private function convertArrayToXML($data, $root = null, $xml_data = null) + { + $_xml_data = $xml_data; + if ($_xml_data === null) + $_xml_data = new SimpleXMLElement($root !== null ? '<' . $root . ' />' : ''); + + foreach ($data as $key => $value) { + if (is_array($value)) { + if (is_numeric($key)) { + $key = 'item' . $key; // dealing with <0/>.. issues + $this->convertArrayToXML($value, null, $_xml_data); + } else { + $subnode = $_xml_data->addChild($key); + $this->convertArrayToXML($value, null, $subnode); + } + } else { + // Remove UTF8 Control Characters (breaking XML) + $value = preg_replace('/[\x00-\x1F\x7F]/u', '', $value); + $_xml_data->addChild((string)$key, htmlspecialchars("$value")); + } + } + + return $_xml_data->asXML(); + } + + /** + * Get default outputformat from mimetype if its not set + * + * @param string $outputformat + * @param string $mimetype + * + * @return string + */ + private function getDefaultOutputFormat($outputformat, $mimetype) + { + if ($outputformat) + return $outputformat; + + if ($mimetype == 'application/vnd.oasis.opendocument.spreadsheet') + return 'ods'; + if ($mimetype == 'application/vnd.oasis.opendocument.text') + return 'odt'; + + return 'pdf'; + } +} diff --git a/application/libraries/FilterCmptLib.php b/application/libraries/FilterCmptLib.php index 8b13ae3e5..272899de6 100644 --- a/application/libraries/FilterCmptLib.php +++ b/application/libraries/FilterCmptLib.php @@ -371,21 +371,21 @@ class FilterCmptLib foreach ($filterFields as $filterField) { // If not an empty array - if ($filterField != null) + if (!isEmptyArray($filterField)) { // - if (isset($filterField->name) && isset($filterField->operation) && isset($filterField->condition) - && !isEmptyString($filterField->name) && !isEmptyString($filterField->operation) - && !isEmptyString($filterField->condition)) + if (isset($filterField['name']) && isset($filterField['operation']) && isset($filterField['condition']) + && !isEmptyString($filterField['name']) && !isEmptyString($filterField['operation']) + && !isEmptyString((string)$filterField['condition'])) { // Fine $filter = new stdClass(); - $filter->name = $filterField->name; - $filter->operation = $filterField->operation; - $filter->condition = $filterField->condition; - if (isset($filterField->option) && !isEmptyString($filterField->option)) + $filter->name = $filterField['name']; + $filter->operation = $filterField['operation']; + $filter->condition = $filterField['condition']; + if (isset($filterField['option']) && !isEmptyString($filterField['option'])) { - $filter->option = $filterField->option; + $filter->option = $filterField['option']; } else { @@ -565,6 +565,7 @@ class FilterCmptLib getAuthPersonId() ); + // If filters were loaded if (hasData($filters)) { @@ -1173,4 +1174,3 @@ class FilterCmptLib return $filterName; } } - diff --git a/application/libraries/PermissionLib.php b/application/libraries/PermissionLib.php index 857defbf7..42502f999 100644 --- a/application/libraries/PermissionLib.php +++ b/application/libraries/PermissionLib.php @@ -95,6 +95,33 @@ class PermissionLib return $isBerechtigt; } + /** + * Prueft ob die Berechtigung zumindest fuer eine der angegebenen OE vorhanden ist. + * @param $berechtigung_kurzbz + * @param $oe_kurzbz + * @param $art + * @param $kostenstelle_id + * @return boolean + */ + public function isBerechtigtMultipleOe($berechtigung_kurzbz, $oe_kurzbz, $art=null, $kostenstelle_id=null) + { + $results = array(); + + foreach($oe_kurzbz as $value) + { + $results[] = $this->isBerechtigt($berechtigung_kurzbz, $art, $value, $kostenstelle_id); + } + + if(!in_array(true, $results)) + { + return false; + } + else + { + return true; + } + } + /** * Checks if the caller is allowed to access to this content with the given permissions * - if it's called from command line than it's trusted diff --git a/application/libraries/PhrasesLib.php b/application/libraries/PhrasesLib.php index dec3d54c0..ecd8094d6 100644 --- a/application/libraries/PhrasesLib.php +++ b/application/libraries/PhrasesLib.php @@ -200,6 +200,17 @@ class PhrasesLib return '<< PHRASE '.$phrase.' >>'; } + /** + * Workaround to reload the phrases array on an already constructed library. + * @parameters -> look for _setPhrases docs + */ + public function setPhrases($categories, $language) + { + if (count($categories) > 0) $this->_setPhrases($categories, $language); + + return $this->_phrases; + } + // ----------------------------------------------------------------------------------------------------------------- // Private methods @@ -319,6 +330,7 @@ class PhrasesLib { $this->_phrases = $phrases->retval; } + } /** @@ -329,4 +341,4 @@ class PhrasesLib { return json_encode($this->_phrases); } -} +} \ No newline at end of file diff --git a/application/libraries/TableWidgetLib.php b/application/libraries/TableWidgetLib.php index 3af99cca7..feda0d67c 100644 --- a/application/libraries/TableWidgetLib.php +++ b/application/libraries/TableWidgetLib.php @@ -26,6 +26,8 @@ class TableWidgetLib { const TABLE_UNIQUE_ID = 'tableUniqueId'; // TableWidget unique id + const TABLE_BOOTSTRAP_VERSION = 'bootstrapVersion'; // TableWidget bootstrap version + // TableWidget session name const SESSION_NAME = 'FHC_TABLE_WIDGET'; diff --git a/application/libraries/dashboard/DashboardLib.php b/application/libraries/dashboard/DashboardLib.php new file mode 100644 index 000000000..edea7c310 --- /dev/null +++ b/application/libraries/dashboard/DashboardLib.php @@ -0,0 +1,232 @@ +_ci =& get_instance(); + + $this->_ci->load->model('dashboard/Dashboard_model', 'DashboardModel'); + $this->_ci->load->model('dashboard/Dashboard_Preset_model', 'DashboardPresetModel'); + $this->_ci->load->model('dashboard/Dashboard_Override_model', 'DashboardOverrideModel'); + } + + public function generateWidgetId($dashboard_kurzbz = '') + { + $dashboard_kurzbz = (!empty($dashboard_kurzbz)) ? $dashboard_kurzbz : self::DEFAULT_DASHBOARD_KURZBZ; + $widgetid_input = time() . '_' . $dashboard_kurzbz . '_' . bin2hex(random_bytes(self::WIDGET_ID_RANDOM_BYTES)); + $widgetid = md5($widgetid_input); + return $widgetid; + } + + public function getDashboardByKurzbz($dashboard_kurzbz) + { + $result = $this->_ci->DashboardModel->getDashboardByKurzbz($dashboard_kurzbz); + + if (hasData($result)) + { + return current(getData($result)); + } + + return null; + } + + public function getMergedConfig($dashboard_id, $uid) + { + $defaultconfig = $this->getDefaultConfig($dashboard_id, $uid); + $userconfig = $this->getUserConfig($dashboard_id, $uid); + + $mergedconfig = array_replace_recursive($defaultconfig, $userconfig); + + return $mergedconfig; + } + + public function getDefaultConfig($dashboard_id, $uid) + { + $res_presets = $this->_ci->DashboardPresetModel->getPresets($dashboard_id, $uid); + $defaultconfig = array(); + + if (hasData($res_presets)) + { + $presets = getData($res_presets); + foreach ($presets as $presetobj) + { + $preset = json_decode($presetobj->preset, true); + if (null !== $preset) + { + $defaultconfig = array_replace_recursive($defaultconfig, $preset); + } + } + } + + return $defaultconfig; + } + + public function getUserConfig($dashboard_id, $uid) + { + $res_userconfig = $this->_ci->DashboardOverrideModel->getOverride($dashboard_id, $uid); + + if (hasData($res_userconfig)) + { + $data = getData($res_userconfig); + $decodedconfig = json_decode(current($data)->override, true); + if (null !== $decodedconfig) + { + return $decodedconfig; + } + } + + return []; + } + + public function getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid) + { + $override = $this->getOverride($dashboard_kurzbz, $uid); + if (null !== $override) { + return $override; + } + + $dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz); + + $emptyoverride = new stdClass(); + $emptyoverride->dashboard_id = $dashboard->dashboard_id; + $emptyoverride->uid = $uid; + $emptyoverride->override = '{"widgets": {"' . self::USEROVERRIDE_SECTION . '": {}}}'; + + return $emptyoverride; + } + + public function getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz) + { + if ($funktion_kurzbz === self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL) + $funktion_kurzbz = null; + $preset = $this->getPreset($dashboard_kurzbz, $funktion_kurzbz); + if (null !== $preset) { + return $preset; + } + + $dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz); + + $emptypreset = new stdClass(); + $emptypreset->dashboard_id = $dashboard->dashboard_id; + $emptypreset->funktion_kurzbz = $funktion_kurzbz; + $section = ($funktion_kurzbz !== null) ? $funktion_kurzbz : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL; + $emptypreset->preset = '{"widgets": {"' . $section . '": {}}}'; + + return $emptypreset; + } + + public function getPreset($dashboard_kurzbz, $section) + { + $dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz); + + $funktion_kurzbz = ($section === self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL) ? null : $section; + $result = $this->_ci->DashboardPresetModel + ->getPresetByDashboardAndFunktion($dashboard->dashboard_id, $funktion_kurzbz); + + if (hasData($result)) + { + return current(getData($result)); + } + + return null; + } + + public function getOverride($dashboard_kurzbz, $uid) + { + $dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz); + + $result = $this->_ci->DashboardOverrideModel + ->getOverride($dashboard->dashboard_id, $uid); + + if (hasData($result)) + { + return current(getData($result)); + } + + return null; + } + + public function insertOrUpdatePreset($preset) + { + if (isset($preset->preset_id) && $preset->preset_id > 0) + { + $result = $this->_ci->DashboardPresetModel->update($preset->preset_id, $preset); + } + else + { + $result = $this->_ci->DashboardPresetModel->insert($preset); + } + + return $result; + } + + public function insertOrUpdateOverride($override) + { + if (isset($override->override_id) && $override->override_id > 0) + { + $result = $this->_ci->DashboardOverrideModel->update($override->override_id, $override); + } + else + { + $result = $this->_ci->DashboardOverrideModel->insert($override); + } + + return $result; + } + + public function addWidgetsToWidgets(&$widgets, $dashboard_kurzbz, $section, $addwigets) + { + foreach ($addwigets as $widget) + { + if(!isset($widget->widgetid)) + { + $widget->widgetid = $this->generateWidgetId($dashboard_kurzbz); + } + $this->addWidgetToWidgets($widgets, $section, $widget, $widget->widgetid); + } + } + + public function addWidgetToWidgets(&$widgets, $section, $widget, $widgetid) + { + $section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL; + if (!isset($widgets[$section]) || !is_array($widgets[$section])) + { + $widgets[$section] = array(); + } + + $widgets[$section][$widgetid] = $widget; + } + + public function removeWidgetFromWidgets(&$widgets, $section, $widgetid) + { + $section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL; + if (isset($widgets[$section]) && isset($widgets[$section][$widgetid])) + { + unset($widgets[$section][$widgetid]); + if(empty($widgets[$section]) && $section !== self::USEROVERRIDE_SECTION) { + unset($widgets[$section]); + } + return true; + } + else { + return false; + } + } +} diff --git a/application/libraries/issues/PlausicheckResolverLib.php b/application/libraries/issues/PlausicheckResolverLib.php index 26da985f6..2b20a7d93 100644 --- a/application/libraries/issues/PlausicheckResolverLib.php +++ b/application/libraries/issues/PlausicheckResolverLib.php @@ -13,7 +13,7 @@ class PlausicheckResolverLib private $_ci; // ci instance private $_extensionName; // name of extension private $_codeLibMappings = []; // mappings for issues which explicitly defined resolver - private $_codeProducerLibMappings = []; // mappings for issues which are resolved as produced + private $_codeProducerLibMappings = []; // mappings for issues which are resolved with the same check as they are produced public function __construct($params = null) { @@ -99,10 +99,11 @@ class PlausicheckResolverLib $issueResolved = getData($issueResolvedRes) === true; } } - elseif (isset($this->_codeProducerLibMappings[$issue->fehlercode])) + elseif (isset($this->_codeProducerLibMappings[$issue->fehlercode])) // check if it is an issue without explicit resolver, "self-resolving" { $libName = $this->_codeProducerLibMappings[$issue->fehlercode]; + // execute same check as used for issue production $issueResolvedRes = $this->_ci->plausicheckproducerlib->producePlausicheckIssue( $libName, $issue->fehler_kurzbz, diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0005.php b/application/libraries/issues/resolvers/CORE_PERSON_0005.php new file mode 100644 index 000000000..1d768e70c --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_PERSON_0005.php @@ -0,0 +1,36 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->model('person/Person_model', 'PersonModel'); + + // load geburtsnation for the given person + $this->_ci->PersonModel->addSelect('geburtsnation'); + $personRes = $this->_ci->PersonModel->load($params['issue_person_id']); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + // get person data + $personData = getData($personRes)[0]; + + // if geburtsnation present, issue is resolved + return success(!isEmptyString($personData->geburtsnation)); + } + else + return success(false); // if no person found, not resolved + } +} \ No newline at end of file diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0006.php b/application/libraries/issues/resolvers/CORE_PERSON_0006.php new file mode 100644 index 000000000..8b7ff9c56 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_PERSON_0006.php @@ -0,0 +1,37 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->model('codex/Uhstat1daten_model', 'UhstatModel'); + + $personRes = $this->_ci->UhstatModel->getUHSTAT1PersonData([$params['issue_person_id']]); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + // get person data + $personData = getData($personRes)[0]; + + // if person identification data present, issue is resolved + return success( + !isEmptyString($personData->ersatzkennzeichen) + || (!isEmptyString($personData->vbpkAs) && !isEmptyString($personData->vbpkBf)) + ); + } + else + return success(false); // if no person found, not resolved + } +} \ No newline at end of file diff --git a/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php b/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php index b75bdd722..1aaafa471 100644 --- a/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php +++ b/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php @@ -28,9 +28,17 @@ class GehaltsbestandteilLib $this->GehaltsbestandteilModel = $this->CI->GehaltsbestandteilModel; } - public function fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + public function fetchGehaltsbestandteileValorisiertForChart($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) { - return $this->GehaltsbestandteilModel->getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); + return $this->GehaltsbestandteilModel->getGehaltsbestandteileValorisiertForChart($dienstverhaeltnis_id, $stichtag, $includefuture); + } + + public function fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, + $includefuture=false, $withvalorisationhistory=true) + { + return $this->GehaltsbestandteilModel->getGehaltsbestandteile( + $dienstverhaeltnis_id, $stichtag, $includefuture, $withvalorisationhistory + ); } public function fetchGehaltsbestandteil($gehaltsbestandteil_id) diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php b/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php index b58c514e1..2e6182957 100644 --- a/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php @@ -26,6 +26,8 @@ class VertragsbestandteilLib { const INCLUDE_FUTURE = true; const DO_NOT_INCLUDE_FUTURE = false; + const WITH_VALORISATION_HISTORY = true; + const NOT_WITH_VALORISATION_HISTORY = false; protected $CI; /** @var Dienstverhaeltnis_model */ @@ -90,10 +92,15 @@ class VertragsbestandteilLib return $dv; } - public function fetchVertragsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + public function fetchVertragsbestandteile($dienstverhaeltnis_id, $stichtag=null, + $includefuture=false, $withvalorisationhistory=true) { - $vbs = $this->VertragsbestandteilModel->getVertragsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); - $gbs = $this->GehaltsbestandteilLib->fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); + $vbs = $this->VertragsbestandteilModel->getVertragsbestandteile( + $dienstverhaeltnis_id, $stichtag, $includefuture + ); + $gbs = $this->GehaltsbestandteilLib->fetchGehaltsbestandteile( + $dienstverhaeltnis_id, $stichtag, $includefuture, $withvalorisationhistory + ); $gbsByVBid = array(); foreach( $gbs as $gb ) diff --git a/application/models/accounting/Vertrag_model.php b/application/models/accounting/Vertrag_model.php index 8725cd98d..abc2114a6 100644 --- a/application/models/accounting/Vertrag_model.php +++ b/application/models/accounting/Vertrag_model.php @@ -299,6 +299,91 @@ class Vertrag_model extends DB_Model } } + /** + * Prueft ob ein Mitarbeiter einen erteilten Vertrag zu einer Lehrveranstaltung besitzt. + * @param $lehrveranstaltung_id ID der Lehrveranstaltung + * @param $studiensemester_kurzbz Studiensemester das geprueft wird + * @param $mitarbeiter_uid UID des Mitarbeiters + */ + public function isVertragErteiltLV($lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid) + { + if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON') + && CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '') + { + // Liegt das Studiensemester vor dem Pruefdatum, wird die LV immer als Erteilt angezeigt + $stsemquery = " + SELECT + tbl_studiensemester.start + FROM + public.tbl_studiensemester + WHERE + studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz)." + AND tbl_studiensemester.start < ( + SELECT + start + FROM + public.tbl_studiensemester stsem + WHERE + stsem.studiensemester_kurzbz = " . $this->escape(CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON)." + )"; + + if ($stsemresult = $this->execReadOnlyQuery($stsemquery)) + { + $stsemdata = getData($stsemresult); + if ($stsemdata && count($stsemdata) > 0) + { + // Wenn das Studiensemester vor dem Pruefdatum liegt, gilt der Vertrag immer als erteilt. + return true; + } + } + else + { + return false; + } + } + + $query = " + SELECT + 1 + FROM + lehre.tbl_lehreinheitmitarbeiter + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + JOIN lehre.tbl_vertrag USING(vertrag_id) + JOIN lehre.tbl_vertrag_vertragsstatus USING(vertrag_id) + WHERE + tbl_lehreinheitmitarbeiter.mitarbeiter_uid = " . $this->escape($mitarbeiter_uid) . " + AND tbl_lehreinheit.studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + AND tbl_lehreinheit.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id)) . " + AND tbl_vertrag_vertragsstatus.vertragsstatus_kurzbz='erteilt' + AND NOT EXISTS( + SELECT + 1 + FROM + lehre.tbl_vertrag_vertragsstatus vstatus + WHERE + vstatus.vertrag_id = tbl_vertrag.vertrag_id + AND vstatus.vertragsstatus_kurzbz = 'storno' + ) + "; + + if ($result = $this->execReadOnlyQuery($query)) + { + $data = getData($result); + if ($data && count($data) > 0) + { + return true; + } + else + { + return false; + } + } + else + { + return false; + } + } + // ----------------------------------------------------------------------------------------------------------------- // Private methods diff --git a/application/models/codex/Bisio_model.php b/application/models/codex/Bisio_model.php index 1cff1dc54..5ecd4bb51 100644 --- a/application/models/codex/Bisio_model.php +++ b/application/models/codex/Bisio_model.php @@ -44,4 +44,27 @@ class Bisio_model extends DB_Model else return success("Bisio not found"); } + + /** + * checks, if an (extension) table exists to avoid later errors + * @param String $schema like 'extension' + * @param String $table like 'tbl_mo_bisiozuordnung' + * @return boolean + */ + public function tableExists($schema, $table) + { + $params = array($schema, $table); + + $qry = "SELECT + 1 + FROM + information_schema.role_table_grants + WHERE + table_schema = ? + AND table_name = ?"; + + $result = $this->execQuery($qry, $params); + + return $result; + } } diff --git a/application/models/codex/Bisstandort_model.php b/application/models/codex/Bisstandort_model.php new file mode 100644 index 000000000..9c7e9e45b --- /dev/null +++ b/application/models/codex/Bisstandort_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_bisstandort'; + $this->pk = 'standort_code'; + } +} diff --git a/application/models/codex/Gemeinde_model.php b/application/models/codex/Gemeinde_model.php index 670da739d..069037cee 100644 --- a/application/models/codex/Gemeinde_model.php +++ b/application/models/codex/Gemeinde_model.php @@ -20,6 +20,31 @@ class Gemeinde_model extends DB_Model return $this->loadWhere(array("plz" => $plz)); } + public function getGemeindeByNation($nation, $zip) + { + $this->addSelect(["name"]); + + if ($nation == "A") + { + if (isset($zip) && $zip > 999 && $zip < 32000) + { + $gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]); + if (isError($gemeinde_res)) + { + show_error("error while trying to query bis.tbl_gemeinde"); + } + $gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null; + $gemeinde_res = array_map(function ($obj) { + return $obj->name; + }, $gemeinde_res); + echo json_encode($gemeinde_res); + + } else { + echo json_encode(error("ortschaftskennziffer code was not valid")); + } + } + } + public function checkLocation($plz, $gemeinde, $ort) { $this->db->where('ortschaftsname', $ort); @@ -28,4 +53,4 @@ class Gemeinde_model extends DB_Model return (boolean)$this->db->count_all_results($this->dbTable); } -} \ No newline at end of file +} diff --git a/application/models/codex/Uhstat1daten_model.php b/application/models/codex/Uhstat1daten_model.php index 9bca44b58..899f037ef 100644 --- a/application/models/codex/Uhstat1daten_model.php +++ b/application/models/codex/Uhstat1daten_model.php @@ -11,4 +11,44 @@ class Uhstat1daten_model extends DB_Model $this->dbTable = 'bis.tbl_uhstat1daten'; $this->pk = 'uhstat1daten_id'; } + + /** + * Gets person data needed for sending as UHSTAT1 data. + * @param array $person_id_arr + * @param string $studiensemester + * @param array $status_kurzbz + * @return object success with prestudents or error + */ + public function getUHSTAT1PersonData($person_id_arr) + { + if (!isset($person_id_arr) || isEmptyArray($person_id_arr)) return success([]); + + $params = array($person_id_arr); + + $prstQry = "SELECT + DISTINCT ON (pers.person_id) + pers.person_id, uhstat_daten.uhstat1daten_id, pers.svnr, pers.ersatzkennzeichen, pers.geburtsnation, + uhstat_daten.mutter_geburtsstaat, uhstat_daten.mutter_bildungsstaat, uhstat_daten.mutter_geburtsjahr, + uhstat_daten.mutter_bildungmax, uhstat_daten.vater_geburtsstaat, uhstat_daten.vater_bildungsstaat, + uhstat_daten.vater_geburtsjahr, uhstat_daten.vater_bildungmax, + kzVbpkAs.inhalt AS \"vbpkAs\", kzVbpkBf.inhalt AS \"vbpkBf\" + FROM + public.tbl_person pers + JOIN public.tbl_prestudent ps USING (person_id) + JOIN public.tbl_studiengang stg USING (studiengang_kz) + JOIN bis.tbl_uhstat1daten uhstat_daten USING (person_id) + LEFT JOIN public.tbl_kennzeichen kzVbpkAs ON kzVbpkAs.kennzeichentyp_kurzbz = 'vbpkAs'AND kzVbpkAs.person_id = pers.person_id AND kzVbpkAs.aktiv + LEFT JOIN public.tbl_kennzeichen kzVbpkBf ON kzVbpkBf.kennzeichentyp_kurzbz = 'vbpkBf'AND kzVbpkBf.person_id = pers.person_id AND kzVbpkBf.aktiv + WHERE + ps.bismelden + AND stg.melderelevant + AND pers.person_id IN ? + ORDER BY + pers.person_id"; + + return $this->execReadOnlyQuery( + $prstQry, + $params + ); + } } diff --git a/application/models/content/Ampel_Benutzer_Bestaetigt_model.php b/application/models/content/Ampel_Benutzer_Bestaetigt_model.php new file mode 100644 index 000000000..72373c2d8 --- /dev/null +++ b/application/models/content/Ampel_Benutzer_Bestaetigt_model.php @@ -0,0 +1,14 @@ +dbTable = 'public.tbl_ampel_benutzer_bestaetigt'; + $this->pk = 'ampel_benutzer_bestaetigt_id'; + } + +} diff --git a/application/models/content/Ampel_model.php b/application/models/content/Ampel_model.php index c50025a12..1f6cf9f93 100644 --- a/application/models/content/Ampel_model.php +++ b/application/models/content/Ampel_model.php @@ -16,37 +16,95 @@ class Ampel_model extends DB_Model * 1. not after the deadline date * 2. not before the vorlaufszeit * @param bool $email If true, then only ampeln are retrieved that are marked to be sent by mail. - * @return array Returns array of objects. + * @return stdClass Returns array of objects. */ - public function active($email = false) + public function active($email = false, $uid = null) { - $parametersArray = null; - $query = ' - SELECT * - FROM public.tbl_ampel - WHERE'; - - if ($email === true) - { - $parametersArray['email'] = $email; - $query .= ' email = ? AND'; + $userLanguage = getUserLanguage(); + $selectStatement='*,beschreibung[('.$this->getLanguageIndex($this->escape($userLanguage)).')] as beschreibung_trans, buttontext[('.$this->getLanguageIndex($this->escape($userLanguage)).')] as buttontext_trans'; + + if($uid != null ){ + $selectStatement .= ', + COALESCE(( + SELECT true + FROM public.tbl_ampel_benutzer_bestaetigt a + WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id + AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) as bestaetigt'; } - $query .= '( - (NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date) - OR (verfallszeit IS NULL) - AND (NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date) - OR (vorlaufzeit IS NULL AND NOW() < deadline))'; + $this->addSelect($selectStatement); + $whereStatement=''; - $query .= ' ORDER BY deadline DESC'; + if ($email === true) { + $whereStatement .= ' email = '.$this->escape($email).' AND'; + } + + $whereStatement .= + '( + ( + (NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date) + OR (verfallszeit IS NULL) + ) + AND + ( + (NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date) + OR (vorlaufzeit IS NULL AND NOW() < deadline) + ) + )'; + + $this->addOrder('deadline', 'DESC'); + return $this->loadWhere($whereStatement); + + } + + public function openActive($uid, $email = false) + { + $userLanguage = getUserLanguage(); + $selectStatement = '*,beschreibung[(' . $this->getLanguageIndex($this->escape($userLanguage)) . ')] as beschreibung_trans, buttontext[(' . $this->getLanguageIndex($this->escape($userLanguage)) . ')] as buttontext_trans'; + + + $selectStatement .= ', + COALESCE(( + SELECT true + FROM public.tbl_ampel_benutzer_bestaetigt a + WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id + AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) as bestaetigt'; + + $this->addSelect($selectStatement); + $whereStatement = ''; + + if ($email === true) { + $whereStatement .= ' email = ' . $this->escape($email) . ' AND'; + } + + $whereStatement .= + ' + (COALESCE(( + SELECT true + FROM public.tbl_ampel_benutzer_bestaetigt a + WHERE a.ampel_id = ' . $this->dbTable . '.ampel_id + AND uid = ' . $this->escape($uid) . ' LIMIT 1), false) = FALSE) AND + ( + ( + (NOW()<(deadline+(COALESCE(verfallszeit,0) || \' days\')::interval)::date) + OR (verfallszeit IS NULL) + ) + AND + ( + (NOW()>(deadline-(COALESCE(vorlaufzeit,0) || \' days\')::interval)::date) + OR (vorlaufzeit IS NULL AND NOW() < deadline) + ) + )'; + + $this->addOrder('deadline', 'DESC'); + return $this->loadWhere($whereStatement); - return $this->execQuery($query, $parametersArray); } /** * Returns all Ampel-receiver of a specific Ampel. * @param string $benutzer_select SQL Statement which defines the Ampel-receiver. - * @return array Returns array of objects with property 'uid'. + * @return stdClass Returns array of objects with property 'uid'. */ public function execBenutzerSelect($benutzer_select) { @@ -90,4 +148,101 @@ class Ampel_model extends DB_Model else return $result; //will contain the error-msg from execQuery } + + /** + * checks if a user is assigned to an ampel + * @param string $uid userID + * @param string $benutzer_select the select query which gets all the user that are assigned to an ampel + * @return stdClass + */ + public function isZugeteilt($uid, $benutzer_select){ + $zugeteilt = $this->execReadOnlyQuery(" + SELECT + CASE WHEN ? IN (".$benutzer_select.") + THEN true + ELSE false + END as zugeteilt + ", [$uid]); + + if(isError($zugeteilt)){ + return $zugeteilt; + } + + $zugeteilt = getData($zugeteilt); + + return success(current($zugeteilt)->zugeteilt); + } + + // THIS FUNCTION IS NOT IN USE + // fetches all ampeln that were assigned to the user after the working start_date + function alleAmpeln($uid){ + $userLanguage = getUserLanguage(); + + $zugeteile_ampeln = []; + + $datum = new datum(); + $now = $datum->mktime_fromdate(date('Y-m-d')); + + // start date of user + $benutzerStartDate = $this->execReadOnlyQuery(" + SELECT insertamum FROM public.tbl_benutzer WHERE uid = ?", [$uid]); + $benutzerStartDate = $datum->mktime_fromdate(date(current(getData($benutzerStartDate))->insertamum)); + + $allAmpeln = $this->execReadOnlyQuery(" + SELECT *, beschreibung[(".$this->getLanguageIndex($this->escape($userLanguage)).")] as beschreibung_trans, buttontext[(".$this->getLanguageIndex($this->escape($userLanguage)).")] as buttontext_trans FROM + public.tbl_ampel"); + + if(isError($allAmpeln)) return error(getError($allAmpeln)); + + $allAmpeln = getData($allAmpeln); + foreach($allAmpeln as $ampel){ + + // check if the ampel is assigned to the user + $zugeteilt = $this->execReadOnlyQuery(" + SELECT + CASE WHEN ? IN (".$ampel->benutzer_select.") + THEN true + ELSE false + END as zugeteilt + ", [$uid]); + + if(isError($zugeteilt)) return error(getError($zugeteilt)); + + $zugeteilt = current(getData($zugeteilt))->zugeteilt; + + + // abgelaufen check + // $now > strtotime('+' . $ampel->verfallszeit . ' day', $ampel->deadline) + + if( + // aktuelles datum liegt vor der Vorlaufzeit der Ampel + (isset($ampel->vorlaufzeit) && $now < strtotime('-' . $ampel->vorlaufzeit . ' day', $datum->mktime_fromdate($ampel->deadline))) + || + // ampel ist vor Arbeitsstart abgelaufen + (isset($ampel->verfallszeit) && $benutzerStartDate > strtotime('+' . $ampel->verfallszeit . ' day', $datum->mktime_fromdate($ampel->deadline))) + || + // ampel ist vor Arbeitsstart abgelaufen (verfallszeit nicht vorhanden) + ($benutzerStartDate > strtotime('+' . $ampel->verfallszeit . ' day', $datum->mktime_fromdate($ampel->deadline))) + ){ + // continue iteration if ampel is expired before work start or shouldn't be visible yet + continue; + } + + $ampel->zugeteilt = $zugeteilt; + + if($zugeteilt) $zugeteile_ampeln[] = $ampel; + + } + + return success($zugeteile_ampeln); + } + + private function getLanguageIndex($userLanguage) + { + return " + SELECT index + FROM public.tbl_sprache + WHERE sprache = " . $userLanguage; + } + } diff --git a/application/models/content/Content_model.php b/application/models/content/Content_model.php index ee4315ebd..278022b59 100644 --- a/application/models/content/Content_model.php +++ b/application/models/content/Content_model.php @@ -11,4 +11,316 @@ class Content_model extends DB_Model $this->dbTable = 'campus.tbl_content'; $this->pk = 'content_id'; } + + /** + * Laedt den Content in der angegebenen Sprache + * Sollte der Content in dieser Sprache nicht vorhanden sein, wird der Content in der Default Sprache geladen + * + * @param integer $content_id + * @param string $sprache optional + * @param integer $version optional + * @param boolean | null $sichtbar optional + * + * @return stdClass + */ + public function getContent($content_id, $sprache = DEFAULT_LANGUAGE, $version = null, $sichtbar = null, $load_default_language = false) + { + $this->load->model('content/Contentsprache_model', 'ContentspracheModel'); + $spracheExists = $this->ContentspracheModel->exists($content_id, $sprache, $version, $sichtbar); + if (isError($spracheExists)) + return $spracheExists; + + if(!getData($spracheExists)) + { + if($load_default_language) + $sprache = DEFAULT_LANGUAGE; + else + return error('Der Content existiert in dieser Sprache nicht '); + } + + $condition = ['content_id' => $content_id, 'sprache' => $sprache]; + + if ($sichtbar === true || $sichtbar === false) + $condition['sichtbar'] = $sichtbar; + if ($version) + $condition['version'] = $version; + + $this->addSelect([ + '*', + 'tbl_contentsprache.insertamum', + 'tbl_contentsprache.insertvon', + 'tbl_contentsprache.updateamum', + 'tbl_contentsprache.updatevon' + ]); + $this->addJoin('campus.tbl_contentsprache', 'content_id'); + $this->addOrder('version', 'DESC'); + $this->addLimit(1); + + $result = $this->loadWhere($condition); + + if (isError($result)) + return $result; + if (!getData($result)) + return error('Dieser Eintrag wurde nicht gefunden'); + + return success(current(getData($result))); + } + + /** + * Sucht die content_id fuer den CIS4_Root Menu content + * + * @return integer|null content_id of the Cis4_Root Menu + */ + public function getMenuContentID(){ + // early return if the CIS4_MENU_ENTRY constant is defined + if(defined('CIS4_MENU_ENTRY')) + { + return CIS4_MENU_ENTRY; + } + + // load the CIS4 Menu content_id from the database using the column 'beschreibugn' of the campus.tbl_content table + $CIS4_ROOT_CONTENT = $this->loadWhere(["beschreibung"=>"CIS4_ROOT"]); + + if(isError($CIS4_ROOT_CONTENT)) + { + return null; + } + + $CIS4_ROOT_CONTENT = getData($CIS4_ROOT_CONTENT); + + if(count($CIS4_ROOT_CONTENT) > 0) + { + return current($CIS4_ROOT_CONTENT)->content_id ?? null; + } + else + { + return null; + } + } + + /** + * Laedt alle Content Eintraege unterhalb eines Contents + * (Ohne Newseintraege) + * + * @param integer $root_content_id + * @param string $uid + * @param string $sprache optional + * + * @return stdClass on success an array with menu objects + */ + public function getMenu($root_content_id, $uid, $sprache = DEFAULT_LANGUAGE) + { + + /*, + { + "content_id": 1000007, + "template_kurzbz": "redirect", + "titel": "Anrechnung", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + } + */ + + /* + { + "content_id": 1000003, + "template_kurzbz": "redirect", + "titel": "COVID-19", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + */ + + if ($root_content_id === null) { + $res = json_decode('{ + "content_id": 1000000, + "template_kurzbz": "contentmittitel", + "titel": "CIS4", + "content": "", + "menu_open": true, + "aktiv": true, + "childs": [ + { + "content_id": 1000001, + "template_kurzbz": "redirect", + "titel": "News", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + { + "content_id": 1000002, + "template_kurzbz": "redirect", + "titel": "Profil", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + { + "content_id": 1000004, + "template_kurzbz": "redirect", + "titel": "Meine LV", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + { + "content_id": 1000005, + "template_kurzbz": "redirect", + "titel": "Stundenplan", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + { + "content_id": 1000006, + "template_kurzbz": "redirect", + "titel": "Dokumente", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + }, + { + "content_id": 1000007, + "template_kurzbz": "redirect", + "titel": "Studierendenstatus", + "content": "", + "menu_open": false, + "aktiv": true, + "childs": [] + } + + ] + }'); + return success($res); + } + $sql = " + SELECT + c.content_id, + c.template_kurzbz, + s.titel, + s.content, + c.menu_open, + c.aktiv, + k.child_content_id, + k.sort FROM ( + SELECT + c.content_id, + s.contentsprache_id + FROM + campus.tbl_content c + JOIN ( + SELECT + s5.content_id, + s5.contentsprache_id + FROM ( + SELECT + content_id, + sprache, + MAX(version) AS version + FROM ( + SELECT + c1.content_id, + COALESCE(s1.sprache, ?) AS sprache + FROM + campus.tbl_content c1 + LEFT JOIN + campus.tbl_contentsprache s1 ON c1.content_id=s1.content_id AND s1.sprache=? + WHERE + sichtbar=true + ) s2 + LEFT JOIN + campus.tbl_contentsprache s3 USING(content_id, sprache) + WHERE + sichtbar=true + GROUP BY + content_id, + sprache + ) s4 + LEFT JOIN + campus.tbl_contentsprache s5 USING(content_id, sprache, version) + WHERE + version IS NOT NULL + ) t USING (content_id) + JOIN + campus.tbl_contentsprache s USING (contentsprache_id) + WHERE + c.template_kurzbz<>'news' + AND + c.content_id IN ( + WITH RECURSIVE childs(content_id, child_content_id) as + ( + SELECT content_id, child_content_id FROM campus.tbl_contentchild + WHERE content_id=? + UNION ALL + SELECT cc.child_content_id, null FROM campus.tbl_contentchild cc, childs + WHERE cc.content_id=childs.content_id + ) + SELECT content_id + FROM childs + GROUP BY content_id + ) + GROUP BY c.content_id, + s.contentsprache_id + ) m + JOIN + campus.tbl_content c USING(content_id) + JOIN + campus.tbl_contentsprache s USING(contentsprache_id) + LEFT JOIN + campus.tbl_contentchild k ON(m.content_id=k.content_id) + WHERE EXISTS ( + SELECT 1 + FROM campus.tbl_contentgruppe + JOIN public.vw_gruppen USING(gruppe_kurzbz) + WHERE ( + tbl_contentgruppe.content_id=c.content_id + OR NOT EXISTS ( + SELECT 1 + FROM campus.tbl_contentgruppe + WHERE content_id=c.content_id + ) + ) + AND vw_gruppen.uid=? + ) + ORDER BY content_id, sort"; + + $result = $this->execQuery($sql, [DEFAULT_LANGUAGE, $sprache, $root_content_id, $uid]); + + if (isError($result)) + return $result; + + $contents = getData($result) ?? []; + $result = []; + foreach ($contents as $content) { + if (!isset($result[$content->content_id])) { + $result[$content->content_id] = clone($content); + unset($result[$content->content_id]->child_content_id); + unset($result[$content->content_id]->sort); + $result[$content->content_id]->childs = []; + } + if ($content->child_content_id !== null) + $result[$content->content_id]->childs[] = $content->child_content_id; + } + foreach ($result as $content) { + foreach ($content->childs as $k => $v) { + if (isset($result[$v])) { + $content->childs[$k] = $result[$v]; + } else { + unset($content->childs[$k]); + } + } + } + + return success(isset($result[$root_content_id]) ? $result[$root_content_id] : null); + } } diff --git a/application/models/content/Contentgruppe_model.php b/application/models/content/Contentgruppe_model.php index 03efc87b1..23dc897a1 100644 --- a/application/models/content/Contentgruppe_model.php +++ b/application/models/content/Contentgruppe_model.php @@ -11,4 +11,50 @@ class Contentgruppe_model extends DB_Model $this->dbTable = 'campus.tbl_contentgruppe'; $this->pk = array('gruppe_kurzbz', 'content_id'); } + + /** + * Prueft ob der Zugriff auf den Content eingeschraenkt ist auf + * eine bestimmte Benutzergruppe + * + * @param int $content_id + * + * @return stdClass success(true) wenn eingeschraenkt sonst success(false) + */ + public function islocked($content_id) + { + $islocked = $this->loadWhere(['content_id' => $content_id]); + + if (isError($islocked)) + return $islocked; + return success(!!getData($islocked)); + } + + /** + * Prueft ob ein User die Berechtigung fuer das Anzeigen des + * Contents besitzt + * + * @param int $content_id ID des Contents + * @param string $uid User der versucht auf den Content zuzugreifen + * + * @return stdClass + */ + public function berechtigt($content_id, $uid) + { + $islocked = $this->islocked($content_id); + if (isError($islocked)) + return $islocked; + + $condition = ['uid' => $uid]; + if (getData($islocked)) { + $condition['content_id'] = $content_id; + } + $this->addJoin('public.vw_gruppen', 'gruppe_kurzbz'); + + $result = $this->loadWhere($condition); + + if (isError($result)) + return $result; + return success(!!getData($result)); + } + } diff --git a/application/models/content/Contentsprache_model.php b/application/models/content/Contentsprache_model.php index eb7e257b2..80b053e28 100644 --- a/application/models/content/Contentsprache_model.php +++ b/application/models/content/Contentsprache_model.php @@ -11,4 +11,32 @@ class Contentsprache_model extends DB_Model $this->dbTable = 'campus.tbl_contentsprache'; $this->pk = 'contentsprache_id'; } + + /** + * Prueft ob der Content in der angegeben Sprache vorhanden ist + * + * @param int $content_id + * @param string $sprache + * @param int | null $version (optional) + * @param boolean | null $sichtbar (optional) + * @return stdClass + */ + public function exists($content_id, $sprache, $version=null, $sichtbar=null) + { + $condition = ['content_id' => $content_id, 'sprache' => $sprache]; + + if ($version) + $condition['version'] = $version; + + if ($sichtbar !== null) + $condition['sichtbar'] = $sichtbar; + + $result = $this->loadWhere($condition); + + if (isError($result)) + return $result; + + return success(!!getData($result)); + } + } diff --git a/application/models/content/News_model.php b/application/models/content/News_model.php index 8d636d808..ad8ecab99 100644 --- a/application/models/content/News_model.php +++ b/application/models/content/News_model.php @@ -11,4 +11,124 @@ class News_model extends DB_Model $this->dbTable = 'campus.tbl_news'; $this->pk = 'news_id'; } + + /** + * Get all News ordered by date. (most actual on top) + * @param null $limit Amount of news. + * @return array + */ + public function getAll($limit = null) + { + $this->addJoin("campus.tbl_content","content_id"); + return $this->execReadOnlyQuery(' + SELECT *, TO_CHAR(campus.tbl_news.datum, ?) as datumformatted + FROM campus.tbl_news + JOIN campus.tbl_content content ON content.content_id = campus.tbl_news.content_id + WHERE + --text IS NOT NULL AND + datum <= NOW() AND (datum_bis IS NULL OR datum_bis >= now()::date) + ORDER BY datum DESC + LIMIT ' . $this->escape($limit) + , ['DD/MM/YYYY']); + } + + public function getNewsContentIDs($limit=10){ + $this->addSelect(['content_id']); + return $this->loadWhere("datum <= NOW() AND (datum_bis IS NULL OR datum_bis >= now()::date) + ORDER BY datum DESC + LIMIT " . $this->escape($limit)); + + } + + + + /** + * @param string $sprache + * @param string $studiengang_kz + * @param integer | null $semester + * @param string $fachbereich_kurzbz + * @param boolean $sichtbar + * @param integer $maxalter + * @param integer $page + * @param integer $page_size + * @param boolean $all + * @param boolean $mischen + * + * TODO(chris): this is not a good function -> the params are all over the place + * + */ + protected function prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true) + { + + $this->addOrder('datum', 'DESC'); + + $studiengang_kz = trim($studiengang_kz); + $fachbereich_kurzbz = trim($fachbereich_kurzbz); + + $where = []; + if (trim($maxalter) != '0') { + $where[] = "(now()-datum) < interval " . $this->db->escape($maxalter) . " days"; + + } + if (!$all) { + $where[] = "datum <= now()"; + $where[] = "(datum_bis >= now()::date OR datum_bis IS NULL)"; + } + if ($fachbereich_kurzbz != '*') { + if ($fachbereich_kurzbz == '') { + $where[] = "fachbereich_kurzbz IS NULL"; + } else { + $where[] = "fachbereich_kurzbz = " . $this->db->escape($fachbereich_kurzbz); + + } + } + if ($studiengang_kz == '0') { + $where[] = "studiengang_kz = " . $this->db->escape($studiengang_kz); + + if ($semester === NULL) + $where[] = "semester IS NULL"; + elseif ($semester === 0) + $where[] = "semester = 0"; + } elseif ($studiengang_kz != '') { + $add = $mischen === true ? " OR (studiengang_kz = 0 AND semester IS NULL)" : ""; + $where[] = "((studiengang_kz = " . $this->db->escape($studiengang_kz) . " AND semester = " . $this->db->escape($semester) . ") OR (studiengang_kz = " . $this->db->escape($studiengang_kz) . " AND semester = 0) OR (studiengang_kz = 0 AND semester = " . $this->db->escape($semester) . ")" . $add . ")"; + + } + $this->addJoin('campus.tbl_contentsprache cs', 'content_id'); + + $where[] = "cs.sichtbar = " . ($sichtbar ? "true" : "false"); + + $where[] = "cs.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=" . $this->db->escape($sprache) . ") THEN " . $this->db->escape($sprache) . " ELSE " . $this->db->escape(DEFAULT_LANGUAGE) . " END)"; + + + $where[] = "cs.version = (SELECT MAX(version) FROM campus.tbl_contentsprache cs3 WHERE cs3.content_id=" . $this->dbTable . ".content_id AND cs3.sprache = (CASE WHEN EXISTS(SELECT 1 FROM campus.tbl_contentsprache cs2 WHERE cs2.content_id=" . $this->dbTable . ".content_id AND sprache=" . $this->db->escape($sprache) . ") THEN " . $this->db->escape($sprache) . " ELSE " . $this->db->escape(DEFAULT_LANGUAGE) . " END))"; + + + $where = implode(" AND ", $where); + + $this->db->where($where, NULL, FALSE); + + } + + public function getNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true) + { + $this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + + // getting the number of rows of the query and adding pagination to the query result + $num_rows = $this->getNumRows(true); + $this->addPagination($page, $page_size, $num_rows); + + // preparing the query again because every call to get_compiled_select or cour_all_results will add the from clause to the query + $this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + + return $this->load(); + } + + public function countNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz = null, $sichtbar = true, $maxalter = 0, $page = 1, $page_size = 10, $all = false, $mischen = true) + { + $this->prepareNewsWithContent($sprache, $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen); + return $this->getNumRows(); + } + + } diff --git a/application/models/crm/Akte_model.php b/application/models/crm/Akte_model.php index 15a38022e..57b6e0665 100644 --- a/application/models/crm/Akte_model.php +++ b/application/models/crm/Akte_model.php @@ -193,4 +193,55 @@ class Akte_model extends DB_Model return success($dokumente->retval); } + + /** + * Liefert die Archivdokumente einer Person + * + * @param integer $person_id + * @param boolean|null $signiert Wenn true werden nur Dokumente geliefert die digital signiert wurden. + * @param boolean|null $stud_selfservice Wenn true werden nur Dokumente geliefert die Studierende selbst herunterladen duerfen. + * + * @return stdClass + */ + public function getArchiv($person_id, $signiert = null, $stud_selfservice = null) + { + $this->addSelect('akte_id'); + $this->addSelect('person_id'); + $this->addSelect('dokument_kurzbz'); + $this->addSelect('mimetype'); + $this->addSelect('erstelltam'); + $this->addSelect('gedruckt'); + $this->addSelect('titel_intern'); + $this->addSelect('anmerkung_intern'); + $this->addSelect('titel'); + $this->addSelect('bezeichnung'); + $this->addSelect('updateamum'); + $this->addSelect('insertamum'); + $this->addSelect('updatevon'); + $this->addSelect('insertvon'); + $this->addSelect('uid'); + $this->addSelect('dms_id'); + $this->addSelect('anmerkung'); + $this->addSelect('nachgereicht'); + $this->addSelect('CASE WHEN inhalt is not null THEN true ELSE false END as inhalt_vorhanden', false); + $this->addSelect('nachgereicht_am'); + $this->addSelect('ausstellungsnation'); + $this->addSelect('formal_geprueft_amum'); + $this->addSelect('archiv'); + $this->addSelect('signiert'); + $this->addSelect('stud_selfservice'); + $this->addSelect('akzeptiertamum'); + + if ($signiert !== null) + $this->db->where('signiert', (boolean)$signiert); + if ($stud_selfservice !== null) + $this->db->where('stud_selfservice', (boolean)$stud_selfservice); + + $this->addOrder('erstelltam', 'DESC'); + + return $this->loadWhere([ + 'person_id' => $person_id, + 'archiv' => true + ]); + } } diff --git a/application/models/crm/Konto_model.php b/application/models/crm/Konto_model.php index d130d5db8..51d3117bc 100644 --- a/application/models/crm/Konto_model.php +++ b/application/models/crm/Konto_model.php @@ -340,6 +340,34 @@ class Konto_model extends DB_Model } /** + * @param integer $prestudent_id + * @param string $stsem + * @param array $buchungstypen + * + * @return stdClass + */ + public function checkStudienbeitragFromPrestudent($prestudent_id, $stsem, $buchungstypen) + { + $this->addSelect($this->dbTable . '.buchungsnr'); + $this->addSelect($this->dbTable . '.buchungsdatum'); + + $this->addJoin('public.tbl_prestudent s', $this->dbTable . '.person_id=s.person_id AND ' . $this->dbTable . '.studiengang_kz=s.studiengang_kz'); + + $this->db->where_in('buchungstyp_kurzbz', $buchungstypen); + $this->db->where('0 >= ( + SELECT sum(betrag) + FROM ' . $this->dbTable . ' skonto + WHERE skonto.buchungsnr = ' . $this->dbTable . '.buchungsnr_verweis + OR skonto.buchungsnr_verweis = ' . $this->dbTable . '.buchungsnr_verweis + )', null, false); + + return $this->loadWhere([ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz' => $stsem + ]); + } + + /* * check if student has paid studienbeitrag for certain semester * * @param $person_id person_id diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index 242c26518..ff56c3268 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -677,7 +677,7 @@ class Prestudent_model extends DB_Model )); } - public function getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt) + public function getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt, $ignoreAbgeschickt = false) { $query = "SELECT ps.prestudent_id FROM public.tbl_prestudentstatus pss @@ -687,22 +687,42 @@ class Prestudent_model extends DB_Model JOIN lehre.tbl_studienordnung so USING(studienordnung_id) WHERE ps.person_id = ? AND UPPER(so.studiengangkurzbzlang || ':' || sp.orgform_kurzbz) = ? - AND pss.studiensemester_kurzbz = ? - AND"; + AND pss.studiensemester_kurzbz = ?"; - if ($abgeschickt === 'true') - $query .= " EXISTS"; - else - $query .= " NOT EXISTS"; + if (!$ignoreAbgeschickt) + { + $query .= "AND"; - $query .= " (SELECT 1 FROM public.tbl_prestudentstatus spss + if ($abgeschickt === 'true') + $query .= " EXISTS"; + else + $query .= " NOT EXISTS"; + + $query .= " (SELECT 1 FROM public.tbl_prestudentstatus spss JOIN public.tbl_prestudent sps USING(prestudent_id) WHERE sps.prestudent_id = ps.prestudent_id AND spss.bewerbung_abgeschicktamum IS NOT NULL)"; + } return $this->execQuery($query, array($person, $studiengang, $studienSemester)); } + public function getByPersonWithoutLehrgang($person, $studienSemester) + { + $query = "SELECT DISTINCT(ps.prestudent_id) + FROM public.tbl_prestudentstatus pss + JOIN public.tbl_prestudent ps USING(prestudent_id) + JOIN public.tbl_studiengang sg USING(studiengang_kz) + JOIN lehre.tbl_studienplan sp USING(studienplan_id) + JOIN lehre.tbl_studienordnung so USING(studienordnung_id) + WHERE ps.person_id = ? + AND (sg.typ = 'b' OR sg.typ = 'm') + AND pss.studiensemester_kurzbz = ?"; + + return $this->execQuery($query, array($person, $studienSemester)); + } + + /** * Gets förderrelevant flag for a prestudent, from prestudent, or, if not set on prestudent level, from studiengang * @param int $prestudent_id diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index 5f0b5876c..de91319b9 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -26,6 +26,77 @@ class Prestudentstatus_model extends DB_Model $this->hasSequence = false; } + /** + * loadWhereUid + * + * loads all rows for a student_uid + * + * @param string $uid + * @param array $where Optional. Default empty array + * @param boolean $withPrestudent Optional. Default true + * + * @return stdClass + */ + public function loadWhereUid($uid, $where = null, $withPrestudent = false) + { + $this->addSelect($this->dbTable . '.*'); + $this->addJoin('public.tbl_student', 'prestudent_id'); + + if ($withPrestudent) { + $this->addJoin('public.tbl_prestudent s', 'prestudent_id'); + $this->addSelect('s.aufmerksamdurch_kurzbz'); + $this->addSelect('s.person_id'); + $this->addSelect('s.studiengang_kz'); + $this->addSelect('s.berufstaetigkeit_code'); + $this->addSelect('s.ausbildungcode'); + $this->addSelect('s.zgv_code'); + $this->addSelect('s.zgvort'); + $this->addSelect('s.zgvdatum'); + $this->addSelect('s.zgvmas_code'); + $this->addSelect('s.zgvmaort'); + $this->addSelect('s.zgvmadatum'); + $this->addSelect('s.aufnahmeschluessel'); + $this->addSelect('s.facheinschlberuf'); + $this->addSelect('s.reihungstest_id'); + $this->addSelect('s.anmeldungreihungstest'); + $this->addSelect('s.reihungstestangetreten'); + $this->addSelect('s.rt_gesamtpunkte'); + $this->addSelect('s.bismelden'); + $this->addSelect('s.dual'); + $this->addSelect('s.rt_punkte1'); + $this->addSelect('s.rt_punkte2'); + $this->addSelect('s.ausstellungsstaat'); + $this->addSelect('s.rt_punkte3'); + $this->addSelect('s.zgvdoktor_code'); + $this->addSelect('s.zgvdoktorort'); + $this->addSelect('s.zgvdoktordatum'); + $this->addSelect('s.mentor'); + $this->addSelect('s.zgvnation'); + $this->addSelect('s.zgvmanation'); + $this->addSelect('s.zgvdoktornation'); + $this->addSelect('s.gsstudientyp_kurzbz'); + $this->addSelect('s.aufnahmegruppe_kurzbz'); + $this->addSelect('s.udf_values'); + $this->addSelect('s.priorisierung'); + $this->addSelect('s.foerderrelevant'); + $this->addSelect('s.standort_code'); + $this->addSelect('s.zgv_erfuellt'); + $this->addSelect('s.zgvmas_erfuellt'); + $this->addSelect('s.zgvdoktor_erfuellt'); + } + + + $this->addOrder('datum'); + $this->addOrder('insertamum'); + + if (!$where) + $where = []; + + $where['student_uid'] = $uid; + + return $this->loadWhere($where); + } + /** * getLastStatus */ @@ -430,17 +501,14 @@ class Prestudentstatus_model extends DB_Model $this->addSelect('tbl_prestudentstatus.studiensemester_kurzbz'); $this->addSelect('tbl_prestudentstatus.ausbildungssemester'); $this->addSelect('tbl_prestudentstatus.datum'); - $this->addSelect("TO_CHAR(tbl_prestudentstatus.datum::timestamp, 'DD.MM.YYYY') AS format_datum"); $this->addSelect('tbl_prestudentstatus.insertamum'); $this->addSelect('tbl_prestudentstatus.insertvon'); $this->addSelect('tbl_prestudentstatus.updateamum'); $this->addSelect('tbl_prestudentstatus.updatevon'); $this->addSelect('tbl_prestudentstatus.orgform_kurzbz'); $this->addSelect('tbl_prestudentstatus.bestaetigtam'); - $this->addSelect("TO_CHAR(tbl_prestudentstatus.bestaetigtam::timestamp, 'DD.MM.YYYY') AS format_bestaetigtam"); $this->addSelect('tbl_prestudentstatus.bestaetigtvon'); $this->addSelect('tbl_prestudentstatus.bewerbung_abgeschicktamum'); - $this->addSelect("TO_CHAR(tbl_prestudentstatus.bewerbung_abgeschicktamum::timestamp, 'DD.MM.YYYY') AS format_bewerbung_abgeschicktamum"); $this->addSelect('tbl_prestudentstatus.anmerkung'); $this->addSelect('plan.studienplan_id'); $this->addSelect('plan.bezeichnung'); diff --git a/application/models/crm/Student_model.php b/application/models/crm/Student_model.php index bd7ab41b6..539c3cf56 100644 --- a/application/models/crm/Student_model.php +++ b/application/models/crm/Student_model.php @@ -17,6 +17,28 @@ class Student_model extends DB_Model $this->hasSequence = false; } + /** + * Checks if the user is a Student. + * @param string $uid + * @return array + */ + public function isStudent($uid) + { + $this->addSelect('1'); + + $result = $this->loadWhere(array('student_uid' => $uid)); + + + if(hasData($result)) + { + return success(true); + } + else + { + return success(false); + } + } + // **** // * Generiert die Matrikelnummer // * FORMAT: 0710254001 diff --git a/application/models/dashboard/Bookmark_model.php b/application/models/dashboard/Bookmark_model.php new file mode 100644 index 000000000..5efacc26b --- /dev/null +++ b/application/models/dashboard/Bookmark_model.php @@ -0,0 +1,18 @@ +dbTable = 'dashboard.tbl_bookmark'; + $this->pk = 'bookmark_id'; + } + + + + +} diff --git a/application/models/dashboard/Dashboard_Override_model.php b/application/models/dashboard/Dashboard_Override_model.php new file mode 100644 index 000000000..d7a12bb42 --- /dev/null +++ b/application/models/dashboard/Dashboard_Override_model.php @@ -0,0 +1,26 @@ +dbTable = 'dashboard.tbl_dashboard_benutzer_override'; + $this->pk = 'override_id'; + } + + + /** + * Get Overrides of given uid. + * @param integer dashboard_id + * @param string $uid + * @return array + */ + public function getOverride($dashboard_id, $uid) + { + return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'uid'=> $uid)); + } +} diff --git a/application/models/dashboard/Dashboard_Preset_model.php b/application/models/dashboard/Dashboard_Preset_model.php new file mode 100644 index 000000000..ca10ce98a --- /dev/null +++ b/application/models/dashboard/Dashboard_Preset_model.php @@ -0,0 +1,67 @@ +dbTable = 'dashboard.tbl_dashboard_preset'; + $this->pk = 'preset_id'; + } + + /** + * Get Presets of given uid. + * @param integer dashboard_id + * @param string $uid + * @return array + */ + public function getPresets($dashboard_id, $uid) + { + // TODO: get Funktionen for uid and load all preset for all funktionen for uid + //return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'funktion_kurzbz'=> null)); + $sql = <<execQuery($sql, array($dashboard_id, $uid)); + } + + /** + * Get Preset by Dashboard and Funktion + * @param integer dashboard_id + * @param string funktion_kurzbz + * @return array + */ + public function getPresetByDashboardAndFunktion($dashboard_id, $funktion_kurzbz) + { + return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'funktion_kurzbz' => $funktion_kurzbz)); + } +} diff --git a/application/models/dashboard/Dashboard_Widget_model.php b/application/models/dashboard/Dashboard_Widget_model.php new file mode 100644 index 000000000..9e0a4c200 --- /dev/null +++ b/application/models/dashboard/Dashboard_Widget_model.php @@ -0,0 +1,15 @@ +dbTable = 'dashboard.tbl_dashboard_widget'; + $this->pk = ['dashboard_id', 'widget_id']; + $this->hasSequence = false; + } +} diff --git a/application/models/dashboard/Dashboard_model.php b/application/models/dashboard/Dashboard_model.php new file mode 100644 index 000000000..88946ed83 --- /dev/null +++ b/application/models/dashboard/Dashboard_model.php @@ -0,0 +1,25 @@ +dbTable = 'dashboard.tbl_dashboard'; + $this->pk = 'dashboard_id'; + } + + + /** + * Get Dashboard by kurzbz. + * @param string dashboard_kurzbz + * @return array + */ + public function getDashboardByKurzbz($dashboard_kurzbz) + { + return $this->loadWhere(array('dashboard_kurzbz' => $dashboard_kurzbz)); + } +} diff --git a/application/models/dashboard/Widget_model.php b/application/models/dashboard/Widget_model.php new file mode 100644 index 000000000..b1160e28f --- /dev/null +++ b/application/models/dashboard/Widget_model.php @@ -0,0 +1,32 @@ +dbTable = 'dashboard.tbl_widget'; + $this->pk = 'widget_id'; + } + + public function getWithAllowedForDashboard($dashboard_id) + { + $this->addSelect($this->dbTable . '.*'); + $this->addSelect('CASE WHEN dashboard_id IS NULL THEN 0 ELSE 1 END AS allowed', false); + $this->db->join('dashboard.tbl_dashboard_widget dw', $this->dbTable . '.widget_id=dw.widget_id AND dashboard_id = ?', 'LEFT', false); + + return $this->execQuery($this->db->get_compiled_select($this->dbTable), [$dashboard_id]); + } + + public function getForDashboard($db) + { + $this->addSelect($this->dbTable . '.*'); + $this->addJoin('dashboard.tbl_dashboard_widget', 'widget_id'); + $this->addJoin('dashboard.tbl_dashboard', 'dashboard_id'); + + return $this->loadWhere(['dashboard_kurzbz' => $db]); + } +} diff --git a/application/models/education/Abschlusspruefung_model.php b/application/models/education/Abschlusspruefung_model.php index 268e786cb..0ba8fd55c 100644 --- a/application/models/education/Abschlusspruefung_model.php +++ b/application/models/education/Abschlusspruefung_model.php @@ -113,4 +113,61 @@ class Abschlusspruefung_model extends DB_Model return success($abschlusspruefungdata); } + + /** + * Gets data of an Abschlusspruefung + * @param $student_uid + * @return object + */ + public function getAbschlusspruefungForPrestudent($student_uid) + { + $qry = " + SELECT + exam.*, + CONCAT( + person_pruefer1.nachname || ' ', + person_pruefer1.vorname, + COALESCE(' ' || person_pruefer1.titelpre) + ) AS person_pruefer1, + CONCAT( + person_pruefer2.nachname || ' ', + person_pruefer2.vorname, + COALESCE(' ' || person_pruefer2.titelpre) + ) AS person_pruefer2, + CONCAT( + person_pruefer3.nachname || ' ', + person_pruefer3.vorname, + COALESCE(' ' || person_pruefer3.titelpre) + ) AS person_pruefer3, + CONCAT( + person_vorsitzender.nachname || ' ', + person_vorsitzender.vorname, + COALESCE(' ' || person_vorsitzender.titelpre) + ) AS person_vorsitzender, + datum, + freigabedatum, + sponsion, + uhrzeit, + person_pruefer1.nachname as p1_nachname, + person_pruefer2.nachname as p2_nachname, + person_pruefer3.nachname as p3_nachname, + person_vorsitzender.nachname as vorsitz_nachname, + beurteilung.bezeichnung as beurteilung_bezeichnung, + antritt.bezeichnung as antritt_bezeichnung + FROM + lehre.tbl_abschlusspruefung exam + JOIN lehre.tbl_pruefungstyp USING (pruefungstyp_kurzbz) + LEFT JOIN public.tbl_benutzer ben_vorsitzender ON (ben_vorsitzender.uid = vorsitz) + LEFT JOIN public.tbl_person person_vorsitzender ON (ben_vorsitzender.person_id = person_vorsitzender.person_id) + LEFT JOIN public.tbl_person person_pruefer1 ON (person_pruefer1.person_id = pruefer1) + LEFT JOIN public.tbl_person person_pruefer2 ON (person_pruefer2.person_id = pruefer2) + LEFT JOIN public.tbl_person person_pruefer3 ON (person_pruefer3.person_id = pruefer3) + LEFT JOIN lehre.tbl_abschlussbeurteilung beurteilung USING (abschlussbeurteilung_kurzbz) + LEFT JOIN lehre.tbl_abschlusspruefung_antritt antritt USING (pruefungsantritt_kurzbz) + WHERE student_uid = ? + ORDER BY exam.datum DESC + "; + + return $this->execQuery($qry, array('student_uid' => $student_uid)); + } } diff --git a/application/models/education/Akadgrad_model.php b/application/models/education/Akadgrad_model.php new file mode 100644 index 000000000..92762a525 --- /dev/null +++ b/application/models/education/Akadgrad_model.php @@ -0,0 +1,14 @@ +dbTable = 'lehre.tbl_akadgrad'; + $this->pk = 'akadgrad_id'; + } +} \ No newline at end of file diff --git a/application/models/education/Anwesenheit_model.php b/application/models/education/Anwesenheit_model.php index 80a1fc111..b2c78fe02 100644 --- a/application/models/education/Anwesenheit_model.php +++ b/application/models/education/Anwesenheit_model.php @@ -11,4 +11,193 @@ class Anwesenheit_model extends DB_Model $this->dbTable = 'campus.tbl_anwesenheit'; $this->pk = 'anwesenheit_id'; } + + /** + * Laedt die Anwesenheiten in Prozent von Studierenden bei Lehrveranstaltungen + * Wenn die StudentUID uebergeben wird, werden alle Lehrveranstaltungen zu denen der Studierenden zugeteilt ist inkl Prozent der Anwesenheit + * Wenn die LehrveranstaltungID uebergeben wird, werden alle Studierenden geholt die zugeteilt sind inkl Prozent der Anwesenheit + * Es werden pro Student die Anwesenheiten berechnet aufgrund der Lehreinheit zu der sie zugeordnet sind + * + * @param string $studiensemester_kurzbz + * @param string|null (optional) $student_uid + * @param integer|null (optional) $lehrveranstaltung_id + * + * @return stdClass + */ + public function loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid = null, $lehrveranstaltung_id = null) + { + $this->addSelect("vorname"); + $this->addSelect("nachname"); + $this->addSelect("wahlname"); + $this->addSelect("lehrveranstaltung_id"); + $this->addSelect("bezeichnung"); + $this->addSelect("gruppe"); + $this->addSelect("student_uid AS uid"); + $this->addSelect("COUNT(stundenplan_id) AS gesamtstunden"); + $this->addSelect("COALESCE(anwesend.summe, 0) AS anwesend"); + $this->addSelect("COALESCE(nichtanwesend.summe, 0) AS nichtanwesend"); + $this->addSelect("COALESCE(anwesend.summe, 0) + COALESCE(nichtanwesend.summe, 0) AS erfassteanwesenheit"); + $this->addSelect("CASE + WHEN COUNT(stundenplan_id) = 0 OR COALESCE(anwesend.summe, 0) + COALESCE(nichtanwesend.summe, 0) = 0 + THEN 100 + ELSE TRUNC(100-(100/COUNT(stundenplan_id)*COALESCE(nichtanwesend.summe, 0)), 2) + END AS prozent"); + + + $this->db->join("( + SELECT + semester::text AS gruppe, + public.tbl_studentlehrverband.studiensemester_kurzbz, + student_uid, + studiengang_kz + FROM public.tbl_studentlehrverband + WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + + UNION + + SELECT + semester || verband AS gruppe, + public.tbl_studentlehrverband.studiensemester_kurzbz, + student_uid, + studiengang_kz + FROM public.tbl_studentlehrverband + WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + + UNION + + SELECT + semester || verband || gruppe AS gruppe, + public.tbl_studentlehrverband.studiensemester_kurzbz, + student_uid, + studiengang_kz + FROM public.tbl_studentlehrverband + WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + + UNION + + SELECT + gruppe_kurzbz AS gruppe, + public.tbl_benutzergruppe.studiensemester_kurzbz, + uid AS student_uid, + studiengang_kz + FROM public.tbl_benutzergruppe + JOIN public.tbl_gruppe USING (gruppe_kurzbz) + WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + ) a", "gruppe,studiensemester_kurzbz,studiengang_kz", "", false); + $this->addJoin("public.tbl_benutzer b", "b.uid = student_uid"); + $this->addJoin("public.tbl_person p", "person_id"); + $this->db->join("( + SELECT + lehrveranstaltung_id, + studiensemester_kurzbz, uid AS student_uid, + SUM(einheiten) AS summe + FROM campus.tbl_anwesenheit a + JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) + WHERE anwesend = TRUE + AND studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + GROUP BY + lehrveranstaltung_id, + bezeichnung, + uid, + studiensemester_kurzbz + ) anwesend", "lehrveranstaltung_id,student_uid,studiensemester_kurzbz", "LEFT", false); + $this->db->join("( + SELECT + lehrveranstaltung_id, + studiensemester_kurzbz, + uid AS student_uid, + SUM(einheiten) AS summe + FROM campus.tbl_anwesenheit a + JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) + WHERE anwesend = FALSE + AND studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + GROUP BY + lehrveranstaltung_id, bezeichnung, uid, studiensemester_kurzbz + ) nichtanwesend", "lehrveranstaltung_id,student_uid,studiensemester_kurzbz", "LEFT", false); + + $this->addGroupBy("vorname"); + $this->addGroupBy("nachname"); + $this->addGroupBy("wahlname"); + $this->addGroupBy("lehrveranstaltung_id"); + $this->addGroupBy("bezeichnung"); + $this->addGroupBy("gruppe"); + $this->addGroupBy("student_uid"); + $this->addGroupBy("anwesend.summe"); + $this->addGroupBy("nichtanwesend.summe"); + + + $where = [ + "lehrveranstaltung_id >" => 0 + ]; + + if ($student_uid) + $where["student_uid"] = $student_uid; + + if ($lehrveranstaltung_id) + $where["lehrveranstaltung_id"] = $lehrveranstaltung_id; + + if ($lehrveranstaltung_id) { + $this->addOrder("nachname"); + $this->addOrder("vorname"); + } elseif ($student_uid) { + $this->addOrder("bezeichnung"); + } + + + $tmp = $this->dbTable; + + $this->dbTable = "( + SELECT + SUM(stundenplan_id) AS stundenplan_id, + datum, + stunde, + lehrveranstaltung_id, + bezeichnung, + studiensemester_kurzbz, + studiengang_kz, + TRIM( + CASE + WHEN stp.gruppe_kurzbz IS NOT NULL + THEN stp.gruppe_kurzbz + ELSE stp.semester || ( + CASE + WHEN verband IS NULL + THEN '' + ELSE stp.verband + END + ) || ( + CASE + WHEN stp.gruppe IS NULL + THEN '' + ELSE stp.gruppe + END + ) + END + ) AS gruppe + FROM lehre.tbl_lehrveranstaltung lv + JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id) + JOIN lehre.tbl_stundenplan stp USING (lehreinheit_id,studiengang_kz) + WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + AND (titel NOT LIKE '%Nebenprüfung%' OR titel IS NULL) + GROUP BY + datum, + stunde, + lehrveranstaltung_id, + bezeichnung, + studiensemester_kurzbz, + studiengang_kz, + stp.gruppe_kurzbz, + stp.semester, + stp.verband, + stp.gruppe + ) x"; + + $result = $this->loadWhere($where); + + $this->dbTable = $tmp; + + return $result; + } } diff --git a/application/models/education/LePruefung_model.php b/application/models/education/LePruefung_model.php index ac6c7f9b2..6e51f1975 100644 --- a/application/models/education/LePruefung_model.php +++ b/application/models/education/LePruefung_model.php @@ -11,4 +11,45 @@ class LePruefung_model extends DB_Model $this->dbTable = 'lehre.tbl_pruefung'; $this->pk = 'pruefung_id'; } + + /** + * gets all Pruefungen for a student_uid + * @param string $student_uid + * @param string $studiensemester_kurzbz + * + * @return stdClass + */ + public function getPruefungenByStudentuid($student_uid, $studiensemester_kurzbz = null) + { + $this->addSelect('tbl_pruefung.datum'); + $this->addSelect("TO_CHAR(tbl_pruefung.datum::timestamp, 'DD.MM.YYYY') AS format_datum"); + $this->addSelect('tbl_pruefung.anmerkung'); + $this->addSelect('tbl_pruefung.pruefungstyp_kurzbz'); + $this->addSelect('tbl_pruefung.pruefung_id'); + $this->addSelect('tbl_pruefung.lehreinheit_id'); + $this->addSelect('tbl_pruefung.student_uid'); + $this->addSelect('tbl_pruefung.mitarbeiter_uid'); + $this->addSelect('tbl_pruefung.punkte'); + + $this->addSelect('tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung'); + $this->addSelect('tbl_lehrveranstaltung.lehrveranstaltung_id'); + $this->addSelect('tbl_note.bezeichnung as note_bezeichnung'); + $this->addSelect('tbl_pruefungstyp.beschreibung as typ_beschreibung'); + $this->addSelect('tbl_lehreinheit.studiensemester_kurzbz as studiensemester_kurzbz'); + + $this->addJoin('lehre.tbl_lehreinheit', 'lehre.tbl_pruefung.lehreinheit_id=lehre.tbl_lehreinheit.lehreinheit_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $this->addJoin('lehre.tbl_note', 'note'); + $this->addJoin('lehre.tbl_pruefungstyp', 'pruefungstyp_kurzbz'); + + if ($studiensemester_kurzbz) + $this->db->where("tbl_lehreinheit.studiensemester_kurzbz = ", $studiensemester_kurzbz); + + $this->addOrder('tbl_pruefung.datum', 'DESC'); + $this->addOrder('tbl_pruefung.pruefung_id', 'DESC'); + + return $this->loadWhere([ + 'student_uid' => $student_uid + ]); + } } diff --git a/application/models/education/Lehreinheit_model.php b/application/models/education/Lehreinheit_model.php index 10c122b94..d4bc7a22f 100644 --- a/application/models/education/Lehreinheit_model.php +++ b/application/models/education/Lehreinheit_model.php @@ -31,7 +31,7 @@ class Lehreinheit_model extends DB_Model $this->addOrder('lehreinheit_id'); $les = $this->loadWhere( array('lehrveranstaltung_id' => $lehrveranstaltung_id, - 'studiensemester_kurzbz' => $studiensemester) + 'studiensemester_kurzbz' => $studiensemester) ); if (hasData($les)) @@ -113,4 +113,194 @@ class Lehreinheit_model extends DB_Model return $this->execQuery($query, array($lehreinheit_id)); } + + /** + * Gets emails of all Studierende in a lehrveranstaltung + * @param int $lehreinheit_id + * @return array + */ + public function getStudentenMail($lehreinheit_id) + { + + // logic used from cis_menu_lv.inc.php line 335 + return $this->execReadOnlyQuery(" + SELECT + gruppe_kurzbz, + CASE + WHEN nomail = TRUE THEN 'nomail' + WHEN gruppe_kurzbz !='' THEN LOWER(gruppe_kurzbz || '@' || ?) + ELSE LOWER(stg_typ || stg_kurzbz || semester || TRIM(verband) || TRIM(gruppe) || '@' || ?) + END AS mail + + FROM + ( + SELECT + distinct vw_lehreinheit.studiensemester_kurzbz, vw_lehreinheit.stg_kurzbz, vw_lehreinheit.stg_typ, vw_lehreinheit.semester, + COALESCE(vw_lehreinheit.verband,'') as verband, COALESCE(vw_lehreinheit.gruppe,'') as gruppe, vw_lehreinheit.gruppe_kurzbz, tbl_gruppe.mailgrp, + CASE + WHEN mailgrp = TRUE OR mailgrp IS NULL THEN FALSE + ELSE TRUE + END as nomail + FROM campus.vw_lehreinheit + LEFT JOIN public.tbl_gruppe USING(gruppe_kurzbz) + WHERE + vw_lehreinheit.lehrveranstaltung_id= + (select distinct lehrveranstaltung_id from campus.vw_lehreinheit where lehreinheit_id=?) + AND + vw_lehreinheit.studiensemester_kurzbz = + (select distinct studiensemester_kurzbz from campus.vw_lehreinheit where lehreinheit_id=?) + AND (vw_lehreinheit.gruppe_kurzbz IS NULL OR + (vw_lehreinheit.gruppe_kurzbz IS NOT NULL AND (SELECT COUNT(*) FROM public.tbl_benutzergruppe where gruppe_kurzbz = vw_lehreinheit.gruppe_kurzbz AND studiensemester_kurzbz = vw_lehreinheit.studiensemester_kurzbz) > 0)) + + + ) AS subquery + ",[DOMAIN,DOMAIN,$lehreinheit_id,$lehreinheit_id ]); + } + + public function getLehreinheitenForStudentAndStudienSemester($lehrveranstaltung_id, $student_uid, $studiensemester_kurzbz) + { + $query = <<escape($lehrveranstaltung_id)} AND + vslv.uid = {$this->escape($student_uid)} AND + vslv.studiensemester_kurzbz = {$this->escape($studiensemester_kurzbz)} +EOSQL; + + $res = $this->execReadOnlyQuery($query); + return $res; + } + + public function getLehrfachIdMitarbeiter($angezeigtes_stsem,$user,$lvid) + { + $query = " + SELECT + distinct lehrfach_id + FROM + lehre.tbl_lehreinheit + JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id) + WHERE + studiensemester_kurzbz=" . $this->escape($angezeigtes_stsem) . " + AND mitarbeiter_uid=" . $this->escape($user)." + AND lehrveranstaltung_id=" . $this->escape(intval($lvid)); + + $res = $this->execReadOnlyQuery($query); + return $res; + } + + public function getLehrfachIdStudierender($angezeigtes_stsem,$user,$lvid) + { + $query = " + SELECT + distinct lehrfach_id + FROM + campus.vw_student_lehrveranstaltung + WHERE + lehrveranstaltung_id=" . $this->escape(intval($lvid))." + AND studiensemester_kurzbz=" . $this->escape($angezeigtes_stsem)." + AND uid=" . $this->escape($user); + + $res = $this->execReadOnlyQuery($query); + return $res; + } + + public function getLehreinheitInfo($lvid, $angezeigtes_stsem, $lehrfach_id) + { + $query = " + SELECT + * + FROM ( + SELECT + distinct on(uid) vorname, nachname, tbl_benutzer.uid as uid, + CASE + WHEN lehrfunktion_kurzbz='LV-Leitung' THEN true + ELSE false + END as lvleiter + FROM + lehre.tbl_lehreinheit, lehre.tbl_lehreinheitmitarbeiter, + public.tbl_benutzer, public.tbl_person + WHERE + tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitmitarbeiter.lehreinheit_id + AND tbl_lehreinheitmitarbeiter.mitarbeiter_uid = tbl_benutzer.uid + AND tbl_person.person_id = tbl_benutzer.person_id + AND lehrveranstaltung_id = " . $this->escape(intval($lvid)) . " + AND tbl_lehreinheitmitarbeiter.mitarbeiter_uid NOT like '_Dummy%' + AND tbl_benutzer.aktiv = true + AND tbl_person.aktiv = true + AND studiensemester_kurzbz = " . $this->escape($angezeigtes_stsem); + + if($lehrfach_id != '') + { + $query .= " AND tbl_lehreinheit.lehrfach_id = " . $this->escape(intval($lehrfach_id)); + } + + $query .= " ORDER BY uid, lvleiter desc) as a ORDER BY lvleiter desc, nachname, vorname"; + + $res = $this->execReadOnlyQuery($query); + return $res; + } + + /** + * Gets Lehreinheiten for Lehrveranstaltungen in a Studiensemester. + * Without using tbl_lehrfach: bezeichnung and kurzbz ALWAYS from lehrveranstaltung + * @param $lehrveranstaltung_id + * @param $studiensemester + * @return array with Lehreinheiten and their Lehreinheitgruppen + */ + public function getLesFromLvIds($lehrveranstaltung_id, $studiensemester_kurzbz = null) + { + $params = array($lehrveranstaltung_id); + + $query = " + SELECT + lv.lehrveranstaltung_id, + le.lehreinheit_id, + le.lehrform_kurzbz, + lv.kurzbz, + lv.bezeichnung, + lv.semester, + ( + SELECT + STRING_AGG(CONCAT(leg.semester, leg.verband, leg.gruppe), ' ') + FROM lehre.tbl_lehreinheitgruppe leg + WHERE leg.lehreinheit_id = le.lehreinheit_id + ) AS gruppe, + STRING_AGG(tma.kurzbz, ' ') as kuerzel + FROM + lehre.tbl_lehreinheit le + JOIN + lehre.tbl_lehrveranstaltung lv ON lv.lehrveranstaltung_id = le.lehrveranstaltung_id + JOIN + lehre.tbl_lehreinheitmitarbeiter ma USING (lehreinheit_id) + JOIN + public.tbl_mitarbeiter tma USING (mitarbeiter_uid) + WHERE + lv.lehrveranstaltung_id = ? + "; + + if (isset($studiensemester_kurzbz)) + { + $query .= " AND le.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + $query .=" + GROUP BY + lv.lehrveranstaltung_id, + le.lehreinheit_id, + le.lehrform_kurzbz, + lv.kurzbz, + lv.bezeichnung, + lv.semester + ORDER BY + le.lehreinheit_id; + "; + + return $this->execQuery($query, $params); + } } diff --git a/application/models/education/Lehreinheitmitarbeiter_model.php b/application/models/education/Lehreinheitmitarbeiter_model.php index dd5c7c858..ae1ac55d2 100644 --- a/application/models/education/Lehreinheitmitarbeiter_model.php +++ b/application/models/education/Lehreinheitmitarbeiter_model.php @@ -41,4 +41,38 @@ class Lehreinheitmitarbeiter_model extends DB_Model return error ('Incorrect parameter type'); } } + + /** + * @param integer $lehrveranstaltung_id + * @param string $studiensemester_kurzbz + * + * @return stdClass + */ + public function getForLv($lehrveranstaltung_id, $studiensemester_kurzbz) + { + $this->addSelect('ma.uid, ma.vorname, ma.nachname, ma.titelpre, ma.titelpost, lehrfunktion_kurzbz'); + $this->addGroupBy('ma.uid, ma.vorname, ma.nachname, ma.titelpre, ma.titelpost, lehrfunktion_kurzbz'); + + $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); + $this->addJoin('campus.vw_mitarbeiter ma', $this->dbTable . '.mitarbeiter_uid=ma.uid'); + + $this->addOrder('nachname'); + $this->addOrder('vorname'); + + if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON') && CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '') + { + $this->addJoin('(SELECT vertrag_id, CASE WHEN vertragsstatus_kurzbz=\'storno\' THEN 0 WHEN vertragsstatus_kurzbz=\'erteilt\' THEN 1 ELSE 2 END AS vertragsstatus_kurzbz FROM lehre.tbl_vertrag_vertragsstatus) v', 'vertrag_id', 'LEFT'); + $having = $this->db->compile_binds('(EXISTS (SELECT 1 FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=? AND tbl_studiensemester.start < (SELECT start FROM public.tbl_studiensemester stsem WHERE stsem.studiensemester_kurzbz=?)) OR MIN(vertragsstatus_kurzbz)=1)', [ + $studiensemester_kurzbz, + CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON + ]); + $this->db->having($having); + } + + return $this->loadWhere([ + 'lehrveranstaltung_id' => $lehrveranstaltung_id, + 'studiensemester_kurzbz' => $studiensemester_kurzbz + ]); + } + } diff --git a/application/models/education/LehrveranstaltungFaktor_model.php b/application/models/education/LehrveranstaltungFaktor_model.php new file mode 100644 index 000000000..c8a0c8aa8 --- /dev/null +++ b/application/models/education/LehrveranstaltungFaktor_model.php @@ -0,0 +1,14 @@ +dbTable = 'lehre.tbl_lehrveranstaltung_faktor'; + $this->pk = 'lehrveranstaltung_faktor_id'; + } +} diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index de8ebc5c9..056fb45d7 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -16,145 +16,21 @@ class Lehrveranstaltung_model extends DB_Model } /** - * Get Lehrveranstaltungen by eventQuery string. Use with autocomplete event queries. - * @param $eventQuery String - * @param string $studiensemester_kurzbz Filter by Studiensemester - * @param array $oes Filter by Organisationseinheiten - * @return array - */ - public function getAutocompleteSuggestions($eventQuery, $studiensemester_kurzbz = null, $oes = null) - { - $subQry = $this->_getQryLvsByStudienplan($studiensemester_kurzbz, $oes); - $params = []; - - /* filter by input string */ - if (is_string($eventQuery)) { - $subQry.= ' AND lv.bezeichnung ILIKE ?'; - $params[] = '%' . $eventQuery . '%'; - } - - $qry = 'SELECT DISTINCT ON (lehrveranstaltung_id) * FROM ('. $subQry. ') AS tmp'; - - return $this->execQuery($qry, $params); - } - - /** - * Get Lehrveranstaltungen with its Stg, OE and OE-type. - * Filter by Studiensemester and Organisationseinheiten if necessary. - * @param $eventQuery String - * @param string $studiensemester_kurzbz Filter by Studiensemester - * @param array $oes Filter by Organisationseinheiten - * @param array $lv_ids Filter by Lehrveranstaltung-Ids - * @return array - */ - public function getLvsByStudienplan($studiensemester_kurzbz = null, $oes = null, $lv_ids = null) - { - $subQry = $this->_getQryLvsByStudienplan($studiensemester_kurzbz, $oes); - $qry = 'SELECT * FROM ('. $subQry. ') AS tmp'; - - if (isset($lv_ids) && is_array($lv_ids)) - { - /* filter by lv_ids */ - $implodedLvIds = "'". implode("', '", $lv_ids). "'"; - $qry.= ' WHERE lehrveranstaltung_id IN ('. $implodedLvIds. ')'; - } - - $qry.= ' ORDER BY stg_typ_kurzbz, orgform_kurzbz DESC'; - - return $this->execQuery($qry); - } - - /** - * Get basic query to retrieve Lehrveranstaltungen according to the Orgforms and Ausbildungssemesters actual Studienplan. - * - * @return string - */ - private function _getQryLvsByStudienplan($studiensemester_kurzbz = null, $oes = null, $lehrtyp_kurzbz = 'lv') - { - $qry = ' - SELECT - lv.oe_kurzbz AS lv_oe_kurzbz, - CASE - WHEN oe.organisationseinheittyp_kurzbz = \'Kompetenzfeld\' THEN (\'KF \' || oe.bezeichnung) - WHEN oe.organisationseinheittyp_kurzbz = \'Department\' THEN (\'DEP \' || oe.bezeichnung) - ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung) - END AS lv_oe_bezeichnung, - stplsem.studiensemester_kurzbz, - studienordnung_id, - sto.studiengang_kz, - stpl.studienplan_id, - stplsem.semester, - stpl.orgform_kurzbz, - upper(stg.typ || stg.kurzbz) AS stg_typ_kurzbz, - stg.bezeichnung AS stg_bezeichnung, - stgtyp.bezeichnung AS stg_typ_bezeichnung, - lv.lehrveranstaltung_id, - lv.semester, - lv.bezeichnung AS lv_bezeichnung, - ( - -- comma seperated string of all lehreinheitgruppen - SELECT string_agg(bezeichnung, \', \') AS lehreinheitgruppe_bezeichnung - FROM( - -- distinct bezeichnung, as may come multiple times from different lehreinheiten - SELECT DISTINCT ON (studiengang_kz, bezeichnung) studiengang_kz, bezeichnung FROM - ( - -- distinct lehreinheitgruppe, as may come multiple times from different lehrform - SELECT DISTINCT ON (legr.lehreinheitgruppe_id) legr.studiengang_kz, - -- get Spezialgruppe or Lehrverbandgruppe - COALESCE( - legr.gruppe_kurzbz, - CONCAT( UPPER(stg1.typ), UPPER(stg1.kurzbz), \'-\', legr.semester, legr.verband, legr.gruppe ) - ) as bezeichnung - FROM lehre.tbl_lehreinheitgruppe legr - JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id) - JOIN lehre.tbl_lehrveranstaltung lv1 USING (lehrveranstaltung_id) - JOIN public.tbl_studiengang stg1 ON stg1.studiengang_kz = legr.studiengang_kz - WHERE lv1.lehrveranstaltung_id = lv.lehrveranstaltung_id - AND le.studiensemester_kurzbz = stplsem.studiensemester_kurzbz - ) AS lehreinheitgruppen - GROUP BY studiengang_kz, bezeichnung - ORDER BY studiengang_kz DESC - ) AS uniqueLehreinheitgruppen_bezeichnung - ) AS lehreinheitgruppen_bezeichnung - FROM - lehre.tbl_studienplan stpl - JOIN lehre.tbl_studienordnung sto USING (studienordnung_id) - JOIN lehre.tbl_studienplan_semester stplsem USING (studienplan_id) - JOIN lehre.tbl_studienplan_lehrveranstaltung stpllv ON (stpllv.studienplan_id = stpl.studienplan_id AND stpllv.semester = stplsem.semester) - JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) - JOIN public.tbl_organisationseinheit oe USING (oe_kurzbz) - JOIN public.tbl_studiengang stg ON stg.studiengang_kz = sto.studiengang_kz - JOIN public.tbl_studiengangstyp stgtyp ON stgtyp.typ = stg.typ - /* filter by lehrtyp_kurzbz, default is lvs only */ - WHERE - lehrtyp_kurzbz = '. $this->db->escape($lehrtyp_kurzbz); - - if (isset($studiensemester_kurzbz) && is_string($studiensemester_kurzbz)) - { - /* filter by studiensemester */ - $qry.= ' AND stplsem.studiensemester_kurzbz = '. $this->db->escape($studiensemester_kurzbz); - - } - - if (isset($oes) && is_array($oes)) - { - /* filter by organisationseinheit */ - $implodedOes = "'". implode("', '", $oes). "'"; - $qry.= ' AND lv.oe_kurzbz IN ('. $implodedOes. ')'; - } - - return $qry; - } - - /** - * Get all Templates and union with all Lehrveranstaltungen of given Studiensemester and Oes, that are assigned to - * a template. This data structure can be used for nested tabulator data tree. + * Get all Templates and its assigned Lehrveranstaltungen of given Studiensemester and Oes. + * Lvs are queried via actual Studienordnung and Studienplan. * * @param null|string $studiensemester_kurzbz * @param null|array $oes + * @param null $lehrveranstaltung_id Queries certain LV only * @return array|stdClass|null */ - public function getTemplateLvTree($studiensemester_kurzbz = null, $oes = null){ + public function getTemplateLvTree($studiensemester_kurzbz = null, $oes = null, $studienjahr_kurzbz = null){ + + if (is_string($studiensemester_kurzbz) && is_string($studienjahr_kurzbz)) + { + return error('Query not possible for both studiensemester and studienjahr'); + } + $params = []; $qry = ' WITH @@ -189,6 +65,17 @@ class Lehrveranstaltung_model extends DB_Model } + if (is_string($studienjahr_kurzbz)) { + /* filter by studiensemester */ + $params[] = $studienjahr_kurzbz; + $qry .= ' + AND stplsem.studiensemester_kurzbz IN ( + SELECT studiensemester_kurzbz + FROM public.tbl_studiensemester + WHERE studienjahr_kurzbz = ? + )'; + } + if (is_array($oes)) { /* filter by organisationseinheit */ @@ -300,7 +187,15 @@ class Lehrveranstaltung_model extends DB_Model JOIN public.tbl_studiengangstyp stgtyp ON stgtyp.typ = stg.typ JOIN public.tbl_organisationseinheit oe ON oe.oe_kurzbz = lv.oe_kurzbz ORDER BY - oe.bezeichnung, lv.semester, lv.bezeichnung + -- Sort by lv.bezeichnung + lv.bezeichnung, + -- Within each group, ensure templates appear first + CASE + WHEN lv.lehrtyp_kurzbz = \'tpl\' THEN 0 + ELSE 1 + END, + -- Ensure assigend lvs follow their template, grouped by lehrveranstaltung_template_id + COALESCE(lv.lehrveranstaltung_template_id, lv.lehrveranstaltung_id) '; return $this->execQuery($qry, $params); @@ -517,33 +412,145 @@ class Lehrveranstaltung_model extends DB_Model /** * Gets Lehrveranstaltungen of a student * @param $student_uid - * @param null $studiensemester_kurzbz + * @param $studiensemester_kurzbz * @return array|null */ public function getLvsByStudent($student_uid, $studiensemester_kurzbz = null) { $params = array($student_uid); - $qry = "SELECT * FROM lehre.tbl_lehrveranstaltung - WHERE lehrveranstaltung_id IN(SELECT lehrveranstaltung_id FROM campus.vw_student_lehrveranstaltung - WHERE uid=?"; + WHERE lehrveranstaltung_id IN( + SELECT lehrveranstaltung_id FROM campus.vw_student_lehrveranstaltung + WHERE uid=?"; + if (isset($studiensemester_kurzbz)) { - $qry .= " AND studiensemester_kurzbz=?"; $params[] = $studiensemester_kurzbz; + $qry .= " AND studiensemester_kurzbz=?"; } - $qry .= ") OR lehrveranstaltung_id IN(SELECT lehrveranstaltung_id FROM lehre.tbl_zeugnisnote WHERE student_uid=?"; + $qry .= ")"; + + $qry .= " OR lehrveranstaltung_id IN( + SELECT lehrveranstaltung_id FROM lehre.tbl_zeugnisnote + WHERE student_uid=?"; $params[] = $student_uid; - if (isset($studiensemester_kurzbz)) - { - $qry .= " AND studiensemester_kurzbz=?"; - $params[] = $studiensemester_kurzbz; - } + $qry .= ") ORDER BY semester, bezeichnung"; return $this->execQuery($qry, $params); } + /** + * Gets Lehrveranstaltungen of a student with grades if available + * + * @param string $student_uid + * @param string $studiensemester_kurzbz + * @param string|null $sprache + * @param number|null $lvid - returns only information about that single lv if the parameter is set + * + * @return stdClass + */ + public function getLvsByStudentWithGrades($student_uid, $studiensemester_kurzbz, $sprache = null, $lvid=null) + { + if ($sprache) { + $sprache_qry = $this->db->compile_binds('SELECT index FROM public.tbl_sprache WHERE sprache = ?', [$sprache]); + $bezeichnung = 'bezeichnung_mehrsprachig[(' . $sprache_qry . ')]'; + $sgbezeichnung = $sprache == 'English' ? 'COALESCE(sg.english, sg.bezeichnung)' : 'sg.bezeichnung'; + $lvbezeichnung = $sprache == 'English' ? 'COALESCE(v.bezeichnung_english, v.bezeichnung)' : 'v.bezeichnung'; + } else { + $bezeichnung = 'bezeichnung'; + $sgbezeichnung = 'sg.bezeichnung'; + $lvbezeichnung = 'v.bezeichnung'; + } + + $this->addDistinct(); + // TODO(chris): selects + /* + semester (?) + module + bezeichnung + sg_bezeichnung + studiengang_kuerzel + lvnote + znote + studiengang_kz + lehrveranstaltung_id + benotung + lvinfo + farbe + + sprache (?) + ects (?) + incoming (?) + orgform_kurzbz (?) + */ + // TODO(chris): module or kf + #$this->addSelect($this->dbTable . '.*'); + #$this->addSelect('v.*'); + $this->addSelect($this->dbTable . '.benotung'); + $this->addSelect($this->dbTable . '.lvinfo'); + $this->addSelect($this->dbTable . '.farbe'); + $this->addSelect($this->dbTable . '.incoming'); + $this->addSelect($this->dbTable . '.orgform_kurzbz'); + $this->addSelect('v.studiengang_kz'); + $this->addSelect('v.lehrveranstaltung_id'); + $this->addSelect('v.semester'); + + $this->addSelect('v.sprache'); + $this->addSelect('v.ects'); + $this->addSelect('znn.positiv'); + + #$this->addSelect('splv.module'); + $this->addSelect($lvbezeichnung . ' AS bezeichnung'); + $this->addSelect($sgbezeichnung . ' AS sg_bezeichnung'); + $this->addSelect('UPPER(sg.typ::VARCHAR(1) || sg.kurzbz) AS studiengang_kuerzel'); + + //also adds returns the index of the grade + //TODO: ist zeugnissnote immer gleich wie die lvgesamtnote + $this->addSelect('COALESCE(zn.note::numeric,gn.note::numeric) as note_index'); + $this->addSelect('COALESCE(znn.positiv,gnn.positiv) as positiv'); + $this->addSelect('COALESCE(gnn.' . $bezeichnung . ', gnn.bezeichnung, gn.note::text) AS lvnote'); + $this->addSelect('COALESCE(znn.' . $bezeichnung . ', znn.bezeichnung, zn.note::text) AS znote'); + + // TODO(chris): Potentielle Anpassung "Eine UID" + $this->addJoin('campus.vw_student_lehrveranstaltung v', 'lehrveranstaltung_id'); + $this->addJoin('public.tbl_studiengang sg', $this->dbTable . '.studiengang_kz = sg.studiengang_kz'); + $this->db->where("v.lehreverzeichnis<>''"); + if(isset($lvid)) + { + $this->db->where("v.lehrveranstaltung_id", $lvid); + } + + $this->addJoin('campus.tbl_lvgesamtnote gn', 'gn.lehrveranstaltung_id=v.lehrveranstaltung_id AND gn.student_uid=v.uid AND gn.studiensemester_kurzbz=v.studiensemester_kurzbz', 'LEFT'); + $this->addJoin('lehre.tbl_note gnn', 'gn.note=gnn.note', 'LEFT'); + + $this->addJoin('lehre.tbl_zeugnisnote zn', 'zn.lehrveranstaltung_id=v.lehrveranstaltung_id AND zn.student_uid=v.uid AND zn.studiensemester_kurzbz=v.studiensemester_kurzbz', 'LEFT'); + $this->addJoin('lehre.tbl_note znn', 'zn.note=znn.note', 'LEFT'); + + $this->addOrder('bezeichnung'); + + /*if (!defined("CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN") || !CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN) { + $modulebezeichnung = str_replace('v.', 'm.', $lvbezeichnung); + $modulesql = ' + LEFT JOIN lehre.tbl_studienplan_lehrveranstaltung p ON(lv.studienplan_lehrveranstaltung_id_parent=p.studienplan_lehrveranstaltung_id) + LEFT JOIN lehre.tbl_lehrveranstaltung m ON(m.lehrveranstaltung_id = p.lehrveranstaltung_id)'; + } else { + $modulebezeichnung = 'NULL'; + $modulesql = ''; + } + + $this->addJoin('( + SELECT lv.lehrveranstaltung_id, sps.studiensemester_kurzbz, so.studiengang_kz, lv.semester, ' . $modulebezeichnung . ' AS module + FROM lehre.tbl_studienplan_lehrveranstaltung lv + LEFT JOIN lehre.tbl_studienplan sp ON(sp.studienplan_id=lv.studienplan_id) + JOIN lehre.tbl_studienplan_semester sps ON(sp.studienplan_id=sps.studienplan_id AND sps.semester=lv.semester) + JOIN lehre.tbl_studienordnung so ON(so.studienordnung_id=sp.studienordnung_id) + ' . $modulesql . ' + ) splv', 'splv.lehrveranstaltung_id=v.lehrveranstaltung_id AND splv.studiensemester_kurzbz=v.studiensemester_kurzbz AND splv.studiengang_kz=v.studiengang_kz', 'LEFT');*/ + + return $this->loadWhere(['v.uid' => $student_uid, 'v.lehre' => true, 'v.studiensemester_kurzbz' => $studiensemester_kurzbz]); + } + /** * Gets valid Lehrveranstaltungen with incoming places for a Studiensemester. * Only @@ -623,6 +630,37 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($query, array($uid, $studiensemester_kurzbz, $lehrveranstaltung_id)); } + /** + * Get Lehreinheit. + * + * @param string $student_uid + * @param string $studiensemester_kurzbz + * @param integer $lehrveranstaltung_id + * + * @return stdClass + */ + public function getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id) + { + $this->addSelect("lehreinheit_id"); + + $this->addOrder("lehreinheit_id", "ASC"); + + $this->addLimit(1); + + $tmp = $this->dbTable; + $this->dbTable = "campus.vw_student_lehrveranstaltung"; + + $result = $this->loadWhere([ + "uid" => $student_uid, + "lehrveranstaltung_id" => $lehrveranstaltung_id, + "studiensemester_kurzbz" => $studiensemester_kurzbz + ]); + + $this->dbTable = $tmp; + + return $result; + } + /** * Sucht nach LV Templates und gibt Id und Label ("bezeichnung [kurzbz]") aus * Diese funktion ist für autocomplete gedacht @@ -668,6 +706,28 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($qry); } + /** + * Check if given LV is a template (Quellkurs) + * + * @param $lehrveranstaltung_id + * @return array|stdClass|void + */ + public function checkIsTemplate($lehrveranstaltung_id) + { + $this->addSelect('lehrtyp_kurzbz, lehrveranstaltung_template_id'); + $result = $this->load($lehrveranstaltung_id); + + if (isError($result)) + return error(getError($result)); + + if (hasData($result)) + { + return success( + getData($result)[0]->lehrtyp_kurzbz === 'tpl' && + getData($result)[0]->lehrveranstaltung_template_id === null + ); + } + } /** * Get ECTS Summe pro angerechnetes Quereinstiegssemester. @@ -785,10 +845,147 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($qry, array($student_uid)); } + /** + * @param integer $lehrveranstaltung_id + * @param string $studiensemester_kurzbz + * + * @return stdClass + */ + public function getKoordinator($lehrveranstaltung_id, $studiensemester_kurzbz = null) + { + $binds = [ + $lehrveranstaltung_id, + $lehrveranstaltung_id, + $lehrveranstaltung_id, + $lehrveranstaltung_id + ]; + $qry = " + SELECT + a.uid, vorname, nachname, titelpre, titelpost + FROM ( + SELECT + koordinator as uid + FROM + lehre.tbl_lehrveranstaltung + WHERE + lehrveranstaltung_id = ? + UNION + SELECT + uid + FROM + lehre.tbl_lehreinheit + JOIN lehre.tbl_lehrveranstaltung AS lehrfach ON(tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id) + JOIN public.tbl_fachbereich ON(lehrfach.oe_kurzbz=tbl_fachbereich.oe_kurzbz) + JOIN public.tbl_benutzerfunktion ON(tbl_fachbereich.fachbereich_kurzbz=tbl_benutzerfunktion.fachbereich_kurzbz) + WHERE + tbl_benutzerfunktion.funktion_kurzbz='fbk' + AND (tbl_benutzerfunktion.datum_von IS null OR tbl_benutzerfunktion.datum_von <= now()) + AND (tbl_benutzerfunktion.datum_bis IS null OR tbl_benutzerfunktion.datum_bis >= now()) + AND tbl_lehreinheit.lehrveranstaltung_id = ? + AND tbl_benutzerfunktion.oe_kurzbz = ( + SELECT + tbl_studiengang.oe_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE lehrveranstaltung_id = ? + ) + AND EXISTS ( + SELECT + lehrveranstaltung_id + FROM + lehre.tbl_lehrveranstaltung + WHERE + lehrveranstaltung_id = ? + AND koordinator IS null + ) + "; + + if ($studiensemester_kurzbz !== null) + { + $qry .= " AND tbl_lehreinheit.studiensemester_kurzbz = ?"; + $binds[] = $studiensemester_kurzbz; + } + + $qry .= " + ) AS a + JOIN campus.vw_mitarbeiter ON(a.uid=vw_mitarbeiter.uid) + WHERE vw_mitarbeiter.aktiv + "; + + return $this->execQuery($qry, $binds); + } + public function getStg($lehrveranstaltung_id) { $this->addSelect('stg.*'); $this->addJoin('public.tbl_studiengang stg', 'studiengang_kz'); return $this->load($lehrveranstaltung_id); } + + //Berechtigungen auf Fachbereichsebene + public function getBerechtigungenAufFachberechsebene($lvid, $angezeigtes_stsem) + { + $query = " + SELECT + DISTINCT lehrfach.oe_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN + lehre.tbl_lehreinheit USING(lehrveranstaltung_id) + JOIN + lehre.tbl_lehrveranstaltung as lehrfach ON(tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id) + WHERE + tbl_lehrveranstaltung.lehrveranstaltung_id = " . $this->escape(intval($lvid)); + + if(isset($angezeigtes_stsem) && $angezeigtes_stsem != ''){ + $query .= " AND studiensemester_kurzbz = " . $this->escape($angezeigtes_stsem); + } + + $res = $this->execReadOnlyQuery($query); + return $res; + } + + public function getStudentEMail($lvid, $angezeigtes_stsem) + { + $query = " + SELECT + DISTINCT vw_lehreinheit.stg_kurzbz, vw_lehreinheit.stg_typ, + vw_lehreinheit.semester, COALESCE(vw_lehreinheit.verband,'') as verband, + COALESCE(vw_lehreinheit.gruppe,'') as gruppe, + vw_lehreinheit.gruppe_kurzbz, tbl_gruppe.mailgrp + FROM + campus.vw_lehreinheit + LEFT JOIN + public.tbl_gruppe USING(gruppe_kurzbz) + WHERE + lehrveranstaltung_id = " . $this->escape(intval($lvid)) . " + AND studiensemester_kurzbz = " . $this->escape($angezeigtes_stsem); + + $res = $this->execReadOnlyQuery($query); + return $res; + } + + /** + * Gets lehrveranstaltungen of a studiengang + * @param integer $studiengang_kz + * @return array|null + */ + public function getLvsByStudiengangkz($studiengang_kz) + { + $params = array($studiengang_kz); + + $qry = "SELECT + * + FROM + lehre.tbl_lehrveranstaltung + WHERE lehrveranstaltung_id IN + (SELECT lehrveranstaltung_id + FROM campus.vw_student_lehrveranstaltung + WHERE studiengang_kz = ?"; + + $qry .= ") ORDER BY semester, bezeichnung"; + + return $this->execQuery($qry, $params); + } } diff --git a/application/models/education/Lvangebot_model.php b/application/models/education/Lvangebot_model.php index e16b726dd..8d5096fb0 100644 --- a/application/models/education/Lvangebot_model.php +++ b/application/models/education/Lvangebot_model.php @@ -11,4 +11,39 @@ class Lvangebot_model extends DB_Model $this->dbTable = 'lehre.tbl_lvangebot'; $this->pk = 'lvangebot_id'; } + +/** + * Prueft ob eine Abmeldung von einer Lehrveranstaltung moeglich ist + * und liefert die Gruppen von denen sich abgemeldet werden kann + * @param $lehrveranstaltung_id + * @param $studiensemester_kurzbz + * @param $uid + * @return $gruppen Array mit den Gruppen + */ + public function AbmeldungMoeglich($lehrveranstaltung_id, $studiensemester_kurzbz, $uid) + { + $query = "SELECT + gruppe_kurzbz + FROM + lehre.tbl_lvangebot + JOIN public.tbl_benutzergruppe USING(studiensemester_kurzbz, gruppe_kurzbz) + WHERE + tbl_lvangebot.studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz)." + AND tbl_benutzergruppe.uid = " . $this->escape($uid)." + AND (tbl_lvangebot.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id))." + OR tbl_lvangebot.lehrveranstaltung_id IN(SELECT lehrveranstaltung_id_kompatibel + FROM lehre.tbl_lehrveranstaltung_kompatibel + WHERE lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id))." + ) + )"; + $res = $this->execReadOnlyQuery($query); + $rows = (hasData($res)) ? getData($res) : array(); + + $gruppen=array(); + foreach($rows as $row) + { + $gruppen[] = $row->gruppe_kurzbz; + } + return $gruppen; + } } diff --git a/application/models/education/Lvgesamtnote_model.php b/application/models/education/Lvgesamtnote_model.php index 975833287..c30045ff0 100644 --- a/application/models/education/Lvgesamtnote_model.php +++ b/application/models/education/Lvgesamtnote_model.php @@ -12,4 +12,38 @@ class Lvgesamtnote_model extends DB_Model $this->pk = array('student_uid', 'studiensemester_kurzbz', 'lehrveranstaltung_id'); $this->hasSequence = false; } + + /** + * Laedt die Noten + * + * @param integer $lehrveranstaltung_id + * @param string $student_uid + * @param string $studiensemester_kurzbz + * + * @return stdClass + */ + public function getLvGesamtNoten($lehrveranstaltung_id, $student_uid, $studiensemester_kurzbz) + { + $this->addSelect($this->dbTable . ".*"); + $this->addSelect("n.bezeichnung AS note_bezeichnung"); + $this->addSelect("lv.bezeichnung AS lehrveranstaltung_bezeichnung"); + $this->addSelect("lv.studiengang_kz"); + $this->addSelect("UPPER(stg.typ || stg.kurzbz) AS studiengang"); + + $this->addJoin("lehre.tbl_note n", "note"); + $this->addJoin("lehre.tbl_lehrveranstaltung lv", "lehrveranstaltung_id"); + $this->addJoin("public.tbl_studiengang stg", "studiengang_kz"); + + $this->db->where($this->dbTable . ".freigabedatum <", "NOW()", false); + + $where = []; + if ($studiensemester_kurzbz) + $where[$this->dbTable . ".studiensemester_kurzbz"] = $studiensemester_kurzbz; + if ($lehrveranstaltung_id) + $where[$this->dbTable . ".lehrveranstaltung_id"] = $lehrveranstaltung_id; + if ($student_uid) + $where[$this->dbTable . ".student_uid"] = $student_uid; + + return $this->loadWhere($where); + } } diff --git a/application/models/education/Note_model.php b/application/models/education/Note_model.php new file mode 100644 index 000000000..80b454398 --- /dev/null +++ b/application/models/education/Note_model.php @@ -0,0 +1,14 @@ +dbTable = 'lehre.tbl_note'; + $this->pk = 'note'; + } +} \ No newline at end of file diff --git a/application/models/education/Notenschluesselaufteilung_model.php b/application/models/education/Notenschluesselaufteilung_model.php index 5e0f2f05c..d48e16b0b 100644 --- a/application/models/education/Notenschluesselaufteilung_model.php +++ b/application/models/education/Notenschluesselaufteilung_model.php @@ -11,4 +11,34 @@ class Notenschluesselaufteilung_model extends DB_Model $this->dbTable = 'lehre.tbl_notenschluesselaufteilung'; $this->pk = 'notenschluesselaufteilung_id'; } + + /** + * Liefert die Note zu Punkten einer Lehrveranstaltung + * + * @param number $points + * @param integer $lehrveranstaltung_id + * @param string $studiensemester_kurzbz + * + * @return stdClass returns success(null) if no entry is found + */ + public function getNote($points, $lehrveranstaltung_id, $studiensemester_kurzbz) + { + $this->load->model('education/Notenschluesselzuordnung_model', 'NotenschluesselzuordnungModel'); + $notenschluessel_kurzbz = $this->NotenschluesselzuordnungModel->getKurzbzForLv($lehrveranstaltung_id, $studiensemester_kurzbz); + + $this->addSelect("note"); + $this->addOrder("punkte", "DESC"); + $this->addLimit(1); + + $result = $this->loadWhere([ + "notenschluessel_kurzbz" => $notenschluessel_kurzbz, + "punkte <=" => $points + ]); + + if (isError($result)) + return $result; + if (!hasData($result)) + return success(null); + return success(current(getData($result))->note); + } } diff --git a/application/models/education/Notenschluesselzuordnung_model.php b/application/models/education/Notenschluesselzuordnung_model.php index e6881e12b..9eb46b290 100644 --- a/application/models/education/Notenschluesselzuordnung_model.php +++ b/application/models/education/Notenschluesselzuordnung_model.php @@ -11,4 +11,71 @@ class Notenschluesselzuordnung_model extends DB_Model $this->dbTable = 'lehre.tbl_notenschluesselzuordnung'; $this->pk = 'notenschluesselzuordnung_id'; } + + /** + * Liefert den passenden Notenschluessel zu einer Lehrveranstaltung + * + * @param integer $lehrveranstaltung_id + * @param string $studiensemester_kurzbz + * + * @return integer|null + */ + public function getKurzbzForLv($lehrveranstaltung_id, $studiensemester_kurzbz) + { + $this->addSelect("notenschluessel_kurzbz"); + + $this->db->where("lehrveranstaltung_id", $lehrveranstaltung_id); + if ($studiensemester_kurzbz) { + $this->db->where("studiensemester_kurzbz", $studiensemester_kurzbz); + $this->db->or_where("studiensemester_kurzbz", null); + } else { + $this->db->where("studiensemester_kurzbz", null); + } + + $result = $this->load(); + + if (!isError($result) && hasData($result)) + return current(getData($result))->notenschluessel_kurzbz; + + + $this->addSelect("notenschluessel_kurzbz"); + + $this->addJoin("( + WITH RECURSIVE oes(oe_kurzbz, oe_parent_kurzbz, depth) AS ( + SELECT oe_kurzbz, oe_parent_kurzbz, 1 + FROM public.tbl_organisationseinheit + WHERE oe_kurzbz = ( + SELECT + oe_kurzbz + FROM + lehre.tbl_lehrveranstaltung + WHERE + lehrveranstaltung_id = " . $this->escape($lehrveranstaltung_id) . " + ) + UNION ALL + SELECT o.oe_kurzbz, o.oe_parent_kurzbz, oes.depth+1 AS depth + FROM public.tbl_organisationseinheit o, oes + WHERE o.oe_kurzbz = oes.oe_parent_kurzbz + AND aktiv = true + ) + SELECT * FROM oes + ) oes", "oe_kurzbz"); + + $this->addOrder("depth", "ASC"); + $this->addLimit(1); + + if ($studiensemester_kurzbz) { + $this->db->where_in("studiensemester_kurzbz", [$studiensemester_kurzbz, null]); + $result = $this->load(); + } else { + $result = $this->loadWhere([ + "studiensemester_kurzbz" => null + ]); + } + + if (isError($result) || !hasData($result)) + return null; + + return current(getData($result))->notenschluessel_kurzbz; + } } diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index 409c0b733..927d83c82 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -37,6 +37,35 @@ class Pruefung_model extends DB_Model return $this->execQuery($qry, array($person_id, $studiensemester_kurzbz)); } + /** + * Gets Pruefungen of a student for a Lehrveranstaltung. + * + * @param string $uid + * @param string $lehrveranstaltung_id + * @param string|null $sprache + * + * @return object + */ + public function getByStudentAndLv($uid, $lehrveranstaltung_id, $sprache = null) + { + // TODO(chris): Potentielle Anpassung "Eine UID" + $this->dbTable = 'lehre.tbl_pruefung'; + + if ($sprache) { + $sprache_qry = $this->db->compile_binds('SELECT index FROM public.tbl_sprache WHERE sprache = ?', [$sprache]); + $bezeichnung = 'bezeichnung_mehrsprachig[(' . $sprache_qry . ')]'; + } else { + $bezeichnung = 'bezeichnung'; + } + + $this->addSelect($this->dbTable . '.pruefung_id, ' . $this->dbTable . '.pruefungstyp_kurzbz, ' . $this->dbTable . '.datum, COALESCE(n.' . $bezeichnung . ', n.note::text) AS note'); + + $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + $this->addJoin('lehre.tbl_note n', 'note'); + + return $this->loadWhere(['lehrveranstaltung_id' => $lehrveranstaltung_id, 'student_uid' => $uid]); + } /** * NOTE(chris): not used diff --git a/application/models/education/Pruefungsantritt_model.php b/application/models/education/Pruefungsantritt_model.php new file mode 100644 index 000000000..f22633117 --- /dev/null +++ b/application/models/education/Pruefungsantritt_model.php @@ -0,0 +1,14 @@ +dbTable = 'lehre.tbl_abschlusspruefung_antritt'; + $this->pk = 'pruefungsantritt_kurzbz'; + } +} \ No newline at end of file diff --git a/application/models/education/Studierendenantraglehrveranstaltung_model.php b/application/models/education/Studierendenantraglehrveranstaltung_model.php index 4318c773e..927343a3e 100644 --- a/application/models/education/Studierendenantraglehrveranstaltung_model.php +++ b/application/models/education/Studierendenantraglehrveranstaltung_model.php @@ -46,6 +46,15 @@ class Studierendenantraglehrveranstaltung_model extends DB_Model } } + /** + * Gets all LVs for a repeating prestudent that are either not allowed or + * already done. + * + * @param string $prestudent_id + * @param string $studiensemester_kurzbz + * + * @return stdClass + */ public function getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz) { $this->addSelect($this->dbTable . '.*'); @@ -66,39 +75,53 @@ class Studierendenantraglehrveranstaltung_model extends DB_Model ); $this->addJoin('public.tbl_student s', 'prestudent_id'); - // NOTE(chris): last offizell note - $this->addJoin('( - SELECT z.* - FROM lehre.tbl_zeugnisnote z - LEFT JOIN public.tbl_studiensemester zs - USING(studiensemester_kurzbz) - JOIN ( - SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start - FROM lehre.tbl_zeugnisnote zi - LEFT JOIN lehre.tbl_note zin - USING(note) - LEFT JOIN public.tbl_studiensemester zis - USING(studiensemester_kurzbz) - WHERE zin.aktiv AND zin.offiziell - GROUP BY zi.lehrveranstaltung_id, zi.student_uid - ) zx - ON ( - z.lehrveranstaltung_id=zx.lehrveranstaltung_id - AND z.student_uid=zx.student_uid - AND zs.start = zx.start - )) z', 'z.lehrveranstaltung_id=lv.lehrveranstaltung_id AND z.student_uid=s.student_uid', 'LEFT'); - $this->addJoin('lehre.tbl_note zn', 'z.note = zn.note', 'LEFT'); - + $this->load->config('studierendenantrag'); $note_intern_angerechntet = $this->config->item('wiederholung_note_angerechnet'); - return $this->loadWhere([ + $where = [ 'ps.prestudent_id' => $prestudent_id, 'a.typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, 'stat.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, 'n.note <> ' => 0, - $this->dbTable . '.studiensemester_kurzbz' => $studiensemester_kurzbz, - '(n.note<>' . $this->db->escape($note_intern_angerechntet) . ' OR (z.note IS NOT NULL AND zn.positiv))' => null - ]); + // NOTE(chris): grade "intern angerechnet" needs an official grade beforehand (the subquery gets the last positive offical grade) + "(n.note<>" . $this->db->escape($note_intern_angerechntet) . " OR EXISTS ( + SELECT + 1 + FROM + lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs USING(studiensemester_kurzbz) + JOIN ( + SELECT + zi.lehrveranstaltung_id, + zi.student_uid, + MAX(zis.start) AS start + FROM + lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin USING(note) + LEFT JOIN public.tbl_studiensemester zis USING(studiensemester_kurzbz) + WHERE + zin.aktiv + AND zin.offiziell + GROUP BY + zi.lehrveranstaltung_id, + zi.student_uid + ) zx ON ( + z.lehrveranstaltung_id = zx.lehrveranstaltung_id + AND z.student_uid = zx.student_uid + AND zs.start = zx.start + ) + JOIN lehre.tbl_note zn USING (note) + WHERE + z.lehrveranstaltung_id = lv.lehrveranstaltung_id + AND z.student_uid = s.student_uid + AND zn.positiv + ))" => null + ]; + + if ($studiensemester_kurzbz !== false) + $where[$this->dbTable . '.studiensemester_kurzbz'] = $studiensemester_kurzbz; + + return $this->loadWhere($where); } } diff --git a/application/models/education/Zeugnisnote_model.php b/application/models/education/Zeugnisnote_model.php index b4d909e37..f32713dec 100644 --- a/application/models/education/Zeugnisnote_model.php +++ b/application/models/education/Zeugnisnote_model.php @@ -177,45 +177,63 @@ class Zeugnisnote_model extends DB_Model $params[] = $studiensemester_kurzbz; } - $qry = "SELECT vw_student_lehrveranstaltung.lehrveranstaltung_id, uid, - vw_student_lehrveranstaltung.studiensemester_kurzbz, note, punkte, uebernahmedatum, benotungsdatum, - vw_student_lehrveranstaltung.ects, vw_student_lehrveranstaltung.semesterstunden, - tbl_zeugnisnote.updateamum, tbl_zeugnisnote.updatevon, tbl_zeugnisnote.insertamum, - tbl_zeugnisnote.insertvon, tbl_zeugnisnote.ext_id, - vw_student_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, - vw_student_lehrveranstaltung.bezeichnung_english as lehrveranstaltung_bezeichnung_english, - tbl_note.bezeichnung as note_bezeichnung, - tbl_note.positiv as note_positiv, - tbl_zeugnisnote.bemerkung as bemerkung, - vw_student_lehrveranstaltung.sort, - vw_student_lehrveranstaltung.zeugnis, - vw_student_lehrveranstaltung.studiengang_kz, - vw_student_lehrveranstaltung.lv_lehrform_kurzbz, - tbl_lehrveranstaltung.sws - FROM - ( - campus.vw_student_lehrveranstaltung LEFT JOIN lehre.tbl_zeugnisnote - ON(uid=student_uid - AND vw_student_lehrveranstaltung.studiensemester_kurzbz=tbl_zeugnisnote.studiensemester_kurzbz - AND vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_zeugnisnote.lehrveranstaltung_id - ) - ) LEFT JOIN lehre.tbl_note USING(note) - JOIN lehre.tbl_lehrveranstaltung ON(vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id) - WHERE true $where + $qry = "SELECT + a.*, + lv.lehrform_kurzbz AS lehrveranstaltung_lehrform, + lv.kurzbz AS lehrveranstaltung_kurzbz, + UPPER(stg1.typ || stg1.kurzbz) AS studiengang, + s.studiengang_kz AS studiengang_kz, + UPPER(stg2.typ || stg2.kurzbz) AS studiengang_lv, + lv.studiengang_kz AS studiengang_kz_lv, + lv.semester AS semester_lv, + lv.ects AS ects_lv, + lv.zeugnis, + lv.bezeichnung_english AS lehrveranstaltung_bezeichnung_english + FROM ( + SELECT vw_student_lehrveranstaltung.lehrveranstaltung_id, uid, + vw_student_lehrveranstaltung.studiensemester_kurzbz, note, punkte, uebernahmedatum, benotungsdatum, + vw_student_lehrveranstaltung.ects, vw_student_lehrveranstaltung.semesterstunden, + tbl_zeugnisnote.updateamum, tbl_zeugnisnote.updatevon, tbl_zeugnisnote.insertamum, + tbl_zeugnisnote.insertvon, tbl_zeugnisnote.ext_id, + vw_student_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, + vw_student_lehrveranstaltung.bezeichnung_english as lehrveranstaltung_bezeichnung_english, + tbl_note.bezeichnung as note_bezeichnung, + tbl_note.positiv as note_positiv, + tbl_zeugnisnote.bemerkung as bemerkung, + vw_student_lehrveranstaltung.sort, + vw_student_lehrveranstaltung.zeugnis, + vw_student_lehrveranstaltung.studiengang_kz, + vw_student_lehrveranstaltung.lv_lehrform_kurzbz, + tbl_lehrveranstaltung.sws + FROM + ( + campus.vw_student_lehrveranstaltung LEFT JOIN lehre.tbl_zeugnisnote + ON(uid=student_uid + AND vw_student_lehrveranstaltung.studiensemester_kurzbz=tbl_zeugnisnote.studiensemester_kurzbz + AND vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_zeugnisnote.lehrveranstaltung_id + ) + ) LEFT JOIN lehre.tbl_note USING(note) + JOIN lehre.tbl_lehrveranstaltung ON(vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id) + WHERE true $where - UNION - SELECT lehre.tbl_lehrveranstaltung.lehrveranstaltung_id,student_uid AS uid,studiensemester_kurzbz, note, punkte, - uebernahmedatum, benotungsdatum,lehre.tbl_lehrveranstaltung.ects,lehre.tbl_lehrveranstaltung.semesterstunden, tbl_zeugnisnote.updateamum, tbl_zeugnisnote.updatevon, tbl_zeugnisnote.insertamum, - tbl_zeugnisnote.insertvon, tbl_zeugnisnote.ext_id, lehre.tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, lehre.tbl_lehrveranstaltung.bezeichnung_english as lehrveranstaltung_bezeichnung_english, - tbl_note.bezeichnung as note_bezeichnung, tbl_note.positiv as note_positiv, tbl_zeugnisnote.bemerkung as bemerkung, tbl_lehrveranstaltung.sort, tbl_lehrveranstaltung.zeugnis, tbl_lehrveranstaltung.studiengang_kz, - tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.sws - FROM - lehre.tbl_zeugnisnote - JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) - JOIN lehre.tbl_note USING(note) - WHERE true $where2 + UNION + SELECT lehre.tbl_lehrveranstaltung.lehrveranstaltung_id,student_uid AS uid,studiensemester_kurzbz, note, punkte, + uebernahmedatum, benotungsdatum,lehre.tbl_lehrveranstaltung.ects,lehre.tbl_lehrveranstaltung.semesterstunden, tbl_zeugnisnote.updateamum, tbl_zeugnisnote.updatevon, tbl_zeugnisnote.insertamum, + tbl_zeugnisnote.insertvon, tbl_zeugnisnote.ext_id, lehre.tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, lehre.tbl_lehrveranstaltung.bezeichnung_english as lehrveranstaltung_bezeichnung_english, + tbl_note.bezeichnung as note_bezeichnung, tbl_note.positiv as note_positiv, tbl_zeugnisnote.bemerkung as bemerkung, tbl_lehrveranstaltung.sort, tbl_lehrveranstaltung.zeugnis, tbl_lehrveranstaltung.studiengang_kz, + tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.sws + FROM + lehre.tbl_zeugnisnote + JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) + JOIN lehre.tbl_note USING(note) + WHERE true $where2 - ORDER BY sort"; + ORDER BY sort + ) a + LEFT JOIN public.tbl_student s ON (a.uid = s.student_uid) + LEFT JOIN public.tbl_studiengang stg1 ON (s.studiengang_kz = stg1.studiengang_kz) + LEFT JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) + LEFT JOIN public.tbl_studiengang stg2 ON (lv.studiengang_kz = stg2.studiengang_kz)"; return $this->execQuery($qry, $params); } diff --git a/application/models/organisation/Organisationseinheit_model.php b/application/models/organisation/Organisationseinheit_model.php index 4a64ee055..1b1a826aa 100644 --- a/application/models/organisation/Organisationseinheit_model.php +++ b/application/models/organisation/Organisationseinheit_model.php @@ -189,6 +189,19 @@ class Organisationseinheit_model extends DB_Model return $this->loadWhere($condition); } + /** + * @param string $oe_kurzbz + * + * @return stdClass + */ + public function getWithType($oe_kurzbz) + { + $this->addSelect($this->dbTable . '.*, t.bezeichnung AS organisationseinheittyp'); + $this->addJoin('public.tbl_organisationseinheittyp t', 'organisationseinheittyp_kurzbz'); + + return $this->load($oe_kurzbz); + } + /** * Get OEs by eventQuery string. Use with autocomplete event queries. * @param $eventQuery String diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 4bbb63805..7ea8a901c 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -457,7 +457,7 @@ class Studiengang_model extends DB_Model */ public function getLeitung($studiengang_kz = null) { - $this->addSelect('uid, studiengang_kz, oe_kurzbz, vorname, nachname, email'); + $this->addSelect('uid, studiengang_kz, oe_kurzbz, vorname, nachname, email, titelpre, titelpost, alias'); $this->addJoin('public.tbl_benutzerfunktion', 'oe_kurzbz'); $this->addJoin('public.tbl_benutzer', 'uid'); $this->addJoin('public.tbl_person', 'person_id'); @@ -493,6 +493,53 @@ class Studiengang_model extends DB_Model return $this->loadWhere($condition); } + /** + * Get Studiengangsleitung/en of Studiengang/Studiengaenge. With Details + * + * @param null $studiengang_kz Numeric or Array + * @return array + */ + public function getLeitungDetailed($studiengang_kz = null) + { + $this->addSelect('studiengang_kz, email, f.oe_kurzbz, b.uid, b.alias, b.aktiv, p.vorname, p.nachname, p.titelpre, p.titelpost, m.telefonklappe, k.kontakt, o.planbezeichnung'); + $this->addJoin('public.tbl_benutzerfunktion f', 'oe_kurzbz'); + $this->addJoin('public.tbl_benutzer b', 'uid'); + $this->addJoin('public.tbl_person p', 'person_id'); + $this->addJoin('public.tbl_mitarbeiter m', 'mitarbeiter_uid=uid', 'LEFT'); + $this->addJoin('public.tbl_kontakt k', 'k.standort_id=m.standort_id AND kontakttyp=\'telefon\'', 'LEFT'); + $this->addJoin('public.tbl_ort o', 'ort_kurzbz', 'LEFT'); + + if (!is_numeric($studiengang_kz) && !is_array($studiengang_kz)) + { + return error('Studiengangskennzahl ungültig'); + } + + if (is_null($studiengang_kz)) + { + $condition = ' + funktion_kurzbz = \'Leitung\' + AND ( datum_von <= NOW() OR datum_von IS NULL ) + AND ( datum_bis >= NOW() OR datum_bis IS NULL ) + '; + } + elseif (is_numeric($studiengang_kz) || is_array($studiengang_kz)) + { + if (is_array($studiengang_kz)) + { + $studiengang_kz = array_map(array($this,'escape'), $studiengang_kz); + $studiengang_kz = implode(', ', $studiengang_kz); + } + $condition = ' + funktion_kurzbz = \'Leitung\' + AND ( datum_von <= NOW() OR datum_von IS NULL ) + AND ( datum_bis >= NOW() OR datum_bis IS NULL ) + AND studiengang_kz IN (' . $studiengang_kz. ')'; + ; + } + + return $this->loadWhere($condition); + } + public function getStudiengaengeWithOrgForm($typ, $semester) { $query = "SELECT DISTINCT (UPPER(so.studiengangkurzbzlang || ':' || sp.orgform_kurzbz)) AS Studiengang @@ -600,4 +647,135 @@ class Studiengang_model extends DB_Model return $this->load(); } + + /** + * @return stdClass + */ + public function getStudiengangInfoForNews() + { + + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + + $addEmailProperty= function(&$benutzerfunktionen){ + if(count($benutzerfunktionen) && defined('DOMAIN')) + { + $benutzerfunktionen = array_map(function($benutzer) + { + $benutzer->email = $benutzer->alias."@".DOMAIN; + return $benutzer; + },$benutzerfunktionen) ; + } + + }; + $addFotoProperty= function(&$collection){ + $collection = array_map(function($item){ + $person_id = $this->PersonModel->getByUid($item->uid); + if(isError($person_id)) + return error($person_id); + $person_id = current(getData($person_id))->person_id; + $this->PersonModel->addSelect('foto'); + $foto = $this->PersonModel->loadWhere(array('person_id'=>$person_id)); + if(isError($foto)) + return error($foto); + $foto = current(getData($foto))->foto; + $item->foto = $foto; + return $item; + },$collection); + }; + + + $this->load->model('crm/Student_model', 'StudentModel'); + + $student = $this->StudentModel->loadWhere(['student_uid' => getAuthUID()]); + if (isError($student)) + return error($student); + if (getData($student)) { + $student = current(getData($student)); + $studiengang_kz = $student->studiengang_kz; + $semester = $student->semester; + } + + $stg_obj = $this->load($studiengang_kz); + if(isError($stg_obj)) + return error($stg_obj); + if(getData($stg_obj)) + { + $stg_obj = current(getData($stg_obj)); + } + + $stg_ltg = $this->getLeitungDetailed($stg_obj->studiengang_kz); + if (isError($stg_ltg)) + return $stg_ltg; + $stg_ltg = getData($stg_ltg) ?: []; + $addFotoProperty($stg_ltg); + + $gf_ltg = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('gLtg', $stg_obj->oe_kurzbz); + if (isError($gf_ltg)) + return $gf_ltg; + $gf_ltg = getData($gf_ltg) ?: []; + $addEmailProperty($gf_ltg); + + $stv_ltg = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stvLtg', $stg_obj->oe_kurzbz); + if (isError($stv_ltg)) + return $stv_ltg; + $stv_ltg = getData($stv_ltg) ?: []; + $addEmailProperty($stv_ltg); + + $ass = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('ass', $stg_obj->oe_kurzbz); + if (isError($ass)) + return $ass; + $ass = getData($ass) ?: []; + $addEmailProperty($ass); + $addFotoProperty($ass); + + $hochschulvertr = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('hsv'); + if (isError($hochschulvertr)) + return $hochschulvertr; + $hochschulvertr = getData($hochschulvertr) ?: []; + $addEmailProperty($hochschulvertr); + + + $stdv = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stdv', $stg_obj->oe_kurzbz); + if (isError($stdv)) + return $stdv; + $stdv = getData($stdv) ?: []; + $addEmailProperty($stdv); + + + $jahrgangsvertr = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('jgv', $stg_obj->oe_kurzbz, $semester); + if (isError($jahrgangsvertr)) + return $jahrgangsvertr; + $jahrgangsvertr = getData($jahrgangsvertr) ?: []; + $addEmailProperty($jahrgangsvertr); + + + $result_object = new stdClass(); + $result_object->studiengang = $stg_obj; + $result_object->semester = $semester; + $result_object->stg_ltg = $stg_ltg; + $result_object->gf_ltg = $gf_ltg; + $result_object->stv_ltg = $stv_ltg; + $result_object->ass = $ass; + $result_object->hochschulvertr = $hochschulvertr; + $result_object->stdv = $stdv; + $result_object->jahrgangsvertr = $jahrgangsvertr; + + return success($result_object); + } + + public function getLvaForStudiengangInStudiensemester($studiengang_kz, $orgform_kurzbz, $studiensemester_kurzbz) { + $qry = ' + SELECT DISTINCT ON (lehre.tbl_lehrveranstaltung.lehrveranstaltung_id, + kurzbz, bezeichnung, semester, + lehre.tbl_lehrveranstaltung.sprache, orgform_kurzbz, + lehre.tbl_lehrveranstaltung.lehrform_kurzbz) + lehre.tbl_lehrveranstaltung.lehrveranstaltung_id, kurzbz, bezeichnung, + semester, lehre.tbl_lehrveranstaltung.sprache, orgform_kurzbz, lehre.tbl_lehrveranstaltung.lehrform_kurzbz + FROM lehre.tbl_lehrveranstaltung JOIN lehre.tbl_lehreinheit USING(lehrveranstaltung_id) JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id) + WHERE aktiv = TRUE AND studiengang_kz = ? AND orgform_kurzbz = ? AND tbl_lehreinheit.studiensemester_kurzbz IN ?'; + + return $this->execReadOnlyQuery($qry, array($studiengang_kz, $orgform_kurzbz, $studiensemester_kurzbz)); + } } diff --git a/application/models/organisation/Studienjahr_model.php b/application/models/organisation/Studienjahr_model.php index a6e1bc575..1686ddc48 100644 --- a/application/models/organisation/Studienjahr_model.php +++ b/application/models/organisation/Studienjahr_model.php @@ -1,4 +1,5 @@ execQuery($query); } + public function getNextStudienjahr() + { + $this->addJoin('public.tbl_studiensemester', 'studienjahr_kurzbz'); + $this->addOrder('start'); + $this->addLimit(1); + + return $this->loadWhere(['start >' => 'NOW()']); + } + public function getNextFrom($studienjahr_kurzbz) + { + $this->addLimit(1); + + return $this->loadWhere([ + 'studienjahr_kurzbz >' => $studienjahr_kurzbz + ]); + } /** * Get the current Studienjahr. During the summer term, continue using the previous Studienjahr. @@ -38,8 +55,7 @@ class Studienjahr_model extends DB_Model */ public function getLastOrAktStudienjahr($days = 60) { - if (!is_numeric($days)) - { + if (!is_numeric($days)) { $days = 60; } @@ -63,8 +79,7 @@ class Studienjahr_model extends DB_Model */ public function getAktOrNextStudienjahr($days = 62) { - if (!is_numeric($days)) - { + if (!is_numeric($days)) { $days = 62; } diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php index c59c9d343..f29ab223c 100644 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -170,13 +170,31 @@ class Studiensemester_model extends DB_Model return $this->execQuery($query, array($studiensemester_kurzbz, $studiengang_kz)); } + /** + * Gets a Studiensemester for a date + * @param $date + * @return string + */ + public function getByDate($date) + { + // gets the studiensemster of a date or the next closest previous studiensemester if a date is not within a studiensemester + $query = " + SELECT studiensemester_kurzbz, start, ende + FROM public.tbl_studiensemester + WHERE ( ende >= ?::date AND start <= ?::date ) OR ( ende >= ?::date + '-45 days'::interval AND start <= ?::date + '-45 days'::interval ) + ORDER BY start DESC + LIMIT 1"; + + return $this->execQuery($query, array($date,$date,$date,$date)); + } + /** * Gets all Studiensemester between two dates * @param $from * @param $to * @return array|null */ - public function getByDate($from, $to) + public function getByDateRange($from, $to) { if (date_format(date_create($from), 'Y-m-d') > (date_format(date_create($to), 'Y-m-d'))) return success(array()); @@ -205,6 +223,25 @@ class Studiensemester_model extends DB_Model return $this->execQuery($query, array($studiensemester_kurzbz)); } + /** + * @param string $student_uid + * + * @return StdClass + */ + public function getWhereStudentHasLvs($student_uid) + { + $this->addDistinct(); + $this->addSelect($this->dbTable . '.*'); + + // TODO(chris): Potentielle Anpassung "Eine UID" + $this->addJoin('campus.vw_student_lehrveranstaltung v', 'studiensemester_kurzbz'); + $this->db->where("v.lehreverzeichnis<>''"); + + $this->addOrder($this->dbTable . '.start'); + + return $this->loadWhere(['uid' => $student_uid, 'v.lehre' => true]); + } + public function getAktAndFutureSemester() { $query = 'SELECT studiensemester_kurzbz @@ -253,4 +290,55 @@ class Studiensemester_model extends DB_Model if (is_numeric($studienjahrNumber) && mb_substr($studiensemester_kurzbz, 0, 2) == 'SS') (int)$studienjahrNumber -= 1; return $studienjahrNumber; } + + /** + * Get Studienjahr by Studiensemester. + * + * @param $studiensemester_kurzbz + * @return array|stdClass + */ + public function getStudienjahrByStudiensemester($studiensemester_kurzbz) + { + $studienjahrObj = null; + + if (!is_numeric($studiensemester_kurzbz)) + { + $this->StudiensemesterModel->addSelect('studienjahr_kurzbz'); + $result = $this->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz =' => $studiensemester_kurzbz)); + } + + if (hasData($result)) + { + $studienjahr = getData($result)[0]->studienjahr_kurzbz; + $startstudienjahr = substr($studienjahr, 0, 4); + $endstudienjahr = substr($studienjahr, 0, 2) . substr($studienjahr, -2); + + $studienjahrObj = new StdClass(); + + $studienjahrObj->studienjahr_kurzbz = $studienjahr; + $studienjahrObj->startstudienjahr = $startstudienjahr; + $studienjahrObj->endstudienjahr= $endstudienjahr; + } + + if (isError($result)) { + return error(getError($result)); + } + + return success($studienjahrObj); + } + + /** + * Holt Start und Ende des Studiensemester_kurzbz + * @param studiensemester_kurzbz + * @return stdClass + */ + public function getStartEndeFromStudiensemester($studiensemester_kurzbz) + { + return $this->execReadOnlyQuery(" + SELECT + start, ende + FROM public.tbl_studiensemester + WHERE studiensemester_kurzbz = ?",[$studiensemester_kurzbz]); + + } } diff --git a/application/models/person/Benutzerfunktion_model.php b/application/models/person/Benutzerfunktion_model.php index e44281a92..8c43e4f84 100644 --- a/application/models/person/Benutzerfunktion_model.php +++ b/application/models/person/Benutzerfunktion_model.php @@ -50,6 +50,53 @@ class Benutzerfunktion_model extends DB_Model return $this->execQuery($qry, $params); } + /** + * Lädt alle Benutzerfunktionen zu einer UID im Zeitraum eines Studiensemesters + * + * @param string $uid + * @param string $stdsem + * @param string $funktion_kurzbz (optional) + * + * @return stdClass + */ + public function getBenutzerFunktionByUidInStdsem($uid, $stdsem, $funktion_kurzbz = null) + { + $stdsemEscaped = $this->escape($stdsem); + $this->addSelect($this->dbTable . ".*"); + $this->addSelect("oe.bezeichnung AS organisationseinheit_bezeichnung"); + $this->addSelect("oe.organisationseinheittyp_kurzbz"); + + $this->addJoin("public.tbl_organisationseinheit oe", "oe_kurzbz"); + + $this->db->where("uid", $uid); + + if ($funktion_kurzbz !== null) + $this->db->where("funktion_kurzbz", $funktion_kurzbz); + + $this->db->group_start(); + $this->db->where("datum_bis IS NULL"); + $this->db->or_where("datum_bis >=", "( + SELECT start + FROM public.tbl_studiensemester + WHERE studiensemester_kurzbz = " . $stdsemEscaped . " + )", false); + $this->db->group_end(); + + $this->db->group_start(); + $this->db->where("datum_von IS NULL"); + $this->db->or_where("datum_von <=", "( + SELECT ende + FROM public.tbl_studiensemester + WHERE studiensemester_kurzbz = " . $stdsemEscaped . " + )", false); + $this->db->group_end(); + + $this->addOrder("datum_bis", "NULLS LAST"); + $this->addOrder("datum_von", "NULLS LAST"); + + return $this->load(); + } + /** * Get the Benutzerfunktion using the person_id */ @@ -147,6 +194,38 @@ class Benutzerfunktion_model extends DB_Model return $this->execQuery($query, $parametersArray); } + /** + * Gets all Benutzer with details for a given Benutzerfunktion and optionally specified Oe and semester + * + * @param string $funktion_kurzbz + * @param string $oe_kurzbz + * @param integer | null $semester + * @return array|null + */ + public function getBenutzerFunktionenDetailed($funktion_kurzbz, $oe_kurzbz = null, $semester = null) + { + $this->addSelect($this->dbTable . '.funktion_kurzbz, ' . $this->dbTable . '.oe_kurzbz, ' . $this->dbTable . '.semester, ' . $this->dbTable . '.bezeichnung, f.beschreibung, b.uid, b.alias, b.aktiv, p.vorname, p.nachname, p.titelpre, p.titelpost, m.telefonklappe, k.kontakt, o.planbezeichnung'); + $this->addJoin('public.tbl_funktion f', 'funktion_kurzbz'); + $this->addJoin('public.tbl_benutzer b', 'uid'); + $this->addJoin('public.tbl_person p', 'person_id'); + $this->addJoin('public.tbl_mitarbeiter m', 'mitarbeiter_uid=uid', 'LEFT'); + $this->addJoin('public.tbl_kontakt k', 'k.standort_id=m.standort_id AND kontakttyp=\'telefon\'', 'LEFT'); + $this->addJoin('public.tbl_ort o', 'ort_kurzbz', 'LEFT'); + + $this->addOrder('LOWER(uid)'); + + $where = [$this->dbTable . '.funktion_kurzbz' => $funktion_kurzbz]; + if ($oe_kurzbz !== null) + $where[$this->dbTable . '.oe_kurzbz'] = $oe_kurzbz; + if ($semester !== null) + $where[$this->dbTable . '.semester'] = $semester; + + $this->db->where('(' . $this->dbTable . '.datum_bis >= NOW() OR ' . $this->dbTable . '.datum_bis IS NULL)', NULL, FALSE); + $this->db->where('(' . $this->dbTable . '.datum_von <= NOW() OR ' . $this->dbTable . '.datum_von IS NULL)', NULL, FALSE); + + return $this->loadWhere($where); + } + /** * Get active Studiengangsleitung(en) of the user by UID. * @param $uid diff --git a/application/models/person/Benutzergruppe_model.php b/application/models/person/Benutzergruppe_model.php index e569094c4..fba797641 100644 --- a/application/models/person/Benutzergruppe_model.php +++ b/application/models/person/Benutzergruppe_model.php @@ -12,4 +12,25 @@ class Benutzergruppe_model extends DB_Model $this->pk = array('gruppe_kurzbz', 'uid'); $this->hasSequence = false; } + + /** + * Laedt die User in einer Benutzergruppe + * @param gruppe_kurzbz, stsem + * @return array + */ + public function getUids($gruppe_kurzbz, $stsem) + { + $query = " + SELECT + uid + FROM + public.tbl_benutzergruppe + WHERE + gruppe_kurzbz = " . $this->escape($gruppe_kurzbz) . " + AND studiensemester_kurzbz = " . $this->escape($stsem); + + $res = $this->execReadOnlyQuery($query); + $uids = (hasData($res)) ? getData($res) : array(); + return $uids; + } } diff --git a/application/models/person/Gruppe_manager_model.php b/application/models/person/Gruppe_manager_model.php new file mode 100644 index 000000000..93d45bd1f --- /dev/null +++ b/application/models/person/Gruppe_manager_model.php @@ -0,0 +1,14 @@ +dbTable = 'public.tbl_gruppe_manager'; + $this->pk = 'gruppe_manager_id'; + } +} diff --git a/application/models/person/Notiz_model.php b/application/models/person/Notiz_model.php index 349eaac60..2e99d1cdd 100644 --- a/application/models/person/Notiz_model.php +++ b/application/models/person/Notiz_model.php @@ -142,7 +142,7 @@ class Notiz_model extends DB_Model $this->addSelect('public.tbl_notiz.*'); $this->addJoin('public.tbl_notizzuordnung', 'notiz_id'); - return $this->loadWhere(array('person_id' => $person_id)); + return $this->loadWhere(array('person_id' => $person_id, 'tbl_notiz.typ' => NULL)); } /** @@ -156,10 +156,10 @@ class Notiz_model extends DB_Model $qry = " SELECT n.*, count(dms_id) as countDoc, z.notizzuordnung_id, - TO_CHAR (CASE + (CASE WHEN n.updateamum >= n.insertamum THEN n.updateamum ELSE n.insertamum - END::timestamp, 'DD.MM.YYYY HH24:MI:SS') AS lastUpdate, + END) AS lastUpdate, regexp_replace(n.text, '<[^>]*>', '', 'g') as text_stripped, TO_CHAR(n.start::timestamp, 'DD.MM.YYYY') AS start_format, TO_CHAR(n.ende::timestamp, 'DD.MM.YYYY') AS ende_format, diff --git a/application/models/person/Person_model.php b/application/models/person/Person_model.php index dc925a171..997048972 100644 --- a/application/models/person/Person_model.php +++ b/application/models/person/Person_model.php @@ -290,6 +290,21 @@ class Person_model extends DB_Model return success($result->vorname. ' '. $result->nachname); } + /** + * Get first name of given uid. (Vorname Nachname) + * @param $uid + * @return array + */ + public function getFirstName($uid) + { + $result = getData($this->getByUid($uid))[0]; + if (!$result) { + show_error('Failed loading person'); + } + + return success($result->vorname); + } + public function checkDuplicate($person_id) { $qry = "SELECT person_id diff --git a/application/models/person/Profil_update_model.php b/application/models/person/Profil_update_model.php new file mode 100644 index 000000000..ffb04b7e7 --- /dev/null +++ b/application/models/person/Profil_update_model.php @@ -0,0 +1,187 @@ +dbTable = 'public.tbl_profil_update'; + $this->pk = ['profil_update_id']; + $this->hasSequence = true; + + + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $this->load->library('PermissionLib'); + } + + /** + * getTimestamp + * returns insert or update timestamp of a certain profil update + * + * @param boolean $update: conditional whether to return insertamum or updateamum + */ + //TODO: function wird nicht verwendet + public function getTimestamp($id, $update = false) + { + $selectStatement = $update ? 'updateamum' : 'insertamum'; + $this->addSelect([$selectStatement]); + $res = $this->load([$id]); + return hasData($res) ? getData($res)[0]->$selectStatement : null; + } + + /** + * getFilesFromChangeRequest + * + * returns all files associated to a profil update request in the following format: + * {dms_id:123 , name:"test"} + * + * @param boolean $profil_update_id primary key of the profil update request + * @return array + */ + //TODO: function wird nicht verwendet + public function getFilesFromChangeRequest($profil_update_id) + { + $this->addSelect(["requested_change"]); + $res = $this->load([$profil_update_id]); + $res = hasData($res) ? getData($res)[0] : null; + return json_decode($res->requested_change)->files ?: []; + } + + + //? queries the tbl_profil_updates without permissions of the user + public function getProfilUpdatesWhere($whereClause) + { + if (array_key_exists("uid", $whereClause)) { + $whereClause["public.tbl_profil_update.uid"] = $whereClause["uid"]; + unset($whereClause["uid"]); + } + $this->addSelect(["public.tbl_profil_update.*", "public.tbl_person.vorname"]); + $this->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_profil_update.uid"); + $this->addJoin("public.tbl_person", "public.tbl_person.person_id = public.tbl_benutzer.person_id"); + $res = $this->loadWhere($whereClause); + if (isError($res)) { + return $res; + } + if (hasData($res)) { + foreach (getData($res) as $request) { + $this->formatProfilRequest($request); + } + } + + return $res; + + } + + //? remove File from the Profil Update + public function removeFileFromProfilUpdate($dms_id) + { + + if(!is_int($dms_id) || $dms_id < 0){ + return error("not valid dms_id"); + } + + return $this->execReadOnlyQuery(" + UPDATE public.tbl_profil_update + SET attachment_id = NULL + WHERE attachment_id = ?", [$dms_id]); + + } + + + /** + * getProfilUpdateWithPermission + * + * queries the profil updates and checks if the user trying to query the data has permissions to get the profil updates + * + * @param string $whereClause additional where clause that will be appended to the db query + * @return array array with all the profil updates that the user is eligible to see + */ + public function getProfilUpdateWithPermission($whereClause = null) + { + + $studentBerechtigung = $this->permissionlib->isBerechtigt('student/stammdaten', 's'); + $mitarbeiterBerechtigung = $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', 's'); + $oe_berechtigung = $this->permissionlib->getOE_isEntitledFor('student/stammdaten'); + + $lang = "select index from public.tbl_sprache where sprache =" . $this->escape(getUserLanguage()); + $res = []; + + if ($studentBerechtigung) { + + + //? Nur wenn der/die AssistentIn auch die Berechtigung in der gleichen Organisationseinheit des Studenten hat + $parameters = []; + $query = " + SELECT + profil_update_id, tbl_profil_update.uid, (tbl_person.vorname || ' ' || tbl_person.nachname) AS name , topic, requested_change, tbl_profil_update.updateamum, tbl_profil_update.updatevon, tbl_profil_update.insertamum, tbl_profil_update.insertvon, status, public.tbl_profil_update_status.bezeichnung_mehrsprachig[(" . $lang . ")] as status_translated, status_timestamp, status_message, attachment_id + FROM public.tbl_profil_update + JOIN public.tbl_profil_update_status ON public.tbl_profil_update_status.status_kurzbz = public.tbl_profil_update.status + JOIN public.tbl_student ON public.tbl_student.student_uid=public.tbl_profil_update.uid + JOIN public.tbl_benutzer ON public.tbl_benutzer.uid = public.tbl_student.student_uid + JOIN public.tbl_person ON public.tbl_benutzer.person_id=public.tbl_person.person_id + JOIN public.tbl_studiengang ON public.tbl_studiengang.studiengang_kz=public.tbl_student.studiengang_kz + Where public.tbl_studiengang.oe_kurzbz IN ? "; + $parameters[] = $oe_berechtigung; + if ($whereClause) { + foreach ($whereClause as $key => $value) { + $parameters[] = $value; + $query .= " AND " . $key . " = ?"; + } + } + + $studentRequests = $this->execReadOnlyQuery($query, $parameters); + + if (isError($studentRequests)) + return error("db error: " . getData($studentRequests)); + $studentRequests = getData($studentRequests) ?: []; + foreach ($studentRequests as $request) { + array_push($res, $request); + } + } + if ($mitarbeiterBerechtigung) { + $this->addSelect(["profil_update_id", "tbl_profil_update.uid", "(tbl_person.vorname || ' ' || tbl_person.nachname) AS name", "topic", "requested_change", "tbl_profil_update.updateamum", "tbl_profil_update.updatevon", "tbl_profil_update.insertamum", "tbl_profil_update.insertvon", "status", "public.tbl_profil_update_status.bezeichnung_mehrsprachig[(" . $lang . ")] AS status_translated", "status_timestamp", "status_message", "attachment_id"]); + $this->addJoin('tbl_profil_update_status', 'tbl_profil_update_status.status_kurzbz=tbl_profil_update.status'); + $this->addJoin('tbl_mitarbeiter', 'tbl_mitarbeiter.mitarbeiter_uid=tbl_profil_update.uid'); + $this->addJoin('tbl_benutzer', 'tbl_benutzer.uid=tbl_profil_update.uid'); + $this->addJoin('tbl_person', 'tbl_benutzer.person_id=tbl_person.person_id'); + $mitarbeiterRequests = $this->loadWhere($whereClause); + if (isError($mitarbeiterRequests)) + return error("db error: " . getData($mitarbeiterRequests)); + $mitarbeiterRequests = getData($mitarbeiterRequests) ?: []; + foreach ($mitarbeiterRequests as $request) { + array_push($res, $request); + } + } + if ($res) { + + foreach ($res as $request) { + $this->formatProfilRequest($request); + } + } + + return $res; + + } + + /** + * formatProfilRequest + * + * formats the the properties of a profilUpdate request row result + * + * @param stdClass $request unflitered profilUpdate row result from the database + * @return void + */ + private function formatProfilRequest($request) + { + $request->requested_change = json_decode($request->requested_change); + $request->insertamum = !is_null($request->insertamum) ? date_create($request->insertamum)->format('d.m.Y') : null; + $request->updateamum = !is_null($request->updateamum) ? date_create($request->updateamum)->format('d.m.Y') : null; + $request->status_timestamp = !is_null($request->status_timestamp) ? date_create($request->status_timestamp)->format('d.m.Y') : null; + } + +} diff --git a/application/models/person/Profil_update_status_model.php b/application/models/person/Profil_update_status_model.php new file mode 100644 index 000000000..e69f9a047 --- /dev/null +++ b/application/models/person/Profil_update_status_model.php @@ -0,0 +1,18 @@ +dbTable = 'public.tbl_profil_update_status'; + $this->pk = ['status_kurzbz']; + $this->hasSequence = false; + + + + } +} \ No newline at end of file diff --git a/application/models/person/Profil_update_topic_model.php b/application/models/person/Profil_update_topic_model.php new file mode 100644 index 000000000..0b7ad61e3 --- /dev/null +++ b/application/models/person/Profil_update_topic_model.php @@ -0,0 +1,16 @@ +dbTable = 'public.tbl_profil_update_topic'; + $this->pk = ['topic_kurzbz']; + $this->hasSequence = false; + + } +} \ No newline at end of file diff --git a/application/models/project/Projects_employees_model.php b/application/models/project/Projects_employees_model.php new file mode 100644 index 000000000..a12e3961c --- /dev/null +++ b/application/models/project/Projects_employees_model.php @@ -0,0 +1,22 @@ +dbTable = 'sync.tbl_projects_employees'; + $this->pk = 'projects_employees_id'; + } + + public function deleteByProjectTaskId($ids) + { + $qry = "DELETE FROM " . $this->dbTable . " + WHERE project_task_id IN ?"; + + return $this->execQuery($qry, array($ids)); + } +} diff --git a/application/models/ressource/Betriebsmittelperson_model.php b/application/models/ressource/Betriebsmittelperson_model.php index 39f08b5cd..6da9a384d 100644 --- a/application/models/ressource/Betriebsmittelperson_model.php +++ b/application/models/ressource/Betriebsmittelperson_model.php @@ -115,13 +115,18 @@ class Betriebsmittelperson_model extends DB_Model $query = " SELECT - bm.nummer, bmp.person_id, bm.betriebsmitteltyp, bmp.anmerkung as anmerkung, bmp.retouram, TO_CHAR(bmp.retouram::timestamp, 'DD.MM.YYYY') AS format_retour, bmp.ausgegebenam, TO_CHAR(bmp.ausgegebenam::timestamp, 'DD.MM.YYYY') AS format_ausgabe, bm.beschreibung, bmp.uid, bmp.kaution, bm.betriebsmittel_id, bmp.betriebsmittelperson_id, bm.inventarnummer, bm.nummer2 + bm.nummer, bmp.person_id, bm.betriebsmitteltyp, bmp.anmerkung as anmerkung, + bmp.retouram, + bmp.ausgegebenam, + bm.beschreibung, bmp.uid, bmp.kaution, + bm.betriebsmittel_id, bmp.betriebsmittelperson_id, + bm.inventarnummer, bm.nummer2 FROM - wawi.tbl_betriebsmittelperson bmp + wawi.tbl_betriebsmittelperson bmp JOIN - wawi.tbl_betriebsmittel bm ON (bmp.betriebsmittel_id = bm.betriebsmittel_id) + wawi.tbl_betriebsmittel bm ON (bmp.betriebsmittel_id = bm.betriebsmittel_id) WHERE - " . $cond . " = ? "; + " . $cond . " = ? "; return $this->execQuery($query, array($id)); } diff --git a/application/models/ressource/Lehretools_model.php b/application/models/ressource/Lehretools_model.php new file mode 100644 index 000000000..69d9f6555 --- /dev/null +++ b/application/models/ressource/Lehretools_model.php @@ -0,0 +1,62 @@ +dbTable = 'campus.tbl_lehre_tools'; + $this->pk = 'lehre_tools_id'; + } + + /** + * + * Laedt die Tools zu einer Lehrveranstaltung + * @param $lehrveranstaltung_id + * @param $studiensemester_kurzbz + */ + public function getTools($lehrveranstaltung_id, $studiensemester_kurzbz, $sprache) + { + $query = "SELECT + lehre_tools_id, + bezeichnung[(SELECT index FROM public.tbl_sprache WHERE sprache = " . $this->escape($sprache) . ")] AS bezeichnung, + kurzbz, + basis_url, + logo_dms_id + FROM + campus.tbl_lehre_tools + JOIN campus.tbl_lehre_tools_organisationseinheit USING(lehre_tools_id) + WHERE + campus.tbl_lehre_tools_organisationseinheit.aktiv AND + ( + oe_kurzbz IN( + SELECT + tbl_studiengang.oe_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE + tbl_lehrveranstaltung.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id)) . " + ) + OR + oe_kurzbz IN( + SELECT + lehrfach.oe_kurzbz + FROM + lehre.tbl_lehreinheit + JOIN lehre.tbl_lehrveranstaltung as lehrfach ON(lehrfach_id=lehrfach.lehrveranstaltung_id) + WHERE + tbl_lehreinheit.studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . " + AND tbl_lehreinheit.lehrveranstaltung_id = " . $this->escape(intval($lehrveranstaltung_id)) . " + ) + ) + ORDER BY lehre_tools_id"; + + $toolsres = $this->execReadOnlyQuery($query); + $tools = (hasData($toolsres)) ? getData($toolsres) : array(); + + return $tools; + } +} \ No newline at end of file diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php index c38fcf054..836f5d65a 100644 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -217,12 +217,28 @@ class Mitarbeiter_model extends DB_Model return success($kurzbz); } - public function searchMitarbeiter($filter) + /** + * Search function for mitarbeiter + * @param $filter searchstring: searches for nachname, vorname, mitarbeiter_uid + * $param $mode gives the resultobject in different version: + * null : "[mitarbeiter_uid], Nachname, Vorname, (mitarbeiter_uid)" + * 'mitAkadGrad': "[mitarbeiter_uid], Nachname, Vorname, Titelpre, Titelpost (mitarbeiter_uid)" + * 'ohneMaUid' : "[mitarbeiter_uid], Nachname, Vorname, Titelpre, Titelpost" + * @return object in 3 versions + */ + public function searchMitarbeiter($filter, $mode=null) { $filter = strtoLower($filter); + + if ($mode == "mitAkadGrad") + $returnwert = "ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' ', p.titelpost, ' ', p.titelpre, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter"; + elseif ($mode == "ohneMaUid") + $returnwert = "p.person_id, CONCAT(p.nachname, ' ', p.vorname, ' ', p.titelpost, ' ', p.titelpre) as mitarbeiter"; + else + $returnwert = "ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter"; + $qry = " - SELECT - ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter + SELECT " . $returnwert . " FROM public.tbl_mitarbeiter ma JOIN @@ -238,4 +254,28 @@ class Mitarbeiter_model extends DB_Model return $this->execQuery($qry); } + + /** + * Gets Mitarbeiter for a certain Lehrveranstaltung. + * + * @param $lehrveranstaltung_id + * @return array with Mitarbeiter and their Lehreinheiten + */ + public function getMitarbeiterFromLV($lehrveranstaltung_id){ + //TODO(manu) maybe filter that in pruefungslist.js ? + $qry = "SELECT DISTINCT + lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid + FROM + lehre.tbl_lehreinheitmitarbeiter, campus.vw_mitarbeiter, lehre.tbl_lehreinheit + WHERE + lehrveranstaltung_id= ? + AND + mitarbeiter_uid=uid + AND + tbl_lehreinheitmitarbeiter.lehreinheit_id=tbl_lehreinheit.lehreinheit_id;"; + + $parametersArray = array($lehrveranstaltung_id); + + return $this->execQuery($qry, $parametersArray); + } } diff --git a/application/models/ressource/Ort_model.php b/application/models/ressource/Ort_model.php index 59b213a54..de0c8e331 100644 --- a/application/models/ressource/Ort_model.php +++ b/application/models/ressource/Ort_model.php @@ -20,4 +20,16 @@ class Ort_model extends DB_Model return $this->OrtModel->loadWhere(array("raumtyp_kurzbz" => $raumtyp_kurzbz)); } + + public function getContentID($ort_kurzbz) + { + + return $this->execReadOnlyQuery(" + SELECT content_id + FROM public.tbl_ort + WHERE ort_kurzbz = ?; + ",[$ort_kurzbz]); + + } + } \ No newline at end of file diff --git a/application/models/ressource/Reservierung_model.php b/application/models/ressource/Reservierung_model.php index 37d0cb376..f635d0cb1 100644 --- a/application/models/ressource/Reservierung_model.php +++ b/application/models/ressource/Reservierung_model.php @@ -11,4 +11,129 @@ class Reservierung_model extends DB_Model $this->dbTable = 'campus.tbl_reservierung'; $this->pk = 'reservierung_id'; } + + + /** + * @param $uid + * + * @return stdClass + */ + public function getReservierungen($start_date, $end_date, $ort_kurzbz = null) + { + + $stundenplan_reservierungen_query="SELECT r.* , stund.beginn, stund.ende, + CASE + WHEN r.gruppe_kurzbz IS NOT NULL THEN r.gruppe_kurzbz + ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(r.semester AS varchar),'/'),COALESCE(CAST(r.verband AS varchar),'/')) + END as gruppen_kuerzel + FROM campus.vw_reservierung r + JOIN public.tbl_studiengang studg ON studg.studiengang_kz=r.studiengang_kz + JOIN lehre.tbl_stunde stund ON stund.stunde = r.stunde + LEFT JOIN public.tbl_benutzergruppe bg ON r.gruppe_kurzbz=bg.gruppe_kurzbz AND bg.uid=? + LEFT JOIN public.tbl_studiensemester ss1 ON bg.studiensemester_kurzbz=ss1.studiensemester_kurzbz AND ss1.start <= r.datum AND ss1.ende >= r.datum + LEFT JOIN public.tbl_studentlehrverband slv ON r.studiengang_kz=slv.studiengang_kz AND slv.student_uid=? AND (slv.semester=r.semester OR r.semester IS NULL) AND (slv.verband=r.verband OR r.verband IS NULL OR r.verband='' OR r.verband='0') AND (slv.gruppe=r.gruppe OR r.gruppe IS NULL OR r.gruppe ='' OR r.gruppe ='0') AND r.gruppe_kurzbz IS NULL + LEFT JOIN public.tbl_studiensemester ss2 ON slv.studiensemester_kurzbz = ss2.studiensemester_kurzbz AND ss2.start <=r.datum AND ss2.ende >= r.datum + WHERE datum >= ? AND datum <= ? AND (ss1.studiensemester_kurzbz IS NOT NULL + OR ss2.studiensemester_kurzbz IS NOT NULL)"; + + $raum_reservierungen_query = "SELECT res.*, beginn, ende, + CASE + WHEN res.gruppe_kurzbz IS NOT NULL THEN res.gruppe_kurzbz + ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/')) + END as gruppen_kuerzel + FROM campus.vw_reservierung res + JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz + JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = res.stunde + WHERE res.ort_kurzbz = ? AND datum >= ? AND datum <= ?"; + + $subquery = is_null($ort_kurzbz)? $stundenplan_reservierungen_query:$raum_reservierungen_query; + + $query_result= $this->execReadOnlyQuery(" + SELECT + 'reservierung' as type, beginn, ende, datum, + COALESCE(titel, beschreibung) as topic, + array_agg(DISTINCT mitarbeiter_kurzbz) as lektor, + array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe, + + ort_kurzbz, 'FFFFFF' as farbe + + FROM + ( + ". $subquery ." + ) AS subquery + + GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung + + ORDER BY datum, beginn + ", is_null($ort_kurzbz) ?[getAuthUID(), getAuthUID(),$start_date,$end_date]: [$ort_kurzbz, $start_date, $end_date]); + + + return $query_result; + } + + /** + * @param $uid + * + * @return stdClass + */ + public function getReservierungenMitarbeiter($start_date, $end_date, $ort_kurzbz = null) + { + + $raum_reservierungen_query = "SELECT res.*, beginn, ende, + CASE + WHEN res.gruppe_kurzbz IS NOT NULL THEN res.gruppe_kurzbz + ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/')) + END as gruppen_kuerzel + FROM campus.vw_reservierung res + JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz + JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = res.stunde + WHERE res.uid = ? AND datum >= ? AND datum <= ?"; + +// $subquery = is_null($ort_kurzbz)? $stundenplan_reservierungen_query:$raum_reservierungen_query; + $subquery = $raum_reservierungen_query; + + + $query_result= $this->execReadOnlyQuery(" + SELECT + 'reservierung' as type, beginn, ende, datum, + COALESCE(titel, beschreibung) as topic, + array_agg(DISTINCT mitarbeiter_kurzbz) as lektor, + array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe, + + ort_kurzbz, 'FFFFFF' as farbe + + FROM + ( + ". $subquery ." + ) AS subquery + + GROUP BY datum, beginn, ende, ort_kurzbz, titel, beschreibung + + ORDER BY datum, beginn + ", [getAuthUID(), $start_date, $end_date]); + + + return $query_result; + } + + /** + * @param $uid + * + * @return stdClass + */ + public function loadForUid($uid) + { + $this->addSelect('r.*'); + $this->db->join('public.tbl_benutzergruppe bg', 'r.gruppe_kurzbz=bg.gruppe_kurzbz AND bg.uid=?', 'LEFT', false); + $this->addJoin('public.tbl_studiensemester ss1', 'bg.studiensemester_kurzbz=ss1.studiensemester_kurzbz AND ss1.start<=r.datum AND ss1.ende>=r.datum', 'LEFT'); + $this->db->join('public.tbl_studentlehrverband slv', "r.studiengang_kz=slv.studiengang_kz AND slv.student_uid=? AND (slv.semester=r.semester OR r.semester IS NULL) AND (slv.verband=r.verband OR r.verband IS NULL OR r.verband='' OR r.verband='0') AND (slv.gruppe=r.gruppe OR r.gruppe IS NULL OR r.gruppe='' OR r.gruppe='0') AND r.gruppe_kurzbz IS NULL", 'LEFT', false); + $this->addJoin('public.tbl_studiensemester ss2', 'slv.studiensemester_kurzbz=ss2.studiensemester_kurzbz AND ss2.start<=r.datum AND ss2.ende>=r.datum', 'LEFT'); + $this->db->or_where('ss1.studiensemester_kurzbz IS NOT NULL', null, false); + $this->db->or_where('ss2.studiensemester_kurzbz IS NOT NULL', null, false); + + $query = $this->db->get_compiled_select('campus.vw_reservierung r'); + + return $this->execQuery($query, [$uid, $uid]); + } + } diff --git a/application/models/ressource/Stundenplan_model.php b/application/models/ressource/Stundenplan_model.php index be3d520b5..012ce0a57 100644 --- a/application/models/ressource/Stundenplan_model.php +++ b/application/models/ressource/Stundenplan_model.php @@ -11,4 +11,428 @@ class Stundenplan_model extends DB_Model $this->dbTable = 'lehre.tbl_stundenplan'; $this->pk = 'stundenplan_id'; } + + /** + * @param string $ort_kurzbz + * @param string $date + * + * @return stdClass + */ + public function getRoomDataOnInterval($ort_kurzbz,$start_date,$end_date){ + + + + /*$raum_stundenplan= $this->execReadOnlyQuery(" + -- merging all reservierungs information with the stundenplan information but with different types + SELECT 'stundenplan_eintrag' as eintrags_type, CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) AS stg, CONCAT(lehrfach,'-',lehrform) AS lv_info, ort_kurzbz, studiengang_kz, uid, stunde, datum, titel, semester, verband, gruppe, gruppe_kurzbz, stg_kurzbz, * FROM lehre.vw_stundenplan sp + WHERE ort_kurzbz = ? AND datum >= ? AND datum <= ? + UNION ALL + SELECT 'reservierungs_eintrag' as eintrags_type, NULL, NULL, ort_kurzbz, studiengang_kz, uid, stunde, datum, titel, semester, verband, gruppe, gruppe_kurzbz, stg_kurzbz, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL FROM lehre.vw_reservierung res + WHERE ort_kurzbz = ? AND datum >= ? AND datum <= ? + ", [$ort_kurzbz, $start_date, $end_date,$ort_kurzbz, $start_date, $end_date]); + */ + + + $raum_stundenplan= $this->execReadOnlyQuery(" + SELECT CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) AS stg, CONCAT(lehrfach,'-',lehrform) AS lv_info, * FROM lehre.vw_stundenplan sp + WHERE ort_kurzbz = ? AND datum >= ? AND datum <= ? + ", [$ort_kurzbz, $start_date, $end_date]); + + return $raum_stundenplan; + } + + /** + * @param string $ort_kurzbz The room to query the planning for + * @param string $start_date The start date of the query interval + * @param string $end_date The end date of the query interval + * + * @return stdClass + */ + public function groupedCalendarEvents($ort_kurzbz,$start_date,$end_date){ + + + $gruppierteEvents= $this->execReadOnlyQuery(" + SELECT + + 'reservierung' as type, + NULL as unr,datum, stunde, + titel AS topic, + beschreibung as beschreibung, + string_agg(DISTINCT gruppe, '/') as gruppe, + string_agg(DISTINCT lektor, '/') as lektor, + res.ort_kurzbz,res.studiengang_kz, res.titel, res.beschreibung,NULL as lehreinheit_id,NULL as lehrfach_id,NULL as anmerkung, NULL as fix,NULL as lehrveranstaltung_id,NULL as stg_kurzbzlang,NULL as stg_bezeichnung,NULL as stg_typ, NULL as fachbereich_kurzbz,NULL as lehrfach,NULL as lehrfach_bez,NULL as farbe,NULL as lehrform, NULL as anmerkung_lehreinheit + + FROM + + ( + SELECT + NULL as unr,datum, stunde, + CASE + WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz + ELSE CONCAT(UPPER(studg.typ),UPPER(res.stg_kurzbz),'-',COALESCE(CAST(res.semester AS varchar),'/'),COALESCE(CAST(res.verband AS varchar),'/')) + END as gruppe, + CASE + WHEN mit.kurzbz IS NOT NULL THEN mit.kurzbz + ELSE uid + END as lektor, + res.ort_kurzbz,res.studiengang_kz, res.titel, res.beschreibung,NULL as lehreinheit_id,NULL as lehrfach_id,NULL as anmerkung, NULL as fix,NULL as lehrveranstaltung_id,NULL as stg_kurzbzlang,NULL as stg_bezeichnung,NULL as stg_typ, NULL as fachbereich_kurzbz,NULL as lehrfach,NULL as lehrfach_bez,NULL as farbe,NULL as lehrform, NULL as anmerkung_lehreinheit + FROM lehre.vw_reservierung res + + LEFT JOIN public.tbl_mitarbeiter mit ON mit.mitarbeiter_uid=uid + JOIN public.tbl_studiengang studg ON studg.studiengang_kz=res.studiengang_kz + + WHERE + res.ort_kurzbz = ? + AND res.datum >= ? + AND res.datum <= ? + ) as res + + GROUP BY res.ort_kurzbz,res.studiengang_kz, res.datum, res.stunde, res.titel, res.beschreibung + + UNION ALL + + SELECT + + 'stundenplan' as type, + unr,datum, stunde, + CONCAT(lehrfach,'-',lehrform) as topic, + '' as beschreibung, + string_agg(DISTINCT gruppe, '/') as gruppe, + string_agg(DISTINCT lektor, '/') as lektor, + ort_kurzbz, studiengang_kz, titel,'' as beschreibung,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit + + FROM + ( + SELECT + unr,datum, stunde, + CASE + WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz + ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) + END as gruppe, + CASE + WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz + ELSE lektor + END as lektor, + ort_kurzbz, studiengang_kz, titel,'' as beschreibung,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit + + FROM lehre.vw_stundenplan sp + + WHERE ort_kurzbz = ? + AND datum >= ? + AND datum <= ? + + ) as sp + + GROUP BY + + ort_kurzbz,unr, datum, stunde, lehreinheit_id, lehrfach_id,studiengang_kz,titel,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit + + ORDER BY datum, stunde + ", [$ort_kurzbz, $start_date, $end_date, $ort_kurzbz, $start_date, $end_date]); + + return $gruppierteEvents; + } + + + /** + * groups rows of a subquery that fetches data from the lehre.vw_stundenplan table + * @param string $stundenplanViewQuery the subquery used to group the result + * + * @return stdClass + */ + public function stundenplanGruppierung($stundenplanViewQuery) + { + $query_result = $this->execReadOnlyQuery(" + SELECT + 'lehreinheit' as type, beginn, ende, datum, + CONCAT(lehrfach,'-',lehrform) as topic, + array_agg(DISTINCT lektor) as lektor, + array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe, + string_agg(DISTINCT ort_kurzbz, '/') as ort_kurzbz, + array_agg(DISTINCT lehreinheit_id) as lehreinheit_id, + + titel, lehrfach, lehrform, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + + FROM + ( + SELECT unr,datum,beginn, ende, + CASE + WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz + ELSE lektor + END as lektor, + CASE + WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz + ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) + END as gruppen_kuerzel, + (SELECT bezeichnung + FROM public.tbl_organisationseinheit + WHERE oe_kurzbz IN( + SELECT oe_kurzbz + FROM lehre.tbl_lehrveranstaltung + WHERE lehrveranstaltung_id = sp.lehrveranstaltung_id + )) as organisationseinheit, + ort_kurzbz, studiengang_kz, titel,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz + + FROM (".$stundenplanViewQuery.") sp + JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde + + ) as subquery + + GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + + ORDER BY datum, beginn + "); + + return $query_result; + } + + /** + * queries Stundenplan but for a whole lva, irrespective of who is requesting it + * + * @return void + */ + public function getStundenplanLVA($start_date, $end_date, $lv_id) { + return $this->execReadOnlyQuery(" + + SELECT + 'lehreinheit' as type, beginn, ende, datum, + CONCAT(lehrfach,'-',lehrform) as topic, + array_agg(DISTINCT lektor) as lektor, + array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe, + string_agg(DISTINCT ort_kurzbz, '/') as ort_kurzbz, + array_agg(DISTINCT lehreinheit_id) as lehreinheit_id, + + titel, lehrfach, lehrform, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + + FROM + ( + SELECT unr,datum,beginn, ende, + CASE + WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz + ELSE lektor + END as lektor, + CASE + WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz + ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) + END as gruppen_kuerzel, + (SELECT bezeichnung + FROM public.tbl_organisationseinheit + WHERE oe_kurzbz IN( + SELECT oe_kurzbz + FROM lehre.tbl_lehrveranstaltung + WHERE lehrveranstaltung_id = sp.lehrveranstaltung_id + )) as organisationseinheit, + ort_kurzbz, studiengang_kz, titel,lehreinheit_id,lehrfach_id,anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz + + FROM ( + SELECT sp.* + FROM lehre.vw_stundenplan sp + WHERE + sp.datum >= ? + AND sp.datum <= ? AND sp.lehrveranstaltung_id = ? + ) sp + JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde + + ) as subquery + + GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + + ORDER BY datum, beginn + ", [$start_date, $end_date, $lv_id]); + } + + /** + * queries Stundenplan and filters by assigned ma_kurzbz, very similar to get by LVA + * + * @return void + */ + public function getStundenplanMitarbeiter($start_date, $end_date, $ma_uid) { + return $this->execReadOnlyQuery(" + + SELECT + 'lehreinheit' as type, beginn, ende, datum, + CONCAT(lehrfach,'-',lehrform) as topic, + array_agg(DISTINCT lektor) as lektor, + array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe, + string_agg(DISTINCT ort_kurzbz, '/') as ort_kurzbz, + array_agg(DISTINCT lehreinheit_id) as lehreinheit_id, + + titel, lehrfach, lehrform, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + + FROM + ( + SELECT unr,datum,beginn, ende, + CASE + WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz + ELSE sp.lektor + END as lektor, + CASE + WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz + ELSE CONCAT(UPPER(sp.stg_typ),UPPER(sp.stg_kurzbz),'-',COALESCE(CAST(sp.semester AS varchar),'/'),COALESCE(CAST(sp.verband AS varchar),'/')) + END as gruppen_kuerzel, + (SELECT bezeichnung + FROM public.tbl_organisationseinheit + WHERE oe_kurzbz IN( + SELECT oe_kurzbz + FROM lehre.tbl_lehrveranstaltung + WHERE lehrveranstaltung_id = sp.lehrveranstaltung_id + )) as organisationseinheit, + sp.ort_kurzbz, sp.studiengang_kz, sp.titel,sp.lehreinheit_id,sp.lehrfach_id,sp.anmerkung,fix,lehrveranstaltung_id,stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz + + FROM ( + SELECT sp.* + FROM lehre.vw_stundenplan sp + WHERE + sp.datum >= ? + AND sp.datum <= ? + ) sp + JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde + JOIN public.tbl_mitarbeiter ON public.tbl_mitarbeiter.kurzbz = sp.mitarbeiter_kurzbz + WHERE mitarbeiter_uid = ? + + ) as subquery + + GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + + ORDER BY datum, beginn", [$start_date, $end_date, $ma_uid]); + } + + /** + * NO STANDALONE FUNCTION - Generates a SQL query string to fetch 'stundenplan' events for a specific student within the current semester. + * + * @return mixed + */ + public function getStundenplanQuery($start_date, $end_date,$semester,$gruppen,$studentlehrverbaende){ + + // helper function to check if either $gruppen or $studentlehrverbaende are empty for each semester + $emptyCheck = function($toBeCheckedArray) use ($semester){ + $result = true; + $sem = array_keys($semester); + foreach($sem as $s){ + if(count($toBeCheckedArray[$s]) > 0){ + $result = false; + break; + } + } + return $result; + }; + + // if both the gruppen and the studentlehrverbaende are empty we early return + if($emptyCheck($gruppen) && $emptyCheck($studentlehrverbaende)) + { + return false; + } + + $query = + "select sp.* + from lehre.vw_stundenplan sp + WHERE + sp.datum >= ".$this->escape($start_date)." + AND sp.datum <= ".$this->escape($end_date); + + // adds the AND sql chain only if both $gruppen and $studentlehrverbaende are not empty + if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende)) + { + $query .= " AND ( "; + } + + foreach($semester as $sem => $semester_date_range) + { + + foreach($semester_date_range as $sem_date => $sem_date_range) + { + // if there are not groups for the semester skip the iteration step + if(!array_key_exists($sem_date,$gruppen) || count($gruppen[$sem_date]) == 0) + { + continue; + } + // converts the array of gruppen strings into a sql IN (_,_,_) chain + $query .="(sp.gruppe_kurzbz IN (" .implode(',',$gruppen[$sem_date]).") AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende)." )"; + + $query .="OR"; + } + } + + // if there are no studentlehrverbaende and the gruppen are not empty, we can remove the last OR added after the groups + if($emptyCheck($studentlehrverbaende) && !$emptyCheck($gruppen)) + { + $query = substr($query, 0, -2); + } + + foreach($semester as $sem=>$semester_date_range) + { + foreach($semester_date_range as $sem_date => $sem_date_range) + { + if(!array_key_exists($sem_date,$studentlehrverbaende) || count($studentlehrverbaende[$sem_date]) == 0) + { + continue; + } + foreach($studentlehrverbaende[$sem_date] as $key=>$lehrverband) + { + $query .= "((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; + // Eintraege fuer den ganzen Verband + $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; + // Eintraege fuer das ganze Semester + $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).") AND gruppe_kurzbz is null)"; + + $query .="OR"; + + } + } + } + + // if the studentlehrverbaende is not empty we can remove the last OR that was added to the query + if(!$emptyCheck($studentlehrverbaende)) + { + $query = substr($query, 0, -2); + } + + // closes the AND sql chain only if it was opened previously + if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende)) + { + $query .= ")"; + } + + return $query; + } + + /** + * NO STANDALONE FUNCTION - Generates a SQL query string to fetch 'stundenplan' events for a specific room within a date range. + * @param string $ort_kurzbz the ort from which we want to query the stundenplan events + * @param string $start_date (inclusive) the minimum date that an event should have to be fetched + * @param string $end_date (inclusive) the maximum date that an event should not extend to be fetched + * + * @return string + */ + public function getRoomQuery($ort_kurzbz, $start_date, $end_date) + { + return + "select sp.* + FROM lehre.vw_stundenplan sp + WHERE ort_kurzbz = ".$this->escape($ort_kurzbz)." + AND datum >= ".$this->escape($start_date)." + AND datum <= ".$this->escape($end_date); + } + + /** + * @param string $uid + * + * @return stdClass + */ + public function loadForUid($uid) + { + $this->addSelect(['sp.*','le.studiensemester_kurzbz']); + $this->db->join('public.tbl_benutzergruppe bg', 'sp.gruppe_kurzbz=bg.gruppe_kurzbz AND bg.uid=?', 'LEFT', false); + $this->addJoin('public.tbl_studiensemester ss1', 'bg.studiensemester_kurzbz=ss1.studiensemester_kurzbz AND ss1.start<=sp.datum AND ss1.ende>=sp.datum', 'LEFT'); + $this->db->join('public.tbl_studentlehrverband slv', "sp.studiengang_kz=slv.studiengang_kz AND slv.student_uid=? AND (slv.semester=sp.semester OR sp.semester IS NULL) AND (slv.verband=sp.verband OR sp.verband IS NULL OR sp.verband='' OR sp.verband='0') AND (slv.gruppe=sp.gruppe OR sp.gruppe IS NULL OR sp.gruppe='' OR sp.gruppe='0') AND sp.gruppe_kurzbz IS NULL", 'LEFT', false); + $this->addJoin('public.tbl_studiensemester ss2', 'slv.studiensemester_kurzbz=ss2.studiensemester_kurzbz AND ss2.start<=sp.datum AND ss2.ende>=sp.datum', 'LEFT'); + $this->db->join('lehre.tbl_lehreinheit le', 'le.lehreinheit_id=sp.lehreinheit_id', 'LEFT'); + $this->db->or_where('ss1.studiensemester_kurzbz IS NOT NULL', null, false); + $this->db->or_where('ss2.studiensemester_kurzbz IS NOT NULL', null, false); + + $query = $this->db->get_compiled_select('lehre.vw_stundenplan sp'); + + return $this->execQuery($query, [$uid, $uid]); + } + } diff --git a/application/models/ressource/Stundenplandev_model.php b/application/models/ressource/Stundenplandev_model.php index a498e209b..800540d60 100644 --- a/application/models/ressource/Stundenplandev_model.php +++ b/application/models/ressource/Stundenplandev_model.php @@ -12,6 +12,8 @@ class Stundenplandev_model extends DB_Model $this->pk = 'stundenplandev_id'; } + + public function getMissingDirectGroups($studiensemester_kurzbz = null) { $qry = " diff --git a/application/models/ressource/Stundensatz_model.php b/application/models/ressource/Stundensatz_model.php index c397d8573..10f5a6aa1 100644 --- a/application/models/ressource/Stundensatz_model.php +++ b/application/models/ressource/Stundensatz_model.php @@ -13,5 +13,33 @@ class Stundensatz_model extends DB_Model $this->pk = 'stundensatz_id'; $this->hasSequence = true; } - + + public function getStundensatzByDatum($uid, $beginn, $ende = null, $typ = null) + { + $qry = "SELECT + * + FROM + hr.tbl_stundensatz + WHERE + uid = ? + AND (gueltig_bis >= ? OR gueltig_bis is null)"; + + $params = array($uid, $beginn); + + if (!is_null($ende)) + { + $qry .= " AND (gueltig_von <= ?)"; + $params[] = $ende; + } + + if (!is_null($typ)) + { + $qry .= " AND stundensatztyp = ?"; + $params[] = $typ; + } + + $qry .= " ORDER BY gueltig_bis DESC NULLS FIRST, gueltig_von DESC NULLS LAST LIMIT 1;"; + + return $this->execQuery($qry, $params); + } } \ No newline at end of file diff --git a/application/models/system/Notiztyp_model.php b/application/models/system/Notiztyp_model.php new file mode 100644 index 000000000..b173377e6 --- /dev/null +++ b/application/models/system/Notiztyp_model.php @@ -0,0 +1,14 @@ +dbTable = 'public.tbl_notiz_typ'; + $this->pk = 'typ_kurzbz'; + } +} diff --git a/application/models/system/Sprache_model.php b/application/models/system/Sprache_model.php index 202157a83..fb12b91e9 100644 --- a/application/models/system/Sprache_model.php +++ b/application/models/system/Sprache_model.php @@ -11,4 +11,19 @@ class Sprache_model extends DB_Model $this->dbTable = 'public.tbl_sprache'; $this->pk = 'sprache'; } + + /** + * @param array $sprachen + * + * @return stdClass + */ + public function loadMultiple($sprachen) + { + $this->db->where_in('sprache', $sprachen); + + $this->addOrder('index'); + + return $this->load(); + } + } diff --git a/application/models/system/Variable_model.php b/application/models/system/Variable_model.php index 875fc8876..bfa1dcd98 100644 --- a/application/models/system/Variable_model.php +++ b/application/models/system/Variable_model.php @@ -66,6 +66,15 @@ class Variable_model extends DB_Model } } } + + if (!isset($vardata['emailadressentrennzeichen'])) + { + $vardata['emailadressentrennzeichen'] = + (defined('DEFAULT_EMAILADRESSENTRENNZEICHEN')) + ? DEFAULT_EMAILADRESSENTRENNZEICHEN + : ','; + } + $result = success($vardata); } diff --git a/application/models/system/Vorlagestudiengang_model.php b/application/models/system/Vorlagestudiengang_model.php index 24af7353c..613d88226 100644 --- a/application/models/system/Vorlagestudiengang_model.php +++ b/application/models/system/Vorlagestudiengang_model.php @@ -11,4 +11,49 @@ class Vorlagestudiengang_model extends DB_Model $this->dbTable = 'public.tbl_vorlagestudiengang'; $this->pk = 'vorlagestudiengang_id'; } + + /** + * Gets the Current Vorlagestudiengang + * + * @param string $vorlage_kurzbz + * @param string $oe_kurzbz Or studiengang_kz + * @param integer $version (optional) + * @param boolean|null $active (optional) + * + * @return stdClass + */ + public function getCurrent($vorlage_kurzbz, $oe_kurzbz, $version = null, $active = true) + { + if (is_numeric($oe_kurzbz)) { + $initselect = "SELECT oe_kurzbz, 1 AS l FROM public.tbl_studiengang WHERE studiengang_kz = " . $this->escape($oe_kurzbz); + } else { + $initselect = "SELECT oe_kurzbz, 1 AS l FROM public.tbl_organisationseinheit WHERE oe_kurzbz = " . $this->escape($oe_kurzbz); + } + + $this->addJoin("( + WITH RECURSIVE tmp (oe_kurzbz, l) AS ( + " . $initselect . " + UNION ALL + SELECT o.oe_parent_kurzbz AS oe_kurzbz, l+1 AS l + FROM tmp + JOIN public.tbl_organisationseinheit o USING (oe_kurzbz) + WHERE o.oe_parent_kurzbz IS NOT NULL + ) SELECT * FROM tmp + ) oe", "oe_kurzbz"); + + if (!is_null($version)) + $this->db->where('version', $version); + if ($active) + $this->db->where('aktiv', true); + + $this->addOrder('l', 'ASC'); + $this->addOrder('version', 'DESC'); + $this->addLimit(1); + + $result = $this->loadWhere([ + 'vorlage_kurzbz' => $vorlage_kurzbz + ]); + + return $result; + } } diff --git a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php index 6827beaa4..f81a2d518 100644 --- a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php +++ b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php @@ -59,7 +59,14 @@ class Dienstverhaeltnis_model extends DB_Model } $qry .=" - ORDER BY dv.von desc + ORDER BY + CASE + WHEN (COALESCE(dv.bis, '2999-12-31'::date) - NOW()::date) < 0 THEN NULL + ELSE + (COALESCE(dv.bis, '2999-12-31'::date) - NOW()::date) + END ASC NULLS LAST, + COALESCE(dv.bis, '2999-12-31'::date) DESC, + dv.von DESC "; return $this->execQuery($qry, $data); diff --git a/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php index e9006dfc0..c50627697 100644 --- a/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php +++ b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php @@ -33,41 +33,84 @@ class Gehaltsbestandteil_model extends DB_Model implements IEncryption $datestring = $date->format("Y-m-d"); $qry = " - SELECT - gehaltsbestandteil_id, - gbt.von, - gbt.bis, - gbt.anmerkung, - gbt.dienstverhaeltnis_id, - gehaltstyp_kurzbz, - valorisierungssperre, - gbt.valorisierung, - grundbetrag as grund_betrag_decrypted, - betrag_valorisiert as betrag_val_decrypted, - gt.bezeichnung as gehaltstyp_bezeichnung, - vb.vertragsbestandteiltyp_kurzbz, - bf.funktion_kurzbz, - bf.oe_kurzbz, - fkt.beschreibung as fkt_beschreibung, - fb.bezeichnung as fb_bezeichnung, - org.bezeichnung as org_bezeichnung, - freitext.freitexttyp_kurzbz, - freitext.titel as freitext_titel - FROM hr.tbl_gehaltsbestandteil gbt LEFT JOIN hr.tbl_gehaltstyp gt using(gehaltstyp_kurzbz) - LEFT JOIN hr.tbl_vertragsbestandteil vb using(vertragsbestandteil_id) - LEFT JOIN hr.tbl_vertragsbestandteil_funktion vbf using(vertragsbestandteil_id) - LEFT JOIN public.tbl_benutzerfunktion bf using(benutzerfunktion_id) - LEFT JOIN public.tbl_funktion fkt using(funktion_kurzbz) - LEFT JOIN public.tbl_fachbereich fb using(fachbereich_kurzbz) - LEFT JOIN public.tbl_organisationseinheit org on (bf.oe_kurzbz=org.oe_kurzbz) - LEFT JOIN hr.tbl_vertragsbestandteil_freitext freitext on(vb.vertragsbestandteil_id=freitext.vertragsbestandteil_id) - WHERE gbt.dienstverhaeltnis_id=? AND - (gbt.von<=? and (gbt.bis is null OR gbt.bis>=?)) - ORDER BY gt.sort +with gbt as ( + select + gb.gehaltsbestandteil_id, + gb.von, + gb.bis, + gb.anmerkung, + gb.dienstverhaeltnis_id, + gb.gehaltstyp_kurzbz, + gb.valorisierungssperre, + gb.valorisierung, + gb.grundbetrag as grund_betrag_decrypted, + coalesce(vh.betrag_valorisiert, gb.grundbetrag) as betrag_val_decrypted, + gb.vertragsbestandteil_id + from + hr.tbl_gehaltsbestandteil gb + LEFT JOIN + hr.tbl_valorisierung_historie vh ON vh.gehaltsbestandteil_id = gb.gehaltsbestandteil_id AND vh.valorisierungsdatum = ( + SELECT + vi.valorisierungsdatum + FROM + hr.tbl_valorisierung_instanz vi + JOIN + hr.tbl_dienstverhaeltnis d ON d.dienstverhaeltnis_id = ? + AND d.oe_kurzbz = vi.oe_kurzbz + WHERE + ? >= valorisierungsdatum + ORDER BY + valorisierungsdatum DESC + LIMIT 1 + ) + where + dienstverhaeltnis_id = ? + and ( + ? BETWEEN COALESCE(von, '1970-01-01'::date) AND COALESCE(bis, '2170-01-01'::date) + ) +) +select + gbt.gehaltsbestandteil_id, + gbt.von, + gbt.bis, + gbt.anmerkung, + gbt.dienstverhaeltnis_id, + gbt.gehaltstyp_kurzbz, + gbt.valorisierungssperre, + gbt.valorisierung, + gbt.grund_betrag_decrypted, + gbt.betrag_val_decrypted, + gt.bezeichnung as gehaltstyp_bezeichnung, + vb.vertragsbestandteiltyp_kurzbz, + bf.funktion_kurzbz, + bf.oe_kurzbz, + fkt.beschreibung as fkt_beschreibung, + fb.bezeichnung as fb_bezeichnung, + org.bezeichnung as org_bezeichnung, + freitext.freitexttyp_kurzbz, + freitext.titel as freitext_titel +from + gbt +LEFT JOIN + hr.tbl_gehaltstyp gt using(gehaltstyp_kurzbz) +LEFT JOIN + hr.tbl_vertragsbestandteil vb using(vertragsbestandteil_id) +LEFT JOIN + hr.tbl_vertragsbestandteil_funktion vbf using(vertragsbestandteil_id) +LEFT JOIN + public.tbl_benutzerfunktion bf using(benutzerfunktion_id) +LEFT JOIN + public.tbl_funktion fkt using(funktion_kurzbz) +LEFT JOIN + public.tbl_fachbereich fb using(fachbereich_kurzbz) +LEFT JOIN + public.tbl_organisationseinheit org on (bf.oe_kurzbz=org.oe_kurzbz) +LEFT JOIN + hr.tbl_vertragsbestandteil_freitext freitext on(vb.vertragsbestandteil_id=freitext.vertragsbestandteil_id) "; return $this->execQuery($qry, - array($dienstverhaeltnis_id, $datestring, $datestring), + array($dienstverhaeltnis_id, $datestring, $dienstverhaeltnis_id, $datestring), $this->getEncryptedColumns()); } @@ -86,9 +129,38 @@ class Gehaltsbestandteil_model extends DB_Model implements IEncryption array($dienstverhaeltnis_id), $this->getEncryptedColumns()); } - - public function getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + public function getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, + $includefuture=false, $withvalorisationhistory=true) + { + if( !is_null($stichtag) && (time() > strtotime($stichtag)) + && $withvalorisationhistory !== false ) + { + $query = $this->getGehaltsbestandteileMitValorisierungsHistorie( + $dienstverhaeltnis_id, $stichtag, $includefuture + ); + } + else + { + $query = $this->getGehaltsbestandteileOhneValorisierungsHistorie( + $dienstverhaeltnis_id, $stichtag, $includefuture + ); + } + + $gehaltsbestandteile = array(); + if( null !== ($rows = getData($query)) ) + { + foreach( $rows as $row ) { + $tmpgb = new Gehaltsbestandteil(); + $tmpgb->hydrateByStdClass($row, true); + $gehaltsbestandteile[] = $tmpgb; + } + } + + return $gehaltsbestandteile; + } + + protected function getGehaltsbestandteileOhneValorisierungsHistorie($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) { $stichtagclause = ''; if( !is_null($stichtag) ) @@ -111,25 +183,145 @@ class Gehaltsbestandteil_model extends DB_Model implements IEncryption {$stichtagclause} EOSQL; - $query = $this->loadWhere( + $result = $this->loadWhere( $where, $this->getEncryptedColumns() ); + return $result; + } + + protected function getGehaltsbestandteileMitValorisierungsHistorie($dienstverhaeltnis_id, $stichtag, $includefuture=false) + { + $date = strftime('%Y-%m-%d', strtotime($stichtag)); + $includefuture_clause = ($includefuture) + ? ' OR COALESCE(von, \'1970-01-01\'::date) > ' . $this->escape($date) + : ''; + $sql = <<escape($dienstverhaeltnis_id)} + AND d.oe_kurzbz = vi.oe_kurzbz + WHERE + {$this->escape($date)} >= valorisierungsdatum + ORDER BY + valorisierungsdatum DESC + LIMIT 1 + ) +WHERE + g.dienstverhaeltnis_id = {$this->escape($dienstverhaeltnis_id)} + AND ( + {$this->escape($date)} BETWEEN COALESCE(von, '1970-01-01'::date) AND COALESCE(bis, '2170-01-01'::date) + {$includefuture_clause} + ) +EOSQL; + + $result = $this->execReadOnlyQuery($sql, array(), $this->getEncryptedColumns()); + return $result; + } - $gehaltsbestandteile = array(); + public function getGehaltsbestandteileValorisiertForChart($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + { + $stichtagclause = ''; + if( !is_null($stichtag) ) + { + $date = strftime('%Y-%m-%d', strtotime($stichtag)); + $stichtagclause = 'AND (' . $this->escape($date) + . ' BETWEEN COALESCE(von, \'1970-01-01\'::date)' + . ' AND COALESCE(bis, \'2170-01-01\'::date)'; + if( $includefuture ) + { + $stichtagclause .= ' OR COALESCE(von, \'1970-01-01\'::date) > ' + . $this->escape($date); + } + $stichtagclause .= ')'; + } + + // Note: replaced gb.betrag_valorisiert with vh.betrag_valorisiert! + $qry = " + SELECT + gb.gehaltsbestandteil_id,gb.dienstverhaeltnis_id,gb.vertragsbestandteil_id,gb.gehaltstyp_kurzbz, + gb.von,gb.bis,gb.anmerkung,gb.grundbetrag as grundbetrag,gb.valorisierungssperre,gb.insertamum, + gb.insertvon,gb.updateamum,gb.updatevon,gb.valorisierung,gb.auszahlungen, + vh.valorisierungsdatum, vh.betrag_valorisiert as betrag_valorisiert + FROM hr.tbl_gehaltsbestandteil gb LEFT JOIN hr.tbl_valorisierung_historie vh using (gehaltsbestandteil_id) + WHERE dienstverhaeltnis_id=? + $stichtagclause + ORDER BY gb.von,vh.valorisierungsdatum, gb.gehaltsbestandteil_id; + "; + + $query = $this->execQuery($qry, + array($dienstverhaeltnis_id), + $this->getEncryptedColumns()); + + $gehaltsbestandteile = array(); if( null !== ($rows = getData($query)) ) { + // store for preserving the last records of every gehaltsbestandteil_id + $lastRecords = array(); + foreach( $rows as $row ) { $tmpgb = new Gehaltsbestandteil(); $tmpgb->hydrateByStdClass($row, true); - $gehaltsbestandteile[] = $tmpgb; + + // prevent duplication (caused by the join with historic values) + if (!isset($lastRecords[(string)$row->gehaltsbestandteil_id])) { + $gehaltsbestandteile[] = $tmpgb; + $lastRecords[(string)$row->gehaltsbestandteil_id] = $tmpgb; + } + + if ($row->betrag_valorisiert != null && $row->valorisierungsdatum != null + && $row->valorisierungsdatum != $row->von && $row->valorisierungsdatum != $row->bis) { + + // create additional row + $tmpgbv = new Gehaltsbestandteil(); + $tmpgbv->hydrateByStdClass($row, true); + $tmpgbv->setVon($row->valorisierungsdatum); + $tmpgbv->setBis($lastRecords[(string)$row->gehaltsbestandteil_id]->getBis()); + // overwrite Grundbetrag with the current valorized loan + // (otherwise the chart would show the wrong value) + $tmpgbv->setGrundbetrag($row->betrag_valorisiert); + $gehaltsbestandteile[] = $tmpgbv; + + // finish previous + $daybefore = new DateTimeImmutable($row->valorisierungsdatum); + $daybefore = $daybefore->sub(new \DateInterval('P1D')); + $lastRecords[(string)$row->gehaltsbestandteil_id]->setBis($daybefore->format('Y-m-d')); + + // preserve as last row, because there might be another valorization + $lastRecords[(string)$row->gehaltsbestandteil_id] = $tmpgbv; + + } + } } return $gehaltsbestandteile; } - public function getGehaltsbestandteil($id) { $this->addSelect('*'); diff --git a/application/models/vertragsbestandteil/Vertragsbestandteil_model.php b/application/models/vertragsbestandteil/Vertragsbestandteil_model.php index 6d8c18859..cbc529d83 100644 --- a/application/models/vertragsbestandteil/Vertragsbestandteil_model.php +++ b/application/models/vertragsbestandteil/Vertragsbestandteil_model.php @@ -19,12 +19,17 @@ class Vertragsbestandteil_model extends DB_Model protected function getVertragsbestandteilSQL() { + $sapInstalled = $this->_checkIfSAPSyncTableExists(); + + $oe_kurzbz_sap = $sapInstalled ? 'sap.oe_kurzbz_sap' : 'NULL AS oe_kurzbz_sap'; + $sap_join = $sapInstalled ? 'LEFT JOIN sync.tbl_sap_organisationsstruktur sap USING(oe_kurzbz)' : ''; + $sql = <<overlappingvbs; } + + /** + * Checks if sap sync table exists. + * @return bool + */ + private function _checkIfSAPSyncTableExists() + { + $params = array( + DB_NAME, + 'sync', + 'tbl_sap_organisationsstruktur' + ); + + $sql = "SELECT + 1 AS exists + FROM + information_schema.tables + WHERE + table_catalog = ? AND + table_schema = ? AND + table_name = ?"; + + $res = $this->execReadOnlyQuery($sql, $params); + + return hasData($res); + } } diff --git a/application/views/Cis/Cms/News/Xml/Address/Detailed.php b/application/views/Cis/Cms/News/Xml/Address/Detailed.php new file mode 100644 index 000000000..934b5ba93 --- /dev/null +++ b/application/views/Cis/Cms/News/Xml/Address/Detailed.php @@ -0,0 +1,11 @@ +aktiv) { ?> + uid; ?>]]> + titelpre . ' ' . $obj->vorname . ' ' . $obj->nachname . ' ' . $obj->titelpost; ?>]]> + alias ?: $obj->uid; ?>@]]> + telefonklappe !== null) { ?> + kontakt ?: ''; ?> - telefonklappe; ?>]]> + + planbezeichnung) { ?> + planbezeichnung; ?>]]> + + \ No newline at end of file diff --git a/application/views/Cis/Cms/News/Xml/Address/Short.php b/application/views/Cis/Cms/News/Xml/Address/Short.php new file mode 100644 index 000000000..61888fb7e --- /dev/null +++ b/application/views/Cis/Cms/News/Xml/Address/Short.php @@ -0,0 +1,6 @@ +aktiv) { ?> + uid; ?>]]> + uid; ?>@]]> + + titelpre . ' ' . $obj->vorname . ' ' . $obj->nachname . ' ' . $obj->titelpost; ?>bezeichnung != '' && $obj->bezeichnung != $obj->beschreibung) echo ' (' . $obj->bezeichnung . ')'; ?>]]> + diff --git a/application/views/Cis/Cms/News/Xml/NewsExtras.php b/application/views/Cis/Cms/News/Xml/NewsExtras.php new file mode 100644 index 000000000..b3b86e567 --- /dev/null +++ b/application/views/Cis/Cms/News/Xml/NewsExtras.php @@ -0,0 +1,46 @@ + + studiengang_kz; ?> + p->t('global', 'studiengangsleitung'); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?> + + p->t('global', 'geschaeftsfuehrendeltg'); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?> + + p->t('global', 'stellvertreter'); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?> + + p->t('global', 'sekretariat'); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Detailed', ['obj' => $item]); ?> + + + zusatzinfo_html; ?>]]> + + p->t('global', 'hochschulvertretung'); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Short', ['obj' => $item]); ?> + + + p->t('global', 'studentenvertreter'); ?> oe_kurzbz); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Short', ['obj' => $item]); ?> + + + p->t('global', 'jahrgangsvertretung'); ?> p->t('global', 'semester'); ?>]]>'; + + view('Cis/Cms/News/Xml/Address/Short', ['obj' => $item]); ?> + + + + + p->t('global', 'allgemeinerdownload'); ?>]]> + typ . $studiengang->kurzbz); ?>]]> + kurzbzlang); ?>]]> + studiengang_kz; ?>]]> + '; + + + diff --git a/application/views/Cis/Documents.php b/application/views/Cis/Documents.php new file mode 100644 index 000000000..f34ce3fc1 --- /dev/null +++ b/application/views/Cis/Documents.php @@ -0,0 +1,212 @@ + 'Documents', + 'tabulator5' => true, + 'customJSModules' => ['public/js/apps/Cis/Documents.js'] +); + +$this->load->view('templates/CISVUE-Header', $includesArray); +?> + +

+
+

p->t('tools', 'dokumente'); ?>p->t('tools', 'bestaetigungenZeugnisse'); ?>

+
+ +
+ +
+
+
+

p->t('tools', 'inskriptionsbestaetigung'); ?>p->t('tools', 'studienbuchblatt') : ''; ?>

+ +
+ +
+ +
+ +
+
+ + + + + + + + + + + + + studiensemester as $stsem => $sem) { ?> + inskriptionsbestaetigung) { ?> + + + + + + + + + + + + + + + + + + + + +
DokumentStudiengangStudiensemester
+ + PDF p->t('tools', 'inskriptionsbestaetigung'); ?> + + bezeichnung; ?>
+ + PDF p->t('tools', 'studienbuchblatt'); ?> + + bezeichnung; ?>
+
+ +
+
+

p->t('tools', 'studienerfolgsbestaetigung'); ?>

+ +
+ +
+ +
+ +
+
+ +
+
+ + + + + + + + + + + + + + $this->p->t('global', 'deutsch'), 'StudienerfolgEng' => $this->p->t('global', 'englisch')] as $lang_xsl => $lang) { ?> + + + + + + + + + + + + studiensemester as $stsem => $sem) { ?> + + + + + + + + + + + + + + +
DokumentStudiengangStudiensemesterSprachep->t('tools', 'vorlageWohnsitzfinanzamt'); ?>
+ + PDF p->t('tools', 'studienerfolgsbestaetigung'); ?> + + bezeichnung; ?>p->t('tools', 'alleStudiensemester'); ?>
+ + PDF p->t('tools', 'studienerfolgsbestaetigung'); ?> + + bezeichnung; ?>
+
+ + +
+
+

p->t('tools', 'abschlussdokumente'); ?>

+
+ + + + + + + + + + + + + + +
DokumentDatum
+ + PDF bezeichnung; ?> + + erstelltam))->format('d.m.Y'); ?>
+
+ +
+ +
+ +
+ + +
+
+ +load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/InfoTerminal.php b/application/views/Cis/InfoTerminal.php new file mode 100644 index 000000000..7e89b9f0c --- /dev/null +++ b/application/views/Cis/InfoTerminal.php @@ -0,0 +1,16 @@ + 'Infoterminal', + 'tabulator5' => true, + 'primevue3' => true, +); +$this->load->view( + 'templates/CISVUE-Header', + $includesArray +); +?> + + +load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/Login.php b/application/views/Cis/Login.php new file mode 100644 index 000000000..68490e67e --- /dev/null +++ b/application/views/Cis/Login.php @@ -0,0 +1,42 @@ + 'FH-Complete', + 'bootstrap5' => true, + 'fontawesome6' => true + ); + + $this->load->view('templates/FHC-Header', $includesArray); +?> + +
+
+
+ +

+ +

+ +
+ + ', '
'); ?> + +
+ 'username', 'class' => 'form-control', 'placeholder' => 'Username', 'required' => true]); ?> +
+ +
+ 'password', 'class' => 'form-control', 'placeholder' => 'Password', 'required' => true]); ?> +
+ +
+ 'submit', 'class' => 'btn btn-primary'], 'Log in'); ?> +
+ +

Forgot Password?

+ +
+
+ + +load->view('templates/FHC-Footer', $includesArray); ?> + diff --git a/application/views/Cis/LvInfo.php b/application/views/Cis/LvInfo.php new file mode 100644 index 000000000..49a7b7a85 --- /dev/null +++ b/application/views/Cis/LvInfo.php @@ -0,0 +1,15 @@ + 'LvInfo', + 'customJSModules' => ['public/js/apps/Cis/LvInfo.js'] +); + +$this->load->view('templates/CISVUE-Header', $includesArray); +?> + +
+ + +
+ +load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/Profil.php b/application/views/Cis/Profil.php new file mode 100644 index 000000000..f66ebf8a9 --- /dev/null +++ b/application/views/Cis/Profil.php @@ -0,0 +1,18 @@ + 'Profil', + 'customJSModules' => ['public/js/apps/Cis/Profil.js'], + 'tabulator5' => true, + 'primevue3' => true, + 'customCSSs' => ['public/css/components/calendar.css', 'public/css/components/FilterComponent.css','public/css/components/Profil.css','public/css/components/FormUnderline.css'], + +); + +$this->load->view('templates/CISVUE-Header', $includesArray); +?> + +
+ +
+ +load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/ProfilUpdate.php b/application/views/Cis/ProfilUpdate.php new file mode 100644 index 000000000..e797d436f --- /dev/null +++ b/application/views/Cis/ProfilUpdate.php @@ -0,0 +1,49 @@ + 'Profil Änderungen', + 'vue3' => true, + 'bootstrap5' => true, + 'fontawesome6'=> true, + 'axios027' => true, + 'tabulator5' => true, + 'customJSModules' => array( + 'public/js/apps/Cis/ProfilUpdateRequests.js' + ), + 'customCSSs' => array( + 'public/css/components/FilterComponent.css','public/css/components/FormUnderline.css' + ) +); + +if(defined("CIS4")) +{ + $this->load->view( + 'templates/CISVUE-Header', + $includesArray + ); +} +else +{ + $this->load->view( + 'templates/FHC-Header', + $includesArray + ); +} +?> + +
+ +
+ +load->view( + 'templates/CISVUE-Footer', + $includesArray + ); +} else { + $this->load->view( + 'templates/FHC-Footer', + $includesArray + ); +} +?> \ No newline at end of file diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php new file mode 100644 index 000000000..4590b210e --- /dev/null +++ b/application/views/CisRouterView/CisRouterView.php @@ -0,0 +1,41 @@ + 'Cis4', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'tabulator5' => true, + 'vue3' => true, + 'primevue3' => true, + 'customCSSs' => array( + 'public/css/components/verticalsplit.css', + 'public/css/components/searchbar/searchbar.css', + 'public/css/Fhc.css', + 'public/css/components/dashboard.css', + 'public/css/components/calendar.css', + 'public/css/components/Sprachen.css', + 'public/css/components/MyLv.css', + 'public/css/components/FilterComponent.css', + 'public/css/components/Profil.css', + 'public/css/components/FormUnderline.css', + 'public/css/Cis4/Cms.css', + ), + 'customJSs' => array( + 'vendor/npm-asset/primevue/accordion/accordion.js', + 'vendor/npm-asset/primevue/accordiontab/accordiontab.js' + ), + 'customJSModules' => array( + 'public/js/apps/Dashboard/Fhc.js' + ), + +); + +$this->load->view('templates/CISVUE-Header', $includesArray); +?> +
> + +
+load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Studentenverwaltung.php b/application/views/Studentenverwaltung.php index 2d0d22346..c10dc475a 100644 --- a/application/views/Studentenverwaltung.php +++ b/application/views/Studentenverwaltung.php @@ -34,8 +34,10 @@ !defined('GENERATE_ALIAS_STUDENT') ? true : GENERATE_ALIAS_STUDENT, - 'showZgvDoktor' => !defined('ZGV_DOKTOR_ANZEIGEN') ? false : ZGV_DOKTOR_ANZEIGEN, - 'showZgvErfuellt' => !defined('ZGV_ERFUELLT_ANZEIGEN') ? false : ZGV_ERFUELLT_ANZEIGEN + //replaced by possibility to hide each formular field via config stv.php + #'showZgvDoktor' => !defined('ZGV_DOKTOR_ANZEIGEN') ? false : ZGV_DOKTOR_ANZEIGEN, + #'showZgvErfuellt' => !defined('ZGV_ERFUELLT_ANZEIGEN') ? false : ZGV_ERFUELLT_ANZEIGEN + 'showHintKommPrfg' => !defined('FAS_STUDSTATUS_SHOW_KOMM_PRFG_HINT') ? false : FAS_STUDSTATUS_SHOW_KOMM_PRFG_HINT ]; ?> diff --git a/application/views/codex/oehbeitrag.php b/application/views/codex/oehbeitrag.php index feebeddef..ba99bbf0c 100644 --- a/application/views/codex/oehbeitrag.php +++ b/application/views/codex/oehbeitrag.php @@ -26,7 +26,6 @@ $this->load->view( ); ?> -
widgetlib->widget('NavigationWidget'); ?> @@ -63,6 +62,5 @@ $this->load->view(
- load->view('templates/FHC-Footer'); ?> diff --git a/application/views/dashboard/dashboard_demo.php b/application/views/dashboard/dashboard_demo.php new file mode 100644 index 000000000..8efc230b7 --- /dev/null +++ b/application/views/dashboard/dashboard_demo.php @@ -0,0 +1,32 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'FH-Complete', + 'bootstrap5' => true, + 'fontawesome6' => true, + 'axios027' => true, + 'restclient' => true, + 'vue3' => true, + 'customJSModules' => ['public/js/apps/Dashboard.js'], + 'customCSSs' => [ + 'public/css/components/dashboard.css' + ], + 'navigationcomponent' => true + ) +); +?> + +
+ + + +
+
+

Dashboard

+
+ +
+
+ +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/dashboard/dashboard_demo_admin.php b/application/views/dashboard/dashboard_demo_admin.php new file mode 100644 index 000000000..0d92146a8 --- /dev/null +++ b/application/views/dashboard/dashboard_demo_admin.php @@ -0,0 +1,32 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'FH-Complete', + 'bootstrap5' => true, + 'fontawesome6' => true, + 'axios027' => true, + 'restclient' => true, + 'vue3' => true, + 'customJSModules' => ['public/js/apps/DashboardAdmin.js'], + 'customCSSs' => [ + 'public/css/components/dashboard.css' + ], + 'navigationcomponent' => true + ) +); +?> + +
+ + + +
+
+

Dashboard

+
+ +
+
+ +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/lehre/Antrag/Create.php b/application/views/lehre/Antrag/Create.php index 7e8bda874..00e41d1cd 100644 --- a/application/views/lehre/Antrag/Create.php +++ b/application/views/lehre/Antrag/Create.php @@ -18,14 +18,22 @@ $sitesettings = array( ) ); -$this->load->view( - 'templates/FHC-Header', - $sitesettings -); +if(defined('CIS4')){ + $this->load->view( + 'templates/CISVUE-Header', + $sitesettings + ); +}else{ + $this->load->view( + 'templates/FHC-Header', + $sitesettings + ); +} + ?>
-
+

p->t('studierendenantrag', 'antrag_header'); ?>

@@ -49,7 +57,15 @@ $this->load->view(
load->view( - 'templates/FHC-Footer', - $sitesettings -); \ No newline at end of file + +if (defined('CIS4')) { + $this->load->view( + 'templates/CISVUE-Footer', + $sitesettings + ); +} else { + $this->load->view( + 'templates/FHC-Footer', + $sitesettings + ); +} diff --git a/application/views/lehre/Antrag/Student/List.php b/application/views/lehre/Antrag/Student/List.php index 4a4b4f064..6d769dafe 100644 --- a/application/views/lehre/Antrag/Student/List.php +++ b/application/views/lehre/Antrag/Student/List.php @@ -17,10 +17,17 @@ $sitesettings = array( ) ); -$this->load->view( - 'templates/FHC-Header', - $sitesettings -); +if(defined('CIS4')){ + $this->load->view( + 'templates/CISVUE-Header', + $sitesettings + ); +}else{ + $this->load->view( + 'templates/FHC-Header', + $sitesettings + ); +} ?>
@@ -221,7 +228,14 @@ $this->load->view(
load->view( - 'templates/FHC-Footer', - $sitesettings -); +if (defined('CIS4')) { + $this->load->view( + 'templates/CISVUE-Footer', + $sitesettings + ); +} else { + $this->load->view( + 'templates/FHC-Footer', + $sitesettings + ); +} diff --git a/application/views/lehre/Antrag/Wiederholung/Student.php b/application/views/lehre/Antrag/Wiederholung/Student.php index 2171d6928..e51cfd1bc 100644 --- a/application/views/lehre/Antrag/Wiederholung/Student.php +++ b/application/views/lehre/Antrag/Wiederholung/Student.php @@ -28,7 +28,7 @@ $this->load->view( ?>
-
+

p->t('studierendenantrag', 'title_lvzuweisen', ['name' => $antrag->name]);?>

diff --git a/application/views/lehre/anrechnung/adminAnrechnung.php b/application/views/lehre/anrechnung/adminAnrechnung.php index cb9a55c18..df36b3598 100644 --- a/application/views/lehre/anrechnung/adminAnrechnung.php +++ b/application/views/lehre/anrechnung/adminAnrechnung.php @@ -7,7 +7,8 @@ $includesArray = array( 'fontawesome6' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tabulator4' => true, + 'tabulator5' => true, + 'tabulator5JQuery' => true, 'tablewidget' => true, 'sbadmintemplate3' => true, 'navigationwidget' => true, @@ -48,11 +49,22 @@ $includesArray = array( 'public/js/lehre/anrechnung/adminAnrechnung.js' ), 'customCSSs' => array( - 'public/css/sbadmin2/tablesort_bootstrap.css' + 'public/css/sbadmin2/tablesort_bootstrap.css', + 'public/css/lehre/anrechnung.css' ) ); -$this->load->view('templates/FHC-Header', $includesArray); +if (defined("CIS4")) { + $this->load->view( + 'templates/CISVUE-Header', + $includesArray + ); +} else { + $this->load->view( + 'templates/FHC-Header', + $includesArray + ); +} ?>
@@ -64,16 +76,16 @@ $this->load->view('templates/FHC-Header', $includesArray);
- -

p->t('anrechnung', 'anrechnungszeitraumFestlegen'); ?>


-
@@ -86,52 +98,67 @@ $this->load->view('templates/FHC-Header', $includesArray);
-