diff --git a/application/config/navigation.php b/application/config/navigation.php index c2d221a80..d76b8a7f2 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -23,6 +23,14 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 10, 'requiredPermissions' => 'basis/vilesci:r' + ), + 'oehbeitragsverwaltung' => array( + 'link' => site_url('codex/Oehbeitrag'), + 'icon' => '', + 'description' => 'ÖH-Beitragsverwaltung', + 'expand' => true, + 'sort' => 20, + 'requiredPermissions' => 'admin:w' ) ) ), @@ -94,6 +102,13 @@ $config['navigation_header'] = array( 'description' => 'BPK Wartung', 'sort' => 20, 'requiredPermissions' => 'admin:r' + ), + 'errormonitoring' => array( + 'link' => site_url('system/issues/Issues'), + 'description' => 'Fehler Monitoring', + 'expand' => true, + 'sort' => 30, + 'requiredPermissions' => 'system/issues_verwalten:r' ) ) ), diff --git a/application/config/udfmasterschema.json b/application/config/udfmasterschema.json index fa06dc80d..ab3faa8c9 100644 --- a/application/config/udfmasterschema.json +++ b/application/config/udfmasterschema.json @@ -9,6 +9,13 @@ "name": { "type": "string" }, + "type": { + "type": "string", + "enum": ["checkbox", "textfield", "textarea", "date", "dropdown", "multipledropdown"] + }, + "requiredPermissions": { + "type": "array" + }, "description": { "type": "array", }, @@ -18,10 +25,6 @@ "title": { "type": "array", }, - "type": { - "type": "string", - "enum": ["checkbox", "textfield", "textarea", "date", "dropdown", "multipledropdown"] - }, "sort": { "type": "integer" }, @@ -67,5 +70,6 @@ } } }, - "required": ["type", "name"] -} \ No newline at end of file + "required": ["type", "name", "requiredPermissions"] +} + diff --git a/application/controllers/codex/Oehbeitrag.php b/application/controllers/codex/Oehbeitrag.php new file mode 100644 index 000000000..da8c63e08 --- /dev/null +++ b/application/controllers/codex/Oehbeitrag.php @@ -0,0 +1,269 @@ + 'admin:r',// TODO which Berechtigung? + 'getOehbeitraege' => 'admin:r', + 'getValidStudiensemester' => 'admin:r', + 'addOehbeitrag' => 'admin:rw', + 'updateOehbeitrag' => 'admin:rw', + 'deleteOehbeitrag' => 'admin:rw' + ) + ); + + $this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + $this->load->library('WidgetLib'); + + $this->loadPhrases( + array( + 'global', + 'ui', + 'oehbeitrag' + ) + ); + } + + public function index() + { + $oehbeitraege = array(); + + $oehbeitragRes = $this->_loadOehbeitraege(); + + if (isError($oehbeitragRes)) + show_error(getError($oehbeitragRes)); + + if (hasData($oehbeitragRes)) + $oehbeitraege = getData($oehbeitragRes); + + $this->load->view("codex/oehbeitrag.php", array('oehbeitraege' => $oehbeitraege)); + } + + /** + * Gets all valid, i.e. unassigned, Studiensemester. + */ + public function getValidStudiensemester() + { + $oehbeitrag_id = $this->input->get('oehbeitrag_id'); + $oehbeitrag_id_arr = isset($oehbeitrag_id) ? array($oehbeitrag_id) : null; + + $studiensemester = array(); + + $studiensemesterres = $this->OehbeitragModel->getUnassignedStudiensemester(self::STUDIENSEMESTER_START, $oehbeitrag_id_arr); + if (isError($studiensemesterres)) + { + $this->outputJsonError(getError($studiensemesterres)); + return; + } + + if (hasData($studiensemesterres)) + $studiensemester = getData($studiensemesterres); + + $this->outputJsonSuccess($studiensemester); + } + + /** + * Gets all Öhbeiträge. Wrapper function for output as JSON. + */ + public function getOehbeitraege() + { + $this->outputJson($this->_loadOehbeitraege()); + } + + /** + * Adds an Öhbeitrag. Checks for errors beforehand. + */ + public function addOehbeitrag() + { + $studierendenbeitrag = $this->input->post('studierendenbeitrag'); + $versicherung = $this->input->post('versicherung'); + $von_studiensemester_kurzbz = $this->input->post('von_studiensemester_kurzbz'); + $bis_studiensemester_kurzbz = $this->input->post('bis_studiensemester_kurzbz'); + if ($bis_studiensemester_kurzbz == 'null') + $bis_studiensemester_kurzbz = null; + + if (!$this->_checkAmount($studierendenbeitrag)) + $this->outputJsonError('Ungültiger Studierendenbeitrag'); + elseif (!$this->_checkAmount($versicherung)) + $this->outputJsonError('Ungültige Versicherung'); + else + { + $vonBisCheck = $this->_checkVonBisStudiensemester($von_studiensemester_kurzbz, $bis_studiensemester_kurzbz); + + if (isError($vonBisCheck)) + $this->outputJsonError(getError($vonBisCheck)); + else + { + $data = array( + 'studierendenbeitrag' => $studierendenbeitrag, + 'versicherung' => $versicherung, + 'von_studiensemester_kurzbz' => $von_studiensemester_kurzbz, + 'bis_studiensemester_kurzbz' => $bis_studiensemester_kurzbz + ); + + $this->outputJson($this->OehbeitragModel->insert($data)); + } + } + } + + /** + * Updates an Öhbeitrag. Checks for errors beforehand. + */ + public function updateOehbeitrag() + { + $oehbeitrag_id = $this->input->post("oehbeitrag_id"); + $data = $this->input->post("data"); + + if (!is_numeric($oehbeitrag_id) || isEmptyArray($data)) + { + $this->outputJsonError("Ungültige Parameter"); + return; + } + + foreach ($data as $idx => $value) + { + if ($idx == 'studierendenbeitrag' || $idx == 'versicherung') + { + if (!$this->_checkAmount($value)) + { + $this->outputJsonError("Ungültige(r) $idx"); + return; + } + } + elseif ($idx == 'von_studiensemester_kurzbz' || $idx == 'bis_studiensemester_kurzbz') + { + $this->OehbeitragModel->addSelect('von_studiensemester_kurzbz, bis_studiensemester_kurzbz'); + $vonBisStudiensemesterRes = $this->OehbeitragModel->load($oehbeitrag_id); + + if (!hasData($vonBisStudiensemesterRes)) + { + $this->outputJsonError("Fehler beim Holen des Öhbeitrags"); + return; + } + + $vonBisStudiensemester = getData($vonBisStudiensemesterRes); + + $von_studiensemester_kurzbz = isset($data['von_studiensemester_kurzbz']) + ? $data['von_studiensemester_kurzbz'] + : $vonBisStudiensemester[0]->von_studiensemester_kurzbz; + + if (isset($data['bis_studiensemester_kurzbz'])) + { + $bis_studiensemester_kurzbz = $data['bis_studiensemester_kurzbz'] = $data['bis_studiensemester_kurzbz'] == 'null' ? null : $data['bis_studiensemester_kurzbz']; + } + else + $bis_studiensemester_kurzbz = $vonBisStudiensemester[0]->bis_studiensemester_kurzbz; + + $checkStudiensemester = $this->_checkVonBisStudiensemester($von_studiensemester_kurzbz, $bis_studiensemester_kurzbz, $oehbeitrag_id); + + if (isError($checkStudiensemester)) + { + $this->outputJsonError(getError($checkStudiensemester)); + return; + } + } + } + + $this->outputJson($this->OehbeitragModel->update($oehbeitrag_id, $data)); + } + + /** + * Deletes an Öhbeitrag. + */ + public function deleteOehbeitrag() + { + $oehbeitrag_id = $this->input->post("oehbeitrag_id"); + + $this->outputJson($this->OehbeitragModel->delete($oehbeitrag_id)); + } + + /** + * Loads all Öhbeiträge sorted by date descending. + * @return object + */ + private function _loadOehbeitraege() + { + $this->OehbeitragModel->addSelect('oehbeitrag_id, von_studiensemester_kurzbz, bis_studiensemester_kurzbz, studierendenbeitrag, versicherung, sem_von.start as von_datum, sem_bis.ende as bis_datum'); + $this->OehbeitragModel->addJoin('public.tbl_studiensemester sem_von', 'tbl_oehbeitrag.von_studiensemester_kurzbz = sem_von.studiensemester_kurzbz'); + $this->OehbeitragModel->addJoin('public.tbl_studiensemester sem_bis', 'tbl_oehbeitrag.bis_studiensemester_kurzbz = sem_bis.studiensemester_kurzbz', 'LEFT'); + $this->OehbeitragModel->addOrder('sem_von.start', 'DESC'); + return $this->OehbeitragModel->load(); + } + + /** + * Checks if an amount is numeric and not too big. + * @param $amount + * @return bool true if valid amount, false otherwise + */ + private function _checkAmount($amount) + { + return is_numeric($amount) && (float) $amount <= 99999.99; + } + + /** + * Checks if a certain Von-Studiensemester is valid together with a Bis-Studiensemester. + * Checks for correct format, Von-Studiensemester cannot be after the Bis-Studiensemester, + * checks that semester are not overlapping with semester for existent Öhbeiträge. + * @param string $von_studiensemester_kurzbz + * @param string $bis_studiensemester_kurzbz + * @param int $oehbeitrag_id öhbeitrag to ignore, i.e. which is assignable (id of Öhbeitrag of the passed semesters) + * @return object array with true if assignable, with false if not + */ + private function _checkVonBisStudiensemester($von_studiensemester_kurzbz, $bis_studiensemester_kurzbz, $oehbeitrag_id = null) + { + $regex = "/^(WS|SS)\d{4}$/"; + if (!preg_match($regex, $von_studiensemester_kurzbz)) + return error("Ungültiges Von-Studiensemester"); + + if (!preg_match($regex, $bis_studiensemester_kurzbz) && $bis_studiensemester_kurzbz != null) + return error("Ungültiges Bis-Studiensemester"); + + $this->StudiensemesterModel->addSelect("start"); + $vonStudiensemesterRes = $this->StudiensemesterModel->load($von_studiensemester_kurzbz); + + if (!hasData($vonStudiensemesterRes)) + return error("Fehler beim Holen von Von-Studiensemester"); + + $this->StudiensemesterModel->addSelect("start"); + $bisStudiensemesterRes = $this->StudiensemesterModel->load($bis_studiensemester_kurzbz); + + if (!hasData($bisStudiensemesterRes)) + return error("Fehler beim Holen von Bis-Studiensemester"); + + $vonStudiensemester = getData($vonStudiensemesterRes)[0]->start; + $bisStudiensemester = getData($bisStudiensemesterRes)[0]->start; + + if ($bis_studiensemester_kurzbz != null && new DateTime($vonStudiensemester) > new DateTime($bisStudiensemester)) + return error("Von-Studiensemester größer als Bis-Studiensemester"); + + $oehbeitrag_id_arr = isset($oehbeitrag_id) ? array($oehbeitrag_id) : null; + + $assignableRes = $this->OehbeitragModel->checkIfStudiensemesterAssignable( + $von_studiensemester_kurzbz, + $bis_studiensemester_kurzbz, + $oehbeitrag_id_arr + ); + + if (isError($assignableRes)) + return $assignableRes; + + if (hasData($assignableRes)) + { + $assignable = getData($assignableRes)[0]; + + if (!$assignable) + return error("Keine Zuweisung möglich, Semesterüberschneidung"); + } + + return success("Studiensemester gültig"); + } +} diff --git a/application/controllers/system/FAS_UDF.php b/application/controllers/system/FAS_UDF.php index febe266c7..ecaa44393 100644 --- a/application/controllers/system/FAS_UDF.php +++ b/application/controllers/system/FAS_UDF.php @@ -31,7 +31,7 @@ class FAS_UDF extends Auth_Controller if (isset($person_id) && is_numeric($person_id)) { - if ($this->PersonModel->hasUDF()) + if ($this->PersonModel->udfsExistAndDefined()) { $personUdfs = $this->PersonModel->getUDFs($person_id); $data['person_id'] = $person_id; @@ -41,7 +41,7 @@ class FAS_UDF extends Auth_Controller if (isset($prestudent_id) && is_numeric($prestudent_id)) { - if ($this->PrestudentModel->hasUDF()) + if ($this->PrestudentModel->udfsExistAndDefined()) { $prestudentUdfs = $this->PrestudentModel->getUDFs($prestudent_id); $data['prestudent_id'] = $prestudent_id; diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index cd88f814a..9e68c5cb8 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -297,6 +297,13 @@ class InfoCenter extends Auth_Controller } $persondata = $this->_loadPersonData($person_id); + + $checkPerson = $this->PersonModel->checkDuplicate($person_id); + + if (isError($checkPerson)) show_error(getError($checkPerson)); + + $duplicate = array('duplicated' => getData($checkPerson)); + $prestudentdata = $this->_loadPrestudentData($person_id); $this->DokumentModel->addOrder('bezeichnung'); @@ -305,7 +312,8 @@ class InfoCenter extends Auth_Controller $data = array_merge( $persondata, $prestudentdata, - $dokumentdata + $dokumentdata, + $duplicate ); $data[self::FHC_CONTROLLER_ID] = $this->getControllerId(); @@ -734,7 +742,7 @@ class InfoCenter extends Auth_Controller if (hasData($lastStatus) && hasData($statusgrresult)) { - //check if still Interessent + //check if still Interessent, Bewerber or Wartender if ($lastStatus->retval[0]->status_kurzbz === self::INTERESSENTSTATUS || $lastStatus->retval[0]->status_kurzbz === self::BEWERBERSTATUS || $lastStatus->retval[0]->status_kurzbz === self::WARTENDER) @@ -2134,17 +2142,18 @@ class InfoCenter extends Auth_Controller { $statusgrund = $this->input->post('statusgrund'); $studiengang = $this->input->post('studiengang'); + $abgeschickt = $this->input->post('abgeschickt'); $personen = $this->input->post('personen'); $studienSemester = $this->variablelib->getVar('infocenter_studiensemester'); - if ($statusgrund === 'null' || $studiengang === 'null' || empty($personen)) - $this->terminateWithJsonError("Bitte Statusgrund, Studiengang und Personen auswählen."); + if ($statusgrund === 'null' || $studiengang === 'null' || $abgeschickt === 'null' || empty($personen)) + $this->terminateWithJsonError("Bitte füllen Sie alle Felder aus"); foreach($personen as $person) { - $prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester); + $prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt); - if(!hasData($prestudent)) + if (!hasData($prestudent)) continue; $prestudentData = getData($prestudent); diff --git a/application/controllers/system/issues/Issues.php b/application/controllers/system/issues/Issues.php new file mode 100644 index 000000000..e9764fb63 --- /dev/null +++ b/application/controllers/system/issues/Issues.php @@ -0,0 +1,145 @@ + array(self::BERECHTIGUNG_KURZBZ.':r'), + 'changeIssueStatus' => array(self::BERECHTIGUNG_KURZBZ.':rw') + ) + ); + + // Load libraries + $this->load->library('IssuesLib'); + $this->load->library('PermissionLib'); + $this->load->library('WidgetLib'); + + // Load models + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); + + $this->loadPhrases( + array( + 'global', + 'ui', + 'filter', + 'lehre', + 'person', + 'fehlermonitoring' + ) + ); + + $this->_setAuthUID(); // sets property uid + } + + public function index() + { + $oes_for_issues = $this->_getOesForIssues(); + + $this->load->view( + 'system/issues/issues', + $oes_for_issues + ); + } + + /** + * Initializes issues status change + */ + public function changeIssueStatus() + { + $issue_ids = $this->input->post('issue_ids'); + $status_kurzbz = $this->input->post('status_kurzbz'); + $verarbeitetvon = $this->_uid; + + $errors = array(); + foreach ($issue_ids as $issue_id) + { + $issueRes = $this->issueslib->changeIssueStatus($issue_id, $status_kurzbz, $verarbeitetvon); + + if (isError($issueRes)) + $errors[] = getError($issueRes); + } + + if (!isEmptyArray($errors)) + $this->outputJsonError(implode(", ", $errors)); + else + $this->outputJsonSuccess("Status erfolgreich aktualisiert"); + } + + /** + * 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'); + } + + /** + * Gets oes of logged in user, which are needed to display issues of the user. + * This includes oes assigned by a funktio and as the issue permission. + * @return array + */ + private function _getOesForIssues() + { + // get oes of uid for which there is a current funktion + $all_funktionen_oe_kurzbz = array(); + $oe_kurzbz_for_funktion = array(); + $benutzerfunktionRes = $this->BenutzerfunktionModel->getBenutzerFunktionByUid($this->_uid, null, date('Y-m-d'), date('Y-m-d')); + + if (isError($benutzerfunktionRes)) + show_error(getError($benutzerfunktionRes)); + + if (hasData($benutzerfunktionRes)) + { + foreach (getData($benutzerfunktionRes) as $benutzerfunktion) + { + $all_funktionen_oe_kurzbz[$benutzerfunktion->oe_kurzbz][] = $benutzerfunktion->funktion_kurzbz; + + // separate oes for the funktion needed for displaying issues + if ($benutzerfunktion->funktion_kurzbz == self::FUNKTION_KURZBZ) + { + $oe_kurzbz_for_funktion[] = $benutzerfunktion->oe_kurzbz; + + // permission also for all oes under the oe for which funktion is assigend + $childOesFunktionRes = $this->OrganisationseinheitModel->getChilds($benutzerfunktion->oe_kurzbz); + + if (isError($childOesFunktionRes)) + show_error(getError($childOesFunktionRes)); + + if (hasData($childOesFunktionRes)) + { + $childOesFunktion = getData($childOesFunktionRes); + + foreach ($childOesFunktion as $childOeFunktion) + { + if (!in_array($childOeFunktion->oe_kurzbz, $oe_kurzbz_for_funktion)) + $oe_kurzbz_for_funktion[] = $childOeFunktion->oe_kurzbz; + } + } + } + } + } + + // add oes for which there is the "manage issues" Berechtigung + if (!$oe_kurzbz_berechtigt = $this->permissionlib->getOE_isEntitledFor(self::BERECHTIGUNG_KURZBZ)) + show_error('Keine Berechtigung oder Fehler bei Berechtigungsprüfung'); + + $all_oe_kurzbz_berechtigt = array_unique(array_merge($oe_kurzbz_for_funktion, $oe_kurzbz_berechtigt)); + + return array( + 'all_funktionen_oe_kurzbz' => $all_funktionen_oe_kurzbz, + 'all_oe_kurzbz_berechtigt' => $all_oe_kurzbz_berechtigt + ); + } +} diff --git a/application/controllers/widgets/UDF.php b/application/controllers/widgets/UDF.php index 5b4c45776..26c30293c 100644 --- a/application/controllers/widgets/UDF.php +++ b/application/controllers/widgets/UDF.php @@ -26,9 +26,6 @@ class UDF extends FHC_Controller // Loads the UDFLib with HTTP GET/POST parameters $this->_loadUDFLib(); - - // Checks if the caller is allow to use this UDF widget - $this->_isAllowed(); } //------------------------------------------------------------------------------------------------------------------ @@ -39,7 +36,6 @@ class UDF extends FHC_Controller */ public function saveUDFs() { - $udfUniqueId = $this->input->post(self::UDF_UNIQUE_ID); $udfs = $this->input->post(UDFLib::UDFS_ARG_NAME); if (!isEmptyString($udfs)) @@ -47,7 +43,7 @@ class UDF extends FHC_Controller $jsonDecodedUDF = json_decode($udfs); if ($jsonDecodedUDF != null) { - $this->outputJson($this->udflib->saveUDFs($udfUniqueId, $jsonDecodedUDF)); + $this->outputJson($this->udflib->saveUDFs($jsonDecodedUDF)); } else { @@ -63,17 +59,6 @@ class UDF extends FHC_Controller //------------------------------------------------------------------------------------------------------------------ // Private methods - /** - * Checks if the user is allowed to use this UDFWidget - */ - private function _isAllowed() - { - if (!$this->udflib->isAllowed()) - { - $this->terminateWithJsonError('You are not allowed to access to this content'); - } - } - /** * Loads the UDFLib with the UDF_UNIQUE_ID parameter * If the parameter UDF_UNIQUE_ID is not given then the execution of the controller is terminated and @@ -105,3 +90,4 @@ class UDF extends FHC_Controller } } } + diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index 4b89ae5bf..4e555be6c 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -86,7 +86,7 @@ class DB_Model extends CI_Model if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); // If this table has UDF and the validation of them is ok - if (isError($validate = $this->_manageUDFs($data, $this->dbTable))) return $validate; + if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable))) return $validate; // DB-INSERT $insert = $this->db->insert($this->dbTable, $data); @@ -137,7 +137,7 @@ class DB_Model extends CI_Model if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); // If this table has UDF and the validation of them is ok - if (isError($validate = $this->_manageUDFs($data, $this->dbTable, $id))) return $validate; + if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable, $id))) return $validate; $tmpId = $id; @@ -670,6 +670,7 @@ class DB_Model extends CI_Model /** * Returns all the UDF contained in this table ($dbTable) * If no UDF are present, an empty array will be returned + * NOTE: only the UDFs that the logged user is allowed to read are loaded by this method */ public function getUDFs($id, $udfName = null) { @@ -700,9 +701,9 @@ class DB_Model extends CI_Model } /** - * Checks if this table has the field udf_values + * Checks if this table has the field udf_values and if there is a UDF definition for this table */ - public function hasUDF() + public function udfsExistAndDefined() { if ($this->fieldExists(UDFLib::COLUMN_NAME)) { @@ -844,25 +845,25 @@ class DB_Model extends CI_Model } /** - * Wrapper method for UDFLib->manageUDFs + * Wrapper method for UDFLib->prepareUDFsWrite */ - private function _manageUDFs(&$data, $schemaAndTable, $id = null) + private function _prepareUDFsWrite(&$data, $schemaAndTable, $id = null) { - $manageUDFs = success(); + $prepareUDFsWrite = success(); - if ($this->hasUDF()) + if ($this->udfsExistAndDefined()) { if ($id != null) { - $manageUDFs = $this->udflib->manageUDFs($data, $this->dbTable, $this->getUDFs($id)); + $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $this->dbTable, $this->_getUDFsNoPerms($id)); } else { - $manageUDFs = $this->udflib->manageUDFs($data, $this->dbTable); + $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $this->dbTable); } } - return $manageUDFs; + return $prepareUDFsWrite; } /** @@ -874,9 +875,10 @@ class DB_Model extends CI_Model */ private function _toPhp($result) { + $udfs = false; // if UDFs are inside the given result set $toPhp = $result; // if there is nothing to convert then return the result from DB - // If it's an object its fields will be parsed to find booleans and arrays types + // If it's an object its fields will be parsed to find booleans, arrays and UDFs types if (is_object($result)) { $toBeConverterdArray = array(); // Fields to be converted @@ -884,40 +886,48 @@ class DB_Model extends CI_Model $this->executedQueryMetaData = $result->field_data(); // Fields information $this->executedQueryListFields = $result->list_fields(); // List of the retrieved fields - for ($i = 0; $i < count($this->executedQueryMetaData); $i++) // Looking for booleans and arrays + // Looking for booleans, arrays and UDFs + foreach ($this->executedQueryMetaData as $eqmd) { // If array type, boolean type OR a UDF - if (strpos($this->executedQueryMetaData[$i]->type, DB_Model::PGSQL_ARRAY_TYPE) !== false - || $this->executedQueryMetaData[$i]->type == DB_Model::PGSQL_BOOLEAN_TYPE - || $this->udflib->isUDFColumn($this->executedQueryMetaData[$i]->name, $this->executedQueryMetaData[$i]->type)) + if (strpos($eqmd->type, DB_Model::PGSQL_ARRAY_TYPE) !== false + || $eqmd->type == DB_Model::PGSQL_BOOLEAN_TYPE + || $this->udflib->isUDFColumn($eqmd->name, $eqmd->type)) { - // Name and type of the field to be converted - $toBeConverted = new stdClass(); - // Set the type of the field to be converted - $toBeConverted->type = $this->executedQueryMetaData[$i]->type; - // Set the name of the field to be converted - $toBeConverted->name = $this->executedQueryMetaData[$i]->name; - // Add the field to be converted to $toBeConverterdArray - array_push($toBeConverterdArray, $toBeConverted); + // If UDFs are inside this result set + if ($this->udflib->isUDFColumn($eqmd->name, $eqmd->type)) + { + $udfs = true; + } + else // all the other cases + { + // Name and type of the field to be converted + $toBeConverted = new stdClass(); + // Set the type of the field to be converted + $toBeConverted->type = $eqmd->type; + // Set the name of the field to be converted + $toBeConverted->name = $eqmd->name; + // Add the field to be converted to $toBeConverterdArray + array_push($toBeConverterdArray, $toBeConverted); + } } } - // If there is something to convert, otherwhise don't lose time - if (count($toBeConverterdArray) > 0) - { - // Returns the array of objects, each of them represents a DB record - $resultsArray = $result->result(); - // Looping on results - for ($i = 0; $i < count($resultsArray); $i++) - { - // Single element - $resultElement = $resultsArray[$i]; - // Looping on fields to be converted - for ($j = 0; $j < count($toBeConverterdArray); $j++) - { - // Single element - $toBeConverted = $toBeConverterdArray[$j]; + // Returns the array of objects, each of them represents a DB record + $resultsArray = $result->result(); + // If in this result set there are UDFs then prepare them + if ($udfs) $this->udflib->prepareUDFsRead($resultsArray, $this->dbTable); + + // If there is something to convert, otherwhise don't waste time + if (!isEmptyArray($toBeConverterdArray)) + { + // Looping on results + foreach ($resultsArray as $resultElement) + { + // Looping on fields to be converted + foreach ($toBeConverterdArray as $toBeConverted) + { // Array type if (strpos($toBeConverted->type, DB_Model::PGSQL_ARRAY_TYPE) !== false) { @@ -931,30 +941,12 @@ class DB_Model extends CI_Model { $resultElement->{$toBeConverted->name} = $this->pgBoolPhp($resultElement->{$toBeConverted->name}); } - // UDF - elseif ($this->udflib->isUDFColumn($toBeConverted->name, $toBeConverted->type)) - { - $jsonValues = json_decode($resultElement->{$toBeConverted->name}); // decode UDFs values - if ($jsonValues != null) // if decode is ok - { - // For every UDF - foreach ($jsonValues as $key => $value) - { - $resultElement->{$key} = $value; // create a new element called like the UDF - } - } - unset($resultElement->{UDFLib::COLUMN_NAME}); // remove udf_values from the response - } } } - // Returns DB data as an array - $toPhp = $resultsArray; - } - // And returns DB data as an array - else - { - $toPhp = $result->result(); } + + // Returns DB data as an array + $toPhp = $resultsArray; } return $toPhp; @@ -998,4 +990,48 @@ class DB_Model extends CI_Model { if ($this->debugMode) $this->loglib->logDebug($this->db->last_query()); } + + /** + * Returns all the UDF contained in this table ($dbTable) + * If no UDF are present, an empty array will be returned + * NOTE: it returns all the UDFs, does _not_ check the permissions + */ + private function _getUDFsNoPerms($id) + { + $udfs = array(); + + $this->db->select(UDFLib::COLUMN_NAME, true); // get only the UDF column + + // Primary key management + $tmpId = $id; + + // Check for composite Primary Key + if (is_array($id)) + { + if (isset($id[0])) + { + $tmpId = $this->_arrayCombine($this->pk, $id); + } + } + elseif ($id != null) + { + $tmpId = array($this->pk => $id); + } + + // Read the record from the table + $result = $this->db->get_where($this->dbTable, $tmpId); + + // If was a success and there are data + if ($result && count($result->result()) == 1) + { + // Get the UDF column and decode it from JSON + $jsonValues = json_decode($result->result()[0]->{UDFLib::COLUMN_NAME}); + + // If the JSON convertion was fine convert the object to an array + if ($jsonValues != null) $udfs = get_object_vars($jsonValues); + } + + return $udfs; + } } + diff --git a/application/core/JQW_Controller.php b/application/core/JQW_Controller.php index 361efd998..1bc4cd346 100644 --- a/application/core/JQW_Controller.php +++ b/application/core/JQW_Controller.php @@ -70,6 +70,19 @@ abstract class JQW_Controller extends JOB_Controller return $jobs; } + /** + * To get all the jobs specified by the given parameters + */ + protected function getJobsByTypeStatus($type, $status) + { + $jobs = $this->jobsqueuelib->getJobsByTypeStatus($type, $status); + + // If an error occurred then log it in database + if (isError($jobs)) $this->logError(getError($jobs), array($type, $status)); + + return $jobs; + } + /** * To get all the jobs specified by the given parameters */ diff --git a/application/libraries/FilterWidgetLib.php b/application/libraries/FilterWidgetLib.php index cdf0cac3c..d9a3428a0 100644 --- a/application/libraries/FilterWidgetLib.php +++ b/application/libraries/FilterWidgetLib.php @@ -203,7 +203,7 @@ class FilterWidgetLib // Loops in the session for all the filter widgets foreach ($filterWidgetsSession as $filterWidget => $filterWidgetData) { - // If this filter widget is not the currrent used filter widget and the it is expired... + // If this filter widget is not the current used filter widget and the it is expired... if ($this->_filterUniqueId != $filterWidget && $filterWidgetData[self::SESSION_TIMEOUT] <= time()) { cleanSessionElement(self::SESSION_NAME, $filterWidget); // ...remove it @@ -232,7 +232,7 @@ class FilterWidgetLib if ($filterId != null && is_numeric($filterId) && $filterId > 0) { $whereParameters = array( - 'filter_id' => $filterId + self::FILTER_ID => $filterId ); } else @@ -279,6 +279,18 @@ class FilterWidgetLib 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; @@ -712,8 +724,11 @@ class FilterWidgetLib { $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // to remove the filter definitions from DB - // delete it! - $this->_ci->FiltersModel->delete(array('filter_id' => $filterId)); + // Delete it from database + $this->_ci->FiltersModel->delete(array(self::FILTER_ID => $filterId)); + + // Delete it from session + $this->_dropFromSessionFilterWidgetById($filterId); $removeCustomFilter = true; } @@ -735,7 +750,7 @@ class FilterWidgetLib $session = $this->getSession(); // The filter currently stored in session (the one that is currently used) if ($session != null) { - // Loads the Fitlers model + // 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) @@ -761,7 +776,7 @@ class FilterWidgetLib '%s?%s=%s', site_url($navigationPage), self::FILTER_ID, - $filter->filter_id + $filter->{self::FILTER_ID} ) // link ); @@ -774,7 +789,7 @@ class FilterWidgetLib { $menuEntry['subscriptDescription'] = 'Remove'; $menuEntry['subscriptLinkClass'] = 'remove-custom-filter'; - $menuEntry['subscriptLinkValue'] = $filter->filter_id; + $menuEntry['subscriptLinkValue'] = $filter->{self::FILTER_ID}; $childrenPersonalArray[] = $menuEntry; // adds to personal filters menu array } } @@ -974,5 +989,29 @@ class FilterWidgetLib return $pos; } + + /** + * Remove from the session the given filter widget + */ + private function _dropFromSessionFilterWidgetById($filterId) + { + // Loads the session for all the filter widgets + $filterWidgetsSession = getSession(self::SESSION_NAME); + + // If something is present in session + if ($filterWidgetsSession != null) + { + // Loops in the session for all the filter widgets + foreach ($filterWidgetsSession as $filterWidget => $filterWidgetData) + { + // If this filter widget is not the one that we are looking for + if ($filterWidgetData[self::FILTER_ID] == $filterId) + { + cleanSessionElement(self::SESSION_NAME, $filterWidget); // ...remove it + break; // stop to search + } + } + } + } } diff --git a/application/libraries/IssuesLib.php b/application/libraries/IssuesLib.php new file mode 100644 index 000000000..1b06db333 --- /dev/null +++ b/application/libraries/IssuesLib.php @@ -0,0 +1,244 @@ +_ci =& get_instance(); + + // Properties default values + $this->_app = 'core'; + $this->_insertvon = 'system'; + $this->_fallbackFehlercode = 'UNKNOWN_ERROR'; + + // If parameters are given then overwrite the default values + if (!isEmptyArray($params)) $this->setConfigs($params); + + // load models + $this->_ci->load->model('system/Issue_model', 'IssueModel'); + $this->_ci->load->model('system/Fehler_model', 'FehlerModel'); + } + + // -------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Store configuration parameters for this lib + */ + public function setConfigs($params) + { + // If parameters are given then overwrite the default values + if (!isEmptyArray($params)) + { + if (isset($params[self::APP_INDEX])) $this->_app = $params[self::APP_INDEX]; + if (isset($params[self::INSERTVON_INDEX])) $this->_insertvon = $params[self::INSERTVON_INDEX]; + if (isset($params[self::FALLBACK_FEHLERCODE_INDEX])) $this->_fallbackFehlercode = $params[self::FALLBACK_FEHLERCODE_INDEX]; + } + } + + /** + * Adds an Fhc issue, i.e. an internal, self-defined issue. + * @param string $fehler_kurzbz short unique text name of the issue + * @param int $person_id + * @param string $oe_kurzbz + * @param array $fehlertext_params params for sprint replace of error text in system.tbl_fehler + * @return object success or error + */ + public function addFhcIssue($fehler_kurzbz, $person_id = null, $oe_kurzbz = null, $fehlertext_params = null) + { + $fehlerRes = $this->_ci->FehlerModel->loadWhere(array('fehler_kurzbz' => $fehler_kurzbz)); + + if (hasData($fehlerRes)) + { + $fehlercode = getData($fehlerRes)[0]->fehlercode; + return $this->_addIssue($fehlercode, $person_id, $oe_kurzbz, $fehlertext_params); + } + else + return error("Fehler $fehler_kurzbz nicht gefunden"); + } + + /** + * Adds an external issue, already defined externally by another system. + * @param string $fehlercode_extern the error code in the external system + * @param string $inhalt_extern error text in external system + * @param int $person_id + * @param int $oe_kurzbz + * @param array $fehlertext_params params for replacement of parts of error text + * @param bool $force_predefined if true, only predefined external issues are added + * @return object success or error + */ + public function addExternalIssue($fehlercode_extern, $inhalt_extern, $person_id = null, $oe_kurzbz = null, $fehlertext_params = null, $force_predefined = false) + { + if (isEmptyString($fehlercode_extern)) + return error("fehlercode_extern fehlt"); + + // get external fehlercode (unique for each app) + $this->_ci->FehlerModel->addSelect('fehlercode'); + $fehlerRes = $this->_ci->FehlerModel->loadWhere( + array( + 'fehlercode_extern' => $fehlercode_extern, + 'app' => $this->_app + ) + ); + + if (isError($fehlerRes)) + return $fehlerRes; + + $fehlerData = getData($fehlerRes)[0]; + + // check if there is a predefined custom error for the external issue + if (hasData($fehlerRes)) + { + // if found, use the code + $fehlercode = $fehlerData->fehlercode; + } + elseif ($force_predefined === true) + { + // only added if predefined + return success("No definition found - not added"); + } + else + { + // if predefined error is not found, insert with fallback code + $fehlercode = $this->_fallbackFehlercode; + } + + // add external issue + return $this->_addIssue($fehlercode, $person_id, $oe_kurzbz, $fehlertext_params, $fehlercode_extern, $inhalt_extern); + } + + /** + * Changes status of an issue. + * @param int $issue_id + * @param string $status_kurzbz the new status + * @param string $verarbeitetvon uid of person changing the status (needed for in Bearbeitung and behoben) + * @return success or error + */ + public function changeIssueStatus($issue_id, $status_kurzbz, $verarbeitetvon = null) + { + if (!isset($issue_id) || !is_numeric($issue_id)) + return error("Issue Id muss korrekt gesetzt sein."); + + // check if given status is same as existing + $this->_ci->IssueModel->addSelect('status_kurzbz'); + $currStatus = $this->_ci->IssueModel->load($issue_id); + + if (hasData($currStatus)) + { + if (getData($currStatus)[0]->status_kurzbz == $status_kurzbz) + return success("Gleicher Status bereits gesetzt"); + } + else + return error("Fehler beim Holen des Status"); + + $data = array( + 'status_kurzbz' => $status_kurzbz, + 'updatevon' => $verarbeitetvon, + 'updateamum' => date('Y-m-d H:i:s') + ); + + if ($status_kurzbz == self::STATUS_NEU) + { + + $data['verarbeitetvon'] = null; + } + + if ($status_kurzbz == self::STATUS_NEU || $status_kurzbz == self::STATUS_IN_BEARBEITUNG) + { + $data['verarbeitetamum'] = null; + } + + if ($status_kurzbz == self::STATUS_IN_BEARBEITUNG || $status_kurzbz == self::STATUS_BEHOBEN) + { + if (isset($verarbeitetvon)) + $data['verarbeitetvon'] = $verarbeitetvon; + else + return error("Verarbeitetvon nicht gesetzt"); + } + + if ($status_kurzbz == self::STATUS_BEHOBEN) + $data['verarbeitetamum'] = date('Y-m-d H:i:s'); + + return $this->_ci->IssueModel->update( + array( + 'issue_id' => $issue_id + ), + $data + ); + } + + /** + * Adds an issue. + * @param $fehlercode + * @param int $person_id + * @param string $oe_kurzbz + * @param array $fehlertext_params + * @param string $fehlercode_extern + * @param string $inhalt_extern + * @return object success or error + */ + private function _addIssue($fehlercode, $person_id = null, $oe_kurzbz = null, $fehlertext_params = null, $fehlercode_extern = null, $inhalt_extern = null) + { + if (isEmptyString($person_id) && isEmptyString($oe_kurzbz)) + return error("Person_id oder oe_kurzbz muss gesetzt sein."); + + // get fehlertextVorlage and replace it with params + $fehlerRes = $this->_ci->FehlerModel->load($fehlercode); + + if (hasData($fehlerRes)) + { + $fehlertextVorlage = getData($fehlerRes)[0]->fehlertext; + $fehlertext = isEmptyArray($fehlertext_params) ? $fehlertextVorlage : vsprintf($fehlertextVorlage, $fehlertext_params); + + $openIssuesCountRes = $this->_ci->IssueModel->getOpenIssueCount($fehlercode, $person_id, $oe_kurzbz, $fehlercode_extern); + + if (hasData($openIssuesCountRes)) + { + // don't insert if issue is already open + // already open - status new with same fehlercode or same fehlercode-extern (if set) + $openIssueCount = getData($openIssuesCountRes)[0]->anzahl_open_issues; + + if ($openIssueCount == 0) + { + return $this->_ci->IssueModel->insert( + array( + 'fehlercode' => $fehlercode, + 'fehlercode_extern' => $fehlercode_extern, + 'inhalt' => $fehlertext, + 'inhalt_extern' => $inhalt_extern, + 'person_id' => $person_id, + 'oe_kurzbz' => $oe_kurzbz, + 'datum' => date('Y-m-d H:i:s'), + 'status_kurzbz' => self::STATUS_NEU, + 'insertvon' => $this->_insertvon + ) + ); + } + else + return success($openIssueCount); + } + else + return error("Anzahl offener Issues konnte nicht ermittelt werden."); + } + else + return error("Fehler $fehlercode nicht gefunden"); + } +} diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index d264f7119..5871a3767 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -72,6 +72,18 @@ class JobsQueueLib return $this->_ci->JobsQueueModel->loadWhere(array('status' => self::STATUS_NEW, 'type' => $type)); } + /** + * To get all the jobs specified by the given parameters + */ + public function getJobsByTypeStatus($type, $status) + { + $this->_ci->JobsQueueModel->resetQuery(); + + $this->_ci->JobsQueueModel->addOrder('creationtime', 'DESC'); + + return $this->_ci->JobsQueueModel->loadWhere(array('status' => $status, 'type' => $type)); + } + /** * To get all the jobs specified by the given parameters */ diff --git a/application/libraries/UDFLib.php b/application/libraries/UDFLib.php index f9ad7d20d..c5f0d3e98 100644 --- a/application/libraries/UDFLib.php +++ b/application/libraries/UDFLib.php @@ -30,13 +30,14 @@ class UDFLib // ...to specify permissions that are needed to use this TableWidget const REQUIRED_PERMISSIONS_PARAMETER = 'requiredPermissions'; + const PERMISSION_TABLE_METHOD = 'UDFWidget'; // Name for fake method to be checked by the PermissionLib + const PERMISSION_TYPE_READ = 'r'; + const PERMISSION_TYPE_WRITE = 'w'; + // ...to specify the primary key name and value const PRIMARY_KEY_NAME = 'primaryKeyName'; const PRIMARY_KEY_VALUE = 'primaryKeyValue'; - const PERMISSION_TABLE_METHOD = 'UDFWidget'; // Name for fake method to be checked by the PermissionLib - const PERMISSION_TYPE = 'rw'; - // HTML components const LABEL = 'title'; const TITLE = 'description'; @@ -76,10 +77,10 @@ class UDFLib // Public methods /** - * UDFWidget - */ - public function UDFWidget($args, $htmlArgs = array()) - { + * UDFWidget + */ + public function UDFWidget($args, $htmlArgs = array()) + { if ((isset($args[self::SCHEMA_ARG_NAME]) && !isEmptyString($args[self::SCHEMA_ARG_NAME])) && (isset($args[self::TABLE_ARG_NAME]) && !isEmptyString($args[self::TABLE_ARG_NAME]))) { @@ -112,16 +113,17 @@ class UDFLib show_error(self::TABLE_ARG_NAME.' parameter is missing!'); } } - } + } - /** + /** * It renders the HTML of the UDF * * NOTE: When this method is called $widgetData contains different data from * parameter $args in the constructor */ - public function displayUDFWidget(&$widgetData) + public function displayUDFWidget(&$widgetData) { + $field = null; $schema = $widgetData[self::SCHEMA_ARG_NAME]; // schema attribute $table = $widgetData[self::TABLE_ARG_NAME]; // table attribute @@ -133,7 +135,7 @@ class UDFLib $udfResults = $this->_loadUDF($schema, $table); // loads UDF definition if (hasData($udfResults)) { - $udf = $udfResults->retval[0]; // only one record is loaded + $udf = getData($udfResults)[0]; // only one record is loaded if (isset($udf->jsons)) { $jsonSchemas = json_decode($udf->jsons); // decode the json schema @@ -155,7 +157,7 @@ class UDFLib $found = false; // used to check if the field is found or not in the json schema $this->_sortJsonSchemas($jsonSchemasArray); // Sort the list of UDF by sort property - + // Loops through json schemas foreach ($jsonSchemasArray as $jsonSchema) { @@ -169,21 +171,37 @@ class UDFLib { show_error(sprintf('%s.%s: Attribute "name" not present in the json schema', $schema, $table)); } + // If the requiredPermissions property is not present then show an error + if (!isset($jsonSchema->{self::REQUIRED_PERMISSIONS_PARAMETER})) + { + show_error(sprintf('%s.%s: Attribute "requiredPermissions" not present in the json schema', $schema, $table)); + } + + // Set the required permissions for this UDF + $this->_setRequiredPermissions($jsonSchema->{self::NAME}, $jsonSchema->{self::REQUIRED_PERMISSIONS_PARAMETER}); // If a UDF is specified and is present in the json schemas list or no UDF is specified if ((isset($field) && $field == $jsonSchema->{self::NAME}) || !isset($field)) { - // Set attributes using phrases - $this->_setAttributesWithPhrases($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); + // If the user has the permissions to read this field + if ($this->_readAllowed($jsonSchema->{self::REQUIRED_PERMISSIONS_PARAMETER})) + { + // Set attributes using phrases + $this->_setAttributesWithPhrases($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); - // Set validation attributes - $this->_setValidationAttributes($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); + // Set validation attributes + $this->_setValidationAttributes($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); - // Set name and id attributes - $this->_setNameAndId($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); + // Set name and id attributes + $this->_setNameAndId($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); - // Render the HTML for this UDF - $this->_render($jsonSchema, $widgetData); + // Set if the field is in read only mode + $this->_setReadOnly($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); + + // Render the HTML for this UDF + $this->_render($jsonSchema, $widgetData); + } + // otherwise the UDF is not displayed // If a UDf is specified and it was found then stop looking through this list if (isset($field) && $field == $jsonSchema->{self::NAME}) @@ -213,12 +231,97 @@ class UDFLib show_error(sprintf('%s.%s: Does not contain "jsons" field', $schema, $table)); } } - } + } /** - * Manage UDFs + * UDFs permissions check and convertion to read them from database */ - public function manageUDFs(&$data, $schemaAndTable, $udfValues = null) + public function prepareUDFsRead(&$data, $schemaAndTable, $udfValues = null) + { + $this->_ci->load->model('system/UDF_model', 'UDFModel'); + + // Retrieves UDFs definitions for this table + $resultUDFsDefinitions = $this->_ci->UDFModel->getUDFsDefinitions($schemaAndTable); + + // If an error occurred while reading from database + if (isError($resultUDFsDefinitions)) + { + $data = array(); // then set data as an empty array + return; // and exit from this method + } + + // If there are no UDFs defined for this table the return + if (!hasData($resultUDFsDefinitions)) return; + + // If not an error and has data, decodes json that define the UDFs for this table + $decodedUDFDefinitions = json_decode( + getData($resultUDFsDefinitions)[0]->{self::COLUMN_JSON_DESCRIPTION} + ); + + // Looping on results, resultElement is an object that represent a database record + foreach ($data as $resultElement) + { + // Decode the JSON column udf_values + $udfColumn = json_decode($resultElement->{self::COLUMN_NAME}); + + // If this is not a valid JSON then skip to the next database record + if ($udfColumn == null) continue; + + // For each UDF column of this database record + foreach (get_object_vars($udfColumn) as $columnName => $columnValue) + { + $udfColumnToBeRemoved = $columnName; // let's try to remove it + + // Loops through the UDFs definitions + foreach ($decodedUDFDefinitions as $decodedUDFDefinition) + { + // If the column exists in the UDF definition + if ($columnName == $decodedUDFDefinition->{self::NAME}) + { + $udfColumnToBeRemoved = null; // then keep it + } + } + + // If in this record have been found a _not_ defined UDF then remove it + if (!isEmptyString($udfColumnToBeRemoved)) unset($udfColumn->{$udfColumnToBeRemoved}); + } + + // Loops through the UDFs definitions + foreach ($decodedUDFDefinitions as $decodedUDFDefinition) + { + // Checks if the requiredPermissions is available and it is a valid array or a valid string + if (isset($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER}) + && (!isEmptyArray($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER}) + || !isEmptyString($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER}))) + { + // Then check if the user has the permissions to read such UDF + if (!$this->_readAllowed($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER})) + { + // If not then remove the UDF from the result set + unset($udfColumn->{$decodedUDFDefinition->{self::NAME}}); + } + } + else // If not then remove the UDF from the result set + { + unset($udfColumn->{$decodedUDFDefinition->{self::NAME}}); + } + } + + // Add the defined and permitted UDF columns to the record set + foreach (get_object_vars($udfColumn) as $columnName => $columnValue) + { + $resultElement->{$columnName} = $columnValue; + } + + // And finally remove the UDFs column + unset($resultElement->{self::COLUMN_NAME}); + } + } + + /** + * UDFs validation and permissions check to write them into database + */ + public function prepareUDFsWrite(&$data, $schemaAndTable, $udfValues = null) { $validate = success(true); // returned value // Contains a list of validation errors for the UDFs that have not passed the validation @@ -241,18 +344,34 @@ class UDFLib // Decodes json that define the UDFs for this table $decodedUDFDefinitions = json_decode( - $resultUDFsDefinitions->retval[0]->{self::COLUMN_JSON_DESCRIPTION} + getData($resultUDFsDefinitions)[0]->{self::COLUMN_JSON_DESCRIPTION} ); // Loops through the UDFs definitions - for ($i = 0; $i < count($decodedUDFDefinitions); $i++) + foreach ($decodedUDFDefinitions as $decodedUDFDefinition) { - $decodedUDFDefinition = $decodedUDFDefinitions[$i]; // Definition of a single UDF + // Checks if the requiredPermissions is available and it is a valid array or a valid string + if (isset($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER}) + && (!isEmptyArray($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER}) + || !isEmptyString($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER}))) + { + // Then check if the user has the permissions to write such UDF + if (!$this->_writeAllowed($decodedUDFDefinition->{self::REQUIRED_PERMISSIONS_PARAMETER})) + { + // If the logged user has no permissions then remove the UDF + unset($udfsParameters[$decodedUDFDefinition->{self::NAME}]); + } + } + else + { + // If no permissions have been defined for this UDF then remove it + unset($udfsParameters[$decodedUDFDefinition->{self::NAME}]); + } // Loops through the UDFs values that should be stored foreach ($udfsParameters as $key => $val) { - $tmpValidate = success(true); // temporary variable used to store the returned value from _validateUDFs + $tmpValidateArray = array(); // temporary variable used to store the returned value from _validateUDFs // If this is the definition of this UDF if ($decodedUDFDefinition->{self::NAME} == $key) @@ -314,7 +433,7 @@ class UDFLib if ($toBeValidated === true) // Checks if validation should be performed { - $tmpValidate = $this->_validateUDFs( + $tmpValidateArray = $this->_validateUDFs( $decodedUDFDefinition->{self::VALIDATION}, $decodedUDFDefinition->{self::NAME}, $val @@ -324,13 +443,13 @@ class UDFLib } // If validation is ok copy the value that is to be stored into $toBeStoredUDFsArray - if (isSuccess($tmpValidate)) + if (isEmptyArray($tmpValidateArray)) { $toBeStoredUDFsArray[$key] = $val; } - else // otherwise store the validation error in $notValidUDFsArray + else // otherwise store the validation errors in $notValidUDFsArray { - $notValidUDFsArray[] = $tmpValidate; + $notValidUDFsArray = array_merge($notValidUDFsArray, $tmpValidateArray); } } } @@ -344,11 +463,11 @@ class UDFLib } // If the validation of all the supplied UDFs is ok - if (count($notValidUDFsArray) == 0) + if (isEmptyArray($notValidUDFsArray)) { // An update is performed, then in this case it preserves the values // of the UDF that are not updated - if (is_array($udfValues) && count($udfValues) > 0) + if (!isEmptyArray($udfValues)) { foreach ($udfValues as $fieldName => $fieldValue) { @@ -379,7 +498,7 @@ class UDFLib /** * isUDFColumn */ - public function isUDFColumn($columnName, $columnType) + public function isUDFColumn($columnName, $columnType = self::COLUMN_TYPE) { $isUDFColumn = false; @@ -466,7 +585,7 @@ class UDFLib /** * Save UDFs */ - public function saveUDFs($udfUniqueId, $udfs) + public function saveUDFs($udfs) { // Read the all session for this udf widget $session = $this->getSession(); @@ -490,30 +609,80 @@ class UDFLib // Returns the result of the database update operation to save UDFs return $dbModel->update( array($session[self::PRIMARY_KEY_NAME] => $session[self::PRIMARY_KEY_VALUE]), - (array)$udfs + get_object_vars($udfs) ); } - /** - * 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 UDFWidget. - * If the parameter requiredPermissions is NOT given or is not present in the session, - * then NO one is allow to use this UDFWidget - * Wrapper method to permissionlib->hasAtLeastOne - */ - public function isAllowed($requiredPermissions = null) - { - $this->_ci->load->library('PermissionLib'); // Load permission library - - // Gets the required permissions from the session if they are not provided as parameter - $rq = $requiredPermissions; - if ($rq == null) $rq = $this->getSessionElement(self::REQUIRED_PERMISSIONS_PARAMETER); - - return $this->_ci->permissionlib->hasAtLeastOne($rq, self::PERMISSION_TABLE_METHOD, self::PERMISSION_TYPE); - } - // ------------------------------------------------------------------------------------------------- // Private methods + // + + /** + * Checks if at least one of the permissions given as parameter belongs to the authenticated user in read mode + * Wrapper method to permissionlib->hasAtLeastOne + */ + private function _readAllowed($requiredPermissions) + { + $readAllowed = false; + + // If the user is logged then it is possible to check the permissions + if (isLogged()) + { + $this->_ci->load->library('PermissionLib'); // Load permission library + + $readAllowed = $this->_ci->permissionlib->hasAtLeastOne( + $requiredPermissions, + self::PERMISSION_TABLE_METHOD, + self::PERMISSION_TYPE_READ + ); + } // otherwise it is not possible to check the permissions + + return $readAllowed; + } + + /** + * Checks if at least one of the permissions given as parameter belongs to the authenticated user in write mode + * Wrapper method to permissionlib->hasAtLeastOne + */ + private function _writeAllowed($requiredPermissions) + { + $writeAllowed = false; + + // If the user is logged then it is possible to check the permissions + if (isLogged()) + { + $this->_ci->load->library('PermissionLib'); // Load permission library + + $writeAllowed = $this->_ci->permissionlib->hasAtLeastOne( + $requiredPermissions, + self::PERMISSION_TABLE_METHOD, + self::PERMISSION_TYPE_WRITE + ); + } // otherwise it is not possible to check the permissions + + return $writeAllowed; + } + + /** + * Set an array of required permissions for a UDF into the session + */ + private function _setRequiredPermissions($udfName, $permissions) + { + // Get the session for this UDFWidget + $session = $this->getSession(); + + // If does _not_ exist yet in the session + if (!isset($session[self::REQUIRED_PERMISSIONS_PARAMETER])) + { + $session[self::REQUIRED_PERMISSIONS_PARAMETER] = array(); + } + + // Set the required permission in the session for this UDFWidget + $session[self::REQUIRED_PERMISSIONS_PARAMETER][$udfName] = $permissions; + + // Write into the session + $this->setSession($session); + } /** * Print the block for UDFs @@ -544,12 +713,12 @@ class UDFLib { $udfsParameters = array(); - foreach ($data as $key => $val) + foreach ($data as $columnName => $columnValue) { - if (substr($key, 0, 4) == self::COLUMN_PREFIX) + if ($this->isUDFColumn($columnName)) { - $udfsParameters[$key] = $val; // stores UDF value into property UDFs - unset($data[$key]); // remove from data + $udfsParameters[$columnName] = $columnValue; // stores UDF value into property UDFs + unset($data[$columnName]); // remove from data } } @@ -645,29 +814,39 @@ class UDFLib } } - // If no UDF validation errors were raised, it's a success!! - if (count($returnArrayValidation) == 0) - { - $returnArrayValidation = success(true); - } - return $returnArrayValidation; } - /** - * Set the name and id attribute of the HTML element - */ - private function _setNameAndId($jsonSchema, &$htmlParameters) - { + /** + * Disable the HTML element if in read only mode + */ + private function _setReadOnly($jsonSchema, &$htmlParameters) + { + // If write permissions _not_ exist then set the field as disabled + if (!$this->_writeAllowed($jsonSchema->{self::REQUIRED_PERMISSIONS_PARAMETER})) + { + $htmlParameters[HTMLWidget::DISABLED] = HTMLWidget::DISABLED; // any values is fine + } + else // otherwise restore to default + { + if (isset($htmlParameters[HTMLWidget::DISABLED])) unset($htmlParameters[HTMLWidget::DISABLED]); + } + } + + /** + * Set the name and id attribute of the HTML element + */ + private function _setNameAndId($jsonSchema, &$htmlParameters) + { $htmlParameters[HTMLWidget::HTML_ID] = $jsonSchema->{self::NAME}; $htmlParameters[HTMLWidget::HTML_NAME] = $jsonSchema->{self::NAME}; - } - - /** - * Sort the list of UDF by sort property - */ - private function _sortJsonSchemas(&$jsonSchemasArray) - { + } + + /** + * Sort the list of UDF by sort property + */ + private function _sortJsonSchemas(&$jsonSchemasArray) + { usort($jsonSchemasArray, function ($a, $b) { if (!isset($a->{self::SORT})) { @@ -684,13 +863,13 @@ class UDFLib return ($a->{self::SORT} < $b->{self::SORT}) ? -1 : 1; }); - } - - /** - * Loads the UDF description by the given schema and table - */ - private function _loadUDF($schema, $table) - { + } + + /** + * Loads the UDF description by the given schema and table + */ + private function _loadUDF($schema, $table) + { // Loads UDF model $this->_ci->load->model('system/UDF_model', 'UDFModel'); @@ -703,18 +882,7 @@ class UDFLib if (isError($udfResults)) { - if (is_object($udfResults) && isset($udfResults->retval)) - { - show_error(getError($udfResults)); - } - elseif (is_string($udfResults)) - { - show_error($udfResults); - } - else - { - show_error('UDFWidget: generic error occurred'); - } + show_error(getError($udfResults)); } elseif (!hasData($udfResults)) { @@ -722,13 +890,13 @@ class UDFLib } return $udfResults; - } + } - /** - * Render the HTML for the UDF - */ - private function _render($jsonSchema, &$widgetData) - { + /** + * Render the HTML for the UDF + */ + private function _render($jsonSchema, &$widgetData) + { // Checkbox if ($jsonSchema->{self::TYPE} == 'checkbox') { @@ -759,11 +927,11 @@ class UDFLib { $this->_renderDropdown($jsonSchema, $widgetData, true); } - } + } - /** - * Renders a dropdown element - */ + /** + * Renders a dropdown element + */ private function _renderDropdown($jsonSchema, &$widgetData, $multiple = false) { // Selected element/s @@ -792,7 +960,7 @@ class UDFLib $queryResult = $this->_ci->UDFModel->execReadOnlyQuery($jsonSchema->{self::LIST_VALUES}->sql); if (hasData($queryResult)) { - $parameters = $queryResult->retval; + $parameters = getData($queryResult); } } @@ -805,8 +973,8 @@ class UDFLib } /** - * Renders a textarea element - */ + * Renders a textarea element + */ private function _renderTextarea($jsonSchema, &$widgetData) { $text = null; // text value @@ -823,8 +991,8 @@ class UDFLib } /** - * Renders an input text element - */ + * Renders an input text element + */ private function _renderTextfield($jsonSchema, &$widgetData) { $text = null; // text value @@ -841,8 +1009,8 @@ class UDFLib } /** - * Renders a checkbox element - */ + * Renders a checkbox element + */ private function _renderCheckbox($jsonSchema, &$widgetData) { // Set checkbox value if present in the DB @@ -861,11 +1029,11 @@ class UDFLib $checkboxWidgetUDF->render(); } - /** - * Sets the attributes of the HTML element using the phrases system - */ - private function _setAttributesWithPhrases($jsonSchema, &$htmlParameters) - { + /** + * Sets the attributes of the HTML element using the phrases system + */ + private function _setAttributesWithPhrases($jsonSchema, &$htmlParameters) + { // By default set to null all the attributes $htmlParameters[HTMLWidget::LABEL] = null; $htmlParameters[HTMLWidget::TITLE] = null; @@ -893,7 +1061,7 @@ class UDFLib ); if (hasData($tmpResult)) { - $htmlParameters[HTMLWidget::LABEL] = $tmpResult->retval[0]->text; + $htmlParameters[HTMLWidget::LABEL] = getData($tmpResult)[0]->text; } } @@ -911,7 +1079,7 @@ class UDFLib ); if (hasData($tmpResult)) { - $htmlParameters[HTMLWidget::TITLE] = $tmpResult->retval[0]->text; + $htmlParameters[HTMLWidget::TITLE] = getData($tmpResult)[0]->text; } } @@ -929,17 +1097,17 @@ class UDFLib ); if (hasData($tmpResult)) { - $htmlParameters[HTMLWidget::PLACEHOLDER] = $tmpResult->retval[0]->text; + $htmlParameters[HTMLWidget::PLACEHOLDER] = getData($tmpResult)[0]->text; } } } - } + } - /** - * Sets the validation attributes of the HTML element using the configuration inside the json schema - */ - private function _setValidationAttributes($jsonSchema, &$htmlParameters) - { + /** + * Sets the validation attributes of the HTML element using the configuration inside the json schema + */ + private function _setValidationAttributes($jsonSchema, &$htmlParameters) + { // Validation attributes set by default to null $htmlParameters[HTMLWidget::REGEX] = null; $htmlParameters[HTMLWidget::REQUIRED] = null; @@ -998,3 +1166,4 @@ class UDFLib } } } + diff --git a/application/models/codex/Aufenthaltfoerderung_model.php b/application/models/codex/Aufenthaltfoerderung_model.php new file mode 100644 index 000000000..b650b3a05 --- /dev/null +++ b/application/models/codex/Aufenthaltfoerderung_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_aufenthaltfoerderung'; + $this->pk = 'aufenthaltfoerderung_code'; + } +} diff --git a/application/models/codex/Oehbeitrag_model.php b/application/models/codex/Oehbeitrag_model.php new file mode 100644 index 000000000..0df016ba8 --- /dev/null +++ b/application/models/codex/Oehbeitrag_model.php @@ -0,0 +1,107 @@ +dbTable = 'bis.tbl_oehbeitrag'; + $this->pk = 'oehbeitrag_id'; + } + + /** + * Gets oehbeitrag data valid for a certain Studiensemester. + * @param string $studiensemester_kurzbz + * @return object + */ + public function getByStudiensemester($studiensemester_kurzbz) + { + $qry = "WITH semstart AS ( + SELECT start FROM public.tbl_studiensemester + WHERE studiensemester_kurzbz = ? + ) + SELECT * FROM bis.tbl_oehbeitrag oehb + JOIN public.tbl_studiensemester semvon ON oehb.von_studiensemester_kurzbz = semvon.studiensemester_kurzbz + LEFT JOIN public.tbl_studiensemester sembis ON oehb.bis_studiensemester_kurzbz = sembis.studiensemester_kurzbz + JOIN semstart ON semstart.start::date >= semvon.start::date AND (sembis.studiensemester_kurzbz IS NULL OR semstart.start::date <= sembis.start::date) + ORDER BY semvon.start + LIMIT 1"; + + return $this->execQuery($qry, array($studiensemester_kurzbz)); + } + + /** + * Gets all Studiensemester for which no Oehbeitrag value assignment exists. + * @param string $start_studiensemester_kurzbz semester before the given semester are ignored + * @param array $excluded_oehbeitrag_id oehbeitraege to be ignored, i.e. which are assigned + * @return object + */ + public function getUnassignedStudiensemester($start_studiensemester_kurzbz, $excluded_oehbeitrag_id = array()) + { + $params = array($start_studiensemester_kurzbz); + + $qry = "SELECT * FROM public.tbl_studiensemester sem + WHERE sem.start >= (SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz = ?) + AND NOT EXISTS (SELECT 1 FROM bis.tbl_oehbeitrag oeh + JOIN public.tbl_studiensemester oeh_von ON oeh.von_studiensemester_kurzbz = oeh_von.studiensemester_kurzbz + LEFT JOIN public.tbl_studiensemester oeh_bis ON oeh.bis_studiensemester_kurzbz = oeh_bis.studiensemester_kurzbz + WHERE sem.start::date >= oeh_von.start::date AND (sem.start::date <= oeh_bis.start::date OR oeh_bis.studiensemester_kurzbz IS NULL)"; + + if (!isEmptyArray($excluded_oehbeitrag_id)) + { + $qry .= " AND oehbeitrag_id NOT IN ?"; + $params[] = $excluded_oehbeitrag_id; + } + + $qry .= ") ORDER BY sem.start"; + + return $this->execQuery($qry, $params); + } + + /** + * Checks if a Öhbeitrag can be assigned for a Studiensemester range. + * @param string $von_studiensemester_kurzbz + * @param string $bis_studiensemester_kurzbz + * @param array $excluded_oehbeitrag_id oehbeitraege to ignore, i.e. which are assignable + * @return object array with true if assignable, with false if not + */ + public function checkIfStudiensemesterAssignable($von_studiensemester_kurzbz, $bis_studiensemester_kurzbz = null, $excluded_oehbeitrag_id = array()) + { + $params = array($von_studiensemester_kurzbz); + + $allStdSemSpanQry = "SELECT count(studiensemester_kurzbz) as number_assigned FROM public.tbl_studiensemester sem + WHERE start >= (SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz = ?)"; + + if ($bis_studiensemester_kurzbz != null) + { + $allStdSemSpanQry .= " AND (start <= (SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz = ?))"; + $params[] = $bis_studiensemester_kurzbz; + } + + $allStdSemSpanQry .= " AND EXISTS (SELECT 1 FROM bis.tbl_oehbeitrag + JOIN public.tbl_studiensemester sem_von ON tbl_oehbeitrag.von_studiensemester_kurzbz = sem_von.studiensemester_kurzbz + LEFT JOIN public.tbl_studiensemester sem_bis ON tbl_oehbeitrag.bis_studiensemester_kurzbz = sem_bis.studiensemester_kurzbz + WHERE sem.start >= sem_von.start AND (sem.start <= sem_bis.start OR sem_bis.studiensemester_kurzbz IS NULL)"; + + if (!isEmptyArray($excluded_oehbeitrag_id)) + { + $allStdSemSpanQry .= " AND oehbeitrag_id NOT IN ?"; + $params[] = $excluded_oehbeitrag_id; + } + + $allStdSemSpanQry .= ")"; + + $nrAssigned = $this->execQuery($allStdSemSpanQry, $params); + + if (isError($nrAssigned)) + return $nrAssigned; + + if (!hasData($nrAssigned)) + return error("Fehler bei Überprüfung der Möglichkeit der Semesterzuweisung"); + + return success(array(getData($nrAssigned)[0]->number_assigned == 0)); + } +} diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index 2553fd5fa..2d8ac4a7e 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -291,7 +291,7 @@ class Prestudent_model extends DB_Model $prestudentdata->prestudentstatus = $lastStatusData; - if ($this->hasUDF()) + if ($this->udfsExistAndDefined()) { $prestudentdata->prestudentUdfs = $this->getUDFs($prestudent_id); } @@ -611,7 +611,7 @@ class Prestudent_model extends DB_Model )); } - public function getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester) + public function getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt) { $query = "SELECT ps.prestudent_id FROM public.tbl_prestudentstatus pss @@ -621,8 +621,48 @@ class Prestudent_model extends DB_Model WHERE ps.person_id = ? AND UPPER((sg.typ || sg.kurzbz) || ':' || sp.orgform_kurzbz) = ? AND pss.studiensemester_kurzbz = ? - "; + AND"; + + if ($abgeschickt === 'true') + $query .= " EXISTS"; + else + $query .= " NOT EXISTS"; + + $query .= " (SELECT 1 FROM public.tbl_prestudentstatus spss + JOIN public.tbl_prestudent sps USING(prestudent_id) + WHERE sps.prestudent_id = ps.prestudent_id + AND spss.bewerbung_abgeschicktamum IS NOT NULL)"; return $this->execQuery($query, array($person, $studiengang, $studienSemester)); } + + /** + * Gets förderrelevant flag for a prestudent, from prestudent, or, if not set on prestudent level, from studiengang + * @param int $prestudent_id + * @return object + */ + public function getFoerderrelevant($prestudent_id) + { + $query = 'SELECT COALESCE (ps.foerderrelevant, stg.foerderrelevant) AS foerderrelevant + FROM public.tbl_prestudent ps + LEFT JOIN public.tbl_studiengang stg USING (studiengang_kz) + WHERE prestudent_id = ?'; + + return $this->execQuery($query, array($prestudent_id)); + } + + /** + * Gets bis standort_code for a prestudent, from prestudent, or, if not set on prestudent level, from studiengang + * @param int $prestudent_id + * @return object + */ + public function getStandortCode($prestudent_id) + { + $query = 'SELECT COALESCE (ps.standort_code, stg.standort_code) AS standort_code + FROM public.tbl_prestudent ps + LEFT JOIN public.tbl_studiengang stg USING (studiengang_kz) + WHERE prestudent_id = ?'; + + return $this->execQuery($query, array($prestudent_id)); + } } diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index d10364979..e3776c4ad 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -11,4 +11,29 @@ class Pruefung_model extends DB_Model $this->dbTable = 'campus.tbl_pruefung'; $this->pk = 'pruefung_id'; } + + /** + * Gets Pruefungen of a person for a Studiensemester. + * @param int $person_id + * @param string $studiensemester_kurzbz + * @return object + */ + public function getByPerson($person_id, $studiensemester_kurzbz) + { + $qry = ' + SELECT prfg.*, pers.matr_nr, lv.ects, stg.studiengang_kz, prst.prestudent_id, + UPPER(stg.typ||stg.kurzbz) AS studiengang, stg.bezeichnung AS studiengang_bezeichnung + FROM public.tbl_person pers + JOIN public.tbl_prestudent prst USING (person_id) + JOIN public.tbl_student USING (prestudent_id) + JOIN lehre.tbl_pruefung prfg USING (student_uid) + JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) + JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz + WHERE pers.person_id = ? + AND le.studiensemester_kurzbz = ? + ORDER BY prfg.datum, pruefung_id'; + + return $this->execQuery($qry, array($person_id, $studiensemester_kurzbz)); + } } diff --git a/application/models/education/Zeugnisnote_model.php b/application/models/education/Zeugnisnote_model.php index 7ed0e6456..65607e252 100644 --- a/application/models/education/Zeugnisnote_model.php +++ b/application/models/education/Zeugnisnote_model.php @@ -12,4 +12,125 @@ class Zeugnisnote_model extends DB_Model $this->pk = array('studiensemester_kurzbz', 'student_uid', 'lehrveranstaltung_id'); $this->hasSequence = false; } + + /** + * Gets ECTS sums of completed courses (Zeugnisnoten) of a person for a Studiensemester. + * If no valid Noten for the course were entered, 0 ects is returned. + * @param int $person_id + * @param string $studiensemester_kurzbz + * @param bool $aktiv + * @param bool $lehre + * @param bool $offiziell + * @param bool $positiv + * @return object + */ + public function getEctsSumsByPerson($person_id, $studiensemester_kurzbz, $aktiv = true, $lehre = null, $offiziell = null, $positiv = null) + { + $params = array(); + + $qry = "SELECT DISTINCT ON (prst.prestudent_id) pers.matr_nr, stg.studiengang_kz, prst.prestudent_id, stg.erhalter_kz, + UPPER(stg.typ||stg.kurzbz) AS studiengang, stg.bezeichnung AS studiengang_bezeichnung, COALESCE(summen.summe_ects, 0) AS summe_ects + FROM public.tbl_person pers + JOIN public.tbl_prestudent prst USING (person_id) + JOIN public.tbl_prestudentstatus prstst USING (prestudent_id) + JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz + LEFT JOIN ( + SELECT zgnisnote.student_uid, prestudent_id, zgnisnote.studiensemester_kurzbz, sum(ects) AS summe_ects + FROM public.tbl_student + LEFT JOIN lehre.tbl_zeugnisnote zgnisnote USING(student_uid) + LEFT JOIN lehre.tbl_note note ON zgnisnote.note = note.note + LEFT JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) + WHERE TRUE"; + + if (isset($aktiv)) + { + $qry .= ' AND (note.aktiv = ?)'; + $params[] = $aktiv; + } + + if (isset($lehre)) + { + $qry .= ' AND (note.lehre = ?)'; + $params[] = $lehre; + } + + if (isset($offiziell)) + { + $qry .= ' AND (note.offiziell = ?)'; + $params[] = $offiziell; + } + + if (isset($positiv)) + { + $qry .= ' AND (note.positiv = ?)'; + $params[] = $positiv; + } + + $qry .= " GROUP BY zgnisnote.studiensemester_kurzbz, zgnisnote.student_uid, prestudent_id + ) summen ON prst.prestudent_id = summen.prestudent_id AND prstst.studiensemester_kurzbz = summen.studiensemester_kurzbz + WHERE pers.person_id = ? + AND prstst.studiensemester_kurzbz = ? + ORDER BY prst.prestudent_id"; + + $params[] = $person_id; + $params[] = $studiensemester_kurzbz; + + return $this->execQuery($qry, $params); + } + + /** + * Gets courses (Zeugnisnoten) of a person for a Studiensemester. + * @param int $person_id + * @param string $studiensemester_kurzbz + * @param bool $aktiv + * @param bool $lehre + * @param bool $offiziell + * @param bool $positiv + * @return object + */ + public function getByPerson($person_id, $studiensemester_kurzbz, $aktiv = true, $lehre = null, $offiziell = null, $positiv = null) + { + $params = array($person_id, $studiensemester_kurzbz); + + $qry = "SELECT zgnisnote.*, pers.matr_nr, lv.ects, stg.studiengang_kz, prst.prestudent_id, stg.erhalter_kz, + UPPER(stg.typ||stg.kurzbz) AS studiengang, stg.bezeichnung AS studiengang_bezeichnung, note.note, + note.bezeichnung AS note_bezeichnung + FROM public.tbl_person pers + JOIN public.tbl_prestudent prst USING (person_id) + JOIN public.tbl_student USING (prestudent_id) + JOIN lehre.tbl_zeugnisnote zgnisnote USING (student_uid) + JOIN lehre.tbl_note note ON zgnisnote.note = note.note + JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) + JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz + WHERE pers.person_id = ? + AND zgnisnote.studiensemester_kurzbz = ?"; + + if (isset($aktiv)) + { + $qry .= ' AND note.aktiv = ?'; + $params[] = $aktiv; + } + + if (isset($lehre)) + { + $qry .= ' AND note.lehre = ?'; + $params[] = $lehre; + } + + if (isset($offiziell)) + { + $qry .= ' AND note.offiziell = ?'; + $params[] = $offiziell; + } + + if (isset($positiv)) + { + $qry .= ' AND note.positiv = ?'; + $params[] = $positiv; + } + + $qry .= ' ORDER BY zgnisnote.benotungsdatum'; + + return $this->execQuery($qry, $params); + } } diff --git a/application/models/person/Person_model.php b/application/models/person/Person_model.php index e005e243c..ec5522674 100644 --- a/application/models/person/Person_model.php +++ b/application/models/person/Person_model.php @@ -152,34 +152,36 @@ class Person_model extends DB_Model */ public function getPersonStammdaten($person_id, $zustellung_only = false) { - $this->addSelect('public.tbl_person.*, s.kurztext as staatsbuergerschaft, g.kurztext as geburtsnation'); + $this->addSelect('public.tbl_person.*, tbl_person.staatsbuergerschaft AS staatsbuergerschaft_code, tbl_person.geburtsnation AS geburtsnation_code, + s.kurztext as staatsbuergerschaft, g.kurztext as geburtsnation'); $this->addJoin('bis.tbl_nation s', 'public.tbl_person.staatsbuergerschaft = s.nation_code', 'LEFT'); $this->addJoin('bis.tbl_nation g', 'public.tbl_person.geburtsnation = g.nation_code', 'LEFT'); $person = $this->load($person_id); - if($person->error) return $person; + if (isError($person)) return $person; //return null if not found - if(count($person->retval) < 1) + if (!hasData($person)) return success(null); - $this->KontaktModel->addDistinct(); $this->KontaktModel->addSelect('kontakttyp, anmerkung, kontakt, zustellung'); $this->KontaktModel->addOrder('kontakttyp'); + $this->KontaktModel->addOrder('insertamum', 'DESC'); $where = $zustellung_only === true ? array('person_id' => $person_id, 'zustellung' => true) : array('person_id' => $person_id); $kontakte = $this->KontaktModel->loadWhere($where); - if($kontakte->error) return $kontakte; + if (isError($kontakte)) return $kontakte; $where = $zustellung_only === true ? array('person_id' => $person_id, 'zustelladresse' => true) : array('person_id' => $person_id); $this->AdresseModel->addSelect('public.tbl_adresse.*, bis.tbl_nation.kurztext AS nationkurztext'); $this->AdresseModel->addJoin('bis.tbl_nation', 'tbl_adresse.nation = tbl_nation.nation_code', 'LEFT'); + $this->AdresseModel->addOrder('insertamum', 'DESC'); $adressen = $this->AdresseModel->loadWhere($where); - if($adressen->error) return $adressen; + if (isError($adressen)) return $adressen; - $stammdaten = $person->retval[0]; - $stammdaten->kontakte = $kontakte->retval; - $stammdaten->adressen = $adressen->retval; + $stammdaten = getData($person)[0]; + $stammdaten->kontakte = hasData($kontakte) ? getData($kontakte) : array(); + $stammdaten->adressen = hasData($adressen) ? getData($adressen) : array(); return success($stammdaten); } @@ -263,4 +265,19 @@ class Person_model extends DB_Model return success($result->vorname. ' '. $result->nachname); } + + public function checkDuplicate($person_id) + { + $qry = "SELECT sp.person_id + FROM public.tbl_person p + LEFT JOIN public.tbl_person sp ON p.vorname = sp.vorname + AND p.nachname = sp.nachname + AND p.gebdatum = sp.gebdatum + JOIN public.tbl_prestudent ps ON sp.person_id = ps.person_id + JOIN public.tbl_prestudentstatus pss ON ps.prestudent_id = pss.prestudent_id + WHERE p.person_id = ? AND sp.person_id != ? AND pss.status_kurzbz = ?"; + + + return $this->execQuery($qry, array($person_id, $person_id, 'Abbrecher')); + } } diff --git a/application/models/ressource/Betriebsmittelperson_model.php b/application/models/ressource/Betriebsmittelperson_model.php index 87915cfa8..1a97d9e38 100644 --- a/application/models/ressource/Betriebsmittelperson_model.php +++ b/application/models/ressource/Betriebsmittelperson_model.php @@ -18,7 +18,7 @@ class Betriebsmittelperson_model extends DB_Model * @param bool $isRetourniert False to retrieve only active Betriebsmittel. * @return array|bool */ - public function getBetriebsmittel($person_id, $betriebsmitteltyp = null, $isRetourniert = null) + public function getBetriebsmittel($person_id, $betriebsmitteltyp = null, $isRetourniert = null, $onlyAktiveBenutzer=false) { if (!is_numeric($person_id)) { @@ -28,8 +28,12 @@ class Betriebsmittelperson_model extends DB_Model $this->addJoin('wawi.tbl_betriebsmittel', 'betriebsmittel_id'); + if( $onlyAktiveBenutzer ) { + $this->addJoin('public.tbl_benutzer b', 'b.uid = wawi.tbl_betriebsmittelperson.uid AND b.aktiv = \'t\''); + } + $condition = ' - person_id = '. $this->escape($person_id). ' + wawi.tbl_betriebsmittelperson.person_id = '. $this->escape($person_id). ' '; if (is_string($betriebsmitteltyp)) { diff --git a/application/models/system/Fehler_model.php b/application/models/system/Fehler_model.php new file mode 100644 index 000000000..28618f6d9 --- /dev/null +++ b/application/models/system/Fehler_model.php @@ -0,0 +1,14 @@ +dbTable = 'system.tbl_fehler'; + $this->pk = 'fehlercode'; + } +} diff --git a/application/models/system/Issue_model.php b/application/models/system/Issue_model.php new file mode 100644 index 000000000..5dac85066 --- /dev/null +++ b/application/models/system/Issue_model.php @@ -0,0 +1,51 @@ +dbTable = 'system.tbl_issue'; + $this->pk = 'issue_id'; + } + + /** + * Gets number of open (non-resolved) issues. + * @param string $fehlercode unique error code + * @param int $person_id if provided, only issues with this person_id are counted. + * @param string $oe_kurzbz if provided, only issues with this oe_kurzbz are counted. + * @param string $fehlercode_extern if provided, only issues with this external fehlercode are counted (for identifying issues from external systems). + * @return Object success with number of issues or error + */ + public function getOpenIssueCount($fehlercode, $person_id = null, $oe_kurzbz = null, $fehlercode_extern = null) + { + $params = array($fehlercode); + // issue exists for a fehlercode (or fehlercode_extern), person_id, oe_kurzbz, if not verarbeitet yet + $qry = 'SELECT count(*) as anzahl_open_issues FROM system.tbl_issue + WHERE fehlercode = ? + AND verarbeitetamum IS NULL'; + + if (!isEmptyString($fehlercode_extern)) + { + $qry .= ' AND fehlercode_extern = ?'; + $params[] = $fehlercode_extern; + } + + if (isset($person_id)) + { + $qry .= ' AND person_id = ?'; + $params[] = $person_id; + } + + if (isset($oe_kurzbz)) + { + $qry .= ' AND oe_kurzbz = ?'; + $params[] = $oe_kurzbz; + } + + return $this->execQuery($qry, $params); + } +} diff --git a/application/views/codex/oehbeitrag.php b/application/views/codex/oehbeitrag.php new file mode 100644 index 000000000..8a697129e --- /dev/null +++ b/application/views/codex/oehbeitrag.php @@ -0,0 +1,68 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'ÖH-Beitragsverwaltung', + 'jquery' => true, + 'jqueryui' => true, + 'bootstrap' => true, + 'fontawesome' => true, + 'sbadmintemplate' => true, + 'tablesorter' => true, + 'dialoglib' => true, + 'ajaxlib' => true, + 'navigationwidget' => true, + 'phrases' => array( + 'person' => array('vorname', 'nachname'), + 'global' => array('unbeschraenkt'), + 'ui' => array('bearbeiten', 'loeschen', 'speichern', 'entfernen'), + 'oehbeitrag' => array('oehbeitraegeFestgelegt', 'fehlerHolenOehbeitraege', 'fehlerHolenSemester', + 'fehlerHinzufuegenOehbeitrag', 'fehlerAktualisierenOehbeitrag', + 'fehlerLoeschenOehbeitrag') + ), + 'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/codex/oehbeitrag.css'), + 'customJSs' => array('public/js/tablesort/tablesort.js', 'public/js/codex/oehbeitrag.js') + ) +); +?> + +
+| p->t('global', 'gueltigVon')) ?> | +p->t('global', 'gueltigBis')) ?> | +p->t('oehbeitrag', 'studierendenbetrag')) ?> | +p->t('oehbeitrag', 'versicherungsbetrag')) ?> | +p->t('ui', 'aktion')) ?> | +
|---|