diff --git a/.gitignore b/.gitignore index bd98c9b59..96af3e5dc 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ application/logs/ application/models/extensions/ application/views/extensions/ application/widgets/extensions/ +application/components/extensions/ public/extensions/ diff --git a/include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html b/application/components/extensions/.placeholder similarity index 100% rename from include/fckeditor/editor/dialog/fck_spellerpages/spellerpages/blank.html rename to application/components/extensions/.placeholder diff --git a/application/components/filters/LogsViewer.php b/application/components/filters/LogsViewer.php new file mode 100644 index 000000000..3a5390273 --- /dev/null +++ b/application/components/filters/LogsViewer.php @@ -0,0 +1,19 @@ + 'core', + 'datasetName' => 'logs', + //'filterKurzbz' => 'jobs48hours', // REMOVE ME + 'query' => ' + SELECT wsl.webservicelog_id AS "LogId", + wsl.request_id AS "RequestId", + wsl.execute_time AS "ExecutionTime", + wsl.execute_user AS "ExecutedBy", + wsl.beschreibung AS "Description", + wsl.request_data AS "Data", + wsl.webservicetyp_kurzbz AS "WebserviceType" + FROM system.tbl_webservicelog wsl + ORDER BY wsl.execute_time DESC + ', + 'requiredPermissions' => 'admin' + ); + diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php index d1f4f0958..c2e38385c 100644 --- a/application/config/anrechnung.php +++ b/application/config/anrechnung.php @@ -7,8 +7,8 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); $config['interval_blocking_application'] = 'P1M'; // Application submission period given by start- and enddate. -$config['submit_application_start'] = '01.02.2021'; -$config['submit_application_end'] = '22.02.2021'; +$config['submit_application_start'] = '05.09.2022'; +$config['submit_application_end'] = '22.09.2022'; // Lehrveranstaltungen with these grades will be blocked for application $config['grades_blocking_application'] = array( diff --git a/application/config/navigation.php b/application/config/navigation.php index d415e9332..092c00cc5 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -15,7 +15,7 @@ $config['navigation_header'] = array( 'description' => 'Organisation', 'sort' => 20, 'requiredPermissions' => 'basis/vilesci:r', - 'children'=> array( + 'children' => array( 'vilesci' => array( 'link' => base_url('vilesci'), 'icon' => '', @@ -40,7 +40,7 @@ $config['navigation_header'] = array( 'description' => 'Lehre', 'sort' => 30, 'requiredPermissions' => 'basis/vilesci:r', - 'children'=> array( + 'children' => array( 'cis' => array( 'link' => CIS_ROOT, 'icon' => '', @@ -71,16 +71,16 @@ $config['navigation_header'] = array( 'lehre/lehrauftrag_erteilen:r' ) ), - 'zverfueg' => array( - 'link' => site_url('lehre/lvplanung/AdminZeitverfuegbarkeit'), - 'description' => 'Zeitverfügbarkeit', - 'expand' => true, - 'sort' => 45, - 'requiredPermissions' => array( - 'lehre/zeitverfuegbarkeit:rw', - 'lehre/zeitverfuegbarkeit:rw' - ) - ), + 'zverfueg' => array( + 'link' => site_url('lehre/lvplanung/AdminZeitverfuegbarkeit'), + 'description' => 'Zeitverfügbarkeit', + 'expand' => true, + 'sort' => 45, + 'requiredPermissions' => array( + 'lehre/zeitverfuegbarkeit:rw', + 'lehre/zeitverfuegbarkeit:rw' + ) + ), 'zgvueberpruefung' => array( 'link' => site_url('system/infocenter/ZGVUeberpruefung'), 'description' => 'ZGV Überprüfung', @@ -98,7 +98,7 @@ $config['navigation_header'] = array( 'description' => 'Personen', 'sort' => 40, 'requiredPermissions' => 'basis/vilesci:r', - 'children'=> array( + 'children' => array( 'messages' => array( 'link' => site_url('system/messages/MessageClient/read'), 'icon' => '', @@ -119,6 +119,20 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 30, 'requiredPermissions' => 'system/issues_verwalten:r' + ), + 'plausichecks' => array( + 'link' => site_url('system/issues/Plausichecks'), + 'description' => 'Plausichecks', + 'expand' => true, + 'sort' => 40, + 'requiredPermissions' => 'system/issues_verwalten:r' + ), + 'gruppenmanagement' => array( + 'link' => site_url('person/Gruppenmanagement'), + 'description' => 'Gruppenmanagement', + 'expand' => true, + 'sort' => 50, + 'requiredPermissions' => 'lehre/gruppenmanager:r' ) ) ), @@ -129,7 +143,7 @@ $config['navigation_header'] = array( 'expand' => false, 'sort' => 50, 'requiredPermissions' => 'admin:r', - 'children'=> array( + 'children' => array( 'extensions' => array( 'link' => site_url('system/extensions/Manager'), 'description' => 'Extensions Manager', @@ -194,7 +208,8 @@ $config['navigation_menu']['lehre/lehrauftrag/Lehrauftrag/*'] = array( 'icon' => 'dashboard', 'sort' => 1, 'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r','lehre/lehrauftrag_erteilen:r') - ),'lehrauftragBestellen' => array( + ), + 'lehrauftragBestellen' => array( 'link' => site_url('lehre/lehrauftrag/Lehrauftrag'), 'description' => 'Lehrauftrag bestellen', 'icon' => '', @@ -216,6 +231,7 @@ $config['navigation_menu']['lehre/lehrauftrag/Lehrauftrag/*'] = array( 'requiredPermissions' => array('lehre/lehrauftrag_erteilen:r') ) ); + $config['navigation_menu']['lehre/lehrauftrag/LehrauftragErteilen/*'] = array( 'lehrauftragDashboard' => array( 'link' => site_url('lehre/lehrauftrag/Lehrauftrag/Dashboard'), @@ -223,7 +239,8 @@ $config['navigation_menu']['lehre/lehrauftrag/LehrauftragErteilen/*'] = array( 'icon' => 'dashboard', 'sort' => 1, 'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r','lehre/lehrauftrag_erteilen:r') - ),'lehrauftragBestellen' => array( + ), + 'lehrauftragBestellen' => array( 'link' => site_url('lehre/lehrauftrag/Lehrauftrag'), 'description' => 'Lehrauftrag bestellen', 'icon' => '', @@ -245,3 +262,15 @@ $config['navigation_menu']['lehre/lehrauftrag/LehrauftragErteilen/*'] = array( 'requiredPermissions' => array('lehre/lehrauftrag_erteilen:r') ) ); + +$config['navigation_menu']['system/issues/Issues/*'] = array( + 'fehlerzustaendigkeiten' => array( + 'link' => site_url('system/issues/IssuesZustaendigkeiten'), + 'description' => 'Fehler Zuständigkeiten', + 'icon' => 'cogs', + 'sort' => 100, + 'target' => '_blank', + 'requiredPermissions' => array('admin:rw') + ) +); + diff --git a/application/config/routes.php b/application/config/routes.php index 36bfdcb1e..15da5698f 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -60,3 +60,26 @@ $route['api/v1/organisation/[G|g]eschaeftsjahr/(:any)'] = 'api/v1/organisation/g $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisation/organisationseinheit2/$1'; $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'; + +// load routes from extensions +$subdir = 'application/config/extensions'; +$dirlist = scandir($subdir); + +if ($dirlist) +{ + $files = array_diff($dirlist, array('.','..')); + + foreach ($files as &$item) + { + if (is_dir($subdir . DIRECTORY_SEPARATOR . $item)) + { + $routes_file = $subdir . DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . 'routes.php'; + + if (file_exists($routes_file)) + { + require($routes_file); + } + } + } +} + diff --git a/application/controllers/components/Filter.php b/application/controllers/components/Filter.php new file mode 100644 index 000000000..ab7e1493e --- /dev/null +++ b/application/controllers/components/Filter.php @@ -0,0 +1,207 @@ +load->library('AuthLib'); + + // Loads the FilterCmptLib with HTTP GET/POST parameters + $this->_startFilterCmptLib(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data about the current filter from the session and will be written on the output in JSON format + */ + public function getFilter() + { + $this->outputJsonSuccess($this->filtercmptlib->getSession()); + } + + /** + * Remove an applied filter (SQL where condition) from the current filter + */ + public function removeFilterField() + { + $request = $this->getPostJSON(); + + if (property_exists($request, 'filterField') + && $this->filtercmptlib->removeFilterField($request->filterField) == true) + { + $this->outputJsonSuccess('Field removed'); + } + else + { + $this->outputJsonError('Error occurred'); + } + } + + /** + * Add a filter (SQL where clause) to be applied to the current filter + */ + public function addFilterField() + { + $request = $this->getPostJSON(); + + if (property_exists($request, 'filterField') + && $this->filtercmptlib->addFilterField($request->filterField) == true) + { + $this->outputJsonSuccess('Field added'); + } + else + { + $this->outputJsonError('Error occurred'); + } + } + + /** + * Apply the filter changes + */ + public function applyFilterFields() + { + $request = $this->getPostJSON(); + + if (property_exists($request, 'filterFields') + && $this->filtercmptlib->applyFilterFields($request->filterFields) == true) + { + $this->outputJsonSuccess('Applied'); + } + else + { + $this->outputJsonError('Error occurred'); + } + } + + /** + * Save the current filter as a custom filter for this user with the given description + */ + public function saveCustomFilter() + { + $request = $this->getPostJSON(); + + if (property_exists($request, 'customFilterName') + && $this->filtercmptlib->saveCustomFilter($request->customFilterName) == true) + { + $this->outputJsonSuccess('Saved'); + } + else + { + $this->outputJsonError('An error occurred while saving a custom filter'); + } + } + + /** + * Remove a custom filter by its filterId + */ + public function removeCustomFilter() + { + $request = $this->getPostJSON(); + + if (property_exists($request, 'filterId') + && $this->filtercmptlib->removeCustomFilter($request->filterId) == true) + { + $this->outputJsonSuccess('Removed'); + } + else + { + $this->outputJsonError('Wrong parameter'); + } + } + + /** + * Reloads the dataset + */ + public function reloadDataset() + { + $this->filtercmptlib->reloadDataset(); + + $this->outputJsonSuccess('Success'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Loads the FilterCmptLib with the FILTER_UNIQUE_ID parameter + * If the parameter FILTER_UNIQUE_ID is not given then the execution of the controller is terminated and + * an error message is printed + */ + private function _startFilterCmptLib() + { + $filterUniqueId = null; + $filterType = null; + $filterId = null; + + // Try to get the POSTed JSON + $postJSON = $this->getPostJSON(); + + // POSTed JSON + if ($postJSON != null) + { + // If the mandatory parameters FILTER_UNIQUE_ID and FILTER_TYPE have been provided + if (property_exists($postJSON, self::FILTER_UNIQUE_ID) && property_exists($postJSON, self::FILTER_TYPE)) + { + // Retrives them from the POSTed JSON + $filterUniqueId = $postJSON->{self::FILTER_UNIQUE_ID}; + $filterType = $postJSON->{self::FILTER_TYPE}; + } + + // If the optional parameter FILTER_ID has been provided + if (property_exists($postJSON, self::FILTER_ID)) $filterId = $postJSON->{self::FILTER_ID}; + } + else // otherwise it is an HTTP GET call + { + // If the mandatory parameters FILTER_UNIQUE_ID and FILTER_TYPE have been provided + if (isset($_GET[self::FILTER_UNIQUE_ID]) && isset($_GET[self::FILTER_TYPE])) + { + // Retrives them from the HTTP GET + $filterUniqueId = $this->input->get(self::FILTER_UNIQUE_ID); + $filterType = $this->input->get(self::FILTER_TYPE); + } + + // If the optional parameter FILTER_ID has been provided + if (isset($_GET[self::FILTER_ID])) $filterId = $filterId = $this->input->get(self::FILTER_ID); + } + + // If the mandatory parameters have _not_ been provided, then terminate the execution and return an error + if ($filterUniqueId == null) $this->terminateWithJsonError('Parameter "'.self::FILTER_UNIQUE_ID.'" not provided!'); + if ($filterType == null) $this->terminateWithJsonError('Parameter "'.self::FILTER_TYPE.'" not provided!'); + + // Loads the FilterCmptLib that contains all the used logic + $this->load->library( + 'FilterCmptLib', + array( + 'filterUniqueId' => $filterUniqueId, + 'filterType' => $filterType, + 'filterId' => $filterId + ) + ); + + // Start the component + $this->filtercmptlib->start(); + } +} + diff --git a/application/controllers/components/SearchBar.php b/application/controllers/components/SearchBar.php new file mode 100644 index 000000000..09a49e163 --- /dev/null +++ b/application/controllers/components/SearchBar.php @@ -0,0 +1,51 @@ +load->library('SearchBarLib'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + public function search() + { + $json = json_decode($this->input->raw_input_stream); + + // Checks if the searchstr and the types parameters are in the POSTed JSON + if (isset($json->{self::SEARCHSTR_PARAM}) && isset($json->{self::TYPES_PARAM})) + { + // Convert to json the result from searchbarlib->search + $this->outputJson( + $this->searchbarlib->search( + $json->{self::SEARCHSTR_PARAM}, + $json->{self::TYPES_PARAM} + ) + ); + } + else // otherwise return an error in JSON format + { + $this->outputJsonError(SearchBarLib::ERROR_WRONG_JSON); + } + } +} + diff --git a/application/controllers/jobs/AnrechnungJob.php b/application/controllers/jobs/AnrechnungJob.php index f32a8268a..7aae80d54 100644 --- a/application/controllers/jobs/AnrechnungJob.php +++ b/application/controllers/jobs/AnrechnungJob.php @@ -16,9 +16,11 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); class AnrechnungJob extends JOB_Controller { const APPROVE_ANRECHNUNG_URI = '/lehre/anrechnung/ApproveAnrechnungUebersicht'; + const REVIEW_ANRECHNUNG_URI = '/lehre/anrechnung/ReviewAnrechnungUebersicht'; const ANRECHNUNGSTATUS_APPROVED = 'approved'; const ANRECHNUNGSTATUS_REJECTED = 'rejected'; + const ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR = 'inProgressLektor'; const ANRECHNUNG_NOTIZTITEL_NOTIZ_BY_STGL = 'AnrechnungNotizSTGL'; /** @@ -33,6 +35,8 @@ class AnrechnungJob extends JOB_Controller $this->load->helper('url'); $this->load->helper('hlp_sancho_helper'); + + $this->load->library('AnrechnungLib'); } /** @@ -342,6 +346,79 @@ html; } + /** + * Send Sancho mail to remind lecturers to provide their recommendation if not done until one week after request. + */ + public function sendMailRemindRecommendation(){ + + $this->logInfo('Start AnrechnungJob sendMailRemindRecommendation to remind lecturers to provide their recommendation.'); + + // Get Anrechnungen with pending recommendations, that were requested 1 week before today. + // Restrict query for Anrechnungen of actual semester. + $this->AnrechnungModel->addSelect('astat.anrechnung_id, astat.datum, astat.insertamum'); + $this->AnrechnungModel->addDistinct('astat.anrechnung_id'); + $this->AnrechnungModel->addJoin('lehre.tbl_anrechnung_anrechnungstatus astat', 'anrechnung_id'); + + $result = $this->AnrechnungModel->loadWhere(' + studiensemester_kurzbz = ( + SELECT studiensemester_kurzbz FROM tbl_studiensemester WHERE now()::date BETWEEN start AND ende) + ) + AND genehmigt_von IS NULL + AND empfehlung_anrechnung IS NULL + AND status_kurzbz = '. $this->db->escape(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR) .' -- in Bearbeitung durch Lektor + AND NOW()::date = (astat.datum + interval \'1 week\') -- eine Woche nach Empfehlungsanfrage + ORDER BY astat.anrechnung_id, astat.datum DESC, astat.insertamum DESC -- nur letzten status dabei prüfen + '); + + // Exit if there are no pending recommendations + if (!hasData($result)) + { + $this->logInfo('End AnrechnungJob sendMailRemindRecommendation, because no recommendations to be done.'); + exit; + } + + $anrechnung_id_arr = array_column(getData($result), 'anrechnung_id'); + + $arr_lvLector_arr = array(); + foreach ($anrechnung_id_arr as $anrechnung_id) + { + $arr_lvLector_arr[]= $this->anrechnunglib->getLectors($anrechnung_id); // Returns LV Leitung. If not present, then all lectors of LV. + } + + // Unique lector array to send only one mail per lector + $arr_lvLector_arr = array_unique($arr_lvLector_arr, SORT_REGULAR); + + // Link to 'Anrechnungen prüfen' dashboard + $url = + CIS_ROOT. 'cis/index.php?menu='. + CIS_ROOT. 'cis/menu.php?content_id=&content='. + CIS_ROOT. index_page(). self::REVIEW_ANRECHNUNG_URI; + + foreach ($arr_lvLector_arr as $lvLector_arr) + { + foreach ($lvLector_arr as $lector) + { + // Prepare mail content + $fields = array( + 'vorname' => $lector->vorname, + 'stgl_name' => 'Die Studiengangsleitung', + 'link' => anchor($url, 'Anrechnungsanträge Übersicht') + ); + + // Send mail + sendSanchoMail( + 'AnrechnungEmpfehlungAnfordern', + $fields, + $lector->uid. '@'. DOMAIN, + 'Erinnerung: Deine Empfehlung wird benötigt zur Anerkennung nachgewiesener Kenntnisse' + ); + } + } + + $this->logInfo('SUCCEDED AnrechnungJob sendMailRemindRecommendation'); + + } + // Get STGL mail address private function _getSTGLMailAddress($studiengang_kz) { diff --git a/application/controllers/jobs/IssueResolver.php b/application/controllers/jobs/IssueResolver.php index 17c4cb9ce..cf97b7f68 100755 --- a/application/controllers/jobs/IssueResolver.php +++ b/application/controllers/jobs/IssueResolver.php @@ -22,7 +22,33 @@ class IssueResolver extends IssueResolver_Controller 'CORE_INOUT_0003' => 'CORE_INOUT_0003', 'CORE_INOUT_0004' => 'CORE_INOUT_0004', 'CORE_INOUT_0005' => 'CORE_INOUT_0005', - 'CORE_INOUT_0006' => 'CORE_INOUT_0006' + 'CORE_INOUT_0006' => 'CORE_INOUT_0006', + 'CORE_INOUT_0007' => 'CORE_INOUT_0007', + 'CORE_INOUT_0008' => 'CORE_INOUT_0008', + 'CORE_INOUT_0009' => 'CORE_INOUT_0009', + 'CORE_STG_0001' => 'CORE_STG_0001', + 'CORE_STG_0002' => 'CORE_STG_0002', + 'CORE_STG_0003' => 'CORE_STG_0003', + 'CORE_STG_0004' => 'CORE_STG_0004', + 'CORE_STUDENTSTATUS_0001' => 'CORE_STUDENTSTATUS_0001', + 'CORE_STUDENTSTATUS_0002' => 'CORE_STUDENTSTATUS_0002', + 'CORE_STUDENTSTATUS_0003' => 'CORE_STUDENTSTATUS_0003', + 'CORE_STUDENTSTATUS_0004' => 'CORE_STUDENTSTATUS_0004', + 'CORE_STUDENTSTATUS_0005' => 'CORE_STUDENTSTATUS_0005', + 'CORE_STUDENTSTATUS_0006' => 'CORE_STUDENTSTATUS_0006', + 'CORE_STUDENTSTATUS_0007' => 'CORE_STUDENTSTATUS_0007', + 'CORE_STUDENTSTATUS_0008' => 'CORE_STUDENTSTATUS_0008', + 'CORE_STUDENTSTATUS_0009' => 'CORE_STUDENTSTATUS_0009', + 'CORE_STUDENTSTATUS_0010' => 'CORE_STUDENTSTATUS_0010', + 'CORE_STUDENTSTATUS_0011' => 'CORE_STUDENTSTATUS_0011', + 'CORE_STUDENTSTATUS_0012' => 'CORE_STUDENTSTATUS_0012', + 'CORE_STUDENTSTATUS_0013' => 'CORE_STUDENTSTATUS_0013', + 'CORE_STUDENTSTATUS_0014' => 'CORE_STUDENTSTATUS_0014', + 'CORE_STUDENTSTATUS_0015' => 'CORE_STUDENTSTATUS_0015', + 'CORE_PERSON_0001' => 'CORE_PERSON_0001', + 'CORE_PERSON_0002' => 'CORE_PERSON_0002', + 'CORE_PERSON_0003' => 'CORE_PERSON_0003', + 'CORE_PERSON_0004' => 'CORE_PERSON_0004' ); } } diff --git a/application/controllers/jobs/LVPlanJob.php b/application/controllers/jobs/LVPlanJob.php index 2acbe5512..c3fe5495a 100644 --- a/application/controllers/jobs/LVPlanJob.php +++ b/application/controllers/jobs/LVPlanJob.php @@ -240,11 +240,13 @@ class LVPlanJob extends JOB_Controller } // Send mail to STG Assistenz + /* $result = $this->_sendMailToStg($uidByStg_arr); if (isError($result)) { $this->logError(getError($result)); } + */ // Send mail to Kompetenzfeld Leitung $result = $this->_sendMailToKF($uidByOe_arr); diff --git a/application/controllers/jobs/LehrauftragJob.php b/application/controllers/jobs/LehrauftragJob.php index 7f5754595..f1974c8a5 100644 --- a/application/controllers/jobs/LehrauftragJob.php +++ b/application/controllers/jobs/LehrauftragJob.php @@ -359,7 +359,7 @@ class LehrauftragJob extends JOB_Controller for ($i = 0; $i < $data_len; $i++) { // Get all users entitled by organisational unit - $result = $this->BenutzerrolleModel->getBenutzerByBerechtigung(self::BERECHTIGUNG_LEHRAUFTRAG_ERTEILEN, $data[$i]['oe_kurzbz']); + $result = $this->BenutzerrolleModel->getBenutzerByBerechtigung(self::BERECHTIGUNG_LEHRAUFTRAG_ERTEILEN, $data[$i]['oe_kurzbz'], 'suid'); if ($berechtigung_arr = getData($result)) { diff --git a/application/controllers/jobs/PlausiIssueProducer.php b/application/controllers/jobs/PlausiIssueProducer.php new file mode 100644 index 000000000..943d7aa46 --- /dev/null +++ b/application/controllers/jobs/PlausiIssueProducer.php @@ -0,0 +1,62 @@ +load->library('issues/PlausicheckProducerLib'); + $this->load->library('IssuesLib'); + } + + /** + * Runs issue production job. + * @param studiensemester_kurzbz string job is run for students of a certain semester. + * @param studiengang_kz int job is run for students of certain Studiengang. + */ + public function run($studiensemester_kurzbz = null, $studiengang_kz = null) + { + $fehlerKurzbz = $this->plausicheckproducerlib->getFehlerKurzbz(); + + $this->logInfo("Plausicheck issue producer job started"); + + // get the data returned by Plausicheck + foreach ($fehlerKurzbz as $fehler_kurzbz) + { + // execute the check + $this->logInfo("Checking " . $fehler_kurzbz . "..."); + $plausicheckRes = $this->plausicheckproducerlib->producePlausicheckIssue($fehler_kurzbz, $studiensemester_kurzbz, $studiengang_kz); + + if (isError($plausicheckRes)) $this->logError(getError($plausicheckRes)); + + if (hasData($plausicheckRes)) + { + $plausicheckData = getData($plausicheckRes); + + foreach ($plausicheckData as $plausiData) + { + // get the data needed for issue production + $person_id = isset($plausiData['person_id']) ? $plausiData['person_id'] : null; + $oe_kurzbz = isset($plausiData['oe_kurzbz']) ? $plausiData['oe_kurzbz'] : null; + $fehlertext_params = isset($plausiData['fehlertext_params']) ? $plausiData['fehlertext_params'] : null; + $resolution_params = isset($plausiData['resolution_params']) ? $plausiData['resolution_params'] : null; + + // write the issue + $addIssueRes = $this->issueslib->addFhcIssue($fehler_kurzbz, $person_id, $oe_kurzbz, $fehlertext_params, $resolution_params); + + // log if error, or log info if inserted new issue + if (isError($addIssueRes)) + $this->logError(getError($addIssueRes)); + elseif (hasData($addIssueRes) && is_integer(getData($addIssueRes))) + $this->logInfo("Plausicheck issue " . $fehler_kurzbz . " successfully produced, person_id: " . $person_id); + } + } + } + + $this->logInfo("Plausicheck issue producer job stopped"); + } +} diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 28edf4824..1f5c853db 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -395,8 +395,12 @@ class approveAnrechnungDetail extends Auth_Controller // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file - $this->dmslib->download($dms_id, $filename); + $this->outputFile(getData($download)); } /** diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index 053988848..9eb0c9734 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -8,13 +8,13 @@ class approveAnrechnungUebersicht extends Auth_Controller const BERECHTIGUNG_ANRECHNUNG_ANLEGEN = 'lehre/anrechnung_anlegen'; const REVIEW_ANRECHNUNG_URI = '/lehre/anrechnung/ReviewAnrechnungUebersicht'; - + 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 @@ -27,23 +27,23 @@ class approveAnrechnungUebersicht extends Auth_Controller 'requestRecommendation' => 'lehre/anrechnung_genehmigen:rw' ) ); - + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); $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 language phrases $this->loadPhrases( array( @@ -55,23 +55,23 @@ class approveAnrechnungUebersicht extends Auth_Controller 'table' ) ); - + $this->_setAuthUID(); - + $this->setControllerId(); } - + public function index() { // Get study semester $studiensemester_kurzbz = $this->input->get('studiensemester'); - + if (isEmptyString($studiensemester_kurzbz)) { $result = $this->StudiensemesterModel->getNearest(); $studiensemester_kurzbz = getData($result)[0]->studiensemester_kurzbz; } - + // Get studiengaenge the user is entitled for if (!$studiengang_kz_arr = $this->permissionlib->getSTG_isEntitledFor(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN)) { @@ -91,10 +91,10 @@ class approveAnrechnungUebersicht extends Auth_Controller 'hasReadOnlyAccess' => $hasReadOnlyAccess, 'hasCreateAnrechnungAccess' => $hasCreateAnrechnungAccess ); - + $this->load->view('lehre/anrechnung/approveAnrechnungUebersicht.php', $viewData); } - + /** * Approve Anrechnungen. */ @@ -107,22 +107,30 @@ class approveAnrechnungUebersicht extends Auth_Controller { return $this->outputJsonError('Fehler beim Übertragen der Daten.'); } - + + $json = array( + 'status_kurzbz' => self::ANRECHNUNGSTATUS_APPROVED, + 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_APPROVED), + 'prestudenten' => [] + ); + // Approve Anrechnung foreach ($data as $item) { - if ($this->anrechnunglib->approveAnrechnung($item['anrechnung_id'])) + // Get Prestudent + $this->AnrechnungModel->addSelect('prestudent_id'); + $result = $this->AnrechnungModel->load($item['anrechnung_id']); + $prestudent_id = getData($result)[0]->prestudent_id; + + // Approve + if ($this->anrechnunglib->approveAnrechnung($item['anrechnung_id'])) { - $json[]= array( - 'anrechnung_id' => $item['anrechnung_id'], - 'status_kurzbz' => self::ANRECHNUNGSTATUS_APPROVED, - 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_APPROVED) - ); + $json['prestudenten'][$prestudent_id][] = $item['anrechnung_id']; } } - + // Output json to ajax - if (isset($json) && !isEmptyArray($json)) + if (isset($json) && !isEmptyArray($json['prestudenten'])) { return $this->outputJsonSuccess($json); } @@ -131,20 +139,20 @@ class approveAnrechnungUebersicht extends Auth_Controller return $this->outputJsonError('Es wurden keine Anrechnungen genehmigt.'); } } - + /** * Reject Anrechnungen. */ public function reject() { $data = $this->input->post('data'); - + // Validate data if (isEmptyArray($data)) { return $this->outputJsonError('Fehler beim Übertragen der Daten.'); } - + // Reject Anrechnung foreach ($data as $item) { @@ -157,7 +165,7 @@ class approveAnrechnungUebersicht extends Auth_Controller ); } } - + // Output json to ajax if (isset($json) && !isEmptyArray($json)) { @@ -168,22 +176,22 @@ class approveAnrechnungUebersicht extends Auth_Controller return $this->outputJsonError('Es wurden keine Anrechnungen genehmigt.'); } } - + /** * Request recommendation for Anrechnungen. */ public function requestRecommendation() { $data = $this->input->post('data'); - + if(isEmptyArray($data)) { return $this->outputJsonError('Fehler beim Übertragen der Daten.'); } - + $retval = array(); $counter = 0; - + foreach ($data as $item) { // Check if Anrechnungs-LV has lector @@ -191,7 +199,7 @@ class approveAnrechnungUebersicht extends Auth_Controller { // Count up LV with no lector $counter++; - + // Continue loop, if LV has no lector continue; } @@ -205,7 +213,7 @@ class approveAnrechnungUebersicht extends Auth_Controller $empfehlungsanfrage_an = !isEmptyArray($lector_arr) ? implode(', ', array_column($lector_arr, 'fullname')) : ''; - + $retval[]= array( 'anrechnung_id' => $item['anrechnung_id'], 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, @@ -216,7 +224,7 @@ class approveAnrechnungUebersicht extends Auth_Controller ); } } - + /** * Send mails to lectors * NOTE: mails are sent at the end to ensure sending only ONE mail to each LV-Leitung or lector @@ -226,16 +234,16 @@ class approveAnrechnungUebersicht extends Auth_Controller { self::_sendSanchoMailToLectors($retval); } - + // Output json to ajax if (isEmptyArray($retval) && $counter == 0) { return $this->outputJsonError('Es wurden keine Empfehlungen angefordert'); } - + return $this->outputJsonSuccess($retval); } - + /** * Download and open uploaded document (Nachweisdokument). */ @@ -250,25 +258,28 @@ class approveAnrechnungUebersicht extends Auth_Controller // Check if user is entitled to read dms doc $this->_checkIfEntitledToReadDMSDoc($dms_id); - + // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); - + + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file - $this->dmslib->download($dms_id, $filename); + $this->outputFile(getData($download)); } - - + /** * 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'); } - + /** * Check if user is entitled to read dms doc * @param $dms_id @@ -276,31 +287,30 @@ class approveAnrechnungUebersicht extends Auth_Controller private function _checkIfEntitledToReadDMSDoc($dms_id) { $result = $this->AnrechnungModel->loadWhere(array('dms_id' => $dms_id)); - + if(!$result = getData($result)[0]) { show_error('Failed retrieving Anrechnung'); } - + $result = $this->LehrveranstaltungModel->loadWhere(array( 'lehrveranstaltung_id' => $result->lehrveranstaltung_id )); - - + if(!$result = getData($result)[0]) { show_error('Failed loading Lehrveranstaltung'); } $studiengang_kz = $result->studiengang_kz; - + // Check if user is entitled if (!$this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 's', $studiengang_kz)) { show_error('You are not entitled to read this document'); } } - + /** * Send mail to lectors asking for recommendation. (first to LV-Leitung, if not present to all lectors of lv) * @param $mail_params @@ -310,7 +320,7 @@ class approveAnrechnungUebersicht extends Auth_Controller { // Get Lehrveranstaltungen $anrechnung_arr = array(); - + foreach ($mail_params as $item) { $this->AnrechnungModel->addSelect('lehrveranstaltung_id, studiensemester_kurzbz'); @@ -319,10 +329,10 @@ class approveAnrechnungUebersicht extends Auth_Controller 'studiensemester_kurzbz' => $this->AnrechnungModel->load($item['anrechnung_id'])->retval[0]->studiensemester_kurzbz ); } - + $anrechnung_arr = array_unique($anrechnung_arr, SORT_REGULAR); - + /** * Get lectors (prio for LV-Leitung, if not present to all lectors of LV. * Anyway this function will receive a unique array to avoid sending more mails to one and the same lector. @@ -334,27 +344,27 @@ class approveAnrechnungUebersicht extends Auth_Controller { $to = $lector->uid; $vorname = $lector->vorname; - + // Get full name of stgl $this->load->model('person/Person_model', 'PersonModel'); if (!$stgl_name = getData($this->PersonModel->getFullName($this->_uid))) { show_error ('Failed retrieving person'); } - + // Link to Antrag genehmigen $url = CIS_ROOT. 'cis/index.php?menu='. CIS_ROOT. 'cis/menu.php?content_id=&content='. CIS_ROOT. index_page(). self::REVIEW_ANRECHNUNG_URI; - + // Prepare mail content $body_fields = array( 'vorname' => $vorname, 'stgl_name' => $stgl_name, 'link' => anchor($url, 'Anrechnungsanträge Übersicht') ); - + sendSanchoMail( 'AnrechnungEmpfehlungAnfordern', $body_fields, @@ -364,7 +374,7 @@ class approveAnrechnungUebersicht extends Auth_Controller } return true; } - + /** * Get lectors (prio for LV-Leitung, if not present to all lectors of LV. * Anyway this function will receive a unique array to avoid sending more mails to one and the same lector. @@ -374,18 +384,18 @@ class approveAnrechnungUebersicht extends Auth_Controller private function _getLectors($anrechnung_arr) { $lector_arr = array(); - + // Get lectors foreach($anrechnung_arr as $anrechnung) { $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); $result = $this->LehrveranstaltungModel->getLecturersByLv($anrechnung['studiensemester_kurzbz'], $anrechnung['lehrveranstaltung_id']); - + if (!hasData($result)) { show_error('Failed retrieving lectors of Lehrveranstaltung'); } - + $lecturersByLv = getData($result); // Check if lv has LV-Leitung @@ -401,7 +411,7 @@ class approveAnrechnungUebersicht extends Auth_Controller $lector_arr = array_merge($lector_arr, $lecturersByLv); } } - + /** * NOTE: This step is only done to make the array unique by uid, vorname and nachname in the following step * (e.g. if same lector is ones LV-Leitung and another time not, then array_unique would leave both. @@ -411,10 +421,10 @@ class approveAnrechnungUebersicht extends Auth_Controller { unset($lector->lvleiter); } - + // Now make the lector array aka mail receivers unique $lector_arr = array_unique($lector_arr, SORT_REGULAR); - + return $lector_arr; } -} \ No newline at end of file +} diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index bf98e1c59..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'); @@ -205,9 +205,14 @@ class requestAnrechnung extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); - $this->dmslib->download($dms_id); + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id); + if (isError($download)) return $download; + + // Download file + $this->outputFile(getData($download)); } /** @@ -216,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. * @@ -232,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)) { @@ -240,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)) { @@ -248,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. * @@ -268,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) @@ -278,10 +283,10 @@ class requestAnrechnung extends Auth_Controller return; } } - + show_error('You are not entitled to read this document'); } - + /** * Check if application already exists. * @@ -297,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. * @@ -317,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 @@ -331,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'))) { @@ -345,7 +350,7 @@ class requestAnrechnung extends Auth_Controller } return false; } - + /** * Upload file via DMS library. * @@ -362,8 +367,8 @@ 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')); } -} \ No newline at end of file +} diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 7981f0ac8..1bd92004d 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -217,15 +217,18 @@ class reviewAnrechnungDetail extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); - // Download file - $this->dmslib->download($dms_id, $filename); - } + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file + $this->outputFile(getData($download)); + } /** * Retrieve the UID of the logged user and checks if it is valid @@ -319,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 = @@ -340,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; } @@ -366,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 e5475d0d0..c63d0af69 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -180,13 +180,17 @@ class reviewAnrechnungUebersicht extends Auth_Controller } // Check if user is entitled to read dms doc - self::_checkIfEntitledToReadDMSDoc($dms_id); + $this->_checkIfEntitledToReadDMSDoc($dms_id); // Set filename to be used on downlaod $filename = $this->anrechnunglib->setFilenameOnDownload($dms_id); + // Get file to be downloaded from DMS + $download = $this->dmslib->download($dms_id, $filename); + if (isError($download)) return $download; + // Download file - $this->dmslib->download($dms_id, $filename); + $this->outputFile(getData($download)); } @@ -253,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 = @@ -274,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; } @@ -300,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 new file mode 100644 index 000000000..1a4c341a4 --- /dev/null +++ b/application/controllers/person/Gruppenmanagement.php @@ -0,0 +1,254 @@ + 'lehre/gruppenmanager:r', + 'showBenutzergruppe' => 'lehre/gruppenmanager:r', + 'getBenutzer' => 'lehre/gruppenmanager:r', + 'getAllBenutzer' => 'lehre/gruppenmanager:r', + 'addBenutzer' => 'lehre/gruppenmanager:rw', + 'removeBenutzer' => 'lehre/gruppenmanager:rw' + ) + ); + + // Loads models + $this->load->model('person/benutzer_model', 'BenutzerModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('system/Log_model', 'LogModel'); + + $this->load->library('WidgetLib'); + $this->loadPhrases( + array( + 'global', + 'person', + 'lehre', + 'ui', + 'filter', + 'gruppenmanagement' + ) + ); + + $this->setControllerId(); // sets the controller id + $this->_setAuthUID(); // sets property uid + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Main page + */ + public function index() + { + $this->load->view( + 'person/gruppenmanagement/gruppenmanagement.php', + array('uid' => $this->_uid) + ); + } + + /** + * Shows Benutzergruppe overview page. + */ + public function showBenutzergruppe() + { + $this->_setNavigationMenuShowDetails(); + $gruppe_kurzbz = $this->input->get('gruppe_kurzbz'); + + $data[self::FHC_CONTROLLER_ID] = $this->getControllerId(); + + $this->load->view( + 'person/gruppenmanagement/benutzergruppe.php', + array('gruppe_kurzbz' => $gruppe_kurzbz) + ); + } + + /** + * Gets Benutzer assigned to a Gruppe + */ + public function getBenutzer() + { + $gruppe_kurzbz = $this->input->get('gruppe_kurzbz'); + + $this->BenutzergruppeModel->addSelect('uid, vorname, nachname, ben.aktiv'); + $this->BenutzergruppeModel->addJoin('public.tbl_benutzer ben', 'uid'); + $this->BenutzergruppeModel->addJoin('public.tbl_person', 'person_id'); + $benutzerRes = $this->BenutzergruppeModel->loadWhere(array('gruppe_kurzbz' => $gruppe_kurzbz)); + + $this->outputJson($benutzerRes); + } + + /** + * Gets all Benutzer for assignment to Gruppe + */ + public function getAllBenutzer() + { + $this->BenutzerModel->addSelect('uid, vorname, nachname'); + $this->BenutzerModel->addJoin('public.tbl_person', 'person_id'); + $benutzerRes = $this->BenutzerModel->loadWhere( + array('tbl_benutzer.aktiv' => true) + ); + $this->outputJson($benutzerRes); + } + + /** + * Adds a Benutzer to Gruppe + */ + public function addBenutzer() + { + $uid = $this->input->post('uid'); + $gruppe_kurzbz = $this->input->post('gruppe_kurzbz'); + + if (isEmptyString($uid)) + $result = error('Uid missing'); + else + { + $benutzerExistsRes = $this->BenutzergruppeModel->loadWhere( + array( + 'uid' => $uid, + 'gruppe_kurzbz' => $gruppe_kurzbz + ) + ); + + if (isError($benutzerExistsRes)) + { + $this->outputJsonError(getError($benutzerExistsRes)); + return; + } + + if (hasData($benutzerExistsRes)) + { + $this->outputJsonError($this->p->t('gruppenmanagement', 'benutzerSchonZugewiesen')); + return; + } + + $result = $this->BenutzergruppeModel->insert( + array( + 'uid' => $uid, + 'gruppe_kurzbz' => $gruppe_kurzbz, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => $this->_uid + ) + ); + + // log the group add + $lastQry = $this->db->last_query(); + + if (isSuccess($result)) + { + $beschreibung = 'Gruppenmanagement: Nutzer zu Gruppe hinzugefügt'; + $this->_writeLog($this->_uid, $beschreibung, $lastQry); + } + } + + $this->outputJson($result); + } + + /** + * Removes Benutzer from Gruppe + */ + public function removeBenutzer() + { + $uid = $this->input->post('uid'); + $gruppe_kurzbz = $this->input->post('gruppe_kurzbz'); + + if (isEmptyString($uid)) + $result = error('Uid missing'); + else + { + $result = $this->BenutzergruppeModel->delete( + array( + 'uid' => $uid, + 'gruppe_kurzbz' => $gruppe_kurzbz + ) + ); + } + + // log the group remove + $lastQry = $this->db->last_query(); + + if (isSuccess($result)) + { + $beschreibung = 'Gruppenmanagement: Nutzer aus Gruppe entfernt'; + $this->_writeLog($this->_uid, $beschreibung, $lastQry); + } + + $this->outputJson($result); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * Define the navigation menu for the showDetails page + */ + private function _setNavigationMenuShowDetails() + { + $this->load->library('NavigationLib', array('navigation_page' => 'person/Gruppenmanagement/showBenutzergruppe')); + + $link = site_url('person/Gruppenmanagement'); + + $this->navigationlib->setSessionMenu( + array( + 'back' => $this->navigationlib->oneLevel( + 'Zurück', // description + $link, // link + array(), // children + 'angle-left', // icon + true, // expand + null, // subscriptDescription + null, // subscriptLinkClass + null, // subscriptLinkValue + '', // target + 1 // sort + ) + ) + ); + } + + /** + * Set uid of authentificated user + */ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) show_error('User authentification failed'); + } + + /** + * Writes an entry in the log table + */ + private function _writeLog($uid, $beschreibung, $lastQry) + { + $mitarbeiterResult = $this->MitarbeiterModel->load(array('mitarbeiter_uid'=>$this->_uid)); + + if(!isSuccess($mitarbeiterResult) || !hasData($mitarbeiterResult)) + { + $uid = DUMMY_LEKTOR_UID; + $beschreibung .= ': '.$this->_uid; + $beschreibung = mb_substr($beschreibung, 0, 64); + } + + $this->LogModel->insert(array( + 'mitarbeiter_uid' => $uid, + 'beschreibung' => $beschreibung, + 'sql' => $lastQry + )); + } + +} diff --git a/application/controllers/system/Navigation.php b/application/controllers/system/Navigation.php index 190f84acd..c3764b612 100644 --- a/application/controllers/system/Navigation.php +++ b/application/controllers/system/Navigation.php @@ -1,4 +1,20 @@ . + */ if (! defined('BASEPATH')) exit('No direct script access allowed'); diff --git a/application/controllers/system/TestSearch.php b/application/controllers/system/TestSearch.php new file mode 100644 index 000000000..1f5c66a1d --- /dev/null +++ b/application/controllers/system/TestSearch.php @@ -0,0 +1,44 @@ + '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/Variables.php b/application/controllers/system/Variables.php index c56407416..3cc246301 100644 --- a/application/controllers/system/Variables.php +++ b/application/controllers/system/Variables.php @@ -18,10 +18,10 @@ class Variables extends Auth_Controller { parent::__construct( array( - 'setVar' => 'basis/variable:rw', - 'getVar' => 'basis/variable:rw', - 'changeStudiensemesterVar' => 'basis/variable:rw', - 'changeStudengangsTypVar' => 'basis/variable:rw' + 'setVar' => array('basis/variable:rw','basis/variable_persoenlich:rw'), + 'getVar' => array('basis/variable:rw','basis/variable_persoenlich:rw'), + 'changeStudiensemesterVar' => array('basis/variable:rw','basis/variable_persoenlich:rw'), + 'changeStudengangsTypVar' => array('basis/variable:rw','basis/variable_persoenlich:rw') ) ); diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 76011dc04..d027e559e 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 @@ -115,6 +121,7 @@ class InfoCenter extends Auth_Controller 'unlockPerson' => 'infocenter:rw', 'saveFormalGeprueft' => 'infocenter:rw', 'saveDocTyp' => 'infocenter:rw', + 'updateStammdaten' => 'infocenter:rw', 'saveNachreichung' => 'infocenter:rw', 'getPrestudentData' => 'infocenter:r', 'getLastPrestudentWithZgvJson' => 'infocenter:r', @@ -131,6 +138,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 +150,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,11 +169,20 @@ 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'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('person/Geschlecht_model', 'GeschlechtModel'); + $this->load->model('person/adresse_model', 'AdresseModel'); // Loads libraries $this->load->library('PersonLogLib'); $this->load->library('WidgetLib'); + $this->load->config('infocenter'); + $this->loadPhrases( array( 'global', @@ -398,6 +417,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 @@ -1069,11 +1117,22 @@ class InfoCenter extends Auth_Controller public function reloadDoks($person_id) { - $dokumente_nachgereicht = $this->AkteModel->getAktenWithDokInfo($person_id, null, true); + $dokumente_nachgereicht = $this->AkteModel->getAktenWithDokInfo($person_id, null, true, false); $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, 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 @@ -1267,6 +1326,126 @@ class InfoCenter extends Auth_Controller $this->outputJsonSuccess('success'); } + public function updateStammdaten() + { + if (isEmptyString($this->input->post('nachname')) || + isEmptyString($this->input->post('geschlecht')) || + isEmptyString($this->input->post('gebdatum'))) + { + $this->terminateWithJsonError($this->p->t('infocenter', 'stammdatenFeldFehlt')); + } + + $datum = explode('.', $this->input->post('gebdatum')); + + if (!checkdate($datum[1], $datum[0], $datum[2])) + { + $this->terminateWithJsonError($this->p->t('infocenter', 'datumUngueltig')); + } + + $person_id = $this->input->post('personid'); + + $update = $this->PersonModel->update( + array + ( + 'person_id' => $person_id + ), + array + ( + 'titelpre' => isEmptyString($this->input->post('titelpre')) ? null : $this->input->post('titelpre'), + 'vorname' => isEmptyString($this->input->post('vorname')) ? null : $this->input->post('vorname'), + 'nachname' => $this->input->post('nachname'), + 'titelpost' => isEmptyString($this->input->post('titelpost')) ? null : $this->input->post('titelpost'), + 'gebdatum' => isEmptyString($this->input->post('gebdatum')) ? null : date("Y-m-d", strtotime($this->input->post('gebdatum'))), + 'svnr' => isEmptyString($this->input->post('svnr')) ? null : $this->input->post('svnr'), + 'staatsbuergerschaft' => isEmptyString($this->input->post('buergerschaft')) ? null : $this->input->post('buergerschaft'), + 'geschlecht' => $this->input->post('geschlecht'), + 'geburtsnation' => isEmptyString($this->input->post('gebnation')) ? null : $this->input->post('gebnation'), + 'gebort' => isEmptyString($this->input->post('gebort')) ? null : $this->input->post('gebort'), + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_uid + ) + ); + + if (isError($update)) + $this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern')); + + $kontakte = $this->input->post('kontakt'); + foreach ($kontakte as $kontakt) + { + $kontaktExists = $this->KontaktModel->loadWhere(array( + 'kontakt_id' => $kontakt['id'], + 'person_id' => $person_id, + )); + + if (hasData($kontaktExists)) + { + $kontaktExists = getData($kontaktExists)[0]; + + if ($kontaktExists->kontakt === $kontakt['value']) + continue; + + $update = $this->KontaktModel->update( + array + ( + 'kontakt_id' => $kontakt['id'] + ), + array + ( + 'kontakt' => isEmptyString($kontakt['value']) ? null : $kontakt['value'], + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_uid + ) + ); + + if (isError($update)) + $this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern')); + } + } + + $adressen = $this->input->post('adresse'); + + foreach ($adressen as $adresse) + { + $adresseExists = $this->AdresseModel->loadWhere(array( + 'adresse_id' => $adresse['id'], + 'person_id' => $person_id, + )); + + if (hasData($adresseExists)) + { + $adresse = $adresse['value']; + $adresseExists = getData($adresseExists)[0]; + if ($adresseExists->strasse !== $adresse['strasse'] || + $adresseExists->plz !== $adresse['plz'] || + $adresseExists->ort !== $adresse['ort'] || + $adresseExists->nation !== $adresse['nation']) + { + $update = $this->AdresseModel->update( + array + ( + 'adresse_id' => $adresseExists->adresse_id + ), + array + ( + 'strasse' => isEmptyString($adresse['strasse']) ? null : $adresse['strasse'], + 'plz' => isEmptyString($adresse['plz']) ? null : $adresse['plz'], + 'ort' => isEmptyString($adresse['ort']) ? null : $adresse['ort'], + 'nation' => isEmptyString($adresse['nation']) ? null : $adresse['nation'], + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_uid + ) + ); + + if (isError($update)) + $this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern')); + } + + } + } + + $this->outputJsonSuccess('Success'); + } + public function saveNachreichung($person_id) { $nachreichungAm = $this->input->post('nachreichungAm'); @@ -1741,14 +1920,14 @@ class InfoCenter extends Auth_Controller if (!isset($stammdaten->retval)) return null; - $dokumente = $this->AkteModel->getAktenWithDokInfo($person_id, null, false); + $dokumente = $this->AkteModel->getAktenWithDokInfo($person_id, null, false, false); if (isError($dokumente)) { show_error(getError($dokumente)); } - $dokumente_nachgereicht = $this->AkteModel->getAktenWithDokInfo($person_id, null, true); + $dokumente_nachgereicht = $this->AkteModel->getAktenWithDokInfo($person_id, null, true, false); if (isError($dokumente_nachgereicht)) { @@ -1932,10 +2111,33 @@ 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()); + + + $additional_stg = explode(',', ($this->config->item('infocenter_studiengang_kz'))); + + $this->GeschlechtModel->addOrder('sort'); + $allGenders = getData($this->GeschlechtModel->load()); + $data = array ( 'zgvpruefungen' => $zgvpruefungen, 'abwstatusgruende' => $abwstatusgruende, - 'intstatusgruende' => $intstatusgruende + 'intstatusgruende' => $intstatusgruende, + 'studienArtBerechtigung' => $studienArtBerechtigung, + 'all_zgvs' => $allZGVs, + 'all_zgvs_master' => $allZGVsMaster, + 'all_nations' => $allNations, + 'additional_stg' => $additional_stg, + 'all_genders' => $allGenders ); return $data; @@ -2096,8 +2298,8 @@ class InfoCenter extends Auth_Controller $prestudentstatus = $prestudent->prestudentstatus; $person_id = $prestudent->person_id; $person = $this->PersonModel->getPersonStammdaten($person_id, true)->retval; - $dokumente = $this->AkteModel->getAktenWithDokInfo($person_id, null, false)->retval; - $dokumenteNachzureichen = $this->AkteModel->getAktenWithDokInfo($person_id, null, true)->retval; + $dokumente = $this->AkteModel->getAktenWithDokInfo($person_id, null, false, false)->retval; + $dokumenteNachzureichen = $this->AkteModel->getAktenWithDokInfo($person_id, null, true, false)->retval; //fill mail variables $interessentbez = $person->geschlecht == 'm' ? 'Ein Interessent' : 'Eine Interessentin'; @@ -2194,18 +2396,35 @@ class InfoCenter extends Auth_Controller public function getAbsageData() { - $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $stg_typ = $this->getStudienArtBerechtigung(['b', 'm']); - $statusgruende = $this->StatusgrundModel->getStatus(self::ABGEWIESENERSTATUS, true)->retval; - $studienSemester = $this->variablelib->getVar('infocenter_studiensemester'); - $studiengaenge = $this->StudiengangModel->getStudiengaengeWithOrgForm(['b', 'm'], $studienSemester); + if (!is_null($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($typ = null) + { + $studiengang_kz_all = $this->permissionlib->getSTG_isEntitledFor('infocenter'); + $stg_typ = $this->StudiengangModel->getStudiengangTyp($studiengang_kz_all, $typ); + return getData($stg_typ); + } + + public function getStudienartData() + { + $this->outputJsonSuccess($this->getStudienArtBerechtigung(['b', 'm', 'l'])); } public function saveAbsageForAll() diff --git a/application/controllers/system/issues/Issues.php b/application/controllers/system/issues/Issues.php index e0103cfec..6d959a024 100644 --- a/application/controllers/system/issues/Issues.php +++ b/application/controllers/system/issues/Issues.php @@ -6,7 +6,7 @@ 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 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() @@ -39,6 +39,7 @@ class Issues extends Auth_Controller ); $this->_setAuthUID(); // sets property uid + $this->setControllerId(); // sets the controller id } public function index() @@ -80,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); @@ -127,7 +128,7 @@ class Issues extends Auth_Controller { $all_funktionen_oe_kurzbz[$benutzerfunktion->oe_kurzbz][] = $benutzerfunktion->funktion_kurzbz; - // separate oes for the funktion needed for displaying issues + // separate oes for the additional funktion which enables displaying issues if ($benutzerfunktion->funktion_kurzbz == self::FUNKTION_KURZBZ) { $oe_kurzbz_for_funktion[] = $benutzerfunktion->oe_kurzbz; @@ -153,7 +154,9 @@ class Issues extends Auth_Controller } // add oes for which there is the "manage issues" Berechtigung - if (!$oe_kurzbz_berechtigt = $this->permissionlib->getOE_isEntitledFor(self::BERECHTIGUNG_KURZBZ)) + $oe_kurzbz_berechtigt = $this->permissionlib->getOE_isEntitledFor(self::BERECHTIGUNG_KURZBZ); + + if (!$oe_kurzbz_berechtigt) show_error('No permission or error when checking permissions'); $all_oe_kurzbz_berechtigt = array_unique(array_merge($oe_kurzbz_for_funktion, $oe_kurzbz_berechtigt)); diff --git a/application/controllers/system/issues/IssuesZustaendigkeiten.php b/application/controllers/system/issues/IssuesZustaendigkeiten.php new file mode 100644 index 000000000..fd3e6192a --- /dev/null +++ b/application/controllers/system/issues/IssuesZustaendigkeiten.php @@ -0,0 +1,217 @@ + 'admin:r', + 'getApps' => 'admin:r', + 'getFehlercodes' => 'admin:r', + 'getNonAssignedZustaendigkeiten' => 'admin:r', + 'addZustaendigkeit' => 'admin:rw', + 'deleteZustaendigkeit' => 'admin:rw' + ) + ); + + // Load libraries + $this->load->library('IssuesLib'); + $this->load->library('WidgetLib'); + + // Load models + $this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); + $this->load->model('system/Fehler_model', 'FehlerModel'); + $this->load->model('system/Fehler_model', 'FehlerModel'); + $this->load->model('system/Fehlerzustaendigkeiten_model', 'FehlerzustaendigkeitenModel'); + + $this->loadPhrases( + array( + 'global', + 'ui', + 'filter', + 'lehre', + 'person', + 'fehlermonitoring' + ) + ); + + $this->_setAuthUID(); // sets property uid + $this->setControllerId(); // sets the controller id + } + + public function index() + { + $this->load->view("system/issues/issuesZustaendigkeiten.php"); + } + + /** + * Loads all Apps to which Fehler exist. + */ + public function getApps() + { + $this->FehlerModel->addDistinct(); + $this->FehlerModel->addSelect('app'); + $this->FehlerModel->addOrder('app'); + + $appRes = $this->FehlerModel->load(); + + $this->outputJson($appRes); + } + + /** + * Gets all fehlercodes, optionally by app. + */ + public function getFehlercodes() + { + $app = $this->input->get('app'); + + //$this->FehlerModel->addSelect('fehlercode, fehler_kurzbz, fehlertext, fehlertyp_kurzbz'); + $this->FehlerModel->addOrder('fehlercode'); + + $fehlerRes = isset($app) ? $this->FehlerModel->loadWhere(array('app' => $app)) : $this->FehlerModel->load(); + + $this->outputJson($fehlerRes); + } + + /** + * Gets all Mitarbeiter, Organisationseinheiten, Funktionen not assigned to a Fehler yet. + */ + public function getNonAssignedZustaendigkeiten() + { + $fehlercode = $this->input->get('fehlercode'); + + $mitarbeiterRes = $this->FehlerzustaendigkeitenModel->getNonAssignedMitarbeiter($fehlercode); + + if (isError($mitarbeiterRes)) + { + $this->outputJsonError(getError($mitarbeiterRes)); + return; + } + + $this->OrganisationseinheitModel->addSelect('oe_kurzbz, bezeichnung, organisationseinheittyp_kurzbz'); + $this->OrganisationseinheitModel->addOrder('organisationseinheittyp_kurzbz, bezeichnung'); + $oeRes = $this->OrganisationseinheitModel->loadWhere(array('aktiv' => true)); + + if (isError($oeRes)) + { + $this->outputJsonError(getError($oeRes)); + return; + } + + $oe_funktionen = array(); + + if (hasData($oeRes)) + { + $oes = getData($oeRes); + + foreach ($oes as $oe) + { + $oe->funktionen = array(); + $funktionRes = $this->FehlerzustaendigkeitenModel->getNonAssignedFunktionen($fehlercode, $oe->oe_kurzbz); + + if (isError($funktionRes)) + { + $this->outputJsonError(getError($oeRes)); + return; + } + + $funktionData = getData($funktionRes); + $oe->funktionen = $funktionData; + $oe_funktionen[] = $oe; + } + } + + if (isError($funktionRes)) + { + $this->outputJsonError(getError($funktionRes)); + return; + } + + $result = array( + 'mitarbeiter' => getData($mitarbeiterRes), + 'oe_funktionen' => $oe_funktionen + ); + + $this->outputJsonSuccess($result); + } + + /** + * Adds a Zuständigkeit after performing error checks. + */ + public function addZustaendigkeit() + { + $fehlercode = $this->input->post('fehlercode'); + $mitarbeiter_person_id = $this->input->post('mitarbeiter_person_id'); + $oe_kurzbz = $this->input->post('oe_kurzbz'); + $funktion_kurzbz = $this->input->post('funktion_kurzbz'); + + if (isEmptyString($fehlercode)) + $this->outputJsonError($this->p->t('fehlermonitoring', 'fehlercodeFehlt')); + elseif (isEmptyString($mitarbeiter_person_id) && isEmptyString($oe_kurzbz)) + $this->outputJsonError($this->p->t('fehlermonitoring', 'mitarbeiterUndOeFehlt')); + elseif (!isEmptyString($mitarbeiter_person_id) && !isEmptyString($oe_kurzbz)) + $this->outputJsonError($this->p->t('fehlermonitoring', 'nurOeOderMitarbeiterSetzen')); + elseif (isset($mitarbeiter_person_id) && !is_numeric($mitarbeiter_person_id)) + $this->outputJsonError($this->p->t('fehlermonitoring', 'ungueltigeMitarbeiterId')); + else + { + $data = array( + 'fehlercode' => $fehlercode + ); + + if (!isEmptyString($mitarbeiter_person_id)) + $data['person_id'] = $mitarbeiter_person_id; + + if (!isEmptyString($oe_kurzbz)) + $data['oe_kurzbz'] = $oe_kurzbz; + + if (!isEmptyString($funktion_kurzbz)) + $data['funktion_kurzbz'] = $funktion_kurzbz; + + $zustaendigkeitExistsRes = $this->FehlerzustaendigkeitenModel->loadWhere($data); + + if (isError($zustaendigkeitExistsRes)) + $this->outputJsonError(getError($zustaendigkeitExistsRes)); + elseif (hasData($zustaendigkeitExistsRes)) + $this->outputJsonError($this->p->t('fehlermonitoring', 'zustaendigkeitExistiert')); + else + { + $data['insertvon'] = $this->_uid; + + $this->outputJson($this->FehlerzustaendigkeitenModel->insert($data)); + } + } + } + + /** + * Deletes a Zuständigkeit. + */ + public function deleteZustaendigkeit() + { + $fehlerzustaendigkeiten_id = $this->input->post('fehlerzustaendigkeiten_id'); + + // check if Id correctly passed + if (!isset($fehlerzustaendigkeiten_id) || !is_numeric($fehlerzustaendigkeiten_id)) + { + $this->outputJsonError($this->p->t('fehlermonitoring', 'ungueltigeZustaendigkeitenId')); + return; + } + + $this->outputJson($this->FehlerzustaendigkeitenModel->delete($fehlerzustaendigkeiten_id)); + } + + /** + * 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/system/issues/Plausichecks.php b/application/controllers/system/issues/Plausichecks.php new file mode 100644 index 000000000..2dd166794 --- /dev/null +++ b/application/controllers/system/issues/Plausichecks.php @@ -0,0 +1,142 @@ + array('system/issues_verwalten:r'), + 'runChecks' => array('system/issues_verwalten:r') + ) + ); + + // Load libraries + $this->load->library('issues/PlausicheckProducerLib'); + $this->load->library('WidgetLib'); + + // Load models + $this->load->model('system/Fehler_model', 'FehlerModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + } + + /* + * Get data for filtering the plausichecks and load the view. + */ + public function index() + { + $filterData = $this->_getFilterData(); + $this->load->view('system/issues/plausichecks', $filterData); + } + + /** + * Initiate plausichecks run. + */ + public function runChecks() + { + $studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz'); + $studiengang_kz = $this->input->get('studiengang_kz'); + $fehler_kurzbz = $this->input->get('fehler_kurzbz'); + + // issues array for passing issue texts + $issueTexts = array(); + // all fehler kurzbz which are going to be checked + $fehlerKurzbz = !isEmptyString($fehler_kurzbz) ? array($fehler_kurzbz) : $this->plausicheckproducerlib->getFehlerKurzbz(); + // set Studiengang to null if not passed + if (isEmptyString($studiengang_kz)) $studiengang_kz = null; + + // get the data returned by Plausicheck + foreach ($fehlerKurzbz as $fehler_kurzbz) + { + // execute the check + $issueTexts[$fehler_kurzbz] = array(); + $plausicheckRes = $this->plausicheckproducerlib->producePlausicheckIssue($fehler_kurzbz, $studiensemester_kurzbz, $studiengang_kz); + + if (isError($plausicheckRes)) $this->terminateWithJsonError(getError($plausicheckRes)); + + if (hasData($plausicheckRes)) + { + $plausicheckData = getData($plausicheckRes); + + foreach ($plausicheckData as $plausiData) + { + // get the data needed for issue production + $person_id = isset($plausiData['person_id']) ? $plausiData['person_id'] : null; + $oe_kurzbz = isset($plausiData['oe_kurzbz']) ? $plausiData['oe_kurzbz'] : null; + $fehlertext_params = isset($plausiData['fehlertext_params']) ? $plausiData['fehlertext_params'] : null; + $resolution_params = isset($plausiData['resolution_params']) ? $plausiData['resolution_params'] : null; + + // get Text of the Fehler + $this->FehlerModel->addSelect('fehlertext'); + $fehlerRes = $this->FehlerModel->loadWhere(array('fehler_kurzbz' => $fehler_kurzbz)); + + if (isError($fehlerRes)) $this->outputJsonError(getError($fehlerRes)); + + // optionally replace fehler parameters in text, output the fehlertext + if (hasData($fehlerRes)) + { + // use issue fehler text from database if present + $fehlerText = getData($fehlerRes)[0]->fehlertext; + + if (!isEmptyArray($fehlertext_params)) + { + // replace placeholder with params, if present + if (count($fehlertext_params) != substr_count($fehlerText, '%s')) + $this->terminateWithJsonError('Wrong number of parameters for Fehlertext, fehler_kurzbz ' . $fehler_kurzbz); + + $fehlerText = vsprintf($fehlerText, $fehlertext_params); + } + } + else // if no issue text found, use generic text + { + $fehlerText = self::GENERIC_ISSUE_OCCURED_TEXT; + } + + // add generic parameters to issue text + if (isset($person_id)) $fehlerText .= "; person_id: $person_id"; + if (isset($oe_kurzbz)) $fehlerText .= "; oe_kurzbz: $oe_kurzbz"; + $issueTexts[$fehler_kurzbz][] = $fehlerText; + } + } + } + + $this->outputJsonSuccess($issueTexts); + } + + /** + * Get the data needed for filtering for limiting checks. + */ + private function _getFilterData() + { + $this->StudiensemesterModel->addOrder('start', 'DESC'); + $studiensemesterRes = $this->StudiensemesterModel->load(); + + if (isError($studiensemesterRes)) show_error(getError($studiensemesterRes)); + + $currSemRes = $this->StudiensemesterModel->getAkt(); + + if (isError($currSemRes)) show_error(getError($currSemRes)); + + $this->StudiengangModel->addSelect('studiengang_kz, tbl_studiengang.bezeichnung, tbl_studiengang.typ, + tbl_studiengangstyp.bezeichnung AS typbezeichnung, UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as kuerzel'); + $this->StudiengangModel->addJoin('public.tbl_studiengangstyp', 'typ'); + $this->StudiengangModel->addOrder('kuerzel, tbl_studiengang.bezeichnung, studiengang_kz'); + $studiengaengeRes = $this->StudiengangModel->loadWhere(array('aktiv' => true)); + + if (isError($studiengaengeRes)) show_error(getError($studiengaengeRes)); + + $fehlerKurzbz = $this->plausicheckproducerlib->getFehlerKurzbz(); + + return array( + 'semester' => hasData($studiensemesterRes) ? getData($studiensemesterRes) : array(), + 'currsemester' => hasData($currSemRes) ? getData($currSemRes) : array(), + 'studiengaenge' => hasData($studiengaengeRes) ? getData($studiengaengeRes) : array(), + 'fehler' => $fehlerKurzbz + ); + } +} diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index 4e555be6c..bdd5316e7 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -22,11 +22,16 @@ class DB_Model extends CI_Model const PGSQL_BOOLEAN_FALSE = 'f'; const PGSQL_BOOLEAN_TYPE = 'bool'; const PGSQL_BOOLEAN_ARRAY_TYPE = '_bool'; + const PGSQL_INT2_TYPE = 'int2'; + const PGSQL_INT4_TYPE = 'int4'; + const PGSQL_INT8_TYPE = 'int8'; + const PGSQL_FLOAT4_TYPE = 'float4'; + const PGSQL_FLOAT8_TYPE = 'float8'; protected $dbTable; // Name of the DB-Table for CI-Insert, -Update, ... - protected $pk; // Name of the PrimaryKey for DB-Update, Load, ... + 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 + // True if this table has a primary key that uses a sequence private $executedQueryMetaData; private $executedQueryListFields; @@ -271,11 +276,6 @@ class DB_Model extends CI_Model /** * Load data and convert a record into a list of data from the main table, * and linked to every element, the data from the side tables - * - * TODO: - * - Adding support for composed primary key - * - Adding support for cascading side tables (useful?) - * * NOTE: sub queries are not supported in the from clause * * @return array @@ -598,6 +598,28 @@ class DB_Model extends CI_Model return $val; } + /** + * Convert PG-Int* to PHP-Integer + */ + public function pgIntPhp($val) + { + // If it is null, let it be null + if ($val == null) return $val; + + return intval($val); + } + + /** + * Convert PG-Float* to PHP-Float + */ + public function pgFloatPhp($val) + { + // If it is null, let it be null + if ($val == null) return $val; + + return floatval($val); + } + /** * Converts from PostgreSQL array to php array * It also takes care about array of booleans @@ -892,6 +914,11 @@ class DB_Model extends CI_Model // If array type, boolean type OR a UDF if (strpos($eqmd->type, DB_Model::PGSQL_ARRAY_TYPE) !== false || $eqmd->type == DB_Model::PGSQL_BOOLEAN_TYPE + || $eqmd->type == DB_Model::PGSQL_INT2_TYPE + || $eqmd->type == DB_Model::PGSQL_INT4_TYPE + || $eqmd->type == DB_Model::PGSQL_INT8_TYPE + || $eqmd->type == DB_Model::PGSQL_FLOAT4_TYPE + || $eqmd->type == DB_Model::PGSQL_FLOAT8_TYPE || $this->udflib->isUDFColumn($eqmd->name, $eqmd->type)) { // If UDFs are inside this result set @@ -941,6 +968,19 @@ class DB_Model extends CI_Model { $resultElement->{$toBeConverted->name} = $this->pgBoolPhp($resultElement->{$toBeConverted->name}); } + // Integer type + elseif ($toBeConverted->type == DB_Model::PGSQL_INT2_TYPE + || $toBeConverted->type == DB_Model::PGSQL_INT4_TYPE + || $toBeConverted->type == DB_Model::PGSQL_INT8_TYPE) + { + $resultElement->{$toBeConverted->name} = $this->pgIntPhp($resultElement->{$toBeConverted->name}); + } + // Float type + elseif ($toBeConverted->type == DB_Model::PGSQL_FLOAT4_TYPE + || $toBeConverted->type == DB_Model::PGSQL_FLOAT8_TYPE) + { + $resultElement->{$toBeConverted->name} = $this->pgFloatPhp($resultElement->{$toBeConverted->name}); + } } } } diff --git a/application/core/FHC_Controller.php b/application/core/FHC_Controller.php index ce8748c5a..dcd693cb1 100644 --- a/application/core/FHC_Controller.php +++ b/application/core/FHC_Controller.php @@ -121,7 +121,7 @@ abstract class FHC_Controller extends CI_Controller protected function terminateWithJsonError($message) { header('Content-Type: application/json'); - echo json_encode(error($message)); + echo json_encode(error($message)); // KEEP IT!!! exit; } @@ -132,31 +132,50 @@ abstract class FHC_Controller extends CI_Controller { $this->output->set_content_type('application/json')->set_output(json_encode($mixed)); } - + + /** + * To download the given file represented by the fileObj parameter. + * fileObj has the following structure: + * $fileObj->filename + * $fileObj->file + * $fileObj->name + * $fileObj->mimetype + * $fileObj->disposition + */ protected function outputFile($fileObj) { - if (file_exists($fileObj->file)) + // If the file exists + if (isset($fileObj->file) && !isEmptyString($fileObj->file) && file_exists($fileObj->file)) { - $finfo = new finfo(FILEINFO_MIME); - header('Content-Description: File Transfer'); - header('Content-Type: '. $finfo->file($fileObj->file)); + header('Content-Type: '. $fileObj->mimetype); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($fileObj->file)); - - if (isset($fileObj->disposition) && ($fileObj->disposition == 'inline' || $fileObj->disposition == 'attachment')) + + if (isset($fileObj->disposition) + && ($fileObj->disposition == 'inline' || $fileObj->disposition == 'attachment')) { header('Content-Disposition: '. $fileObj->disposition. '; filename="'. $fileObj->name. '"'); } - - readfile($fileObj->file); - - exit; + + readfile($fileObj->file); // reads the file content to the output buffer } - - return false; + else + { + // Otherwise print an error + show_error('The provided file does not exist: '.(isset($fileObj->file) ? $fileObj->file : 'file not given')); + } + } + + /** + * Return the JSON decoded HTTP POST request + * If the request is not in JSON format then a null value is returned + */ + protected function getPostJSON() + { + return json_decode($this->input->raw_input_stream); } //------------------------------------------------------------------------------------------------------------------ @@ -175,3 +194,4 @@ abstract class FHC_Controller extends CI_Controller } } } + diff --git a/application/core/FS_Model.php b/application/core/FS_Model.php index 03a0ee095..0d696d378 100644 --- a/application/core/FS_Model.php +++ b/application/core/FS_Model.php @@ -3,113 +3,238 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); /** - * + * Model to work with the filesystem, it represents a directory + * It could be extended or could be used directly to work on the given path */ -abstract class FS_Model extends CI_Model +class FS_Model extends CI_Model { - protected $filepath; // Path of the file + const READ_MODE = 'r'; + const READ_WRITE_MODE = 'w+'; + const READ_APPEND_MODE = 'a+'; + const BLOCK_SIZE = 8192; + const META_URI = 'uri'; + + private $_path; // Directory where this model can operate /** - * Loads FilesystemLib and set properties + * Set properties */ - public function __construct($filepath = null) + public function __construct($path) { parent::__construct(); - // Load the filesystem library - $this->load->library('FilesystemLib'); + $this->_path = $path; + } - $this->filepath = $filepath; + // ------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Opens a file in read mode and returns its file handle + */ + public function openRead($filename) + { + return $this->_open($filename, self::READ_MODE); } /** - * Read data from file system - * - * @return array + * Opens a file in read and write mode and returns its file handle + * If the file does not exist then it is created */ - public function read($filename) + public function openReadWrite($filename) { - // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); - - // Check method parameters - if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); - - if (!is_null($data = $this->filesystemlib->read($this->filepath, $filename))) - { - return success(base64_encode($data)); - } - else - { - return error('An error occurred while reading a file', EXIT_ERROR); - } + return $this->_open($filename, self::READ_WRITE_MODE); } /** - * Writing data to file system - * - * @param string $fileContent File content - * @return object + * Opens a file in read and append mode and returns its file handle + * If the file does not exist then it is created */ - public function write($filename, $content) + public function openReadAppend($filename) { - // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + return $this->_open($filename, self::READ_APPEND_MODE); + } - // Check method parameters - if (is_null($content)) return error('The given file content is not valid', EXIT_ERROR); - if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); + /** + * Closes a file handle + */ + public function close($fileHandle) + { + return fclose($fileHandle) === true ? success() : error('Error while closing the file handler'); + } - if ($this->filesystemlib->write($this->filepath, $filename, base64_decode($content)) === true) + /** + * Reads a block of bytes from the given file + * Returns a success that contains the block + * On failure returns an error + */ + public function readBlock($fileHandle) + { + // Reads a block of bytes from the file + $block = fread($fileHandle, self::BLOCK_SIZE); + + // If an error occurred + if ($block === false) + { + // Prepare the error message + $errorMsg = 'An error occurred while reading a file'; + + // Tries to get the file name and to concatenate it to the error message + $fileMetaData = stream_get_meta_data($fileHandle); + if (isset($fileMetaData[self::META_URI])) $errorMsg .= ': '.$fileMetaData[self::META_URI]; + + return error($errorMsg); // returns the error + } + + return success($block); // return success if everything was fine + } + + /** + * Writes/appends (depending on how the file was opened) a content into a file + * Returns a success that contains the written number of bytes + * On failure returns an error + */ + public function write($fileHandle, $content) + { + // Writes the provided content to the file + $writeResult = fwrite($fileHandle, $content); + + // If an error occurred + if ($writeResult === false) + { + $errorMsg = 'An error occurred while writing a file'; + + // Tries to get the file name and to concatenate it to the error message + $fileMetaData = stream_get_meta_data($fileHandle); + if (isset($fileMetaData[self::META_URI])) $errorMsg .= ': '.$fileMetaData[self::META_URI]; + + return error($errorMsg); // returns the error + } + + return success($writeResult); + } + + /** + * Removes a given file + */ + public function remove($filename) + { + // Check if the property _path represents a valid directory + $checkResult = $this->_checkPath(); + + if (isError($checkResult)) return $checkResult; // If not then return the error + + // Check filename + if (isEmptyString($filename)) return error('The given filename is not valid'); + + // remove file + if (unlink($this->_path.DIRECTORY_SEPARATOR.$filename) === true) { return success(); } else { - return error('An error occurred while writing a file', EXIT_ERROR); + return error('An error occurred while removing a file'); } } + // ------------------------------------------------------------------------------------------------------------------ + // Old public methods that work with the base64 encoding, not to be used! + /** - * Append data to a file - * - * @param array $data File content - * @return array + * Read data from the given file and encode its content to base64 */ - public function append($filename, $content) + public function readBase64($filename) { - // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + // Open the file in read mode + $openReadResult = $this->openRead($filename); + if (isError($openReadResult)) return $openReadResult; // if an error occurred then return it - // Check method parameters - if (is_null($content)) return error('The given file content is not valid', EXIT_ERROR); - if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); + $fileContent = ''; // to store the file content + $fileHandle = getData($openReadResult); // get the file handle - if ($this->filesystemlib->append($this->filepath, $filename, base64_decode($content)) === true) + // While the end of the file is not reached and the read does not fail + while (!feof($fileHandle) && isSuccess($readBlockResult = $this->readBlock($fileHandle))) { - return success(); - } - else - { - return error('An error occurred while appending to a file', EXIT_ERROR); + // Concatenate the content of the file + $fileContent .= getData($readBlockResult); } + + // If an error occurred while reading then return it + if (isError($readBlockResult)) return $readBlockResult; + + // Close the file handler + $closeResult = $this->close($fileHandle); + if (isError($closeResult)) return $closeResult; // if it fails then return the error + + // If everything was fine encode the file content into base64 and return it as a success + return success(base64_encode($fileContent)); + } + + /** + * Writes the given content into the given file. The content is base64 encoded + */ + public function writeBase64($filename, $content) + { + // Open the file in read and write mode + $openWriteResult = $this->openReadWrite($filename); + if (isError($openWriteResult)) return $openWriteResult; // if an error occurred then return it + + $fileHandle = getData($openWriteResult); // get the file handle + + // Writes the given base64 encoded content into to given file + $writeResult = $this->write($fileHandle, base64_decode($content)); + // If an error occurred while writing then return it + if (isError($writeResult)) return $writeResult; + + // Close the file handler + $closeResult = $this->close($fileHandle); + if (isError($closeResult)) return $closeResult; // if it fails then return the error + + // If everything was fine + return success(); + } + + /** + * Appends the given content into the given file. The content is base64 encoded + */ + public function appendBase64($filename, $content) + { + // Open the file in read and append mode + $openWriteResult = $this->openReadAppend($filename); + if (isError($openWriteResult)) return $openWriteResult; // if an error occurred then return it + + $fileHandle = getData($openWriteResult); // get the file handle + + // Writes the given base64 encoded content into to given file + $writeResult = $this->write($fileHandle, base64_decode($content)); + // If an error occurred while writing then return it + if (isError($writeResult)) return $writeResult; + + // Close the file handler + $closeResult = $this->close($fileHandle); + if (isError($closeResult)) return $closeResult; // if it fails then return the error + + // If everything was fine + return success(); } /** * Delete data from file system + * NOTE: it does not work with the base64 encoding but it has been kept for retro compatibility * * @param string $id Primary Key for DELETE * @return array */ - public function remove($filename) + public function removeBase64($filename) { // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + if (is_null($this->_path)) return error('The given _path in not valid', EXIT_ERROR); // Check method parameters if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); - if ($this->filesystemlib->remove($this->filepath, $filename) === true) + if (unlink($this->_path.DIRECTORY_SEPARATOR.$filename) === true) { return success(); } @@ -121,20 +246,21 @@ abstract class FS_Model extends CI_Model /** * Rename a file + * NOTE: it does not work with the base64 encoding but it has been kept for retro compatibility * * @param string $id Primary Key for DELETE * @return array */ - public function rename($filename, $newFilename) + public function renameBase64($filename, $newFilename) { // Check Class-Attributes - if (is_null($this->filepath)) return error('The given filepath in not valid', EXIT_ERROR); + if (is_null($this->_path)) return error('The given _path in not valid', EXIT_ERROR); // Check method parameters if (is_null($filename)) return error('The given filename is not valid', EXIT_ERROR); if (is_null($newFilename)) return error('The given new filename is not valid', EXIT_ERROR); - if ($this->filesystemlib->rename($this->filepath, $filename, $this->filepath, $newFilename) === true) + if (rename($this->_path.DIRECTORY_SEPARATOR.$filename, $this->_path.DIRECTORY_SEPARATOR.$newFilename) === true) { return success(); } @@ -143,4 +269,67 @@ abstract class FS_Model extends CI_Model return error('An error occurred while renaming a file', EXIT_ERROR); } } + + // ------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks if the given $this->_path is a valid directory + */ + private function _checkPath() + { + // If _path... + if (!isEmptyString($this->_path) // ...is a not empty string... + && file_exists($this->_path) && is_dir($this->_path)) // ...exists on the file system and it is a directory... + { + return success(); // return a success + } + + // If not a valid path return an error + return error('The given path is not valid: '.$this->_path); + } + + /** + * Open a file using the provided mode + * It returns a file handle + * Or write and append if the file does not exist then creates it + */ + private function _open($filename, $mode) + { + // Check if the property _path represents a valid directory + $checkResult = $this->_checkPath(); + if (isError($checkResult)) return $checkResult; // If not then return the error + + // Full file path: path + filename + $fileFullPath = $this->_path.DIRECTORY_SEPARATOR.$filename; + + // If needed then check if the file exists and really it is a file + if ($mode == self::READ_MODE && (!file_exists($fileFullPath) || !is_file($fileFullPath))) + { + return error('Trying to read a not existing file'); + } + + // If needed then check if it is possible to read from the path and the file + if ($mode == self::READ_MODE && (!is_readable($this->_path) || !is_readable($fileFullPath))) + { + return error('The given path or filename are not readable: '.$fileFullPath); + } + + // If needed then check if the path and the filename are writable + if (($mode == self::READ_WRITE_MODE || $mode == self::READ_APPEND_MODE) + && (!is_writable($this->_path) || (file_exists($fileFullPath) && !is_writable($fileFullPath)))) + { + return error('The given path or filename are not writable: '.$fileFullPath); + } + + // Open the file in read mode + $fileHandle = fopen($fileFullPath, $mode); + + // If it was a failure the return the error + if ($fileHandle === false) return error('An error occurred while opening a file in '.$mode.' mode'); + + // Otherwise return the file handle + return success($fileHandle); + } } + diff --git a/application/core/IIssueExistsChecker.php b/application/core/IIssueExistsChecker.php new file mode 100644 index 000000000..7f5a6b6e5 --- /dev/null +++ b/application/core/IIssueExistsChecker.php @@ -0,0 +1,21 @@ +_codeLibMappings[$issue->fehlercode])) + // ignore if Fehlercode is not in libmappings (shouldn't be checked) + if (!isset($this->_codeLibMappings[$issue->fehlercode])) continue; + + $libName = $this->_codeLibMappings[$issue->fehlercode]; + + // add person id and oe kurzbz automatically as params, merge it with additional params + // decode bewerbung_parameter into assoc array + $params = array_merge( + array('issue_id' => $issue->issue_id, 'issue_person_id' => $issue->person_id, 'issue_oe_kurzbz' => $issue->oe_kurzbz), + isset($issue->behebung_parameter) ? json_decode($issue->behebung_parameter, true) : array() + ); + + // if called from extension (extension name set), path includes extension names, otherwise it is the core library folder + $libRootPath = isset($this->_extensionName) ? 'extensions/' . $this->_extensionName . '/' : ''; + $issuesLibPath = $libRootPath . self::ISSUE_RESOLVERS_FOLDER . '/'; + $issuesLibFilePath = DOC_ROOT . self::CI_PATH . '/' . $libRootPath . 'libraries/' . self::ISSUE_RESOLVERS_FOLDER . '/' . $libName . '.php'; + + // check if library file exists + if (!file_exists($issuesLibFilePath)) { - $libName = $this->_codeLibMappings[$issue->fehlercode]; + // log error and continue with next issue if not + $this->logError("Issue library file " . $issuesLibFilePath . " does not exist"); + continue; + } - // add person id and oe kurzbz automatically as params, merge it with additional params - // decode bewerbung_parameter into assoc array - $params = array_merge( - array('issue_id' => $issue->issue_id, 'issue_person_id' => $issue->person_id, 'issue_oe_kurzbz' => $issue->oe_kurzbz), - isset($issue->behebung_parameter) ? json_decode($issue->behebung_parameter, true) : array() - ); + // load library connected to fehlercode + $this->load->library($issuesLibPath . $libName); - // if called from extension (extension name set), path includes extension names, otherwise it is the core library folder - $libRootPath = isset($this->_extensionName) ? 'extensions/' . $this->_extensionName . '/' : ''; - $issuesLibPath = $libRootPath . self::ISSUES_FOLDER . '/'; - $issuesLibFilePath = DOC_ROOT . 'application/' . $libRootPath . 'libraries/' . self::ISSUES_FOLDER . '/' . $libName . '.php'; + $lowercaseLibName = mb_strtolower($libName); - // check if library file exists - if (!file_exists($issuesLibFilePath)) + // check if method is defined in library class + if (!is_callable(array($this->{$lowercaseLibName}, self::CHECK_ISSUE_RESOLVED_METHOD_NAME))) + { + // log error and continue with next issue if not + $this->logError("Method " . self::CHECK_ISSUE_RESOLVED_METHOD_NAME . " is not defined in library $lowercaseLibName"); + continue; + } + + // call the function for checking for issue resolution + $issueResolvedRes = $this->{$lowercaseLibName}->{self::CHECK_ISSUE_RESOLVED_METHOD_NAME}($params); + + if (isError($issueResolvedRes)) + { + $this->logError(getError($issueResolvedRes)); + } + else + { + $issueResolvedData = getData($issueResolvedRes); + + if ($issueResolvedData === true) { - // log error and continue with next issue if not - $this->logError("Issue library file " . $issuesLibFilePath . " does not exist"); - continue; - } + // set issue to resolved if needed + $behobenRes = $this->issueslib->setBehoben($issue->issue_id, null); - // load library connected to fehlercode - $this->load->library( - $issuesLibPath . $libName - ); - - $lowercaseLibName = mb_strtolower($libName); - - // check if method is defined in libary class - if (!is_callable(array($this->{$lowercaseLibName}, self::CHECK_ISSUE_RESOLVED_METHOD_NAME))) - { - // log error and continue with next issue if not - $this->logError("Method " . self::CHECK_ISSUE_RESOLVED_METHOD_NAME . " is not defined in library $lowercaseLibName"); - continue; - } - - // call the function for checking for issue resolution - $issueResolvedRes = $this->{$lowercaseLibName}->{self::CHECK_ISSUE_RESOLVED_METHOD_NAME}($params); - - if (isError($issueResolvedRes)) - { - $this->logError(getError($issueResolvedRes)); - } - else - { - $issueResolvedData = getData($issueResolvedRes); - - if ($issueResolvedData === true) - { - // set issue to resolved if needed - $behobenRes = $this->issueslib->setBehoben($issue->issue_id, null); - - if (isError($behobenRes)) - $this->logError(getError($behobenRes)); - else - $this->logInfo("Issue " . $issue->issue_id . " successfully resolved"); - } + if (isError($behobenRes)) + $this->logError(getError($behobenRes)); + else + $this->logInfo("Issue " . $issue->issue_id . " successfully resolved"); } } } diff --git a/application/helpers/hlp_common_helper.php b/application/helpers/hlp_common_helper.php index 7b937d73d..913d29b54 100644 --- a/application/helpers/hlp_common_helper.php +++ b/application/helpers/hlp_common_helper.php @@ -1,20 +1,19 @@ . */ if (! defined('BASEPATH')) exit('No direct script access allowed'); @@ -42,15 +41,19 @@ function generateToken($length = 64) { $firstGeneratedToken = random_bytes($length); // try to generates cryptographically secure pseudo-random bytes... } - catch (Exception $e) { $firstGeneratedToken = null; } // if fails $firstGeneratedToken is set to null + catch (Exception $e) + { + // If fails $firstGeneratedToken is set to null + $firstGeneratedToken = null; + } } // For PHP >= 5.3 and < 7 and openssl is available elseif (function_exists('openssl_random_pseudo_bytes')) { $firstGeneratedToken = openssl_random_pseudo_bytes($length, $strong); // If the token generation ended with errors OR the generated token is NOT strong enough - if ($firstGeneratedToken == false || $strong == false) $firstGeneratedToken = null; // $firstGeneratedToken is set to null - } + if ($firstGeneratedToken == false || $strong == false) $firstGeneratedToken = null; // $firstGeneratedToken is set to null + } if ($firstGeneratedToken != null) // If everything was fine { @@ -107,10 +110,7 @@ function var_dump_to_error_log($parameter) function loadResource($path, $resources = null, $subdir = false) { // Place a / character at the and of the string if not present - if (strrpos($path, '/') < strlen($path) - 1) - { - $path .= '/'; - } + if (strrpos($path, '/') < strlen($path) - 1) $path .= '/'; // Loads in $tmpResources all the given resources $tmpResources = $resources; @@ -125,28 +125,36 @@ function loadResource($path, $resources = null, $subdir = false) // Loads in $tmpPaths path and eventually the subdirectories $tmpPaths = array($path); - // NOTE: Used @ to prevent ugly error messages - if (is_dir($path) && ($dirHandler = @opendir($path)) !== false) + + // If path is a directory + if (is_dir($path)) { - // Reads all file system entries present in path - while (($entry = readdir($dirHandler)) !== false) + // NOTE: Used @ to prevent ugly error messages + $dirHandler = @opendir($path); + + // Successfully opened + if ($dirHandler !== false) { - // If entry is a directory but not the current and subdirectories should be loaded - if ($subdir === true && $entry != '.' && $entry != '..' && is_dir($entry)) + // Reads all file system entries present in path + while (($entry = readdir($dirHandler)) !== false) { - $tmpPaths[] = $entry; - } - // If no resources are specified and the current file system entry is a file - if ($resources == null && is_file($path.$entry)) - { - // If the current entry is a php file store the name without extension - if ($entry != ($tmpName = str_replace('.php', '', $entry))) + // If entry is a directory but not the current and subdirectories should be loaded + if ($subdir === true && $entry != '.' && $entry != '..' && is_dir($path.$entry)) { - $tmpResources[] = $tmpName; + $tmpPaths[] = $path.$entry.'/'; + } + // If no resources are specified and the current file system entry is a file + if ($resources == null && is_file($path.$entry)) + { + // Name without php extension + $tmpName = str_replace('.php', '', $entry); + + // If the current entry is a php file store the name without extension + if ($entry != $tmpName) $tmpResources[] = $tmpName; } } + closedir($dirHandler); } - closedir($dirHandler); } // Loops through the resources @@ -156,10 +164,7 @@ function loadResource($path, $resources = null, $subdir = false) foreach ($tmpPaths as $tmpPath) { $fileName = $tmpPath.$tmpResource.'.php'; // Php extension - if (file_exists($fileName)) - { - include_once($fileName); - } + if (file_exists($fileName)) include_once($fileName); } } } @@ -351,3 +356,52 @@ function sanitizeProblemChars($str) return preg_replace($acentos, array_keys($acentos), htmlentities($str, ENT_NOQUOTES | ENT_HTML5, $enc)); } + +/** + * + */ +function findResource($path, $resource, $subdir = false, $extraDir = null) +{ + // Place a / character at the and of the string if not present + if (strrpos($path, '/') < strlen($path) - 1) $path .= '/'; + + // Loads in $tmpPaths path and eventually the subdirectories + $tmpPaths = array($path); + if (is_dir($path)) + { + // NOTE: Used @ to prevent ugly error messages + $dirHandler = @opendir($path); + + // Successfully opened + if ($dirHandler !== false) + { + // Reads all file system entries present in path + while (($entry = readdir($dirHandler)) !== false) + { + // If entry is a directory but not the current and subdirectories should be loaded + if ($subdir === true && $entry != '.' && $entry != '..' && is_dir($path.$entry)) + { + if ($extraDir == null) + { + $tmpPaths[] = $path.$entry.'/'; + } + else + { + $tmpPaths[] = $path.$entry.'/'.$extraDir.'/'; + } + } + } + closedir($dirHandler); + } + } + + // Loops through the paths + foreach ($tmpPaths as $tmpPath) + { + $fileName = $tmpPath.$resource.'.php'; // Php extension + if (file_exists($fileName)) return $fileName; + } + + return null; +} + diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index 203834ebb..05bba48c4 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -149,6 +149,31 @@ function generateJSsInclude($JSs) } } +/** + * Generates tags for the javascript modules you want to include, the parameter could by a string or an array of strings + */ +function generateJSModulesInclude($JSModules) +{ + $jsInclude = ''; + + $ci =& get_instance(); + $cachetoken = '?'.$ci->config->item('fhcomplete_build_version'); + + if (isset($JSModules)) + { + $tmpJSs = is_array($JSModules) ? $JSModules : array($JSModules); + + for ($tmpJSsCounter = 0; $tmpJSsCounter < count($tmpJSs); $tmpJSsCounter++) + { + $toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter].$cachetoken)).PHP_EOL; + + if ($tmpJSsCounter > 0) $toPrint = "\t\t".$toPrint; + + echo $toPrint; + } + } +} + /** * Generates all the includes needed by the Addons */ @@ -156,16 +181,26 @@ function generateAddonsJSsInclude($calledFrom) { $aktive_addons = array_filter(explode(";", ACTIVE_ADDONS)); + // For each active addon foreach ($aktive_addons as $addon) { + // Build the path to the hook file $hookfile = DOC_ROOT.'addons/'.$addon.'/hooks.config.inc.php'; + + // If the hook file exists if (file_exists($hookfile)) { - include($hookfile); + $js_hooks = array(); // default value + + include($hookfile); // include the hook file where the array js_hooks should be setup + + // If it contains the provided key calledFrom if (key_exists($calledFrom, $js_hooks)) { foreach ($js_hooks[$calledFrom] as $js_file) + { generateJSsInclude('addons/'.$addon.'/'.$js_file); + } } } } @@ -180,3 +215,4 @@ function generateBackwardCompatibleJSMsIe($js) echo ' '."\n"; echo "\n"; } + diff --git a/application/libraries/AkteLib.php b/application/libraries/AkteLib.php new file mode 100644 index 000000000..c4aee0095 --- /dev/null +++ b/application/libraries/AkteLib.php @@ -0,0 +1,268 @@ +_ci =& get_instance(); + + // Set the the _who property + $this->_who = 'Akte system'; // default + // It is possible to set it using the who parameter + if (!isEmptyArray($params) && isset($params['who']) && !isEmptyString($params['who'])) $this->_who = $params['who']; + + $this->_ci->load->model('crm/Akte_model', 'AkteModel'); + $this->_ci->load->model('content/DmsFS_model', 'DmsFSModel'); + + $this->_ci->load->library('DmsLib'); + } + + /** + * Writes a new file, adds a new dms entry with given akte data, + * adds a new dms version 0 for the written file, and adds Akte if dms add was successfull + * Returns success with inserted akte id or error + */ + public function add( + $person_id, $dokument_kurzbz, $titel, $mimetype, $fileHandle, // Required parameters + $bezeichnung = null, $archiv = false, $signiert = false, $stud_selfservice = false + ) + { + // add new dms entry and new dms version for the Akte, using Akte data (title, mimetype, file content as handle) + $dmsAddResult = $this->_ci->dmslib->add($titel, $mimetype, $fileHandle, self::AKTE_KATEGORIE_KURZBZ, $dokument_kurzbz, $bezeichnung); + + if (isError($dmsAddResult)) return $dmsAddResult; + + if (!hasData($dmsAddResult)) return error("Dms document could not be added"); + + $dmsAddData = getData($dmsAddResult); + + // insert the Akte + return $this->_ci->AkteModel->insert( + array( + 'person_id' => $person_id, + 'dokument_kurzbz' => $dokument_kurzbz, + 'titel' => $titel, + 'mimetype' => $mimetype, + 'bezeichnung' => $bezeichnung, + 'erstelltam' => date('Y-m-d'), + 'dms_id' => $dmsAddData->dms_id, + 'archiv' => $archiv, + 'signiert' => $signiert, + 'stud_selfservice' => $stud_selfservice, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => $this->_who + ) + ); + } + + /** + * Writes a new file, adds a new dms version 0 for the written file, and updates Akte if dms version add was successfull + * Returns success with updated akte id or error + */ + public function update($akte_id, $titel, $mimetype, $fileHandle, $bezeichnung = null, $archiv = false, $signiert = false, $stud_selfservice = false) + { + // check if Akte with dms exists + $this->_ci->AkteModel->addSelect('dms_id'); + $akteResult = $this->_ci->AkteModel->load($akte_id); + + if (isError($akteResult)) return $akteResult; + + if (!hasData($akteResult)) return error("Akte not found"); + + $dms_id = getData($akteResult)[0]->dms_id; + + if (isEmptyString($dms_id)) return error("Akte has no dms document"); + + // if Akte with dms found, update the last dms version + $dmsUpdateResult = $this->_ci->dmslib->updateLastVersion($dms_id, $fileHandle, $titel, $mimetype, $bezeichnung); + + if (isError($dmsUpdateResult)) return $dmsUpdateResult; + + if (!hasData($dmsUpdateResult)) return error("Dms document could not be updated"); + + // update the Akte + return $this->_ci->AkteModel->update( + $akte_id, + array( + 'titel' => $titel, + 'mimetype' => $mimetype, + 'bezeichnung' => $bezeichnung, + 'erstelltam' => date('Y-m-d'), + 'dms_id' => $dms_id, + 'archiv' => $archiv, + 'signiert' => $signiert, + 'stud_selfservice' => $stud_selfservice, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => $this->_who + ) + ); + } + + /** + * Gets akte data and associated dms data by akte Id + * Returns success with akte and dms data or error + */ + public function get($akte_id) + { + // get Akte data + $this->_ci->AkteModel->addSelect('person_id, dokument_kurzbz, mimetype, erstelltam, titel, bezeichnung, + gedruckt, uid, dms_id, nachgereicht, nachgereicht_am, anmerkung, + ausstellungsnation, formal_geprueft_amum, archiv, signiert, + stud_selfservice, akzeptiertamum, insertvon, insertamum, updatevon, updateamum'); + $this->_ci->AkteModel->load($akte_id); + $akteResult = $this->_ci->AkteModel->load($akte_id); + + if (isError($akteResult)) return $akteResult; + + if (!hasData($akteResult)) return error("Akte not found"); + + $resultObject = getData($akteResult)[0]; + + // set properties with same name in Akte and Dms table + $resultObject->akte_mimetype = $resultObject->mimetype; + + // get dms data + $dmsResult = $this->_ci->dmslib->getLastVersion($resultObject->dms_id); + + if (isError($dmsResult)) return $dmsResult; + + // properties to retrieve from dms + $dmsProperties = array('version', 'filename', 'mimetype', 'name', 'beschreibung', 'cis_suche', 'schlagworte', DmsLib::FILE_CONTENT_PROPERTY); + + // set dms properties + if (hasData($dmsResult)) + { + $dmsData = getData($dmsResult); + + foreach ($dmsProperties as $dmsProperty) + { + $resultObject->{$dmsProperty} = $dmsData->{$dmsProperty}; + } + } + else + { + // set null if no dms result found + foreach ($dmsProperties as $dmsProperty) + { + $resultObject->{$dmsProperty} = null; + } + } + + // return the object containing akte and dms data + return success($resultObject); + } + + /** + * Gets Akte data and associated dms data by person Id and dokument_kurzbz + * Returns success with result array with akte and dms data or error + */ + public function getByPersonIdAndDocumentType($person_id, $dokument_kurzbz) + { + // load all Akte entries for given person and dokument_kurzbz + $this->_ci->AkteModel->addSelect('akte_id'); + $akteResult = $this->_ci->AkteModel->loadWhere( + array( + 'person_id' => $person_id, + 'dokument_kurzbz' => $dokument_kurzbz + ) + ); + + if (!hasData($akteResult)) return error("Akte not found"); + + $akteData = getData($akteResult); + + $resultArr = array(); + + // for each found akte entry + foreach ($akteData as $akte) + { + // get dms and akte data from akte Id + $getAkteDmsResult = $this->get($akte->akte_id); + + if (isError($getAkteDmsResult)) return $getAkteDmsResult; + + $resultArr[] = getData($getAkteDmsResult); + } + + // return all found entries + return success($resultArr); + } + + /** + * Removes Akte by akte Id, removes all associated dms entries and versions, and deletes all associated files + * Returns success with removed version numbers or error + */ + public function remove($akte_id) + { + // get dms_id for akte + $this->_ci->AkteModel->addSelect('dms_id'); + $akteResult = $this->_ci->AkteModel->load($akte_id); + + if (isError($akteResult)) return $akteResult; + + if (!hasData($akteResult)) return error("Akte not found"); + + $dms_id = getData($akteResult)[0]->dms_id; + $error = null; + + // Start DB transaction to avoid deleting only part of the data + $this->_ci->db->trans_begin(); + + // delete Akte + $deleteResult = $this->_ci->AkteModel->delete($akte_id); + + if (isError($deleteResult)) + { + $error = $deleteResult; + } + else + { + // remove all dms entry for dms of the akte + $removeAllResult = $this->_ci->dmslib->removeAll($dms_id); + + if (isError($removeAllResult)) + $error = $removeAllResult; + } + + // Transaction complete! + $this->_ci->db->trans_complete(); + + // Check if everything went ok during the transaction + if ($this->_ci->db->trans_status() === false || isset($error)) + { + $this->_ci->db->trans_rollback(); + + // return occured error + if (isset($error)) + return $error; + else + return error("Error occured when deleting, rolled back"); + } + else + { + $this->_ci->db->trans_commit(); + + // return removed dms entry data + return $removeAllResult; + } + } +} diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index ee197ab05..86a81fb55 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -80,14 +80,24 @@ class AnrechnungLib // Get latest ZGV $result = $this->ci->PrestudentModel->getLatestZGVBezeichnung($prestudent_id); $latest_zgv_bezeichnung = hasData($result) ? getData($result)[0]->bezeichnung : ''; - + + // Get Sum of berufliche and schulische ECTS + $result = $this->ci->LehrveranstaltungModel->getEctsSumSchulisch($uid, $prestudent_id, $lv->studiengang_kz); + $sumEctsSchulisch = getData($result)[0]->ectssumschulisch; + + $result = $this->ci->LehrveranstaltungModel->getEctsSumBeruflich($uid); + $sumEctsBeruflich = getData($result)[0]->ectssumberuflich; + // Set the given studiensemester $antrag_data->lv_id = $lv_id; $antrag_data->lv_bezeichnung = $lv->bezeichnung; $antrag_data->ects = $lv->ects; + $antrag_data->sumEctsSchulisch = $sumEctsSchulisch; + $antrag_data->sumEctsBeruflich = $sumEctsBeruflich; $antrag_data->studiensemester_kurzbz = $studiensemester_kurzbz; $antrag_data->vorname = $person->vorname; $antrag_data->nachname = $person->nachname; + $antrag_data->student_uid = $uid; $antrag_data->matrikelnr = $student->matrikelnr; $antrag_data->studiengang_kz = $studiengang->studiengang_kz; $antrag_data->stg_bezeichnung = $studiengang->bezeichnung; @@ -112,6 +122,7 @@ class AnrechnungLib $anrechnung_data = new StdClass(); + $this->ci->AnrechnungModel->addJoin('lehre.tbl_anrechnung_begruendung', 'begruendung_id'); $result = $this->ci->AnrechnungModel->load($anrechnung_id); if (isError($result)) @@ -145,6 +156,7 @@ class AnrechnungLib $anrechnung_data->prestudent_id = ''; $anrechnung_data->lehrveranstaltung = ''; $anrechnung_data->begruendung_id = ''; + $anrechnung_data->begruendung = ''; $anrechnung_data->anmerkung = ''; $anrechnung_data->dms_id = ''; $anrechnung_data->insertamum = ''; @@ -155,6 +167,7 @@ class AnrechnungLib $anrechnung_data->status = getUserLanguage() == 'German' ? 'neu' : 'new'; $anrechnung_data->dokumentname = ''; + $this->ci->AnrechnungModel->addJoin('lehre.tbl_anrechnung_begruendung', 'begruendung_id'); $result = $this->ci->AnrechnungModel->loadWhere( array( 'lehrveranstaltung_id' => $lehrveranstaltung_id, @@ -800,6 +813,7 @@ class AnrechnungLib $anrechnung_data->prestudent_id = $anrechnung->prestudent_id; $anrechnung_data->lehrveranstaltung_id = $anrechnung->lehrveranstaltung_id; $anrechnung_data->begruendung_id = $anrechnung->begruendung_id; + $anrechnung_data->begruendung = $anrechnung->bezeichnung; $anrechnung_data->anmerkung = $anrechnung->anmerkung_student; $anrechnung_data->dms_id = $anrechnung->dms_id; $anrechnung_data->insertamum = (new DateTime($anrechnung->insertamum))->format('d.m.Y'); @@ -823,4 +837,110 @@ class AnrechnungLib return $anrechnung_data; } + + /** + * If Student is a Quereinsteiger, get ECTS Summe of all angerechnete Studiensemester. + * + * @param $prestudent_id + * @param $studiengang_kz Studiengang_kz der LV + * @return int|mixed + */ + public function getQuereinsteigerEctsSumme($prestudent_id, $studiengang_kz) + { + $sumEctsQuereinsteiger = 0; + + // Check, if student is Quereinsteiger + $this->ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + $result = $this->ci->PrestudentstatusModel->getFirstStatus($prestudent_id, 'Student'); + + $prestudentFirstStudentStatus = getData($result)[0]; + + // If Prestudent is not a Quereinsteiger + if ($prestudentFirstStudentStatus->ausbildungssemester == 1) + { + return $sumEctsQuereinsteiger; // return 0 + } + + $anzahlAngerechneteStudiensemester = $prestudentFirstStudentStatus->ausbildungssemester - 1; + + // If Prestudent is a Quereinsteiger + if ($prestudentFirstStudentStatus->ausbildungssemester > 1) + { + // Get the 'angerechnete Studiensemester' + $this->ci->load->model('organisations/Studiensemester_model', 'StudiensemesterModel'); + $result = $this->ci->StudiensemesterModel->getPreviousFrom( + $prestudentFirstStudentStatus->studiensemester_kurzbz, + $anzahlAngerechneteStudiensemester + ); + + // Get ECTS Summe of each 'angerechnetes Studiensemester' + foreach (getData($result) as $studiensemester) + { + $result = $this->ci->LehrveranstaltungModel->getSumQuereinstiegsECTSProSemester( + $studiengang_kz, + $studiensemester->studiensemester_kurzbz, + $anzahlAngerechneteStudiensemester--, + $prestudentFirstStudentStatus->orgform_kurzbz + ); + + if (hasData($result)) + { + $sumEctsQuereinsteiger = $sumEctsQuereinsteiger + getData($result)[0]->sum_ects; + } + } + } + return $sumEctsQuereinsteiger; // return sum of ects of all 'angerechnete Studiensemester' + } + + /** + * Get ECTS Summe of all Anrechnungen based on schulische Kenntnisse. + * + * @param $student_uid + * @return int|mixed + */ + public function getSchulischeAnrechnungenEctsSumme($student_uid) + { + $sumEctsSchule = 0; + + $result = $this->ci->LehrveranstaltungModel->getSumAngerechneteECTSByBegruendung($student_uid); + + if (hasData($result)) + { + foreach (getData($result) as $ects) + { + if ($ects->begruendung_id != 4) + { + $sumEctsSchule = $sumEctsSchule + $ects->sum; + } + } + } + + return $sumEctsSchule; + } + + /** + * Get ECTS Summe of all Anrechnungen based on berufliche Kenntnisse. + * + * @param $student_uid + * @return int + */ + public function getBeruflicheAnrechnungenEctsSumme($student_uid) + { + $sumEctsBeruflich = 0; + + $result = $this->ci->LehrveranstaltungModel->getSumAngerechneteECTSByBegruendung($student_uid); + + if (hasData($result)) + { + foreach (getData($result) as $ects) + { + if ($ects->begruendung_id == 4) + { + $sumEctsBeruflich = $ects->sum; + } + } + } + + return $sumEctsBeruflich; + } } diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index eae1a9ac4..fccfe503b 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -1,26 +1,483 @@ ci =& get_instance(); + $this->_ci =& get_instance(); - $this->ci->load->model('crm/Akte_model', 'AkteModel'); - $this->ci->load->model('content/Dms_model', 'DmsModel'); - $this->ci->load->model('content/DmsVersion_model', 'DmsVersionModel'); - $this->ci->load->model('content/DmsFS_model', 'DmsFSModel'); + // Set the the _who property + $this->_who = 'DMS system'; // default + // It is possible to set it using the who parameter + if (!isEmptyArray($params) && isset($params['who']) && !isEmptyString($params['who'])) $this->_who = $params['who']; + + $this->_ci->load->model('crm/Akte_model', 'AkteModel'); // deprecated, should not be used here! + $this->_ci->load->model('content/Dms_model', 'DmsModel'); + $this->_ci->load->model('content/DmsVersion_model', 'DmsVersionModel'); + $this->_ci->load->model('content/DmsFS_model', 'DmsFSModel'); } - + + // ----------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Writes a new file, adds a new dms entry and a new dms version 0 for the written file + * Returns success info of added dms entry (dms_id, version, filename) or error + */ + public function add( + $name, $mimetype, $fileHandle, // Required parameters + $kategorie_kurzbz = null, $dokument_kurzbz = null, $beschreibung = null, $cis_suche = false, $schlagworte = null + ) + { + // create unique filename, using original document name to detect file extension + $filename = $this->_getUniqueFilename($name); + + // copy file from fileHandle to dms folder + $copyFileResult = $this->_copyFile($fileHandle, $filename); + + 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)) + { + $dms_id = getData($dmsResult); + $version = 0; + + // 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') + ); + + $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"); + } + + /** + * Writes a new file with content of fileHandle, adds a new dms version (max version number + 1) for the written file + * Returns success with info of added dms version (version, filename) or error + */ + public function addNewVersion($dms_id, $fileHandle, $name = null, $mimetype = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) + { + // get the latest version + $lastVersionResult = $this->getLastVersion($dms_id); + + if (isError($lastVersionResult)) return $lastVersionResult; + + if (hasData($lastVersionResult)) + { + $lastVersion = getData($lastVersionResult); + + $originalName = isset($name) ? $name : $lastVersion->name; + + // create unique filename, using original document name to detect file extension + $filename = $this->_getUniqueFilename($originalName); + + // copy file from fileHandle to dms folder + $copyFileResult = $this->_copyFile($fileHandle, $filename); + + if (isError($copyFileResult)) return $copyFileResult; + + // 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') + ); + + $addVersionResult = $this->_ci->DmsVersionModel->insert($newVersion); + + if (isError($addVersionResult)) return $addVersionResult; + + // return dms info + $resObj = new stdClass(); + $resObj->version = $newVersionNumber; + $resObj->filename = $filename; + + return success($resObj); + } + else + return error("last version not found"); + } + + /** + * Updates the last version (max version number) of a dms entry + * Overwrites the file associated with this version with content read from fileHandle + * Returns success with info of added dms version (version, filename) or error + */ + public function updateLastVersion($dms_id, $fileHandle, $name = null, $mimetype = null, $beschreibung = null, $cis_suche = false, $schlagworte = null) + { + // get the latest version + $lastVersionResult = $this->getLastVersion($dms_id); + + if (isError($lastVersionResult)) return $lastVersionResult; + + if (hasData($lastVersionResult)) + { + $lastVersion = getData($lastVersionResult); + $filename = $lastVersion->filename; + + // update file in filesystem + $copyFileResult = $this->_copyFile($fileHandle, $filename); + + if (isError($copyFileResult)) return $copyFileResult; + + // 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 + ); + + if (isError($addVersionResult)) return $addVersionResult; + + // return dms info + $resObj = new stdClass(); + $resObj->version = $lastVersion->version; + $resObj->filename = $filename; + + return success($resObj); + } + else + return error("last version not found"); + } + + /** + * Gets dms version with highest number + * Returns success with dms data and fileHandle with file content or error + */ + public function getLastVersion($dms_id) + { + // get the latest version number + $this->_ci->DmsVersionModel->addSelect('version'); + $this->_ci->DmsVersionModel->addOrder('version', 'DESC'); + $this->_ci->DmsVersionModel->addOrder('insertamum', 'DESC'); + $this->_ci->DmsVersionModel->addLimit(1); + $lastDmsVersionResult = $this->_ci->DmsVersionModel->loadWhere( + array('dms_id' => $dms_id) + ); + + if (isError($lastDmsVersionResult)) return $lastDmsVersionResult; + + if (hasData($lastDmsVersionResult)) + { + $lastDmsVersionData = getData($lastDmsVersionResult)[0]; + $lastDmsVersion = $lastDmsVersionData->version; + + // call get Version with last version number + return $this->getVersion($dms_id, $lastDmsVersion); + } + else + return error("Dms last version not found"); + } + + /** + * Gets specified dms version + * Returns success with dms data and fileHandle with file content or error + */ + public function getVersion($dms_id, $version) + { + $this->_ci->DmsVersionModel->addSelect('dms_id, version, filename, mimetype, name, beschreibung, cis_suche, schlagworte'); + $dmsVersionResult = $this->_ci->DmsVersionModel->loadWhere( + array( + 'dms_id' => $dms_id, + 'version' => $version + ) + ); + + if (isError($dmsVersionResult)) return $dmsVersionResult; + + if (hasData($dmsVersionResult)) + { + $dmsVersion = getData($dmsVersionResult)[0]; + + // get file content as file pointer + $fileHandleResult = $this->_ci->DmsFSModel->openRead($dmsVersion->filename); + + if (isError($fileHandleResult)) return $fileHandleResult; + + if (hasData($fileHandleResult)) + { + $fileHandle = getData($fileHandleResult); + $dmsVersion->{self::FILE_CONTENT_PROPERTY} = $fileHandle; + + // close file pointer + $closeResult = $this->_ci->DmsFSModel->close($fileHandle); + + if (isError($closeResult)) return $closeResult; + + return success($dmsVersion); + } + else + return error("File could not be opened"); + } + else + return error("Dms version not found"); + } + + /** + * Removes dms entry and all its versions, deletes all associated files + * Returns success with removed version numbers or error + */ + public function removeAll($dms_id) + { + $versionsRemoved = array(); + + $this->_ci->DmsVersionModel->addSelect('version, filename'); + $allVersionsResult = $this->_ci->DmsVersionModel->loadWhere(array('dms_id' => $dms_id)); + + if (hasData($allVersionsResult)) + { + $allVersionsData = getData($allVersionsResult); + + $error = null; + + // Start DB transaction to avoid deleting only part of the data + $this->_ci->db->trans_begin(); + + // remove all versions of the dms Id + foreach ($allVersionsData as $version) + { + $removeVersionResult = $this->removeVersion($dms_id, $version->version); + + if (isError($removeVersionResult)) + { + $error = $removeVersionResult; + break; + } + else + $versionsRemoved[] = $version; // return removed versions + } + + // Transaction complete! + $this->_ci->db->trans_complete(); + + // Check if everything went ok during the transaction + if ($this->_ci->db->trans_status() === false || isset($error)) + { + $this->_ci->db->trans_rollback(); + + if (isset($error)) + return $error; + else + return error("Error occured when deleting, rolled back"); + } + else + { + $this->_ci->db->trans_commit(); + } + } + + return success($versionsRemoved); + } + + /** + * Removes latest version and its associated file + * Returns success with removed dms version data (dms_id, version, filename) or error + */ + public function removeLastVersion($dms_id) + { + $lastVersionNumber = 0; + // get the latest version + $lastVersionResult = $this->getLastVersion($dms_id); + + if (isError($lastVersionResult)) return $lastVersionResult; + + if (hasData($lastVersionResult)) + { + $lastVersion = getData($lastVersionResult); + $lastVersionNumber = $lastVersion->version; + } + + // call remove method for latest version + return $this->removeVersion($dms_id, $lastVersionNumber); + } + + /** + * Removes latest version and its associated file + * Returns success with removed dms version data (dms_id, version, filename) or error + */ + public function removeVersion($dms_id, $version) + { + $removeVersionResultObj = new stdClass(); + $removeVersionResultObj->dms_id = null; + $removeVersionResultObj->version = null; + $removeVersionResultObj->filename = null; + + // load dms version and check how many versions there are + $db = new DB_Model(); + + $checkDeleteResult = $db->execReadOnlyQuery( + "SELECT filename, + (SELECT count(version) + FROM campus.tbl_dms_version dv_anzahl + WHERE dv_anzahl.dms_id = dv.dms_id) AS anzahl_versionen + FROM campus.tbl_dms_version dv + WHERE dms_id=? + AND version=?", + array($dms_id, $version) + ); + + if (isError($checkDeleteResult)) return $checkDeleteResult; + + if (hasData($checkDeleteResult)) + { + $checkDeleteData = getData($checkDeleteResult)[0]; + + // delete version + $deleteVersionResult = $this->_ci->DmsVersionModel->delete(array($dms_id, $version)); + + if (isError($deleteVersionResult)) return $deleteVersionResult; + + $removeVersionResultObj->version = $version; + $removeVersionResultObj->filename = $checkDeleteData->filename; + + // delete dms too if no versions left + if ($checkDeleteData->anzahl_versionen <= 1) + { + $deleteDmsResult = $this->_ci->DmsModel->delete($dms_id); + + if (isError($deleteDmsResult)) return $deleteDmsResult; + + $removeVersionResultObj->dms_id = $dms_id; + } + + // delete file from file system + $removeResult = $this->_ci->DmsFSModel->remove($checkDeleteData->filename); + + if (isError($removeResult)) return $removeResult; + } + + return success($removeVersionResultObj); + } + + // ----------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * Copies file from sourceFileHandle to destinationFilename in DMS folder + * Returns success or error on fail + */ + private function _copyFile($sourceFileHandle, $destinationFilename) + { + // get file location from file handle + $metaData = stream_get_meta_data($sourceFileHandle); + + if (isset($metaData['uri']) && !isEmptyString($metaData['uri'])) + { + // 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'); + } + } + else + { + // error when source location could not be determined + return error('error occured while getting source file name'); + } + + return success($resObj); + } + + /** + * Generates unique filename, appends file extension from document name + * Returns the filename string + */ + private function _getUniqueFilename($dokname) + { + // create unique id + $uniqueFilename = uniqid(); + + // getting extension of file from document name + $fileExtension = pathinfo($dokname, PATHINFO_EXTENSION); + + // if file extension found, append it + if (!isEmptyString($fileExtension)) + $uniqueFilename .= '.'.$fileExtension; + + return $uniqueFilename; + } + + // ----------------------------------------------------------------------------------------------------------- + // Deprecated methods, not to be used + /** * Load a DMS Document. * If no version is particularly given, the latest version is loaded. @@ -33,19 +490,20 @@ class DmsLib extends FHC_Controller { if (is_numeric($dms_id)) { - $this->ci->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id'); - $this->ci->DmsModel->addOrder('version', 'DESC'); - $this->ci->DmsModel->addLimit(1); - + $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); + return $this->_ci->DmsModel->load($dms_id); } else { - return $this->ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); + return $this->_ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); } } + return error('The parameter DMS ID must be a number'); } @@ -57,34 +515,30 @@ class DmsLib extends FHC_Controller */ public function read($dms_id, $version = null) { - $result = null; + $result = error('Wrong dms_id parameter'); if (isset($dms_id)) { - $this->ci->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id'); - $this->ci->DmsModel->addOrder('version', 'DESC'); - $this->ci->DmsModel->addLimit(1); + $this->_ci->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id'); + $this->_ci->DmsModel->addOrder('version', 'DESC'); + $this->_ci->DmsModel->addLimit(1); if (!isset($version)) { - $result = $this->ci->DmsModel->load($dms_id); + $result = $this->_ci->DmsModel->load($dms_id); } else { - $result = $this->ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); + $result = $this->_ci->DmsModel->loadWhere(array('dms_id' => $dms_id, 'version' => $version)); } - } - if (hasData($result)) - { - $resultFS = $this->ci->DmsFSModel->read($result->retval[0]->filename); - if (isSuccess($resultFS)) + // If a dms has been found + if (hasData($result)) { - $result->retval[0]->{DmsLib::FILE_CONTENT_PROPERTY} = $resultFS->retval; - } - else - { - $result = $resultFS; + $resultFS = $this->_ci->DmsFSModel->readBase64(getData($result)[0]->filename); + if (isError($resultFS)) return $resultFS; // if an error occurred return it + + $result->retval[0]->{self::FILE_CONTENT_PROPERTY} = getData($resultFS); } } @@ -101,28 +555,22 @@ class DmsLib extends FHC_Controller */ public function getAktenAcceptedDms($person_id, $dokument_kurzbz = null, $no_file = null) { - $result = $this->ci->AkteModel->getAktenAcceptedDms($person_id, $dokument_kurzbz); + $result = $this->_ci->AkteModel->getAktenAcceptedDms($person_id, $dokument_kurzbz); if (hasData($result) && $no_file == null) { - $cnt = count($result->retval); - for ($i = 0; $i < $cnt; $i++) + for ($i = 0; $i < count(getData($result)); $i++) { - $resultFS = $this->ci->DmsFSModel->read($result->retval[$i]->filename); - if (isSuccess($resultFS)) - { - $result->retval[$i]->{DmsLib::FILE_CONTENT_PROPERTY} = $resultFS->retval; - } - else - { - $result = $resultFS; - } + $resultFS = $this->_ci->DmsFSModel->readBase64(getData($result)[$i]->filename); + if (isError($resultFS)) return $resultFS; // if an error occurred return it + + $result->retval[$i]->{self::FILE_CONTENT_PROPERTY} = getData($resultFS); } } return $result; } - + /** * Uploads a document and saves it to DMS * @param $dms DMS assoc array @@ -135,32 +583,33 @@ class DmsLib extends FHC_Controller // Init upload configs $this->_loadUploadLibrary($allowed_types); - if (!$this->ci->upload->do_upload($field_name)) + if (!$this->_ci->upload->do_upload($field_name)) { - return error($this->ci->upload->display_errors()); + return error($this->_ci->upload->display_errors()); } - $upload_data = $this->ci->upload->data(); // data about the uploaded file - $filename = $upload_data['file_name']; + $upload_data = $this->_ci->upload->data(); // data about the uploaded file // Insert to DMS table - if (!$result = $this->ci->DmsModel->insert($this->ci->DmsModel->filterFields($dms))) - { - return error('Failed inserting to DMS'); - } - $upload_data['dms_id'] = $result->retval; + $insDmsResult = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms)); + if (isError($insDmsResult)) return $insDmsResult; + + $upload_data['dms_id'] = getData($insDmsResult); // Insert DMS version - if (!$result = $this->ci->DmsVersionModel->insert( - $this->ci->DmsVersionModel->filterFields($dms, $result->retval, $filename))) - { - return error('Failed inserting DMS version'); - } + $insVersionResult = $this->_ci->DmsVersionModel->insert( + $this->_ci->DmsVersionModel->filterFields( + $dms, + $upload_data['dms_id'], + $upload_data['file_name'] + ) + ); + if (isError($insVersionResult)) return $insVersionResult; - // return result of uploaded data - return success($upload_data); // data about the uploaded file + // Return result of uploaded data + return success($upload_data); } - + /** * Download a document. * @@ -171,38 +620,31 @@ class DmsLib extends FHC_Controller */ public function download($dms_id, $filename = null, $disposition = 'inline') { - $result = $this->getFileInfo($dms_id); - - if (isError($result)) + // Retrieves info about the given dms + $fileInfoResult = $this->getFileInfo($dms_id); + if (isError($fileInfoResult)) return error(getError($fileInfoResult)); + + // If data have been found + if (hasData($fileInfoResult)) { - return error(getError($result)); + $fileObj = getData($fileInfoResult); + + // Change filename, if filename is provided + if (!isEmptyString($filename)) $fileObj->name = $filename; + + // Add file disposition if disposition has a valid value + if ($disposition == 'attachment' || $disposition == 'inline') + { + $fileObj->disposition = $disposition; + } + + return success($fileObj); } - $fileObj = getData($result); - - // Change filename, if filename is provided - if (is_string($filename)) - { - $fileObj->name = $filename; - } - - // Add file disposition - if ($disposition == 'attachment') - { - $fileObj->disposition = 'attachment'; - } - else - { - $fileObj->disposition = 'inline'; - } - - // Output file - if(!$this->outputFile($fileObj)) - { - return error('Error on file output'); - } + // If no data have been found then return an empty success + return success(); } - + /** * Get file information. * @@ -212,28 +654,28 @@ class DmsLib extends FHC_Controller */ public function getFileInfo($dms_id, $version = null) { - if (!is_numeric($dms_id)) - { - return error('Wrong parameter'); - } - - // Load file + // 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)); - if (isError($result)) + // If data have been found + if (hasData($result)) { - return error(getError($result)); + // Store file information in fileObj + $fileObj = new stdClass(); + $fileObj->filename = getData($result)[0]->filename; + $fileObj->file = DMS_PATH.getData($result)[0]->filename; + $fileObj->name = DMS_PATH.getData($result)[0]->name; // original user filename + $fileObj->mimetype = getData($result)[0]->mimetype; + + return success($fileObj); } - // Store file information in fileObj - $fileObj = new StdClass(); - $fileObj->filename = getData($result)[0]->filename; - $fileObj->file = DMS_PATH. getData($result)[0]->filename; - $fileObj->name = DMS_PATH. getData($result)[0]->name; // original users filename - $fileObj->mimetype = DMS_PATH. getData($result)[0]->mimetype; - - return success($fileObj); - + // If no data have been found return an empty success + return success(); } /** @@ -253,20 +695,20 @@ class DmsLib extends FHC_Controller $result = $this->_saveFileOnInsert($dms); if (isSuccess($result)) { - $filename = $result->retval; + $filename = getData($result); if (isset($dms['dms_id']) && $dms['dms_id'] != '') { - $result = $this->ci->DmsVersionModel->insert( - $this->ci->DmsVersionModel->filterFields($dms, $dms['dms_id'], $filename) + $result = $this->_ci->DmsVersionModel->insert( + $this->_ci->DmsVersionModel->filterFields($dms, $dms['dms_id'], $filename) ); } else { - $result = $this->ci->DmsModel->insert($this->ci->DmsModel->filterFields($dms)); + $result = $this->_ci->DmsModel->insert($this->_ci->DmsModel->filterFields($dms)); if (isSuccess($result)) { - $result = $this->ci->DmsVersionModel->insert( - $this->ci->DmsVersionModel->filterFields($dms, $result->retval, $filename) + $result = $this->_ci->DmsVersionModel->insert( + $this->_ci->DmsVersionModel->filterFields($dms, getData($result), $filename) ); } } @@ -277,15 +719,15 @@ class DmsLib extends FHC_Controller $result = $this->_saveFileOnUpdate($dms); if (isSuccess($result)) { - $result = $this->ci->DmsModel->update($dms['dms_id'], $this->ci->DmsModel->filterFields($dms)); + $result = $this->_ci->DmsModel->update($dms['dms_id'], $this->_ci->DmsModel->filterFields($dms)); if (isSuccess($result)) { - $result = $this->ci->DmsVersionModel->update( + $result = $this->_ci->DmsVersionModel->update( array( $dms['dms_id'], $dms['version'] ), - $this->ci->DmsVersionModel->filterFields($dms) + $this->_ci->DmsVersionModel->filterFields($dms) ); } } @@ -308,56 +750,54 @@ class DmsLib extends FHC_Controller if (is_numeric($person_id) && is_numeric($dms_id)) { // Start DB transaction - $this->ci->db->trans_start(false); + $this->_ci->db->trans_start(false); // Get akte_id from table tbl_akte - $result = $this->ci->AkteModel->loadWhere(array('person_id' => $person_id, 'dms_id' => $dms_id)); + $result = $this->_ci->AkteModel->loadWhere(array('person_id' => $person_id, 'dms_id' => $dms_id)); if (isSuccess($result)) { // Delete all entries in tbl_akte - $cnt = count($result->retval); - for ($i = 0; $i < $cnt; $i++) + for ($i = 0; $i < count(getData($result)); $i++) { - $this->ci->AkteModel->delete($result->retval[$i]->akte_id); + $this->_ci->AkteModel->delete(getData($result)[$i]->akte_id); } // Get all filenames related to this dms - $resultFileNames = $this->ci->DmsVersionModel->loadWhere(array('dms_id' => $dms_id)); + $resultFileNames = $this->_ci->DmsVersionModel->loadWhere(array('dms_id' => $dms_id)); if (isSuccess($resultFileNames)) { // Delete from tbl_dms_version - $result = $this->ci->DmsVersionModel->delete(array('dms_id' => $dms_id)); + $result = $this->_ci->DmsVersionModel->delete(array('dms_id' => $dms_id)); if (isSuccess($result)) { // Delete from tbl_dms - $result = $this->ci->DmsModel->delete($dms_id); + $result = $this->_ci->DmsModel->delete($dms_id); } } } // Transaction complete! - $this->ci->db->trans_complete(); + $this->_ci->db->trans_complete(); // Check if everything went ok during the transaction - if ($this->ci->db->trans_status() === false || isError($result)) + if ($this->_ci->db->trans_status() === false || isError($result)) { - $this->ci->db->trans_rollback(); + $this->_ci->db->trans_rollback(); $result = error('An error occurred while performing a delete operation', EXIT_ERROR); } else { - $this->ci->db->trans_commit(); + $this->_ci->db->trans_commit(); $result = success('Dms successfully removed from DB'); } // If everything is ok if (isSuccess($result)) { - $cnt = count($resultFileNames->retval); // Remove all files related to this person and dms - for ($i = 0; $i < $cnt; $i++) + for ($i = 0; $i < count(getData($resultFileNames)); $i++) { - $this->ci->DmsFSModel->remove($resultFileNames->retval[$i]->filename); + $this->_ci->DmsFSModel->removeBase64(getData($resultFileNames)[$i]->filename); } } } @@ -376,19 +816,19 @@ class DmsLib extends FHC_Controller */ public function getAkteContent($akte_id) { - $akte = $this->ci->AkteModel->load($akte_id); + $akte = $this->_ci->AkteModel->load($akte_id); if (hasData($akte)) { - if ($akte->retval[0]->inhalt != '') + if (getData($akte)[0]->inhalt != '') { - return success(base64_decode($akte->retval[0]->inhalt)); + return success(base64_decode(getData($akte)[0]->inhalt)); } - elseif ($akte->retval[0]->dms_id != '') + elseif (getData($akte)[0]->dms_id != '') { - $dmscontent = $this->read($akte->retval[0]->dms_id); + $dmscontent = $this->read(getData($akte)[0]->dms_id); if (isSuccess($dmscontent)) { - return success(base64_decode($dmscontent->retval[0]->file_content)); + return success(base64_decode(getData($dmscontent)[0]->file_content)); } else { @@ -415,10 +855,10 @@ class DmsLib extends FHC_Controller { $filename = uniqid().'.'.pathinfo($dms['name'], PATHINFO_EXTENSION); - $result = $this->ci->DmsFSModel->write($filename, $dms['file_content']); + $result = $this->_ci->DmsFSModel->writeBase64($filename, $dms['file_content']); if (isSuccess($result)) { - $result->retval = $filename; + $result = success($filename); } return $result; @@ -439,7 +879,7 @@ class DmsLib extends FHC_Controller if (hasData($result)) { - $result = $this->ci->DmsFSModel->write($result->retval[0]->filename, $dms['file_content']); + $result = $this->_ci->DmsFSModel->writeBase64(getData($result)[0]->filename, $dms['file_content']); } } @@ -451,12 +891,13 @@ class DmsLib extends FHC_Controller */ private function _loadUploadLibrary($allowed_types) { - $config['upload_path'] = $this->UPLOAD_PATH; - $config['allowed_types'] = implode('|', $allowed_types); - $config['overwrite'] = true; - $config['file_name'] = uniqid().'.pdf'; + $config = array(); + $config['upload_path'] = DMS_PATH; + $config['allowed_types'] = implode('|', $allowed_types); + $config['overwrite'] = true; + $config['file_name'] = uniqid().'.pdf'; - $this->ci->load->library('upload', $config); - $this->ci->upload->initialize($config); + $this->_ci->load->library('upload', $config); + $this->_ci->upload->initialize($config); } } diff --git a/application/libraries/DocsboxLib.php b/application/libraries/DocsboxLib.php new file mode 100644 index 000000000..f9167c379 --- /dev/null +++ b/application/libraries/DocsboxLib.php @@ -0,0 +1,304 @@ +attach(array('file' => $inputFileName)) + ->expectsJson() + ->send(); + + // Checks that: + // - the response is not empty + // - the reponse body has the property id + // - the property id is a valid string + // - the reponse body has the property status + // - docsbox queued the conversion of the posted file + if (is_object($postFileResponse) + && isset($postFileResponse->body) + && isset($postFileResponse->body->id) + && $postFileResponse->body->id != '' && $postFileResponse->body->id != null + && isset($postFileResponse->body->status) + && $postFileResponse->body->status == self::STATUS_QUEUED) + { + $queueId = $postFileResponse->body->id; + } + else + { + // If docsbox refused to convert the posted file + if (isset($postFileResponse->body->status) + && $postFileResponse->body->status != self::STATUS_QUEUED) + { + error_log( + 'Docsbox did not queue the posted file. Returned status: '. + $postFileResponse->body->status + ); + } + else // any other generic error + { + error_log( + 'An error occurred while posting to docsbox. Response: '. + print_r($postFileResponse, 1) + ); + } + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception + { + error_log($cee->getMessage()); + } + catch (Exception $e) // any other exception + { + error_log($e->getMessage()); + } + + return $queueId; + } + + /** + * Check the status of the file convertion identified by the given queue element id + * A URL is returned with the path where it is possible to download the converted file + * If an error occurred then a null value is returned + */ + private static function _checkConvertion($queueId) + { + $resultUrl = null; + $startConvertionsTime = time(); // time when the file conversion has started + + // Until a timeout has occurred + while (time() - $startConvertionsTime <= DOCSBOX_CONVERSION_TIMEOUT) + { + sleep(DOCSBOX_WAITING_SLEEP_TIME); // takes a nap on every round + + try + { + // Calls the docsbox server to check the status of the + // file conversion using the provided queue id + // it expects a response in JSON format + $getStatusResponse = \Httpful\Request::get(DOCSBOX_SERVER.DOCSBOX_PATH_API.$queueId) + ->expectsJson() + ->send(); + + // Checks that: + // - the response is not empty + // - the reponse body has the property id + // - the property id is a valid string + // - the reponse body has the property status + // - docsbox is working the conversion of the posted file + if (is_object($getStatusResponse) + && isset($getStatusResponse->body->id) + && $getStatusResponse->body->id != '' && $getStatusResponse->body->id != null + && isset($getStatusResponse->body->status)) + { + // Checks that docsbox has finished working on the file conversion + // and that there is a valid resultUrl property + if ($getStatusResponse->body->status == self::STATUS_FINISHED + && isset($getStatusResponse->body->result_url) + && $getStatusResponse->body->result_url != '' + && $getStatusResponse->body->result_url != null) + { + $resultUrl = $getStatusResponse->body->result_url; + break; + } + // Just started or still working on it + elseif ($getStatusResponse->body->status == self::STATUS_WORKING + || $getStatusResponse->body->status == self::STATUS_STARTED) + { + // go on! + } + else // any other status is abnormal + { + error_log( + 'Not valid status for queue element: '.$queueId.'. Response: '. + print_r($getStatusResponse, 1) + ); + break; // interrupt the loop on error + } + } + else // if the response from the docsbox server is not valid + { + error_log( + 'An error occurred while checking the docsbox activity. Response: '. + print_r($getStatusResponse, 1) + ); + break; // interrupt the loop on error + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception + { + error_log($cee->getMessage()); + break; // interrupt the loop on error + } + catch (Exception $e) // any other exception + { + error_log($e->getMessage()); + break; // interrupt the loop on error + } + } + + return $resultUrl; + } + + /** + * Download the converted file using the provided URL, unzip it, and renames it into the provided file name + */ + private static function _downloadFile($resultUrl, $outputFileName) + { + $downloaded = false; // pessimistic assumption + + try + { + // Download the file + $getFileResponse = \Httpful\Request::get(DOCSBOX_SERVER.$resultUrl)->send(); + + // If the downloaded file content is valid and not empty + if (isset($getFileResponse->body) + && $getFileResponse->body != null + && $getFileResponse->body != '') + { + // Output directory where to unzip the downloaded zip file + $outputDirectory = dirname($outputFileName); + // The path and name of the downloaded zip file + $temporaryDownloadedZip = sys_get_temp_dir().'/'.basename($resultUrl); + + // Write the file content into a temporary directory and file + if (file_put_contents($temporaryDownloadedZip, $getFileResponse->body) != false) + { + $zipArchive = new ZipArchive; + + // Open and extract the dowloaded zip file into the directory of the output file + if ($zipArchive->open($temporaryDownloadedZip) === true + && $zipArchive->extractTo($outputDirectory) === true + && $zipArchive->close() === true) + { + // Opened, extracted and closed! + + // Rename the extracted file to the given output file name + if (rename($outputDirectory.'/'.self::OUTPUT_FILENAME, $outputFileName)) + { + $downloaded = true; + } + else + { + error_log( + 'An error occurred while renaming the extracted file: '. + $outputDirectory.'/'.self::OUTPUT_FILENAME.' into: '. + $outputFileName + ); + } + } + else + { + error_log( + 'An error occurred while working the dowloaded zip file: '. + $temporaryDownloadedZip + ); + } + } + else // if an error occurred while writing + { + error_log( + 'An error occurred while writing the file content to: '. + $temporaryDownloadedZip + ); + } + } + else // if the downloaded file is not valid + { + error_log( + 'An error occurred while downloading the file from the docsbox server: '. + print_r($getFileResponse, 1) + ); + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) + { + error_log($cee->getMessage()); + } + catch (Exception $e) + { + error_log($e->getMessage()); + } + + return $downloaded; + } +} + diff --git a/application/libraries/DocumentLib.php b/application/libraries/DocumentLib.php index 98e546b4e..c1dd21c29 100644 --- a/application/libraries/DocumentLib.php +++ b/application/libraries/DocumentLib.php @@ -14,20 +14,28 @@ class DocumentLib // Gets CI instance $this->ci =& get_instance(); - exec('unoconv --version', $ret_arr); - - if(isset($ret_arr[0])) + // Which document converter has to be used + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) { - $hlp = explode(' ', $ret_arr[0]); - if(isset($hlp[1])) - { - $this->unoconv_version = $hlp[1]; - } - else - show_error('Could not get Unoconv Version'); + // Use docsbox!! } else - show_error('Unoconv not found - Please install Unoconv'); + { + 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('Could not get Unoconv Version'); + } + else + show_error('Unoconv not found - Please install Unoconv'); + } } /** @@ -57,9 +65,16 @@ class DocumentLib case 'application/vnd.ms-word': case 'application/vnd.oasis.opendocument.text': case 'text/plain': - // Unoconv Version 0.6 seems to fail on converting TXT Files - if ($this->unoconv_version == '0.6') - return error(); + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) + { + // Use docsbox + } + else + { + // Unoconv Version 0.6 seems to fail on converting TXT Files + if ($this->unoconv_version == '0.6') + return error(); + } $ret = $this->convert($filename, $outFile, 'pdf'); if(isSuccess($ret)) @@ -105,6 +120,7 @@ class DocumentLib finfo_close($finfo); + $out = null; exec($cmd, $out, $ret); if ($ret != 0) { @@ -123,13 +139,26 @@ class DocumentLib */ public function convert($inFile, $outFile, $format) { - if ($this->unoconv_version == '0.6') - $command = 'unoconv -f %1$s %3$s > %2$s'; - else - $command = 'unoconv -f %s --output %s %s 2>&1'; - $command = sprintf($command, $format, $outFile, $inFile); + $ret = 0; - exec($command, $out, $ret); + // If it is set to use docsbox + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) + { + require_once(dirname(__FILE__).'/../application/libraries/DocsboxLib.php'); + + $ret = DocsboxLib::convert($inFile, $outFile, $format); + } + else // otherwise use unoconv + { + if ($this->unoconv_version == '0.6') + $command = 'unoconv -f %1$s %3$s > %2$s'; + else + $command = 'unoconv -f %s --output %s %s 2>&1'; + $command = sprintf($command, $format, $outFile, $inFile); + + $out = null; + exec($command, $out, $ret); + } if ($ret != 0) { @@ -191,6 +220,7 @@ class DocumentLib $cmd .= '/countspaces { [ exch { dup 32 ne { pop } if } forall ] length } bind def >> '; $cmd .= 'setpagedevice viewJPEG"'; + $out = null; exec($cmd, $out, $ret); if ($ret != 0) { diff --git a/application/libraries/ExtensionsLib.php b/application/libraries/ExtensionsLib.php index cec40a753..9fe5d9e87 100644 --- a/application/libraries/ExtensionsLib.php +++ b/application/libraries/ExtensionsLib.php @@ -1,7 +1,25 @@ . + */ if (! defined('BASEPATH')) exit('No direct script access allowed'); +use \stdClass as stdClass; + /** * Library to manage core extensions */ @@ -23,7 +41,7 @@ class ExtensionsLib // Directories that are part of the extension archive private $SOFTLINK_TARGET_DIRECTORIES = array( - APPPATH => array('config', 'controllers', 'helpers', 'hooks', 'libraries', 'models', 'views', 'widgets'), + APPPATH => array('config', 'components', 'controllers', 'helpers', 'hooks', 'libraries', 'models', 'views', 'widgets'), DOC_ROOT => array('public') ); @@ -181,17 +199,15 @@ class ExtensionsLib // Select all the version of this extension $this->_ci->ExtensionsModel->addSelect('extension_id'); $result = $this->_ci->ExtensionsModel->loadWhere(array('name' => $extensionName)); - if (hasData($result)) // if something was found + // If something was found + if (hasData($result)) { - $extsArray = array(); - foreach ($result->retval as $key => $extension) // loops on them + // Loops on them + foreach ($result->retval as $extension) { // Remove them all $result = $this->_ci->ExtensionsModel->delete($extension->extension_id); - if (isSuccess($result)) - { - $delExtension = true; - } + if (isSuccess($result)) $delExtension = true; } } } @@ -432,9 +448,13 @@ class ExtensionsLib // If no errors occurred if ($extensionJson != null) { + // Default value + $fhcomplete_version = 0; + 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); @@ -587,18 +607,22 @@ class ExtensionsLib for ($sqlDir = $startVersion; $sqlDir <= $extensionJson->version; $sqlDir++) { // If a directory with the same value of the version is present in the sql scripts directory - if (($files = glob($pkgSQLsPath.'/'.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION)) != false) - { + $files = glob($pkgSQLsPath.'/'.$sqlDir.'/*'.ExtensionsLib::SQL_FILE_EXTENSION); + if ($files != false) + { // Loads every sql files - foreach ($files as $file) - { - $sql = file_get_contents($file); // gets the entire content of the file + foreach ($files as $file) + { + $sql = file_get_contents($file); // gets the entire content of the file $this->_printMessage('Executing query:'); $this->_printMessage($sql); // Try to execute that - if (!isSuccess($result = @$this->_ci->ExtensionsModel->executeQuery($sql))) + $resultQuery = @$this->_ci->ExtensionsModel->executeQuery($sql); + + // If _not_ a success + if (!isSuccess($resultQuery)) { $this->_errorOccurred = true; $this->_printFailure(' error occurred while executing the query'); @@ -608,11 +632,11 @@ class ExtensionsLib else { $this->_printMessage('Query result:'); - var_dump($result->retval); // KEEP IT!!! + var_dump(getData($resultQuery)); // KEEP IT!!! $this->_ci->eprintflib->printEOL(); } - } - } + } + } } $this->_printSuccess(!$this->_errorOccurred); @@ -673,7 +697,7 @@ class ExtensionsLib foreach ($this->SOFTLINK_TARGET_DIRECTORIES as $rootPath => $targetDirectories) { - foreach ($targetDirectories as $key => $targetDirectory) + foreach ($targetDirectories as $targetDirectory) { if (file_exists($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName)) { @@ -727,7 +751,7 @@ class ExtensionsLib // For every target directory foreach ($this->SOFTLINK_TARGET_DIRECTORIES as $rootPath => $targetDirectories) { - foreach ($targetDirectories as $key => $targetDirectory) + foreach ($targetDirectories as $targetDirectory) { // If destination of the symlink does not exist if (!file_exists($rootPath.$targetDirectory.'/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$extensionName)) diff --git a/application/libraries/FilesystemLib.php b/application/libraries/FilesystemLib.php deleted file mode 100644 index c940acede..000000000 --- a/application/libraries/FilesystemLib.php +++ /dev/null @@ -1,142 +0,0 @@ -checkParameters($filepath, $filename)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (file_exists($resource) && $fileHandle = fopen($resource, 'r')) - { - $result = ''; - while (!feof($fileHandle)) - { - $result .= fread($fileHandle, 8192); - } - fclose($fileHandle); - } - } - - return $result; - } - - /** - * write - */ - public function write($filepath, $filename, $content) - { - $result = null; - - if ($this->checkParameters($filepath, $filename) && isset($content)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (is_writable($filepath) && $fileHandle = fopen($resource, 'w')) - { - if (fwrite($fileHandle, $content) !== false) - { - $result = true; - } - fclose($fileHandle); - } - } - - return $result; - } - - /** - * append - */ - public function append($filepath, $filename, $content) - { - $result = null; - - if ($this->checkParameters($filepath, $filename) && isset($content)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (is_writable($resource) && $fileHandle = fopen($resource, 'a')) - { - if (fwrite($fileHandle, $content) !== false) - { - $result = true; - } - fclose($fileHandle); - } - } - - return $result; - } - - /** - * remove - */ - public function remove($filepath, $filename) - { - $result = null; - - if ($this->checkParameters($filepath, $filename)) - { - if (is_writable($filepath)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - $result = unlink($resource); - } - } - - return $result; - } - - /** - * rename - */ - public function rename($filepath, $filename, $newFilepath, $newFilename) - { - $result = null; - - if ($this->checkParameters($filepath, $filename) && $this->checkParameters($newFilepath, $newFilename)) - { - $resource = $filepath.DIRECTORY_SEPARATOR.$filename; - if (is_writable($filepath) && is_writable($newFilepath) && file_exists($resource)) - { - $destination = $newFilepath.DIRECTORY_SEPARATOR.$newFilename; - $result = rename($resource, $destination); - } - } - - return $result; - } -} diff --git a/application/libraries/FilterCmptLib.php b/application/libraries/FilterCmptLib.php new file mode 100644 index 000000000..9d6dfa681 --- /dev/null +++ b/application/libraries/FilterCmptLib.php @@ -0,0 +1,1163 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use \stdClass as stdClass; + +/** + * Filter component logic + */ +class FilterCmptLib +{ + // FilterCmpt session name + const SESSION_NAME = 'FHC_FILTER_COMPONENT'; + + // Session elements + const SESSION_FILTER_NAME = 'filterName'; + const SESSION_FIELDS = 'fields'; + const SESSION_SELECTED_FIELDS = 'selectedFields'; + const SESSION_FILTERS = 'filters'; + const SESSION_METADATA = 'datasetMetadata'; + const SESSION_ROW_NUMBER = 'rowNumber'; + const SESSION_TIMEOUT = 'sessionTimeout'; + + // Session dataset elements + const SESSION_DATASET = 'dataset'; + const SESSION_DATASET_RELOAD = 'reloadDataset'; + + const SESSION_SIDE_MENU = 'sideMenu'; + + // Default session timeout + const SESSION_DEFAULT_TIMEOUT = 30; + + // Alias for the dynamic table used to retrieve the dataset + const DATASET_TABLE_ALIAS = 'datasetFilterTable'; + + // Parameters names... + // ...to identify a single filter component in the session + const FHC_CONTROLLER_ID = 'fhc_controller_id'; + + // ...to identify a single filter component in the DB + const FILTER_ID = 'filter_id'; + const APP = 'app'; + const DATASET_NAME = 'datasetName'; + const FILTER_KURZBZ = 'filterKurzbz'; + const DATASET_RELOAD = 'reloadDataset'; + + // ...to specify permissions that are needed to use this FilterCmpt + const REQUIRED_PERMISSIONS = 'requiredPermissions'; + + // ...stament to retrieve the dataset + const QUERY = 'query'; + + // Filter operations values + const OP_EQUAL = 'equal'; + const OP_NOT_EQUAL = 'nequal'; + const OP_GREATER_THAN = 'gt'; + const OP_LESS_THAN = 'lt'; + const OP_IS_TRUE = 'true'; + const OP_IS_FALSE = 'false'; + const OP_CONTAINS = 'contains'; + const OP_NOT_CONTAINS = 'ncontains'; + const OP_SET = 'set'; + const OP_NOT_SET = 'nset'; + + // Filter options values + const OPT_MINUTES = 'minutes'; + const OPT_HOURS = 'hours'; + const OPT_DAYS = 'days'; + const OPT_MONTHS = 'months'; + + const FILTER_PHRASES_CATEGORY = 'FilterWidget'; // The category used to store phrases for the FilterCmpt + + const FILTER_UNIQUE_ID = 'filterUniqueId'; // Filter page parameter name + + const PERMISSION_FILTER_METHOD = 'FilterCmpt'; // Name for fake method to be checked by the PermissionLib + const PERMISSION_TYPE = 'r'; + + private $_ci; // Code igniter instance + + private $_filterUniqueId; // Unique id for this filter component + private $_filterType; // + private $_filterId; // + + private $_app; + private $_datasetName; + private $_filterKurzbz; + private $_query; + private $_requiredPermissions; + private $_reloadDataset; + private $_sessionTimeout; + + /** + * Gets the CI instance and loads message helper + */ + public function __construct($params) + { + $this->_ci =& get_instance(); // get code igniter instance + + // Set parameters + $this->_setParameters($params); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Wrapper method to the session helper funtions to retrieve the whole session for this filter + */ + public function getSession() + { + return getSessionElement(self::SESSION_NAME, $this->_filterUniqueId); + } + + /** + * Contains all the logic used to load all the data needed to the FilterCmpt + */ + public function start() + { + // + if (!$this->_checkJSParameters()) return; + + $filterCmptArray = array(); // default value + + // + $filePath = findResource(APPPATH.'components/filters/', $this->_filterType, true); + if (!isEmptyString($filePath)) + { + // Gets the filter configuration from the file system + require_once($filePath); + } + else + { + $filePath = findResource(APPPATH.'components/extensions/', $this->_filterType, true, 'filters'); + if (!isEmptyString($filePath)) require_once($filePath); + } + + // + if (!isset($filterCmptArray) && isEmptyArray($filterCmptArray)) + { + $this->_setSession(error('Component definition file '.$this->_filterType.' not found')); + return; + } + + // + if (!$this->_checkPHPParameters($filterCmptArray)) return; + + // + $this->_initFilterCmpt($filterCmptArray); + + // + if (!$this->_isAllowed()) return; + + // Looks for expired filter components in session and drops them + $this->_dropExpiredFilterCmpts(); + + // Read the all session for this filter component + $session = $this->getSession(); + + // If session is NOT empty -> a filter was already loaded + if ($session != null) + { + // Retrieve the filterId stored in the session + $sessionFilterId = $this->_getSessionElement(FilterCmptLib::FILTER_ID); + + // If the filter loaded in session is NOT the same that is being requested then empty the session + if ($this->_filterId != $sessionFilterId) + { + $this->_setSession(null); + $session = null; + } + else // else if the filter loaded in session is the same that is being requested + { + // Get SESSION_DATASET_RELOAD from the session + $sessionReloadDataset = $this->_getSessionElement(FilterCmptLib::SESSION_DATASET_RELOAD); + + // if Filter changed or reload is forced by parameter then reload the Dataset + if ($this->_reloadDataset === true || $sessionReloadDataset === true) + { + // Set as false to stop changing the dataset + $this->_setSessionElement(FilterCmptLib::SESSION_DATASET_RELOAD, false); + + // Generate dataset query using filters from the session + $datasetQuery = $this->_generateDatasetQuery( + $this->_query, + $this->_getSessionElement(FilterCmptLib::SESSION_FILTERS) + ); + + // Then retrieve dataset from DB + $dataset = $this->_getDataset($datasetQuery); + + // Save changes into session if data are valid + if (!isError($dataset)) + { + // Set the new dataset and its attributes in the session + $this->_setSessionElement(FilterCmptLib::SESSION_METADATA, $this->_ci->FiltersModel->getExecutedQueryMetaData()); + $this->_setSessionElement(FilterCmptLib::SESSION_ROW_NUMBER, count($dataset->retval)); + $this->_setSessionElement(FilterCmptLib::SESSION_DATASET, $dataset->retval); + } + } + } + } + + // If the session is empty -> first time that this filter is loaded + if ($session == null) + { + // Load filter definition data from DB + $definition = $this->_loadDefinition( + $this->_filterId, + $this->_app, + $this->_datasetName, + $this->_filterKurzbz + ); + + // Checks and parse json present into the definition + $parsedFilterJson = $this->_parseFilterJson($definition); + if ($parsedFilterJson != null) // if the json is valid + { + // Generate dataset query + $datasetQuery = $this->_generateDatasetQuery($this->_query, $parsedFilterJson->filters); + + // Then retrieve dataset from DB + $dataset = $this->_getDataset($datasetQuery); + + // Try to load the name of the filter using the PhrasesLib + $filterName = $this->_getFilterName($parsedFilterJson); + + // Save changes into session if data are valid + if (!isError($dataset)) + { + // Stores an array that contains all the data useful for + $this->_setSession( + array( + FilterCmptLib::FILTER_ID => $this->_filterId, // the current filter id + FilterCmptLib::APP => $this->_app, // the current app parameter + FilterCmptLib::DATASET_NAME => $this->_datasetName, // the carrent dataset name + FilterCmptLib::SESSION_FILTER_NAME => $filterName, // the current filter name + FilterCmptLib::SESSION_FIELDS => $this->_ci->FiltersModel->getExecutedQueryListFields(), // all the fields of the dataset + FilterCmptLib::SESSION_SELECTED_FIELDS => $this->_getColumnsNames($parsedFilterJson->columns), // all the selected fields + FilterCmptLib::SESSION_FILTERS => $parsedFilterJson->filters, // all the filters used to filter the dataset + FilterCmptLib::SESSION_METADATA => $this->_ci->FiltersModel->getExecutedQueryMetaData(), // the metadata of the dataset + FilterCmptLib::SESSION_ROW_NUMBER => count($dataset->retval), // the number of loaded rows by this filter + FilterCmptLib::SESSION_DATASET => $dataset->retval, // the entire dataset + FilterCmptLib::SESSION_DATASET_RELOAD => false, // if the dataset must be reloaded, not needed the first time + FilterCmptLib::SESSION_SIDE_MENU => $this->_generateFilterMenu($this->_app, $this->_datasetName) + ) + ); + } + } + } + + // NOTE: latest operations to be performed in the session to be shure that they are always present + // To be always stored in the session, otherwise is not possible to load data from Filters controller + $this->_setSessionElement(FilterCmptLib::REQUIRED_PERMISSIONS, $this->_requiredPermissions); + // Renew or set the session expiring time + $this->_setSessionElement(FilterCmptLib::SESSION_TIMEOUT, strtotime('+'.$this->_sessionTimeout.' minutes', time())); + } + + /** + * Add a filter (SQL where clause) to be applied to the current filter + */ + public function addFilterField($filterField) + { + $addFilterField = false; + + // Checks the parameter filter + if (!isEmptyString($filterField)) + { + // Retrieves all the used fields by the current filter + $fields = $this->_getSessionElement(self::SESSION_FIELDS); + // Retrieves the applied filters by the current filter + $filters = $this->_getSessionElement(self::SESSION_FILTERS); + + // Checks that the given applied filter is present in the list of all the used fields by the current filter + if (in_array($filterField, $fields)) + { + // Search in what position the given applied filter is + $pos = $this->_searchFilterByName($filters, $filterField); + if ($pos === false) // If NOT found then add it + { + // New filter definition + $filterDefinition = new stdClass(); + // Sets filter definition required properties + $filterDefinition->name = $filterField; + // Sets filter definition optional properties + $filterDefinition->operation = null; + $filterDefinition->condition = null; + $filterDefinition->option = null; + // Place the new applied filter at the end of the applied filters list + array_push($filters, $filterDefinition); + } + + $this->_setSessionElement(self::SESSION_FILTERS, $filters); // write changes into the session + + $addFilterField = true; + } + } + + return $addFilterField; + } + + /** + * Remove an applied filter (SQL where condition) from the current filter + */ + public function removeFilterField($filterField) + { + $removeFilterField = false; + + // Checks the parameter filterField + if (!isEmptyString($filterField)) + { + // Retrieves all the used fields by the current filter + $fields = $this->_getSessionElement(self::SESSION_FIELDS); + // Retrieves the applied filters by the current filter + $filters = $this->_getSessionElement(self::SESSION_FILTERS); + + // Checks that the given applied filter is present in the list of all the used fields by the current filter + if (in_array($filterField, $fields)) + { + // Search in what position the given applied filter is + $pos = $this->_searchFilterByName($filters, $filterField); + if ($pos !== false) // If found + { + array_splice($filters, $pos, 1); // Then remove it and shift the rest of elements by one if needed + } + + // Write changes into the session + $this->_setSessionElement(self::SESSION_FILTERS, $filters); + $this->_setSessionElement(self::SESSION_DATASET_RELOAD, true); // the dataset must be reloaded + + $removeFilterField = true; + } + } + + return $removeFilterField; + } + + /** + * Apply all the applied filters (SQL where conditions) to the current filter + */ + public function applyFilterFields($filterFields) + { + $applyFilters = false; + + // Check if the parameter is an array and it is not empty + if (!isEmptyArray($filterFields)) + { + $filters = array(); + + // Check if the parameter is fine + $fine = true; + foreach ($filterFields as $filterField) + { + // If not an empty array + if ($filterField != null) + { + // + if (isset($filterField->name) && isset($filterField->operation) && isset($filterField->condition) + && !isEmptyString($filterField->name) && !isEmptyString($filterField->operation) + && !isEmptyString($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->option = $filterField->option; + } + else + { + $filter->option = null; + } + $filters[] = $filter; + } + else // otherwise is not fine and stop checking + { + $fine = false; + break; + } + } + else // + { + $fine = false; + break; + } + } + + // + if ($fine) + { + // Write changes into the session + $this->_setSessionElement(self::SESSION_FILTERS, $filters); + $this->_setSessionElement(self::SESSION_DATASET_RELOAD, true); // the dataset must be reloaded + + $applyFilters = true; + } + } + + return $applyFilters; + } + + /** + * Reloads dataset by setting session variable to true + */ + public function reloadDataset() + { + $this->_setSessionElement(self::SESSION_DATASET_RELOAD, true); + } + + /** + * Save the current filter as a custom filter for this user with the given description + */ + public function saveCustomFilter($customFilterDescription) + { + $saveCustomFilter = false; // by default returns a failure + + // Checks parameter customFilterDescription if not valid stop the execution + if (isEmptyString($customFilterDescription)) return $saveCustomFilter; + + $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // to load the filter definitions + $this->_ci->FiltersModel->resetQuery(); // reset any previous built query + + // person_id of the authenticated user + $authPersonId = getAuthPersonId(); + // Postgres array for the description + $descPGArray = str_replace('%desc%', $customFilterDescription, '{"%desc%", "%desc%", "%desc%", "%desc%"}'); + + // Loads the definition to check if is already present in the DB + $definition = $this->_ci->FiltersModel->loadWhere(array( + 'app' => $this->_getSessionElement(self::APP), + 'dataset_name' => $this->_getSessionElement(self::DATASET_NAME), + 'description' => $descPGArray, + 'person_id' => $authPersonId + )); + + // New definition to be json encoded + $jsonDeifinition = new stdClass(); + $jsonDeifinition->name = $customFilterDescription; // name of the filter + + // Generates the "column" property + $jsonDeifinition->columns = array(); + $selectedFields = $this->_getSessionElement(self::SESSION_SELECTED_FIELDS); // retrieved the selected fields + for ($i = 0; $i < count($selectedFields); $i++) + { + // Each element is an object with a property called "name" + $jsonDeifinition->columns[$i] = new stdClass(); + $jsonDeifinition->columns[$i]->name = $selectedFields[$i]; + } + + // List of applied filters + $jsonDeifinition->filters = $this->_getSessionElement(self::SESSION_FILTERS); + + // If it is already present + if (hasData($definition)) + { + // update it + $this->_ci->FiltersModel->update( + array( + 'app' => $this->_getSessionElement(self::APP), + 'dataset_name' => $this->_getSessionElement(self::DATASET_NAME), + 'description' => $descPGArray, + 'person_id' => $authPersonId + ), + array( + 'filter' => json_encode($jsonDeifinition) + ) + ); + + $saveCustomFilter = true; + } + else // otherwise insert a new one + { + $this->_ci->FiltersModel->insert( + array( + 'app' => $this->_getSessionElement(self::APP), + 'dataset_name' => $this->_getSessionElement(self::DATASET_NAME), + 'filter_kurzbz' => uniqid($authPersonId, true), + 'description' => $descPGArray, + 'person_id' => $authPersonId, + 'sort' => null, + 'default_filter' => false, + 'filter' => json_encode($jsonDeifinition), + 'oe_kurzbz' => null + ) + ); + + $saveCustomFilter = true; + } + + if ($saveCustomFilter === true) + { + $this->_setSessionElement(FilterCmptLib::SESSION_SIDE_MENU, + $this->_generateFilterMenu($this->_app, $this->_datasetName)); + } + + return $saveCustomFilter; + } + + /** + * Remove a custom filter by its filter_id + */ + public function removeCustomFilter($filterId) + { + $removeCustomFilter = false; + + // Checks the parameter filterId + if (isset($filterId) && is_numeric($filterId) && $filterId > 0) + { + $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // to remove the filter definitions from DB + + // Delete it from database + $this->_ci->FiltersModel->delete(array(self::FILTER_ID => $filterId)); + + // Delete it from session + $this->_dropFromSessionFilterCmptById($filterId); + + $removeCustomFilter = true; + } + + return $removeCustomFilter; + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Generates the filters menu structure array and stores it into the session + */ + private function _generateFilterMenu($app, $datasetName) + { + $filterMenu = new stdClass(); + $filterMenu->filters = array(); + $filterMenu->personalFilters = array(); + + // Loads the Filters model + $this->_ci->load->model('system/Filters_model', 'FiltersModel'); + + // Loads all the filters related to this page (same dataset_name and same app name) + $filters = $this->_ci->FiltersModel->getFiltersByAppDatasetNamePersonId( + $app, + $datasetName, + getAuthPersonId() + ); + + // If filters were loaded + if (hasData($filters)) + { + // Loops through loaded filters + foreach (getData($filters) as $filter) + { + $menuEntry = new stdClass(); + $menuEntry->desc = $filter->description[0]; + $menuEntry->filter_id = $filter->filter_id; + + // If it is NOT a personal filter + if ($filter->person_id == null) + { + $filterMenu->filters[] = $menuEntry; + } + else // otherwise + { + $menuEntry->subscriptDescription = '(Remove)'; + $menuEntry->subscriptLinkClass = 'remove-custom-filter'; + $menuEntry->subscriptLinkValue = $filter->{self::FILTER_ID}; + + $filterMenu->personalFilters[] = $menuEntry; // adds to personal filters menu array + } + } + } + + return $filterMenu; + } + + /** + * Wrapper method to the session helper funtions to retrieve one element from the session of this filter + */ + private function _getSessionElement($name) + { + $session = getSessionElement(self::SESSION_NAME, $this->_filterUniqueId); + + if (isset($session[$name])) + { + return $session[$name]; + } + + return null; + } + + /** + * Checks if at least one of the permissions given as parameter (requiredPermissions) belongs + * to the authenticated user, if confirmed then is allowed to use this FilterCmpt. + * If the parameter requiredPermissions is NOT given or is not present in the session, + * then NO one is allow to use this FilterCmpt + * Wrapper method to permissionlib->hasAtLeastOne + */ + private function _isAllowed() + { + $this->_ci->load->library('PermissionLib'); // Load permission library + + if (!$this->_ci->permissionlib->hasAtLeastOne($this->_requiredPermissions, self::PERMISSION_FILTER_METHOD, self::PERMISSION_TYPE)) + { + $this->_setSession(error('The required permission is not help by the logged user')); + return false; + } + + return true; + } + + /** + * + */ + private function _setParameters($params) + { + if (isset($params['filterUniqueId'])) $this->_filterUniqueId = $params['filterUniqueId']; + if (isset($params['filterType'])) $this->_filterType = $params['filterType']; + if (isset($params['filterId'])) $this->_filterId = $params['filterId']; + } + + /** + * Checks the required parameters used to call this FilterCmpt + */ + private function _checkJSParameters() + { + // + if (isEmptyString($this->_filterUniqueId)) + { + $this->_setSession(error('Parameter "filterUniqueId" not provided')); + return false; + } + + // + if (isEmptyString($this->_filterType)) + { + $this->_setSession(error('Parameter "filterType" not provided')); + return false; + } + + return true; + } + + /** + * Checks the required parameters used to call this FilterCmpt + */ + private function _checkPHPParameters($filterCmptArray) + { + // If no options are given to this component... + if (!is_array($filterCmptArray) || (is_array($filterCmptArray) && count($filterCmptArray) == 0)) + { + $this->_setSession(error('No parameters provided')); + return false; + } + else // ...otherwise + { + // Parameters app AND dataset name + if (!isset($filterCmptArray[FilterCmptLib::APP]) && !isset($filterCmptArray[FilterCmptLib::DATASET_NAME])) + { + $this->_setSession( + error( + 'The parameters "'.FilterCmptLib::APP.'" AND "'.FilterCmptLib::DATASET_NAME.' must be specified' + ) + ); + return false; + } + + // The query parameter is mandatory + if (!isset($filterCmptArray[FilterCmptLib::QUERY])) + { + $this->_setSession(error('The parameter "'.FilterCmptLib::QUERY.'" must be specified')); + return false; + } + + // + if (!isset($filterCmptArray[FilterCmptLib::DATASET_NAME])) + { + $this->_setSession(error('The parameter "'.FilterCmptLib::DATESET_NAME.'" must be specified')); + return false; + } + + // + if (!isset($filterCmptArray[FilterCmptLib::REQUIRED_PERMISSIONS])) + { + $this->_setSession(error('The parameter "'.FilterCmptLib::REQUIRED_PERMISSIONS.'" must be specified')); + return false; + } + } + + return true; + } + + /** + * Checks parameters and initialize all the properties of this FilterCmpt + */ + private function _initFilterCmpt($filterCmptArray) + { + // If here then everything is ok + + // Initialize class properties + $this->_app = null; + $this->_datasetName = null; + $this->_filterKurzbz = null; + $this->_query = null; + $this->_requiredPermissions = null; + + $this->_reloadDataset = true; // by default the dataset is NOT cached in session + $this->_sessionTimeout = FilterCmptLib::SESSION_DEFAULT_TIMEOUT; + + // Retrieved the required permissions parameter if present + if (isset($filterCmptArray[FilterCmptLib::REQUIRED_PERMISSIONS])) + { + $this->_requiredPermissions = $filterCmptArray[FilterCmptLib::REQUIRED_PERMISSIONS]; + } + + // Parameters needed to retrieve univocally a filter from DB + if (isset($filterCmptArray[FilterCmptLib::APP])) + { + $this->_app = $filterCmptArray[FilterCmptLib::APP]; + } + + if (isset($filterCmptArray[FilterCmptLib::DATASET_NAME])) + { + $this->_datasetName = $filterCmptArray[FilterCmptLib::DATASET_NAME]; + } + + if (isset($filterCmptArray[FilterCmptLib::FILTER_KURZBZ])) + { + $this->_filterKurzbz = $filterCmptArray[FilterCmptLib::FILTER_KURZBZ]; + } + + // How to retrieve data for the filter: SQL statement or a result from DB + if (isset($filterCmptArray[FilterCmptLib::QUERY])) + { + $this->_query = $filterCmptArray[FilterCmptLib::QUERY]; + } + } + + /** + * Generates a condition for a SQL where clause using the given applied filter definition. + * By default an empty string is returned. + */ + private function _getDatasetQueryCondition($filterDefinition) + { + $condition = ''; // starts building the condition + + $this->_ci->load->model('system/Filters_model', 'FiltersModel'); + + // "operation" is a required property for the applied filter definition + if (!isEmptyString($filterDefinition->operation)) + { + // Checks what operation is required + switch ($filterDefinition->operation) + { + // comparison (==) + case self::OP_EQUAL: + // 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: + // 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: + // If it's a date type + if (is_numeric($filterDefinition->condition) + && isset($filterDefinition->option) + && ($filterDefinition->option == self::OPT_HOURS + || $filterDefinition->option == self::OPT_DAYS + || $filterDefinition->option == self::OPT_MONTHS + || $filterDefinition->option == self::OPT_MINUTES)) + { + $condition = '< (NOW() - \''.$filterDefinition->condition.' '.$filterDefinition->option.'\'::interval)'; + } + else // otherwise is a number + { + $condition = '> '.$filterDefinition->condition; + } + break; + // less than (<) + case self::OP_LESS_THAN: + // If it's a date type + if (is_numeric($filterDefinition->condition) + && isset($filterDefinition->option) + && ($filterDefinition->option == self::OPT_HOURS + || $filterDefinition->option == self::OPT_DAYS + || $filterDefinition->option == self::OPT_MONTHS + || $filterDefinition->option == self::OPT_MINUTES)) + { + $condition = '> (NOW() - \''.$filterDefinition->condition.' '.$filterDefinition->option.'\'::interval)'; + } + else // otherwise is a number + { + $condition = '< '.$filterDefinition->condition; + } + break; + // contains (ILIKE) + case self::OP_CONTAINS: + $condition = 'ILIKE \'%'.$this->_ci->FiltersModel->escapeLike($filterDefinition->condition).'%\''; + break; + // not contains (NOT ILIKE) + case self::OP_NOT_CONTAINS: + $condition = 'NOT ILIKE \'%'.$this->_ci->FiltersModel->escapeLike($filterDefinition->condition).'%\''; + break; + // is true (=== true) + case self::OP_IS_TRUE: + $condition = 'IS TRUE'; + break; + // is false (=== false) + case self::OP_IS_FALSE: + $condition = 'IS FALSE'; + break; + // is set + case self::OP_SET: + $condition = 'IS NOT NULL'; + break; + // is NOT set + case self::OP_NOT_SET: + $condition = 'IS NULL'; + break; + // by default must not be null (!= null) + default: + $condition = 'IS NOT NULL'; + break; + } + } + + // if the condition is valid + if (!isEmptyString($condition)) $condition = ' '.$condition; // add a white space before + + return $condition; + } + + /** + * Search for a filter inside a list of filters by the given filter name + * Returns false if NOT found, otherwise the position inside the list + */ + private function _searchFilterByName($filters, $filterName) + { + $pos = false; + + for($i = 0; $i < count($filters); $i++) + { + if ($filters[$i]->name == $filterName) + { + $pos = $i; + break; + } + } + + return $pos; + } + + /** + * Remove from the session the given filter component + */ + private function _dropFromSessionFilterCmptById($filterId) + { + // Loads the session for all the filter components + $filterCmptsSession = getSession(self::SESSION_NAME); + + // If something is present in session + if ($filterCmptsSession != null) + { + // Loops in the session for all the filter components + foreach ($filterCmptsSession as $filterCmpt => $filterCmptData) + { + // If this filter component is not the one that we are looking for + if ($filterCmptData[self::FILTER_ID] == $filterId) + { + cleanSessionElement(self::SESSION_NAME, $filterCmpt); // ...remove it + break; // stop to search + } + } + } + } + + /** + * Utility method that retrieves the name of the columns present in a filter JSON definition + */ + private function _getColumnsNames($columns) + { + $columnsNames = array(); + + // For each column + foreach ($columns as $obj) + { + // If it is set the property name of the column + if (isset($obj->name)) $columnsNames[] = $obj->name; + } + + return $columnsNames; + } + + /** + * Wrapper method to the session helper funtions to set the whole session for this filter + */ + private function _setSession($data) + { + setSessionElement(self::SESSION_NAME, $this->_filterUniqueId, $data); + } + + /** + * Wrapper method to the session helper funtions to set one element in the session for this filter + */ + private function _setSessionElement($name, $value) + { + $session = getSessionElement(self::SESSION_NAME, $this->_filterUniqueId); + + $session[$name] = $value; + + setSessionElement(self::SESSION_NAME, $this->_filterUniqueId, $session); // stores the single value + } + + /** + * + */ + private function _dropExpiredFilterCmpts() + { + // Loads the session for all the filter components + $filterCmptsSession = getSession(self::SESSION_NAME); + + // If something is present in session + if ($filterCmptsSession != null) + { + // Loops in the session for all the filter components + foreach ($filterCmptsSession as $filterCmpt => $filterCmptData) + { + // If this filter component is not the current used filter component and the it is expired... + if ($this->_filterUniqueId != $filterCmpt && $filterCmptData[self::SESSION_TIMEOUT] <= time()) + { + cleanSessionElement(self::SESSION_NAME, $filterCmpt); // ...remove it + } + } + } + } + + /** + * Loads the definition data from DB for a filter component + */ + private function _loadDefinition($filterId, $app, $datasetName, $filterKurzbz) + { + // Loads the needed models + $this->_ci->load->model('system/Filters_model', 'FiltersModel'); + $this->_ci->FiltersModel->resetQuery(); // reset any previous built query + + $this->_ci->FiltersModel->addSelect('system.tbl_filters.*'); // select only from table filters + $this->_ci->FiltersModel->addOrder('sort', 'ASC'); // sort on column sort + $this->_ci->FiltersModel->addLimit(1); // if more than one filter is set as default only one will be retrieved + + $definition = null; + $whereParameters = null; // where clause parameters + + // If we have a good filterId then use it! + if ($filterId != null && is_numeric($filterId) && $filterId > 0) + { + $whereParameters = array( + self::FILTER_ID => $filterId + ); + } + else + { + // If we can univocally retrieve a filter + if ($app != null && $datasetName != null && $filterKurzbz != null) + { + $whereParameters = array( + 'app' => $app, + 'dataset_name' => $datasetName, + 'filter_kurzbz' => $filterKurzbz + ); + } + // Else if we have only app and datasetName + elseif ($app != null && $datasetName != null && $filterKurzbz == null) + { + // Try to load the custom filter (person_id = logged user person_id) with the given "app" and "dataset_name" + // that is set as default filter (default_filter = true) + $whereParameters = array( + 'app' => $app, + 'dataset_name' => $datasetName, + 'person_id' => getAuthPersonId(), + 'default_filter' => true + ); + + $definition = $this->_ci->FiltersModel->loadWhere($whereParameters); + if (!hasData($definition)) // If a custom filter is NOT found + { + // Try to load the global filter (person_id = null) with the given "app" and "dataset_name" that is set as + // default filter (default_filter = true) + $whereParameters = array( + 'app' => $app, + 'dataset_name' => $datasetName, + 'person_id' => null, + 'default_filter' => true + ); + + $definition = $this->_ci->FiltersModel->loadWhere($whereParameters); + } + } + } + + // If no definition where loaded and where parameters were set + if ($definition == null && $whereParameters != null) + { + $definition = $this->_ci->FiltersModel->loadWhere($whereParameters); + + // Last chance!!! + if (!hasData($definition)) // If no data have been found until now the tries the most desperate query + { + $this->_ci->FiltersModel->addOrder('filter_id', 'ASC'); // sort on column filter_id to get the oldest + $whereParameters = array( + 'app' => $app, + 'dataset_name' => $datasetName + ); + + $definition = $this->_ci->FiltersModel->loadWhere($whereParameters); + } + } + + return $definition; + } + + /** + * Checks if the json definition of this filter is valid + */ + private function _parseFilterJson($definition) + { + $jsonEncodedFilter = null; + + // If the definition contains data and they are valid + if (hasData($definition) && isset(getData($definition)[0]->filter) && trim(getData($definition)[0]->filter) != '') + { + // Get the json definition of the filter + $tmpJsonEncodedFilter = json_decode(getData($definition)[0]->filter); + + // Checks required filter's properies + if (isset($tmpJsonEncodedFilter->name) + && isset($tmpJsonEncodedFilter->columns) + && is_array($tmpJsonEncodedFilter->columns) + && isset($tmpJsonEncodedFilter->filters) + && is_array($tmpJsonEncodedFilter->filters)) + { + $jsonEncodedFilter = $tmpJsonEncodedFilter; + } + } + + return $jsonEncodedFilter; + } + + /** + * Generate the query to retrieve the dataset for a filter + */ + private function _generateDatasetQuery($query, $filters) + { + $datasetQuery = 'SELECT * FROM ('.$query.') '.self::DATASET_TABLE_ALIAS; + + // If the given query is valid and the parameter filters is an array + if (!isEmptyString($query) && $filters != null && is_array($filters)) + { + $where = ''; // starts building the SQL where clause + + // Loops through the given applied filters + for ($filtersCounter = 0; $filtersCounter < count($filters); $filtersCounter++) + { + $filterDefinition = $filters[$filtersCounter]; // definition of one filter + + // If the name of the applied filter is valid + if (!isEmptyString($filterDefinition->name)) + { + // 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 the SQL where clause was built + if ($where != '') $datasetQuery .= ' WHERE '.$where; + } + + return $datasetQuery; + } + + /** + * Retrieves the dataset from the DB + */ + private function _getDataset($datasetQuery) + { + $dataset = null; + + if ($datasetQuery != null) + { + $this->_ci->load->model('system/Filters_model', 'FiltersModel'); + + // Execute the given SQL statement suppressing error messages + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + } + + return $dataset; + } + + /** + * Get the filter name, the default is the "name" property of the JSON definition + * If the property namePhrase is present into the JSON definition, then try to load that from the phrases system + * NOTE: filterJson should be already checked using the method _parseFilterJson + */ + private function _getFilterName($filterJson) + { + $filterName = $filterJson->name; // always present, used as default + + // Filter name from phrases system + if (isset($filterJson->namePhrase) && !isEmptyString($filterJson->namePhrase)) + { + // Loads the library to use the phrases system + $this->_ci->load->library('PhrasesLib', array(self::FILTER_PHRASES_CATEGORY)); + + $tmpFilterNamePhrase = $this->_ci->phraseslib->t(self::FILTER_PHRASES_CATEGORY, $filterJson->namePhrase); + if (!isEmptyString($tmpFilterNamePhrase)) // if is not null or an empty string + { + $filterName = $tmpFilterNamePhrase; + } + } + + return $filterName; + } +} + 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/IssuesLib.php b/application/libraries/IssuesLib.php index d6488bc36..9b3a9de6e 100644 --- a/application/libraries/IssuesLib.php +++ b/application/libraries/IssuesLib.php @@ -169,6 +169,9 @@ class IssuesLib return $this->_changeIssueStatus($issue_id, $data, $user); } + // -------------------------------------------------------------------------------------------------------------- + // Private methods + /** * Changes status of an issue. * @param int $issue_id @@ -215,8 +218,15 @@ class IssuesLib * @param string $inhalt_extern * @return object success or error */ - private function _addIssue($fehlercode, $person_id = null, $oe_kurzbz = null, $fehlertext_params = null, $resolution_params = null, $fehlercode_extern = null, $inhalt_extern = null) - { + private function _addIssue( + $fehlercode, + $person_id = null, + $oe_kurzbz = null, + $fehlertext_params = null, + $resolution_params = null, + $fehlercode_extern = null, + $inhalt_extern = null + ) { if (isEmptyString($person_id) && isEmptyString($oe_kurzbz)) return error("Person_id or oe_kurzbz must be set."); @@ -226,7 +236,15 @@ class IssuesLib if (hasData($fehlerRes)) { $fehlertextVorlage = getData($fehlerRes)[0]->fehlertext; - $fehlertext = isEmptyArray($fehlertext_params) ? $fehlertextVorlage : vsprintf($fehlertextVorlage, $fehlertext_params); + + $fehlertext = $fehlertextVorlage; + if (!isEmptyArray($fehlertext_params)) + { + if (count($fehlertext_params) != substr_count($fehlertextVorlage, '%s')) + return error('Wrong number of parameters for Fehlertext, fehler_kurzbz ' . $fehlercode); + + $fehlertext = vsprintf($fehlertextVorlage, $fehlertext_params); + } $openIssuesCountRes = $this->_ci->IssueModel->getOpenIssueCount($fehlercode, $person_id, $oe_kurzbz, $fehlercode_extern); @@ -252,6 +270,7 @@ class IssuesLib return error("Invalid parameters for resolution"); } + // insert new issue return $this->_ci->IssueModel->insert( array( 'fehlercode' => $fehlercode, @@ -267,8 +286,8 @@ class IssuesLib ) ); } - else - return success($openIssueCount); + else // return success if issue already exists + return success("Issue already exists"); } else return error("Number of open issues could not be determined"); diff --git a/application/libraries/NavigationLib.php b/application/libraries/NavigationLib.php index e2492cef4..95ce67610 100644 --- a/application/libraries/NavigationLib.php +++ b/application/libraries/NavigationLib.php @@ -1,4 +1,20 @@ . + */ if (! defined('BASEPATH')) exit('No direct script access allowed'); @@ -37,7 +53,7 @@ class NavigationLib // Loads library ExtensionsLib $this->_ci->load->library('ExtensionsLib'); - $this->_navigationPage = $this->_getNavigationtPage($params); // sets the id for the related navigation widget + $this->_navigationPage = $this->_getNavigationPage($params); // sets the id for the related navigation widget } //------------------------------------------------------------------------------------------------------------------ @@ -67,9 +83,19 @@ class NavigationLib * Returns the structure for one level of the menu */ public function oneLevel( - $description, $link = '#', $children = null, $icon = '', $expand = false, - $subscriptDescription = null, $subscriptLinkClass = null, $subscriptLinkValue = null, $target = '', - $sort = null, $requiredPermissions = null, $subscriptLinkHref = '#') + $description, + $link = '#', + $children = null, + $icon = '', + $expand = false, + $subscriptDescription = null, + $subscriptLinkClass = null, + $subscriptLinkValue = null, + $target = '', + $sort = null, + $requiredPermissions = null, + $subscriptLinkHref = '#' + ) { return array( 'description' => $description, @@ -223,7 +249,8 @@ class NavigationLib $filename = APPPATH.'config/'.ExtensionsLib::EXTENSIONS_DIR_NAME.'/'.$ext->name.'/'.self::CONFIG_NAVIGATION_FILENAME; if (file_exists($filename)) { - unset($config); + $config = array(); // default value + include($filename); if (isset($config[$configName]) && is_array($config[$configName])) @@ -278,7 +305,7 @@ class NavigationLib } else { - foreach ($navigationArray as $key=>$row) + foreach ($navigationArray as $key => $row) { // Search for * Entries if (mb_strpos($key, '*') === 0 || mb_strpos($key, '*') === mb_strlen($key) - 1) @@ -300,7 +327,7 @@ class NavigationLib * Return an unique string that identify this navigation widget * NOTE: The default value is the URI where the NavigationWidget is called */ - private function _getNavigationtPage($params) + private function _getNavigationPage($params) { if ($params != null && is_array($params) diff --git a/application/libraries/SearchBarLib.php b/application/libraries/SearchBarLib.php new file mode 100644 index 000000000..3a9d06d13 --- /dev/null +++ b/application/libraries/SearchBarLib.php @@ -0,0 +1,298 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use \stdClass as stdClass; + +/** + * + */ +class SearchBarLib +{ + // Error constats + const ERROR_WRONG_JSON = 'ERR001'; + const ERROR_WRONG_SEARCHSTR = 'ERR002'; + const ERROR_NO_TYPES = 'ERR003'; + const ERROR_WRONG_TYPES = 'ERR004'; + + // List of allowed types of search + const ALLOWED_TYPES = ['mitarbeiter', 'organisationunit', 'raum', 'person', 'student', 'prestudent', 'document', 'cms']; + + const PHOTO_IMG_URL = '/cis/public/bild.php?src=person&person_id='; + + private $_ci; // Code igniter instance + + /** + * Gets the CI instance and loads model + */ + public function __construct() + { + $this->_ci =& get_instance(); // get code igniter instance + + // It is loaded only to have the DB_Model available + $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * It performes the search of the given search string using the specified search types + */ + public function search($searchstr, $types) + { + // Checks if the given parameters are fine + $search = $this->_checkParameters($searchstr, $types); + + // If the check was successful then perform the search + if (isSuccess($search)) $search = $this->_search($searchstr, $types); + + return $search; // return the result + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks: + * - The given searchstr is a not empty string + * - The given types is a not empty array and contains allowed search types + */ + private function _checkParameters($searchstr, $types) + { + // If searchstr is empty + if (isEmptyString($searchstr)) return error(self::ERROR_WRONG_SEARCHSTR); + + // If types is not an array or it is empty + if (isEmptyArray($types)) return error(self::ERROR_NO_TYPES); + + // If all the elements in types are allowed search types + if (!isEmptyArray(array_diff($types, self::ALLOWED_TYPES))) return error(self::ERROR_WRONG_TYPES); + + return success(); // The check is fine! + } + + /** + * Loops on types and perform the search of that type using searchstr + * Then it collects all the returned data into an array as property of an object + */ + private function _search($searchstr, $types) + { + // Object to be returned + $result = new stdClass(); + $result->data = array(); + + // For each search type + foreach ($types as $type) + { + // Perform the search and then add the result to data + $result->data = array_merge($result->data, $this->{'_'.$type}($searchstr, $type)); + } + + return $result; + } + + /** + * Search for employees + */ + private function _mitarbeiter($searchstr, $type) + { + $dbModel = new DB_Model(); + + $employees = $dbModel->execReadOnlyQuery(' + SELECT + \''.$type.'\' AS type, + b.uid AS uid, + p.person_id AS person_id, + p.vorname || \' \' || p.nachname AS name, + ARRAY_AGG(DISTINCT(org.bezeichnung)) AS organisationunit_name, + 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, + 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 + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + WHERE bf.funktion_kurzbz = \'oezuordnung\' + 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 ON org.uid = b.uid + LEFT JOIN ( + SELECT kontakt, standort_id + FROM public.tbl_kontakt + WHERE kontakttyp = \'telefon\' + ) k ON(k.standort_id = m.standort_id) + 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 + '); + + // If something has been found then return it + if (hasData($employees)) return getData($employees); + + // Otherwise return an empty array + return array(); + } + + /** + * Seach for organisation units + */ + private function _organisationunit($searchstr, $type) + { + $dbModel = new DB_Model(); + + $ous = $dbModel->execReadOnlyQuery(' + SELECT + \''.$type.'\' AS type, + o.oe_kurzbz AS oe_kurzbz, + o.bezeichnung AS name, + oParent.oe_kurzbz AS parentoe_kurzbz, + oParent.bezeichnung AS parentoe_name, + ARRAY_AGG(DISTINCT(bfLeader.uid)) AS leader_uid, + ARRAY_AGG(DISTINCT(bfLeader.vorname || \' \' || bfLeader.nachname)) AS leader_name, + COUNT(bfCount.benutzerfunktion_id) AS number_of_people, + (CASE WHEN o.mailverteiler = TRUE THEN o.oe_kurzbz || \''.'@'.DOMAIN.'\' END) AS mailgroup + FROM public.tbl_organisationseinheit o + LEFT JOIN public.tbl_organisationseinheit oParent ON(oParent.oe_kurzbz = o.oe_parent_kurzbz) + LEFT JOIN ( + SELECT benutzerfunktion_id, oe_kurzbz + FROM public.tbl_benutzerfunktion + WHERE funktion_kurzbz = \'oezuordnung\' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + ) bfCount ON(bfCount.oe_kurzbz = o.oe_kurzbz) + LEFT JOIN ( + SELECT bf.oe_kurzbz, bf.uid, p.vorname, p.nachname + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_benutzer b USING(uid) + JOIN public.tbl_person p USING(person_id) + WHERE funktion_kurzbz = \'Leitung\' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND b.aktiv = TRUE + ) bfLeader ON(bfLeader.oe_kurzbz = o.oe_kurzbz) + WHERE o.oe_kurzbz ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' + OR o.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' + GROUP BY type, o.oe_kurzbz, o.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung + '); + + // If something has been found + if (hasData($ous)) + { + // Loop through the returned dataset + foreach (getData($ous) as $ou) + { + // Create the new property leaders as an empty array + $ou->leaders = array(); + + // Loop through the found leaders for this organisation unit + for ($i = 0; $i < count($ou->leader_uid); $i++) + { + // If a leader exists for this organisationunit and has a name :D + if (!isEmptyString($ou->leader_uid[$i]) && !isEmptyString($ou->leader_name[$i])) + { + // Empty object that will contains the leader uid and name + $leader = new stdClass(); + // Set the properties name and uid + $leader->uid = $ou->leader_uid[$i]; + $leader->name = $ou->leader_name[$i]; + // Add the leader object to the leaders array + $ou->leaders[] = $leader; + } + } + + // Remove the not needed properties leader_uid and leader_name + unset($ou->leader_uid); + unset($ou->leader_name); + } + + // Returns the changed dataset + return getData($ous); + } + + // Otherwise return an empty array + return array(); + } + + /** + * Search for persons + */ + private function _person($searchstr, $type) + { + return array(); + } + + /** + * Search for students + */ + private function _student($searchstr, $type) + { + return array(); + } + + /** + * Search for prestudents + */ + private function _prestudent($searchstr, $type) + { + return array(); + } + + /** + * Search for documents + */ + private function _document($searchstr, $type) + { + return array(); + } + + /** + * Search for CMSs + */ + private function _cms($searchstr, $type) + { + return array(); + } + + /** + * Search for rooms + */ + private function _raum($searchstr, $type) + { + return array(); + } +} + diff --git a/application/libraries/issues/PlausicheckLib.php b/application/libraries/issues/PlausicheckLib.php new file mode 100644 index 000000000..19442de3c --- /dev/null +++ b/application/libraries/issues/PlausicheckLib.php @@ -0,0 +1,1362 @@ +_ci =& get_instance(); // get ci instance + + // load models + $this->_ci->load->model('crm/Prestudent_model', 'PrestudentModel'); + $this->_ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + // get database for queries + $this->_db = new DB_Model(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Studiengang checks + + /** + * Studiengang should be the same for prestudent and student. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getStgPrestudentUngleichStgStudent($studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + pre.person_id, pre.prestudent_id, stg.oe_kurzbz prestudent_stg_oe_kurzbz, student_stg.oe_kurzbz student_stg_oe_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_student stud USING(prestudent_id) + JOIN public.tbl_person pers USING(person_id) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + JOIN public.tbl_studiengang student_stg ON stud.studiengang_kz = student_stg.studiengang_kz + WHERE + stud.studiengang_kz != pre.studiengang_kz"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Orgform of a Studiengang in Studienplan should be the same as orgform of student. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getOrgformStgUngleichOrgformPrestudent($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + prestudent.person_id, prestudent.prestudent_id, status.studiensemester_kurzbz, + studiengang.orgform_kurzbz AS stg_orgform, status.orgform_kurzbz AS student_orgform, + prestudent.studiengang_kz AS student_studiengang, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_studiengang studiengang + JOIN public.tbl_student student USING(studiengang_kz) + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_benutzer benutzer on(benutzer.uid = student.student_uid) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + LEFT JOIN lehre.tbl_studienplan stpl USING (studienplan_id) + WHERE + benutzer.aktiv = true + AND status.status_kurzbz IN ('Student', 'Unterbrecher', 'Abbrecher', 'Diplomand', 'Absolvent') + AND studiengang.studiengang_kz < 10000 + AND status.studiensemester_kurzbz = ? + AND NOT (status.orgform_kurzbz IS NULL AND studiengang.mischform = FALSE) + AND NOT EXISTS( + SELECT 1 + FROM + lehre.tbl_studienplan + JOIN + lehre.tbl_studienordnung USING(studienordnung_id) + WHERE + tbl_studienplan.studienplan_id = stpl.studienplan_id + AND tbl_studienordnung.studiengang_kz = prestudent.studiengang_kz + AND tbl_studienplan.orgform_kurzbz = status.orgform_kurzbz)"; + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND studiengang.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + $qry .= " + ORDER BY student_uid"; + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students in "mixed" Studiengang should have Orgform. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getPrestudentMischformOhneOrgform($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + pre.person_id, pre.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + status.status_kurzbz IN ('Bewerber', 'Student') + AND stg.mischform + AND (status.orgform_kurzbz='' OR status.orgform_kurzbz IS NULL) + AND status.studiensemester_kurzbz=?"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Studiengang should be the same for prestudent and studienplan. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @param studienordnung_id int if check is to be executed only for a certain studienordnung_id + * @return success with prestudents or error + */ + public function getStgPrestudentUngleichStgStudienplan($studiengang_kz = null, $prestudent_id = null, $studienordnung_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT ON (ps.prestudent_id) ps.person_id, ps.prestudent_id, stordnung.studienordnung_id, + stplan.bezeichnung AS studienplan, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_prestudent ps + JOIN public.tbl_prestudentstatus USING(prestudent_id) + JOIN lehre.tbl_studienplan stplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung stordnung USING(studienordnung_id) + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_studiengang stg ON ps.studiengang_kz = stg.studiengang_kz + WHERE + ps.studiengang_kz<>stordnung.studiengang_kz + AND stg.melderelevant"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND ps.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + if (isset($studienordnung_id)) + { + $qry .= " AND stordnung.studienordnung_id = ?"; + $params[] = $studienordnung_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + //------------------------------------------------------------------------------------------------------------------ + // Studentstatus checks + + /** + * Abbrecher cannot be active. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getAbbrecherAktiv($studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + pre.person_id, pre.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_prestudentstatus pre_status + JOIN public.tbl_prestudent pre USING(prestudent_id) + JOIN public.tbl_student student USING(prestudent_id) + JOIN public.tbl_benutzer benutzer on(benutzer.uid=student.student_uid) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + WHERE + pre_status.status_kurzbz ='Abbrecher' + AND benutzer.aktiv=true"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * There shouldn't be any status after Abbrecher status. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getStudentstatusNachAbbrecher($studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + prestudent.person_id, prestudent.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_student student + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_prestudentstatus prestatus USING(prestudent_id) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + WHERE + prestatus.status_kurzbz = 'Abbrecher' + AND get_rolle_prestudent(prestudent.prestudent_id, prestatus.studiensemester_kurzbz) <> 'Abbrecher'"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Ausbildungssemester of prestudent (lehrverband) must be the same as Ausbildungssemester of prestudentstatus. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getAusbildungssemPrestudentUngleichAusbildungssemStatus($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $params = array($studiensemester_kurzbz, $studiensemester_kurzbz, $studiensemester_kurzbz); + + $qry = " + SELECT + DISTINCT(student.student_uid), student.student_uid, prestudent.person_id, prestudent.prestudent_id, + status.ausbildungssemester AS status_ausbildungssemester, lv.semester AS student_ausbildungssemester, status.studiensemester_kurzbz, + stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_student student + JOIN public.tbl_studentlehrverband lv USING(student_uid) + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + WHERE + status.studiensemester_kurzbz = ? + AND lv.studiensemester_kurzbz = ? + AND status.status_kurzbz NOT IN ('Interessent','Bewerber','Aufgenommener','Wartender','Abgewiesener','Unterbrecher') + AND get_rolle_prestudent (prestudent_id, ?)='Student' + AND status.ausbildungssemester != lv.semester"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students with active status should have an active Benutzer. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getInaktiverStudentAktiverStatus($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $aktStudiensemesterRes = $this->_ci->StudiensemesterModel->getAkt(); + + if (isError($aktStudiensemesterRes)) return $aktStudiensemesterRes; + + $studiensemester_kurzbz = hasData($aktStudiensemesterRes) ? getData($aktStudiensemesterRes)[0]->studiensemester_kurzbz : ''; + + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + DISTINCT(student.student_uid), prestudent.person_id, prestudent.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_benutzer benutzer + JOIN public.tbl_student student on(benutzer.uid = student.student_uid) + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + WHERE + benutzer.aktiv=false + AND EXISTS (SELECT 1 FROM public.tbl_prestudentstatus WHERE prestudent_id = prestudent.prestudent_id AND studiensemester_kurzbz = ?) + AND get_rolle_prestudent(prestudent_id, NULL) IN ('Student', 'Diplomand', 'Unterbrecher', 'Praktikant') + AND stg.melderelevant + AND prestudent.bismelden"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students of a semester shouldn't start studies before the date of Bismeldung. + * e.g. If student studies in WS2022 datum of status shouldn't be before 15.4.2020 + * e.g. If student studies in SS2022 datum of status shouldn't be before 15.11.2022 + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getInskriptionVorLetzerBismeldung($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + // get Bismeldedatum + $datumBis = $this->_getBisdateFromSemester($studiensemester_kurzbz); + + $params = array($datumBis, $studiensemester_kurzbz, $datumBis); + + // get active students + $qry = " + SELECT + DISTINCT ON (student.student_uid) ? AS datum_bismeldung, + prestudent.person_id, prestudent.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz + FROM + public.tbl_benutzer benutzer + JOIN public.tbl_student student on(benutzer.uid = student.student_uid) + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + WHERE + benutzer.aktiv=true + AND status.studiensemester_kurzbz = ? + /* inscription date before date of first student status */ + AND ( + SELECT datum + FROM public.tbl_prestudentstatus + WHERE prestudent_id = prestudent.prestudent_id + AND studiensemester_kurzbz = status.studiensemester_kurzbz + AND status_kurzbz = 'Student' + ORDER BY datum, insertamum, ext_id + LIMIT 1 + ) < ? + AND stg.melderelevant + AND prestudent.bismelden"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Status Dates and status studysemester dates should be in correct order. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getDatumStudiensemesterFalscheReihenfolge($studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + // all active students with Status student in current semester + $qry = " + SELECT DISTINCT ON (prestudent_id) * + FROM ( + SELECT + prestudent.person_id, prestudent.prestudent_id, + stg.studiengang_kz, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, + ROW_NUMBER () OVER ( + PARTITION BY prestudent.prestudent_id + ORDER BY sem.start DESC, status.datum DESC, status.insertamum DESC, status.ext_id DESC + ) AS reihenfolge_semester, + ROW_NUMBER () OVER ( + PARTITION BY prestudent.prestudent_id + ORDER BY status.datum DESC, status.insertamum DESC, status.ext_id DESC + ) AS reihenfolge_datum + FROM + public.tbl_student student + JOIN public.tbl_benutzer benutzer on(student.student_uid = benutzer.uid) + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiensemester sem USING(studiensemester_kurzbz) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + WHERE + benutzer.aktiv=true + AND status.status_kurzbz='Student' + ) reihenfolge + WHERE reihenfolge_semester <> reihenfolge_datum"; + + if (isset($studiengang_kz)) + { + $qry .= " AND studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students with active Benutzer should have a status in the current semester. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getAktiverStudentOhneStatus($studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT (student_uid), prestudent.person_id, prestudent.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_student student + JOIN public.tbl_benutzer benutzer on (benutzer.uid = student.student_uid) + JOIN public.tbl_prestudent prestudent USING(prestudent_id) + JOIN public.tbl_studiengang stg ON prestudent.studiengang_kz = stg.studiengang_kz + WHERE + benutzer.aktiv=TRUE + AND stg.melderelevant + AND prestudent.bismelden + AND NOT EXISTS ( + SELECT 1 + FROM public.tbl_prestudentstatus + JOIN public.tbl_studiensemester sem USING (studiensemester_kurzbz) + WHERE prestudent_id = prestudent.prestudent_id + /* buffer of four months, as status are often entered later */ + AND sem.ende::date > NOW() - interval '4 months' + )"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Studienplan should be valid in current Ausbildungssemester of prestudent. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getStudienplanUngueltig($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + DISTINCT pre.person_id, pre.prestudent_id, + tbl_studienplan.bezeichnung AS studienplan, + status.status_kurzbz, + status.studiensemester_kurzbz, + status.ausbildungssemester, + stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_person USING(person_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + WHERE + status_kurzbz in('Student', 'Interessent','Bewerber','Aufgenommener') + AND NOT EXISTS ( + SELECT + 1 + FROM + lehre.tbl_studienplan_semester + WHERE + studienplan_id=status.studienplan_id + AND tbl_studienplan_semester.semester = status.ausbildungssemester + AND tbl_studienplan_semester.studiensemester_kurzbz = status.studiensemester_kurzbz + ) + AND status.studiensemester_kurzbz=? + AND pre.bismelden + AND stg.melderelevant"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND tbl_prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students with finished studies should have exactly one final exam. + * @param studiensemester_kurzbz string if check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getFalscheAnzahlAbschlusspruefungen($studiensemester_kurzbz = null, $studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT * FROM ( + SELECT + DISTINCT ON(pre.prestudent_id) pre.person_id, pre.prestudent_id, student_uid, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, + ( + SELECT COUNT(*) + FROM lehre.tbl_abschlusspruefung + WHERE student_uid = stud.student_uid + AND abschlussbeurteilung_kurzbz != 'nicht' + AND abschlussbeurteilung_kurzbz IS NOT NULL + ) AS anzahl_abschlusspruefungen + FROM + public.tbl_prestudent pre + JOIN public.tbl_student stud USING(prestudent_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + WHERE + status_kurzbz = 'Absolvent' + AND pre.bismelden + AND stg.melderelevant + AND NOT EXISTS ( /* exclude gs */ + SELECT 1 + FROM bis.tbl_mobilitaet + WHERE prestudent_id = pre.prestudent_id + AND studiensemester_kurzbz = status.studiensemester_kurzbz + )"; + + if (isset($studiensemester_kurzbz)) + { + $qry .= " AND status.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + $qry .= ") studenten + WHERE anzahl_abschlusspruefungen != 1"; + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Date of final exam shouldn't be missing for Absolvent. + * @param studiensemester_kurzbz string if check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param abschlusspruefung_id int if check is to be executed for a certain Abschlussprüfung + * @return success with prestudents or error + */ + public function getDatumAbschlusspruefungFehlt($studiensemester_kurzbz = null, $studiengang_kz = null, $abschlusspruefung_id = null) + { + $results = array(); + + $pruefungenRes = $this->_getInvalidAbschlusspruefungen($studiensemester_kurzbz, $studiengang_kz, $abschlusspruefung_id); + + if (isError($pruefungenRes)) return $pruefungenRes; + + if (hasData($pruefungenRes)) + { + $pruefungen = getData($pruefungenRes); + + foreach ($pruefungen as $pruefung) + { + if (isEmptyString($pruefung->datum)) $results[] = $pruefung; + } + } + + return success($results); + } + + /** + * Date of sponsion shouldn't be missing for Absolvent. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param abschlusspruefung_id int if check is to be executed only for a certain Abschlussprüfung + * @return success with prestudents or error + */ + public function getDatumSponsionFehlt($studiensemester_kurzbz = null, $studiengang_kz = null, $abschlusspruefung_id = null) + { + $results = array(); + + $pruefungenRes = $this->_getInvalidAbschlusspruefungen($studiensemester_kurzbz, $studiengang_kz, $abschlusspruefung_id); + + if (isError($pruefungenRes)) return $pruefungenRes; + + if (hasData($pruefungenRes)) + { + $pruefungen = getData($pruefungenRes); + + foreach ($pruefungen as $pruefung) + { + if (isEmptyString($pruefung->sponsion)) $results[] = $pruefung; + } + } + + return success($results); + } + + /** + * Bewerber should have participated in Reihungstest. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getBewerberNichtZumRtAngetreten($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $previousStudiensemesterRes = $this->_ci->StudiensemesterModel->getPreviousFrom($studiensemester_kurzbz); + + if (isError($previousStudiensemesterRes)) return $previousStudiensemesterRes; + + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + prestudent.person_id, prestudent.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz + FROM + public.tbl_prestudent prestudent + JOIN public.tbl_prestudentstatus status ON(prestudent.prestudent_id=status.prestudent_id) + JOIN public.tbl_person USING(person_id) + LEFT JOIN bis.tbl_orgform USING(orgform_kurzbz) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + status_kurzbz='Bewerber' + AND reihungstestangetreten=false + AND stg.melderelevant + AND prestudent.bismelden"; + + if (hasData($previousStudiensemesterRes)) + { + $previousStudiensemester = getData($previousStudiensemesterRes)[0]->studiensemester_kurzbz; + $qry .= " AND (studiensemester_kurzbz=? OR studiensemester_kurzbz=?)"; + $params[] = $previousStudiensemester; + } + else + { + $qry .= " AND studiensemester_kurzbz=?"; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Current Ausbildungssemester shouldn't be 0. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getAktSemesterNull($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + DISTINCT pre.person_id, pre.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, prestat.studiensemester_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_prestudentstatus prestat USING(prestudent_id) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + prestat.status_kurzbz != 'Incoming' + AND prestat.studiensemester_kurzbz = ? + AND ausbildungssemester = 0 + AND stg.melderelevant + AND pre.bismelden"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Prestudent should have a final status. + * @param studiensemester_kurzbz string if check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getAbschlussstatusFehlt($studiensemester_kurzbz = null, $studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT ON (pre.prestudent_id) + pre.person_id, pre.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + NOT EXISTS( /*student does not study anymore*/ + SELECT + 1 + FROM + public.tbl_prestudentstatus ps + JOIN public.tbl_studiensemester USING(studiensemester_kurzbz) + WHERE + prestudent_id=pre.prestudent_id + /* 4 months: There might be Diplomanden, in summer months end status is often not entered yet */ + AND tbl_studiensemester.ende>now() - interval '4 months' + ) + /* check only valid begininng with 2018 */ + AND '2018-01-01'<(SELECT max(datum) FROM public.tbl_prestudentstatus WHERE prestudent_id=pre.prestudent_id) + AND NOT EXISTS( /* no end status */ + SELECT 1 + FROM public.tbl_prestudentstatus ps + WHERE + prestudent_id=pre.prestudent_id + AND status_kurzbz IN('Abbrecher','Abgewiesener','Absolvent','Incoming') + ) + AND stg.melderelevant + AND pre.bismelden"; + + if (isset($studiensemester_kurzbz)) + { + $prevStudiensemesterRes = $this->_ci->StudiensemesterModel->getPreviousFrom($studiensemester_kurzbz); + + if (isError($prevStudiensemesterRes)) return $prevStudiensemesterRes; + + if (hasData($prevStudiensemesterRes)) + { + // if Studiensemester given, check only if has status in current or previous semester + $prevStudiensemester = getData($prevStudiensemesterRes)[0]->studiensemester_kurzbz; + $qry .= " AND EXISTS ( + SELECT 1 + FROM public.tbl_prestudentstatus ps + WHERE studiensemester_kurzbz IN (?, ?) + AND ps.prestudent_id = pre.prestudent_id + )"; + $params[] = $prevStudiensemester; + $params[] = $studiensemester_kurzbz; + } + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Student with active status should have been charged, i.e. have a Kontobuchung with a negative or zero value. + * @param studiensemester_kurzbz string if check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getAktiverStudentstatusOhneKontobuchung($studiensemester_kurzbz, $studiengang_kz = null, $prestudent_id = null) + { + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + DISTINCT ON (pre.prestudent_id) + pre.person_id, pre.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_person pers USING(person_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + status.studiensemester_kurzbz = ? + AND status.status_kurzbz IN ('Student', 'Incoming') + AND NOT EXISTS ( + SELECT 1 + FROM + public.tbl_konto + WHERE + person_id = pers.person_id + AND studiensemester_kurzbz = status.studiensemester_kurzbz + AND buchungsnr_verweis IS NULL + AND betrag <= 0 + ) + AND stg.melderelevant + AND pre.bismelden"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND pre.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + //------------------------------------------------------------------------------------------------------------------ + // Person checks + + /** + * Birthdate is too long ago. + * @param studiensemester_kurzbz string if check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param person_id int if check is to be executed only for one person + * @return success with prestudents or error + */ + public function getGbDatumWeitZurueck($studiensemester_kurzbz = null, $studiengang_kz = null, $person_id = null) + { + $params = array(); + + $qry = " + SELECT + pers.person_id + FROM + public.tbl_person pers + WHERE + pers.gebdatum < '1920-01-01' + AND EXISTS ( + SELECT 1 + FROM public.tbl_prestudent + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE person_id = pers.person_id"; + + if (isset($studiensemester_kurzbz)) + { + $qry .= " AND status.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + $qry .= ")"; + + if (isset($person_id)) + { + $qry .= " AND pers.person_id = ?"; + $params[] = $person_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Nation is not Austria, but address has austrian Gemeinde. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param person_id int if check is to be executed only for one person + * @return success with prestudents or error + */ + public function getNationNichtOesterreichAberGemeinde($studiengang_kz = null, $person_id = null) + { + $params = array(); + + $qry = "SELECT DISTINCT tbl_person.person_id, adr.gemeinde, adr.adresse_id + FROM + public.tbl_adresse adr + JOIN public.tbl_prestudent USING(person_id) + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_student USING(prestudent_id) + JOIN public.tbl_benutzer ON(uid=student_uid) + JOIN public.tbl_studiengang stg ON tbl_prestudent.studiengang_kz = stg.studiengang_kz + WHERE + adr.nation!='A' + AND tbl_benutzer.aktiv + AND gemeinde NOT IN ('Münster') + AND EXISTS(SELECT 1 FROM bis.tbl_gemeinde WHERE name = adr.gemeinde)"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($person_id)) + { + $qry .= " AND tbl_person.person_id = ?"; + $params[] = $person_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students should have exactly one home address. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param person_id int if check is to be executed only for one person + * @return success with prestudents or error + */ + public function getFalscheAnzahlHeimatadressen($studiensemester_kurzbz = null, $studiengang_kz = null, $person_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT person_id + FROM + ( + SELECT person_id, COUNT(adresse_id) AS anzahl_adressen + FROM public.tbl_adresse addr + WHERE heimatadresse IS TRUE + GROUP BY person_id + ) adressen + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_prestudent pre USING(person_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_student USING(prestudent_id) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + WHERE + anzahl_adressen != 1 + AND stg.melderelevant + AND pre.bismelden"; + + if (isset($studiensemester_kurzbz)) + { + $qry .= " AND status.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($person_id)) + { + $qry .= " AND person_id = ?"; + $params[] = $person_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Students should have exactly one delivery address. + * @param studiensemester_kurzbz string if check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param person_id int if check is to be executed only for one person + * @return success with prestudents or error + */ + public function getFalscheAnzahlZustelladressen($studiensemester_kurzbz = null, $studiengang_kz = null, $person_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT person_id + FROM + ( + SELECT person_id, COUNT(adresse_id) AS anzahl_adressen + FROM public.tbl_adresse addr + WHERE zustelladresse IS TRUE + GROUP BY person_id + ) adressen + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_prestudent pre USING(person_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_student USING(prestudent_id) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + WHERE + anzahl_adressen != 1 + AND stg.melderelevant + AND pre.bismelden"; + + if (isset($studiensemester_kurzbz)) + { + $qry .= " AND status.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($person_id)) + { + $qry .= " AND person_id = ?"; + $params[] = $person_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + //------------------------------------------------------------------------------------------------------------------ + // I/O checks + + /** + * Incoming shouldn't have austrian home address. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param person_id int if check is to be executed only for one person + * @return success with prestudents or error + */ + public function getIncomingHeimatNationOesterreich($studiensemester_kurzbz, $studiengang_kz = null, $person_id = null) + { + $params = array($studiensemester_kurzbz); + + $qry = " + SELECT + DISTINCT pers.person_id, status.studiensemester_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_person pers USING(person_id) + JOIN public.tbl_adresse addr USING(person_id) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + status.status_kurzbz = 'Incoming' + AND addr.nation = 'A' + AND addr.heimatadresse + AND status.studiensemester_kurzbz = ? + AND stg.melderelevant + AND pre.bismelden"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($person_id)) + { + $qry .= " AND pers.person_id = ?"; + $params[] = $person_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Incoming should have IN/OUT data. + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return success with prestudents or error + */ + public function getIncomingOhneIoDatensatz($studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT ON(student_uid, nachname, vorname) + tbl_person.person_id, + tbl_prestudent.prestudent_id, + stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_student + JOIN public.tbl_benutzer ON(student_uid=uid) + JOIN public.tbl_person USING(person_id) + JOIN public.tbl_prestudent USING(prestudent_id) + JOIN public.tbl_prestudentstatus ON(tbl_prestudent.prestudent_id=tbl_prestudentstatus.prestudent_id) + JOIN public.tbl_studiengang stg ON(stg.studiengang_kz=tbl_student.studiengang_kz) + WHERE + bismelden=TRUE + AND status_kurzbz='Incoming' AND NOT EXISTS (SELECT 1 FROM bis.tbl_bisio WHERE student_uid=tbl_student.student_uid) + AND stg.melderelevant"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND tbl_prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Incoming or gemeinsame Studien students should not receive funding (not be förderrelevant). + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @return object success or error + */ + public function getIncomingOrGsFoerderrelevant($studiensemester_kurzbz = null, $studiengang_kz = null, $prestudent_id = null) + { + $params = array(); + + $qry = " + SELECT + DISTINCT ON(prestudent_id) + pers.person_id, + ps.prestudent_id, + stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_student stud + JOIN public.tbl_benutzer ON(student_uid=uid) + JOIN public.tbl_person pers USING(person_id) + JOIN public.tbl_prestudent ps USING(prestudent_id) + JOIN public.tbl_prestudentstatus status USING(prestudent_id) + JOIN public.tbl_studiengang stg ON(stg.studiengang_kz=stud.studiengang_kz) + WHERE + ( + status.status_kurzbz = 'Incoming' + OR EXISTS ( + SELECT 1 + FROM + bis.tbl_mobilitaet + JOIN public.tbl_prestudent USING(prestudent_id) + WHERE + prestudent_id = ps.prestudent_id + AND gsstudientyp_kurzbz = 'Extern' + ) + ) + AND (ps.foerderrelevant <> FALSE OR ps.foerderrelevant IS NULL) + AND bismelden=TRUE + AND stg.melderelevant"; + + if (isset($studiensemester_kurzbz)) + { + $qry .= " AND status.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND ps.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Get final exams in a semester which are invalid (e.g. missing data) + * @param studiensemester_kurzbz string if check is to be executed for certain Studiengang + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param abschlusspruefung_id int if check is to be executed for certain Abschlussprüfung + */ + private function _getInvalidAbschlusspruefungen($studiensemester_kurzbz = null, $studiengang_kz = null, $abschlusspruefung_id = null) + { + $params = array(); + + $qry = " + SELECT + pre.person_id, pre.prestudent_id, + pruefung.sponsion, pruefung.datum, pruefung.abschlusspruefung_id, + stg.oe_kurzbz AS prestudent_stg_oe_kurzbz + FROM + public.tbl_prestudent pre + JOIN public.tbl_student stud USING(prestudent_id) + JOIN public.tbl_prestudentstatus prestatus USING(prestudent_id) + JOIN public.tbl_studiengang stg ON pre.studiengang_kz = stg.studiengang_kz + JOIN lehre.tbl_abschlusspruefung pruefung ON stud.student_uid = pruefung.student_uid + WHERE + status_kurzbz = 'Absolvent' + AND NOT EXISTS ( /* exclude gs */ + SELECT 1 + FROM bis.tbl_mobilitaet + WHERE prestudent_id = pre.prestudent_id + AND studiensemester_kurzbz = prestatus.studiensemester_kurzbz + ) + AND abschlussbeurteilung_kurzbz!='nicht' + AND abschlussbeurteilung_kurzbz IS NOT NULL + AND (pruefung.datum IS NULL OR pruefung.sponsion IS NULL) + AND pre.bismelden + AND stg.melderelevant"; + + if (isset($studiensemester_kurzbz)) + { + $qry .= " AND prestatus.studiensemester_kurzbz = ?"; + $params[] = $studiensemester_kurzbz; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($abschlusspruefung_id)) + { + $qry .= " AND pruefung.abschlusspruefung_id = ?"; + $params[] = $abschlusspruefung_id; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } + + /** + * Gets Bismeldedate from Studiensemester. + * @param studiensemester_kurzbz string + */ + private function _getBisdateFromSemester($studiensemester_kurzbz) + { + $semesterYear = substr($studiensemester_kurzbz, 2, 6); + $semesterType = substr($studiensemester_kurzbz, 0, 2); + + if ($semesterType == 'SS') + { + return date_format(date_create(($semesterYear - 1)."-11-15"), 'Y-m-d'); + } + + if ($semesterType == 'WS') + { + return date_format(date_create($semesterYear."-04-15"), 'Y-m-d'); + } + } +} diff --git a/application/libraries/issues/PlausicheckProducerLib.php b/application/libraries/issues/PlausicheckProducerLib.php new file mode 100644 index 000000000..dde9b5396 --- /dev/null +++ b/application/libraries/issues/PlausicheckProducerLib.php @@ -0,0 +1,103 @@ + class (library) name for resolving + private $_fehlerLibMappings = array( + 'AbbrecherAktiv' => 'AbbrecherAktiv', + 'AbschlussstatusFehlt' => 'AbschlussstatusFehlt', + 'AktSemesterNull' => 'AktSemesterNull', + 'AktiverStudentOhneStatus' => 'AktiverStudentOhneStatus', + 'AktiverStudentstatusOhneKontobuchung' => 'AktiverStudentstatusOhneKontobuchung', + 'AusbildungssemPrestudentUngleichAusbildungssemStatus' => 'AusbildungssemPrestudentUngleichAusbildungssemStatus', + 'BewerberNichtZumRtAngetreten' => 'BewerberNichtZumRtAngetreten', + 'DatumAbschlusspruefungFehlt' => 'DatumAbschlusspruefungFehlt', + 'DatumSponsionFehlt' => 'DatumSponsionFehlt', + 'DatumStudiensemesterFalscheReihenfolge' => 'DatumStudiensemesterFalscheReihenfolge', + 'FalscheAnzahlAbschlusspruefungen' => 'FalscheAnzahlAbschlusspruefungen', + 'FalscheAnzahlHeimatadressen' => 'FalscheAnzahlHeimatadressen', + 'FalscheAnzahlZustelladressen' => 'FalscheAnzahlZustelladressen', + 'GbDatumWeitZurueck' => 'GbDatumWeitZurueck', + 'InaktiverStudentAktiverStatus' => 'InaktiverStudentAktiverStatus', + 'IncomingHeimatNationOesterreich' => 'IncomingHeimatNationOesterreich', + 'IncomingOhneIoDatensatz' => 'IncomingOhneIoDatensatz', + 'IncomingOrGsFoerderrelevant' => 'IncomingOrGsFoerderrelevant', + 'InskriptionVorLetzerBismeldung' => 'InskriptionVorLetzerBismeldung', + 'NationNichtOesterreichAberGemeinde' => 'NationNichtOesterreichAberGemeinde', + 'OrgformStgUngleichOrgformPrestudent' => 'OrgformStgUngleichOrgformPrestudent', + 'PrestudentMischformOhneOrgform' => 'PrestudentMischformOhneOrgform', + 'StgPrestudentUngleichStgStudienplan' => 'StgPrestudentUngleichStgStudienplan', + 'StgPrestudentUngleichStgStudent' => 'StgPrestudentUngleichStgStudent', + 'StudentstatusNachAbbrecher' => 'StudentstatusNachAbbrecher' + //'StudienplanUngueltig' => 'StudienplanUngueltig' + ); + + public function __construct() + { + $this->_ci =& get_instance(); // get ci instance + + // load models + $this->_ci->load->model('organisation/studiensemester_model', 'StudiensemesterModel'); + + // get current Studiensemester + $studiensemesterRes = $this->_ci->StudiensemesterModel->getAkt(); + if (hasData($studiensemesterRes)) $this->_currentStudiensemester = getData($studiensemesterRes)[0]->studiensemester_kurzbz; + } + + /** + * Executes check for a fehler_kurzbz, returns the result. + * @param $fehler_kurzbz string + * @param $studiensemester_kurzbz string optionally needed for issue production + * @param $studiengang_kz int optionally needed for issue production + */ + public function producePlausicheckIssue($fehler_kurzbz, $studiensemester_kurzbz = null, $studiengang_kz = null) + { + $libName = $this->_fehlerLibMappings[$fehler_kurzbz]; + + // get Studiensemester + if (isEmptyString($studiensemester_kurzbz)) $studiensemester_kurzbz = $this->_currentStudiensemester; + + // get path of library for issue to be produced + $issuesLibPath = DOC_ROOT . self::CI_LIBRARY_PATH . '/' . self::PLAUSI_ISSUES_FOLDER . '/'; + $issuesLibFilePath = $issuesLibPath . $libName . '.php'; + + // check if library file exists + if (!file_exists($issuesLibFilePath)) return error("Issue library file " . $issuesLibFilePath . " does not exist"); + + // load library connected to fehlercode + $this->_ci->load->library(self::PLAUSI_ISSUES_FOLDER . '/'.$libName); + + $lowercaseLibName = mb_strtolower($libName); + + // check if method is defined in library class + if (!is_callable(array($this->_ci->{$lowercaseLibName}, self::EXECUTE_PLAUSI_CHECK_METHOD_NAME))) + return error("Method " . self::EXECUTE_PLAUSI_CHECK_METHOD_NAME . " is not defined in library $lowercaseLibName"); + + // pass the data needed for issue check + $paramsForCheck = array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiengang_kz' => $studiengang_kz + ); + + // call the function for checking for issue production + return $this->_ci->{$lowercaseLibName}->{self::EXECUTE_PLAUSI_CHECK_METHOD_NAME}($paramsForCheck); + } + + /** + * Gets all fehler_kurzbz for fehler which need to be checked. + */ + public function getFehlerKurzbz() + { + return array_keys($this->_fehlerLibMappings); + } +} diff --git a/application/libraries/issues/plausichecks/AbbrecherAktiv.php b/application/libraries/issues/plausichecks/AbbrecherAktiv.php new file mode 100644 index 000000000..cc6e2996a --- /dev/null +++ b/application/libraries/issues/plausichecks/AbbrecherAktiv.php @@ -0,0 +1,43 @@ +_ci->plausichecklib->getAbbrecherAktiv($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php b/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php new file mode 100644 index 000000000..66615220a --- /dev/null +++ b/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php @@ -0,0 +1,44 @@ +_ci->plausichecklib->getAbschlussstatusFehlt($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/AktSemesterNull.php b/application/libraries/issues/plausichecks/AktSemesterNull.php new file mode 100644 index 000000000..d55506d68 --- /dev/null +++ b/application/libraries/issues/plausichecks/AktSemesterNull.php @@ -0,0 +1,50 @@ +_ci->plausichecklib->getAktSemesterNull($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/AktiverStudentOhneStatus.php b/application/libraries/issues/plausichecks/AktiverStudentOhneStatus.php new file mode 100644 index 000000000..2dfd9f866 --- /dev/null +++ b/application/libraries/issues/plausichecks/AktiverStudentOhneStatus.php @@ -0,0 +1,43 @@ +_ci->plausichecklib->getAktiverStudentOhneStatus($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/AktiverStudentstatusOhneKontobuchung.php b/application/libraries/issues/plausichecks/AktiverStudentstatusOhneKontobuchung.php new file mode 100644 index 000000000..baa35bc57 --- /dev/null +++ b/application/libraries/issues/plausichecks/AktiverStudentstatusOhneKontobuchung.php @@ -0,0 +1,50 @@ +_ci->plausichecklib->getAktiverStudentstatusOhneKontobuchung($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/AusbildungssemPrestudentUngleichAusbildungssemStatus.php b/application/libraries/issues/plausichecks/AusbildungssemPrestudentUngleichAusbildungssemStatus.php new file mode 100644 index 000000000..ca967a97f --- /dev/null +++ b/application/libraries/issues/plausichecks/AusbildungssemPrestudentUngleichAusbildungssemStatus.php @@ -0,0 +1,56 @@ +_ci->plausichecklib->getAusbildungssemPrestudentUngleichAusbildungssemStatus( + $studiensemester_kurzbz, + $studiengang_kz + ); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'status_ausbildungssemester' => $prestudent->status_ausbildungssemester, + 'student_ausbildungssemester' => $prestudent->student_ausbildungssemester, + 'student_uid' => $prestudent->student_uid, + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/BewerberNichtZumRtAngetreten.php b/application/libraries/issues/plausichecks/BewerberNichtZumRtAngetreten.php new file mode 100644 index 000000000..35d954236 --- /dev/null +++ b/application/libraries/issues/plausichecks/BewerberNichtZumRtAngetreten.php @@ -0,0 +1,47 @@ +_ci->plausichecklib->getBewerberNichtZumRtAngetreten($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array( + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz, + 'prestudent_id' => $prestudent->prestudent_id + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/DatumAbschlusspruefungFehlt.php b/application/libraries/issues/plausichecks/DatumAbschlusspruefungFehlt.php new file mode 100644 index 000000000..7a2555b69 --- /dev/null +++ b/application/libraries/issues/plausichecks/DatumAbschlusspruefungFehlt.php @@ -0,0 +1,47 @@ +_ci->plausichecklib->getDatumAbschlusspruefungFehlt($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'abschlusspruefung_id' => $prestudent->abschlusspruefung_id + ), + 'resolution_params' => array('abschlusspruefung_id' => $prestudent->abschlusspruefung_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/DatumSponsionFehlt.php b/application/libraries/issues/plausichecks/DatumSponsionFehlt.php new file mode 100644 index 000000000..102a89656 --- /dev/null +++ b/application/libraries/issues/plausichecks/DatumSponsionFehlt.php @@ -0,0 +1,47 @@ +_ci->plausichecklib->getDatumSponsionFehlt($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'abschlusspruefung_id' => $prestudent->abschlusspruefung_id + ), + 'resolution_params' => array('abschlusspruefung_id' => $prestudent->abschlusspruefung_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/DatumStudiensemesterFalscheReihenfolge.php b/application/libraries/issues/plausichecks/DatumStudiensemesterFalscheReihenfolge.php new file mode 100644 index 000000000..ab8566e47 --- /dev/null +++ b/application/libraries/issues/plausichecks/DatumStudiensemesterFalscheReihenfolge.php @@ -0,0 +1,45 @@ +_ci->plausichecklib->getDatumStudiensemesterFalscheReihenfolge($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/FalscheAnzahlAbschlusspruefungen.php b/application/libraries/issues/plausichecks/FalscheAnzahlAbschlusspruefungen.php new file mode 100644 index 000000000..7fbe2d828 --- /dev/null +++ b/application/libraries/issues/plausichecks/FalscheAnzahlAbschlusspruefungen.php @@ -0,0 +1,44 @@ +_ci->plausichecklib->getFalscheAnzahlAbschlusspruefungen($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/FalscheAnzahlHeimatadressen.php b/application/libraries/issues/plausichecks/FalscheAnzahlHeimatadressen.php new file mode 100644 index 000000000..eac50a88a --- /dev/null +++ b/application/libraries/issues/plausichecks/FalscheAnzahlHeimatadressen.php @@ -0,0 +1,42 @@ +_ci->plausichecklib->getFalscheAnzahlHeimatadressen($studiensemester_kurzbz, $studiengang_kz); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $persons = getData($personRes); + + // populate results with data necessary for writing issues + foreach ($persons as $person) + { + $results[] = array( + 'person_id' => $person->person_id, + 'resolution_params' => array('person_id' => $person->person_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/FalscheAnzahlZustelladressen.php b/application/libraries/issues/plausichecks/FalscheAnzahlZustelladressen.php new file mode 100644 index 000000000..e2fc4a781 --- /dev/null +++ b/application/libraries/issues/plausichecks/FalscheAnzahlZustelladressen.php @@ -0,0 +1,42 @@ +_ci->plausichecklib->getFalscheAnzahlZustelladressen($studiensemester_kurzbz, $studiengang_kz); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $persons = getData($personRes); + + // populate results with data necessary for writing issues + foreach ($persons as $person) + { + $results[] = array( + 'person_id' => $person->person_id, + 'resolution_params' => array('person_id' => $person->person_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php b/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php new file mode 100644 index 000000000..7a7cf0d6f --- /dev/null +++ b/application/libraries/issues/plausichecks/GbDatumWeitZurueck.php @@ -0,0 +1,42 @@ +_ci->plausichecklib->getGbDatumWeitZurueck($studiensemester_kurzbz, $studiengang_kz); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $persons = getData($personRes); + + // populate results with data necessary for writing issues + foreach ($persons as $person) + { + $results[] = array( + 'person_id' => $person->person_id, + 'resolution_params' => array('person_id' => $person->person_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/InaktiverStudentAktiverStatus.php b/application/libraries/issues/plausichecks/InaktiverStudentAktiverStatus.php new file mode 100644 index 000000000..76fd477e3 --- /dev/null +++ b/application/libraries/issues/plausichecks/InaktiverStudentAktiverStatus.php @@ -0,0 +1,47 @@ +_ci->plausichecklib->getInaktiverStudentAktiverStatus($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/IncomingHeimatNationOesterreich.php b/application/libraries/issues/plausichecks/IncomingHeimatNationOesterreich.php new file mode 100644 index 000000000..51726d969 --- /dev/null +++ b/application/libraries/issues/plausichecks/IncomingHeimatNationOesterreich.php @@ -0,0 +1,42 @@ +_ci->plausichecklib->getIncomingHeimatNationOesterreich($studiensemester_kurzbz, $studiengang_kz); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $persons = getData($personRes); + + // populate results with data necessary for writing issues + foreach ($persons as $person) + { + $results[] = array( + 'person_id' => $person->person_id, + 'resolution_params' => array('person_id' => $person->person_id, 'studiensemester_kurzbz' => $studiensemester_kurzbz) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/IncomingOhneIoDatensatz.php b/application/libraries/issues/plausichecks/IncomingOhneIoDatensatz.php new file mode 100644 index 000000000..9681554e5 --- /dev/null +++ b/application/libraries/issues/plausichecks/IncomingOhneIoDatensatz.php @@ -0,0 +1,43 @@ +_ci->plausichecklib->getIncomingOhneIoDatensatz($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/IncomingOrGsFoerderrelevant.php b/application/libraries/issues/plausichecks/IncomingOrGsFoerderrelevant.php new file mode 100644 index 000000000..0e12ccac8 --- /dev/null +++ b/application/libraries/issues/plausichecks/IncomingOrGsFoerderrelevant.php @@ -0,0 +1,44 @@ +_ci->plausichecklib->getIncomingOrGsFoerderrelevant($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/InskriptionVorLetzerBismeldung.php b/application/libraries/issues/plausichecks/InskriptionVorLetzerBismeldung.php new file mode 100644 index 000000000..672dfa585 --- /dev/null +++ b/application/libraries/issues/plausichecks/InskriptionVorLetzerBismeldung.php @@ -0,0 +1,51 @@ +_ci->plausichecklib->getInskriptionVorLetzerBismeldung($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'datum_bismeldung' => date_format(date_create($prestudent->datum_bismeldung), 'd.m.Y'), + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/NationNichtOesterreichAberGemeinde.php b/application/libraries/issues/plausichecks/NationNichtOesterreichAberGemeinde.php new file mode 100644 index 000000000..c61531e46 --- /dev/null +++ b/application/libraries/issues/plausichecks/NationNichtOesterreichAberGemeinde.php @@ -0,0 +1,42 @@ +_ci->plausichecklib->getNationNichtOesterreichAberGemeinde($studiengang_kz); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $persons = getData($personRes); + + // populate results with data necessary for writing issues + foreach ($persons as $person) + { + $results[] = array( + 'person_id' => $person->person_id, + 'fehlertext_params' => array('gemeinde' => $person->gemeinde, 'adresse_id' => $person->adresse_id), + 'resolution_params' => array('adresse_id' => $person->adresse_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/OrgformStgUngleichOrgformPrestudent.php b/application/libraries/issues/plausichecks/OrgformStgUngleichOrgformPrestudent.php new file mode 100644 index 000000000..b7ef64c41 --- /dev/null +++ b/application/libraries/issues/plausichecks/OrgformStgUngleichOrgformPrestudent.php @@ -0,0 +1,52 @@ +_ci->plausichecklib->getOrgformStgUngleichOrgformPrestudent($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'student_studiengang' => $prestudent->student_studiengang, + 'student_orgform' => $prestudent->student_orgform, + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/PlausiChecker.php b/application/libraries/issues/plausichecks/PlausiChecker.php new file mode 100644 index 000000000..bfa72b5e0 --- /dev/null +++ b/application/libraries/issues/plausichecks/PlausiChecker.php @@ -0,0 +1,24 @@ +_ci =& get_instance(); // get code igniter instance + + // load libraries + $this->_ci->load->library('issues/PlausicheckLib'); // load plausicheck library + } + + /** + * Executes a plausi check. + * @param $paramsForChecking array parameters needed for executing the check + * @return array with objects which failed the plausi check + */ + abstract public function executePlausiCheck($paramsForChecking); +} diff --git a/application/libraries/issues/plausichecks/PrestudentMischformOhneOrgform.php b/application/libraries/issues/plausichecks/PrestudentMischformOhneOrgform.php new file mode 100644 index 000000000..369085089 --- /dev/null +++ b/application/libraries/issues/plausichecks/PrestudentMischformOhneOrgform.php @@ -0,0 +1,50 @@ +_ci->plausichecklib->getPrestudentMischformOhneOrgform($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudent.php b/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudent.php new file mode 100644 index 000000000..4eb25ed11 --- /dev/null +++ b/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudent.php @@ -0,0 +1,43 @@ +_ci->plausichecklib->getStgPrestudentUngleichStgStudent($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudienplan.php b/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudienplan.php new file mode 100644 index 000000000..7175725fd --- /dev/null +++ b/application/libraries/issues/plausichecks/StgPrestudentUngleichStgStudienplan.php @@ -0,0 +1,43 @@ +_ci->plausichecklib->getStgPrestudentUngleichStgStudienplan($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id, 'studienplan' => $prestudent->studienplan), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id, 'studienordnung_id' => $prestudent->studienordnung_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/StudentstatusNachAbbrecher.php b/application/libraries/issues/plausichecks/StudentstatusNachAbbrecher.php new file mode 100644 index 000000000..12a7516ef --- /dev/null +++ b/application/libraries/issues/plausichecks/StudentstatusNachAbbrecher.php @@ -0,0 +1,43 @@ +_ci->plausichecklib->getStudentstatusNachAbbrecher($studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array('prestudent_id' => $prestudent->prestudent_id), + 'resolution_params' => array('prestudent_id' => $prestudent->prestudent_id) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/plausichecks/StudienplanUngueltig.php b/application/libraries/issues/plausichecks/StudienplanUngueltig.php new file mode 100644 index 000000000..6b8fe49aa --- /dev/null +++ b/application/libraries/issues/plausichecks/StudienplanUngueltig.php @@ -0,0 +1,51 @@ +_ci->plausichecklib->getStudienplanUngueltig($studiensemester_kurzbz, $studiengang_kz); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'studienplan' => $prestudent->studienplan, + 'ausbildungssemester' => $prestudent->ausbildungssemester, + 'prestudent_id' => $prestudent->prestudent_id + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } +} diff --git a/application/libraries/issues/CORE_INOUT_0001.php b/application/libraries/issues/resolvers/CORE_INOUT_0001.php similarity index 100% rename from application/libraries/issues/CORE_INOUT_0001.php rename to application/libraries/issues/resolvers/CORE_INOUT_0001.php diff --git a/application/libraries/issues/CORE_INOUT_0002.php b/application/libraries/issues/resolvers/CORE_INOUT_0002.php similarity index 100% rename from application/libraries/issues/CORE_INOUT_0002.php rename to application/libraries/issues/resolvers/CORE_INOUT_0002.php diff --git a/application/libraries/issues/CORE_INOUT_0003.php b/application/libraries/issues/resolvers/CORE_INOUT_0003.php similarity index 100% rename from application/libraries/issues/CORE_INOUT_0003.php rename to application/libraries/issues/resolvers/CORE_INOUT_0003.php diff --git a/application/libraries/issues/CORE_INOUT_0004.php b/application/libraries/issues/resolvers/CORE_INOUT_0004.php similarity index 100% rename from application/libraries/issues/CORE_INOUT_0004.php rename to application/libraries/issues/resolvers/CORE_INOUT_0004.php diff --git a/application/libraries/issues/CORE_INOUT_0005.php b/application/libraries/issues/resolvers/CORE_INOUT_0005.php similarity index 100% rename from application/libraries/issues/CORE_INOUT_0005.php rename to application/libraries/issues/resolvers/CORE_INOUT_0005.php diff --git a/application/libraries/issues/CORE_INOUT_0006.php b/application/libraries/issues/resolvers/CORE_INOUT_0006.php similarity index 93% rename from application/libraries/issues/CORE_INOUT_0006.php rename to application/libraries/issues/resolvers/CORE_INOUT_0006.php index a447a9625..6894c9878 100644 --- a/application/libraries/issues/CORE_INOUT_0006.php +++ b/application/libraries/issues/resolvers/CORE_INOUT_0006.php @@ -15,7 +15,6 @@ class CORE_INOUT_0006 implements IIssueResolvedChecker $this->_ci =& get_instance(); // get code igniter instance $this->_ci->load->model('codex/Bisio_model', 'BisioModel'); - //$this->_ci->load->model('codex/Aufenthaltfoerderung_model', 'AufenthaltfoerderungModel'); // get all Zwecke $this->_ci->BisioModel->addSelect('ects_erworben'); diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0007.php b/application/libraries/issues/resolvers/CORE_INOUT_0007.php new file mode 100644 index 000000000..2d9c7a3f4 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_INOUT_0007.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getIncomingHeimatNationOesterreich($params['studiensemester_kurzbz'], null, $params['issue_person_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0008.php b/application/libraries/issues/resolvers/CORE_INOUT_0008.php new file mode 100644 index 000000000..afa43893a --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_INOUT_0008.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getIncomingOhneIoDatensatz(null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_INOUT_0009.php b/application/libraries/issues/resolvers/CORE_INOUT_0009.php new file mode 100644 index 000000000..b56344042 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_INOUT_0009.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getIncomingOrGsFoerderrelevant(null, null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0001.php b/application/libraries/issues/resolvers/CORE_PERSON_0001.php new file mode 100644 index 000000000..bd94fea59 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_PERSON_0001.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getGbDatumWeitZurueck(null, null, $params['issue_person_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0002.php b/application/libraries/issues/resolvers/CORE_PERSON_0002.php new file mode 100644 index 000000000..d1bb2fe94 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_PERSON_0002.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getNationNichtOesterreichAberGemeinde(null, $params['issue_person_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0003.php b/application/libraries/issues/resolvers/CORE_PERSON_0003.php new file mode 100644 index 000000000..08fea6c05 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_PERSON_0003.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getFalscheAnzahlHeimatadressen(null, null, $params['issue_person_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_PERSON_0004.php b/application/libraries/issues/resolvers/CORE_PERSON_0004.php new file mode 100644 index 000000000..bfe243fd1 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_PERSON_0004.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getFalscheAnzahlZustelladressen(null, null, $params['issue_person_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STG_0001.php b/application/libraries/issues/resolvers/CORE_STG_0001.php new file mode 100644 index 000000000..97cef6056 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STG_0001.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getStgPrestudentUngleichStgStudent(null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STG_0002.php b/application/libraries/issues/resolvers/CORE_STG_0002.php new file mode 100644 index 000000000..fe414de38 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STG_0002.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getOrgformStgUngleichOrgformPrestudent($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STG_0003.php b/application/libraries/issues/resolvers/CORE_STG_0003.php new file mode 100644 index 000000000..33cb0846b --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STG_0003.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getPrestudentMischformOhneOrgform($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STG_0004.php b/application/libraries/issues/resolvers/CORE_STG_0004.php new file mode 100644 index 000000000..02d45bbd3 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STG_0004.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getStgPrestudentUngleichStgStudienplan(null, $params['prestudent_id'], $params['studienordnung_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0001.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0001.php new file mode 100644 index 000000000..78c49810b --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0001.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getAbbrecherAktiv(null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0002.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0002.php new file mode 100644 index 000000000..23943397a --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0002.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getStudentstatusNachAbbrecher(null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0003.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0003.php new file mode 100644 index 000000000..6ac243b4f --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0003.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getAusbildungssemPrestudentUngleichAusbildungssemStatus($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0004.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0004.php new file mode 100644 index 000000000..d76215b6a --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0004.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getInaktiverStudentAktiverStatus($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0005.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0005.php new file mode 100644 index 000000000..7f7ca4723 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0005.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getInskriptionVorLetzerBismeldung($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0006.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0006.php new file mode 100644 index 000000000..ba1e5b715 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0006.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getDatumStudiensemesterFalscheReihenfolge(null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0007.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0007.php new file mode 100644 index 000000000..1dd8fdcb2 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0007.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getAktiverStudentOhneStatus(null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0008.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0008.php new file mode 100644 index 000000000..83357d9bf --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0008.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getStudienplanUngueltig($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0009.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0009.php new file mode 100644 index 000000000..b1b5e9876 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0009.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getFalscheAnzahlAbschlusspruefungen(null, null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0010.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0010.php new file mode 100644 index 000000000..1e3a6849b --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0010.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getDatumAbschlusspruefungFehlt(null, null, $params['abschlusspruefung_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0011.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0011.php new file mode 100644 index 000000000..233240305 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0011.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getDatumSponsionFehlt(null, null, $params['abschlusspruefung_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0012.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0012.php new file mode 100644 index 000000000..38832edc0 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0012.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getBewerberNichtZumRtAngetreten($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0013.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0013.php new file mode 100644 index 000000000..78ad40a8e --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0013.php @@ -0,0 +1,32 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getAktSemesterNull($params['studiensemester_kurzbz'], null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0014.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0014.php new file mode 100644 index 000000000..8d96b7c65 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0014.php @@ -0,0 +1,29 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getAbschlussstatusFehlt(null, null, $params['prestudent_id']); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0015.php b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0015.php new file mode 100644 index 000000000..aafee1124 --- /dev/null +++ b/application/libraries/issues/resolvers/CORE_STUDENTSTATUS_0015.php @@ -0,0 +1,36 @@ +_ci =& get_instance(); // get code igniter instance + + $this->_ci->load->library('issues/PlausicheckLib'); + + // check if issue persists + $checkRes = $this->_ci->plausichecklib->getAktiverStudentstatusOhneKontobuchung( + $params['studiensemester_kurzbz'], + null, + $params['prestudent_id'] + ); + + if (isError($checkRes)) return $checkRes; + + if (hasData($checkRes)) + return success(false); // not resolved if issue is still present + else + return success(true); // resolved otherwise + } +} diff --git a/application/libraries/issues/CORE_ZGV_0001.php b/application/libraries/issues/resolvers/CORE_ZGV_0001.php similarity index 100% rename from application/libraries/issues/CORE_ZGV_0001.php rename to application/libraries/issues/resolvers/CORE_ZGV_0001.php diff --git a/application/libraries/issues/CORE_ZGV_0002.php b/application/libraries/issues/resolvers/CORE_ZGV_0002.php similarity index 100% rename from application/libraries/issues/CORE_ZGV_0002.php rename to application/libraries/issues/resolvers/CORE_ZGV_0002.php diff --git a/application/libraries/issues/CORE_ZGV_0003.php b/application/libraries/issues/resolvers/CORE_ZGV_0003.php similarity index 100% rename from application/libraries/issues/CORE_ZGV_0003.php rename to application/libraries/issues/resolvers/CORE_ZGV_0003.php diff --git a/application/libraries/issues/CORE_ZGV_0004.php b/application/libraries/issues/resolvers/CORE_ZGV_0004.php similarity index 100% rename from application/libraries/issues/CORE_ZGV_0004.php rename to application/libraries/issues/resolvers/CORE_ZGV_0004.php diff --git a/application/libraries/issues/CORE_ZGV_0005.php b/application/libraries/issues/resolvers/CORE_ZGV_0005.php similarity index 100% rename from application/libraries/issues/CORE_ZGV_0005.php rename to application/libraries/issues/resolvers/CORE_ZGV_0005.php diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index 4975af382..04192a7b4 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -128,8 +128,8 @@ class Messages_model extends CI_Model { $ouOptions .= sprintf( "\n".'', - is_numeric($ou->prestudent_id) ? $ou->oe_kurzbz : self::ALT_OE, - $ou->bezeichnung . (is_numeric($ou->prestudent_id) ? '' : ' *') + ($ou->typ === 'l' ? $ou->oe_kurzbz : (is_numeric($ou->prestudent_id) ? $ou->oe_kurzbz : self::ALT_OE)), + $ou->bezeichnung . ((is_numeric($ou->prestudent_id) || $ou->typ === 'l' ) ? '' : ' *') ); } } @@ -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/accounting/Vertragvertragsstatus_model.php b/application/models/accounting/Vertragvertragsstatus_model.php index 609394321..78a065540 100644 --- a/application/models/accounting/Vertragvertragsstatus_model.php +++ b/application/models/accounting/Vertragvertragsstatus_model.php @@ -135,7 +135,7 @@ class Vertragvertragsstatus_model extends DB_Model /** * Get all contracts, where the status had been set to 'bestellt' on given date - * @param string $string_date e.g. '01.11.2019' or special Date/Time inputs like 'YESTERDAY', 'TODAY', 'NOW' + * @param string $string_date e.g. 'YYYY-MM-DD' or special Date/Time inputs like 'YESTERDAY', 'TODAY', 'NOW' * @param bool $further_processed If true, ALL ordered contracts of that day are retrieved, even if they were * were ALSO approved/accepted/cancelled (further processed) on that same day. * @return array 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/content/DmsFS_model.php b/application/models/content/DmsFS_model.php index 38a72d853..81443805f 100644 --- a/application/models/content/DmsFS_model.php +++ b/application/models/content/DmsFS_model.php @@ -7,7 +7,7 @@ class DmsFS_model extends FS_Model */ public function __construct() { - parent::__construct(); - $this->filepath = DMS_PATH; + parent::__construct(DMS_PATH); } -} \ No newline at end of file +} + diff --git a/application/models/content/TempFS_model.php b/application/models/content/TempFS_model.php new file mode 100644 index 000000000..ac55a24d7 --- /dev/null +++ b/application/models/content/TempFS_model.php @@ -0,0 +1,16 @@ +addSelect('public.tbl_akte.*, bezeichnung_mehrsprachig, dokumentbeschreibung_mehrsprachig, public.tbl_dokument.bezeichnung as dokument_bezeichnung, bis.tbl_nation.*, ausstellungsdetails'); $this->addJoin('public.tbl_dokument', 'dokument_kurzbz'); @@ -184,6 +184,9 @@ class Akte_model extends DB_Model if(is_bool($nachgereicht)) $where['nachgereicht'] = $nachgereicht; + if (is_bool($archiv)) + $where['archiv'] = $archiv; + $dokumente = $this->loadWhere($where); if($dokumente->error) return $dokumente; 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..7b24b8769 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -309,13 +309,39 @@ class Prestudent_model extends DB_Model */ public function getLastPrestudent($person_id, $withzgv = false) { - $qry = 'SELECT * FROM public.tbl_prestudent - WHERE person_id = ? + $qry = 'SELECT * FROM public.tbl_prestudent ps %s + WHERE ps.person_id = ? ORDER BY updateamum DESC NULLS LAST, insertamum DESC NULLS LAST LIMIT 1'; - $zgvwhere = $withzgv === true ? 'AND zgv_code IS NOT NULL' : ''; + $zgvwhere = ''; + if ($withzgv === true) + { + $zgvwhere = ' + LEFT JOIN ( + SELECT ps2.zgvmas_code, + ps2.zgvmanation, + ps2.zgvmadatum, + ps2.zgvmaort, + ps2.zgvmas_erfuellt, + ps2.person_id + FROM tbl_prestudent ps2 + WHERE zgvmas_code IS NOT NULL + ORDER BY updateamum DESC NULLS LAST, insertamum DESC NULLS LAST + ) zgvmas ON zgvmas.person_id = ps.person_id + LEFT JOIN ( + SELECT ps2.zgv_code, + ps2.zgvnation, + ps2.zgvdatum, + ps2.zgvort, + ps2.zgv_erfuellt, + ps2.person_id + FROM tbl_prestudent ps2 + WHERE zgv_code IS NOT NULL + ORDER BY updateamum DESC NULLS LAST, insertamum DESC NULLS LAST + )zgv ON zgv.person_id = ps.person_id'; + } $qry = sprintf($qry, $zgvwhere); @@ -556,13 +582,14 @@ 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 - WHEN sg.typ = \'m\' THEN ps.prestudent_id + WHEN sg.typ = \'m\' THEN mps.prestudent_id ELSE NULL - END) AS prestudent_id + END) AS prestudent_id, + sg.typ FROM public.tbl_prestudent p JOIN public.tbl_studiengang sg USING(studiengang_kz) JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) @@ -571,11 +598,17 @@ class Prestudent_model extends DB_Model FROM public.tbl_prestudentstatus WHERE status_kurzbz = \'Bewerber\' ) ps USING(prestudent_id) + LEFT JOIN ( + SELECT prestudent_id + FROM public.tbl_prestudentstatus + WHERE status_kurzbz = \'Interessent\' AND bestaetigtam IS NOT NULL + ) mps ON p.prestudent_id = mps.prestudent_id WHERE p.person_id = ? GROUP BY o.oe_kurzbz, o.bezeichnung, sg.typ, ps.prestudent_id, + mps.prestudent_id, p.prestudent_id ORDER BY o.bezeichnung'; diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index 3335de021..f39a41fda 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -52,6 +52,24 @@ class Prestudentstatus_model extends DB_Model return $this->execQuery($query, $parametersArray); } + /** + * Liefert den Ersten Status eines Prestudenten mit der übergebenen Statuskurzbezeichnung. + * + * @param $prestudent_id + * @param $status_kurzbz + * @return array + */ + public function getFirstStatus($prestudent_id, $status_kurzbz) + { + $this->addOrder('datum, insertamum, ext_id'); + $this->addLimit(1); + + return $this->loadWhere(array( + 'prestudent_id' => $prestudent_id, + 'status_kurzbz' => $status_kurzbz + )); + } + /** * updateStufe */ diff --git a/application/models/crm/Student_model.php b/application/models/crm/Student_model.php index 4d1c84521..4404beb54 100644 --- a/application/models/crm/Student_model.php +++ b/application/models/crm/Student_model.php @@ -66,4 +66,20 @@ class Student_model extends DB_Model return $result->retval[0]->student_uid; } + + public function searchStudent($filter) + { + $this->addSelect('vorname, nachname, gebdatum, person.person_id, student_uid'); + $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); + $this->addJoin('public.tbl_person person', 'person_id'); + + $result = $this->loadWhere( + "lower(student_uid) like ".$this->db->escape('%'.$filter.'%')." + OR lower(person.nachname) like ".$this->db->escape('%'.$filter.'%')." + OR lower(person.vorname) like ".$this->db->escape('%'.$filter.'%')." + OR lower(person.nachname || ' ' || person.vorname) like ".$this->db->escape('%'.$filter.'%')." + OR lower(person.vorname || ' ' || person.nachname) like ".$this->db->escape('%'.$filter.'%')); + + return $result; + } } diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 8517d7f9d..f54443955 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -309,4 +309,166 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($query, array($uid, $studiensemester_kurzbz, $lehrveranstaltung_id)); } + + /** + * Sucht nach LV Templates und gibt Id und Label ("bezeichnung [kurzbz]") aus + * Diese funktion ist für autocomplete gedacht + * + * @param string $filter Suchfilter + * @return \stdClass A return object + */ + public function loadTemplates($filter) + { + $filter = strtolower($filter); + $qry = "SELECT + tbl_lehrveranstaltung.lehrveranstaltung_id, tbl_lehrveranstaltung.bezeichnung, tbl_lehrveranstaltung.kurzbz + FROM + lehre.tbl_lehrveranstaltung + WHERE + tbl_lehrveranstaltung.lehrtyp_kurzbz = 'tpl' AND ( + CAST(tbl_lehrveranstaltung.lehrveranstaltung_id AS TEXT) LIKE '%".$this->db_escape($filter)."%' OR + LOWER(tbl_lehrveranstaltung.bezeichnung) LIKE '%".$this->db_escape($filter). "%' OR + LOWER(tbl_lehrveranstaltung.kurzbz) LIKE '%".$this->db_escape($filter). "%' + ) + "; + return $this->execQuery($qry); + } + + /** + * Lädt Template und gibt Id und Label ("bezeichnung [kurzbz]") zurück + * Diese funktion ist für autocomplete gedacht + * + * @param string $name + * @return \stdClass A return object + */ + public function loadTemplateByName($name) + { + $qry = "SELECT + tbl_lehrveranstaltung.lehrveranstaltung_id as id, CONCAT(tbl_lehrveranstaltung.bezeichnung, ' [', tbl_lehrveranstaltung.kurzbz, ']') as label + FROM + lehre.tbl_lehrveranstaltung + WHERE + tbl_lehrveranstaltung.lehrtyp_kurzbz = 'tpl' AND ( + CAST(tbl_lehrveranstaltung.lehrveranstaltung_id AS TEXT) = '".($name ? $this->db_escape($name) : 0)."' OR tbl_lehrveranstaltung.bezeichnung = '".$this->db_escape($name). "' OR tbl_lehrveranstaltung.kurzbz = '".$this->db_escape($name). "' + ) + "; + return $this->execQuery($qry); + } + + + /** + * Get ECTS Summe pro angerechnetes Quereinstiegssemester. + * + * @param $studiengang_kz + * @param $studiensemester_kurzbz + * @param $ausbildungssemester + * @param $orgform_kurzbz + * @return array|stdClass|null + */ + public function getSumQuereinstiegsECTSProSemester($studiengang_kz, $studiensemester_kurzbz, $ausbildungssemester, $orgform_kurzbz) + { + $qry = ' + SELECT + sum(tbl_lehrveranstaltung.ects) as "sum_ects" + FROM + lehre.tbl_studienplan + JOIN lehre.tbl_studienplan_lehrveranstaltung USING (studienplan_id) + JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) + WHERE + tbl_studienplan.studienplan_id = ( + SELECT + studienplan_id + FROM + lehre.tbl_studienordnung + JOIN lehre.tbl_studienplan USING (studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING (studienplan_id) + WHERE tbl_studienordnung.studiengang_kz = ? + AND tbl_studienplan_semester.semester = ? + AND tbl_studienplan_semester.studiensemester_kurzbz = ? + AND tbl_studienplan.orgform_kurzbz = ? + + LIMIT 1 + ) + AND tbl_studienplan_lehrveranstaltung.semester = ? + AND studienplan_lehrveranstaltung_id_parent IS NULL -- auf Modulebene + AND tbl_studienplan_lehrveranstaltung.export = TRUE + '; + + return $this->execQuery($qry, array( + $studiengang_kz, $ausbildungssemester, $studiensemester_kurzbz, $orgform_kurzbz, $ausbildungssemester) + ); + } + + /** + * Get ECTS Summe aller bisher angerechneten LVs. + * Wenn keine explizite Begruendung angegeben ist, wird eine schulische Begruendung angenommen. + * + * @param $student_uid + * @return array|stdClass|null + */ + public function getSumAngerechneteECTSByBegruendung($student_uid) + { + $qry = ' + SELECT sum(ects), begruendung_id FROM ( + SELECT + lehrveranstaltung_id, studiensemester_kurzbz, ects, COALESCE(begruendung_id, 1) as begruendung_id -- fallback auf externes Zeugnis + FROM + lehre.tbl_zeugnisnote + LEFT JOIN lehre.tbl_anrechnung USING(lehrveranstaltung_id, studiensemester_kurzbz) + JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN public.tbl_student USING(student_uid) + WHERE + tbl_zeugnisnote.note = 6 + AND student_uid = ? + AND (lehre.tbl_anrechnung.prestudent_id = tbl_student.prestudent_id + OR lehre.tbl_anrechnung.prestudent_id is null) + + UNION + + SELECT + lehrveranstaltung_id, studiensemester_kurzbz, ects, begruendung_id -- fallback auf externes Zeugnis + FROM + lehre.tbl_anrechnung + JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN public.tbl_student USING(prestudent_id) + WHERE + genehmigt_von is not null + AND student_uid = ? + ) lvsangerechnet + GROUP BY begruendung_id + '; + + return $this->execQuery($qry, array($student_uid, $student_uid)); + } + + /** + * Get ECTS Summe aller bisher schulisch begruendeten angerechneten LVs. + * Derzeit wird auch jede Anrechnung, die nicht beruflich ist, als schulisch angenommen. + * + * @param $student_uid + * @return array|stdClass|null + */ + public function getEctsSumSchulisch($student_uid, $prestudent_id, $studiengang_kz) + { + $qry = ' + SELECT get_ects_summe_schulisch(?, ?, ?) AS ectsSumSchulisch + '; + + return $this->execQuery($qry, array($student_uid, $prestudent_id, $studiengang_kz)); + } + + /** + * Get ECTS Summe aller bisher beruflich angerechneten LVs. + * + * @param $student_uid + * @return array|stdClass|null + */ + public function getEctsSumBeruflich($student_uid) + { + $qry = ' + SELECT get_ects_summe_beruflich(?) AS ectsSumBeruflich + '; + + return $this->execQuery($qry, array($student_uid)); + } } diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 087c27663..b876030a6 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -1,7 +1,6 @@ dbTable = 'campus.tbl_paabgabe'; $this->pk = 'paabgabe_id'; } + + /** + * Gets last Endabgabe of a Projektarbeit, including filename. + * @param int $projektarbeit_id + * @return object + */ + public function getEndabgabe($projektarbeit_id) + { + $qry = "SELECT paabgabe_id, student_uid, paabg.datum, paabg.abgabedatum, projekttyp_kurzbz, titel, titel_english, + paabgabe_id || '_' || student_uid || '.pdf' AS filename + FROM campus.tbl_paabgabe paabg + JOIN lehre.tbl_projektarbeit USING (projektarbeit_id) + WHERE projektarbeit_id = ? + AND paabgabetyp_kurzbz = 'end' + AND paabg.abgabedatum IS NOT NULL + ORDER BY paabg.abgabedatum, paabg.datum DESC + LIMIT 1"; + + return $this->execQuery($qry, array($projektarbeit_id)); + } } diff --git a/application/models/education/Projektbetreuer_model.php b/application/models/education/Projektbetreuer_model.php index 0200f6468..95950bf95 100644 --- a/application/models/education/Projektbetreuer_model.php +++ b/application/models/education/Projektbetreuer_model.php @@ -54,18 +54,28 @@ class Projektbetreuer_model extends DB_Model $qry = "SELECT DISTINCT ON (pers.person_id) pers.person_id, betreuerart_kurzbz, vorname, nachname, trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as voller_name, anrede, titelpre, titelpost, gebdatum, geschlecht, pa.projekttyp_kurzbz, - ben.uid, ben.alias, ma.personalnummer, mitarbeiter_uid, student_uid - FROM lehre.tbl_projektarbeit pa - JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) - JOIN public.tbl_person pers USING (person_id) - LEFT JOIN public.tbl_benutzer ben USING (person_id) - LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid - WHERE ben.aktiv - AND projektarbeit_id = ? - AND betreuerart_kurzbz = ? - ORDER BY pers.person_id, CASE WHEN ma.mitarbeiter_uid IS NULL THEN 1 ELSE 0 END, /*Mitarbeiter account first*/ - CASE WHEN ben.uid IS NULL THEN 1 ELSE 0 END, /*user with account first*/ - ben.insertamum"; + ben.uid, ben.alias, ma.personalnummer, mitarbeiter_uid, student_uid, + ( + SELECT kontakt + FROM public.tbl_kontakt + WHERE kontakttyp = 'email' + AND person_id = pers.person_id + ORDER BY + CASE WHEN zustellung THEN 0 ELSE 1 END, + insertamum DESC NULLS LAST + LIMIT 1 + ) AS private_email + FROM lehre.tbl_projektarbeit pa + JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + JOIN public.tbl_person pers USING (person_id) + LEFT JOIN public.tbl_benutzer ben USING (person_id) + LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid + WHERE (ben.aktiv OR ben.aktiv IS NULL) + AND projektarbeit_id = ? + AND betreuerart_kurzbz = ? + ORDER BY pers.person_id, CASE WHEN ma.mitarbeiter_uid IS NULL THEN 1 ELSE 0 END, /*Mitarbeiter account first*/ + CASE WHEN ben.uid IS NULL THEN 1 ELSE 0 END, /*user with account first*/ + ben.insertamum"; return $this->execQuery($qry, array($projektarbeit_id, $betreuerart_kurzbz)); } @@ -77,14 +87,14 @@ class Projektbetreuer_model extends DB_Model */ public function getBetreuerByToken($zugangstoken) { - $qry = ' + $qry = " SELECT tbl_projektbetreuer.person_id, tbl_projektbetreuer.projektarbeit_id, student_uid FROM lehre.tbl_projektbetreuer JOIN lehre.tbl_projektarbeit USING (projektarbeit_id) WHERE zugangstoken = ? AND zugangstoken_gueltigbis >= NOW() ORDER BY tbl_projektbetreuer.insertamum DESC, projektarbeit_id DESC LIMIT 1 - '; + "; return $this->execQuery($qry, array($zugangstoken)); } @@ -96,31 +106,60 @@ class Projektbetreuer_model extends DB_Model * @param $student_uid string uid des Studenten der Arbeit abgibt * @return object | bool */ - public function getZweitbegutachterWithToken($erstbegutachter_person_id, $projektarbeit_id, $student_uid) + public function getZweitbegutachterWithToken($erstbegutachter_person_id, $projektarbeit_id, $student_uid, $zweitbegutachter_person_id = null) { - $qry_betr = "SELECT betr.person_id, betr.projektarbeit_id, pers.anrede, betr.zugangstoken, betr.zugangstoken_gueltigbis, tbl_benutzer.uid, kontakt, - trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as voller_name, - CASE WHEN tbl_benutzer.uid IS NULL THEN kontakt ELSE tbl_benutzer.uid || '@".DOMAIN."' END AS email, abg.abgabedatum - FROM lehre.tbl_projektbetreuer betr - JOIN lehre.tbl_projektarbeit parb ON betr.projektarbeit_id = parb.projektarbeit_id - JOIN public.tbl_person pers ON betr.person_id = pers.person_id - LEFT JOIN public.tbl_kontakt ON pers.person_id = tbl_kontakt.person_id AND kontakttyp = 'email' AND zustellung = true - LEFT JOIN public.tbl_benutzer ON pers.person_id = tbl_benutzer.person_id - LEFT JOIN campus.tbl_paabgabe abg ON betr.projektarbeit_id = abg.projektarbeit_id AND abg.paabgabetyp_kurzbz = 'end' - WHERE betr.betreuerart_kurzbz = 'Zweitbegutachter' - AND betr.projektarbeit_id = ? - AND parb.student_uid = ? - AND EXISTS ( - SELECT 1 FROM lehre.tbl_projektbetreuer - WHERE person_id = ? - AND betreuerart_kurzbz = 'Erstbegutachter' - AND projektarbeit_id = betr.projektarbeit_id - ) - AND (tbl_benutzer.aktiv OR tbl_benutzer.aktiv IS NULL) - ORDER BY betr.insertamum DESC - LIMIT 1"; + $params = array($erstbegutachter_person_id, $erstbegutachter_person_id, $projektarbeit_id, $student_uid); - return $this->execQuery($qry_betr, array($projektarbeit_id, $student_uid, $erstbegutachter_person_id)); + $qry_betr = "SELECT betr.person_id, betr.projektarbeit_id, pers.anrede, betr.zugangstoken, betr.zugangstoken_gueltigbis, tbl_benutzer.uid, + trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as voller_name, + CASE WHEN tbl_benutzer.uid IS NULL THEN kontakt ELSE tbl_benutzer.uid || '@".DOMAIN."' END AS email, kontakt, + abg.abgabedatum, betr.betreuerart_kurzbz + FROM lehre.tbl_projektbetreuer betr + JOIN lehre.tbl_projektarbeit parb ON betr.projektarbeit_id = parb.projektarbeit_id + JOIN public.tbl_person pers ON betr.person_id = pers.person_id + LEFT JOIN public.tbl_kontakt ON pers.person_id = tbl_kontakt.person_id AND kontakttyp = 'email' AND zustellung = true + LEFT JOIN public.tbl_benutzer ON pers.person_id = tbl_benutzer.person_id + LEFT JOIN campus.tbl_paabgabe abg ON betr.projektarbeit_id = abg.projektarbeit_id AND abg.paabgabetyp_kurzbz = 'end' + WHERE + ( + ( + betr.betreuerart_kurzbz = 'Zweitbegutachter' + AND EXISTS ( + SELECT 1 FROM lehre.tbl_projektbetreuer + WHERE person_id = ? + AND betreuerart_kurzbz = 'Erstbegutachter' + AND projektarbeit_id = betr.projektarbeit_id + ) + ) + OR /* either Zweitbegutachter of masterarbeit, or Kommissionsprüfer if Kommission */ + ( + betr.betreuerart_kurzbz = 'Senatsmitglied' + AND EXISTS ( + SELECT 1 FROM lehre.tbl_projektbetreuer + WHERE person_id = ? + AND betreuerart_kurzbz = 'Senatsvorsitz' + AND projektarbeit_id = betr.projektarbeit_id + ) + ) + ) + AND betr.projektarbeit_id = ? + AND parb.student_uid = ? + AND (tbl_benutzer.aktiv OR tbl_benutzer.aktiv IS NULL)"; + + if (isset($zweitbegutachter_person_id)) + { + $qry_betr .= " AND betr.person_id = ?"; + $params[] = $zweitbegutachter_person_id; + } + + $qry_betr .= " ORDER BY betr.person_id DESC, + (CASE WHEN EXISTS ( /* if multiple accounts, prioritize mitarbeiter */ + SELECT 1 FROM public.tbl_mitarbeiter ma + WHERE ma.mitarbeiter_uid = tbl_benutzer.uid + ) THEN 0 ELSE 1 END), betr.insertamum DESC + LIMIT 1"; + + return $this->execQuery($qry_betr, $params); } /** @@ -131,23 +170,23 @@ class Projektbetreuer_model extends DB_Model */ public function generateZweitbegutachterToken($zweitbegutachter_person_id, $projektarbeit_id) { - $betreuerUidQry = "SELECT uid, zugangstoken, zugangstoken_gueltigbis, tbl_projektbetreuer.person_id + $betreuerUidQry = "SELECT uid, zugangstoken, zugangstoken_gueltigbis, tbl_projektbetreuer.person_id, betreuerart_kurzbz FROM lehre.tbl_projektbetreuer JOIN public.tbl_person USING(person_id) LEFT JOIN public.tbl_benutzer USING(person_id) WHERE projektarbeit_id = ? AND tbl_projektbetreuer.person_id = ? - AND betreuerart_kurzbz = 'Zweitbegutachter' + AND betreuerart_kurzbz IN ('Zweitbegutachter', 'Senatsmitglied') LIMIT 1"; - $betreueruidres = $this->execQuery($betreuerUidQry, array($projektarbeit_id, $zweitbegutachter_person_id)); + $betreueruidRes = $this->execQuery($betreuerUidQry, array($projektarbeit_id, $zweitbegutachter_person_id)); - if (!hasData($betreueruidres)) + if (!hasData($betreueruidRes)) return error('Zweitbegutachter nicht gefunden'); - $row_betr = getData($betreueruidres)[0]; + $zweitbetreuer = getData($betreueruidRes)[0]; - if (!isset($row_betr->uid)) + if (!isset($zweitbetreuer->uid)) { do { $token = generateToken(16); @@ -156,8 +195,8 @@ class Projektbetreuer_model extends DB_Model $result = $this->update( array('projektarbeit_id' => $projektarbeit_id, - 'person_id' => $row_betr->person_id, - 'betreuerart_kurzbz' => 'Zweitbegutachter'), + 'person_id' => $zweitbetreuer->person_id, + 'betreuerart_kurzbz' => $zweitbetreuer->betreuerart_kurzbz), array('zugangstoken' => $token, 'zugangstoken_gueltigbis' => date('Y-m-d', strtotime('+1 year'))) ); @@ -167,4 +206,29 @@ class Projektbetreuer_model extends DB_Model else return success("Account vorhanden, kein Token benötigt"); } + + /** + * Gets betreuerart of a Betreuer for a Projektarbeit. + * Main Betreuer are prioritized (normally one Betreuer should be assigned to a Projektarbeit another time with a different Betreuerart). + * @param int projektarbeit_id + * @param int betreuer_person_id + * @return object success or error + */ + public function getBetreuerart($projektarbeit_id, $betreuer_person_id) + { + $qry = "SELECT betreuerart_kurzbz + FROM lehre.tbl_projektbetreuer + WHERE projektarbeit_id = ? + AND person_id = ? + ORDER BY CASE WHEN betreuerart_kurzbz = 'Senatsvorsitz' THEN 1 /*Senatsvorsitz has priority*/ + WHEN betreuerart_kurzbz = 'Begutachter' THEN 2 + WHEN betreuerart_kurzbz = 'Erstbegutachter' THEN 3 + WHEN betreuerart_kurzbz = 'Zweitbegutachter' THEN 4 + WHEN betreuerart_kurzbz = 'Senatsmitglied' THEN 5 + ELSE 5 + END, insertamum DESC + LIMIT 1"; + + return $this->execQuery($qry, array($projektarbeit_id, $betreuer_person_id)); + } } diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 0d0c248a6..f4f8b3c9e 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -507,4 +507,21 @@ class Studiengang_model extends DB_Model return $this->execQuery($query, array($typ, $semester)); } + + public function getStudiengangTyp($studiengang_kz, $typ = null) + { + $query = "SELECT DISTINCT(sgt.*) + FROM tbl_studiengangstyp sgt JOIN tbl_studiengang sg on sgt.typ = sg.typ + WHERE studiengang_kz IN ?"; + + $params[] = $studiengang_kz; + + if (!is_null($typ)) + { + $query .= " AND sgt.typ IN ?"; + $params[] = $typ; + } + + return $this->execQuery($query, $params); + } } diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php index e7a3d77b1..bb9b94c92 100644 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -105,7 +105,7 @@ class Studiensemester_model extends DB_Model /** * getPreviousFrom */ - public function getPreviousFrom($studiensemester_kurzbz) + public function getPreviousFrom($studiensemester_kurzbz, $limit = 1) { $query = 'SELECT studiensemester_kurzbz, start, @@ -117,9 +117,9 @@ class Studiensemester_model extends DB_Model WHERE studiensemester_kurzbz = ? ) ORDER BY start DESC - LIMIT 1'; + LIMIT ?'; - return $this->execQuery($query, array($studiensemester_kurzbz)); + return $this->execQuery($query, array($studiensemester_kurzbz, $limit)); } /** diff --git a/application/models/person/Adressentyp_model.php b/application/models/person/Adressentyp_model.php new file mode 100644 index 000000000..94a8c6048 --- /dev/null +++ b/application/models/person/Adressentyp_model.php @@ -0,0 +1,14 @@ +dbTable = 'public.tbl_adressentyp'; + $this->pk = 'adressentyp_kurzbz'; + } +} diff --git a/application/models/person/Geschlecht_model.php b/application/models/person/Geschlecht_model.php new file mode 100644 index 000000000..60ac3ba15 --- /dev/null +++ b/application/models/person/Geschlecht_model.php @@ -0,0 +1,14 @@ +dbTable = 'public.tbl_geschlecht'; + $this->pk = 'geschlecht'; + } +} diff --git a/application/models/person/Person_model.php b/application/models/person/Person_model.php index 6bf9fc2c0..8875fd4c5 100644 --- a/application/models/person/Person_model.php +++ b/application/models/person/Person_model.php @@ -82,7 +82,7 @@ class Person_model extends DB_Model } else { - $person['svnr'] = $person['svnr'] . 'v' . ($result->retval[0]->svnr{11} + 1); + $person['svnr'] = $person['svnr'] . 'v' . ($result->retval[0]->svnr[11] + 1); } } } @@ -283,8 +283,8 @@ class Person_model extends DB_Model SELECT p2.person_id FROM public.tbl_person p JOIN public.tbl_person p2 - ON p.vorname = p2.vorname - AND p.nachname = p2.nachname + ON lower(p.vorname) = lower(p2.vorname) + AND lower(p.nachname) = lower(p2.nachname) AND p.gebdatum = p2.gebdatum AND p.person_id = ? ) @@ -310,8 +310,8 @@ class Person_model extends DB_Model SELECT p2.person_id FROM public.tbl_person p JOIN public.tbl_person p2 - ON p.vorname = p2.vorname - AND p.nachname = p2.nachname + ON lower(p.vorname) = lower(p2.vorname) + AND lower(p.nachname) = lower(p2.nachname) AND p.gebdatum = p2.gebdatum AND p.person_id = ? ) @@ -321,8 +321,18 @@ class Person_model extends DB_Model JOIN public.tbl_status USING(status_kurzbz) WHERE status_kurzbz = 'Abbrecher' ) - "; - return $this->execQuery($qry, array($person_id, $person_id)); + UNION + + SELECT p2.person_id + FROM tbl_person p1 + INNER JOIN ( + SELECT vorname, nachname, gebdatum, person_id + FROM tbl_person + ) p2 + ON (lower(p1.vorname) = lower(p2.vorname) AND lower(p1.nachname) = lower(p2.nachname) AND p1.gebdatum = p2.gebdatum) + WHERE p1.person_id != p2.person_id AND (p1.person_id = ?)"; + + return $this->execQuery($qry, array($person_id, $person_id, $person_id)); } } diff --git a/application/models/ressource/Betriebsmittelperson_model.php b/application/models/ressource/Betriebsmittelperson_model.php index 7d9689753..04878a9ad 100644 --- a/application/models/ressource/Betriebsmittelperson_model.php +++ b/application/models/ressource/Betriebsmittelperson_model.php @@ -72,4 +72,28 @@ class Betriebsmittelperson_model extends DB_Model return $this->loadWhere($where); } + + public function getBetriebsmittelByUid($uid, $betriebsmitteltyp = null, $isRetourniert = false) + { + $this->addJoin('wawi.tbl_betriebsmittel', 'betriebsmittel_id'); + + $condition = ' wawi.tbl_betriebsmittelperson.uid = '. $this->escape($uid); + + if (is_string($betriebsmitteltyp)) + { + $condition .= ' AND betriebsmitteltyp = ' . $this->escape($betriebsmitteltyp); + } + + if ($isRetourniert === true) { + $condition .= ' AND retouram IS NOT NULL'; + } + elseif ($isRetourniert === false) + { + $condition .= ' AND retouram IS NULL'; + } + + $this->addOrder('ausgegebenam', 'DESC'); + + return $this->loadWhere($condition); + } } diff --git a/application/models/system/Benutzerrolle_model.php b/application/models/system/Benutzerrolle_model.php index 765ad9bd4..0714a1f8f 100644 --- a/application/models/system/Benutzerrolle_model.php +++ b/application/models/system/Benutzerrolle_model.php @@ -43,7 +43,7 @@ class Benutzerrolle_model extends DB_Model * @param null $oe_kurzbz * @return array */ - public function getBenutzerByBerechtigung($berechtigung_kurzbz, $oe_kurzbz = null) + public function getBenutzerByBerechtigung($berechtigung_kurzbz, $oe_kurzbz = null, $art = null) { $params = array(); $query = ' @@ -62,6 +62,12 @@ class Benutzerrolle_model extends DB_Model $params[] = $oe_kurzbz; } + if (!is_null($art)) + { + $query .= ' AND art = ?'; + $params[] = $art; + } + return $this->execQuery($query, $params); } } diff --git a/application/models/system/Fehlerzustaendigkeiten_model.php b/application/models/system/Fehlerzustaendigkeiten_model.php new file mode 100644 index 000000000..9277f3609 --- /dev/null +++ b/application/models/system/Fehlerzustaendigkeiten_model.php @@ -0,0 +1,58 @@ +dbTable = 'system.tbl_fehler_zustaendigkeiten'; + $this->pk = 'fehlerzustaendigkeiten_id'; + } + + /** + * Gets active Mitarbeiter not assigned to a Fehler. + * @param $fehlercode + * @return object + */ + public function getNonAssignedMitarbeiter($fehlercode) + { + $query = "SELECT person_id, ben.uid, vorname, nachname, titelpre, titelpost, personalnummer + FROM public.tbl_mitarbeiter + JOIN public.tbl_benutzer ben ON tbl_mitarbeiter.mitarbeiter_uid = ben.uid + JOIN public.tbl_person pers USING (person_id) + WHERE ben.aktiv + AND NOT EXISTS ( + SELECT 1 FROM system.tbl_fehler_zustaendigkeiten + WHERE person_id = pers.person_id + AND fehlercode = ? + ) + ORDER BY nachname, vorname, uid"; + + return $this->execReadOnlyQuery($query, array($fehlercode)); + } + + /** + * Gets Funktionen not assigned to a Fehler (over an organisational unit). + * @param $fehlercode + * @param $oe_kurzbz + * @return object + */ + public function getNonAssignedFunktionen($fehlercode, $oe_kurzbz) + { + $query = "SELECT funktion_kurzbz, beschreibung + FROM public.tbl_funktion funk + WHERE aktiv + AND NOT EXISTS ( + SELECT 1 FROM system.tbl_fehler_zustaendigkeiten + WHERE funktion_kurzbz = funk.funktion_kurzbz + AND fehlercode = ? + AND oe_kurzbz = ? + ) + ORDER BY beschreibung"; + + return $this->execReadOnlyQuery($query, array($fehlercode, $oe_kurzbz)); + } +} 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/codex/oehbeitrag.php b/application/views/codex/oehbeitrag.php index 8a697129e..feebeddef 100644 --- a/application/views/codex/oehbeitrag.php +++ b/application/views/codex/oehbeitrag.php @@ -3,12 +3,12 @@ $this->load->view( 'templates/FHC-Header', array( 'title' => 'ÖH-Beitragsverwaltung', - 'jquery' => true, - 'jqueryui' => true, - 'bootstrap' => true, - 'fontawesome' => true, - 'sbadmintemplate' => true, - 'tablesorter' => true, + 'jquery3' => true, + 'jqueryui1' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'sbadmintemplate3' => true, + 'tablesorter2' => true, 'dialoglib' => true, 'ajaxlib' => true, 'navigationwidget' => true, diff --git a/application/views/home.php b/application/views/home.php index 79669dd88..eb7ef0406 100644 --- a/application/views/home.php +++ b/application/views/home.php @@ -1,42 +1,36 @@ load->view('templates/FHC-Header', - array( + $includesArray = array( 'title' => 'FH-Complete', - 'jquery' => true, - 'jqueryui' => true, - 'bootstrap' => true, - 'fontawesome' => true, - 'sbadmintemplate' => true, + 'jquery3' => true, + 'jqueryui1' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'sbadmintemplate3' => true, 'ajaxlib' => true, + 'bootstrapper' => true, // to be used only if you know what you are doing! 'addons' => true, 'navigationwidget' => true - ) -); + ); + + $this->load->view('templates/FHC-Header', $includesArray); ?> -
-| p->t('person','titelpre')) ?> | +p->t('person', 'titelpre')) ?> | titelpre ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','vorname')) ?> | +p->t('person', 'vorname')) ?> | vorname ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','nachname')) ?> | +p->t('person', 'nachname')) ?> | nachname ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','titelpost')) ?> | +p->t('person', 'titelpost')) ?> | titelpost ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','geburtsdatum')) ?> | +p->t('person', 'geburtsdatum')) ?> | gebdatum), 'd.m.Y') ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','svnr')) ?> | +p->t('person', 'svnr')) ?> | svnr ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','ersatzkennzeichen')) ?> | +p->t('person', 'ersatzkennzeichen')) ?> | ersatzkennzeichen ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','staatsbuergerschaft')) ?> | +p->t('person', 'staatsbuergerschaft')) ?> | staatsbuergerschaft ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','geschlecht')) ?> | +p->t('person', 'geschlecht')) ?> | geschlecht ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','bpk')) ?> | +p->t('person', 'bpk')) ?> | bpk ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','postleitzahl')) ?> | +p->t('person', 'postleitzahl')) ?> | plz ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| p->t('person','strasse')) ?> | +p->t('person', 'strasse')) ?> | strasse ?> | ||||||||||||||||||||||||||||||||||||||||||||||
| Uid | +p->t('person', 'vorname')); ?> | +p->t('person', 'nachname')); ?> | +p->t('gruppenmanagement', 'aktiv')); ?> | +p->t('ui', 'entfernen')); ?> | + + + +
|---|
| p->t('global','name')) ?> | p->t('global','typ')) ?> | p->t('global','uploaddatum')) ?> | +p->t('ui','loeschen')) ?> | p->t('infocenter','ausstellungsnation')) ?> | akte_id ?>">titel) ? $dokument->bezeichnung : $dokument->titel ?>- | erstelltam), 'd.m.Y') ?> | +> | langtext ?> | load->view( - 'templates/FHC-Header', - array( - 'title' => 'Info Center', - 'jquery' => true, - 'jqueryui' => true, - 'jquerycheckboxes' => true, - 'bootstrap' => true, - 'fontawesome' => true, - 'sbadmintemplate' => true, - 'tablesorter' => true, - 'ajaxlib' => true, - 'filterwidget' => true, - 'navigationwidget' => true, - 'dialoglib' => true, - 'phrases' => array( - 'person' => array('vorname', 'nachname'), - 'global' => array('mailAnXversandt'), - 'ui' => array('bitteEintragWaehlen') - ), - 'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'), - 'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js') - ) + $includesArray = array( + 'title' => 'Info Center', + 'jquery3' => true, + 'jqueryui1' => true, + 'jquerycheckboxes1' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'sbadmintemplate3' => true, + 'tablesorter2' => true, + 'ajaxlib' => true, + 'bootstrapper' => true, + 'filterwidget' => true, + 'navigationwidget' => true, + 'dialoglib' => true, + 'phrases' => array( + 'person' => array('vorname', 'nachname'), + 'global' => array('mailAnXversandt'), + 'ui' => array('bitteEintragWaehlen') + ), + 'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'), + 'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js') ); + + $this->load->view('templates/FHC-Header', $includesArray); ?> -||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| p->t('person','titelpre')) ?> | -titelpre ?> | +
+ titelpre ?>
+ |
| p->t('person','vorname')) ?> | -vorname ?> | +
+ vorname ?>
+ |
| p->t('person','nachname')) ?> | - nachname ?> | +|
| p->t('person','titelpost')) ?> | +
+ titelpost ?>
+ |
|
| p->t('person','titelpost')) ?> | -titelpost ?> | -|
| p->t('person','geburtsdatum')) ?> | - gebdatum), 'd.m.Y') ?> | +|
| p->t('person','svnr')) ?> | - svnr ?> | +|
| p->t('person','staatsbuergerschaft')) ?> | - staatsbuergerschaft ?> | +|
| p->t('person','geschlecht')) ?> | - geschlecht ?> | + +|
| p->t('person','geburtsnation')) ?> | - geburtsnation ?> | +|
| p->t('person','geburtsort')) ?> | -gebort ?> | +
+ gebort ?>
+ |
| p->t('global','kontakt')) ?> | @@ -78,7 +122,7 @@kontakttyp) ?> | - kontakttyp.'">';?> + kontakttyp.'" data-id="'. $kontakt->kontakt_id .'" data-value="' . $kontakt->kontakt .'">';?> kontakttyp === 'email'): ?> kontakt; @@ -99,8 +143,30 @@ p->t('person','adresse')) ?> |
- strasse.', '.$adresse->plz.' '.$adresse->ort : '' ?>
- nationkurztext) ? ' '.$adresse->nationkurztext : '' ?> + +
+
+ strasse ?>
+
+ plz ?>
+
+ ort ?>
+
+ nationkurztext)): ?>
+ + + |
heimatadresse === true ? 'Heimatadresse' : '').
@@ -126,6 +192,16 @@
target='_blank'> p->t('infocenter','zugangBewerbung') ?>
+
diff --git a/application/views/system/infocenter/studiengangZgvInfo.php b/application/views/system/infocenter/studiengangZgvInfo.php
index 1b699d634..8b6d1a636 100644
--- a/application/views/system/infocenter/studiengangZgvInfo.php
+++ b/application/views/system/infocenter/studiengangZgvInfo.php
@@ -3,10 +3,10 @@ $this->load->view(
'templates/FHC-Header',
array(
'title' => 'ZGV Info',
- 'jquery' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'customCSSs' => 'public/css/sbadmin2/admintemplate_contentonly.css'
)
);
@@ -17,7 +17,11 @@ $this->load->view(
-
p->t('infocenter', 'zugangsvoraussetzungen'); ?> -++ p->t('infocenter', 'zugangsvoraussetzungen'); ?> + - + +
@@ -35,3 +39,4 @@ $this->load->view(
load->view('templates/FHC-Footer'); ?>
+
diff --git a/application/views/system/infocenter/zgvpruefungen.php b/application/views/system/infocenter/zgvpruefungen.php
index 253145557..1d26b9d55 100644
--- a/application/views/system/infocenter/zgvpruefungen.php
+++ b/application/views/system/infocenter/zgvpruefungen.php
@@ -2,7 +2,7 @@
infoonly;
$studiengangkurzbz = $studiengangbezeichnung = $studiengangtyp = '';
@@ -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 = '';
+ ?>
- 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 @@
-
-
@@ -336,7 +421,7 @@
prestudentUdfs)) + if (isset($zgvpruefung->prestudentUdfs) && $studiengangtyp !== 'l') { echo $this->udflib->UDFWidget( array( @@ -362,6 +447,8 @@
@@ -408,6 +476,7 @@
-
+
+ widgetlib->widget('NavigationWidget'); ?>
+
+
+
+
+load->view('templates/FHC-Footer'); ?>
diff --git a/application/views/system/issues/issuesZustaendigkeitenData.php b/application/views/system/issues/issuesZustaendigkeitenData.php
new file mode 100644
index 000000000..d4cedd192
--- /dev/null
+++ b/application/views/system/issues/issuesZustaendigkeitenData.php
@@ -0,0 +1,84 @@
+ $query,
+ 'app' => 'core',
+ 'datasetName' => 'fehlerZustaendigkeiten',
+ 'filter_id' => $this->input->get('filter_id'),
+ 'tableUniqueId' => 'issuesZustaendigkeiten',
+ 'requiredPermissions' => 'admin',
+ 'datasetRepresentation' => 'tablesorter',
+ 'additionalColumns' => array('Delete'),
+ 'columnsAliases' => array(
+ 'ID',
+ ucfirst($this->p->t('fehlermonitoring', 'fehlercode')),
+ ucfirst($this->p->t('fehlermonitoring', 'fehlercodeExtern')),
+ ucfirst($this->p->t('fehlermonitoring', 'fehlerkurzbz')),
+ ucfirst($this->p->t('fehlermonitoring', 'fehlertext')),
+ ucfirst($this->p->t('fehlermonitoring', 'fehlertyp')),
+ 'app',
+ 'PersonId',
+ ucfirst($this->p->t('person', 'vorname')),
+ ucfirst($this->p->t('person', 'nachname')),
+ ucfirst($this->p->t('fehlermonitoring', 'oeKurzbz')),
+ ucfirst($this->p->t('fehlermonitoring', 'oeBezeichnung')),
+ ucfirst($this->p->t('fehlermonitoring', 'funktionKurzbz')),
+ ucfirst($this->p->t('fehlermonitoring', 'funktionBeschreibung'))
+ ),
+ 'formatRow' => function($datasetRaw) {
+
+ $datasetRaw->{'Delete'} =
+ "
+
+
+
+
+
+
+
+
+ + p->t('fehlermonitoring', 'fehlerZustaendigkeiten') ?> ++
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ load->view('system/issues/issuesZustaendigkeitenData.php'); ?>
+
+
+
+
+ widgetlib->widget('NavigationWidget'); ?>
+
+
+
+load->view('templates/FHC-Footer'); ?>
diff --git a/application/views/system/jq/jobsQueueViewer.php b/application/views/system/jq/jobsQueueViewer.php
index 6d92d610b..bf4e16645 100644
--- a/application/views/system/jq/jobsQueueViewer.php
+++ b/application/views/system/jq/jobsQueueViewer.php
@@ -3,12 +3,12 @@
'templates/FHC-Header',
array(
'title' => 'Jobs Queue Viewer',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
- 'tablesorter' => true,
+ 'jquery3' => true,
+ 'jqueryui1' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
+ 'tablesorter2' => true,
'ajaxlib' => true,
'filterwidget' => true,
'navigationwidget' => true,
diff --git a/application/views/system/login/usernamePassword.php b/application/views/system/login/usernamePassword.php
index 944212b49..ba6062b46 100644
--- a/application/views/system/login/usernamePassword.php
+++ b/application/views/system/login/usernamePassword.php
@@ -3,11 +3,11 @@
'templates/FHC-Header',
array(
'title' => 'Login',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'jqueryui1' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'ajaxlib' => true,
'dialoglib' => true,
'customCSSs' => 'public/css/Login.css',
diff --git a/application/views/system/logs/logsViewer.php b/application/views/system/logs/logsViewer.php
index 86423006b..8749806bc 100644
--- a/application/views/system/logs/logsViewer.php
+++ b/application/views/system/logs/logsViewer.php
@@ -1,47 +1,41 @@
load->view(
- 'templates/FHC-Header',
- array(
- 'title' => 'Logs Viewer',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
- 'tablesorter' => true,
- 'ajaxlib' => true,
- 'filterwidget' => true,
- 'navigationwidget' => true,
- 'phrases' => array(
- 'global' => array('mailAnXversandt'),
- 'ui' => array('bitteEintragWaehlen')
- ),
- 'customCSSs' => 'public/css/sbadmin2/tablesort_bootstrap.css',
- 'customJSs' => array('public/js/bootstrapper.js')
- )
+ $includesArray = array(
+ 'title' => 'Logs Viewer',
+ 'axios027' => true,
+ 'bootstrap5' => true,
+ 'fontawesome6' => true,
+ 'vue3' => true,
+ 'filtercomponent' => true,
+ 'navigationcomponent' => true,
+ 'tabulator5' => true,
+ 'phrases' => array(
+ 'global' => array('mailAnXversandt'),
+ 'ui' => array('bitteEintragWaehlen')
+ ),
+ 'customJSModules' => array('public/js/apps/LogsViewer/LogsViewer.js')
);
+
+ $this->load->view('templates/FHC-Header', $includesArray);
?>
-
-
+
+
+
+
+
+
+
+ + Plausichecks ++
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ Output:+
+
+ -
+
+
- widgetlib->widget('NavigationWidget'); ?>
+
+
-
-
-
-load->view('templates/FHC-Footer'); ?>
+load->view('templates/FHC-Footer', $includesArray); ?>
+
diff --git a/application/views/system/logs/logsViewerData.php b/application/views/system/logs/logsViewerData.php
deleted file mode 100644
index f8476df6a..000000000
--- a/application/views/system/logs/logsViewerData.php
+++ /dev/null
@@ -1,66 +0,0 @@
- '
- SELECT wsl.webservicelog_id AS "LogId",
- wsl.request_id AS "RequestId",
- wsl.execute_time AS "ExecutionTime",
- wsl.execute_user AS "ExecutedBy",
- wsl.beschreibung AS "Description",
- wsl.request_data AS "Data",
- wsl.webservicetyp_kurzbz AS "WebserviceType"
- FROM system.tbl_webservicelog wsl
- ORDER BY wsl.execute_time DESC
- ',
- 'requiredPermissions' => 'admin',
- 'datasetRepresentation' => 'tablesorter',
- 'columnsAliases' => array(
- 'Log id',
- 'Request id',
- 'Execution time',
- 'Executed by',
- 'Producer',
- 'Data',
- 'Webservice type'
- ),
- 'formatRow' => function($datasetRaw) {
-
- $datasetRaw->ExecutionTime = date_format(date_create($datasetRaw->ExecutionTime), 'd.m.Y H:i:s:u');
-
- return $datasetRaw;
- },
- 'markRow' => function($datasetRaw) {
-
- $mark = '';
-
- if (strpos($datasetRaw->RequestId, 'error') != false)
- {
- $mark = 'text-red';
- }
-
- if (strpos($datasetRaw->RequestId, 'info') != false)
- {
- $mark = 'text-green';
- }
-
- if (strpos($datasetRaw->RequestId, 'warning') != false)
- {
- $mark = 'text-orange';
- }
-
- if (strpos($datasetRaw->RequestId, 'debug') != false)
- {
- $mark = 'text-info';
- }
-
- return $mark;
- }
- );
-
- $filterWidgetArray['app'] = 'core';
- $filterWidgetArray['datasetName'] = 'logs';
- $filterWidgetArray['filter_id'] = $this->input->get('filter_id');
-
- echo $this->widgetlib->widget('FilterWidget', $filterWidgetArray);
-?>
-
diff --git a/application/views/system/logs/testSearch.php b/application/views/system/logs/testSearch.php
new file mode 100644
index 000000000..882b953f5
--- /dev/null
+++ b/application/views/system/logs/testSearch.php
@@ -0,0 +1,60 @@
+ 'Test Search',
+ 'jquery3' => true,
+ 'bootstrap5' => true,
+ 'fontawesome6' => true,
+ 'tablesorter2' => true,
+ 'vue3' => true,
+ 'ajaxlib' => true,
+ 'jqueryui1' => true,
+ 'filtercomponent' => true,
+ 'navigationcomponent' => true,
+ 'phrases' => array(
+ 'global' => array('mailAnXversandt'),
+ 'ui' => array('bitteEintragWaehlen')
+ ),
+ 'customCSSs' => array(
+ 'public/css/components/verticalsplit.css',
+ 'public/css/components/searchbar.css',
+ ),
+ 'customJSs' => array('vendor/axios/axios/axios.min.js'),
+ 'customJSModules' => array('public/js/apps/TestSearch.js')
+ );
+
+ $this->load->view('templates/FHC-Header', $includesArray);
+?>
+
+
-
-
-
- - Job Logs Viewer --
- load->view('system/logs/logsViewerData.php'); ?>
-
+
+
+
+
+
+
+
+
+load->view('templates/FHC-Footer', $includesArray); ?>
+
diff --git a/application/views/system/messages/ajaxRead.php b/application/views/system/messages/ajaxRead.php
index f7d60a68d..2cb88708e 100644
--- a/application/views/system/messages/ajaxRead.php
+++ b/application/views/system/messages/ajaxRead.php
@@ -3,16 +3,16 @@
'templates/FHC-Header',
array(
'title' => 'Read personal messages',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
- 'momentjs' => true,
- 'tabulator' => true,
+ 'jquery3' => true,
+ 'jqueryui1' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
+ 'momentjs2' => true,
+ 'tabulator4' => true,
'ajaxlib' => true,
'dialoglib' => true,
- 'tinymce' => true,
+ 'tinymce4' => true,
'phrases' => array('global', 'ui'),
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/read.js')
diff --git a/application/views/system/messages/ajaxWrite.php b/application/views/system/messages/ajaxWrite.php
index de3d79806..3b1582f22 100644
--- a/application/views/system/messages/ajaxWrite.php
+++ b/application/views/system/messages/ajaxWrite.php
@@ -3,14 +3,14 @@
'templates/FHC-Header',
array(
'title' => 'Write a new message',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'jqueryui1' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'ajaxlib' => true,
'dialoglib' => true,
- 'tinymce' => true,
+ 'tinymce4' => true,
'phrases' => array('global', 'ui'),
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/write.js')
diff --git a/application/views/system/messages/ajaxWriteReply.php b/application/views/system/messages/ajaxWriteReply.php
index 3721565e9..0a496c93e 100644
--- a/application/views/system/messages/ajaxWriteReply.php
+++ b/application/views/system/messages/ajaxWriteReply.php
@@ -3,14 +3,14 @@
'templates/FHC-Header',
array(
'title' => 'Reply to a message',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'jqueryui1' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'ajaxlib' => true,
'dialoglib' => true,
- 'tinymce' => true,
+ 'tinymce4' => true,
'phrases' => array('global', 'ui'),
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/writeReply.js')
diff --git a/application/views/system/messages/htmlMessageSentError.php b/application/views/system/messages/htmlMessageSentError.php
index 90191fcf0..f8a0f8491 100644
--- a/application/views/system/messages/htmlMessageSentError.php
+++ b/application/views/system/messages/htmlMessageSentError.php
@@ -3,10 +3,10 @@
'templates/FHC-Header',
array(
'title' => 'Message sent failure - Fehler beim Senden der Nachricht',
- 'jquery' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css')
)
);
diff --git a/application/views/system/messages/htmlMessageSentSuccess.php b/application/views/system/messages/htmlMessageSentSuccess.php
index 48409a5f4..91eeab519 100644
--- a/application/views/system/messages/htmlMessageSentSuccess.php
+++ b/application/views/system/messages/htmlMessageSentSuccess.php
@@ -3,10 +3,10 @@
'templates/FHC-Header',
array(
'title' => 'Message sent successfully - Nachricht erfolgreich versandt!',
- 'jquery' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css')
)
);
diff --git a/application/views/system/messages/htmlRead.php b/application/views/system/messages/htmlRead.php
index 5413af9f4..35e162b70 100644
--- a/application/views/system/messages/htmlRead.php
+++ b/application/views/system/messages/htmlRead.php
@@ -3,10 +3,10 @@
'templates/FHC-Header',
array(
'title' => 'Read message - Lies die Nachricht',
- 'jquery' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'sbadmintemplate3' => true,
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css')
)
);
diff --git a/application/views/system/messages/htmlWriteReply.php b/application/views/system/messages/htmlWriteReply.php
index fa3390bfa..9106d802b 100644
--- a/application/views/system/messages/htmlWriteReply.php
+++ b/application/views/system/messages/htmlWriteReply.php
@@ -3,11 +3,11 @@
'templates/FHC-Header',
array(
'title' => 'Reply to a message',
- 'jquery' => true,
- 'bootstrap' => true,
- 'fontawesome' => true,
- 'tinymce' => true,
- 'sbadmintemplate' => true,
+ 'jquery3' => true,
+ 'bootstrap3' => true,
+ 'fontawesome4' => true,
+ 'tinymce4' => true,
+ 'sbadmintemplate3' => true,
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/messageWriteReply.js')
)
diff --git a/application/views/system/messages/htmlWriteTemplate.php b/application/views/system/messages/htmlWriteTemplate.php
index 95ab12630..761e05f96 100644
--- a/application/views/system/messages/htmlWriteTemplate.php
+++ b/application/views/system/messages/htmlWriteTemplate.php
@@ -3,13 +3,13 @@
'templates/FHC-Header',
array(
'title' => 'Write a new message or reply using templates',
- 'jquery' => true,
- 'jqueryui' => true,
- 'bootstrap' => true,
+ 'jquery3' => true,
+ 'jqueryui1' => true,
+ 'bootstrap3' => true,
'ajaxlib' => true,
- 'fontawesome' => true,
- 'tinymce' => true,
- 'sbadmintemplate' => true,
+ 'fontawesome4' => true,
+ 'tinymce4' => true,
+ 'sbadmintemplate3' => true,
'dialoglib' => true,
'widgets' => true,
'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'),
@@ -160,7 +160,10 @@
widgetlib->widget(
'Dropdown_widget',
- array('elements' => success($recipientsArray), 'emptyElement' => ucfirst($this->p->t('global', 'empfaenger')).'...'),
+ array(
+ 'elements' => success($recipientsArray),
+ 'emptyElement' => ucfirst($this->p->t('global', 'empfaenger')).'...'
+ ),
array(
'name' => 'recipients[]',
'id' => 'recipients'
diff --git a/application/views/system/phrases/phraseinhaltEdit.php b/application/views/system/phrases/phraseinhaltEdit.php
index 594e8d9dd..388f1dd06 100644
--- a/application/views/system/phrases/phraseinhaltEdit.php
+++ b/application/views/system/phrases/phraseinhaltEdit.php
@@ -1,5 +1,5 @@
load->view('templates/header', array('title' => 'TemplateEdit', 'jquery' => true, 'textile' => true));
+ $this->load->view('templates/header', array('title' => 'TemplateEdit', 'jquery3' => true, 'textile' => true));
?>
+
+
+
+
+
+ + Test Search ++
+
+
+
diff --git a/application/views/system/vorlage/templatetextEdit.php b/application/views/system/vorlage/templatetextEdit.php
index 40ebd1599..42efc1519 100644
--- a/application/views/system/vorlage/templatetextEdit.php
+++ b/application/views/system/vorlage/templatetextEdit.php
@@ -1,5 +1,5 @@
load->view('templates/header', array('title' => 'VorlageEdit', 'tinymce' => true, 'jsonforms' => true));
+ $this->load->view('templates/header', array('title' => 'VorlageEdit', 'tinymce4' => true, 'jsonforms' => true));
?>
diff --git a/application/views/templates/FHC-Common.php b/application/views/templates/FHC-Common.php
new file mode 100644
index 000000000..dd1d8ae1c
--- /dev/null
+++ b/application/views/templates/FHC-Common.php
@@ -0,0 +1,46 @@
+
+config->item('index_page');
+ $calledPath = $this->router->directory.$this->router->class;
+ $calledMethod = $this->router->method;
+
+ // By default set the parameters to null
+ $customJSs = isset($customJSs) ? $customJSs : null;
+ $customJSModules = isset($customJSModules) ? $customJSModules : null;
+
+ // --------------------------------------------------------------------------------------------------------
+ // Javascripts
+
+ // Generates the global object to pass useful parameters to other javascripts
+ // NOTE: must be called before any other JS include
+ generateJSDataStorageObject($indexPage, $calledPath, $calledMethod);
+
+ // Generates the global object to pass phrases to javascripts
+ // NOTE: must be called before including the PhrasesLib.js
+ if ($phrases != null) generateJSPhrasesStorageObject($phrases);
+
+ // --------------------------------------------------------------------------------------------------------
+ // From vendor folder
+
+ // Axios V0.27
+ if ($axios027 === true) generateJSsInclude('vendor/axios/axios/dist/axios.min.js');
+
+ // Securimage JS
+ if ($captcha3 === true) generateJSsInclude('vendor/dapphp/securimage/securimage.js');
+
+ // jQuery V3
+ if ($jquery3 === true) generateJSsInclude('vendor/components/jquery/jquery.min.js');
+
+ // jQuery UI
+ if ($jqueryui1 === true)
+ {
+ generateJSsInclude('vendor/components/jqueryui/jquery-ui.min.js');
+ generateJSsInclude('vendor/components/jqueryui/ui/i18n/datepicker-de.js'); // datepicker german language file
+ }
+
+ // jQuery checkboxes
+ // NOTE: keep it after jQuery includes
+ if ($jquerycheckboxes1 === true) generateJSsInclude('vendor/rmariuzzo/jquery-checkboxes/dist/jquery.checkboxes-1.0.7.min.js');
+
+ // jQuery treetable
+ // NOTE: keep it after jQuery includes
+ if ($jquerytreetable3 === true) generateJSsInclude('vendor/ludo/jquery-treetable/jquery.treetable.js');
+
+ // Bootstrap 3 JS
+ // NOTE: to be kept after jQuery!
+ if ($bootstrap3 === true) generateJSsInclude('vendor/twbs/bootstrap3/dist/js/bootstrap.min.js');
+
+ // Bootstrap 5 JS
+ if ($bootstrap5 === true) generateJSsInclude('vendor/twbs/bootstrap5/dist/js/bootstrap.min.js');
+
+ // Moment JS
+ if ($momentjs2 === true)
+ {
+ generateJSsInclude('vendor/moment/momentjs/min/moment.min.js');
+ generateJSsInclude('vendor/moment/momentjs/locale/de-at.js');
+ generateJSsInclude('vendor/moment/momentjs/locale/en-ie.js');
+ }
+
+ // PivotUI JS
+ if ($pivotui2 === true) generateJSsInclude('vendor/nicolaskruchten/pivottable/dist/pivot.min.js');
+
+ // SB Admin 2 template JS
+ if ($sbadmintemplate3 === true)
+ {
+ generateJSsInclude('vendor/blackrockdigital/startbootstrap-sb-admin-2/vendor/metisMenu/metisMenu.min.js');
+ generateJSsInclude('vendor/blackrockdigital/startbootstrap-sb-admin-2/dist/js/sb-admin-2.min.js');
+ generateBackwardCompatibleJSMsIe('vendor/afarkas/html5shiv/dist/html5shiv.min.js');
+ generateBackwardCompatibleJSMsIe('vendor/scottjehl/respond/dest/respond.min.js');
+ }
+
+ // Table sorter JS
+ if ($tablesorter2 === true)
+ {
+ generateJSsInclude('vendor/mottie/tablesorter/dist/js/jquery.tablesorter.min.js');
+ generateJSsInclude('vendor/mottie/tablesorter/dist/js/jquery.tablesorter.widgets.min.js');
+ generateJSsInclude('vendor/mottie/tablesorter/dist/js/extras/jquery.tablesorter.pager.min.js');
+ }
+
+ // Tabulator 4 JS
+ if ($tabulator4 === true)
+ {
+ generateJSsInclude('vendor/olifolkerd/tabulator4/dist/js/tabulator.min.js');
+ generateJSsInclude('vendor/olifolkerd/tabulator4/dist/js/jquery_wrapper.min.js');
+ }
+
+ // Tabulator 5 JS
+ if ($tabulator5 === true) generateJSsInclude('vendor/olifolkerd/tabulator5/dist/js/tabulator.min.js');
+
+ // Tinymce 4 JS
+ if ($tinymce4 === true) generateJSsInclude('vendor/tinymce/tinymce4/tinymce.min.js');
+
+ // Tinymce 5 JS
+ if ($tinymce5 === true) generateJSsInclude('vendor/tinymce/tinymce5/tinymce.min.js');
+
+ // Vue 3 JS
+ if ($vue3 === true)
+ {
+ generateJSsInclude('vendor/vuejs/vuejs3/vue.global.prod.js');
+ generateJSsInclude('vendor/vuejs/vuerouter4/vue-router.global.js');
+ }
+
+ // PrimeVue
+ if ($primevue3)
+ {
+ generateJSsInclude('vendor/npm-asset/primevue/core/core.min.js');
+ generateJSsInclude('vendor/npm-asset/primevue/organizationchart/organizationchart.min.js');
+ generateJSsInclude('vendor/npm-asset/primevue/treetable/treetable.min.js');
+ generateJSsInclude('vendor/npm-asset/primevue/column/column.min.js');
+ generateJSsInclude('vendor/npm-asset/primevue/calendar/calendar.min.js');
+ generateJSsInclude('vendor/npm-asset/primevue/skeleton/skeleton.min.js');
+ }
+
+ // --------------------------------------------------------------------------------------------------------
+ // From public folder
+
+ // DialogLib JS
+ // NOTE: must be called before including others JS libraries that use it
+ if ($dialoglib === true) generateJSsInclude('public/js/DialogLib.js');
+
+ // AjaxLib JS
+ // NOTE: must be called before including others JS libraries that use it
+ if ($ajaxlib === true) generateJSsInclude('public/js/AjaxLib.js');
+
+ // Bootstrapper include
+ // NOTE: to be used only if you know what you are doing!
+ if ($bootstrapper === true) generateJSsInclude('public/js/bootstrapper.js');
+
+ // NavigationWidget JS
+ if ($navigationwidget === true) generateJSsInclude('public/js/NavigationWidget.js');
+
+ // FilterWidget JS
+ if ($filterwidget === true) generateJSsInclude('public/js/FilterWidget.js');
+
+ // PhrasesLib JS
+ if ($phrases != null) generateJSsInclude('public/js/PhrasesLib.js');
+
+ // TableWidget JS
+ if ($tablewidget === true) generateJSsInclude('public/js/TableWidget.js');
+
+ // User Defined Fields
+ if ($udfs === true) generateJSsInclude('public/js/UDFWidget.js');
+
+ // Load addon hooks JS
+ // NOTE: keep it as the last but one
+ if ($addons === true) generateAddonsJSsInclude($calledPath.'/'.$calledMethod);
+
+ // Eventually required JS
+ // NOTE: keep it as the latest
+ generateJSsInclude($customJSs);
+ generateJSModulesInclude($customJSModules);
+?>
+ | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|