diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php index d1f4f0958..c2e38385c 100644 --- a/application/config/anrechnung.php +++ b/application/config/anrechnung.php @@ -7,8 +7,8 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); $config['interval_blocking_application'] = 'P1M'; // Application submission period given by start- and enddate. -$config['submit_application_start'] = '01.02.2021'; -$config['submit_application_end'] = '22.02.2021'; +$config['submit_application_start'] = '05.09.2022'; +$config['submit_application_end'] = '22.09.2022'; // Lehrveranstaltungen with these grades will be blocked for application $config['grades_blocking_application'] = array( diff --git a/application/controllers/components/Filter.php b/application/controllers/components/Filter.php index 480e98548..ab7e1493e 100644 --- a/application/controllers/components/Filter.php +++ b/application/controllers/components/Filter.php @@ -41,62 +41,6 @@ class Filter extends FHC_Controller $this->outputJsonSuccess($this->filtercmptlib->getSession()); } - /** - * Change the sort of the selected fields of the current filter and - * its data will be written on the output in JSON format - */ - public function sortSelectedFields() - { - $request = $this->getPostJSON(); - - if (property_exists($request, 'selectedFields') - && $this->filtercmptlib->sortSelectedFields($request->selectedFields) == true) - { - $this->outputJsonSuccess('Fields sorted'); - } - else - { - $this->outputJsonError('Wrong parameter'); - } - } - - /** - * Remove a selected field from the current filter and - * its data will be written on the output in JSON format - */ - public function removeSelectedField() - { - $request = $this->getPostJSON(); - - if (property_exists($request, 'selectedField') - && $this->filtercmptlib->removeSelectedField($request->selectedField) == true) - { - $this->outputJsonSuccess('Field removed'); - } - else - { - $this->outputJsonError('Error occurred'); - } - } - - /** - * Add a field to the current filter and its data will be written on the output in JSON format - */ - public function addSelectedField() - { - $request = $this->getPostJSON(); - - if (property_exists($request, 'selectedField') - && $this->filtercmptlib->addSelectedField($request->selectedField) == true) - { - $this->outputJsonSuccess('Field added'); - } - else - { - $this->outputJsonError('Error occurred'); - } - } - /** * Remove an applied filter (SQL where condition) from the current filter */ diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index bc8ab562e..fbaac9b3e 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -6,13 +6,13 @@ class requestAnrechnung extends Auth_Controller { const REQUEST_ANRECHNUNG_URI = '/lehre/anrechnung/RequestAnrechnung'; const APPROVE_ANRECHNUNG_URI = '/lehre/anrechnung/ApproveAnrechnungUebersicht'; - + const ANRECHNUNGSTATUS_PROGRESSED_BY_STGL = 'inProgressDP'; const ANRECHNUNGSTATUS_PROGRESSED_BY_KF = 'inProgressKF'; const ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR = 'inProgressLektor'; const ANRECHNUNGSTATUS_APPROVED = 'approved'; const ANRECHNUNGSTATUS_REJECTED = 'rejected'; - + public function __construct() { // Set required permissions @@ -23,22 +23,22 @@ class requestAnrechnung extends Auth_Controller 'download' => 'student/anrechnung_beantragen:rw', ) ); - + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('content/DmsVersion_model', 'DmsVersionModel'); - + // Load libraries $this->load->library('WidgetLib'); $this->load->library('PermissionLib'); $this->load->library('AnrechnungLib'); $this->load->library('DmsLib'); - + // Load helpers $this->load->helper('form'); $this->load->helper('url'); $this->load->helper('hlp_sancho_helper'); - + // Load configs $this->load->config('anrechnung'); @@ -208,11 +208,11 @@ class requestAnrechnung extends Auth_Controller $this->_checkIfEntitledToReadDMSDoc($dms_id); // Get file to be downloaded from DMS - $download = $this->dmslib->download($dms_id, $filename); - if (isError($download)) return $download; + $download = $this->dmslib->download($dms_id); + if (isError($download)) return $download; - // Download file - $this->outputFile(getData($download)); + // Download file + $this->outputFile(getData($download)); } /** @@ -221,10 +221,10 @@ class requestAnrechnung extends Auth_Controller private function _setAuthUID() { $this->_uid = getAuthUID(); - + if (!$this->_uid) show_error('User authentification failed'); } - + /** * Check if application deadline is expired. * @@ -237,7 +237,7 @@ class requestAnrechnung extends Auth_Controller private function _isExpired($start, $ende, $studiensemester_kurzbz) { $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); - + // If start is not given, set to Semesterstart. if (!isset($start) || isEmptyString($start)) { @@ -245,7 +245,7 @@ class requestAnrechnung extends Auth_Controller $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); $start = getData($result)[0]->start; } - + // If ende is not given, set to Semesterende. if (!isset($ende) || isEmptyString($ende)) { @@ -253,15 +253,15 @@ class requestAnrechnung extends Auth_Controller $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); $ende = getData($result)[0]->ende; } - + $today = new DateTime('today midnight'); $start = new DateTime($start); $ende = new DateTime($ende); - + // True if expired return ($today < $start || $today > $ende); } - + /** * Check if user is entitled to read dms doc. * @@ -273,9 +273,9 @@ class requestAnrechnung extends Auth_Controller { show_error('Failed loading Student'); } - + $result = $this->AnrechnungModel->loadWhere(array('dms_id' => $dms_id)); - + if($result = getData($result)[0]) { if ($result->prestudent_id == $student->prestudent_id) @@ -283,10 +283,10 @@ class requestAnrechnung extends Auth_Controller return; } } - + show_error('You are not entitled to read this document'); } - + /** * Check if application already exists. * @@ -302,15 +302,15 @@ class requestAnrechnung extends Auth_Controller 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'prestudent_id' => $prestudent_id )); - + if (isError($result)) { show_error(getError($result)); } - + return hasData($result); } - + /** * Check if applications' study semester is actual study semester. * @@ -322,10 +322,10 @@ class requestAnrechnung extends Auth_Controller $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $result = $this->StudiensemesterModel->getNearest(); $actual_ss = getData($result)[0]->studiensemester_kurzbz; - + return $studiensemester_kurzbz == $actual_ss; } - + private function _LVhasBlockingGrades($studiensemester_kurzbz, $lehrveranstaltung_id) { // Get Note of Lehrveranstaltung @@ -336,12 +336,12 @@ class requestAnrechnung extends Auth_Controller 'lehrveranstaltung_id' => $lehrveranstaltung_id ) ); - + // If Lehrveranstaltung has Note if (hasData($result)) { $note = getData($result)[0]->note; - + // Check if Note is a blocking grade if (in_array($note, $this->config->item('grades_blocking_application'))) { @@ -350,7 +350,7 @@ class requestAnrechnung extends Auth_Controller } return false; } - + /** * Upload file via DMS library. * @@ -367,7 +367,7 @@ class requestAnrechnung extends Auth_Controller 'insertamum' => (new DateTime())->format('Y-m-d H:i:s'), 'insertvon' => $this->_uid ); - + // Upload document return $this->dmslib->upload($dms, 'uploadfile', array('pdf')); } diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index f574e7dfc..1bd92004d 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -322,20 +322,10 @@ class reviewAnrechnungDetail extends Auth_Controller // Send mail to STGL of each studiengang foreach ($studiengang_kz_arr as $studiengang_kz) { - // Get STGL mail address, if available, otherwise get assistance mail address - $stgmail = $this->_getSTGLMailAddress($studiengang_kz); - - if(isSuccess($stgmail) && hasData($stgmail)) - list ($to, $vorname) = getData($stgmail)[0]; - else - show_error ('Failed retrieving DegreeProgram Mail'); - // Get full name of lector $this->load->model('person/Person_model', 'PersonModel'); - if (!$lector_name = getData($this->PersonModel->getFullName($this->_uid))) - { - show_error ('Failed retrieving person'); - } + $result = $this->PersonModel->getFullName($this->_uid); + $lector_name = hasData($result) ? getData($result) : 'Ein Lektor'; // Link to Antrag genehmigen $url = @@ -343,22 +333,26 @@ class reviewAnrechnungDetail extends Auth_Controller CIS_ROOT. 'cis/menu.php?content_id=&content='. CIS_ROOT. index_page(). self::APPROVE_ANRECHNUNG_URI; - // Prepare mail content - $body_fields = array( - 'vorname' => $vorname, - 'lektor_name' => $lector_name, - 'empfehlung' => $empfehlung ? 'positive' : 'negative', - 'link' => anchor($url, 'Anrechnungsanträge Übersicht') - ); + // Get STGL mail address, if available, otherwise get assistance mail address + if( !$result = $this->_getSTGLMailAddress($studiengang_kz)) return false; + foreach ($result as $stgl) + { + // Prepare mail content + $body_fields = array( + 'vorname' => $stgl['vorname'], + 'lektor_name' => $lector_name, + 'empfehlung' => $empfehlung ? 'positive' : 'negative', + 'link' => anchor($url, 'Anrechnungsanträge Übersicht') + ); - sendSanchoMail( - 'AnrechnungEmpfehlungAbgeben', - $body_fields, - $to, - 'Anerkennung nachgewiesener Kenntnisse: Empfehlung wurde abgegeben' - ); + sendSanchoMail( + 'AnrechnungEmpfehlungAbgeben', + $body_fields, + $stgl['to'], + 'Anerkennung nachgewiesener Kenntnisse: Empfehlung wurde abgegeben' + ); + } } - return true; } @@ -369,28 +363,33 @@ class reviewAnrechnungDetail extends Auth_Controller $result = $this->StudiengangModel->getLeitung($stg_kz); // Get STGL mail address, if available - if (isSuccess($result) && hasData($result)) - { - return success(array( - $result->retval[0]->uid. '@'. DOMAIN, - $result->retval[0]->vorname - )); - } + if (hasData($result)) + { + foreach (getData($result) as $stgl) + { + $stglMailAdress_arr[]= array( + 'to' => $stgl->uid. '@'. DOMAIN, + 'vorname' => $stgl->vorname + ); + } + + return $stglMailAdress_arr; + } // ...otherwise get assistance mail address else { $result = $this->StudiengangModel->load($stg_kz); - if (isSuccess($result) && hasData($result)) + if (hasData($result)) { - return success(array( + return array( $result->retval[0]->email, '' - )); + ); } else { - return error('Keine E-Mail für diesen Stg gefunden'); + return false; } } } diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php index 974b32393..c63d0af69 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -257,20 +257,10 @@ class reviewAnrechnungUebersicht extends Auth_Controller // Send mail to STGL of each studiengang foreach ($studiengang_kz_arr as $studiengang_kz) { - // Get STGL mail address, if available, otherwise get assistance mail address - $stgmail = $this->_getSTGLMailAddress($studiengang_kz); - - if(isSuccess($stgmail) && hasData($stgmail)) - list ($to, $vorname) = getData($stgmail)[0]; - else - show_error ('Failed retrieving DegreeProgram Mail'); - // Get full name of lector $this->load->model('person/Person_model', 'PersonModel'); - if (!$lector_name = getData($this->PersonModel->getFullName($this->_uid))) - { - show_error ('Failed retrieving person'); - } + $result = $this->PersonModel->getFullName($this->_uid); + $lector_name = hasData($result) ? getData($result) : 'Ein Lektor'; // Link to Antrag genehmigen $url = @@ -278,22 +268,26 @@ class reviewAnrechnungUebersicht extends Auth_Controller CIS_ROOT. 'cis/menu.php?content_id=&content='. CIS_ROOT. index_page(). self::APPROVE_ANRECHNUNG_URI; - // Prepare mail content - $body_fields = array( - 'vorname' => $vorname, - 'lektor_name' => $lector_name, - 'empfehlung' => $empfehlung ? 'positive' : 'negative', - 'link' => anchor($url, 'Anrechnungsanträge Übersicht') - ); + // Get STGL mail address, if available, otherwise get assistance mail address + if (!$result = $this->_getSTGLMailAddress($studiengang_kz)) return false; + foreach ($result as $stgl) + { + // Prepare mail content + $body_fields = array( + 'vorname' => $stgl['vorname'], + 'lektor_name' => $lector_name, + 'empfehlung' => $empfehlung ? 'positive' : 'negative', + 'link' => anchor($url, 'Anrechnungsanträge Übersicht') + ); - sendSanchoMail( - 'AnrechnungEmpfehlungAbgeben', - $body_fields, - $to, - 'Anerkennung nachgewiesener Kenntnisse: Empfehlung wurde abgegeben' - ); + sendSanchoMail( + 'AnrechnungEmpfehlungAbgeben', + $body_fields, + $stgl['to'], + 'Anerkennung nachgewiesener Kenntnisse: Empfehlung wurde abgegeben' + ); + } } - return true; } @@ -304,28 +298,33 @@ class reviewAnrechnungUebersicht extends Auth_Controller $result = $this->StudiengangModel->getLeitung($stg_kz); // Get STGL mail address, if available - if (isSuccess($result) && hasData($result)) - { - return success(array( - $result->retval[0]->uid. '@'. DOMAIN, - $result->retval[0]->vorname - )); - } + if (hasData($result)) + { + foreach (getData($result) as $stgl) + { + $stglMailAdress_arr[]= array( + 'to' => $stgl->uid. '@'. DOMAIN, + 'vorname' => $stgl->vorname + ); + } + + return $stglMailAdress_arr; + } // ...otherwise get assistance mail address else { $result = $this->StudiengangModel->load($stg_kz); - if (isSuccess($result) && hasData($result)) + if (hasData($result)) { - return success(array( + return array( $result->retval[0]->email, '' - )); + ); } else { - return error('Keine E-Mail für diesen Stg gefunden'); + return false; } } } diff --git a/application/controllers/organisation/Studiensemester.php b/application/controllers/organisation/Studiensemester.php index 10fa5b3ad..685c8cd7c 100644 --- a/application/controllers/organisation/Studiensemester.php +++ b/application/controllers/organisation/Studiensemester.php @@ -138,7 +138,7 @@ class Studiensemester extends Auth_Controller $start = $this->input->post("semstart"); $ende = $this->input->post("semende"); $studienjahr_kurzbz = $this->input->post("studienjahrkurzbz"); - $beschreibung = $this->input->post("beschreibung"); + $beschreibung = isEmptyString($this->input->post("beschreibung")) ? null : $this->input->post("beschreibung"); $onlinebewerbung = $this->input->post("onlinebewerbung"); $onlinebewerbung = isset($onlinebewerbung); diff --git a/application/controllers/person/BPKWartung.php b/application/controllers/person/BPKWartung.php index 52cb09c5c..0d96f8a12 100644 --- a/application/controllers/person/BPKWartung.php +++ b/application/controllers/person/BPKWartung.php @@ -7,8 +7,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); */ class BPKWartung extends Auth_Controller { - private $_uid; // contains the UID of the logged user - /** * Constructor */ @@ -46,7 +44,7 @@ class BPKWartung extends Auth_Controller // Public methods /** - * Main page of the InfoCenter tool + * Main page of the bPK Wartung. */ public function index() { @@ -56,9 +54,7 @@ class BPKWartung extends Auth_Controller } /** - * Personal details page of the InfoCenter tool - * Initialization function, gets person and prestudent data and loads the view with the data - * @param $person_id + * bPK Details initialization function, gets person data and loads the view with the data. */ public function showDetails() { @@ -85,8 +81,7 @@ class BPKWartung extends Auth_Controller } /** - * Saves a ZGV for a prestudent, includes Ort, Datum, Nation for bachelor and master - * @param $prestudent_id + * Saves a bPK for a person. */ public function saveBPK() { @@ -112,7 +107,7 @@ class BPKWartung extends Auth_Controller // Private methods /** - * Loads all necessary Person data: Stammdaten (name, svnr, contact, ...), Dokumente, Logs and Notizen + * Loads all necessary Person data. * @param $person_id * @return array */ diff --git a/application/controllers/person/Gruppenmanagement.php b/application/controllers/person/Gruppenmanagement.php index acf32b00b..1a4c341a4 100644 --- a/application/controllers/person/Gruppenmanagement.php +++ b/application/controllers/person/Gruppenmanagement.php @@ -27,6 +27,7 @@ class Gruppenmanagement extends Auth_Controller // Loads models $this->load->model('person/benutzer_model', 'BenutzerModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); $this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel'); $this->load->model('system/Log_model', 'LogModel'); @@ -149,11 +150,8 @@ class Gruppenmanagement extends Auth_Controller if (isSuccess($result)) { - $this->LogModel->insert(array( - 'mitarbeiter_uid' => $this->_uid, - 'beschreibung' => 'Gruppenmanagement: Nutzer zu Gruppe hinzugefügt', - 'sql' => $lastQry - )); + $beschreibung = 'Gruppenmanagement: Nutzer zu Gruppe hinzugefügt'; + $this->_writeLog($this->_uid, $beschreibung, $lastQry); } } @@ -185,11 +183,8 @@ class Gruppenmanagement extends Auth_Controller if (isSuccess($result)) { - $this->LogModel->insert(array( - 'mitarbeiter_uid' => $this->_uid, - 'beschreibung' => 'Gruppenmanagement: Nutzer aus Gruppe entfernt', - 'sql' => $lastQry - )); + $beschreibung = 'Gruppenmanagement: Nutzer aus Gruppe entfernt'; + $this->_writeLog($this->_uid, $beschreibung, $lastQry); } $this->outputJson($result); @@ -234,4 +229,26 @@ class Gruppenmanagement extends Auth_Controller if (!$this->_uid) show_error('User authentification failed'); } + + /** + * Writes an entry in the log table + */ + private function _writeLog($uid, $beschreibung, $lastQry) + { + $mitarbeiterResult = $this->MitarbeiterModel->load(array('mitarbeiter_uid'=>$this->_uid)); + + if(!isSuccess($mitarbeiterResult) || !hasData($mitarbeiterResult)) + { + $uid = DUMMY_LEKTOR_UID; + $beschreibung .= ': '.$this->_uid; + $beschreibung = mb_substr($beschreibung, 0, 64); + } + + $this->LogModel->insert(array( + 'mitarbeiter_uid' => $uid, + 'beschreibung' => $beschreibung, + 'sql' => $lastQry + )); + } + } diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 76011dc04..48c50bb4a 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -88,6 +88,12 @@ class InfoCenter extends Auth_Controller 'message' => 'Type of Document %s was updated, set to %s', 'success' => null ), + 'deletedoc' => array( + 'logtype' => 'Action', + 'name' => 'Document deleted', + 'message' => 'Document %s deleted', + 'success' => null + ), ); // Name of Interessentenstatus @@ -131,6 +137,7 @@ class InfoCenter extends Auth_Controller 'reloadZgvPruefungen' => 'infocenter:r', 'reloadMessages' => 'infocenter:r', 'reloadDoks' => 'infocenter:r', + 'reloadUebersichtDoks' => 'infocenter:r', 'reloadNotizen' => array('infocenter:r', 'lehre/zgvpruefung:r'), 'reloadLogs' => 'infocenter:r', 'outputAkteContent' => array('infocenter:r', 'lehre/zgvpruefung:r'), @@ -142,7 +149,9 @@ class InfoCenter extends Auth_Controller 'getStudienjahrEnd' => array('infocenter:r', 'lehre/zgvpruefung:r'), 'setNavigationMenuArrayJson' => 'infocenter:r', 'getAbsageData' => 'infocenter:r', - 'saveAbsageForAll' => 'infocenter:rw' + 'saveAbsageForAll' => 'infocenter:rw', + 'deleteDoc' => 'infocenter:rw', + 'getStudienartData' => 'infocenter:rw' ) ); @@ -159,6 +168,10 @@ class InfoCenter extends Auth_Controller $this->load->model('system/Message_model', 'MessageModel'); $this->load->model('system/Filters_model', 'FiltersModel'); $this->load->model('system/PersonLock_model', 'PersonLockModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('codex/Zgv_model', 'ZgvModel'); + $this->load->model('codex/Zgvmaster_model', 'ZgvmasterModel'); + $this->load->model('codex/Nation_model', 'NationModel'); // Loads libraries $this->load->library('PersonLogLib'); @@ -398,6 +411,35 @@ class InfoCenter extends Auth_Controller $this->outputJsonSuccess(array($json)); } + public function deleteDoc($person_id) + { + $akte_id = $this->input->post('akteid'); + + if (isset($akte_id) && isset($person_id)) + { + $this->load->library('AkteLib'); + $akte = $this->aktelib->get($akte_id); + + if (hasData($akte)) + { + $akte = getData($akte); + if ($akte->person_id === (int)$person_id) + { + $result = $this->aktelib->remove($akte_id); + + if (isError($result)) + { + $this->terminateWithJsonError('Error deleting document'); + } + + $this->_log($person_id, 'deletedoc', array($akte->bezeichnung)); + + $this->outputJsonSuccess('success'); + } + } + } + } + /** * Gets prestudent data for a person in json format * @param $person_id @@ -1074,6 +1116,17 @@ class InfoCenter extends Auth_Controller $this->load->view('system/infocenter/dokNachzureichend.php', array('dokumente_nachgereicht' => $dokumente_nachgereicht->retval)); } + public function reloadUebersichtDoks($person_id) + { + $dokumente = $this->AkteModel->getAktenWithDokInfo($person_id, null, false); + + $this->DokumentModel->addOrder('bezeichnung'); + $dokumentdata = array('dokumententypen' => (getData($this->DokumentModel->load()))); + $data = array_merge($dokumentdata, ['dokumente' => $dokumente->retval]); + + $this->load->view('system/infocenter/dokpruefung.php', $data); + } + /** * Outputs content of an Akte, sends appropriate headers (so the document can be downloaded) * @param $akte_id @@ -1932,10 +1985,25 @@ class InfoCenter extends Auth_Controller $abwstatusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; $intstatusgruende = $this->StatusgrundModel->getStatus(self::INTERESSENTSTATUS)->retval; + $studienArtBerechtigung = array_column($this->getStudienArtBerechtigung(), 'typ'); + + $this->ZgvModel->addOrder('zgv_bez'); + $allZGVs = getData($this->ZgvModel->load()); + + $this->ZgvModel->addOrder('zgvmas_bez'); + $allZGVsMaster = getData($this->ZgvmasterModel->load()); + + $this->NationModel->addOrder('langtext'); + $allNations = getData($this->NationModel->load()); + $data = array ( 'zgvpruefungen' => $zgvpruefungen, 'abwstatusgruende' => $abwstatusgruende, - 'intstatusgruende' => $intstatusgruende + 'intstatusgruende' => $intstatusgruende, + 'studienArtBerechtigung' => $studienArtBerechtigung, + 'all_zgvs' => $allZGVs, + 'all_zgvs_master' => $allZGVsMaster, + 'all_nations' => $allNations, ); return $data; @@ -2194,18 +2262,36 @@ class InfoCenter extends Auth_Controller public function getAbsageData() { - $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter'); + $stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, ['b', 'm']); - $statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; - $studienSemester = $this->variablelib->getVar('infocenter_studiensemester'); - $studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(['b', 'm'], $studienSemester); + if (hasData($stg_typ)) + { + $stg_typ = getData($stg_typ); + $statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; + $studienSemester = $this->variablelib->getVar('infocenter_studiensemester'); + $studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(array_column($stg_typ, 'typ'), $studienSemester); - $data = array ( - 'statusgruende' => $statusgruende, - 'studiengaenge' => $studiengaenge->retval - ); + $data = array ( + 'statusgruende' => $statusgruende, + 'studiengaenge' => $studiengaenge->retval + ); - $this->outputJsonSuccess($data); + $this->outputJsonSuccess($data); + } + else + $this->outputJsonSuccess(null); + } + + public function getStudienArtBerechtigung() + { + $studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter'); + $stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, ['b', 'm', 'l']); + return getData($stg_typ); + } + public function getStudienartData() + { + $this->outputJsonSuccess($this->getStudienArtBerechtigung()); } public function saveAbsageForAll() diff --git a/application/controllers/system/issues/Issues.php b/application/controllers/system/issues/Issues.php index da92c251c..6d959a024 100644 --- a/application/controllers/system/issues/Issues.php +++ b/application/controllers/system/issues/Issues.php @@ -81,7 +81,7 @@ class Issues extends Auth_Controller } if (isEmptyString($changeIssueMethod)) - $errors[] = error("Invalid issue status given"); + $errors[] = "Invalid issue status given"; else { $issueRes = $this->issueslib->{$changeIssueMethod}($issue_id, $user); diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index b2c53a7d9..fccfe503b 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -50,62 +50,57 @@ class DmsLib $kategorie_kurzbz = null, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null ) { - // write file with content of fileHandle - $writeFileResult = $this->_writeNewFile($name, $fileHandle); + // create unique filename, using original document name to detect file extension + $filename = $this->_getUniqueFilename($name); - if (isError($writeFileResult)) return $writeFileResult; + // copy file from fileHandle to dms folder + $copyFileResult = $this->_copyFile($fileHandle, $filename); - if (hasData($writeFileResult)) + if (isError($copyFileResult)) return $copyFileResult; + + // if file written successful, insert dms + $dmsResult = $this->_ci->DmsModel->insert( + array( + 'kategorie_kurzbz' => $kategorie_kurzbz, + 'dokument_kurzbz' => $dokument_kurzbz + ) + ); + + if (isError($dmsResult)) return $dmsResult; + + if (hasData($dmsResult)) { - $writeFileData = getData($writeFileResult); - $filename = $writeFileData->filename; + $dms_id = getData($dmsResult); + $version = 0; - // if file written successful, insert dms - $dmsResult = $this->_ci->DmsModel->insert( - array( - 'kategorie_kurzbz' => $kategorie_kurzbz, - 'dokument_kurzbz' => $dokument_kurzbz - ) + // insert dms version + $dmsVersion = array( + 'dms_id' => $dms_id, + 'version' => $version, + 'filename' => $filename, + 'mimetype' => $mimetype, + 'name' => $name, + 'beschreibung' => $beschreibung, + 'cis_suche' => $cis_suche, + 'schlagworte' => $schlagworte, + 'insertvon' => $this->_who, + 'insertamum' => date('Y-m-d H:i:s') ); - if (isError($dmsResult)) return $dmsResult; + $dmsVersionResult = $this->_ci->DmsVersionModel->insert($dmsVersion); - if (hasData($dmsResult)) - { - $dms_id = getData($dmsResult); - $version = 0; + if (isError($dmsVersionResult)) return $dmsVersionResult; - // insert dms version - $dmsVersion = array( - 'dms_id' => $dms_id, - 'version' => $version, - 'filename' => $filename, - 'mimetype' => $mimetype, - 'name' => $name, - 'beschreibung' => $beschreibung, - 'cis_suche' => $cis_suche, - 'schlagworte' => $schlagworte, - 'insertvon' => $this->_who, - 'insertamum' => date('Y-m-d H:i:s') - ); + // return dms info + $resObj = new stdClass(); + $resObj->dms_id = $dms_id; + $resObj->version = $version; + $resObj->filename = $filename; - $dmsVersionResult = $this->_ci->DmsVersionModel->insert($dmsVersion); - - if (isError($dmsVersionResult)) return $dmsVersionResult; - - // return dms info - $resObj = new stdClass(); - $resObj->dms_id = $dms_id; - $resObj->version = $version; - $resObj->filename = $filename; - - return success($resObj); - } - else - return error("error when inserting DMS"); + return success($resObj); } else - return error("file could not be written"); + return error("error when inserting DMS"); } /** @@ -125,46 +120,41 @@ class DmsLib $originalName = isset($name) ? $name : $lastVersion->name; - // write new file with content of fileHandle - $writeFileResult = $this->_writeNewFile($originalName, $fileHandle); + // create unique filename, using original document name to detect file extension + $filename = $this->_getUniqueFilename($originalName); - if (isError($writeFileResult)) return $writeFileResult; + // copy file from fileHandle to dms folder + $copyFileResult = $this->_copyFile($fileHandle, $filename); - if (hasData($writeFileResult)) - { - $writeFileData = getData($writeFileResult); - $filename = $writeFileData->filename; + if (isError($copyFileResult)) return $copyFileResult; - // insert new version - $newVersionNumber = $lastVersion->version + 1; + // insert new version + $newVersionNumber = $lastVersion->version + 1; - // if new parameters given, use them, otherwise use parameters from last version - $newVersion = array( - 'dms_id' => $dms_id, - 'name' => $originalName, - 'filename' => $filename, - 'version' => $newVersionNumber, - 'mimetype' => isset($mimetype) ? $mimetype : $lastVersion->mimetype, - 'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung, - 'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche, - 'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte, - 'insertvon' => $this->_who, - 'insertamum' => date('Y-m-d H:i:s') - ); + // if new parameters given, use them, otherwise use parameters from last version + $newVersion = array( + 'dms_id' => $dms_id, + 'name' => $originalName, + 'filename' => $filename, + 'version' => $newVersionNumber, + 'mimetype' => isset($mimetype) ? $mimetype : $lastVersion->mimetype, + 'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung, + 'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche, + 'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte, + 'insertvon' => $this->_who, + 'insertamum' => date('Y-m-d H:i:s') + ); - $addVersionResult = $this->_ci->DmsVersionModel->insert($newVersion); + $addVersionResult = $this->_ci->DmsVersionModel->insert($newVersion); - if (isError($addVersionResult)) return $addVersionResult; + if (isError($addVersionResult)) return $addVersionResult; - // return dms info - $resObj = new stdClass(); - $resObj->version = $newVersionNumber; - $resObj->filename = $filename; + // return dms info + $resObj = new stdClass(); + $resObj->version = $newVersionNumber; + $resObj->filename = $filename; - return success($resObj); - } - else - return error("file could not be written"); + return success($resObj); } else return error("last version not found"); @@ -185,44 +175,37 @@ class DmsLib if (hasData($lastVersionResult)) { $lastVersion = getData($lastVersionResult); + $filename = $lastVersion->filename; // update file in filesystem - $writeFileResult = $this->_writeFile($lastVersion->filename, $fileHandle); + $copyFileResult = $this->_copyFile($fileHandle, $filename); - if (isError($writeFileResult)) return $writeFileResult; + if (isError($copyFileResult)) return $copyFileResult; - if (hasData($writeFileResult)) - { - $writeFileData = getData($writeFileResult); - $filename = $writeFileData->filename; + // if new parameters given, use them, otherwise use parameters from last version + $newVersion = array( + 'name' => isset($name) ? $name : $lastVersion->name, + 'filename' => $filename, + 'mimetype' => isset($mimetype) ? $mimetype : $lastVersion->mimetype, + 'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung, + 'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche, + 'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte, + ); - // if new parameters given, use them, otherwise use parameters from last version - $newVersion = array( - 'name' => isset($name) ? $name : $lastVersion->name, - 'filename' => $filename, - 'mimetype' => isset($mimetype) ? $mimetype : $lastVersion->mimetype, - 'beschreibung' => isset($beschreibung) ? $beschreibung : $lastVersion->beschreibung, - 'cis_suche' => isset($cis_suche) ? $cis_suche : $lastVersion->cis_suche, - 'schlagworte' => isset($schlagworte) ? $schlagworte : $lastVersion->schlagworte, - ); + // update last dms version + $addVersionResult = $this->_ci->DmsVersionModel->update( + array($dms_id, $lastVersion->version), + $newVersion + ); - // update last dms version - $addVersionResult = $this->_ci->DmsVersionModel->update( - array($dms_id, $lastVersion->version), - $newVersion - ); + if (isError($addVersionResult)) return $addVersionResult; - if (isError($addVersionResult)) return $addVersionResult; + // return dms info + $resObj = new stdClass(); + $resObj->version = $lastVersion->version; + $resObj->filename = $filename; - // return dms info - $resObj = new stdClass(); - $resObj->version = $lastVersion->version; - $resObj->filename = $filename; - - return success($resObj); - } - else - return error("file could not be written"); + return success($resObj); } else return error("last version not found"); @@ -441,68 +424,35 @@ class DmsLib // Private methods /** - * Writes file with content of fileHandle using original document name for file extension + * Copies file from sourceFileHandle to destinationFilename in DMS folder + * Returns success or error on fail */ - private function _writeNewFile($originalName, $fileHandle) + private function _copyFile($sourceFileHandle, $destinationFilename) { - // create unique filename, using original document name to detect file extension - $filename = $this->_getUniqueFilename($originalName); + // get file location from file handle + $metaData = stream_get_meta_data($sourceFileHandle); - // write the file - return $this->_writeFile($filename, $fileHandle); - } - - /** - * Writes file with content of fileHandle - * Returns number of bytes written and filename - */ - private function _writeFile($filename, $fileHandle) - { - // file content provided by fileHandle - $fileContent = ''; - - $readBlockResult = success(); - - // While the end of the file is not reached and the read does not fail - while (!feof($fileHandle) && isSuccess($readBlockResult = $this->_ci->DmsFSModel->readBlock($fileHandle))) + if (isset($metaData['uri']) && !isEmptyString($metaData['uri'])) { - // Concatenate the content of the file - $fileContent .= getData($readBlockResult); + // if file location determined, copy file + $source = $metaData['uri']; + + if (copy($source, DMS_PATH.$destinationFilename)) + { + return success(); + } + else + { + // error if copy returned false + return error('error occured while copying file'); + } } - - // If an error occurred while reading then return it - if (isError($readBlockResult)) return $readBlockResult; - - // open file for writing - $openFileResult = $this->_ci->DmsFSModel->openReadWrite($filename); - - if (isError($openFileResult)) return $openFileResult; - - if (!hasData($openFileResult)) return error("File could not be opened"); - - $newFileHandle = getData($openFileResult); - - // write file - $writeFileResult = $this->_ci->DmsFSModel->write($newFileHandle, $fileContent); - - if (isError($writeFileResult)) return $writeFileResult; - - // return number of bytes written and filename - $resObj = new stdClass(); - $resObj->bytesWritten = 0; - $resObj->filename = ''; - - if (hasData($writeFileResult)) + else { - $resObj->bytesWritten = getData($writeFileResult); - $resObj->filename = $filename; + // error when source location could not be determined + return error('error occured while getting source file name'); } - // close handle - $closeResult = $this->_ci->DmsFSModel->close($newFileHandle, $fileContent); - - if (isError($closeResult)) return $closeResult; - return success($resObj); } @@ -527,7 +477,7 @@ class DmsLib // ----------------------------------------------------------------------------------------------------------- // Deprecated methods, not to be used - + /** * Load a DMS Document. * If no version is particularly given, the latest version is loaded. @@ -543,7 +493,7 @@ class DmsLib $this->_ci->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id'); $this->_ci->DmsModel->addOrder('version', 'DESC'); $this->_ci->DmsModel->addLimit(1); - + if (!is_numeric($version)) { return $this->_ci->DmsModel->load($dms_id); @@ -620,7 +570,7 @@ class DmsLib return $result; } - + /** * Uploads a document and saves it to DMS * @param $dms DMS assoc array @@ -659,7 +609,7 @@ class DmsLib // Return result of uploaded data return success($upload_data); } - + /** * Download a document. * @@ -678,7 +628,7 @@ class DmsLib if (hasData($fileInfoResult)) { $fileObj = getData($fileInfoResult); - + // Change filename, if filename is provided if (!isEmptyString($filename)) $fileObj->name = $filename; @@ -694,7 +644,7 @@ class DmsLib // If no data have been found then return an empty success return success(); } - + /** * Get file information. * @@ -706,7 +656,7 @@ class DmsLib { // Checks the dms_id parameter if (!is_numeric($dms_id)) return error('Wrong parameter'); - + // Load DMS from database $result = $this->load($dms_id, $version); if (isError($result)) return error(getError($result)); @@ -951,4 +901,3 @@ class DmsLib $this->_ci->upload->initialize($config); } } - diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index 77085b182..9fe5d9e87 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -454,7 +454,7 @@ class ExtensionsLib require_once('version.php'); // get the core version // Checks if the required core version of the extension is the same of this system - if (isset($extensionJson->core_version) && $extensionJson->core_version == $fhcomplete_version) + if (isset($extensionJson->core_version) && version_compare($extensionJson->core_version, $fhcomplete_version,'<=')) { $this->_printMessage('Required core version: '.$extensionJson->core_version); $this->_printMessage('Current core version: '.$fhcomplete_version); diff --git a/application/libraries/FilterCmptLib.php b/application/libraries/FilterCmptLib.php index 429bc1b3b..9d6dfa681 100644 --- a/application/libraries/FilterCmptLib.php +++ b/application/libraries/FilterCmptLib.php @@ -271,95 +271,6 @@ class FilterCmptLib $this->_setSessionElement(FilterCmptLib::SESSION_TIMEOUT, strtotime('+'.$this->_sessionTimeout.' minutes', time())); } - /** - * Change the sort of the selected fields of the current filter - */ - public function sortSelectedFields($selectedFields) - { - $sortSelectedFields = false; - - // Checks the parameter selectedFields - if (isset($selectedFields) && is_array($selectedFields) && count($selectedFields) > 0) - { - // Retrieves all the used fields by the current filter - $fields = $this->_getSessionElement(self::SESSION_FIELDS); - - // Checks that the given selected fields are present in all the used fields by the current filter - if (!array_diff($selectedFields, $fields)) - { - $this->_setSessionElement(self::SESSION_SELECTED_FIELDS, $selectedFields); // write changes into the session - - $sortSelectedFields = true; - } - } - - return $sortSelectedFields; - } - - /** - * Add a field to the current filter - */ - public function addSelectedField($selectedField) - { - $removeSelectedField = false; - - // Checks the parameter selectedField - if (!isEmptyString($selectedField)) - { - // Retrieves all the used fields by the current filter - $fields = $this->_getSessionElement(self::SESSION_FIELDS); - // Retrieves the selected fields by the current filter - $selectedFields = $this->_getSessionElement(self::SESSION_SELECTED_FIELDS); - - // Checks that the given selected field is present in the list of all the used fields by the current filter - if (in_array($selectedField, $fields)) - { - array_push($selectedFields, $selectedField); // place the new filed at the end of the selected fields list - - $this->_setSessionElement(self::SESSION_SELECTED_FIELDS, $selectedFields); // write changes into the session - - $removeSelectedField = true; - } - } - - return $removeSelectedField; - } - - /** - * Remove a selected field from the current filter - */ - public function removeSelectedField($selectedField) - { - $removeSelectedField = false; - - // Checks the parameter selectedField - if (!isEmptyString($selectedField)) - { - // Retrieves all the used fields by the current filter - $fields = $this->_getSessionElement(self::SESSION_FIELDS); - // Retrieves the selected fields by the current filter - $selectedFields = $this->_getSessionElement(self::SESSION_SELECTED_FIELDS); - - // Checks that the given selected field is present in the list of all the used fields by the current filter - if (in_array($selectedField, $fields)) - { - // If the selected field is present in the list of the selected fields by the current filter - $pos = array_search($selectedField, $selectedFields); - if ($pos !== false) - { - // Then remove it and shift the rest of elements by one if needed - array_splice($selectedFields, $pos, 1); - } - - $this->_setSessionElement(self::SESSION_SELECTED_FIELDS, $selectedFields); // write changes into the session - - $removeSelectedField = true; - } - } - - return $removeSelectedField; - } - /** * Add a filter (SQL where clause) to be applied to the current filter */ @@ -593,6 +504,12 @@ class FilterCmptLib $saveCustomFilter = true; } + if ($saveCustomFilter === true) + { + $this->_setSessionElement(FilterCmptLib::SESSION_SIDE_MENU, + $this->_generateFilterMenu($this->_app, $this->_datasetName)); + } + return $saveCustomFilter; } @@ -659,7 +576,7 @@ class FilterCmptLib } else // otherwise { - $menuEntry->subscriptDescription = 'Remove'; + $menuEntry->subscriptDescription = '(Remove)'; $menuEntry->subscriptLinkClass = 'remove-custom-filter'; $menuEntry->subscriptLinkValue = $filter->{self::FILTER_ID}; @@ -851,15 +768,31 @@ class FilterCmptLib { // comparison (==) case self::OP_EQUAL: - if (is_numeric($filterDefinition->condition)) $condition = '= '.$filterDefinition->condition; + // Numeric + if (is_numeric($filterDefinition->condition)) + { + $condition = '= '.$filterDefinition->condition; + } + else // string type + { + $condition = '= \''.$this->_ci->FiltersModel->escapeLike($filterDefinition->condition).'\''; + } break; // not equal (!=) case self::OP_NOT_EQUAL: - if (is_numeric($filterDefinition->condition)) $condition = '!= '.$filterDefinition->condition; + // Numeric + if (is_numeric($filterDefinition->condition)) + { + $condition = '!= '.$filterDefinition->condition; + } + else // string type + { + $condition = '!= \''.$this->_ci->FiltersModel->escapeLike($filterDefinition->condition).'\''; + } break; // greater than (>) case self::OP_GREATER_THAN: - // It it's a date type + // If it's a date type if (is_numeric($filterDefinition->condition) && isset($filterDefinition->option) && ($filterDefinition->option == self::OPT_HOURS @@ -876,7 +809,7 @@ class FilterCmptLib break; // less than (<) case self::OP_LESS_THAN: - // It it's a date type + // If it's a date type if (is_numeric($filterDefinition->condition) && isset($filterDefinition->option) && ($filterDefinition->option == self::OPT_HOURS diff --git a/application/libraries/FilterWidgetLib.php b/application/libraries/FilterWidgetLib.php index d9a3428a0..19cdec848 100644 --- a/application/libraries/FilterWidgetLib.php +++ b/application/libraries/FilterWidgetLib.php @@ -340,20 +340,25 @@ class FilterWidgetLib { $filterDefinition = $filters[$filtersCounter]; // definition of one filter - if ($filtersCounter > 0) - $where .= ' AND '; // if it's NOT the last one - - if (!isEmptyString($filterDefinition->name)) // if the name of the applied filter is valid + // If the name of the applied filter is valid + if (!isEmptyString($filterDefinition->name)) { - // ...build the condition - $where .= '"'.$filterDefinition->name.'"'.$this->_getDatasetQueryCondition($filterDefinition); + // Build the query conditions + $datasetQueryCondition = $this->_getDatasetQueryCondition($filterDefinition); + + // If the built condition is valid then add it to the query clause + if (!isEmptyString($datasetQueryCondition)) + { + // // If this is NOT the first one + if ($filtersCounter > 0) $where .= ' AND '; + + $where .= '"'.$filterDefinition->name.'"'.$datasetQueryCondition; + } } } - if ($where != '') // if the SQL where clause was built - { - $datasetQuery .= ' WHERE '.$where; - } + // If the SQL where clause was built + if ($where != '') $datasetQuery .= ' WHERE '.$where; } return $datasetQuery; diff --git a/application/libraries/SearchBarLib.php b/application/libraries/SearchBarLib.php index ff2ae8934..3a9d06d13 100644 --- a/application/libraries/SearchBarLib.php +++ b/application/libraries/SearchBarLib.php @@ -122,11 +122,21 @@ class SearchBarLib p.person_id AS person_id, p.vorname || \' \' || p.nachname AS name, ARRAY_AGG(DISTINCT(org.bezeichnung)) AS organisationunit_name, - b.uid || \''.'@'.DOMAIN.'\' AS email, + COALESCE(b.alias, b.uid) || \''.'@'.DOMAIN.'\' AS email, TRIM(COALESCE(k.kontakt, \'\') || \' \' || COALESCE(m.telefonklappe, \'\')) AS phone, - \''.base_url(self::PHOTO_IMG_URL).'\' || p.person_id AS photo_url + \''.base_url(self::PHOTO_IMG_URL).'\' || p.person_id AS photo_url, + ARRAY_AGG(DISTINCT(stdkst.bezeichnung)) AS standardkostenstelle FROM public.tbl_mitarbeiter m JOIN public.tbl_benutzer b ON(b.uid = m.mitarbeiter_uid) + JOIN ( + SELECT o.bezeichnung, bf.uid + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + WHERE bf.funktion_kurzbz = \'kstzuordnung\' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + GROUP BY o.bezeichnung, bf.uid + ) stdkst ON stdkst.uid = b.uid JOIN public.tbl_person p USING(person_id) JOIN ( SELECT o.bezeichnung, bf.uid @@ -136,7 +146,7 @@ class SearchBarLib AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) GROUP BY o.bezeichnung, bf.uid - ) org USING(uid) + ) org ON org.uid = b.uid LEFT JOIN ( SELECT kontakt, standort_id FROM public.tbl_kontakt @@ -145,6 +155,8 @@ class SearchBarLib WHERE b.uid ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' OR p.vorname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' OR p.nachname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' + OR org.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' + OR stdkst.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone '); diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index 4975af382..b987102dd 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -528,6 +528,13 @@ class Messages_model extends CI_Model */ public function sendReply($receiver_id, $subject, $body, $relationmessage_id, $token) { + // Checks that the receiver_id, relationmessage_id and token belongs to the same message + $crossedDataResult = $this->MessageTokenModel->crossClientData($token, $relationmessage_id, $receiver_id); + if (isError($crossedDataResult)) show_error(getError($crossedDataResult)); + if (!hasData($crossedDataResult)) show_error( + 'The parameters token, relationmessage_id and receiver_id do not belong to the same message' + ); + // Retrieves message sender information $senderResult = $this->MessageTokenModel->getSenderData($receiver_id); if (isError($senderResult)) show_error(getError($senderResult)); diff --git a/application/models/codex/Gsprogramm_model.php b/application/models/codex/Gsprogramm_model.php new file mode 100644 index 000000000..4fd0694dd --- /dev/null +++ b/application/models/codex/Gsprogramm_model.php @@ -0,0 +1,15 @@ +dbTable = 'bis.tbl_gsprogramm'; + $this->pk = 'gsprogramm_id'; + } + +} diff --git a/application/models/codex/Mobilitaet_model.php b/application/models/codex/Mobilitaet_model.php new file mode 100644 index 000000000..13f966d50 --- /dev/null +++ b/application/models/codex/Mobilitaet_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_mobilitaet'; + $this->pk = 'mobilitaet_id'; + } +} diff --git a/application/models/codex/Nation_model.php b/application/models/codex/Nation_model.php index 239639795..ee38c9051 100644 --- a/application/models/codex/Nation_model.php +++ b/application/models/codex/Nation_model.php @@ -3,7 +3,7 @@ class Nation_model extends DB_Model { /** - * + * */ public function __construct() { @@ -11,4 +11,4 @@ class Nation_model extends DB_Model $this->dbTable = 'bis.tbl_nation'; $this->pk = 'nation_code'; } -} \ No newline at end of file +} diff --git a/application/models/crm/Dokumentprestudent_model.php b/application/models/crm/Dokumentprestudent_model.php index ab4764479..0a6669359 100644 --- a/application/models/crm/Dokumentprestudent_model.php +++ b/application/models/crm/Dokumentprestudent_model.php @@ -10,6 +10,7 @@ class Dokumentprestudent_model extends DB_Model parent::__construct(); $this->dbTable = 'public.tbl_dokumentprestudent'; $this->pk = array('prestudent_id', 'dokument_kurzbz'); + $this->hasSequence = false; } /** diff --git a/application/models/crm/Konto_model.php b/application/models/crm/Konto_model.php index 32fdd97c9..4b2a259c9 100644 --- a/application/models/crm/Konto_model.php +++ b/application/models/crm/Konto_model.php @@ -74,10 +74,11 @@ class Konto_model extends DB_Model } } - public function getLastStudienbeitrag($uid, $buchungstypen) + public function getStudienbeitraege($uid, $buchungstypen) { $query = 'SELECT konto.studiensemester_kurzbz - FROM public.tbl_konto konto, + FROM public.tbl_konto konto + JOIN public.tbl_studiensemester studiensemester ON konto.studiensemester_kurzbz = studiensemester.studiensemester_kurzbz, public.tbl_benutzer, public.tbl_student WHERE tbl_benutzer.uid = \'' . $uid . '\' @@ -91,7 +92,7 @@ class Konto_model extends DB_Model WHERE skonto.buchungsnr = konto.buchungsnr_verweis OR skonto.buchungsnr_verweis = konto.buchungsnr_verweis ) - ORDER BY buchungsnr DESC LIMIT 1; + ORDER BY studiensemester.start DESC; '; return $this->execQuery($query); diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index b7804952e..f37b715f4 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -556,7 +556,7 @@ class Prestudent_model extends DB_Model */ public function getOrganisationunitsByPersonId($person_id) { - $query = 'SELECT o.oe_kurzbz, + $query = 'SELECT DISTINCT o.oe_kurzbz, o.bezeichnung, (CASE WHEN sg.typ = \'b\' THEN ps.prestudent_id diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 0d0c248a6..e848cb4c2 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -507,4 +507,14 @@ class Studiengang_model extends DB_Model return $this->execQuery($query, array($typ, $semester)); } + + public function getStudiengangTyp($studiengang_kz, $typ) + { + $query = "SELECT DISTINCT(sgt.*) + FROM tbl_studiengangstyp sgt JOIN tbl_studiengang sg on sgt.typ = sg.typ + WHERE studiengang_kz IN ? and sgt.typ IN ?"; + + return $this->execQuery($query, array($studiengang_kz, $typ)); + + } } diff --git a/application/models/system/MessageToken_model.php b/application/models/system/MessageToken_model.php index cd3d8f7d9..af7794fdb 100644 --- a/application/models/system/MessageToken_model.php +++ b/application/models/system/MessageToken_model.php @@ -176,4 +176,20 @@ class MessageToken_model extends DB_Model return $this->execQuery($sql, array($oe_kurzbz)); } + + /** + * + */ + public function crossClientData($token, $relationmessage_id, $receiver_id) + { + $sql = 'SELECT mm.message_id + FROM public.tbl_msg_message mm + JOIN public.tbl_msg_recipient mr USING(message_id) + WHERE mr.token = ? + AND mm.message_id = ? + AND mm.person_id = ?'; + + return $this->execQuery($sql, array($token, $relationmessage_id, $receiver_id)); + } } + diff --git a/application/views/lehre/pruefungsprotokoll.php b/application/views/lehre/pruefungsprotokoll.php index 6179b5b25..208f2bdbb 100644 --- a/application/views/lehre/pruefungsprotokoll.php +++ b/application/views/lehre/pruefungsprotokoll.php @@ -1,46 +1,47 @@ load->view( - 'templates/FHC-Header', - array( - 'title' => 'Pruefungsprotokoll', - 'jquery3' => true, - 'jqueryui1' => true, - 'bootstrap3' => true, - 'fontawesome4' => true, - 'dialoglib' => true, - 'ajaxlib' => true, - 'sbadmintemplate3' => true, - 'phrases' => array( - 'abschlusspruefung' => array( - 'freigegebenAm', - 'pruefungGespeichert', - 'pruefungSpeichernFehler', - 'abschlussbeurteilungLeer', - 'beginnzeitLeer', - 'beginnzeitFormatError', - 'endezeitLeer', - 'endezeitFormatError', - 'endezeitBeforeError', - 'verfNotice' - ), - 'ui' => array( - 'stunde', - 'minute' - ) +$sitesettings = array( + 'title' => 'Pruefungsprotokoll', + 'jquery3' => true, + 'jqueryui1' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'dialoglib' => true, + 'ajaxlib' => true, + 'sbadmintemplate3' => true, + 'phrases' => array( + 'abschlusspruefung' => array( + 'freigegebenAm', + 'pruefungGespeichert', + 'pruefungSpeichernFehler', + 'abschlussbeurteilungLeer', + 'beginnzeitLeer', + 'beginnzeitFormatError', + 'endezeitLeer', + 'endezeitFormatError', + 'endezeitBeforeError', + 'verfNotice' ), - 'customCSSs' => array( - 'public/css/sbadmin2/admintemplate_contentonly.css', - 'vendor/fgelinas/timepicker/jquery.ui.timepicker.css', - 'public/css/lehre/pruefungsprotokoll.css' - ), - 'customJSs' => array( - 'vendor/fgelinas/timepicker/jquery.ui.timepicker.js', - 'public/js/lehre/pruefungsprotokoll.js' + 'ui' => array( + 'stunde', + 'minute' ) + ), + 'customCSSs' => array( + 'public/css/sbadmin2/admintemplate_contentonly.css', + 'vendor/fgelinas/timepicker/jquery.ui.timepicker.css', + 'public/css/lehre/pruefungsprotokoll.css' + ), + 'customJSs' => array( + 'vendor/fgelinas/timepicker/jquery.ui.timepicker.js', + 'public/js/lehre/pruefungsprotokoll.js' ) ); + +$this->load->view( + 'templates/FHC-Header', + $sitesettings +); ?> -
@@ -230,4 +231,8 @@ $this->load->view(
- +load->view( + 'templates/FHC-Footer', + $sitesettings +); diff --git a/application/views/person/gruppenmanagement/benutzergruppe.php b/application/views/person/gruppenmanagement/benutzergruppe.php index ea96777b0..c076f6dd0 100644 --- a/application/views/person/gruppenmanagement/benutzergruppe.php +++ b/application/views/person/gruppenmanagement/benutzergruppe.php @@ -11,7 +11,6 @@ 'tablesorter2' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'filterwidget' => true, 'navigationwidget' => true, 'phrases' => array( 'gruppenmanagement', diff --git a/application/views/person/gruppenmanagement/gruppenmanagementData.php b/application/views/person/gruppenmanagement/gruppenmanagementData.php index 6aa339ce7..ddbaea350 100644 --- a/application/views/person/gruppenmanagement/gruppenmanagementData.php +++ b/application/views/person/gruppenmanagement/gruppenmanagementData.php @@ -8,7 +8,7 @@ JOIN public.tbl_gruppe_manager grpmgr USING (gruppe_kurzbz) WHERE grp.aktiv = TRUE AND grpmgr.uid = \''.$uid.'\'', - 'requiredPermissions' => 'admin', + 'requiredPermissions' => 'lehre/gruppenmanager', 'datasetRepresentation' => 'tablesorter', 'additionalColumns' => array('Teilnehmer'), 'columnsAliases' => array( diff --git a/application/views/system/fas_udf.php b/application/views/system/fas_udf.php index 5ee8c9bfe..6d3c710ca 100644 --- a/application/views/system/fas_udf.php +++ b/application/views/system/fas_udf.php @@ -1,28 +1,30 @@ load->view( - 'templates/FHC-Header', - array( - 'title' => 'InfocenterDetails', - 'jquery3' => true, - 'bootstrap3' => true, - 'fontawesome4' => true, - 'jqueryui1' => true, - 'dialoglib' => true, - 'ajaxlib' => true, - 'udfs' => true, - 'widgets' => true, - 'sbadmintemplate3' => true, - 'customCSSs' => array( - 'public/css/sbadmin2/admintemplate.css' - ), - 'customJSs' => array( - 'public/js/bootstrapper.js' - ) - ) - ); +$sitesettings = array( + 'title' => 'InfocenterDetails', + 'jquery3' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'jqueryui1' => true, + 'dialoglib' => true, + 'ajaxlib' => true, + 'udfs' => true, + 'widgets' => true, + 'sbadmintemplate3' => true, + 'customCSSs' => array( + 'public/css/sbadmin2/admintemplate.css' + ), + 'customJSs' => array( + 'public/js/bootstrapper.js' + ) +); + +$this->load->view( + 'templates/FHC-Header', + $sitesettings +); ?> - +
@@ -104,7 +106,4 @@
- - -load->view("templates/footer"); ?> - +load->view("templates/FHC-Footer", $sitesettings); ?> diff --git a/application/views/system/infocenter/dokpruefung.php b/application/views/system/infocenter/dokpruefung.php index b184b9a0b..633f3ec02 100644 --- a/application/views/system/infocenter/dokpruefung.php +++ b/application/views/system/infocenter/dokpruefung.php @@ -1,10 +1,11 @@ -
- +
+
+ akte_id ?>">titel) ? $dokument->bezeichnung : $dokument->titel ?> + variablelib->getVar('infocenter_studiensemester').'\''; $ORG_NAME = '\'InfoCenter\''; + $ONLINE = '\'online\''; $query = ' SELECT @@ -55,10 +56,13 @@ a.dokument_kurzbz in ('.$AKTE_TYP.') ) AS "AnzahlAkte", ( - SELECT CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END + SELECT CASE WHEN student.student_uid IS NULL THEN + (CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END) + ELSE '. $ONLINE .' END FROM system.tbl_log l LEFT JOIN public.tbl_benutzer on l.insertvon = tbl_benutzer.uid LEFT JOIN public.tbl_person sp on tbl_benutzer.person_id = sp.person_id + LEFT JOIN public.tbl_student student ON tbl_benutzer.uid = student.student_uid WHERE l.taetigkeit_kurzbz IN ('.$TAETIGKEIT_KURZBZ.') AND l.logdata->>\'name\' NOT IN ('.$LOGDATA_NAME.') AND l.person_id = p.person_id diff --git a/application/views/system/infocenter/infocenterFreigegebenData.php b/application/views/system/infocenter/infocenterFreigegebenData.php index 75d60a179..13e1d5549 100644 --- a/application/views/system/infocenter/infocenterFreigegebenData.php +++ b/application/views/system/infocenter/infocenterFreigegebenData.php @@ -12,6 +12,7 @@ $STUDIENSEMESTER = '\''.$this->variablelib->getVar('infocenter_studiensemester').'\''; $ORG_NAME = '\'InfoCenter\''; $IDENTITY = '\'identity\''; + $ONLINE = '\'online\''; $query = ' SELECT @@ -42,10 +43,13 @@ $query = ' LIMIT 1 ) AS "LastActionType", ( - SELECT CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END + SELECT CASE WHEN student.student_uid IS NULL THEN + (CASE WHEN sp.nachname IS NULL THEN l.insertvon ELSE sp.nachname END) + ELSE '. $ONLINE .' END FROM system.tbl_log l LEFT JOIN public.tbl_benutzer on l.insertvon = tbl_benutzer.uid LEFT JOIN public.tbl_person sp on tbl_benutzer.person_id = sp.person_id + LEFT JOIN public.tbl_student student ON tbl_benutzer.uid = student.student_uid WHERE l.taetigkeit_kurzbz IN('.$TAETIGKEIT_KURZBZ.') AND l.logdata->>\'name\' NOT IN ('.$LOGDATA_NAME.') AND l.person_id = p.person_id @@ -178,7 +182,7 @@ $query = ' WHERE pss.status_kurzbz = '.$INTERESSENT_STATUS.' AND ps.person_id = p.person_id AND pss.studiensemester_kurzbz = '.$STUDIENSEMESTER.' - ORDER BY pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC + ORDER BY rtp.teilgenommen NULLS FIRST, pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC LIMIT 1 ) AS "ReihungstestAngetreten", ( @@ -199,7 +203,7 @@ $query = ' LIMIT 1 ) AS "ReihungstestApplied", ( - SELECT CONCAT(rtp.datum, rtp.uhrzeit) + SELECT (ARRAY_TO_STRING(array_agg(DISTINCT(CONCAT(rtp.datum, \' \', to_char(rtp.uhrzeit, \'HH24:MI\'), \' \', studiengang.kurzbzlang))), \', \')) FROM public.tbl_prestudentstatus pss JOIN public.tbl_prestudent ps USING(prestudent_id) LEFT JOIN ( @@ -207,14 +211,17 @@ $query = ' rt.studiensemester_kurzbz, rtp.teilgenommen, rt.datum, - rt.uhrzeit + rt.uhrzeit, + rt.studiengang_kz FROM public.tbl_rt_person rtp JOIN tbl_reihungstest rt ON(rtp.rt_id = rt.reihungstest_id) WHERE rt.stufe = 1 ) rtp ON(rtp.person_id = ps.person_id AND rtp.studiensemester_kurzbz = pss.studiensemester_kurzbz) + JOIN tbl_studiengang studiengang ON rtp.studiengang_kz = studiengang.studiengang_kz WHERE pss.status_kurzbz = '.$INTERESSENT_STATUS.' AND ps.person_id = p.person_id AND pss.studiensemester_kurzbz = '.$STUDIENSEMESTER.' + GROUP BY pss.datum, pss.insertamum, pss.ext_id ORDER BY pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC LIMIT 1 ) AS "ReihungstestDate", @@ -414,10 +421,6 @@ $query = ' { $datasetRaw->{'ReihungstestDate'} = '-'; } - else - { - $datasetRaw->{'ReihungstestDate'} = date_format(date_create($datasetRaw->{'ReihungstestDate'}),'Y-m-d H:i'); - } if ($datasetRaw->{'ZGVNation'} == null) { diff --git a/application/views/system/infocenter/zgvpruefungen.php b/application/views/system/infocenter/zgvpruefungen.php index 253145557..2e6ea90d2 100644 --- a/application/views/system/infocenter/zgvpruefungen.php +++ b/application/views/system/infocenter/zgvpruefungen.php @@ -124,6 +124,32 @@
+ prestudentstatus->bewerbung_abgeschicktamum)) + { + $disabled = $disabledStg = 'disabled'; + $disabledTxt = $disabledStgTxt = $this->p->t('infocenter', 'bewerbungMussAbgeschickt'); + } + + if ($studiengangtyp !== 'b' && $studiengangtyp !== 'm') + { + $disabled = 'disabled'; + $disabledTxt = $this->p->t('infocenter', 'nurBachelorMasterFreigeben'); + + // FIT-Lehrgänge: exceptions, can be freigegeben in Infocenter + if (!in_array($studiengang_kz, $fit_programme_studiengaenge)) + { + $disabledStg = 'disabled'; + $disabledStgTxt = $this->p->t('infocenter', 'nurBachelorMasterFreigeben'); + } + } + + if (!in_array($studiengangtyp, $studienArtBerechtigung)) + $disabledPer = 'disabled'; + else + $disabledPer = ''; + ?>
@@ -196,12 +222,25 @@ p->t('infocenter', 'zgv') ?>
- widgetlib->widget( - 'Zgv_widget', - array(DropdownWidget::SELECTED_ELEMENT => $zgvpruefung->zgv_code), - array('name' => 'zgv', 'id' => 'zgv_'.$zgvpruefung->prestudent_id) - ); ?> + prestudent_id . "' name='zgv' class='form-control'>"; + $selectedDefault = (is_null($zgvpruefung->zgv_code) ? 'selected' : ''); + echo ""; + foreach ($all_zgvs as $zgv) + { + $selected = ($zgvpruefung->zgv_code === $zgv->zgv_code) ? 'selected' : ''; + $aktiv = ''; + $class = ''; + if (!$zgv->aktiv) + { + $aktiv = '(inaktiv)'; + $class = 'gesperrtoption'; + } + + echo ""; + } + echo ""; + endif;?>
@@ -239,11 +278,26 @@ zgvnation_bez; else - echo $this->widgetlib->widget( - 'Nation_widget', - array(DropdownWidget::SELECTED_ELEMENT => $zgvpruefung->zgvnation_code), - array('name' => 'zgvnation', 'id' => 'zgvnation_'.$zgvpruefung->prestudent_id) - ); ?> + { + echo ""; + } + ?>
@@ -256,11 +310,25 @@ if ($infoonly) echo $zgvpruefung->zgvmas_bez; else - echo $this->widgetlib->widget( - 'Zgvmaster_widget', - array(DropdownWidget::SELECTED_ELEMENT => $zgvpruefung->zgvmas_code), - array('name' => 'zgvmas', 'id' => 'zgvmas_'.$zgvpruefung->prestudent_id) - ); ?> + { + echo ""; + } + ?>
@@ -300,11 +368,28 @@ if ($infoonly) echo $zgvpruefung->zgvmanation_bez; else - echo $this->widgetlib->widget( - 'Nation_widget', - array(DropdownWidget::SELECTED_ELEMENT => $zgvpruefung->zgvmanation_code), - array('name' => 'zgvmanation', 'id' => 'zgvmanation_'.$zgvpruefung->prestudent_id) - ); ?> + { + echo ""; + } + ?>
@@ -318,17 +403,17 @@
- - statusZGV))) ?: print_r('data-info="need"')?>>
-
@@ -336,7 +421,7 @@
prestudentUdfs)) + if (isset($zgvpruefung->prestudentUdfs) && $studiengangtyp !== 'l') { echo $this->udflib->UDFWidget( array( @@ -362,6 +447,8 @@
+ required>
- @@ -489,6 +558,8 @@
'; diff --git a/include/student.class.php b/include/student.class.php index 55733dd94..cfea879a9 100644 --- a/include/student.class.php +++ b/include/student.class.php @@ -531,6 +531,33 @@ class student extends benutzer } } + /** + * Check, ob inputparameter gültige studenten_id ist + * @param matrikelnummer oder student_uid + * @return ok, wenn gültige Id, sonst false + */ + public function checkIfValidStudentUID($uid) + { + $qry = "SELECT student_uid FROM public.tbl_student WHERE student_uid=".$this->db_add_param($uid); + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + return true; + } + else + { + return false; + } + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + /** * Laedt die UID anhand der Matrikelnummer * @param matrikelnummer diff --git a/include/studienplan.class.php b/include/studienplan.class.php index 7e9963c0a..f180733fe 100644 --- a/include/studienplan.class.php +++ b/include/studienplan.class.php @@ -952,21 +952,34 @@ class studienplan extends basis_db /** * Laedt die Studienplaene zu denen eine Lehrveranstaltung zugeordnet ist */ - public function getStudienplanLehrveranstaltung($lehrveranstaltung_id, $studiensemester_kurzbz) + public function getStudienplanLehrveranstaltung($lehrveranstaltung_id, $studiensemester_kurzbz = null) { $qry= " SELECT - distinct tbl_studienplan.* + DISTINCT tbl_studienplan.* FROM - lehre.tbl_studienplan - JOIN lehre.tbl_studienplan_lehrveranstaltung USING(studienplan_id) + lehre.tbl_studienplan + JOIN lehre.tbl_studienplan_lehrveranstaltung + USING(studienplan_id) WHERE - tbl_studienplan_lehrveranstaltung.lehrveranstaltung_id=".$this->db_add_param($lehrveranstaltung_id, FHC_INTEGER)." - AND EXISTS ( - SELECT 1 FROM lehre.tbl_studienplan_semester - WHERE studienplan_id=tbl_studienplan.studienplan_id - AND studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz)." - AND semester = tbl_studienplan_lehrveranstaltung.semester) + tbl_studienplan_lehrveranstaltung.lehrveranstaltung_id IN ( + SELECT + lv.lehrveranstaltung_id + FROM + lehre.tbl_lehrveranstaltung AS lv + LEFT JOIN lehre.tbl_lehrveranstaltung AS t ON t.lehrveranstaltung_id=lv.lehrveranstaltung_template_id + WHERE + lv.lehrtyp_kurzbz<>'tpl' + AND (lv.lehrveranstaltung_id=" . $this->db_add_param($lehrveranstaltung_id, FHC_INTEGER) . " OR (lv.lehrveranstaltung_template_id=" . $this->db_add_param($lehrveranstaltung_id, FHC_INTEGER) . " AND t.lehrtyp_kurzbz='tpl')) + ) + AND EXISTS ( + SELECT 1 + FROM + lehre.tbl_studienplan_semester + WHERE studienplan_id=tbl_studienplan.studienplan_id". + ($studiensemester_kurzbz != null ? " + AND studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz) : "")." + AND semester = tbl_studienplan_lehrveranstaltung.semester) ORDER BY bezeichnung"; if($result = $this->db_query($qry)) diff --git a/include/zeitaufzeichnung.class.php b/include/zeitaufzeichnung.class.php index fd007d1ad..7f46d763a 100644 --- a/include/zeitaufzeichnung.class.php +++ b/include/zeitaufzeichnung.class.php @@ -940,7 +940,7 @@ or not exists $tagessaldo = $tagessaldo - $pausesumme; //check if blocking error - if (($tagessaldo > 19800 && $pausesumme < 1800) || ($tagessaldo > 18000 && $tagessaldo < 19800 && $pausesumme < $tagessaldo - 18000)) + if (($tagessaldo >= 19800 && $pausesumme < 1800) || ($tagessaldo > 18000 && $tagessaldo < 19800 && $pausesumme < $tagessaldo - 18000)) { $blockingError = true; } diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index e8ef6d8d6..3c8063936 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -170,7 +170,7 @@ $this->phrasen['benotungstool/eingetrageneNoten']='Eingetragene Noten'; $this->phrasen['benotungstool/zeunis']='Zeugnis'; $this->phrasen['benotungstool/handbuch']='Handbuch'; $this->phrasen['benotungstool/punkte']='Punkte'; -$this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten Personenkennzeichen und Note aus der Notenliste und fügen Sie diese in folgendes Feld ein'; +$this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten Personenkennzeichen und Note aus der Notenliste (bzw. StudentenUid und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; $this->phrasen['benotungstool/pruefung']='Prüfung'; $this->phrasen['benotungstool/notenlisteImport']='Notenliste für den LV-Noten-Import (Excel)'; $this->phrasen['benotungstool/bearbeitetvon']='Bearbeitet von'; diff --git a/locale/de-AT/freebusy.php b/locale/de-AT/freebusy.php index dfe9b89ca..2e06ab5c3 100644 --- a/locale/de-AT/freebusy.php +++ b/locale/de-AT/freebusy.php @@ -6,6 +6,8 @@ $this->phrasen['freebusy/aktiv']='Aktiv'; $this->phrasen['freebusy/PfadZuFreebusyUrl']='Ihre Freebusy URL ist unter folgendem Link erreichbar:'; $this->phrasen['freebusy/LVPlanBezeichnung']='Persönlicher LVPlan'; $this->phrasen['freebusy/LVPlanTyp']='LVPlan'; +$this->phrasen['freebusy/ZeitsperrenBezeichnung']='Meine Zeitsperren'; +$this->phrasen['freebusy/ZeitsperrenTyp']='Zeitsperren'; $this->phrasen['freebusy/neuerEintrag']='Neuen Eintrag hinzufügen'; $this->phrasen['freebusy/beschreibungstext1']='Auf dieser Seite können Sie verschiedene externe FreeBusy Informationen zu Ihrer persönlichen FreeBusy URL zusammenfassen.
Diese wird z.B. für das hausinterne "Coodle" herangezogen.

diff --git a/locale/de-AT/global.php b/locale/de-AT/global.php index 7104a83a5..4d16e40bf 100644 --- a/locale/de-AT/global.php +++ b/locale/de-AT/global.php @@ -71,6 +71,7 @@ $this->phrasen['global/aenderungenZuruecksetzen']= "Änderungen zurücks $this->phrasen['global/username']='Username'; $this->phrasen['global/vorname']='Vorname'; $this->phrasen['global/nachname']='Nachname'; +$this->phrasen['global/wahlname']='Wahlname'; $this->phrasen['global/anrede']='Anrede'; $this->phrasen['global/name']='Name'; $this->phrasen['global/uid']='UID'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index 94b0e7891..17f78d2ba 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -169,7 +169,7 @@ $this->phrasen['benotungstool/eingetrageneNoten']='Submitted Grades'; $this->phrasen['benotungstool/zeunis']='Transcript'; $this->phrasen['benotungstool/handbuch']='Handbook'; $this->phrasen['benotungstool/punkte']='Points'; -$this->phrasen['benotungstool/importAnweisung']='Copy the columns "personal identifier" and "grade" from the grade list and insert them in the following field'; +$this->phrasen['benotungstool/importAnweisung']='Copy the columns "personal identifier" and "grade" from the grade list (or "student ID number" and "grade" from the moodle export file) and insert them in the following field'; $this->phrasen['benotungstool/pruefung']='Examination'; $this->phrasen['benotungstool/notenlisteImport']='Grade list for the subject grade import (Excel)'; $this->phrasen['benotungstool/geaenderteNotenVorhanden']='There are changed grades. Please send the changes to the assistant by clicking "Approval"'; diff --git a/locale/en-US/freebusy.php b/locale/en-US/freebusy.php index 657f31333..f504a3ab0 100644 --- a/locale/en-US/freebusy.php +++ b/locale/en-US/freebusy.php @@ -6,13 +6,15 @@ $this->phrasen['freebusy/aktiv']='Active'; $this->phrasen['freebusy/PfadZuFreebusyUrl']='Your Freebusy URL can be accessed at:'; $this->phrasen['freebusy/LVPlanBezeichnung']='Personal schedule'; $this->phrasen['freebusy/LVPlanTyp']='Schedule'; +$this->phrasen['freebusy/ZeitsperrenBezeichnung']='My Planned Absences'; +$this->phrasen['freebusy/ZeitsperrenTyp']='Absences'; $this->phrasen['freebusy/neuerEintrag']='Add a new Entry'; $this->phrasen['freebusy/beschreibungstext1']='On this page you can combine different external FreeBusy information to create your personal FreeBusy URL.
- This is used for example for the in-house "Coodle".

+ This is used for example for the in-house "Coodle".

FreeBusy is a function that allows you to see when others are free or busy (without revealing sensitive details such as the appointment titles or content).
- This tool allows you and your colleagues to efficiently schedule meetings.

+ This tool allows you and your colleagues to efficiently schedule meetings.

To effectively use your FreeBusy URL it is necessary to carefully enter and update your calendar data.
- In general, you can enter the times that you are available or busy in a web calendar for both entire calendars as well as individual appointments.

+ In general, you can enter the times that you are available or busy in a web calendar for both entire calendars as well as individual appointments.

Examples:If I enter the vacations of my colleagues, it makes sense to add them to a separate calendar that is not included in MY availability.
Any notes that I add to my personal calendar should also be marked as "available", unless I am actually busy for that time period.

'; diff --git a/locale/en-US/global.php b/locale/en-US/global.php index 97f5cfe26..d62a264c6 100644 --- a/locale/en-US/global.php +++ b/locale/en-US/global.php @@ -70,6 +70,7 @@ $this->phrasen['global/aenderungenZuruecksetzen']= "Reset changes"; $this->phrasen['global/username']='Username'; $this->phrasen['global/vorname']='First Name'; $this->phrasen['global/nachname']='Last Name'; +$this->phrasen['global/wahlname']='Name of Choice'; $this->phrasen['global/anrede']='Title'; $this->phrasen['global/name']='Name'; $this->phrasen['global/uid']='UID'; diff --git a/public/css/FilterComponent.css b/public/css/components/FilterComponent.css similarity index 67% rename from public/css/FilterComponent.css rename to public/css/components/FilterComponent.css index e549ad263..cd0b33a48 100644 --- a/public/css/FilterComponent.css +++ b/public/css/components/FilterComponent.css @@ -1,32 +1,27 @@ .filter-header-title { - font-weight: bold; - font-size: 16px; - text-decoration: none; - color: #333; - font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; - padding-top: 0.75rem !important; + text-align: right; +} + +.filter-header-title-span-filter { + margin-right: 7px; +} + +.filter-header-title-span-icon { + margin-right: 3px; cursor: pointer; } -.filter-filter-options { - margin-bottom: 30px; -} - .filter-options-div { - margin-bottom: 12px; - padding-bottom: 12px; - border-bottom-style: solid; - border-bottom-color: rgba(0, 0, 0, 0.125); - border-bottom-width: 1px; + padding: 10px; } -.filter-dnd-area { +.filter-fields-area { height: 50px; padding: 3px; margin-bottom: 10px; } -.filter-dnd-object { +.filter-fields-field { height: 100%; margin-left: 7px; padding: 11px; @@ -37,7 +32,7 @@ border-width: 1px; border-radius: 7px; font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; - cursor: move; + cursor: pointer; } .filter-filter-fields { @@ -65,3 +60,7 @@ border-right: 2px solid #428bca; } +.filter-table-dataset { + margin-top: 20px; +} + diff --git a/public/css/NavigationComponent.css b/public/css/components/NavigationComponent.css similarity index 92% rename from public/css/NavigationComponent.css rename to public/css/components/NavigationComponent.css index 3e2273b67..2d64d9cdc 100644 --- a/public/css/NavigationComponent.css +++ b/public/css/components/NavigationComponent.css @@ -55,6 +55,14 @@ border-bottom: none !important; } +.left-side-menu-second-level span { + display: inline-flex; +} + +.remove-custom-filter { + font-size: 10px !important; +} + .left-side-menu-link-entry { font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; font-size: 14px; diff --git a/public/css/infocenter/infocenterDetails.css b/public/css/infocenter/infocenterDetails.css index 2f2debc00..cf81d073b 100644 --- a/public/css/infocenter/infocenterDetails.css +++ b/public/css/infocenter/infocenterDetails.css @@ -104,3 +104,7 @@ display: inline-block } } + +.gesperrtoption { + color: gray; +} \ No newline at end of file diff --git a/public/js/components/filter/API.js b/public/js/components/filter/API.js index 9c208a08c..ff09c452d 100644 --- a/public/js/components/filter/API.js +++ b/public/js/components/filter/API.js @@ -40,6 +40,22 @@ export const CoreFilterAPIs = { } ); }, + /** + * + */ + removeCustomFilter: function(wsParams) { + return CoreRESTClient.post( + 'components/Filter/removeCustomFilter', + { + filterUniqueId: wsParams.filterUniqueId, + filterType: wsParams.filterType, + filterId: wsParams.filterId + }, + { + timeout: CORE_FILTER_CMPT_TIMEOUT + } + ); + }, /** * */ @@ -72,38 +88,6 @@ export const CoreFilterAPIs = { } ); }, - /** - * - */ - addSelectedField: function(wsParams) { - return CoreRESTClient.post( - 'components/Filter/addSelectedField', - { - filterUniqueId: wsParams.filterUniqueId, - filterType: wsParams.filterType, - selectedField: wsParams.selectedField - }, - { - timeout: CORE_FILTER_CMPT_TIMEOUT - } - ); - }, - /** - * - */ - removeSelectedField: function(wsParams) { - return CoreRESTClient.post( - 'components/Filter/removeSelectedField', - { - filterUniqueId: wsParams.filterUniqueId, - filterType: wsParams.filterType, - selectedField: wsParams.selectedField - }, - { - timeout: CORE_FILTER_CMPT_TIMEOUT - } - ); - }, /** * */ diff --git a/public/js/components/filter/Filter.js b/public/js/components/filter/Filter.js index 0deb57941..87100a00c 100644 --- a/public/js/components/filter/Filter.js +++ b/public/js/components/filter/Filter.js @@ -19,6 +19,10 @@ import {CoreFilterAPIs} from './API.js'; import {CoreRESTClient} from '../../RESTClient.js'; import {CoreFetchCmpt} from '../../components/Fetch.js'; +// +const FILTER_COMPONENT_NEW_FILTER = 'Filter Component New Filter'; +const FILTER_COMPONENT_NEW_FILTER_TYPE = 'Filter Component New Filter Type'; + /** * */ @@ -28,6 +32,11 @@ export const CoreFilterCmpt = { CoreFetchCmpt }, props: { + title: String, + sideMenu: { + type: Boolean, + default: true + }, filterType: { type: String, required: true @@ -38,19 +47,24 @@ export const CoreFilterCmpt = { data: function() { return { // FilterCmpt properties + filterName: null, fields: null, dataset: null, datasetMetadata: null, selectedFields: null, notSelectedFields: null, filterFields: null, - notFilterFields: null, + columnsAlias: null, + + availableFilters: null, // FetchCmpt binded properties fetchCmptRefresh: false, fetchCmptApiFunction: null, fetchCmptApiFunctionParams: null, - fetchCmptDataFetched: null + fetchCmptDataFetched: null, + + tabulator: null }; }, created: function() { @@ -100,19 +114,23 @@ export const CoreFilterCmpt = { // If the column has to be displayed or not selectedFields.indexOf(columns[i].field) >= 0 ? columns[i].visible = true : columns[i].visible = false; - if( columns[i].hasOwnProperty('resizable') ) { - columns[i].visible ? columns[i].resizable = true : columns[i].resizable = false; + if (columns[i].hasOwnProperty('resizable')) + { + columns[i].visible ? columns[i].resizable = true : columns[i].resizable = false; } } } + this.columnsAlias = columns; + // Define a default tabulator options in case it was not provided let tabulatorOptions = { height: 500, layout: "fitColumns", + movableColumns: true, + reactiveData: true, columns: columns, - data: JSON.parse(JSON.stringify(this.dataset)), - reactiveData: true + data: JSON.parse(JSON.stringify(this.dataset)) }; // If it was provided @@ -120,14 +138,15 @@ export const CoreFilterCmpt = { { // Then copy it... tabulatorOptions = this.tabulatorOptions; - // ...and overwrite the properties data, reactiveData and columns + // ...and overwrite the properties data, reactiveData, movableColumns and columns tabulatorOptions.data = JSON.parse(JSON.stringify(this.dataset)); - tabulatorOptions.reactiveData = true; tabulatorOptions.columns = columns; + tabulatorOptions.reactiveData = true; + tabulatorOptions.movableColumns = true; } // Start the tabulator with the buid options - let tabulator = new Tabulator( + this.tabulator = new Tabulator( "#filterTableDataset", tabulatorOptions ); @@ -138,7 +157,7 @@ export const CoreFilterCmpt = { // Attach all the provided event handlers to the started tabulator for (let i = 0; i < this.tabulatorEvents.length; i++) { - tabulator.on(this.tabulatorEvents[i].event, this.tabulatorEvents[i].handler); + this.tabulator.on(this.tabulatorEvents[i].event, this.tabulatorEvents[i].handler); } } }, @@ -158,17 +177,17 @@ export const CoreFilterCmpt = { if (CoreRESTClient.hasData(response)) { let data = CoreRESTClient.getData(response); + this.filterName = data.filterName; this.dataset = data.dataset; this.datasetMetadata = data.datasetMetadata; this.fields = data.fields; this.selectedFields = data.selectedFields; this.notSelectedFields = this.fields.filter(x => this.selectedFields.indexOf(x) === -1); - this.filterFields = []; - let tmpFilterFields = []; + for (let i = 0; i < data.datasetMetadata.length; i++) { - for (let j = 0; j< data.filters.length; j++) + for (let j = 0; j < data.filters.length; j++) { if (data.datasetMetadata[i].name == data.filters[j].name) { @@ -176,14 +195,20 @@ export const CoreFilterCmpt = { filter.type = data.datasetMetadata[i].type; this.filterFields.push(filter); - tmpFilterFields.push(filter.name); break; } } } - this.notFilterFields = this.fields.filter(x => tmpFilterFields.indexOf(x) === -1); - this.setSideMenu(data); + // If the side menu is active + if (this.sideMenu === true) + { + this.setSideMenu(data); + } + else // otherwise use the dropdown in the filter options + { + this.setDropDownMenu(data); + } } else { @@ -212,6 +237,26 @@ export const CoreFilterCmpt = { }; } + for (let filtersCount = 0; filtersCount < personalFilters.length; filtersCount++) + { + let link = personalFilters[filtersCount].link; + + if (link == null) link = '#'; + + filtersArray[filtersArray.length] = { + link: link + personalFilters[filtersCount].filter_id, + description: personalFilters[filtersCount].desc, + subscriptDescription: personalFilters[filtersCount].subscriptDescription, + subscriptLinkClass: personalFilters[filtersCount].subscriptLinkClass, + subscriptLinkValue: personalFilters[filtersCount].subscriptLinkValue, + sort: filtersCount, + onClickCall: this.handlerGetFilterById, + onClickSubscriptCall: this.handlerRemoveCustomFilter + }; + } + + this.availableFilters = filtersArray; + this.$emit( 'nwNewEntry', { @@ -222,6 +267,40 @@ export const CoreFilterCmpt = { } ); }, + /** + * Set the drop down menu + */ + setDropDownMenu: function(data) { + let filters = data.sideMenu.filters; + let personalFilters = data.sideMenu.personalFilters; + let filtersArray = []; + + for (let filtersCount = 0; filtersCount < filters.length; filtersCount++) + { + let link = filters[filtersCount].link; + + if (link == null) link = '#'; + + filtersArray[filtersArray.length] = { + option: filters[filtersCount].filter_id, + description: filters[filtersCount].desc + }; + } + + for (let filtersCount = 0; filtersCount < personalFilters.length; filtersCount++) + { + let link = personalFilters[filtersCount].link; + + if (link == null) link = '#'; + + filtersArray[filtersArray.length] = { + option: personalFilters[filtersCount].filter_id, + description: personalFilters[filtersCount].desc + }; + } + + this.availableFilters = filtersArray; + }, /** * Used to start/refresh the FetchCmpt */ @@ -261,52 +340,72 @@ export const CoreFilterCmpt = { this.getFilter ); }, + /** + * + */ + handlerRemoveCustomFilter: function(event) { + // + this.startFetchCmpt( + CoreFilterAPIs.removeCustomFilter, + { + filterId: event.currentTarget.getAttribute("href").substring(1) + }, + this.getFilter + ); + }, /** * */ handlerApplyFilterFields: function(event) { let filterFields = []; - let filterFieldDivs = document.getElementById('filterFields').getElementsByTagName('div'); + let filterFieldDivRows = document.getElementById('filterFields').getElementsByClassName('row'); - for (let i = 0; i< filterFieldDivs.length; i++) + for (let i = 0; i< filterFieldDivRows.length; i++) { let filterField = {}; - for (let j = 0; j< filterFieldDivs[i].children.length; j++) + for (let j = 0; j< filterFieldDivRows[i].children.length; j++) { - if (filterFieldDivs[i].children[j].name != null) + let filterColumn = filterFieldDivRows[i].children[j]; + let filterColumnElement = filterColumn.children[0]; + + // If the first column then search for the fields dropdown + if (j == 0) filterColumnElement = filterColumnElement.querySelector('select[name=fieldName]'); + + // If the filter name is _not_ null and it is _not_ a new filter + if (filterColumnElement.name != null && filterColumnElement.name != FILTER_COMPONENT_NEW_FILTER) { // Condition - if (filterFieldDivs[i].children[j].name == 'condition' && filterFieldDivs[i].children[j].value == "") + if (filterColumnElement.name == 'condition' && filterColumnElement.value == "") { alert("Please fill all the filter options"); return; } // Name - if (filterFieldDivs[i].children[j].name == 'fieldName') + if (filterColumnElement.name == 'fieldName') { - filterField.name = filterFieldDivs[i].children[j].value; + filterField.name = filterColumnElement.value; } // Operation - if (filterFieldDivs[i].children[j].name == 'operation') + if (filterColumnElement.name == 'operation') { - filterField.operation = filterFieldDivs[i].children[j].value; + filterField.operation = filterColumnElement.value; } // Condition - if (filterFieldDivs[i].children[j].name == 'condition') + if (filterColumnElement.name == 'condition') { - filterField.condition = filterFieldDivs[i].children[j].value; + filterField.condition = filterColumnElement.value; } // Option - if (filterFieldDivs[i].children[j].name == 'option') + if (filterColumnElement.name == 'option') { - filterField.option = filterFieldDivs[i].children[j].value; + filterField.option = filterColumnElement.value; } } } - filterFields.push(filterField); + if (Object.entries(filterField).length > 0) filterFields.push(filterField); } // @@ -321,41 +420,66 @@ export const CoreFilterCmpt = { /** * */ - handlerAddFilterField: function(event) { - // - this.startFetchCmpt( - CoreFilterAPIs.addFilterField, + handlerChangeFilterField: function(oldValue, newValue) { + + // If an old filter has been changed + if (oldValue != "") + { + for (let i = 0; i < this.filterFields.length; i++) { - filterField: event.currentTarget.value - }, - this.getFilter - ); + if (this.filterFields[i].name == oldValue) + { + this.filterFields.splice(i, 1); + break; + } + } + } + + // Then add the new filter + for (let i = 0; i < this.datasetMetadata.length; i++) + { + if (this.datasetMetadata[i].name == newValue) + { + let filter = { + name: this.datasetMetadata[i].name, + type: this.datasetMetadata[i].type + }; + + this.filterFields.push(filter); + break; + } + } }, /** * */ - handlerAddSelectedField: function(event) { - // - this.startFetchCmpt( - CoreFilterAPIs.addSelectedField, - { - selectedField: event.currentTarget.value - }, - this.getFilter - ); + handlerAddNewFilter: function(event) { + // Adds a new empty filter + this.filterFields.push({ + name: FILTER_COMPONENT_NEW_FILTER, + type: FILTER_COMPONENT_NEW_FILTER_TYPE + }); }, - /** + /* * */ - handlerRemoveSelectedField: function(event) { - // - this.startFetchCmpt( - CoreFilterAPIs.removeSelectedField, - { - selectedField: event.currentTarget.getAttribute('field-to-remove') - }, - this.getFilter - ); + handlerToggleSelectedField: function(event) { + + // If it is a selected field + if (this.selectedFields.indexOf(event.target.innerText) != -1) + { + // then hide it + this.tabulator.hideColumn(event.target.innerText); + // and remove it from the this.selectedFields property + this.selectedFields.splice(this.selectedFields.indexOf(event.target.innerText), 1); + } + else // otherwise + { + // show it + this.tabulator.showColumn(event.target.innerText); + // and add it to the this.selectedFields property + this.selectedFields.push(event.target.innerText); + } }, /** * @@ -374,51 +498,30 @@ export const CoreFilterCmpt = { * */ handlerGetFilterById: function(event) { - // + + let filterId = null; + + // Get the attribute href if side menu is rendered + let attr = event.currentTarget.getAttribute("href"); + + // Otherwise get the value of the drop down menu + if (attr == null) + { + filterId = event.currentTarget.value; + } + else + { + filterId = attr.substring(1); + } + + // Ajax call this.startFetchCmpt( CoreFilterAPIs.getFilterById, { - filterId: event.currentTarget.getAttribute("href").substring(1) + filterId: filterId }, this.render ); - }, - handlerDragOver: function(event) { - let draggedFieldToDisplay = event.currentTarget; - let fieldsToDisplayDivs = document.getElementsByClassName('filter-dnd-object'); - let filterFilterOptions = document.getElementsByClassName('filter-filter-options')[0]; - - // For each draggable element - for (let i = 0; i < fieldsToDisplayDivs.length; i++) - { - let fieldToDisplayDiv = fieldsToDisplayDivs[i]; // - - // If the dragged element is not the same element in the loop - if (draggedFieldToDisplay != fieldToDisplayDiv) - { - fieldToDisplayDiv.classList.remove("selection-after"); - fieldToDisplayDiv.classList.remove("selection-before"); - - let fieldToDisplayDivCenter = (filterFilterOptions.offsetLeft + fieldToDisplayDiv.offsetLeft + fieldToDisplayDiv.offsetWidth) / 2; - - if (event.pageX > filterFilterOptions.offsetLeft + fieldToDisplayDiv.offsetLeft - && event.pageX < filterFilterOptions.offsetLeft + fieldToDisplayDiv.offsetLeft + fieldToDisplayDiv.offsetWidth) - { - if (event.pageX > fieldToDisplayDivCenter) - { - fieldToDisplayDiv.classList.add("selection-after"); - fieldToDisplayDiv.classList.remove("selection-before"); - } - else if (event.pageX < fieldToDisplayDivCenter) - { - fieldToDisplayDiv.classList.add("selection-before"); - fieldToDisplayDiv.classList.remove("selection-after"); - } - } - } - } - }, - handlerOnDrop: function() { } }, template: ` @@ -430,130 +533,192 @@ export const CoreFilterCmpt = { @data-fetched="fetchCmptDataFetched"> -
-
- Filter options +
+
+
-
- -
-
- +
+ +
+ +
+ [ {{ filterName }} ] + + +
+ +
+
+ +
+
+ +
-
+
+ +
+
-
-
-
p->t('global','name')) ?> p->t('global','typ')) ?> p->t('global','uploaddatum')) ?>p->t('ui','loeschen')) ?> p->t('infocenter','ausstellungsnation')) ?> - autocomplete="off"> bezeichnung === $dokument->dokument_bezeichnung ? 'selected' : '') . " value = " . $dokumenttyp->dokument_kurzbz . ">" . $dokumenttyp->bezeichnung . "" @@ -30,7 +31,7 @@
- +
erstelltam), 'd.m.Y') ?>> langtext ?>