From 719f2d73147bd8808639e575107b41ecb48401c8 Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 17 Dec 2019 13:35:41 +0100 Subject: [PATCH 001/265] - Changed controller system/FAS_UDF, less busy now - Method execReadOnlyQuery of DB_Model less strict check against SQL statements - Added new public method setup to DB_Model to setup the model after initialization - Added new constants to UDFLib - Added new private method _printEndUDFBlock and _printEndUDFBlock to UDFLib - Added new public methods setUDFUniqueId, getSession, getSessionElement, setSession, setSessionElement, saveUDFs and isAllowed to UDFLib - Removed model system/FAS_UDF_model - View views/system/fas_udf now uses the view templates/FHC-Header - Added new parameter udfs to view templates/FHC-Header - Added new properties to UDFWidget - Added new private methods _initUDFWidget, _checkParameters and _startUDFWidget to UDFWidget --- application/controllers/system/FAS_UDF.php | 82 +--- application/controllers/widgets/UDF.php | 102 +++++ application/core/DB_Model.php | 20 +- application/libraries/UDFLib.php | 385 +++++++++++++----- application/models/system/FAS_UDF_model.php | 169 -------- application/views/system/fas_udf.php | 100 ++--- application/views/templates/FHC-Header.php | 4 + application/widgets/udf/DropdownWidgetUDF.php | 24 +- application/widgets/udf/UDFWidget.php | 151 ++++++- public/js/UDFWidget.js | 100 +++++ 10 files changed, 686 insertions(+), 451 deletions(-) create mode 100644 application/controllers/widgets/UDF.php delete mode 100644 application/models/system/FAS_UDF_model.php create mode 100644 public/js/UDFWidget.js diff --git a/application/controllers/system/FAS_UDF.php b/application/controllers/system/FAS_UDF.php index cd78d64d2..7f39543c7 100644 --- a/application/controllers/system/FAS_UDF.php +++ b/application/controllers/system/FAS_UDF.php @@ -24,43 +24,15 @@ class FAS_UDF extends Auth_Controller */ public function index() { - $fasUdfSession = getSession(self::FAS_UDF_SESSION_NAME); - $person_id = $this->input->get('person_id'); - if (isset($fasUdfSession['person_id'])) - { - if (!isset($person_id)) - { - $person_id = $fasUdfSession['person_id']; - } - unset($fasUdfSession['person_id']); - } - $prestudent_id = $this->input->get('prestudent_id'); - if (isset($fasUdfSession['prestudent_id'])) - { - if (!isset($prestudent_id)) - { - $prestudent_id = $fasUdfSession['prestudent_id']; - } - unset($fasUdfSession['prestudent_id']); - } - - $result = null; - if (isset($fasUdfSession['result'])) - { - $result = clone $fasUdfSession['result']; - setSessionElement(self::FAS_UDF_SESSION_NAME, 'result', null); - } - - $data = array('result' => $result); if (isset($person_id) && is_numeric($person_id)) { if ($this->PersonModel->hasUDF()) { $personUdfs = $this->PersonModel->getUDFs($person_id); - $personUdfs['person_id'] = $person_id; + $data['person_id'] = $person_id; $data['personUdfs'] = $personUdfs; } } @@ -70,61 +42,11 @@ class FAS_UDF extends Auth_Controller if ($this->PrestudentModel->hasUDF()) { $prestudentUdfs = $this->PrestudentModel->getUDFs($prestudent_id); - $prestudentUdfs['prestudent_id'] = $prestudent_id; + $data['prestudent_id'] = $prestudent_id; $data['prestudentUdfs'] = $prestudentUdfs; } } $this->load->view('system/fas_udf', $data); } - - /** - * - */ - public function saveUDF() - { - $udfs = $this->input->post(); - $validation = $this->_validate($udfs); - - $userdata = array( - 'person_id' => $this->input->post('person_id'), - 'prestudent_id' => $this->input->post('prestudent_id') - ); - - if (isSuccess($validation)) - { - // Load model UDF_model - $this->load->model('system/FAS_UDF_model', 'FASUDFModel'); - - $result = $this->FASUDFModel->saveUDFs($udfs); - - $userdata['result'] = $result; - } - else - { - $userdata['result'] = $validation; - } - - setSessionElement(self::FAS_UDF_SESSION_NAME, 'person_id', $userdata['person_id']); - setSessionElement(self::FAS_UDF_SESSION_NAME, 'prestudent_id', $userdata['prestudent_id']); - setSessionElement(self::FAS_UDF_SESSION_NAME, 'result', $userdata['result']); - - redirect('system/FAS_UDF'); - } - - /** - * - */ - private function _validate($udfs) - { - $validation = error('person_id or prestudent_id is missing'); - - if((isset($udfs['person_id']) && !(is_null($udfs['person_id'])) && ($udfs['person_id'] != '')) - || (isset($udfs['prestudent_id']) && !(is_null($udfs['prestudent_id'])) && ($udfs['prestudent_id'] != ''))) - { - $validation = success(true); - } - - return $validation; - } } diff --git a/application/controllers/widgets/UDF.php b/application/controllers/widgets/UDF.php new file mode 100644 index 000000000..c71eba73a --- /dev/null +++ b/application/controllers/widgets/UDF.php @@ -0,0 +1,102 @@ +load->library('AuthLib'); + + // Loads the UDFLib with HTTP GET/POST parameters + $this->_loadUDFLib(); + + // Checks if the caller is allow to read this data + $this->_isAllowed(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data about the current filter from the session and will be written on the output in JSON format + */ + public function saveUDFs() + { + $udfUniqueId = $this->input->post(self::UDF_UNIQUE_ID); + $udfs = $this->input->post(UDFLib::UDFS_ARG_NAME); + + if (!isEmptyString($udfs)) + { + $jsonDecodedUDF = json_decode($udfs); + if ($jsonDecodedUDF != null) + { + $this->outputJson($this->udflib->saveUDFs($udfUniqueId, $jsonDecodedUDF)); + } + else + { + $this->outputJsonError('No valid JSON format for UDF values'); + } + } + else + { + $this->outputJsonError('UDFUniqueId, schema, table name, primary key name and primary key value are mandatory paramenters'); + } + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks if the user is allowed to use this filter + */ + private function _isAllowed() + { + if (!$this->udflib->isAllowed()) + { + $this->terminateWithJsonError('You are not allowed to access to this content'); + } + } + + /** + * Loads the tablewidgetlib with the UDF_UNIQUE_ID parameter + * If the parameter UDF_UNIQUE_ID is not given then the execution of the controller is terminated and + * an error message is printed + */ + private function _loadUDFLib() + { + // If the parameter UDF_UNIQUE_ID is present in the HTTP GET or POST + if (isset($_GET[self::UDF_UNIQUE_ID]) || isset($_POST[self::UDF_UNIQUE_ID])) + { + // If it is present in the HTTP GET + if (isset($_GET[self::UDF_UNIQUE_ID])) + { + $udfUniqueId = $this->input->get(self::UDF_UNIQUE_ID); // is retrieved from the HTTP GET + } + elseif (isset($_POST[self::UDF_UNIQUE_ID])) // Else if it is present in the HTTP POST + { + $udfUniqueId = $this->input->post(self::UDF_UNIQUE_ID); // is retrieved from the HTTP POST + } + + // Loads the tablewidgetlib that contains all the used logic + $this->load->library('UDFLib'); + + $this->udflib->setUDFUniqueId($udfUniqueId); + } + else // Otherwise an error will be written in the output + { + $this->terminateWithJsonError('Parameter "'.self::UDF_UNIQUE_ID.'" not provided!'); + } + } +} diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index ca760c662..667ff00ca 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -60,6 +60,20 @@ class DB_Model extends CI_Model // ------------------------------------------------------------------------------------------ // Public methods + /** + * This method provides a way to setup a database model without declaring one + */ + public function setup($schema, $table, $primaryKey, $hasSequence = true) + { + // + if (!isEmptyString($schema) && !isEmptyString($table) && !isEmptyString($primaryKey) && is_bool($hasSequence)) + { + $this->dbTable = $schema.'.'.$table; + $this->pk = $primaryKey; + $this->hasSequence = $hasSequence; + } + } + /** * Insert Data into DB-Table * @@ -690,7 +704,7 @@ class DB_Model extends CI_Model */ public function hasUDF() { - if($this->fieldExists(UDFLib::COLUMN_NAME)) + if ($this->fieldExists(UDFLib::COLUMN_NAME)) { $resultUDFsDefinitions = $this->UDFModel->getUDFsDefinitions($this->dbTable); if (hasData($resultUDFsDefinitions)) @@ -727,8 +741,8 @@ class DB_Model extends CI_Model $cleanedQuery = trim(preg_replace('/\t|\n|\r|;/', '', $query)); // // - if (stripos($cleanedQuery, 'SELECT') == 0 - && (stripos($cleanedQuery, 'INSERT') > 0 || stripos($cleanedQuery, 'INSERT') == false) + if ( + (stripos($cleanedQuery, 'INSERT') > 0 || stripos($cleanedQuery, 'INSERT') == false) && (stripos($cleanedQuery, 'UPDATE') > 0 || stripos($cleanedQuery, 'UPDATE') == false) && (stripos($cleanedQuery, 'CREATE') > 0 || stripos($cleanedQuery, 'CREATE') == false) && (stripos($cleanedQuery, 'DELETE') > 0 || stripos($cleanedQuery, 'DELETE') == false) diff --git a/application/libraries/UDFLib.php b/application/libraries/UDFLib.php index 6166b44a9..edd11fd99 100644 --- a/application/libraries/UDFLib.php +++ b/application/libraries/UDFLib.php @@ -7,6 +7,10 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); */ class UDFLib { + const UDF_UNIQUE_ID = 'udfUniqueId'; + + const SESSION_NAME = 'FHC_UDF_WIDGET'; + const WIDGET_NAME = 'UDFWidget'; const SCHEMA_ARG_NAME = 'schema'; const TABLE_ARG_NAME = 'table'; @@ -22,6 +26,16 @@ class UDFLib const FE_REGEX_LANGUAGE = 'js'; // UDF javascript regex language attribute (front end) const BE_REGEX_LANGUAGE = 'php'; // UDF php regex language attribute (back end) + // ...to specify permissions that are needed to use this TableWidget + const REQUIRED_PERMISSIONS_PARAMETER = 'requiredPermissions'; + + // ... + 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'; @@ -47,6 +61,8 @@ class UDFLib private $_ci; // Code igniter instance + private $_udfUniqueId; // + /** * Loads fhc helper */ @@ -63,8 +79,8 @@ class UDFLib */ public function UDFWidget($args, $htmlArgs = array()) { - if ((isset($args[UDFLib::SCHEMA_ARG_NAME]) && !isEmptyString($args[UDFLib::SCHEMA_ARG_NAME])) - && (isset($args[UDFLib::TABLE_ARG_NAME]) && !isEmptyString($args[UDFLib::TABLE_ARG_NAME]))) + 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]))) { // Loads the widget library $this->_ci->load->library('WidgetLib'); @@ -73,26 +89,26 @@ class UDFLib loadResource(APPPATH.'widgets/udf'); // Default external block is true - if (!isset($args[UDFLib::FIELD_ARG_NAME]) && !isset($htmlArgs[HTMLWidget::EXTERNAL_BLOCK])) + if (!isset($args[self::FIELD_ARG_NAME]) && !isset($htmlArgs[HTMLWidget::EXTERNAL_BLOCK])) { $htmlArgs[HTMLWidget::EXTERNAL_BLOCK] = true; } return $this->_ci->widgetlib->widget( - UDFLib::WIDGET_NAME, + self::WIDGET_NAME, $args, $htmlArgs ); } else { - if (!isset($args[UDFLib::SCHEMA_ARG_NAME]) || isEmptyString($args[UDFLib::SCHEMA_ARG_NAME])) + if (!isset($args[self::SCHEMA_ARG_NAME]) || isEmptyString($args[self::SCHEMA_ARG_NAME])) { - show_error(UDFLib::SCHEMA_ARG_NAME.' parameter is missing!'); + show_error(self::SCHEMA_ARG_NAME.' parameter is missing!'); } - if (!isset($args[UDFLib::TABLE_ARG_NAME]) || isEmptyString($args[UDFLib::TABLE_ARG_NAME])) + if (!isset($args[self::TABLE_ARG_NAME]) || isEmptyString($args[self::TABLE_ARG_NAME])) { - show_error(UDFLib::TABLE_ARG_NAME.' parameter is missing!'); + show_error(self::TABLE_ARG_NAME.' parameter is missing!'); } } } @@ -105,12 +121,12 @@ class UDFLib */ public function displayUDFWidget(&$widgetData) { - $schema = $widgetData[UDFLib::SCHEMA_ARG_NAME]; // schema attribute - $table = $widgetData[UDFLib::TABLE_ARG_NAME]; // table attribute + $schema = $widgetData[self::SCHEMA_ARG_NAME]; // schema attribute + $table = $widgetData[self::TABLE_ARG_NAME]; // table attribute - if (isset($widgetData[UDFLib::FIELD_ARG_NAME])) + if (isset($widgetData[self::FIELD_ARG_NAME])) { - $field = $widgetData[UDFLib::FIELD_ARG_NAME]; // UDF name + $field = $widgetData[self::FIELD_ARG_NAME]; // UDF name } $udfResults = $this->_loadUDF($schema, $table); // loads UDF definition @@ -122,6 +138,9 @@ class UDFLib $jsonSchemas = json_decode($udf->jsons); // decode the json schema if (is_object($jsonSchemas) || is_array($jsonSchemas)) { + // + $this->_printStartUDFBlock($widgetData); + // If the schema is an object then convert it into an array if (is_object($jsonSchemas)) { @@ -140,18 +159,18 @@ class UDFLib foreach ($jsonSchemasArray as $jsonSchema) { // If the type property is not present then show an error - if (!isset($jsonSchema->{UDFLib::TYPE})) + if (!isset($jsonSchema->{self::TYPE})) { show_error(sprintf('%s.%s: Attribute "type" not present in the json schema', $schema, $table)); } // If the name property is not present then show an error - if (!isset($jsonSchema->{UDFLib::NAME})) + if (!isset($jsonSchema->{self::NAME})) { show_error(sprintf('%s.%s: Attribute "name" not present in the json schema', $schema, $table)); } // If a UDF is specified and is present in the json schemas list or no UDF is specified - if ((isset($field) && $field == $jsonSchema->{UDFLib::NAME}) || !isset($field)) + if ((isset($field) && $field == $jsonSchema->{self::NAME}) || !isset($field)) { // Set attributes using phrases $this->_setAttributesWithPhrases($jsonSchema, $widgetData[HTMLWidget::HTML_ARG_NAME]); @@ -166,7 +185,7 @@ class UDFLib $this->_render($jsonSchema, $widgetData); // If a UDf is specified and it was found then stop looking through this list - if (isset($field) && $field == $jsonSchema->{UDFLib::NAME}) + if (isset($field) && $field == $jsonSchema->{self::NAME}) { $found = true; break; @@ -179,6 +198,9 @@ class UDFLib { show_error(sprintf('%s.%s: No schema present for field: %s', $schema, $table, $field)); } + + // + $this->_printEndUDFBlock(); } else // not a valid schema { @@ -218,7 +240,7 @@ class UDFLib // Decodes json that define the UDFs for this table $decodedUDFDefinitions = json_decode( - $resultUDFsDefinitions->retval[0]->{UDFLib::COLUMN_JSON_DESCRIPTION} + $resultUDFsDefinitions->retval[0]->{self::COLUMN_JSON_DESCRIPTION} ); // Loops through the UDFs definitions @@ -232,28 +254,28 @@ class UDFLib $tmpValidate = success(true); // temporary variable used to store the returned value from _validateUDFs // If this is the definition of this UDF - if ($decodedUDFDefinition->{UDFLib::NAME} == $key) + if ($decodedUDFDefinition->{self::NAME} == $key) { - if (isset($decodedUDFDefinition->{UDFLib::VALIDATION})) // If validation rules are present for this UDF + if (isset($decodedUDFDefinition->{self::VALIDATION})) // If validation rules are present for this UDF { // Checks if the given UDF is required and the result will be stored in $chkRequiredPassed // If $chkRequiredPassed == true => required check passed // If $chkRequiredPassed == false => required check NOT passed $chkRequiredPassed = true; // If required property is present in the UDF description and it is true - if (isset($decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED}) - && $decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED} === true) + if (isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED}) + && $decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED} === true) { // If this UDF is a checkbox and the given value is false // OR - // if this UDF is NOT a checkbox and the given value is null - if (($decodedUDFDefinition->{UDFLib::TYPE} == UDFLib::CHKBOX_TYPE && $val === false) - || ($decodedUDFDefinition->{UDFLib::TYPE} != UDFLib::CHKBOX_TYPE && $val == null)) + // if this UD7F is NOT a checkbox and the given value is null + if (($decodedUDFDefinition->{self::TYPE} == self::CHKBOX_TYPE && $val === false) + || ($decodedUDFDefinition->{self::TYPE} != self::CHKBOX_TYPE && $val == null)) { $chkRequiredPassed = false; // not passed // A new error is generated and added to array $requiredUDFsArray - $requiredUDFsArray[$decodedUDFDefinition->{UDFLib::NAME}] = error( - $decodedUDFDefinition->{UDFLib::NAME}, + $requiredUDFsArray[$decodedUDFDefinition->{self::NAME}] = error( + $decodedUDFDefinition->{self::NAME}, EXIT_VALIDATION_UDF_REQUIRED ); } @@ -267,22 +289,22 @@ class UDFLib // If $toBeValidated == false => validation is NOT performed $toBeValidated = false; // If this UDF is NOT a checkbox - if ($decodedUDFDefinition->{UDFLib::TYPE} != UDFLib::CHKBOX_TYPE) + if ($decodedUDFDefinition->{self::TYPE} != self::CHKBOX_TYPE) { // If required property is NOT present in the UDF description - if (!isset($decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED})) + if (!isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED})) { $toBeValidated = true; } // If required property is present in the UDF description and it is true - if (isset($decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED}) - && $decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED} === true) + if (isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED}) + && $decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED} === true) { $toBeValidated = true; } // If required property is present in the UDF description and it is true and the given value is null - if (isset($decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED}) - && $decodedUDFDefinition->{UDFLib::VALIDATION}->{UDFLib::REQUIRED} === false + if (isset($decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED}) + && $decodedUDFDefinition->{self::VALIDATION}->{self::REQUIRED} === false && $val != null) { $toBeValidated = true; @@ -292,8 +314,8 @@ class UDFLib if ($toBeValidated === true) // Checks if validation should be performed { $tmpValidate = $this->_validateUDFs( - $decodedUDFDefinition->{UDFLib::VALIDATION}, - $decodedUDFDefinition->{UDFLib::NAME}, + $decodedUDFDefinition->{self::VALIDATION}, + $decodedUDFDefinition->{self::NAME}, $val ); } @@ -341,7 +363,7 @@ class UDFLib if ($encodedToBeStoredUDFs !== false) // if encode was ok { // Save the supplied UDFs values - $data[UDFLib::COLUMN_NAME] = $encodedToBeStoredUDFs; + $data[self::COLUMN_NAME] = $encodedToBeStoredUDFs; } } else // otherwise the returning value will be the list of UDFs validation errors @@ -360,8 +382,8 @@ class UDFLib { $isUDFColumn = false; - if (substr($columnName, 0, strlen(UDFLib::COLUMN_PREFIX)) == UDFLib::COLUMN_PREFIX - && $columnType == UDFLib::COLUMN_TYPE) + if (substr($columnName, 0, strlen(self::COLUMN_PREFIX)) == self::COLUMN_PREFIX + && $columnType == self::COLUMN_TYPE) { $isUDFColumn = true; } @@ -369,9 +391,148 @@ class UDFLib return $isUDFColumn; } + /** + * Set the _udfUniqueId property + */ + public function setUDFUniqueId($udfUniqueId) + { + $this->_udfUniqueId = $udfUniqueId; + } + + /** + * Return an unique string that identify this filter widget + * NOTE: The default value is the URI where the FilterWidget is called + * If the fhc_controller_id is present then is also used + */ + public function setUDFUniqueIdByParams($params) + { + if ($params != null + && is_array($params) + && isset($params[self::UDF_UNIQUE_ID]) + && !isEmptyString($params[self::UDF_UNIQUE_ID])) + { + $udfUniqueId = $this->_ci->router->directory.$this->_ci->router->class.'/'. + $this->_ci->router->method.'/'. + $params[self::UDF_UNIQUE_ID]; + + $this->setUDFUniqueId($udfUniqueId); + } + } + + /** + * Wrapper method to the session helper funtions to retrieve the whole session for this filter + */ + public function getSession() + { + return getSessionElement(self::SESSION_NAME, $this->_udfUniqueId); + } + + /** + * Wrapper method to the session helper funtions to retrieve one element from the session of this filter + */ + public function getSessionElement($name) + { + $session = getSessionElement(self::SESSION_NAME, $this->_udfUniqueId); + + if (isset($session[$name])) + { + return $session[$name]; + } + + return null; + } + + /** + * Wrapper method to the session helper funtions to set the whole session for this filter + */ + public function setSession($data) + { + setSessionElement(self::SESSION_NAME, $this->_udfUniqueId, $data); + } + + /** + * Wrapper method to the session helper funtions to set one element in the session for this filter + */ + public function setSessionElement($name, $value) + { + $session = getSessionElement(self::SESSION_NAME, $this->_udfUniqueId); + + $session[$name] = $value; + + setSessionElement(self::SESSION_NAME, $this->_udfUniqueId, $session); // stores the single value + } + + /** + * Save UDFs + */ + public function saveUDFs($udfUniqueId, $udfs) + { + // Read the all session for this udf widget + $session = $this->getSession(); + + if ($session == null) return error('No UDFWidget loaded'); + + // Workaround + $this->_ci->load->model('system/UDF_model', 'UDFModel'); + + // + $dbModel = new DB_Model(); + + $dbModel->setup( + $session[self::SCHEMA_ARG_NAME], // + $session[self::TABLE_ARG_NAME], // + $session[self::PRIMARY_KEY_NAME] // + ); + + return $dbModel->update( + array($session[self::PRIMARY_KEY_NAME] => $session[self::PRIMARY_KEY_VALUE]), + (array)$udfs + ); + } + // ------------------------------------------------------------------------------------------------- // Private methods + /** + * + */ + private function _printStartUDFBlock($widgetData) + { + $startBlock = '
'."\n"; + + echo sprintf( + $startBlock, + self::WIDGET_NAME, + $widgetData[self::UDF_UNIQUE_ID] + ); + } + + /** + * + */ + private function _printEndUDFBlock() + { + echo '
'."\n"; + } + + /** + * 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 FilterWidget. + * If the parameter requiredPermissions is NOT given or is not present in the session, + * then NO one is allow to use this FilterWidget + * 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); + } + /** * Move UDFs from $data to $UDFs */ @@ -381,7 +542,7 @@ class UDFLib foreach ($data as $key => $val) { - if (substr($key, 0, 4) == UDFLib::COLUMN_PREFIX) + if (substr($key, 0, 4) == self::COLUMN_PREFIX) { $udfsParameters[$key] = $val; // stores UDF value into property UDFs unset($data[$key]); // remove from data @@ -416,8 +577,8 @@ class UDFLib { // If min value attribute is present in the validation for this UDF, // then checks if the value of this UDF is compliant to this attribute - if (isset($decodedUDFValidation->{UDFLib::MIN_VALUE}) - && $udfVal < $decodedUDFValidation->{UDFLib::MIN_VALUE}) + if (isset($decodedUDFValidation->{self::MIN_VALUE}) + && $udfVal < $decodedUDFValidation->{self::MIN_VALUE}) { // validation is failed and the error is stored in $returnArrayValidation $returnArrayValidation[] = error($udfName, EXIT_VALIDATION_UDF_MIN_VALUE); @@ -425,8 +586,8 @@ class UDFLib // If max value attribute is present in the validation for this UDF, // then checks if the value of this UDF is compliant to this attribute - if (isset($decodedUDFValidation->{UDFLib::MAX_VALUE}) - && $udfVal > $decodedUDFValidation->{UDFLib::MAX_VALUE}) + if (isset($decodedUDFValidation->{self::MAX_VALUE}) + && $udfVal > $decodedUDFValidation->{self::MAX_VALUE}) { // validation is failed and the error is stored in $returnArrayValidation $returnArrayValidation[] = error($udfName, EXIT_VALIDATION_UDF_MAX_VALUE); @@ -436,8 +597,8 @@ class UDFLib $strUdfVal = strval($udfVal); // store in $strUdfVal the string conversion of $udfVal // If min length attribute is present in the validation for this UDF, // then checks if the value of this UDF is compliant to this attribute - if (isset($decodedUDFValidation->{UDFLib::MIN_LENGTH}) && isset($strUdfVal) - && strlen($strUdfVal) < $decodedUDFValidation->{UDFLib::MIN_LENGTH}) + if (isset($decodedUDFValidation->{self::MIN_LENGTH}) && isset($strUdfVal) + && strlen($strUdfVal) < $decodedUDFValidation->{self::MIN_LENGTH}) { // validation is failed and the error is stored in $returnArrayValidation $returnArrayValidation[] = error($udfName, EXIT_VALIDATION_UDF_MIN_LENGTH); @@ -445,8 +606,8 @@ class UDFLib // If max length attribute is present in the validation for this UDF, // then checks if the value of this UDF is compliant to this attribute - if (isset($decodedUDFValidation->{UDFLib::MAX_LENGTH}) && isset($strUdfVal) - && strlen($strUdfVal) > $decodedUDFValidation->{UDFLib::MAX_LENGTH}) + if (isset($decodedUDFValidation->{self::MAX_LENGTH}) && isset($strUdfVal) + && strlen($strUdfVal) > $decodedUDFValidation->{self::MAX_LENGTH}) { // validation is failed and the error is stored in $returnArrayValidation $returnArrayValidation[] = error($udfName, EXIT_VALIDATION_UDF_MAX_LENGTH); @@ -457,12 +618,12 @@ class UDFLib { // Search for a php regular expression in the validation of this UDF, if one is found // then checks if the value of this UDF is compliant to this attribute - if (isset($decodedUDFValidation->{UDFLib::REGEX}) - && is_array($decodedUDFValidation->{UDFLib::REGEX})) + if (isset($decodedUDFValidation->{self::REGEX}) + && is_array($decodedUDFValidation->{self::REGEX})) { - foreach ($decodedUDFValidation->{UDFLib::REGEX} as $regexIndx => $regex) + foreach ($decodedUDFValidation->{self::REGEX} as $regexIndx => $regex) { - if ($regex->language == UDFLib::BE_REGEX_LANGUAGE) + if ($regex->language == self::BE_REGEX_LANGUAGE) { if (preg_match($regex->expression, $udfVal) != 1) { @@ -494,8 +655,8 @@ class UDFLib */ private function _setNameAndId($jsonSchema, &$htmlParameters) { - $htmlParameters[HTMLWidget::HTML_ID] = $jsonSchema->{UDFLib::NAME}; - $htmlParameters[HTMLWidget::HTML_NAME] = $jsonSchema->{UDFLib::NAME}; + $htmlParameters[HTMLWidget::HTML_ID] = $jsonSchema->{self::NAME}; + $htmlParameters[HTMLWidget::HTML_NAME] = $jsonSchema->{self::NAME}; } /** @@ -504,20 +665,20 @@ class UDFLib private function _sortJsonSchemas(&$jsonSchemasArray) { usort($jsonSchemasArray, function ($a, $b) { - if (!isset($a->{UDFLib::SORT})) + if (!isset($a->{self::SORT})) { - $a->{UDFLib::SORT} = 9999; + $a->{self::SORT} = 9999; } - if (!isset($b->{UDFLib::SORT})) + if (!isset($b->{self::SORT})) { - $b->{UDFLib::SORT} = 9999; + $b->{self::SORT} = 9999; } - if ($a->{UDFLib::SORT} == $b->{UDFLib::SORT}) + if ($a->{self::SORT} == $b->{self::SORT}) { return 0; } - return ($a->{UDFLib::SORT} < $b->{UDFLib::SORT}) ? -1 : 1; + return ($a->{self::SORT} < $b->{self::SORT}) ? -1 : 1; }); } @@ -565,32 +726,32 @@ class UDFLib private function _render($jsonSchema, &$widgetData) { // Checkbox - if ($jsonSchema->{UDFLib::TYPE} == 'checkbox') + if ($jsonSchema->{self::TYPE} == 'checkbox') { $this->_renderCheckbox($jsonSchema, $widgetData); } // Textfield - elseif ($jsonSchema->{UDFLib::TYPE} == 'textfield') + elseif ($jsonSchema->{self::TYPE} == 'textfield') { $this->_renderTextfield($jsonSchema, $widgetData); } // Textarea - elseif ($jsonSchema->{UDFLib::TYPE} == 'textarea') + elseif ($jsonSchema->{self::TYPE} == 'textarea') { $this->_renderTextarea($jsonSchema, $widgetData); } // Date - elseif ($jsonSchema->{UDFLib::TYPE} == 'date') + elseif ($jsonSchema->{self::TYPE} == 'date') { // To be done } // Dropdown - elseif ($jsonSchema->{UDFLib::TYPE} == 'dropdown') + elseif ($jsonSchema->{self::TYPE} == 'dropdown') { $this->_renderDropdown($jsonSchema, $widgetData); } // Multiple dropdown - elseif ($jsonSchema->{UDFLib::TYPE} == 'multipledropdown') + elseif ($jsonSchema->{self::TYPE} == 'multipledropdown') { $this->_renderDropdown($jsonSchema, $widgetData, true); } @@ -602,29 +763,29 @@ class UDFLib private function _renderDropdown($jsonSchema, &$widgetData, $multiple = false) { // Selected element/s - if (isset($widgetData[UDFLib::UDFS_ARG_NAME]) - && isset($widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}])) + if (isset($widgetData[self::UDFS_ARG_NAME]) + && isset($widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}])) { - $widgetData[DropdownWidget::SELECTED_ELEMENT] = $widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}]; + $widgetData[DropdownWidget::SELECTED_ELEMENT] = $widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}]; } else { $widgetData[DropdownWidget::SELECTED_ELEMENT] = null; } - $dropdownWidgetUDF = new DropdownWidgetUDF(UDFLib::WIDGET_NAME, $widgetData); + $dropdownWidgetUDF = new DropdownWidgetUDF(self::WIDGET_NAME, $widgetData); $parameters = array(); // If the list of values to show is an array - if (isset($jsonSchema->{UDFLib::LIST_VALUES}->enum)) + if (isset($jsonSchema->{self::LIST_VALUES}->enum)) { - $parameters = $jsonSchema->{UDFLib::LIST_VALUES}->enum; + $parameters = $jsonSchema->{self::LIST_VALUES}->enum; } // If the list of values to show should be retrieved with a SQL statement - elseif (isset($jsonSchema->{UDFLib::LIST_VALUES}->sql)) + elseif (isset($jsonSchema->{self::LIST_VALUES}->sql)) { // UDFModel is loaded in method _loadUDF that is called before the current method - $queryResult = $this->_ci->UDFModel->execReadOnlyQuery($jsonSchema->{UDFLib::LIST_VALUES}->sql); + $queryResult = $this->_ci->UDFModel->execReadOnlyQuery($jsonSchema->{self::LIST_VALUES}->sql); if (hasData($queryResult)) { $parameters = $queryResult->retval; @@ -645,13 +806,13 @@ class UDFLib private function _renderTextarea($jsonSchema, &$widgetData) { $text = null; // text value - $textareaUDF = new TextareaWidgetUDF(UDFLib::WIDGET_NAME, $widgetData); + $textareaUDF = new TextareaWidgetUDF(self::WIDGET_NAME, $widgetData); // Set text value if present in the DB - if (isset($widgetData[UDFLib::UDFS_ARG_NAME]) - && isset($widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}])) + if (isset($widgetData[self::UDFS_ARG_NAME]) + && isset($widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}])) { - $text = $widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}]; + $text = $widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}]; } $textareaUDF->render($text); @@ -663,13 +824,13 @@ class UDFLib private function _renderTextfield($jsonSchema, &$widgetData) { $text = null; // text value - $textareaUDF = new TextfieldWidgetUDF(UDFLib::WIDGET_NAME, $widgetData); + $textareaUDF = new TextfieldWidgetUDF(self::WIDGET_NAME, $widgetData); // Set text value if present in the DB - if (isset($widgetData[UDFLib::UDFS_ARG_NAME]) - && isset($widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}])) + if (isset($widgetData[self::UDFS_ARG_NAME]) + && isset($widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}])) { - $text = $widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}]; + $text = $widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}]; } $textareaUDF->render($text); @@ -681,17 +842,17 @@ class UDFLib private function _renderCheckbox($jsonSchema, &$widgetData) { // Set checkbox value if present in the DB - if (isset($widgetData[UDFLib::UDFS_ARG_NAME]) - && isset($widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}])) + if (isset($widgetData[self::UDFS_ARG_NAME]) + && isset($widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}])) { - $widgetData[CheckboxWidget::VALUE_FIELD] = $widgetData[UDFLib::UDFS_ARG_NAME][$jsonSchema->{UDFLib::NAME}]; + $widgetData[CheckboxWidget::VALUE_FIELD] = $widgetData[self::UDFS_ARG_NAME][$jsonSchema->{self::NAME}]; } else { $widgetData[CheckboxWidget::VALUE_FIELD] = CheckboxWidget::HTML_DEFAULT_VALUE; } - $checkboxWidgetUDF = new CheckboxWidgetUDF(UDFLib::WIDGET_NAME, $widgetData); + $checkboxWidgetUDF = new CheckboxWidgetUDF(self::WIDGET_NAME, $widgetData); $checkboxWidgetUDF->render(); } @@ -707,21 +868,21 @@ class UDFLib $htmlParameters[HTMLWidget::PLACEHOLDER] = null; // Description, title and placeholder - if (isset($jsonSchema->{UDFLib::LABEL}) - || isset($jsonSchema->{UDFLib::TITLE}) - || isset($jsonSchema->{UDFLib::PLACEHOLDER})) + if (isset($jsonSchema->{self::LABEL}) + || isset($jsonSchema->{self::TITLE}) + || isset($jsonSchema->{self::PLACEHOLDER})) { // Loads phrases library $this->_ci->load->library('PhrasesLib'); // If is set the label property in the json schema - if (isset($jsonSchema->{UDFLib::LABEL})) + if (isset($jsonSchema->{self::LABEL})) { // Load the related phrase $tmpResult = $this->_ci->phraseslib->getPhrases( - UDFLib::PHRASES_APP_NAME, + self::PHRASES_APP_NAME, getUserLanguage(), - $jsonSchema->{UDFLib::LABEL}, + $jsonSchema->{self::LABEL}, null, null, 'no' @@ -733,13 +894,13 @@ class UDFLib } // If is set the title property in the json schema - if (isset($jsonSchema->{UDFLib::TITLE})) + if (isset($jsonSchema->{self::TITLE})) { // Load the related phrase $tmpResult = $this->_ci->phraseslib->getPhrases( - UDFLib::PHRASES_APP_NAME, + self::PHRASES_APP_NAME, getUserLanguage(), - $jsonSchema->{UDFLib::TITLE}, + $jsonSchema->{self::TITLE}, null, null, 'no' @@ -751,13 +912,13 @@ class UDFLib } // If is set the placeholder property in the json schema - if (isset($jsonSchema->{UDFLib::PLACEHOLDER})) + if (isset($jsonSchema->{self::PLACEHOLDER})) { // Load the related phrase $tmpResult = $this->_ci->phraseslib->getPhrases( - UDFLib::PHRASES_APP_NAME, + self::PHRASES_APP_NAME, getUserLanguage(), - $jsonSchema->{UDFLib::PLACEHOLDER}, + $jsonSchema->{self::PLACEHOLDER}, null, null, 'no' @@ -784,17 +945,17 @@ class UDFLib $htmlParameters[HTMLWidget::MAX_LENGTH] = null; // If validation property is present in the json schema - if (isset($jsonSchema->{UDFLib::VALIDATION})) + if (isset($jsonSchema->{self::VALIDATION})) { - $jsonSchemaValidation =& $jsonSchema->{UDFLib::VALIDATION}; // Reference for a better code readability + $jsonSchemaValidation =& $jsonSchema->{self::VALIDATION}; // Reference for a better code readability // Front-end regex - if (isset($jsonSchemaValidation->{UDFLib::REGEX}) - && is_array($jsonSchemaValidation->{UDFLib::REGEX})) + if (isset($jsonSchemaValidation->{self::REGEX}) + && is_array($jsonSchemaValidation->{self::REGEX})) { - foreach ($jsonSchemaValidation->{UDFLib::REGEX} as $regex) + foreach ($jsonSchemaValidation->{self::REGEX} as $regex) { - if ($regex->language === UDFLib::FE_REGEX_LANGUAGE) + if ($regex->language === self::FE_REGEX_LANGUAGE) { $htmlParameters[HTMLWidget::REGEX] = $regex->expression; } @@ -802,33 +963,33 @@ class UDFLib } // Required - if (isset($jsonSchemaValidation->{UDFLib::REQUIRED})) + if (isset($jsonSchemaValidation->{self::REQUIRED})) { - $htmlParameters[HTMLWidget::REQUIRED] = $jsonSchemaValidation->{UDFLib::REQUIRED}; + $htmlParameters[HTMLWidget::REQUIRED] = $jsonSchemaValidation->{self::REQUIRED}; } // Min value - if (isset($jsonSchemaValidation->{UDFLib::MIN_VALUE})) + if (isset($jsonSchemaValidation->{self::MIN_VALUE})) { - $htmlParameters[HTMLWidget::MIN_VALUE] = $jsonSchemaValidation->{UDFLib::MIN_VALUE}; + $htmlParameters[HTMLWidget::MIN_VALUE] = $jsonSchemaValidation->{self::MIN_VALUE}; } // Max value - if (isset($jsonSchemaValidation->{UDFLib::MAX_VALUE})) + if (isset($jsonSchemaValidation->{self::MAX_VALUE})) { - $htmlParameters[HTMLWidget::MAX_VALUE] = $jsonSchemaValidation->{UDFLib::MAX_VALUE}; + $htmlParameters[HTMLWidget::MAX_VALUE] = $jsonSchemaValidation->{self::MAX_VALUE}; } // Min length - if (isset($jsonSchemaValidation->{UDFLib::MIN_LENGTH})) + if (isset($jsonSchemaValidation->{self::MIN_LENGTH})) { - $htmlParameters[HTMLWidget::MIN_LENGTH] = $jsonSchemaValidation->{UDFLib::MIN_LENGTH}; + $htmlParameters[HTMLWidget::MIN_LENGTH] = $jsonSchemaValidation->{self::MIN_LENGTH}; } // Max length - if (isset($jsonSchemaValidation->{UDFLib::MAX_LENGTH})) + if (isset($jsonSchemaValidation->{self::MAX_LENGTH})) { - $htmlParameters[HTMLWidget::MAX_LENGTH] = $jsonSchemaValidation->{UDFLib::MAX_LENGTH}; + $htmlParameters[HTMLWidget::MAX_LENGTH] = $jsonSchemaValidation->{self::MAX_LENGTH}; } } } diff --git a/application/models/system/FAS_UDF_model.php b/application/models/system/FAS_UDF_model.php deleted file mode 100644 index aee49d431..000000000 --- a/application/models/system/FAS_UDF_model.php +++ /dev/null @@ -1,169 +0,0 @@ -load->model('person/Person_model', 'PersonModel'); - - $result = $this->load(array('public', 'tbl_person')); - if (isSuccess($result) && count($result->retval) == 1) - { - $jsons = json_decode($result->retval[0]->jsons); - } - - $udfs = $this->_fillMissingTextUDF($udfs, $jsons); - $udfs = $this->_fillMissingChkboxUDF($udfs, $jsons); - $udfs = $this->_fillMissingDropdownUDF($udfs, $jsons); - - $resultPerson = $this->PersonModel->update($person_id, $udfs); - } - - // - if (isset($prestudent_id)) - { - // Load model Prestudent_model - $this->load->model('crm/Prestudent_model', 'PrestudentModel'); - - $result = $this->load(array('public', 'tbl_prestudent')); - if (isSuccess($result) && count($result->retval) == 1) - { - $jsons = json_decode($result->retval[0]->jsons); - } - - $udfs = $this->_fillMissingTextUDF($udfs, $jsons); - $udfs = $this->_fillMissingChkboxUDF($udfs, $jsons); - $udfs = $this->_fillMissingDropdownUDF($udfs, $jsons); - - $resultPrestudent = $this->PrestudentModel->update($prestudent_id, $udfs); - } - - if (isSuccess($resultPerson) && isSuccess($resultPrestudent)) - { - $result = success(array($resultPerson->retval, $resultPrestudent->retval)); - } - else if(isError($resultPerson)) - { - $result = $resultPerson; - } - else if(isError($resultPrestudent)) - { - $result = $resultPrestudent; - } - - return $result; - } - - /** - * - */ - private function _fillMissingChkboxUDF($udfs, $jsons) - { - $_fillMissingChkboxUDF = $udfs; - - foreach($jsons as $udfDescription) - { - if ($udfDescription->{UDFLib::TYPE} == UDFLib::CHKBOX_TYPE) - { - if (!isset($_fillMissingChkboxUDF[$udfDescription->{UDFLib::NAME}])) - { - $_fillMissingChkboxUDF[$udfDescription->{UDFLib::NAME}] = false; - } - else - { - if ($_fillMissingChkboxUDF[$udfDescription->{UDFLib::NAME}] == UDF_model::STRING_FALSE) - { - $_fillMissingChkboxUDF[$udfDescription->{UDFLib::NAME}] = false; - } - else if ($_fillMissingChkboxUDF[$udfDescription->{UDFLib::NAME}] == UDF_model::STRING_TRUE) - { - $_fillMissingChkboxUDF[$udfDescription->{UDFLib::NAME}] = true; - } - } - } - } - - return $_fillMissingChkboxUDF; - } - - /** - * - */ - private function _fillMissingDropdownUDF($udfs, $jsons) - { - $_fillMissingDropdownUDF = $udfs; - - foreach($jsons as $udfDescription) - { - if ($udfDescription->{UDFLib::TYPE} == UDF_model::UDF_DROPDOWN_TYPE - || $udfDescription->{UDFLib::TYPE} == UDF_model::UDF_MULTIPLEDROPDOWN_TYPE) - { - if (!isset($_fillMissingDropdownUDF[$udfDescription->{UDFLib::NAME}])) - { - $_fillMissingDropdownUDF[$udfDescription->{UDFLib::NAME}] = null; - } - else if($_fillMissingDropdownUDF[$udfDescription->{UDFLib::NAME}] == UDF_model::STRING_NULL) - { - $_fillMissingDropdownUDF[$udfDescription->{UDFLib::NAME}] = null; - } - } - } - - return $_fillMissingDropdownUDF; - } - - /** - * - */ - private function _fillMissingTextUDF($udfs, $jsons) - { - $_fillMissingTextUDF = $udfs; - - foreach($jsons as $udfDescription) - { - if ($udfDescription->{UDFLib::TYPE} == 'textarea' - || $udfDescription->{UDFLib::TYPE} == 'textfield') - { - if (!isset($_fillMissingTextUDF[$udfDescription->{UDFLib::NAME}])) - { - $_fillMissingTextUDF[$udfDescription->{UDFLib::NAME}] = null; - } - else if(trim($_fillMissingTextUDF[$udfDescription->{UDFLib::NAME}]) == '') - { - $_fillMissingTextUDF[$udfDescription->{UDFLib::NAME}] = null; - } - } - } - - return $_fillMissingTextUDF; - } -} diff --git a/application/views/system/fas_udf.php b/application/views/system/fas_udf.php index d4a01b9e9..1ffa4b272 100644 --- a/application/views/system/fas_udf.php +++ b/application/views/system/fas_udf.php @@ -1,54 +1,28 @@ -load->view("templates/header", array("title" => "UDF", "widgetsCSS" => true)); ?> +load->view( + 'templates/FHC-Header', + array( + 'title' => 'InfocenterDetails', + 'jquery' => true, + 'bootstrap' => true, + 'fontawesome' => true, + 'jqueryui' => true, + 'dialoglib' => true, + 'ajaxlib' => true, + 'udfs' => true, + 'sbadmintemplate' => true, + 'customCSSs' => array( + 'public/css/sbadmin2/admintemplate.css' + ), + 'customJSs' => array( + 'public/js/bootstrapper.js' + ) + ) + ); +?> - -
- Saved! -
- -
- -
- Error while saving! -
-
-
-retval; - if(is_array($errors)) - { - foreach ($errors as $error) - { - foreach ($error as $fieldError) - { - echo $fieldError->code . ': ' . $fieldError->retval . '
'; - } - } - } - else - echo $result->retval; -?> -
- -
-
-
- -
-
@@ -69,8 +43,12 @@ udflib->UDFWidget( array( + UDFLib::UDF_UNIQUE_ID => 'fasPersonUDFs', + UDFLib::REQUIRED_PERMISSIONS_PARAMETER => 'basis/person', UDFLib::SCHEMA_ARG_NAME => 'public', UDFLib::TABLE_ARG_NAME => 'tbl_person', + UDFLib::PRIMARY_KEY_NAME => 'person_id', + UDFLib::PRIMARY_KEY_VALUE => $person_id, UDFLib::UDFS_ARG_NAME => $personUdfs ) ); @@ -90,8 +68,12 @@ udflib->UDFWidget( array( + UDFLib::UDF_UNIQUE_ID => 'fasPrestudentUDFs', + UDFLib::REQUIRED_PERMISSIONS_PARAMETER => 'basis/person', UDFLib::SCHEMA_ARG_NAME => 'public', UDFLib::TABLE_ARG_NAME => 'tbl_prestudent', + UDFLib::PRIMARY_KEY_NAME => 'prestudent_id', + UDFLib::PRIMARY_KEY_VALUE => $prestudent_id, UDFLib::UDFS_ARG_NAME => $prestudentUdfs ) ); @@ -120,31 +102,9 @@ -
- -
- - - - - - - - - load->view("templates/footer"); ?> diff --git a/application/views/templates/FHC-Header.php b/application/views/templates/FHC-Header.php index 3c1327d5f..49a77fe17 100644 --- a/application/views/templates/FHC-Header.php +++ b/application/views/templates/FHC-Header.php @@ -33,6 +33,7 @@ $tablewidget = isset($tablewidget) ? $tablewidget : false; $tabulator = isset($tabulator) ? $tabulator : false; $tinymce = isset($tinymce) ? $tinymce : false; + $udfs = isset($udfs) ? $udfs : false; ?> @@ -176,6 +177,9 @@ // Tinymce JS if ($tinymce === true) generateJSsInclude('vendor/tinymce/tinymce/tinymce.min.js'); + // Tinymce JS + if ($udfs === true) generateJSsInclude('public/js/UDFWidget.js'); + // SB Admin 2 template JS if ($sbadmintemplate === true) { diff --git a/application/widgets/udf/DropdownWidgetUDF.php b/application/widgets/udf/DropdownWidgetUDF.php index 04552e953..8a55f71f6 100644 --- a/application/widgets/udf/DropdownWidgetUDF.php +++ b/application/widgets/udf/DropdownWidgetUDF.php @@ -12,7 +12,7 @@ class DropdownWidgetUDF extends DropdownWidget { // Array that will contains the elements to be displayed in the dropdown $tmpNewElements = array(); - + // Loops through the given parameters foreach($parameters as $parameter) { @@ -29,27 +29,27 @@ class DropdownWidgetUDF extends DropdownWidget // If the single element is an array of two element if (is_array($parameter) && count($parameter) == 2) { - $newElement->{DropdownWidget::ID_FIELD} = $parameter[0]; // - $newElement->{DropdownWidget::DESCRIPTION_FIELD} = $parameter[1]; // + $newElement->{DropdownWidget::ID_FIELD} = $parameter[0]; // + $newElement->{DropdownWidget::DESCRIPTION_FIELD} = $parameter[1]; // } // If the single element is a string or a number else if (is_string($parameter) || is_numeric($parameter)) { - $newElement->{DropdownWidget::ID_FIELD} = $parameter; // - $newElement->{DropdownWidget::DESCRIPTION_FIELD} = $parameter; // + $newElement->{DropdownWidget::ID_FIELD} = $parameter; // + $newElement->{DropdownWidget::DESCRIPTION_FIELD} = $parameter; // } // If the single element is an object with two properties: id and description else if (is_object($parameter) && isset($parameter->{DropdownWidget::ID_FIELD}) && isset($parameter->{DropdownWidget::DESCRIPTION_FIELD})) { - $newElement->{DropdownWidget::ID_FIELD} = $parameter->{DropdownWidget::ID_FIELD}; // - $newElement->{DropdownWidget::DESCRIPTION_FIELD} = $parameter->{DropdownWidget::DESCRIPTION_FIELD}; // + $newElement->{DropdownWidget::ID_FIELD} = $parameter->{DropdownWidget::ID_FIELD}; // + $newElement->{DropdownWidget::DESCRIPTION_FIELD} = $parameter->{DropdownWidget::DESCRIPTION_FIELD}; // } - + array_push($tmpNewElements, $newElement); // Add $newElement into $tmpNewElements } } - + // Set the list of elements $this->setElementsArray( success($tmpNewElements), @@ -57,9 +57,9 @@ class DropdownWidgetUDF extends DropdownWidget $this->htmlParameters[HTMLWidget::PLACEHOLDER], 'No data found for this UDF' ); - + $this->loadDropDownView(); - + echo $this->content(); } -} \ No newline at end of file +} diff --git a/application/widgets/udf/UDFWidget.php b/application/widgets/udf/UDFWidget.php index 756df4765..b3bf82470 100644 --- a/application/widgets/udf/UDFWidget.php +++ b/application/widgets/udf/UDFWidget.php @@ -6,14 +6,155 @@ */ class UDFWidget extends HTMLWidget { + private $_requiredPermissions; // + + private $_schema; + private $_table; + private $_primaryKeyName; + private $_primaryKeyValue; + + /** + * Initialize the UDFWidget and starts the execution of the logic + */ + public function __construct($name, $args = array()) + { + parent::__construct($name, $args); // calls the parent's constructor + + $this->load->library('UDFLib'); // Loads the UDFLib that contains all the used logic + + $this->udflib->setUDFUniqueIdByParams($args); + + $this->_initUDFWidget($args); // checks parameters and initialize properties + + // Let's start if it's allowed + // NOTE: If it is NOT allowed then no data are loaded + if ($this->udflib->isAllowed($this->_requiredPermissions)) + { + $this->_startUDFWidget($args[UDFLib::UDF_UNIQUE_ID]); + } + } + /** * Called by the WidgetLib, it renders the HTML of the UDF */ public function display($widgetData) { - // _ci is the instance of Code Igniter and the library UDFLib was previously loaded, - // so now is it possibile to call the method displayUDFWidget of UDFLib - // to render the HTML of this UDF - $this->_ci->udflib->displayUDFWidget($widgetData); + // Let's start if it's allowed + // NOTE: If it is NOT allowed then no data are loaded + if ($this->_ci->udflib->isAllowed($this->_requiredPermissions)) + { + $this->_ci->udflib->displayUDFWidget($widgetData); + } } -} \ No newline at end of file + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks parameters and initialize all the properties of this UDFWidget + */ + private function _initUDFWidget($args) + { + $this->_checkParameters($args); + + // If here then everything is ok + + // Initialize class properties + $this->_requiredPermissions = null; + $this->_schema = null; + $this->_table = null; + $this->_primaryKeyName = null; + $this->_primaryKeyValue = null; + + // Retrieved the required permissions parameter if present + if (isset($args[UDFLib::REQUIRED_PERMISSIONS_PARAMETER])) + { + $this->_requiredPermissions = $args[UDFLib::REQUIRED_PERMISSIONS_PARAMETER]; + } + + // Retrieved the + if (isset($args[UDFLib::SCHEMA_ARG_NAME])) + { + $this->_schema = $args[UDFLib::SCHEMA_ARG_NAME]; + } + + // Retrieved the + if (isset($args[UDFLib::TABLE_ARG_NAME])) + { + $this->_table = $args[UDFLib::TABLE_ARG_NAME]; + } + + // Retrieved the + if (isset($args[UDFLib::PRIMARY_KEY_NAME])) + { + $this->_primaryKeyName = $args[UDFLib::PRIMARY_KEY_NAME]; + } + + // Retrieved the + if (isset($args[UDFLib::PRIMARY_KEY_VALUE])) + { + $this->_primaryKeyValue = $args[UDFLib::PRIMARY_KEY_VALUE]; + } + } + + /** + * Checks the required parameters used to call this UDFWidget + */ + private function _checkParameters($args) + { + if (!is_array($args) || (is_array($args) && count($args) == 0)) + { + show_error('Second parameter of the widget call must be a NOT empty associative array'); + } + else + { + if (!isset($args[UDFLib::UDF_UNIQUE_ID])) + { + show_error('The parameter "'.UDFLib::UDF_UNIQUE_ID.'" must be specified'); + } + + if (!isset($args[UDFLib::REQUIRED_PERMISSIONS_PARAMETER])) + { + show_error('The parameter "'.UDFLib::REQUIRED_PERMISSIONS_PARAMETER.'" must be specified'); + } + + if (!isset($args[UDFLib::SCHEMA_ARG_NAME])) + { + show_error('The parameter "'.UDFLib::SCHEMA_ARG_NAME.'" must be specified'); + } + + if (!isset($args[UDFLib::TABLE_ARG_NAME])) + { + show_error('The parameter "'.UDFLib::TABLE_ARG_NAME.'" must be specified'); + } + + if (!isset($args[UDFLib::PRIMARY_KEY_NAME])) + { + show_error('The parameter "'.UDFLib::PRIMARY_KEY_NAME.'" must be specified'); + } + + if (!isset($args[UDFLib::PRIMARY_KEY_VALUE])) + { + show_error('The parameter "'.UDFLib::PRIMARY_KEY_VALUE.'" must be specified'); + } + } + } + + /** + * Contains all the logic used to load all the data needed to the UDFWidget + */ + private function _startUDFWidget($udfUniqueId) + { + // Stores an array that contains all the data useful for + $this->udflib->setSession( + array( + UDFLib::UDF_UNIQUE_ID => $udfUniqueId, // table unique id + UDFLib::REQUIRED_PERMISSIONS_PARAMETER => $this->_requiredPermissions, // + UDFLib::SCHEMA_ARG_NAME => $this->_schema, // + UDFLib::TABLE_ARG_NAME => $this->_table, // + UDFLib::PRIMARY_KEY_NAME => $this->_primaryKeyName, // + UDFLib::PRIMARY_KEY_VALUE => $this->_primaryKeyValue // + ) + ); + } +} diff --git a/public/js/UDFWidget.js b/public/js/UDFWidget.js new file mode 100644 index 000000000..dc04fe0d5 --- /dev/null +++ b/public/js/UDFWidget.js @@ -0,0 +1,100 @@ +/** + * UDFWidget JS magic + */ + +/** + * FHC_UDFWidget this object is used to render the GUI of a table widget and to operate with it + */ +var FHC_UDFWidget = { + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * To display the TableWidget using the loaded data prenset in the session + */ + display: function() { + + $("div[type*='UDFWidget']").each(function(i, udfWidgetDiv) { + + var saveButton = $(''); + + saveButton.on('click', function() { + + var udfs = {}; + + $("div[udfUniqueId*='" + udfWidgetDiv.attributes["udfUniqueId"].nodeValue + "']").find("[name^='udf_']").each(function(i, udf) { + + if (udf.type == 'checkbox') + { + udfs[udf.id] = udf.checked == true; + } + else if (udf.type == 'select-one' || udf.type == 'select-multiple') + { + udfs[udf.id] = null; + + if (!isNaN(udf.value) && udf.value.trim() != '') + { + udfs[udf.id] = Number(udf.value); + } + } + else + { + udfs[udf.id] = udf.value; + } + }); + + FHC_AjaxClient.ajaxCallPost( + "widgets/UDF/saveUDFs", + { + udfUniqueId: FHC_UDFWidget._getUDFUniqueIdPrefix() + "/" + udfWidgetDiv.attributes["udfUniqueId"].nodeValue, + udfs: JSON.stringify(udfs) + }, + { + successCallback: function(data, textStatus, jqXHR) { + + if (FHC_AjaxClient.hasData(data)) + { + FHC_DialogLib.alertSuccess('Done!'); + } + else + { + console.log(FHC_AjaxClient.getError(data)); + } + } + }, + { + errorCallback: function(data, textStatus, jqXHR) { + console.log('Contact the administrator'); + } + } + ); + + }); + + saveButton.appendTo(udfWidgetDiv); + + }); + + }, + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * To retrive the page where the TableWidget is used, using the FHC_JS_DATA_STORAGE_OBJECT + */ + _getUDFUniqueIdPrefix: function() { + + return FHC_JS_DATA_STORAGE_OBJECT.called_path + "/" + FHC_JS_DATA_STORAGE_OBJECT.called_method; + } +}; + +/** + * When JQuery is up + */ +$(document).ready(function() { + + FHC_UDFWidget.display(); + +}); From e509f7acd17e7d6cdf4e6fd82462d20ed73e5dfd Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 17 Dec 2019 16:57:02 +0100 Subject: [PATCH 002/265] Added comments and cleaned code --- application/controllers/widgets/Filters.php | 4 +- application/controllers/widgets/Tables.php | 4 +- application/controllers/widgets/UDF.php | 21 +++-- application/core/DB_Model.php | 2 +- application/libraries/UDFLib.php | 86 +++++++++++---------- application/views/templates/FHC-Header.php | 2 +- application/widgets/udf/UDFWidget.php | 12 +-- 7 files changed, 70 insertions(+), 61 deletions(-) diff --git a/application/controllers/widgets/Filters.php b/application/controllers/widgets/Filters.php index b5cbc07ea..748272f09 100644 --- a/application/controllers/widgets/Filters.php +++ b/application/controllers/widgets/Filters.php @@ -4,7 +4,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** * This controller operates between (interface) the JS (GUI) and the FilterWidgetLib (back-end) - * Provides data to the ajax get calls about the filter + * Provides data to the ajax get calls about the filter widget * Accepts ajax post calls to change the filter data * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON * NOTE: extends the FHC_Controller instead of the Auth_Controller because the FilterWidget has its @@ -12,7 +12,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); */ class Filters extends FHC_Controller { - const FILTER_UNIQUE_ID = 'filterUniqueId'; + const FILTER_UNIQUE_ID = 'filterUniqueId'; // Name of the filter widget unique id /** * Calls the parent's constructor and loads the FilterWidgetLib diff --git a/application/controllers/widgets/Tables.php b/application/controllers/widgets/Tables.php index 21161ff9f..b3ea7d5a5 100644 --- a/application/controllers/widgets/Tables.php +++ b/application/controllers/widgets/Tables.php @@ -4,7 +4,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** * This controller operates between (interface) the JS (GUI) and the tablewidgetlib (back-end) - * Provides data to the ajax get calls about the filter + * Provides data to the ajax get calls about the table widget * Accepts ajax post calls to change the filter data * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON * NOTE: extends the FHC_Controller instead of the Auth_Controller because the TableWidget has its @@ -12,7 +12,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); */ class Tables extends FHC_Controller { - const TABLE_UNIQUE_ID = 'tableUniqueId'; + const TABLE_UNIQUE_ID = 'tableUniqueId'; // Name of the table widget unique id /** * Calls the parent's constructor and loads the tablewidgetlib diff --git a/application/controllers/widgets/UDF.php b/application/controllers/widgets/UDF.php index c71eba73a..5b4c45776 100644 --- a/application/controllers/widgets/UDF.php +++ b/application/controllers/widgets/UDF.php @@ -3,14 +3,19 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** - * This controller... + * This controller operates between (interface) the JS (GUI) and the UDFLib (back-end) + * Provides data to the ajax get calls about the UDF widget + * Accepts ajax post calls to save UDFs + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + * NOTE: extends the FHC_Controller instead of the Auth_Controller because the UDFWidget has its + * own permissions check */ class UDF extends FHC_Controller { - const UDF_UNIQUE_ID = 'udfUniqueId'; + const UDF_UNIQUE_ID = 'udfUniqueId'; // Name of the udf widget unique id /** - * Calls the parent's constructor and loads the + * Calls the parent's constructor and loads the UDFLib */ public function __construct() { @@ -22,7 +27,7 @@ class UDF extends FHC_Controller // Loads the UDFLib with HTTP GET/POST parameters $this->_loadUDFLib(); - // Checks if the caller is allow to read this data + // Checks if the caller is allow to use this UDF widget $this->_isAllowed(); } @@ -30,7 +35,7 @@ class UDF extends FHC_Controller // Public methods /** - * Retrieves data about the current filter from the session and will be written on the output in JSON format + * Save data about the current UDFs and the result will be written on the output in JSON format */ public function saveUDFs() { @@ -59,7 +64,7 @@ class UDF extends FHC_Controller // Private methods /** - * Checks if the user is allowed to use this filter + * Checks if the user is allowed to use this UDFWidget */ private function _isAllowed() { @@ -70,7 +75,7 @@ class UDF extends FHC_Controller } /** - * Loads the tablewidgetlib with the UDF_UNIQUE_ID parameter + * 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 * an error message is printed */ @@ -89,7 +94,7 @@ class UDF extends FHC_Controller $udfUniqueId = $this->input->post(self::UDF_UNIQUE_ID); // is retrieved from the HTTP POST } - // Loads the tablewidgetlib that contains all the used logic + // Loads the UDFLib that contains all the used logic $this->load->library('UDFLib'); $this->udflib->setUDFUniqueId($udfUniqueId); diff --git a/application/core/DB_Model.php b/application/core/DB_Model.php index 667ff00ca..4b89ae5bf 100644 --- a/application/core/DB_Model.php +++ b/application/core/DB_Model.php @@ -61,7 +61,7 @@ class DB_Model extends CI_Model // Public methods /** - * This method provides a way to setup a database model without declaring one + * This method provides a way to setup a database model without declaring one that extends this class */ public function setup($schema, $table, $primaryKey, $hasSequence = true) { diff --git a/application/libraries/UDFLib.php b/application/libraries/UDFLib.php index edd11fd99..b9247fc4e 100644 --- a/application/libraries/UDFLib.php +++ b/application/libraries/UDFLib.php @@ -3,19 +3,20 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** - * Library to manage UDF + * Library to manage UDFs */ class UDFLib { - const UDF_UNIQUE_ID = 'udfUniqueId'; + const UDF_UNIQUE_ID = 'udfUniqueId'; // Name of the UDF widget unique id - const SESSION_NAME = 'FHC_UDF_WIDGET'; + const SESSION_NAME = 'FHC_UDF_WIDGET'; // Name of the session area used for UDFs - const WIDGET_NAME = 'UDFWidget'; - const SCHEMA_ARG_NAME = 'schema'; - const TABLE_ARG_NAME = 'table'; - const FIELD_ARG_NAME = 'field'; - const UDFS_ARG_NAME = 'udfs'; + // Parameters names + const WIDGET_NAME = 'UDFWidget'; // UDFWidget name + const SCHEMA_ARG_NAME = 'schema'; // Schema parameter name + const TABLE_ARG_NAME = 'table'; // Table parameter name + const FIELD_ARG_NAME = 'field'; // Field parameter name + const UDFS_ARG_NAME = 'udfs'; // UDFs parameter name // UDF json schema attributes const NAME = 'name'; // UDF name attribute @@ -29,7 +30,7 @@ class UDFLib // ...to specify permissions that are needed to use this TableWidget const REQUIRED_PERMISSIONS_PARAMETER = 'requiredPermissions'; - // ... + // ...to specify the primary key name and value const PRIMARY_KEY_NAME = 'primaryKeyName'; const PRIMARY_KEY_VALUE = 'primaryKeyValue'; @@ -61,10 +62,10 @@ class UDFLib private $_ci; // Code igniter instance - private $_udfUniqueId; // + private $_udfUniqueId; // Property that contains the UDF widget unique id /** - * Loads fhc helper + * Gets CI instance */ public function __construct() { @@ -400,7 +401,7 @@ class UDFLib } /** - * Return an unique string that identify this filter widget + * Return an unique string that identify this UDF widget * NOTE: The default value is the URI where the FilterWidget is called * If the fhc_controller_id is present then is also used */ @@ -420,7 +421,7 @@ class UDFLib } /** - * Wrapper method to the session helper funtions to retrieve the whole session for this filter + * Wrapper method to the session helper funtions to retrieve the whole session for this UDF widget */ public function getSession() { @@ -428,7 +429,7 @@ class UDFLib } /** - * Wrapper method to the session helper funtions to retrieve one element from the session of this filter + * Wrapper method to the session helper funtions to retrieve one element from the session of this UDF widget */ public function getSessionElement($name) { @@ -443,7 +444,7 @@ class UDFLib } /** - * Wrapper method to the session helper funtions to set the whole session for this filter + * Wrapper method to the session helper funtions to set the whole session for this UDF widget */ public function setSession($data) { @@ -451,7 +452,7 @@ class UDFLib } /** - * Wrapper method to the session helper funtions to set one element in the session for this filter + * Wrapper method to the session helper funtions to set one element in the session for this UDF widget */ public function setSessionElement($name, $value) { @@ -470,31 +471,52 @@ class UDFLib // Read the all session for this udf widget $session = $this->getSession(); + // If session is empty then return an error if ($session == null) return error('No UDFWidget loaded'); - // Workaround + // Workaround to load CI $this->_ci->load->model('system/UDF_model', 'UDFModel'); - // + // Initialize a new DB_Model $dbModel = new DB_Model(); + // Setup the new dbModel object with... $dbModel->setup( - $session[self::SCHEMA_ARG_NAME], // - $session[self::TABLE_ARG_NAME], // - $session[self::PRIMARY_KEY_NAME] // + $session[self::SCHEMA_ARG_NAME], // ... schema... + $session[self::TABLE_ARG_NAME], // ...table... + $session[self::PRIMARY_KEY_NAME] // ...and primary key name ); + // 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 ); } + /** + * 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 /** - * + * Print the block for UDFs */ private function _printStartUDFBlock($widgetData) { @@ -508,31 +530,13 @@ class UDFLib } /** - * + * Print the end of the UDFs block */ private function _printEndUDFBlock() { echo '
'."\n"; } - /** - * 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 FilterWidget. - * If the parameter requiredPermissions is NOT given or is not present in the session, - * then NO one is allow to use this FilterWidget - * 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); - } - /** * Move UDFs from $data to $UDFs */ diff --git a/application/views/templates/FHC-Header.php b/application/views/templates/FHC-Header.php index 49a77fe17..127575c2b 100644 --- a/application/views/templates/FHC-Header.php +++ b/application/views/templates/FHC-Header.php @@ -177,7 +177,7 @@ // Tinymce JS if ($tinymce === true) generateJSsInclude('vendor/tinymce/tinymce/tinymce.min.js'); - // Tinymce JS + // User Defined Fields if ($udfs === true) generateJSsInclude('public/js/UDFWidget.js'); // SB Admin 2 template JS diff --git a/application/widgets/udf/UDFWidget.php b/application/widgets/udf/UDFWidget.php index b3bf82470..7af3dd926 100644 --- a/application/widgets/udf/UDFWidget.php +++ b/application/widgets/udf/UDFWidget.php @@ -6,12 +6,12 @@ */ class UDFWidget extends HTMLWidget { - private $_requiredPermissions; // + private $_requiredPermissions; // The required permissions to use this UDF widget - private $_schema; - private $_table; - private $_primaryKeyName; - private $_primaryKeyValue; + private $_schema; // Schema name + private $_table; // Table name + private $_primaryKeyName; // Primary key name + private $_primaryKeyValue; // Primary key value /** * Initialize the UDFWidget and starts the execution of the logic @@ -22,7 +22,7 @@ class UDFWidget extends HTMLWidget $this->load->library('UDFLib'); // Loads the UDFLib that contains all the used logic - $this->udflib->setUDFUniqueIdByParams($args); + $this->udflib->setUDFUniqueIdByParams($args); // sets the unique id for this UDF $this->_initUDFWidget($args); // checks parameters and initialize properties From b270e65d2e147fab81d6d4a9fd3de2fcba00fccc Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 28 Jan 2020 12:26:08 +0100 Subject: [PATCH 003/265] Extended FHC_TableWidget with column picker, header & footer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added standard behaviour to FHC_TableWidget: . Added column picker to new TableWidgetHeader div. . Moved former footerElement (including Alle aus-/abwählen buttons, CSV Downloads) from single specific files to new TableWidgetFooter divs. . Adapted other files to work with new FHC_TableWidget behaviour --- .../lehrauftrag/acceptLehrauftragData.php | 61 ++--- .../lehrauftrag/approveLehrauftragData.php | 53 ++-- .../lehrauftrag/cancelledLehrauftragData.php | 23 +- .../lehre/lehrauftrag/orderLehrauftrag.php | 9 +- .../lehrauftrag/orderLehrauftragData.php | 80 +++--- application/views/widgets/table/table.php | 12 +- public/js/TableWidget.js | 229 +++++++++++++++++- .../js/lehre/lehrauftrag/acceptLehrauftrag.js | 72 ++---- .../lehre/lehrauftrag/approveLehrauftrag.js | 74 ++---- .../js/lehre/lehrauftrag/orderLehrauftrag.js | 73 ++---- 10 files changed, 417 insertions(+), 269 deletions(-) diff --git a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php index 27a348ae7..08cc94e5f 100644 --- a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php @@ -326,10 +326,12 @@ $filterWidgetArray = array( 'Angenommen von' ), 'datasetRepOptions' => '{ - height: 550, - layout: "fitColumns", // fit columns to width of table - responsiveLayout: "hide", // hide columns that dont fit on the table - movableColumns: true, // allows changing column + height: func_height(this), + layout: "fitColumns", // fit columns to width of table + persistentLayout:true, // enables persistence (default store in localStorage if available, else in cookie) + persistenceID: "acceptLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables + autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated + movableColumns: true, // allows changing column placeholder: func_placeholder(), headerFilterPlaceholder: " ", index: "row_index", // assign specific column as unique id (important for row indexing) @@ -339,7 +341,6 @@ $filterWidgetArray = array( selectableCheck: function(row){ return func_selectableCheck(row); }, - footerElement: func_footerElement(), rowUpdated:function(row){ func_rowUpdated(row); }, @@ -357,40 +358,44 @@ $filterWidgetArray = array( }, renderStarted:function(){ func_renderStarted(this); - } + }, + tableWidgetFooter: { + selectButtons: true + } }', // tabulator properties 'datasetRepFieldsDefs' => '{ row_index: {visible:false}, // necessary for row indexing - lehreinheit_id: {headerFilter:"input", bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();}, width: "7%"}, - lehrveranstaltung_id: {headerFilter:"input", width: "5%"}, - projektarbeit_id: {visible: false}, - studiensemester_kurzbz: {visible: false}, - studiengang_kz: {visible: false}, - stg_typ_kurzbz: {headerFilter:"input", width: "5%"}, + lehreinheit_id: {headerFilter:"input", bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();}}, + lehrveranstaltung_id: {headerFilter:"input"}, + projektarbeit_id: {visible: false, headerFilter:"input"}, + studiensemester_kurzbz: {visible: false, headerFilter:"input"}, + studiengang_kz: {visible: false, headerFilter:"input"}, + stg_typ_kurzbz: {headerFilter:"input"}, semester: {headerFilter:"input"}, orgform_kurzbz: {headerFilter:"input"}, - person_id: {visible: false}, - typ: {headerFilter:"input", width: "7%"}, - auftrag: {headerFilter:"input", width: "15%"}, - lv_oe_kurzbz: {headerFilter:"input", width: "8%"}, - gruppe: {headerFilter:"input", width: "5%"}, + person_id: {visible: false, headerFilter:"input"}, + typ: {headerFilter:"input"}, + auftrag: {headerFilter:"input"}, + lv_oe_kurzbz: {headerFilter:"input"}, + gruppe: {headerFilter:"input"}, stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, - bottomCalc:"sum", bottomCalcParams:{precision:1}, width: "5%"}, - betrag: {align:"right", width: "6%", formatter: form_formatNulltoStringNumber, + bottomCalc:"sum", bottomCalcParams:{precision:1} + }, + betrag: {align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, - bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"}, - width: "8%"}, + bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"} + }, vertrag_id: {visible: false}, vertrag_stunden: {visible: false}, vertrag_betrag: {visible: false}, - mitarbeiter_uid: {visible: false}, - bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip, width: "8%"}, - erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip, width: "8%"}, - akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip, width: "8%"}, - bestellt_von: {visible: false}, - erteilt_von: {visible: false}, - akzeptiert_von: {visible: false} + mitarbeiter_uid: {visible: false, headerFilter:"input"}, + bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip}, + erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip}, + akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip}, + bestellt_von: {visible: false, headerFilter:"input"}, + erteilt_von: {visible: false, headerFilter:"input"}, + akzeptiert_von: {visible: false, headerFilter:"input"} }', // col properties ); diff --git a/application/views/lehre/lehrauftrag/approveLehrauftragData.php b/application/views/lehre/lehrauftrag/approveLehrauftragData.php index fbc30db1c..111e7bd01 100644 --- a/application/views/lehre/lehrauftrag/approveLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/approveLehrauftragData.php @@ -337,14 +337,17 @@ $filterWidgetArray = array( 'Angenommen von' ), 'datasetRepOptions' => '{ - height: 700, - layout: "fitColumns", // fit columns to width of table - responsiveLayout: "hide", // hide columns that dont fit on the table - movableColumns: true, // allows changing column + height: func_height(this), + layout: "fitColumns", // fit columns to width of table + layoutColumnsOnNewData: true, // ajust column widths to the data each time TableWidget is loaded + persistentLayout:true, // enables persistence (default store in localStorage if available, else in cookie) + persistenceID: "approveLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables + autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated + movableColumns: true, // allows changing column placeholder: func_placeholder(), headerFilterPlaceholder: " ", groupBy:"lehrveranstaltung_id", - groupToggleElement:"header", //toggle group on click anywhere in the group header + groupToggleElement:"header", //toggle group on click anywhere in the group header groupHeader: function(value, count, data, group){ return func_groupHeader(data); }, @@ -357,7 +360,6 @@ $filterWidgetArray = array( return func_selectableCheck(row); }, initialFilter: func_initialFilter(), - footerElement: func_footerElement(), rowUpdated:function(row){ func_rowUpdated(row); }, @@ -373,44 +375,47 @@ $filterWidgetArray = array( }, tableBuilt: function(){ func_tableBuilt(this); - } + }, + tableWidgetFooter: { + selectButtons: true + } }', // tabulator properties 'datasetRepFieldsDefs' => '{ // column status is built dynamically in funcTableBuilt(), row_index: {visible:false}, // necessary for row indexing - personalnummer: {visible: false}, - lehreinheit_id: {headerFilter:"input", bottomCalc:"count", width: "7%", + personalnummer: {visible: false, headerFilter:"input"}, + lehreinheit_id: {headerFilter:"input", bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();},}, lehrveranstaltung_id: {headerFilter:"input"}, - lv_bezeichnung: {visible: false}, - projektarbeit_id: {visible: false}, + lv_bezeichnung: {visible: false, headerFilter:"input"}, + projektarbeit_id: {visible: false, headerFilter:"input"}, studiensemester_kurzbz: {headerFilter:"input"}, - studiengang_kz: {visible: false}, - stg_typ_kurzbz: {headerFilter:"input", width: "5%"}, + studiengang_kz: {visible: false, headerFilter:"input"}, + stg_typ_kurzbz: {headerFilter:"input"}, semester: {headerFilter:"input"}, orgform_kurzbz: {headerFilter:"input"}, - person_id: {visible: false}, + person_id: {visible: false, headerFilter:"input"}, typ: {headerFilter:"input"}, - auftrag: {headerFilter:"input", width:"20%"}, + auftrag: {headerFilter:"input"}, lv_oe_kurzbz: {headerFilter:"input"}, gruppe: {headerFilter:"input"}, - lektor: {headerFilter:"input", widthGrow: 3}, + lektor: {headerFilter:"input"}, stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:1}}, - betrag: {align:"right", width: "8%", formatter: form_formatNulltoStringNumber, + betrag: {align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"}}, vertrag_id: {visible: false}, vertrag_stunden: {visible: false}, vertrag_betrag: {visible: false}, - mitarbeiter_uid: {visible: false}, - bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip, width: "8%"}, - erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip, width: "8%"}, - akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip, width: "8%"}, - bestellt_von: {visible: false}, - erteilt_von: {visible: false}, - akzeptiert_von: {visible: false}, + mitarbeiter_uid: {visible: false, headerFilter:"input"}, + bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip}, + erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip}, + akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip}, + bestellt_von: {visible: false, headerFilter:"input"}, + erteilt_von: {visible: false, headerFilter:"input"}, + akzeptiert_von: {visible: false, headerFilter:"input"}, }', // col properties ); diff --git a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php index 04d314636..20629cb84 100644 --- a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php @@ -64,8 +64,11 @@ $tableWidgetArray = array( 'Storniert am' ), 'datasetRepOptions' => '{ - layout: "fitColumns", // fit columns to width of table - responsiveLayout: "hide", // hide columns that dont fit on the table + layout: "fitColumns", // fit columns to width of table + layoutColumnsOnNewData: true, // ajust column widths to the data each time TableWidget is loaded + persistentLayout: true, // enables persistence (default store in localStorage if available, else in cookie) + persistenceID: "cancelledLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables + autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated movableColumns: true, // allows changing column placeholder: func_placeholder(), rowFormatter:function(row){ @@ -79,22 +82,24 @@ $tableWidgetArray = array( }, tableBuilt: function(){ func_tableBuilt(this); - } + }, }', // tabulator properties 'datasetRepFieldsDefs' => '{ vertrag_id: {visible: false}, - vertragsstunden_studiensemester_kurzbz: {visible: false}, - vertragstyp_kurzbz: {widthGrow: 2}, - bezeichnung: {widthGrow: 2}, + vertragsstunden_studiensemester_kurzbz: {visible: false, widthShrink:1}, + vertragstyp_kurzbz: {minWidth: 300}, + bezeichnung: {minWidth: 400}, vertragsstunden: { align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, - bottomCalc:"sum", bottomCalcParams:{precision:1} + bottomCalc:"sum", bottomCalcParams:{precision:1}, + minWidth: 300 }, betrag: { align:"right", formatter: form_formatNulltoStringNumber, - bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"} + bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"}, + minWidth: 200 }, - storniert: {align:"center", mutator: mut_formatStringDate, tooltip: storniert_tooltip}, + storniert: {align:"center", mutator: mut_formatStringDate, tooltip: storniert_tooltip, minWidth: 200}, storniert_von: {visible: false}, letzterStatus_vorStorniert: {visible: false} }', // col properties diff --git a/application/views/lehre/lehrauftrag/orderLehrauftrag.php b/application/views/lehre/lehrauftrag/orderLehrauftrag.php index b04aa7985..27793e8ba 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftrag.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftrag.php @@ -35,7 +35,7 @@ $this->load->view(
-
-
- load->view('lehre/lehrauftrag/orderLehrauftragData.php'); ?> -
-
-
+ load->view('lehre/lehrauftrag/orderLehrauftragData.php'); ?>
diff --git a/application/views/lehre/lehrauftrag/orderLehrauftragData.php b/application/views/lehre/lehrauftrag/orderLehrauftragData.php index b2fa3ac2f..d78f5ecfe 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftragData.php @@ -371,20 +371,22 @@ $filterWidgetArray = array( 'Angenommen von' ), 'datasetRepOptions' => '{ - height: 700, - layout:"fitColumns", // fit columns to width of table - responsiveLayout:"hide", // hide columns that dont fit on the table - movableColumns: true, // allows changing column - placeholder: func_placeholder(), - headerFilterPlaceholder: " ", - groupBy:"lehrveranstaltung_id", - groupToggleElement:"header", //toggle group on click anywhere in the group header - groupHeader: function(value, count, data, group){ - return func_groupHeader(data); - }, - footerElement: func_footerElement(), - columnCalcs:"both", // show column calculations at top and bottom of table and in groups - index: "row_index", // assign specific column as unique id (important for row indexing) + height: func_height(this), + layout:"fitColumns", // fit columns to width of table + layoutColumnsOnNewData: true, // ajust column widths to the data each time TableWidget is loaded + persistentLayout:true, // enables persistence (default store in localStorage if available, else in cookie) + persistenceID: "orderLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables + autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated + movableColumns: true, // allows changing column order + placeholder: func_placeholder(), // shown on empty table (no data) + headerFilterPlaceholder: " ", + groupBy:"lehrveranstaltung_id", + groupToggleElement:"header", //toggle group on click anywhere in the group header + groupHeader: function(value, count, data, group){ + return func_groupHeader(data); + }, + columnCalcs:"both", // show column calculations at top and bottom of table and in groups + index: "row_index", // assign specific column as unique id (important for row indexing) selectable: true, // allows row selection selectableRangeMode: "click", // allows range selection using shift end click on end of range selectablePersistence:false, // deselect previously selected rows when table is filtered, sorted or paginated @@ -409,46 +411,50 @@ $filterWidgetArray = array( dataLoaded: function(data){ func_dataLoaded(data, this); }, + tableWidgetFooter: { + selectButtons: true + } }', // tabulator properties 'datasetRepFieldsDefs' => '{ // column status is built dynamically in funcTableBuilt() row_index: {visible: false}, - personalnummer: {visible: false}, - lehreinheit_id: {headerFilter:"input", bottomCalc:"count", width: "7%", + personalnummer: {visible: false, headerFilter:"input"}, + lehreinheit_id: {headerFilter:"input", bottomCalc:"count", minWidth: 115, bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();}}, lehrveranstaltung_id: {headerFilter:"input"}, - lv_bezeichnung: {visible: false}, - projektarbeit_id: {visible: false}, + lv_bezeichnung: {visible: false, headerFilter:"input"}, + projektarbeit_id: {visible: false, headerFilter:"input"}, studiensemester_kurzbz: {headerFilter:"input"}, - studiengang_kz: {visible: false}, - stg_typ_kurzbz: {headerFilter:"input", width: "5%"}, + studiengang_kz: {visible: false, headerFilter:"input"}, + stg_typ_kurzbz: {headerFilter:"input", minWidth: 70}, semester: {headerFilter:"input"}, - studienplan_bezeichnung: {headerFilter:"input", width: "7%"}, + studienplan_bezeichnung: {headerFilter:"input"}, orgform_kurzbz: {headerFilter:"input"}, - person_id: {visible: false}, - typ: {headerFilter:"input"}, - auftrag: {headerFilter:"input", width:"15%"}, - lv_oe_kurzbz: {headerFilter:"input"}, - gruppe: {headerFilter:"input"}, + person_id: {visible: false, headerFilter:"input"}, + typ: {headerFilter:"input", minWidth:100}, + auftrag: {headerFilter:"input", minWidth:280}, + lv_oe_kurzbz: {headerFilter:"input", minWidth:80}, + gruppe: {headerFilter:"input", minWidth:120}, lektor: {headerFilter:"input", widthGrow: 3}, - stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, + stunden: {align:"right", minWidth: 80, formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:1}}, - stundensatz: {visible: false}, - betrag: {align:"right", width: "8%", formatter: form_formatNulltoStringNumber, + stundensatz: {visible: false, align:"right", minWidth: 100, formatter: form_formatNulltoStringNumber, + headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator}, + betrag: {align:"right", minWidth: 120, formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"}}, - vertrag_id: {visible: false}, + vertrag_id: {visible: false, headerFilter:"input"}, vertrag_stunden: {visible: false}, vertrag_betrag: {visible: false}, - mitarbeiter_uid: {visible: false}, - bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip, width: "8%"}, - erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip, width: "8%"}, - akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip, width: "8%"}, - bestellt_von: {visible: false}, - erteilt_von: {visible: false}, - akzeptiert_von: {visible: false} + mitarbeiter_uid: {visible: false, headerFilter:"input"}, + bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip, minWidth: 100}, + erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip, minWidth: 100}, + akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip, minWidth: 100}, + bestellt_von: {visible: false, headerFilter:"input"}, + erteilt_von: {visible: false, headerFilter:"input"}, + akzeptiert_von: {visible: false, headerFilter:"input"} }', // col properties ); diff --git a/application/views/widgets/table/table.php b/application/views/widgets/table/table.php index e73aec335..936c32dc8 100644 --- a/application/views/widgets/table/table.php +++ b/application/views/widgets/table/table.php @@ -1,17 +1,21 @@ - +
+ +
+
-
- -
+
+ +
+
diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 89e7cf3d5..575ad6b12 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -182,11 +182,90 @@ var FHC_TableWidget = { */ _turnOnEvents: function(tableWidgetDiv) { + var tableUniqueId = tableWidgetDiv.attr('tableUniqueId'); + // If the choosen dataset representation is tablesorter if (FHC_TableWidget._datasetRepresentation == DATASET_REP_TABLESORTER) { FHC_TableWidget._enableTableSorter(tableWidgetDiv); // enable the tablesorter } + + // If the choosen dataset representation is tabulator + if (FHC_TableWidget._datasetRepresentation == DATASET_REP_TABULATOR) + { + // --------------------------------------------------------------------------------------------------------- + // Add events to the elements + // --------------------------------------------------------------------------------------------------------- + + // Click-Event to download csv + tableWidgetDiv.find('#download-csv').on('click', function() + { + // BOM for correct UTF-8 char output + tableWidgetDiv.find("#tableWidgetTabulator").tabulator("download", "csv", "data.csv", {bom:true}); + }) + + // Click-Event to collapse settings div + tableWidgetDiv.find('#settings').on('click', function() + { + + //... auch unteren event für settings hier hinein + $('#tabulatorSettings-' + tableUniqueId).collapse('toggle'); + + $(this).toggleClass('active focus'); + + // De/activate and un/focus on clicked settings button + if(!$(this).hasClass('active focus')) + { + $(this).css({'background-color': 'white', 'border-color' : '#ccc', 'outline': 'none'}); + } + else + { + $(this).css({'background-color': '#e6e6e6'}); + } + }) + + /** + * Click-Event to select all rows + * Default is ALL rows. This can be modified via hook tableWidgetHook_selectAllButton. + */ + if (typeof tableWidgetHook_selectAllButton == 'function') + { + tableWidgetDiv.find('#select-all').on('click', function() { + tableWidgetHook_selectAllButton(tableWidgetDiv); + }); + } + else + { + tableWidgetDiv.find('#select-all').on('click', function() { + tableWidgetDiv.find("#tableWidgetTabulator").tabulator('selectRow', true); + }); + } + + // Click-Event to deselect all rows + tableWidgetDiv.find('#deselect-all').on('click', function() + { + tableWidgetDiv.find("#tableWidgetTabulator").tabulator('deselectRow'); + }) + + // Click-Event to toggle column-picker columns + tableWidgetDiv.find('.btn-select-col').on('click', function() + { + var selected = this.value; + + tableWidgetDiv.find("#tableWidgetTabulator").tabulator('toggleColumn', selected); + + $(this).toggleClass('active'); + + if(!$(this).hasClass('active')) + { + $(this).css('background-color', 'white'); + } + else + { + $(this).css('background-color', '#e6e6e6'); + } + }) + } }, _renderDataset: function(tableWidgetDiv, data) { @@ -443,11 +522,43 @@ var FHC_TableWidget = { options.columns = arrayTabulatorColumns; options.data = data.dataset; - + options.rowSelectionChanged = function(data, rows){ + _func_rowSelectionChanged(data, rows); + }; + options.columnVisibilityChanged = function(column, visible) { + _func_columnVisibilityChanged(column, visible); + }; + // Renders the tabulator tableWidgetDiv.find("#tableWidgetTabulator").tabulator(options); } } + + // ------------------------------------------------------------------------------------------------------------- + // Render TableWidget Header and -Footer + // ------------------------------------------------------------------------------------------------------------- + + // Render tableWidgetHeader + var tabulatorHeaderHTML = _renderTabulatorHeaderHTML(tableWidgetDiv); + tableWidgetDiv.find('#tableWidgetHeader').append(tabulatorHeaderHTML); + + // Render the collapsable div triggered by button in tableWidgetHeader + var tabulatorHeaderCollapseHTML = _renderTabulatorHeaderCollapseHTML(tableWidgetDiv); + tableWidgetDiv.find('#tableWidgetHeader').after(tabulatorHeaderCollapseHTML); + + /** + * tableWidgetFooter is NOT rendered by default. + * tableWidgetFooter is rendered, if tableWidgetFooter is set in tabulators datasetRepOptions. + * Setup options like this: + * tableWidgetFooter: { + * selectButtons: true // tableWidgetFooter properties are checked in _renderTabulatorFooterHTML function + * } + */ + if (options.tableWidgetFooter != 'undefined' && options.tableWidgetFooter != null) + { + var tabulatorFooterHTML = _renderTabulatorFooterHTML(options.tableWidgetFooter); + tableWidgetDiv.find('#tableWidgetFooter').append(tabulatorFooterHTML); + } }, /** @@ -584,6 +695,122 @@ var FHC_TableWidget = { } }; +//********************************************************************************************************************** +// Render functions +//********************************************************************************************************************** +/* + * Processed when row selection changed. + * Displays number of selected rows on row selection change. + */ +function _func_rowSelectionChanged (data, rows){ + + $('#number-selected').html("Ausgewählte Zeilen: " + rows.length + ""); +} + +/* Processed when columns visibility changed (e.g. using the column picker). + * Redraws the table to expand columns to table width. + */ +function _func_columnVisibilityChanged(column, visible){ + + var table = column.getTable(); + + table.redraw(); +} + +// Returns TableWidget Header HTML (download-, setting button...) +function _renderTabulatorHeaderHTML(tableWidgetDiv){ + + var tableUniqueId = tableWidgetDiv.attr('tableUniqueId'); + + var tabulatorHeaderHTML = ''; + tabulatorHeaderHTML += ''; + + return tabulatorHeaderHTML; +} + +// Returns collapsable HTML element for TableWidget header buttons +function _renderTabulatorHeaderCollapseHTML(tableWidgetDiv){ + + var tableUniqueId = tableWidgetDiv.attr('tableUniqueId'); + + var tabulatorHeaderCollapseHTML = ''; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += ''; // end panel-heading + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + + // Create column picker (Spalten einstellen) + tableWidgetDiv.find('#tableWidgetTabulator').tabulator('getColumns').forEach(function(column) + { + var field = column.getField(); + var title = column.getDefinition().title; + var active_status = column.getVisibility() ? 'active' : ''; + + // If certain columns should be excluded from the column picker (define them in a blacklist array) + if (typeof tableWidgetBlacklistArray_columnUnselectable != 'undefined' && + Array.isArray(tableWidgetBlacklistArray_columnUnselectable) && + tableWidgetBlacklistArray_columnUnselectable.length) + { + if ($.inArray(field, tableWidgetBlacklistArray_columnUnselectable) < 0) + { + tabulatorHeaderCollapseHTML += ''; + } + } + // Else provide all tabulator fields as pickable columns + else + { + tabulatorHeaderCollapseHTML += ''; + } + }); + + tabulatorHeaderCollapseHTML += '
'; // end btn-group + tabulatorHeaderCollapseHTML += '
'; // end panel-body + tabulatorHeaderCollapseHTML += '
'; // end panel-collapse + tabulatorHeaderCollapseHTML += '
'; // end panel + + tabulatorHeaderCollapseHTML += '
'; // end panel-group + tabulatorHeaderCollapseHTML += '
'; // end col + tabulatorHeaderCollapseHTML += '
'; // end row + + return tabulatorHeaderCollapseHTML; +} + +// Returns TableWidget Footer HTML (de-/select buttons,...) +function _renderTabulatorFooterHTML(tableWidgetFooterOptions){ + + var tabulatorFooterHTML = ''; + + // If property selectButtons is true, render 'Alle auswaehlen / Alle abwaehlen' buttons + if (tableWidgetFooterOptions.selectButtons != 'undefined' && tableWidgetFooterOptions.selectButtons == true) + { + tabulatorFooterHTML += ''; + tabulatorFooterHTML += '

'; + } + + return tabulatorFooterHTML; +} + /** * When JQuery is up */ diff --git a/public/js/lehre/lehrauftrag/acceptLehrauftrag.js b/public/js/lehre/lehrauftrag/acceptLehrauftrag.js index 03c72e2f2..31ade57fa 100644 --- a/public/js/lehre/lehrauftrag/acceptLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/acceptLehrauftrag.js @@ -19,6 +19,18 @@ const ICON_LEHRAUFTRAG_APPROVED = ''; const ICON_LEHRAUFTRAG_CANCELLED = ''; +// Fields that should not be provided in the column picker +var tableWidgetBlacklistArray_columnUnselectable = [ + 'status', + 'row_index', + 'betrag', + 'vertrag_id', + 'vertrag_stunden', + 'vertrag_betrag', + 'storniert_von', // fields from cancelledLehrauftragData + 'letzterStatus_vorStorniert' // fields from cancelledLehrauftragData +]; + // ----------------------------------------------------------------------------------------------------------------- // Mutators - setter methods to manipulate table data when entering the tabulator // ----------------------------------------------------------------------------------------------------------------- @@ -254,66 +266,22 @@ function func_renderComplete(table){ ); } -// Tabulator footer element +// TableWidget Footer element // ----------------------------------------------------------------------------------------------------------------- -// Adds a footer with buttons select all / deselect all / download -function func_footerElement(){ - - var footer_html = '
'; - footer_html += '
'; - - footer_html += ''; - - footer_html += ''; - - footer_html += '
'; - footer_html += '
'; - - return footer_html; -} - -// Performs download CSV -function footer_downloadCSV(){ - $('#tableWidgetTabulator').tabulator("download", "csv", "data.csv", {bom:true}); // BOM for correct UTF-8 char output -} - /* - * Performs select all + * Hook to overwrite TableWigdgets select-all-button behaviour * Select all (filtered) rows and ignore rows that are bestellt and erteilt */ -function footer_selectAll(){ - $('#tableWidgetTabulator').tabulator('getRows', true) - .filter(row => row.getData().bestellt != null && // bestellt - row.getData().erteilt != null && // AND erteilt - row.getData().akzeptiert == null && // AND NOT akzeptiert - row.getData().status != 'Geändert') // AND NOT geändert +function tableWidgetHook_selectAllButton(tableWidgetDiv){ + tableWidgetDiv.find("#tableWidgetTabulator").tabulator('getRows', true) + .filter(row => row.getData().bestellt != null && // bestellt + row.getData().erteilt != null && // AND erteilt + row.getData().akzeptiert == null && // AND NOT akzeptiert + row.getData().status != 'Geändert') // AND NOT geändert .forEach((row => row.select())); } -/* - * Performs deselect all - * Deselect all (filtered) rows - */ -function footer_deselectAll(){ - $('#tableWidgetTabulator').tabulator('deselectRow'); -} - -// Displays number of selected rows on row selection change -function func_rowSelectionChanged(data, rows){ - $('#number-selected').html("Für Annehmen ausgewählt: " + rows.length + ""); -} - // ----------------------------------------------------------------------------------------------------------------- // Tabulator columns format functions // ----------------------------------------------------------------------------------------------------------------- diff --git a/public/js/lehre/lehrauftrag/approveLehrauftrag.js b/public/js/lehre/lehrauftrag/approveLehrauftrag.js index 94e6af473..f38d251c0 100644 --- a/public/js/lehre/lehrauftrag/approveLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/approveLehrauftrag.js @@ -19,6 +19,17 @@ const ICON_LEHRAUFTRAG_ORDERED = ''; const ICON_LEHRAUFTRAG_CHANGED = ''; +// Fields that should not be provided in the column picker +var tableWidgetBlacklistArray_columnUnselectable = [ + 'status', + 'row_index', + 'personalnummer', + 'betrag', + 'vertrag_id', + 'vertrag_stunden', + 'vertrag_betrag' +]; + // ----------------------------------------------------------------------------------------------------------------- // Mutators - setter methods to manipulate table data when entering the tabulator // ----------------------------------------------------------------------------------------------------------------- @@ -301,65 +312,20 @@ function func_rowUpdated(row){ row.getElement().style["pointerEvents"] = "none"; } - -// Tabulator footer element +// TableWidget Footer element // ----------------------------------------------------------------------------------------------------------------- -// Adds a footer with buttons select all / deselect all / download -function func_footerElement(){ - - var footer_html = '
'; - footer_html += '
'; - - footer_html += ''; - - footer_html += ''; - - footer_html += '
'; - footer_html += '
'; - - return footer_html; -} - -// Performs download CSV -function footer_downloadCSV(){ - $('#tableWidgetTabulator').tabulator("download", "csv", "data.csv", {bom:true}); // BOM for correct UTF-8 char output -} - /* - * Performs select all + * Hook to overwrite TableWigdgets select-all-button behaviour * Select all (filtered) rows that are bestellt */ -function footer_selectAll(){ - $('#tableWidgetTabulator').tabulator('getRows', true) - .filter(row => row.getData().personalnummer >= 0 && // NOT dummies - row.getData().bestellt != null && // AND bestellt - row.getData().erteilt == null && // AND NOT erteilt - row.getData().status != 'Geändert') // AND NOT geaendert - .forEach((row => row.select())); -} - -/* - * Performs deselect all - * Deselect all (filtered) rows - */ -function footer_deselectAll(){ - $('#tableWidgetTabulator').tabulator('deselectRow'); -} - -// Displays number of selected rows on row selection change -function func_rowSelectionChanged(data, rows){ - $('#number-selected').html("Für Erteilung ausgewählt: " + rows.length + ""); +function tableWidgetHook_selectAllButton(tableWidgetDiv){ + tableWidgetDiv.find("#tableWidgetTabulator").tabulator('getRows', true) + .filter(row => row.getData().personalnummer >= 0 && // NOT dummies + row.getData().bestellt != null && // AND bestellt + row.getData().erteilt == null && // AND NOT erteilt + row.getData().status != 'Geändert') // AND NOT geaendert + .forEach((row => row.select())); } // ----------------------------------------------------------------------------------------------------------------- diff --git a/public/js/lehre/lehrauftrag/orderLehrauftrag.js b/public/js/lehre/lehrauftrag/orderLehrauftrag.js index 4e58272e5..a9a59efbb 100644 --- a/public/js/lehre/lehrauftrag/orderLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/orderLehrauftrag.js @@ -18,6 +18,17 @@ const ICON_LEHRAUFTRAG_ORDERED = ''; const ICON_LEHRAUFTRAG_CHANGED = ''; +// Fields that should not be provided in the column picker +var tableWidgetBlacklistArray_columnUnselectable = [ + 'status', + 'row_index', + 'personalnummer', + 'betrag', + 'vertrag_id', + 'vertrag_stunden', + 'vertrag_betrag' +]; + // ----------------------------------------------------------------------------------------------------------------- // Mutators - setter methods to manipulate table data when entering the tabulator // ----------------------------------------------------------------------------------------------------------------- @@ -309,64 +320,20 @@ function func_rowUpdated(row){ row.getElement().style["pointerEvents"] = "none"; } -// Tabulator footer element +// TableWidget Footer element // ----------------------------------------------------------------------------------------------------------------- -// Adds a footer with buttons select all / deselect all / download -function func_footerElement(){ - - var footer_html = '
'; - footer_html += '
'; - - footer_html += ''; - - footer_html += ''; - - footer_html += '
'; - footer_html += '
'; - - return footer_html; -} - -// Performs download CSV -function footer_downloadCSV(){ - $('#tableWidgetTabulator').tabulator("download", "csv", "data.csv", {bom:true}); // BOM for correct UTF-8 char output -} - /* - * Performs select all + * Hook to overwrite TableWigdgets select-all-button behaviour * Select all (filtered) rows and ignore rows which have status bestellt */ -function footer_selectAll(){ - $('#tableWidgetTabulator').tabulator('getRows', true) - .filter(row => row.getData().personalnummer >= 0 && // NOT dummies - row.getData().bestellt == null || // AND neu - row.getData().bestellt != null && // OR (bestellt - row.getData().status == 'Geändert') // AND geaendert) - .forEach((row => row.select())); -} - -/* - * Performs deselect all - * Deselect all (filtered) rows - */ -function footer_deselectAll(){ - $('#tableWidgetTabulator').tabulator('deselectRow'); -} - -// Displays number of selected rows on row selection change -function func_rowSelectionChanged(data, rows){ - $('#number-selected').html("Für Bestellung ausgewählt: " + rows.length + ""); +function tableWidgetHook_selectAllButton(tableWidgetDiv){ + tableWidgetDiv.find("#tableWidgetTabulator").tabulator('getRows', true) + .filter(row => row.getData().personalnummer >= 0 && // NOT dummies + row.getData().bestellt == null || // AND neu + row.getData().bestellt != null && // OR (bestellt + row.getData().status == 'Geändert') // AND geaendert) + .forEach((row => row.select())); } // ----------------------------------------------------------------------------------------------------------------- From 198a3eb2d541cd80512ce88060790289fb51516e Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 28 Jan 2020 12:29:18 +0100 Subject: [PATCH 004/265] Adjusted tabulator size to window screen size --- public/js/lehre/lehrauftrag/acceptLehrauftrag.js | 12 ++++++++++++ public/js/lehre/lehrauftrag/approveLehrauftrag.js | 11 +++++++++++ public/js/lehre/lehrauftrag/orderLehrauftrag.js | 11 +++++++++++ 3 files changed, 34 insertions(+) diff --git a/public/js/lehre/lehrauftrag/acceptLehrauftrag.js b/public/js/lehre/lehrauftrag/acceptLehrauftrag.js index 31ade57fa..c3d89ac52 100644 --- a/public/js/lehre/lehrauftrag/acceptLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/acceptLehrauftrag.js @@ -93,6 +93,11 @@ function hf_filterStringnumberWithOperator(headerValue, rowValue, rowData){ // Tabulator table format functions // ----------------------------------------------------------------------------------------------------------------- +// Returns relative height (depending on screen size) +function func_height(table){ + return $(window).height() * 0.50; +} + // Displays text when table is empty function func_placeholder() { @@ -432,6 +437,13 @@ storniert_tooltip = function(cell){ } $(function() { + + // Redraw table on resize to fit tabulators height to windows height + window.addEventListener('resize', function(){ + $('#tableWidgetTabulator').tabulator('setHeight', $(window).height() * 0.50); + $('#tableWidgetTabulator').tabulator('redraw', true); + }); + // Show all rows $("#show-all").click(function(){ $('#tableWidgetTabulator').tabulator('clearFilter'); diff --git a/public/js/lehre/lehrauftrag/approveLehrauftrag.js b/public/js/lehre/lehrauftrag/approveLehrauftrag.js index f38d251c0..29e2d9651 100644 --- a/public/js/lehre/lehrauftrag/approveLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/approveLehrauftrag.js @@ -106,6 +106,11 @@ function func_initialFilter(){ // Tabulator table format functions // ----------------------------------------------------------------------------------------------------------------- +// Returns relative height (depending on screen size) +function func_height(table){ + return $(window).height() * 0.50; +} + // Displays text when table is empty function func_placeholder() { @@ -492,6 +497,12 @@ akzeptiert_tooltip = function(cell){ } $(function() { + // Redraw table on resize to fit tabulators height to windows height + window.addEventListener('resize', function(){ + $('#tableWidgetTabulator').tabulator('setHeight', $(window).height() * 0.50); + $('#tableWidgetTabulator').tabulator('redraw', true); + }); + // Show all rows $("#show-all").click(function(){ $('#tableWidgetTabulator').tabulator('clearFilter'); diff --git a/public/js/lehre/lehrauftrag/orderLehrauftrag.js b/public/js/lehre/lehrauftrag/orderLehrauftrag.js index a9a59efbb..6471d988f 100644 --- a/public/js/lehre/lehrauftrag/orderLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/orderLehrauftrag.js @@ -111,6 +111,11 @@ function func_dataLoaded(data, table){ // Tabulator table format functions // ----------------------------------------------------------------------------------------------------------------- +// Returns relative height (depending on screen size) +function func_height(table){ + return $(window).height() * 0.50; +} + // Displays text when table is empty function func_placeholder() { @@ -509,6 +514,12 @@ akzeptiert_tooltip = function(cell){ $(function() { + // Redraw table on resize to fit tabulators height to windows height + window.addEventListener('resize', function(){ + $('#tableWidgetTabulator').tabulator('setHeight', $(window).height() * 0.50); + $('#tableWidgetTabulator').tabulator('redraw', true); + }); + // Show all rows $("#show-all").click(function(){ $('#tableWidgetTabulator').tabulator('clearFilter'); From f22931ffa8939449e4a0d77d050957c18faadb2e Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 28 Jan 2020 12:33:23 +0100 Subject: [PATCH 005/265] Adapted row color when hovering on selected rows Before row color was changing from selected-blue to grey, although row was still selected, which was somehow confusing for the user. Now color stays blue. --- public/css/Tabulator.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/css/Tabulator.css b/public/css/Tabulator.css index 359f29e72..eac315f93 100644 --- a/public/css/Tabulator.css +++ b/public/css/Tabulator.css @@ -12,3 +12,8 @@ .tabulator-page.active { color: #337ab7 !important; } + +/* Avoid confusing color change when hovering over selected rows */ +.tabulator-row.tabulator-selected:hover { + background-color: #769bcc !important; +} \ No newline at end of file From 2e30841b0daa98a1b8d179833f5116c00e81dc15 Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 28 Jan 2020 17:21:47 +0100 Subject: [PATCH 006/265] - added UDF prestudent dropdown to infocenterDetails - crm/Prestudent_model: improved code, e.g. replaced ->retval --- .../system/infocenter/InfoCenter.php | 24 +++++--- application/models/crm/Prestudent_model.php | 56 +++++++++++++------ .../models/organisation/Studienjahr_model.php | 2 +- .../system/infocenter/infocenterDetails.php | 1 + .../views/system/infocenter/zgvpruefungen.php | 48 ++++++++++------ public/js/infocenter/infocenterDetails.js | 36 +++++++----- 6 files changed, 108 insertions(+), 59 deletions(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index d085e7db0..3f65ed605 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -1271,7 +1271,7 @@ class InfoCenter extends Auth_Controller show_error(getError($prestudentWithZgv)); } - $zgvpruefung = $prestudentWithZgv->retval[0]; + $zgvpruefung = getData($prestudentWithZgv); if (isset($zgvpruefung->prestudentstatus)) { @@ -1296,11 +1296,15 @@ class InfoCenter extends Auth_Controller $zgvpruefung->isRtFreigegeben = false; $zgvpruefung->isStgFreigegeben = false; $zgvpruefung->sendStgFreigabeMsg = true;//wether Stgudiengangfreigabemessage can be sent (for "exceptions", Studiengänge with no message sending) - $this->PrestudentstatusModel->addSelect('bestaetigtam, statusgrund_id, tbl_status_grund.bezeichnung_mehrsprachig AS bezeichnung_statusgrund'); - $this->PrestudentstatusModel->addJoin('public.tbl_status_grund', 'statusgrund_id', 'LEFT'); - $isFreigegeben = $this->PrestudentstatusModel->loadWhere(array('studiensemester_kurzbz' => $zgvpruefung->prestudentstatus->studiensemester_kurzbz, - 'tbl_prestudentstatus.status_kurzbz' => self::INTERESSENTSTATUS, 'prestudent_id' => $prestudent->prestudent_id)); + $isFreigegeben = null; + if (isset($zgvpruefung->prestudentstatus->studiensemester_kurzbz)) + { + $this->PrestudentstatusModel->addSelect('bestaetigtam, statusgrund_id, tbl_status_grund.bezeichnung_mehrsprachig AS bezeichnung_statusgrund'); + $this->PrestudentstatusModel->addJoin('public.tbl_status_grund', 'statusgrund_id', 'LEFT'); + $isFreigegeben = $this->PrestudentstatusModel->loadWhere(array('studiensemester_kurzbz' => $zgvpruefung->prestudentstatus->studiensemester_kurzbz, + 'tbl_prestudentstatus.status_kurzbz' => self::INTERESSENTSTATUS, 'prestudent_id' => $prestudent->prestudent_id)); + } if (hasData($isFreigegeben)) { @@ -1457,9 +1461,10 @@ class InfoCenter extends Auth_Controller show_error(getError($prestudent)); } - $person_id = $prestudent->retval[0]->person_id; - $studiengang_kurzbz = $prestudent->retval[0]->studiengang; - $studiengang_bezeichnung = $prestudent->retval[0]->studiengangbezeichnung; + $prestudentdata = getData($prestudent); + $person_id = $prestudentdata->person_id; + $studiengang_kurzbz = $prestudentdata->studiengang; + $studiengang_bezeichnung = $prestudentdata->studiengangbezeichnung; return array('person_id' => $person_id, 'studiengang_kurzbz' => $studiengang_kurzbz, 'studiengang_bezeichnung' => $studiengang_bezeichnung); } @@ -1502,7 +1507,8 @@ class InfoCenter extends Auth_Controller private function _sendFreigabeMail($prestudent_id) { //get data - $prestudent = $this->PrestudentModel->getPrestudentWithZgv($prestudent_id)->retval[0]; + $prestudent = $this->PrestudentModel->getPrestudentWithZgv($prestudent_id); + $prestudent = getData($prestudent); $prestudentstatus = $prestudent->prestudentstatus; $person_id = $prestudent->person_id; $person = $this->PersonModel->getPersonStammdaten($person_id, true)->retval; diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index d5c52a3c3..250b68099 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -209,6 +209,9 @@ class Prestudent_model extends DB_Model if (!hasData($prestudent)) return error('prestudent could not be loaded'); + $prestudentdata = getData($prestudent); + $prestudentdata = $prestudentdata[0]; + //Prestudentstatus $lastStatus = $this->PrestudentstatusModel->getLastStatus($prestudent_id); @@ -217,32 +220,41 @@ class Prestudent_model extends DB_Model return $lastStatus; } - if (count($lastStatus->retval) > 0) + if (hasData($lastStatus)) { + $lastStatusData = getData($lastStatus); + $lastStatusData = $lastStatusData[0]; //get Studiengangname from Studienplan and -ordnung $studienordnung = $this->PrestudentstatusModel->getStudienordnungFromPrestudent($prestudent_id); if ($studienordnung->error) return $studienordnung; - if (count($studienordnung->retval) > 0) + if (hasData($studienordnung)) { - $lastStatus->retval[0]->studiengang_kz = $studienordnung->retval[0]->studiengang_kz; - $lastStatus->retval[0]->studiengangkurzbzlang = $studienordnung->retval[0]->studiengangkurzbzlang; - $lastStatus->retval[0]->studiengangbezeichnung = $studienordnung->retval[0]->studiengangbezeichnung; - $lastStatus->retval[0]->studiengangbezeichnung_englisch = $studienordnung->retval[0]->studiengangbezeichnung_englisch; - $lastStatus->retval[0]->regelstudiendauer = $studienordnung->retval[0]->regelstudiendauer; + $studienordnungdata = getData($studienordnung); + $studienordnungdata = $studienordnungdata[0]; + + $lastStatusData->studiengang_kz = $studienordnungdata->studiengang_kz; + $lastStatusData->studiengangkurzbzlang = $studienordnungdata->studiengangkurzbzlang; + $lastStatusData->studiengangbezeichnung = $studienordnungdata->studiengangbezeichnung; + $lastStatusData->studiengangbezeichnung_englisch = $studienordnungdata->studiengangbezeichnung_englisch; + $lastStatusData->regelstudiendauer = $studienordnungdata->regelstudiendauer; } //get Sprache $this->load->model('system/sprache_model', 'SpracheModel'); $this->SpracheModel->addSelect('sprache, locale, bezeichnung'); - $language = $this->SpracheModel->load($lastStatus->retval[0]->sprache); + $language = $this->SpracheModel->load($lastStatusData->sprache); if ($language->error) return $language; - if (count($language->retval) > 0) - $lastStatus->retval[0]->sprachedetails = $language->retval[0]; + if (hasData($language)) + { + $languagedata = getData($language); + $languagedata = $languagedata[0]; + $lastStatusData->sprachedetails = $languagedata; + } //get Bewerbungsfrist $this->load->model('crm/bewerbungstermine_model', 'BewerbungstermineModel'); @@ -251,24 +263,32 @@ class Prestudent_model extends DB_Model $this->BewerbungstermineModel->addLimit(1); $bewerbungstermin = $this->BewerbungstermineModel->loadWhere( array( - 'studienplan_id' => $lastStatus->retval[0]->studienplan_id, - 'studiensemester_kurzbz' => $lastStatus->retval[0]->studiensemester_kurzbz, - 'studiengang_kz' => $prestudent->retval[0]->studiengang_kz + 'studienplan_id' => $lastStatusData->studienplan_id, + 'studiensemester_kurzbz' => $lastStatusData->studiensemester_kurzbz, + 'studiengang_kz' => $prestudentdata->studiengang_kz ) ); if ($bewerbungstermin->error) return $bewerbungstermin; - if (count($bewerbungstermin->retval) > 0) + if (hasData($bewerbungstermin)) { - $lastStatus->retval[0]->bewerbungstermin = $bewerbungstermin->retval[0]->ende; - $lastStatus->retval[0]->bewerbungsnachfrist = $bewerbungstermin->retval[0]->nachfrist_ende; + $bewerbungstermindata = getData($bewerbungstermin); + $bewerbungstermindata = $bewerbungstermindata[0]; + $lastStatusData->bewerbungstermin = $bewerbungstermindata->ende; + $lastStatusData->bewerbungsnachfrist = $bewerbungstermindata->nachfrist_ende; } - $prestudent->retval[0]->prestudentstatus = $lastStatus->retval[0]; + $prestudentdata->prestudentstatus = $lastStatusData; + + + if ($this->hasUDF()) + { + $prestudentdata->prestudentUdfs = $this->getUDFs($prestudent_id); + } } - return success($prestudent->retval); + return success($prestudentdata); } /** diff --git a/application/models/organisation/Studienjahr_model.php b/application/models/organisation/Studienjahr_model.php index 36784a280..3bbe3a07f 100644 --- a/application/models/organisation/Studienjahr_model.php +++ b/application/models/organisation/Studienjahr_model.php @@ -14,7 +14,7 @@ class Studienjahr_model extends DB_Model } /** - * Gets current Studienjahr, as determined by its start and enddate + * Gets current Studienjahr, as determined by start and enddate of current semester * @return array|null */ public function getCurrStudienjahr() diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index ab4e3533e..326c38035 100644 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -14,6 +14,7 @@ 'sbadmintemplate' => true, 'addons' => true, 'navigationwidget' => true, + 'udfs' => true, 'customCSSs' => array( 'public/css/sbadmin2/admintemplate.css', 'public/css/sbadmin2/tablesort_bootstrap.css', diff --git a/application/views/system/infocenter/zgvpruefungen.php b/application/views/system/infocenter/zgvpruefungen.php index 86344d06b..5accd22a4 100644 --- a/application/views/system/infocenter/zgvpruefungen.php +++ b/application/views/system/infocenter/zgvpruefungen.php @@ -118,8 +118,7 @@
-
+
@@ -302,21 +301,38 @@
- -
-
- -
-
- -
-
- + +
+
+ +
+
+ +
+
+ +
+ prestudentUdfs)) + { + echo $this->udflib->UDFWidget( + array( + UDFLib::UDF_UNIQUE_ID => 'infocenterPrestudentUDFs_'.$zgvpruefung->prestudent_id, + UDFLib::REQUIRED_PERMISSIONS_PARAMETER => 'infocenter', + UDFLib::SCHEMA_ARG_NAME => 'public', + UDFLib::TABLE_ARG_NAME => 'tbl_prestudent', + UDFLib::PRIMARY_KEY_NAME => 'prestudent_id', + UDFLib::PRIMARY_KEY_VALUE => $zgvpruefung->prestudent_id, + UDFLib::UDFS_ARG_NAME => $zgvpruefung->prestudentUdfs + ) + ); + } + ?>
Date: Wed, 29 Jan 2020 12:09:10 +0100 Subject: [PATCH 007/265] Added border to tabulator / tabulator header cells --- public/css/Tabulator.css | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/public/css/Tabulator.css b/public/css/Tabulator.css index eac315f93..ffbeed606 100644 --- a/public/css/Tabulator.css +++ b/public/css/Tabulator.css @@ -16,4 +16,18 @@ /* Avoid confusing color change when hovering over selected rows */ .tabulator-row.tabulator-selected:hover { background-color: #769bcc !important; +} + +/* Frame the table */ +.tabulator { + border: 1px solid lightgrey; + border-bottom: none; + margin-top: 20px; + border-top-left-radius: 0.5em; + border-top-right-radius: 0.5em; +} + +/* Frame the header cells */ +.tabulator-col:not(:first-of-type) { + border-left: 0.5px solid lightgrey; } \ No newline at end of file From bc1c33432f9ace5a0398bf195cd26c02814051a2 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 12:24:28 +0100 Subject: [PATCH 008/265] Avoid of triple points at end of header title (more space) --- public/css/Tabulator.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/css/Tabulator.css b/public/css/Tabulator.css index ffbeed606..718295f4e 100644 --- a/public/css/Tabulator.css +++ b/public/css/Tabulator.css @@ -30,4 +30,9 @@ /* Frame the header cells */ .tabulator-col:not(:first-of-type) { border-left: 0.5px solid lightgrey; +} + +/* More space for header title (avoids triple points at the end) */ +.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { + overflow: initial; } \ No newline at end of file From 3b2b279bf99b4b1e23fdbd439d90c32c82860ef1 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 12:27:13 +0100 Subject: [PATCH 009/265] Changed default visibility / order of columns Now fitted to the users primary needs. Columns can be displayed/hidden via Columnpicker by user afterwards. --- .../lehrauftrag/acceptLehrauftragData.php | 35 ++++++------ .../lehrauftrag/approveLehrauftragData.php | 40 +++++++------- .../lehrauftrag/orderLehrauftragData.php | 55 ++++++++++--------- 3 files changed, 69 insertions(+), 61 deletions(-) diff --git a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php index 08cc94e5f..3211e86a9 100644 --- a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php @@ -9,19 +9,19 @@ $query = ' SELECT /* provide extra row index for tabulator, because no other column has unique ids */ ROW_NUMBER() OVER () AS "row_index", + auftrag, + stg_typ_kurzbz, + gruppe, + typ, lehreinheit_id, lehrveranstaltung_id, projektarbeit_id, studiensemester_kurzbz, studiengang_kz, - stg_typ_kurzbz, semester, orgform_kurzbz, person_id, - typ, - auftrag, lv_oe_kurzbz, - gruppe, stunden, betrag, vertrag_id, @@ -299,19 +299,19 @@ $filterWidgetArray = array( 'reloadDataset' => true, // reload query on page refresh 'columnsAliases' => array( // TODO: use phrasen 'Status', // alias for row_index, because row_index is formatted to display the status icons + 'LV- / Projektbezeichnung', + 'Studiengang', + 'Gruppe', + 'Typ', 'LV-Teil', 'LV-ID', 'PA-ID', 'Studiensemester', 'Studiengang-KZ', - 'Studiengang', 'Semester', 'OrgForm', 'Person-ID', - 'Typ', - 'LV- / Projektbezeichnung', 'Organisationseinheit', - 'Gruppe', 'Stunden', 'Betrag', 'Vertrag-ID', @@ -365,19 +365,22 @@ $filterWidgetArray = array( }', // tabulator properties 'datasetRepFieldsDefs' => '{ row_index: {visible:false}, // necessary for row indexing - lehreinheit_id: {headerFilter:"input", bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();}}, - lehrveranstaltung_id: {headerFilter:"input"}, + auftrag: { + headerFilter:"input", widthGrow: 3, + bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();} + }, + stg_typ_kurzbz: {headerFilter:"input"}, + gruppe: {headerFilter:"input"}, + typ: {headerFilter:"input"}, + lehreinheit_id: {visible: false, headerFilter:"input"}, + lehrveranstaltung_id: {visible: false, headerFilter:"input"}, projektarbeit_id: {visible: false, headerFilter:"input"}, studiensemester_kurzbz: {visible: false, headerFilter:"input"}, studiengang_kz: {visible: false, headerFilter:"input"}, - stg_typ_kurzbz: {headerFilter:"input"}, semester: {headerFilter:"input"}, - orgform_kurzbz: {headerFilter:"input"}, + orgform_kurzbz: {visible: false, headerFilter:"input"}, person_id: {visible: false, headerFilter:"input"}, - typ: {headerFilter:"input"}, - auftrag: {headerFilter:"input"}, - lv_oe_kurzbz: {headerFilter:"input"}, - gruppe: {headerFilter:"input"}, + lv_oe_kurzbz: {visible: false, headerFilter:"input"}, stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:1} diff --git a/application/views/lehre/lehrauftrag/approveLehrauftragData.php b/application/views/lehre/lehrauftrag/approveLehrauftragData.php index 111e7bd01..4ad03e138 100644 --- a/application/views/lehre/lehrauftrag/approveLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/approveLehrauftragData.php @@ -9,20 +9,20 @@ SELECT /* provide extra row index for tabulator, because no other column has unique ids */ ROW_NUMBER() OVER () AS "row_index", personalnummer, + auftrag, + stg_typ_kurzbz, + gruppe, + typ, lehreinheit_id, lehrveranstaltung_id, lv_bezeichnung, projektarbeit_id, studiensemester_kurzbz, studiengang_kz, - stg_typ_kurzbz, semester, orgform_kurzbz, person_id, - typ, - auftrag, lv_oe_kurzbz, - gruppe, lektor, stunden, betrag, @@ -308,20 +308,20 @@ $filterWidgetArray = array( 'columnsAliases' => array( // TODO: use phrasen 'Status', // alias for row_index, because row_index is formatted to display the status icons 'Personalnummer', + 'LV- / Projektbezeichnung', + 'Studiengang', + 'Gruppe', + 'Typ', 'LV-Teil', 'LV-ID', 'LV', 'PA-ID', 'Studiensemester', 'Studiengang-KZ', - 'Studiengang', 'Semester', 'OrgForm', 'Person-ID', - 'Typ', - 'LV- / Projektbezeichnung', 'Organisationseinheit', - 'Gruppe', 'Lektor', 'Stunden', 'Betrag', @@ -384,22 +384,24 @@ $filterWidgetArray = array( // column status is built dynamically in funcTableBuilt(), row_index: {visible:false}, // necessary for row indexing personalnummer: {visible: false, headerFilter:"input"}, - lehreinheit_id: {headerFilter:"input", bottomCalc:"count", - bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();},}, - lehrveranstaltung_id: {headerFilter:"input"}, + auftrag: { + headerFilter:"input", widthGrow: 2, + bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();} + }, + stg_typ_kurzbz: {headerFilter:"input"}, + gruppe: {headerFilter:"input"}, + typ: {headerFilter:"input"}, + lehreinheit_id: {visible: false, headerFilter:"input"}, + lehrveranstaltung_id: {visible: false, headerFilter:"input"}, lv_bezeichnung: {visible: false, headerFilter:"input"}, projektarbeit_id: {visible: false, headerFilter:"input"}, - studiensemester_kurzbz: {headerFilter:"input"}, + studiensemester_kurzbz: {visible: false, headerFilter:"input"}, studiengang_kz: {visible: false, headerFilter:"input"}, - stg_typ_kurzbz: {headerFilter:"input"}, semester: {headerFilter:"input"}, - orgform_kurzbz: {headerFilter:"input"}, + orgform_kurzbz: {visible: false, headerFilter:"input"}, person_id: {visible: false, headerFilter:"input"}, - typ: {headerFilter:"input"}, - auftrag: {headerFilter:"input"}, - lv_oe_kurzbz: {headerFilter:"input"}, - gruppe: {headerFilter:"input"}, - lektor: {headerFilter:"input"}, + lv_oe_kurzbz: {visible: false, headerFilter:"input"}, + lektor: {headerFilter:"input", widthGrow: 2}, stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:1}}, diff --git a/application/views/lehre/lehrauftrag/orderLehrauftragData.php b/application/views/lehre/lehrauftrag/orderLehrauftragData.php index d78f5ecfe..5576e7886 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftragData.php @@ -9,13 +9,16 @@ SELECT /* provide extra row index for tabulator, because no other column has unique ids */ ROW_NUMBER() OVER () AS "row_index", personalnummer, + auftrag, + stg_typ_kurzbz, + gruppe, + typ, lehreinheit_id, lehrveranstaltung_id, lv_bezeichnung, projektarbeit_id, studiensemester_kurzbz, studiengang_kz, - stg_typ_kurzbz, semester, /* get valid STPL(s), to which the lehrveranstaltung is assigned to (can be more) */ /* therefore join over lv, studiensemester and semester */ @@ -49,10 +52,7 @@ SELECT ) AS "studienplan_bezeichnung", orgform_kurzbz, person_id, - typ, - auftrag, lv_oe_kurzbz, - gruppe, lektor, stunden, stundensatz, @@ -340,21 +340,22 @@ $filterWidgetArray = array( 'columnsAliases' => array( // TODO: use phrasen 'Status', // alias for row_index, because row_index is formatted to display the status icons 'Personalnummer', + 'LV- / Projektbezeichnung', + 'Studiengang', + 'Gruppe', + 'Typ', 'LV-Teil', 'LV-ID', 'LV', 'PA-ID', 'Studiensemester', 'Studiengang-KZ', - 'Studiengang', + 'Semester', 'Studienplan', 'OrgForm', 'Person-ID', - 'Typ', - 'LV- / Projektbezeichnung', 'Organisationseinheit', - 'Gruppe', 'Lektor', 'Stunden', 'Stundensatz', @@ -419,29 +420,31 @@ $filterWidgetArray = array( // column status is built dynamically in funcTableBuilt() row_index: {visible: false}, personalnummer: {visible: false, headerFilter:"input"}, - lehreinheit_id: {headerFilter:"input", bottomCalc:"count", minWidth: 115, - bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();}}, - lehrveranstaltung_id: {headerFilter:"input"}, + auftrag: { + headerFilter:"input", widthGrow: 2, + bottomCalc:"count", bottomCalcFormatter:function(cell){return "Anzahl: " + cell.getValue();} + }, + stg_typ_kurzbz: {headerFilter:"input"}, + gruppe: {headerFilter:"input"}, + typ: {headerFilter:"input"}, + lehreinheit_id: {visible: false, headerFilter:"input"}, + lehrveranstaltung_id: {visible: false, headerFilter:"input"}, lv_bezeichnung: {visible: false, headerFilter:"input"}, projektarbeit_id: {visible: false, headerFilter:"input"}, - studiensemester_kurzbz: {headerFilter:"input"}, + studiensemester_kurzbz: {visible: false, headerFilter:"input"}, studiengang_kz: {visible: false, headerFilter:"input"}, - stg_typ_kurzbz: {headerFilter:"input", minWidth: 70}, semester: {headerFilter:"input"}, - studienplan_bezeichnung: {headerFilter:"input"}, - orgform_kurzbz: {headerFilter:"input"}, + studienplan_bezeichnung: {visible: false, headerFilter:"input"}, + orgform_kurzbz: {visible: false, headerFilter:"input", widthGrow: 2}, person_id: {visible: false, headerFilter:"input"}, - typ: {headerFilter:"input", minWidth:100}, - auftrag: {headerFilter:"input", minWidth:280}, - lv_oe_kurzbz: {headerFilter:"input", minWidth:80}, - gruppe: {headerFilter:"input", minWidth:120}, - lektor: {headerFilter:"input", widthGrow: 3}, - stunden: {align:"right", minWidth: 80, formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, + lv_oe_kurzbz: {headerFilter:"input"}, + lektor: {headerFilter:"input", widthGrow: 2}, + stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:1}}, - stundensatz: {visible: false, align:"right", minWidth: 100, formatter: form_formatNulltoStringNumber, + stundensatz: {visible: false, align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator}, - betrag: {align:"right", minWidth: 120, formatter: form_formatNulltoStringNumber, + betrag: {align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, bottomCalc:"sum", bottomCalcParams:{precision:2}, bottomCalcFormatter:"money", bottomCalcFormatterParams:{decimal: ",", thousand: ".", symbol:"€"}}, @@ -449,9 +452,9 @@ $filterWidgetArray = array( vertrag_stunden: {visible: false}, vertrag_betrag: {visible: false}, mitarbeiter_uid: {visible: false, headerFilter:"input"}, - bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip, minWidth: 100}, - erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip, minWidth: 100}, - akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip, minWidth: 100}, + bestellt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: bestellt_tooltip}, + erteilt: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: erteilt_tooltip}, + akzeptiert: {align:"center", headerFilter:"input", mutator: mut_formatStringDate, tooltip: akzeptiert_tooltip}, bestellt_von: {visible: false, headerFilter:"input"}, erteilt_von: {visible: false, headerFilter:"input"}, akzeptiert_von: {visible: false, headerFilter:"input"} From 8c36b0b67a5a1303de3a89ccf0b1f527f837af37 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 12:28:51 +0100 Subject: [PATCH 010/265] =?UTF-8?q?Reduced=20default=20minimum=20size=20of?= =?UTF-8?q?=20columns=20in=20Stornierte=20Lehrauftr=C3=A4ge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/lehre/lehrauftrag/cancelledLehrauftragData.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php index 20629cb84..2dbecbb69 100644 --- a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php @@ -87,12 +87,12 @@ $tableWidgetArray = array( 'datasetRepFieldsDefs' => '{ vertrag_id: {visible: false}, vertragsstunden_studiensemester_kurzbz: {visible: false, widthShrink:1}, - vertragstyp_kurzbz: {minWidth: 300}, - bezeichnung: {minWidth: 400}, + vertragstyp_kurzbz: {minWidth: 200}, + bezeichnung: {minWidth: 200}, vertragsstunden: { align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, bottomCalc:"sum", bottomCalcParams:{precision:1}, - minWidth: 300 + minWidth: 200 }, betrag: { align:"right", formatter: form_formatNulltoStringNumber, From e1df2cbf23ed86db046736cc1514d46e72bd47bc Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 12:30:26 +0100 Subject: [PATCH 011/265] Added tooltips on column headers (displaying title) in TableWidget Now this is a standard behaviour of TableWidget. --- public/js/TableWidget.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 575ad6b12..7c1b01b93 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -522,6 +522,7 @@ var FHC_TableWidget = { options.columns = arrayTabulatorColumns; options.data = data.dataset; + options.tooltipsHeader = true; // set header tooltip with column title options.rowSelectionChanged = function(data, rows){ _func_rowSelectionChanged(data, rows); }; From 6897ccdd6b4973e260ebbb355c0f751dc0dc7f10 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 12:43:50 +0100 Subject: [PATCH 012/265] Moved empty table placeholder text to TableWidget Now this is a standard behaviour of TableWidget. --- .../views/lehre/lehrauftrag/acceptLehrauftragData.php | 1 - .../views/lehre/lehrauftrag/approveLehrauftragData.php | 1 - .../views/lehre/lehrauftrag/cancelledLehrauftragData.php | 1 - .../views/lehre/lehrauftrag/orderLehrauftragData.php | 1 - public/js/TableWidget.js | 8 ++++++++ public/js/lehre/lehrauftrag/acceptLehrauftrag.js | 6 ------ public/js/lehre/lehrauftrag/approveLehrauftrag.js | 6 ------ public/js/lehre/lehrauftrag/orderLehrauftrag.js | 6 ------ 8 files changed, 8 insertions(+), 22 deletions(-) diff --git a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php index 3211e86a9..3fa2c603c 100644 --- a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php @@ -332,7 +332,6 @@ $filterWidgetArray = array( persistenceID: "acceptLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated movableColumns: true, // allows changing column - placeholder: func_placeholder(), headerFilterPlaceholder: " ", index: "row_index", // assign specific column as unique id (important for row indexing) selectable: true, // allow row selection diff --git a/application/views/lehre/lehrauftrag/approveLehrauftragData.php b/application/views/lehre/lehrauftrag/approveLehrauftragData.php index 4ad03e138..7cc5bd533 100644 --- a/application/views/lehre/lehrauftrag/approveLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/approveLehrauftragData.php @@ -344,7 +344,6 @@ $filterWidgetArray = array( persistenceID: "approveLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated movableColumns: true, // allows changing column - placeholder: func_placeholder(), headerFilterPlaceholder: " ", groupBy:"lehrveranstaltung_id", groupToggleElement:"header", //toggle group on click anywhere in the group header diff --git a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php index 2dbecbb69..cbf7d8b55 100644 --- a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php @@ -70,7 +70,6 @@ $tableWidgetArray = array( persistenceID: "cancelledLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated movableColumns: true, // allows changing column - placeholder: func_placeholder(), rowFormatter:function(row){ func_rowFormatter(row); }, diff --git a/application/views/lehre/lehrauftrag/orderLehrauftragData.php b/application/views/lehre/lehrauftrag/orderLehrauftragData.php index 5576e7886..f4a122deb 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftragData.php @@ -379,7 +379,6 @@ $filterWidgetArray = array( persistenceID: "orderLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated movableColumns: true, // allows changing column order - placeholder: func_placeholder(), // shown on empty table (no data) headerFilterPlaceholder: " ", groupBy:"lehrveranstaltung_id", groupToggleElement:"header", //toggle group on click anywhere in the group header diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 7c1b01b93..7b914cc60 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -523,6 +523,7 @@ var FHC_TableWidget = { options.columns = arrayTabulatorColumns; options.data = data.dataset; options.tooltipsHeader = true; // set header tooltip with column title + options.placeholder = _func_placeholder(); // display text when table is empty options.rowSelectionChanged = function(data, rows){ _func_rowSelectionChanged(data, rows); }; @@ -718,6 +719,13 @@ function _func_columnVisibilityChanged(column, visible){ table.redraw(); } +/* + * Displays text when table is empty + */ +function _func_placeholder(){ + return "

Keine Daten vorhanden.

"; +} + // Returns TableWidget Header HTML (download-, setting button...) function _renderTabulatorHeaderHTML(tableWidgetDiv){ diff --git a/public/js/lehre/lehrauftrag/acceptLehrauftrag.js b/public/js/lehre/lehrauftrag/acceptLehrauftrag.js index c3d89ac52..341a325fc 100644 --- a/public/js/lehre/lehrauftrag/acceptLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/acceptLehrauftrag.js @@ -98,12 +98,6 @@ function func_height(table){ return $(window).height() * 0.50; } -// Displays text when table is empty -function func_placeholder() -{ - return "

Keine Daten vorhanden.

"; -} - // Formats the rows function func_rowFormatter(row){ var bestellt = row.getData().bestellt; diff --git a/public/js/lehre/lehrauftrag/approveLehrauftrag.js b/public/js/lehre/lehrauftrag/approveLehrauftrag.js index 29e2d9651..7326a95c1 100644 --- a/public/js/lehre/lehrauftrag/approveLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/approveLehrauftrag.js @@ -111,12 +111,6 @@ function func_height(table){ return $(window).height() * 0.50; } -// Displays text when table is empty -function func_placeholder() -{ - return "

Keine Daten vorhanden.

"; -} - // Formats the group header function func_groupHeader(data){ return data[0].lv_bezeichnung + "  " + ' ( LV-ID: ' + data[0].lehrveranstaltung_id + ' )'; // change name to lehrveranstaltung; diff --git a/public/js/lehre/lehrauftrag/orderLehrauftrag.js b/public/js/lehre/lehrauftrag/orderLehrauftrag.js index 6471d988f..379a02b6a 100644 --- a/public/js/lehre/lehrauftrag/orderLehrauftrag.js +++ b/public/js/lehre/lehrauftrag/orderLehrauftrag.js @@ -116,12 +116,6 @@ function func_height(table){ return $(window).height() * 0.50; } -// Displays text when table is empty -function func_placeholder() -{ - return "

Keine Daten vorhanden.

"; -} - // Formats the group header function func_groupHeader(data) { return data[0].lv_bezeichnung + "  " + ' ( LV-ID: ' + data[0].lehrveranstaltung_id + ' )'; // change name to lehrveranstaltung; From bce7f60df43509875467378ecf89c4ec7e986bbc Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 13:22:49 +0100 Subject: [PATCH 013/265] Moved layout options to TableWidget Now this is a standard behaviour of TableWidget. --- .../views/lehre/lehrauftrag/acceptLehrauftragData.php | 3 --- .../views/lehre/lehrauftrag/approveLehrauftragData.php | 3 --- .../views/lehre/lehrauftrag/cancelledLehrauftragData.php | 6 ------ .../views/lehre/lehrauftrag/orderLehrauftragData.php | 3 --- public/js/TableWidget.js | 7 +++++-- 5 files changed, 5 insertions(+), 17 deletions(-) diff --git a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php index 3fa2c603c..7b9443edb 100644 --- a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php @@ -328,10 +328,7 @@ $filterWidgetArray = array( 'datasetRepOptions' => '{ height: func_height(this), layout: "fitColumns", // fit columns to width of table - persistentLayout:true, // enables persistence (default store in localStorage if available, else in cookie) - persistenceID: "acceptLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated - movableColumns: true, // allows changing column headerFilterPlaceholder: " ", index: "row_index", // assign specific column as unique id (important for row indexing) selectable: true, // allow row selection diff --git a/application/views/lehre/lehrauftrag/approveLehrauftragData.php b/application/views/lehre/lehrauftrag/approveLehrauftragData.php index 7cc5bd533..5e1ae27b6 100644 --- a/application/views/lehre/lehrauftrag/approveLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/approveLehrauftragData.php @@ -340,10 +340,7 @@ $filterWidgetArray = array( height: func_height(this), layout: "fitColumns", // fit columns to width of table layoutColumnsOnNewData: true, // ajust column widths to the data each time TableWidget is loaded - persistentLayout:true, // enables persistence (default store in localStorage if available, else in cookie) - persistenceID: "approveLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated - movableColumns: true, // allows changing column headerFilterPlaceholder: " ", groupBy:"lehrveranstaltung_id", groupToggleElement:"header", //toggle group on click anywhere in the group header diff --git a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php index cbf7d8b55..ba7b0d4f6 100644 --- a/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/cancelledLehrauftragData.php @@ -64,12 +64,6 @@ $tableWidgetArray = array( 'Storniert am' ), 'datasetRepOptions' => '{ - layout: "fitColumns", // fit columns to width of table - layoutColumnsOnNewData: true, // ajust column widths to the data each time TableWidget is loaded - persistentLayout: true, // enables persistence (default store in localStorage if available, else in cookie) - persistenceID: "cancelledLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables - autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated - movableColumns: true, // allows changing column rowFormatter:function(row){ func_rowFormatter(row); }, diff --git a/application/views/lehre/lehrauftrag/orderLehrauftragData.php b/application/views/lehre/lehrauftrag/orderLehrauftragData.php index f4a122deb..ca671fbd4 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftragData.php @@ -375,10 +375,7 @@ $filterWidgetArray = array( height: func_height(this), layout:"fitColumns", // fit columns to width of table layoutColumnsOnNewData: true, // ajust column widths to the data each time TableWidget is loaded - persistentLayout:true, // enables persistence (default store in localStorage if available, else in cookie) - persistenceID: "orderLehrauftrag", // TableWidget unique id to store persistence data seperately for multiple tables autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated - movableColumns: true, // allows changing column order headerFilterPlaceholder: " ", groupBy:"lehrveranstaltung_id", groupToggleElement:"header", //toggle group on click anywhere in the group header diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 7b914cc60..204d69280 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -522,8 +522,11 @@ var FHC_TableWidget = { options.columns = arrayTabulatorColumns; options.data = data.dataset; - options.tooltipsHeader = true; // set header tooltip with column title - options.placeholder = _func_placeholder(); // display text when table is empty + options.persistentLayout = true; // enables persistence (default store in localStorage if available, else in cookie) + options.persistenceID = data.tableUniqueId; // TableWidget unique id to store persistence data seperately for multiple tables + options.movableColumns = true; // allows changing column order + options.tooltipsHeader = true; // set header tooltip with column title + options.placeholder = _func_placeholder(); // display text when table is empty options.rowSelectionChanged = function(data, rows){ _func_rowSelectionChanged(data, rows); }; From b2542b5fcca581f37a9f9ef1794009edefd06e09 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 30 Jan 2020 17:09:31 +0100 Subject: [PATCH 014/265] Added HELP button and collapsable help-info to TableWidget [ALPHA VERSION] Now this is a standard behaviour of TableWidget. Removed also table related help information from general Hilfe-zu-dieser-Seite help. [ALPHA VERSION]: minor issue to be fixed: button color not toggling correctly when opening help then settings (and way round) --- .../lehre/lehrauftrag/acceptLehrauftrag.php | 22 ----- .../lehre/lehrauftrag/approveLehrauftrag.php | 22 ----- .../lehre/lehrauftrag/orderLehrauftrag.php | 23 ------ public/css/Tabulator.css | 1 - public/js/TableWidget.js | 82 ++++++++++++++++++- 5 files changed, 81 insertions(+), 69 deletions(-) diff --git a/application/views/lehre/lehrauftrag/acceptLehrauftrag.php b/application/views/lehre/lehrauftrag/acceptLehrauftrag.php index 14ebacecb..15de019e5 100644 --- a/application/views/lehre/lehrauftrag/acceptLehrauftrag.php +++ b/application/views/lehre/lehrauftrag/acceptLehrauftrag.php @@ -83,28 +83,6 @@ $this->load->view(

- -

Auswahl

-
-
    -
  • Einzeln auswählen: Strg + Klick auf einzelne Zeile(n)
  • -
  • Bereich auswählen: Shift + Klick auf Anfangs- und Endzeile
  • -
  • Alle auswählen: Button 'Alle auswählen'
  • -
-
-
- -

Ansicht

-
- Spaltenbreite verändern -

- Um die Spaltenbreite zu verändern, fährt man im Spaltenkopf langsam mit dem Mauszeiger auf - den rechten Rand der entprechenden Spalte.
- Sobald sich der Mauszeiger in einen Doppelpfeil verwandelt, wird die Maustaste geklickt und - mit gedrückter Maustaste die Spalte nach rechts erweitert oder nach links verkleinert. -

-
-
diff --git a/application/views/lehre/lehrauftrag/approveLehrauftrag.php b/application/views/lehre/lehrauftrag/approveLehrauftrag.php index f36ae7dc7..ed1852654 100644 --- a/application/views/lehre/lehrauftrag/approveLehrauftrag.php +++ b/application/views/lehre/lehrauftrag/approveLehrauftrag.php @@ -123,28 +123,6 @@ $this->load->view(
-

Auswahl

-
-
    -
  • Einzeln auswählen: Strg + Klick auf einzelne Zeile(n)
  • -
  • Bereich auswählen: Shift + Klick auf Anfangs- und Endzeile
  • -
  • Alle auswählen: Button 'Alle auswählen'
  • -
-
-
- -

Ansicht

-
- Spaltenbreite verändern -

- Um die Spaltenbreite zu verändern, fährt man im Spaltenkopf langsam mit dem Mauszeiger auf - den rechten Rand der entprechenden Spalte.
- Sobald sich der Mauszeiger in einen Doppelpfeil verwandelt, wird die Maustaste geklickt und - mit gedrückter Maustaste die Spalte nach rechts erweitert oder nach links verkleinert. -

-
-
- diff --git a/application/views/lehre/lehrauftrag/orderLehrauftrag.php b/application/views/lehre/lehrauftrag/orderLehrauftrag.php index 27793e8ba..1e79bee0d 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftrag.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftrag.php @@ -124,29 +124,6 @@ $this->load->view(
- -

Auswahl

-
-
    -
  • Einzeln auswählen: Strg + Klick auf einzelne Zeile(n)
  • -
  • Bereich auswählen: Shift + Klick auf Anfangs- und Endzeile
  • -
  • Alle auswählen: Button 'Alle auswählen'
  • -
-
-
- -

Ansicht

-
- Spaltenbreite verändern -

- Um die Spaltenbreite zu verändern, fährt man im Spaltenkopf langsam mit dem Mauszeiger auf - den rechten Rand der entprechenden Spalte.
- Sobald sich der Mauszeiger in einen Doppelpfeil verwandelt, wird die Maustaste geklickt und - mit gedrückter Maustaste die Spalte nach rechts erweitert oder nach links verkleinert. -

-
-
- diff --git a/public/css/Tabulator.css b/public/css/Tabulator.css index 718295f4e..0545101c9 100644 --- a/public/css/Tabulator.css +++ b/public/css/Tabulator.css @@ -22,7 +22,6 @@ .tabulator { border: 1px solid lightgrey; border-bottom: none; - margin-top: 20px; border-top-left-radius: 0.5em; border-top-right-radius: 0.5em; } diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 204d69280..bc49b8c69 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -204,6 +204,32 @@ var FHC_TableWidget = { tableWidgetDiv.find("#tableWidgetTabulator").tabulator("download", "csv", "data.csv", {bom:true}); }) + // Click-Event to collapse help div + tableWidgetDiv.find('#help').on('click', function() + { + + //... auch unteren event für settings hier hinein + $('#tabulatorHelp-' + tableUniqueId).collapse('toggle'); + + $(this).toggleClass('active focus'); + + // De/activate and un/focus on clicked settings button + if(!$(this).hasClass('active focus')) + { + $(this).css({'background-color': 'white', 'border-color' : '#ccc', 'outline': 'none'}); + } + else + { + $(this).css({'background-color': '#e6e6e6'}); + } + + if($('#tabulatorSettings-' + tableUniqueId).hasClass('collapse in')) + { + $('#tabulatorSettings-' + tableUniqueId).removeClass('in'); + // $('#settings').toggleClass('active focus'); + } + }) + // Click-Event to collapse settings div tableWidgetDiv.find('#settings').on('click', function() { @@ -222,6 +248,12 @@ var FHC_TableWidget = { { $(this).css({'background-color': '#e6e6e6'}); } + + if($('#tabulatorHelp-' + tableUniqueId).hasClass('collapse in')) + { + $('#tabulatorHelp-' + tableUniqueId).removeClass('in'); + // $('#help').toggleClass('active focus'); + } }) /** @@ -738,7 +770,8 @@ function _renderTabulatorHeaderHTML(tableWidgetDiv){ tabulatorHeaderHTML += ''; @@ -751,6 +784,8 @@ function _renderTabulatorHeaderCollapseHTML(tableWidgetDiv){ var tableUniqueId = tableWidgetDiv.attr('tableUniqueId'); var tabulatorHeaderCollapseHTML = ''; + + // CollapseHTML 'Settings' tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; @@ -799,6 +834,51 @@ function _renderTabulatorHeaderCollapseHTML(tableWidgetDiv){ tabulatorHeaderCollapseHTML += '
'; // end col tabulatorHeaderCollapseHTML += '
'; // end row + // CollapseHTML 'Help' + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; + + tabulatorHeaderCollapseHTML += '

Tabelleneinstellungen

'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += 'Spalten ein- und ausblenden'; + tabulatorHeaderCollapseHTML += '

'; + tabulatorHeaderCollapseHTML += '

    '; + tabulatorHeaderCollapseHTML += '
  • Mit einem Klick auf ' + + 'werden die Einstellungen geöffnet.
  • '; + tabulatorHeaderCollapseHTML += '
  • Auf Spalteneinstellungen klicken
  • '; + tabulatorHeaderCollapseHTML += '
  • Durch (wiederholtes) Klicken auf die einzelnen Spaltennamen können ' + + 'diese in der Tabelle beliebig oft aktiviert / deaktiviert werden.
  • '; + tabulatorHeaderCollapseHTML += '
  • Mit einem Klick auf ' + + 'werden die Einstellungen wieder geschlossen.
  • '; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '

'; + tabulatorHeaderCollapseHTML += 'Spaltenbreite verändern'; + tabulatorHeaderCollapseHTML += '

Um die Spaltenbreite zu verändern, fährt man im Spaltenkopf langsam ' + + 'mit dem Mauszeiger auf den rechten Rand der entprechenden Spalte.
' + + 'Sobald sich der Mauszeiger in einen Doppelpfeil verwandelt, wird die Maustaste geklickt und ' + + 'mit gedrückter Maustaste die Spalte nach rechts erweitert oder nach links verkleinert.'; + tabulatorHeaderCollapseHTML += '

'; + tabulatorHeaderCollapseHTML += '
INFO: Alle individuellen Tabelleneinstellungen werden in ' + + 'Ihrem Browser Cache gespeichert. Wenn Sie Ihren Browser Cache löschen, werden Ihre Einstellungen zurückgesetzt und ' + + 'müssen gegebenenfalls neu eingestellt werden.'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '

'; // end panel-body + + tabulatorHeaderCollapseHTML += '

Zeilen auswählen

'; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
    '; + tabulatorHeaderCollapseHTML += '
  • Einzeln auswählen: Strg + Klick auf einzelne Zeile(n)
  • '; + tabulatorHeaderCollapseHTML += '
  • Bereich auswählen: Shift + Klick auf Anfangs- und Endzeile
  • '; + tabulatorHeaderCollapseHTML += '
  • Alle auswählen: Button \'Alle auswählen\'
  • '; + tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '

'; // end panel-body + + tabulatorHeaderCollapseHTML += '
'; // end well + tabulatorHeaderCollapseHTML += '
'; // end col collapse + tabulatorHeaderCollapseHTML += '
'; // end row + return tabulatorHeaderCollapseHTML; } From 3a8e7427a7683f9413336e81ed078644ef814a35 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 11 Feb 2020 08:59:23 +0100 Subject: [PATCH 015/265] Enhanced active status behaviour of button group Active status of button help / settings was not clear before. This is corrected now. --- public/js/TableWidget.js | 63 +++++++++++++++------------------------- 1 file changed, 24 insertions(+), 39 deletions(-) diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index bc49b8c69..eebe5265c 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -204,57 +204,40 @@ var FHC_TableWidget = { tableWidgetDiv.find("#tableWidgetTabulator").tabulator("download", "csv", "data.csv", {bom:true}); }) - // Click-Event to collapse help div + // Click-Event to toggle the collapsable help panel tableWidgetDiv.find('#help').on('click', function() { + // Hide the collapsable settings panel, if it actually shown + $('#tabulatorSettings-' + tableUniqueId).collapse('hide'); - //... auch unteren event für settings hier hinein + // Toggle the collapsable help panel $('#tabulatorHelp-' + tableUniqueId).collapse('toggle'); - - $(this).toggleClass('active focus'); - - // De/activate and un/focus on clicked settings button - if(!$(this).hasClass('active focus')) - { - $(this).css({'background-color': 'white', 'border-color' : '#ccc', 'outline': 'none'}); - } - else - { - $(this).css({'background-color': '#e6e6e6'}); - } - - if($('#tabulatorSettings-' + tableUniqueId).hasClass('collapse in')) - { - $('#tabulatorSettings-' + tableUniqueId).removeClass('in'); - // $('#settings').toggleClass('active focus'); - } }) - // Click-Event to collapse settings div + // Click-Event to toggle the collapsable settings panel tableWidgetDiv.find('#settings').on('click', function() { + // Hide the collapsable help panel, if it actually shown + $('#tabulatorHelp-' + tableUniqueId).collapse('hide'); - //... auch unteren event für settings hier hinein + // Toggle the collapsable settings panel $('#tabulatorSettings-' + tableUniqueId).collapse('toggle'); + }) - $(this).toggleClass('active focus'); - - // De/activate and un/focus on clicked settings button - if(!$(this).hasClass('active focus')) + /* Beautify button group behaviour + * Let buttons stay active even until they are clicked again to close the collapsable help- oder setting panels + * Also remove the disturbing button focus behaviour + */ + $(".btn-group > .btn").click(function(){ + if ($(this).hasClass("active")) { - $(this).css({'background-color': 'white', 'border-color' : '#ccc', 'outline': 'none'}); + $(this).removeClass('active').css('outline', 'none'); } else { - $(this).css({'background-color': '#e6e6e6'}); + $(this).addClass("active").css('outline', 'none').siblings().removeClass("active"); } - - if($('#tabulatorHelp-' + tableUniqueId).hasClass('collapse in')) - { - $('#tabulatorHelp-' + tableUniqueId).removeClass('in'); - // $('#help').toggleClass('active focus'); - } - }) + }); /** * Click-Event to select all rows @@ -774,6 +757,7 @@ function _renderTabulatorHeaderHTML(tableWidgetDiv){ tabulatorHeaderHTML += ''; tabulatorHeaderHTML += ''; tabulatorHeaderHTML += ''; + tabulatorHeaderHTML += '


'; return tabulatorHeaderHTML; } @@ -786,7 +770,6 @@ function _renderTabulatorHeaderCollapseHTML(tableWidgetDiv){ var tabulatorHeaderCollapseHTML = ''; // CollapseHTML 'Settings' - tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; @@ -794,10 +777,13 @@ function _renderTabulatorHeaderCollapseHTML(tableWidgetDiv){ tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += ''; // end panel-heading - tabulatorHeaderCollapseHTML += '
'; + tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; @@ -835,7 +821,6 @@ function _renderTabulatorHeaderCollapseHTML(tableWidgetDiv){ tabulatorHeaderCollapseHTML += '
'; // end row // CollapseHTML 'Help' - tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; tabulatorHeaderCollapseHTML += '
'; From 30c6f10d8091b8ce460e1b79c0052fae30f815e6 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 4 Mar 2020 15:54:23 +0100 Subject: [PATCH 016/265] First proposal --- application/config/jqm.php | 6 ++ .../controllers/system/JobsQueueMonitor.php | 56 +++++++++++++++++++ application/core/JQW_Controller.php | 56 +++++++++++++++++++ application/libraries/JobsQueueLib.php | 56 +++++++++++++++++++ 4 files changed, 174 insertions(+) create mode 100644 application/config/jqm.php create mode 100644 application/controllers/system/JobsQueueMonitor.php create mode 100644 application/core/JQW_Controller.php create mode 100644 application/libraries/JobsQueueLib.php diff --git a/application/config/jqm.php b/application/config/jqm.php new file mode 100644 index 000000000..5890241ae --- /dev/null +++ b/application/config/jqm.php @@ -0,0 +1,6 @@ + 'monitoring:r', + 'getJobsByStatus' => 'monitoring:r', + 'getJobsByCreationTime' => 'monitoring:r' + ) + ); + + // Loads JobsQueueLib + $this->load->library('JobsQueueLib'); + } + + /** + * + */ + public function getJobsByType() + { + $jobType = $this->input->get(JobsQueueLib::PARAM_JOB_TYPE); + + $this->outputJson($this->jobsqueuelib->getJobsByType($jobType)); + } + + /** + * + */ + public function getJobsByStatus() + { + $jobStatus = $this->input->get(JobsQueueLib::PARAM_JOB_STATUS); + + $this->outputJson($this->jobsqueuelib->getJobsByStatus($jobStatus)); + } + + /** + * + */ + public function getJobsByCreationTime() + { + $jobCreationTime = $this->input->get(JobsQueueLib::PARAM_JOB_CREATION_TIME); + + $this->outputJson($this->jobsqueuelib->getJobsByCreationTime($jobCreationTime)); + } +} diff --git a/application/core/JQW_Controller.php b/application/core/JQW_Controller.php new file mode 100644 index 000000000..9cb058f6b --- /dev/null +++ b/application/core/JQW_Controller.php @@ -0,0 +1,56 @@ +load->library('LogLib', array( + 'classIndex' => 5, + 'functionIndex' => 5, + 'lineIndex' => 4, + 'dbLogType' => 'job', // required + 'dbExecuteUser' => 'Jobs queue system' + )); + + // Loads JobsQueueLib + $this->load->library('JobsQueueLib'); + } + + // ------------------------------------------------------------------------------------------------------------ + // Protected methods to read/write the jobs queue + + /** + * + */ + protected function getJobsByType($jobType) + { + $jobs = $this->jobsqueuelib->getJobsByType($jobType); + + if (isError($jobs)) $this->logError(getError($jobs), $jobType); + + return $jobs; + } + + /** + * + */ + protected function addNewJobsToQueue($jobType, $jobs) + { + $result = $this->jobsqueuelib->addNewJobsToQueue($jobType, $jobs); + + if (isError($result)) $this->logError(getError($result), $jobType); + + return $result; + } +} diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php new file mode 100644 index 000000000..0c7e44274 --- /dev/null +++ b/application/libraries/JobsQueueLib.php @@ -0,0 +1,56 @@ +_ci =& get_instance(); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * + */ + public function getJobsByType() + { + } + + /** + * + */ + public function addNewJobsToQueue() + { + } + + /** + * + */ + public function getJobsByStatus() + { + } +} From cd815acdbff64ab4797ec95d5661936cea17137b Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 5 Mar 2020 15:57:06 +0100 Subject: [PATCH 017/265] - Added new constant BEGINNING_OF_TIME - Added new config entry job_type_permissions_white_list in jqm.php - Added new navigation entry jobsqueueviewer - Added new model application/models/system/JobsQueue_model.php - Added new option in FilterWidget for hours comparison with dates - Added new filter core-jq-lastHour to system/filtersupdate.php - Added new statements to system/dbupdate_3.3.php to create tables system.tbl_jobstatuses, system.tbl_jobtypes and system.tbl_jobstatuses - Added new views application/views/system/jq/jobsQueueViewer.php and application/views/system/jq/jobsQueueViewerData.php --- application/config/constants.php | 7 + application/config/jqm.php | 14 +- application/config/navigation.php | 7 + .../controllers/system/JobsQueueMonitor.php | 56 -------- application/controllers/system/LogsViewer.php | 2 +- .../system/jq/JobsQueueManager.php | 51 +++++++ .../controllers/system/jq/JobsQueueViewer.php | 48 +++++++ application/core/JQW_Controller.php | 33 +++-- application/libraries/FilterWidgetLib.php | 7 +- application/libraries/JobsQueueLib.php | 30 ++-- application/models/system/JobsQueue_model.php | 15 ++ .../views/system/jq/jobsQueueViewer.php | 47 +++++++ .../views/system/jq/jobsQueueViewerData.php | 67 +++++++++ application/views/system/logs/logsViewer.php | 4 +- system/dbupdate_3.3.php | 131 ++++++++++++++++++ system/filtersupdate.php | 31 +++++ 16 files changed, 462 insertions(+), 88 deletions(-) delete mode 100644 application/controllers/system/JobsQueueMonitor.php create mode 100644 application/controllers/system/jq/JobsQueueManager.php create mode 100644 application/controllers/system/jq/JobsQueueViewer.php create mode 100644 application/models/system/JobsQueue_model.php create mode 100644 application/views/system/jq/jobsQueueViewer.php create mode 100644 application/views/system/jq/jobsQueueViewerData.php diff --git a/application/config/constants.php b/application/config/constants.php index ef4cdaf2c..f21b6c962 100644 --- a/application/config/constants.php +++ b/application/config/constants.php @@ -31,6 +31,13 @@ define('EXIT_VALIDATION_UDF_NOT_VALID_VAL', 17); // UDF validation has been fail define('EXIT_AUTO_MIN', 1000); // lowest automatically-assigned error code define('EXIT_AUTO_MAX', 2000); // highest automatically-assigned error code +/* +|-------------------------------------------------------------------------- +| General purpose +|-------------------------------------------------------------------------- +*/ +define('BEGINNING_OF_TIME', '1970-01-01'); + /* |-------------------------------------------------------------------------- | Authentication constants diff --git a/application/config/jqm.php b/application/config/jqm.php index 5890241ae..579fc6987 100644 --- a/application/config/jqm.php +++ b/application/config/jqm.php @@ -2,5 +2,15 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); -// -$config['addable_jobs_black_list'] = array('doomsday', 'sudo rm -fR /', 'sudo mv / /dev/null'); +// White list of permissions that are able to store a spcific job type in database +$config['job_type_permissions_white_list'] = array( + 'SAPStammdatenUpdate' => array( + 'admin' + ), + 'OEHPayment' => array( + 'admin' + ), + 'SAPPayment' => array( + 'admin' + ) +); diff --git a/application/config/navigation.php b/application/config/navigation.php index 9253c87a1..f44b297a5 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -102,6 +102,13 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 20, 'requiredPermissions' => 'system/developer:r' + ), + 'jobsqueueviewer' => array( + 'link' => site_url('system/jq/JobsQueueViewer'), + 'description' => 'Jobs Queue Viewer', + 'expand' => true, + 'sort' => 20, + 'requiredPermissions' => 'system/developer:r' ) ) ) diff --git a/application/controllers/system/JobsQueueMonitor.php b/application/controllers/system/JobsQueueMonitor.php deleted file mode 100644 index affb59bef..000000000 --- a/application/controllers/system/JobsQueueMonitor.php +++ /dev/null @@ -1,56 +0,0 @@ - 'monitoring:r', - 'getJobsByStatus' => 'monitoring:r', - 'getJobsByCreationTime' => 'monitoring:r' - ) - ); - - // Loads JobsQueueLib - $this->load->library('JobsQueueLib'); - } - - /** - * - */ - public function getJobsByType() - { - $jobType = $this->input->get(JobsQueueLib::PARAM_JOB_TYPE); - - $this->outputJson($this->jobsqueuelib->getJobsByType($jobType)); - } - - /** - * - */ - public function getJobsByStatus() - { - $jobStatus = $this->input->get(JobsQueueLib::PARAM_JOB_STATUS); - - $this->outputJson($this->jobsqueuelib->getJobsByStatus($jobStatus)); - } - - /** - * - */ - public function getJobsByCreationTime() - { - $jobCreationTime = $this->input->get(JobsQueueLib::PARAM_JOB_CREATION_TIME); - - $this->outputJson($this->jobsqueuelib->getJobsByCreationTime($jobCreationTime)); - } -} diff --git a/application/controllers/system/LogsViewer.php b/application/controllers/system/LogsViewer.php index 8caf9f3a7..4e39db5e3 100644 --- a/application/controllers/system/LogsViewer.php +++ b/application/controllers/system/LogsViewer.php @@ -35,7 +35,7 @@ class LogsViewer extends Auth_Controller // Public methods /** - * Main page of the InfoCenter tool + * Everything has a beginning */ public function index() { diff --git a/application/controllers/system/jq/JobsQueueManager.php b/application/controllers/system/jq/JobsQueueManager.php new file mode 100644 index 000000000..4e82ff44e --- /dev/null +++ b/application/controllers/system/jq/JobsQueueManager.php @@ -0,0 +1,51 @@ + 'admin:r', + 'addNewJobsToQueue' => 'admin:rw' + ) + ); + + // Loads JobsQueueLib + $this->load->library('JobsQueueLib'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * To get all the most recently added jobs using the given job type + */ + public function getLastJobs() + { + $type = $this->input->get(JobsQueueLib::PARAM_JOB_TYPE); + + $this->outputJson($this->jobsqueuelib->getLastJobs($type)); + } + + /** + * Add new jobs in the jobs queue with the given type + * jobs is an array of job objects + */ + public function addNewJobsToQueue() + { + $type = $this->input->post(JobsQueueLib::PARAM_JOB_TYPE); + $jobs = $this->input->post(JobsQueueLib::PARAM_JOBS); + + $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $jobs)); + } +} diff --git a/application/controllers/system/jq/JobsQueueViewer.php b/application/controllers/system/jq/JobsQueueViewer.php new file mode 100644 index 000000000..7e8760209 --- /dev/null +++ b/application/controllers/system/jq/JobsQueueViewer.php @@ -0,0 +1,48 @@ + '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/jq/jobsQueueViewer.php'); + } +} diff --git a/application/core/JQW_Controller.php b/application/core/JQW_Controller.php index 9cb058f6b..616eaf4fd 100644 --- a/application/core/JQW_Controller.php +++ b/application/core/JQW_Controller.php @@ -3,18 +3,22 @@ if (!defined("BASEPATH")) exit("No direct script access allowed"); /** + * Job Queue Worker * + * This controller acts as interface of the JobsQueueLib that contains all the needed functionalities to operate with + * the Jobs Queue System + * This is an abstract class that provide basic functionalities, it has to be extended to broaden its logic */ abstract class JQW_Controller extends JOB_Controller { /** - * + * Constructor */ public function __construct() { parent::__construct(); - // Loads LogLib with different ... + // Loads LogLib with different parameters $this->load->library('LogLib', array( 'classIndex' => 5, 'functionIndex' => 5, @@ -23,33 +27,36 @@ abstract class JQW_Controller extends JOB_Controller 'dbExecuteUser' => 'Jobs queue system' )); - // Loads JobsQueueLib + // Loads JobsQueueLib library $this->load->library('JobsQueueLib'); } - // ------------------------------------------------------------------------------------------------------------ - // Protected methods to read/write the jobs queue + //------------------------------------------------------------------------------------------------------------------ + // Protected methods /** - * + * To get all the most recently added jobs using the given job type */ - protected function getJobsByType($jobType) + protected function getLastJobs($type) { - $jobs = $this->jobsqueuelib->getJobsByType($jobType); + $jobs = $this->jobsqueuelib->getLastJobs($type); - if (isError($jobs)) $this->logError(getError($jobs), $jobType); + // If an error occurred then log it in database + if (isError($jobs)) $this->logError(getError($jobs), $type); return $jobs; } /** - * + * Add new jobs in the jobs queue with the given type + * jobs is an array of job objects */ - protected function addNewJobsToQueue($jobType, $jobs) + protected function addNewJobsToQueue($type, $jobs) { - $result = $this->jobsqueuelib->addNewJobsToQueue($jobType, $jobs); + $result = $this->jobsqueuelib->addNewJobsToQueue($type, $jobs); - if (isError($result)) $this->logError(getError($result), $jobType); + // If an error occurred then log it in database + if (isError($result)) $this->logError(getError($result), $type); return $result; } diff --git a/application/libraries/FilterWidgetLib.php b/application/libraries/FilterWidgetLib.php index 6e87833bd..f909c7083 100644 --- a/application/libraries/FilterWidgetLib.php +++ b/application/libraries/FilterWidgetLib.php @@ -93,6 +93,7 @@ class FilterWidgetLib const OP_NOT_SET = 'nset'; // Filter options values + const OPT_HOURS = 'hours'; const OPT_DAYS = 'days'; const OPT_MONTHS = 'months'; @@ -884,7 +885,8 @@ class FilterWidgetLib // It it's a date type if (is_numeric($filterDefinition->condition) && isset($filterDefinition->option) - && ($filterDefinition->option == self::OPT_DAYS + && ($filterDefinition->option == self::OPT_HOURS + || $filterDefinition->option == self::OPT_DAYS || $filterDefinition->option == self::OPT_MONTHS)) { $condition = '< (NOW() - \''.$filterDefinition->condition.' '.$filterDefinition->option.'\'::interval)'; @@ -899,7 +901,8 @@ class FilterWidgetLib // It it's a date type if (is_numeric($filterDefinition->condition) && isset($filterDefinition->option) - && ($filterDefinition->option == self::OPT_DAYS + && ($filterDefinition->option == self::OPT_HOURS + || $filterDefinition->option == self::OPT_DAYS || $filterDefinition->option == self::OPT_MONTHS)) { $condition = '> (NOW() - \''.$filterDefinition->condition.' '.$filterDefinition->option.'\'::interval)'; diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index 0c7e44274..fe73b40c6 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -2,27 +2,33 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); +/** + * Library that contains all the needed functionalities to operate with the Jobs Queue System + */ class JobsQueueLib { - // - const STATUS_RUNNING = 'running'; - const STATUS_NEW = 'new'; - const STATUS_DONE = 'done'; - - // - const PARAM_JOB_TYPE = 'jobType'; - const PARAM_JOB_STATUS = 'jobStatus'; - const PARAM_JOB_CREATION_TIME = 'jobCreatinTime'; - - // + // Job types + // SAP const JOB_TYPE_SAP_STAMMDATEN_UPDATE = 'SAPStammdatenUpdate'; const JOB_TYPE_SAP_PAYMENT = 'SAPPayment'; + // DVUH const JOB_TYPE_OEH_PAYMENT = 'OEHPayment'; + // Job statuses + const STATUS_NEW = 'new'; + const STATUS_RUNNING = 'running'; + const STATUS_DONE = 'done'; + const STATUS_FAILED = 'failed'; + + // Parameter names + const PARAM_JOB_TYPE = 'type'; + const PARAM_JOB_STATUS = 'status'; + const PARAM_JOBS = 'jobs'; + private $_ci; // CI instance /** - * Construct + * Constructor */ public function __construct($authenticate = true) { diff --git a/application/models/system/JobsQueue_model.php b/application/models/system/JobsQueue_model.php new file mode 100644 index 000000000..e35b45cb3 --- /dev/null +++ b/application/models/system/JobsQueue_model.php @@ -0,0 +1,15 @@ +dbTable = 'system.tbl_jobsqueue'; + $this->pk = 'jobid'; + } +} diff --git a/application/views/system/jq/jobsQueueViewer.php b/application/views/system/jq/jobsQueueViewer.php new file mode 100644 index 000000000..6d92d610b --- /dev/null +++ b/application/views/system/jq/jobsQueueViewer.php @@ -0,0 +1,47 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'Jobs Queue 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') + ) + ); +?> + + +
+ + widgetlib->widget('NavigationWidget'); ?> + +
+
+
+
+ +
+
+
+ load->view('system/jq/jobsQueueViewerData.php'); ?> +
+
+
+
+ + +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/system/jq/jobsQueueViewerData.php b/application/views/system/jq/jobsQueueViewerData.php new file mode 100644 index 000000000..be09e0baf --- /dev/null +++ b/application/views/system/jq/jobsQueueViewerData.php @@ -0,0 +1,67 @@ + ' + SELECT jq.jobid AS "JobId", + jq.creationtime AS "CreationTime", + jq.type AS "Type", + jq.status AS "Status", + jq.starttime AS "StartTime", + jq.endtime AS "EndTime", + jq.insertvon AS "UserService" + FROM system.tbl_jobsqueue jq + ORDER BY jq.creationtime DESC, jq.starttime DESC, jq.endtime DESC + ', + 'requiredPermissions' => 'admin', + 'datasetRepresentation' => 'tablesorter', + 'columnsAliases' => array( + 'Job id', + 'Creation time', + 'Type', + 'Status', + 'Start time', + 'End time', + 'User/Service' + ), + 'formatRow' => function($datasetRaw) { + + $datasetRaw->CreationTime = date_format(date_create($datasetRaw->CreationTime), 'd.m.Y H:i:s'); + $datasetRaw->StartTime = date_format(date_create($datasetRaw->StartTime), 'd.m.Y H:i:s'); + $datasetRaw->EndTime = date_format(date_create($datasetRaw->EndTime), 'd.m.Y H:i:s'); + + return $datasetRaw; + }, + 'markRow' => function($datasetRaw) { + + $mark = ''; + + if ($datasetRaw->Status == 'Failed') + { + $mark = 'text-red'; + } + + if ($datasetRaw->Status == 'Done') + { + $mark = 'text-green'; + } + + if ($datasetRaw->Status == 'Running') + { + $mark = 'text-orange'; + } + + if ($datasetRaw->Status == 'New') + { + $mark = 'text-info'; + } + + return $mark; + } + ); + + $filterWidgetArray['app'] = 'core'; + $filterWidgetArray['datasetName'] = 'jq'; + $filterWidgetArray['filter_id'] = $this->input->get('filter_id'); + + echo $this->widgetlib->widget('FilterWidget', $filterWidgetArray); +?> diff --git a/application/views/system/logs/logsViewer.php b/application/views/system/logs/logsViewer.php index 96790b479..86423006b 100644 --- a/application/views/system/logs/logsViewer.php +++ b/application/views/system/logs/logsViewer.php @@ -2,7 +2,7 @@ $this->load->view( 'templates/FHC-Header', array( - 'title' => 'Logs viewer', + 'title' => 'Logs Viewer', 'jquery' => true, 'jqueryui' => true, 'bootstrap' => true, @@ -32,7 +32,7 @@
diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 623ea7ac7..0440ee5ff 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -3842,6 +3842,134 @@ if ($result = $db->db_query("SELECT 1 FROM pg_class WHERE relname = 'unq_idx_abl } } +// Creates table system.tbl_jobstatuses if it doesn't exist and grants privileges +if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobstatuses LIMIT 1')) +{ + $qry = 'CREATE TABLE system.tbl_jobstatuses ( + status character varying NOT NULL + ); + + COMMENT ON TABLE system.tbl_jobstatuses IS \'All possible job statuses\'; + COMMENT ON COLUMN system.tbl_jobstatuses.status IS \'Job status value and primary key\'; + + ALTER TABLE ONLY system.tbl_jobstatuses ADD CONSTRAINT pk_jobstatuses PRIMARY KEY (status); + '; + + if (!$db->db_query($qry)) + echo 'system.tbl_jobstatuses: '.$db->db_last_error().'
'; + else + echo '
system.tbl_jobstatuses table created'; + + $qry = 'GRANT SELECT ON TABLE system.tbl_jobstatuses TO web;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobstatuses: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to web on system.tbl_jobstatuses'; + + $qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE system.tbl_jobstatuses TO vilesci;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobstatuses: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_jobstatuses'; +} + +// Creates table system.tbl_jobtypes if it doesn't exist and grants privileges +if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobtypes LIMIT 1')) +{ + $qry = 'CREATE TABLE system.tbl_jobtypes ( + type character varying(256) NOT NULL, + description text NOT NULL + ); + + COMMENT ON TABLE system.tbl_jobtypes IS \'All possible job types\'; + COMMENT ON COLUMN system.tbl_jobtypes.type IS \'Job type value and primary key\'; + COMMENT ON COLUMN system.tbl_jobtypes.description IS \'Job type description\'; + + ALTER TABLE ONLY system.tbl_jobtypes ADD CONSTRAINT pk_jobtypes PRIMARY KEY (type); + '; + + if (!$db->db_query($qry)) + echo 'system.tbl_jobtypes: '.$db->db_last_error().'
'; + else + echo '
system.tbl_jobtypes table created'; + + $qry = 'GRANT SELECT ON TABLE system.tbl_jobtypes TO web;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobtypes: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to web on system.tbl_jobtypes'; + + $qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE system.tbl_jobtypes TO vilesci;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobtypes: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_jobtypes'; +} + +// Creates table system.tbl_jobsqueue if it doesn't exist and grants privileges +if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobsqueue LIMIT 1')) +{ + $qry = 'CREATE TABLE system.tbl_jobsqueue ( + jobid integer NOT NULL, + type character varying(256) NOT NULL, + creationtime timestamp without time zone DEFAULT now(), + status character varying(64) NOT NULL, + input jsonb, + output jsonb, + starttime timestamp without time zone, + endtime timestamp without time zone, + insertvon character varying(32), + insertamum timestamp without time zone DEFAULT now() + ); + + COMMENT ON TABLE system.tbl_jobsqueue IS \'Table to schedule/manage the jobs queue\'; + COMMENT ON COLUMN system.tbl_jobsqueue.jobid IS \'Primary key\'; + COMMENT ON COLUMN system.tbl_jobsqueue.type IS \'Job type\'; + COMMENT ON COLUMN system.tbl_jobsqueue.creationtime IS \'Job creation timestamp\'; + COMMENT ON COLUMN system.tbl_jobsqueue.status IS \'Job current status\'; + COMMENT ON COLUMN system.tbl_jobsqueue.input IS \'Job input in JSON format\'; + COMMENT ON COLUMN system.tbl_jobsqueue.output IS \'Job output in JSON format\'; + COMMENT ON COLUMN system.tbl_jobsqueue.starttime IS \'Job start timestamp\'; + COMMENT ON COLUMN system.tbl_jobsqueue.endtime IS \'Job end timestamp\'; + COMMENT ON COLUMN system.tbl_jobsqueue.insertvon IS \'User/Service who/that inserted this record\'; + COMMENT ON COLUMN system.tbl_jobsqueue.insertamum IS \'Record insert time stamp\'; + + CREATE SEQUENCE system.seq_jobsqueue_jobid + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + ALTER SEQUENCE system.seq_jobsqueue_jobid OWNED BY system.tbl_jobsqueue.jobid; + + ALTER TABLE ONLY system.tbl_jobsqueue ALTER COLUMN jobid SET DEFAULT nextval(\'system.seq_jobsqueue_jobid\'::regclass); + + ALTER TABLE ONLY system.tbl_jobsqueue ADD CONSTRAINT pk_jobsqueue PRIMARY KEY (jobid); + + ALTER TABLE ONLY system.tbl_jobsqueue ADD CONSTRAINT fk_jobsqueue_status FOREIGN KEY (status) REFERENCES system.tbl_jobstatuses(status) ON UPDATE CASCADE ON DELETE RESTRICT; + + ALTER TABLE ONLY system.tbl_jobsqueue ADD CONSTRAINT fk_jobsqueue_type FOREIGN KEY (type) REFERENCES system.tbl_jobtypes(type) ON UPDATE CASCADE ON DELETE RESTRICT; + '; + + if (!$db->db_query($qry)) + echo 'system.tbl_jobsqueue: '.$db->db_last_error().'
'; + else + echo '
system.tbl_jobsqueue table created'; + + $qry = 'GRANT SELECT ON TABLE system.tbl_jobsqueue TO web;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobsqueue: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to web on system.tbl_jobsqueue'; + + $qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE system.tbl_jobsqueue TO vilesci;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobsqueue: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_jobsqueue'; +} + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -4100,6 +4228,9 @@ $tabellen=array( "system.tbl_log" => array("log_id","person_id","zeitpunkt","app","oe_kurzbz","logtype_kurzbz","logdata","insertvon","taetigkeit_kurzbz"), "system.tbl_logtype" => array("logtype_kurzbz", "data_schema"), "system.tbl_filters" => array("filter_id","app","dataset_name","filter_kurzbz","person_id","description","sort","default_filter","filter","oe_kurzbz","statistik_kurzbz"), + "system.tbl_jobsqueue" => array("jobid", "type", "creationtime", "status", "input", "output", "starttime", "endtime", "insertvon", "insertamum"), + "system.tbl_jobstatuses" => array("status"), + "system.tbl_jobtypes" => array("type", "description"), "system.tbl_phrase" => array("phrase_id","app","phrase","insertamum","insertvon","category"), "system.tbl_phrasentext" => array("phrasentext_id","phrase_id","sprache","orgeinheit_kurzbz","orgform_kurzbz","text","description","insertamum","insertvon"), "system.tbl_rolle" => array("rolle_kurzbz","beschreibung"), diff --git a/system/filtersupdate.php b/system/filtersupdate.php index d05a39aab..9c648a572 100644 --- a/system/filtersupdate.php +++ b/system/filtersupdate.php @@ -631,6 +631,37 @@ $filters = array( } ', 'oe_kurzbz' => null, + ), + array( + 'app' => 'core', + 'dataset_name' => 'jq', + 'filter_kurzbz' => 'lastHour', + 'description' => '{Last hour queued jobs}', + 'sort' => 1, + 'default_filter' => true, + 'filter' => ' + { + "name": "All jobs queued in the last hour", + "columns": [ + {"name": "JobId"}, + {"name": "CreationTime"}, + {"name": "Type"}, + {"name": "Status"}, + {"name": "StartTime"}, + {"name": "EndTime"}, + {"name": "UserService"} + ], + "filters": [ + { + "name": "CreationTime", + "operation": "lt", + "condition": "1", + "option": "hours" + } + ] + } + ', + 'oe_kurzbz' => null, ) ); From 3bfe1cdeea79322d4d0c4b52264d24ddd2307250 Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 5 Mar 2020 18:48:26 +0100 Subject: [PATCH 018/265] - Fixed messages and comments in PermissionLib - JobsQueueManager->addNewJobsToQueue now checks permission to write new jobs in the queue - Added statuses for system.tbl_jobstatuses in system/dbupdate_3.3.php - Added permission access type (read/write) in configuration file application/config/jqm.php --- application/config/jqm.php | 13 +++++-------- .../system/jq/JobsQueueManager.php | 19 +++++++++++++++++-- application/libraries/PermissionLib.php | 6 +++--- system/dbupdate_3.3.php | 5 +++++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/application/config/jqm.php b/application/config/jqm.php index 579fc6987..77d9bb35d 100644 --- a/application/config/jqm.php +++ b/application/config/jqm.php @@ -2,15 +2,12 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); -// White list of permissions that are able to store a spcific job type in database +// White list of permissions (write mode have to be set) that are able to store a specific job type in database $config['job_type_permissions_white_list'] = array( 'SAPStammdatenUpdate' => array( - 'admin' + 'admin:rw', + 'developer:rw' ), - 'OEHPayment' => array( - 'admin' - ), - 'SAPPayment' => array( - 'admin' - ) + 'OEHPayment' => 'developer:rw', + 'SAPPayment' => 'developer:rw' ); diff --git a/application/controllers/system/jq/JobsQueueManager.php b/application/controllers/system/jq/JobsQueueManager.php index 4e82ff44e..9275fa845 100644 --- a/application/controllers/system/jq/JobsQueueManager.php +++ b/application/controllers/system/jq/JobsQueueManager.php @@ -8,6 +8,9 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); */ class JobsQueueManager extends Auth_Controller { + // Config entry name for White list of permissions... + const JOB_TYPE_PERMISSIONS_WHITE_LIST = 'job_type_permissions_white_list'; + /** * Constructor */ @@ -15,7 +18,7 @@ class JobsQueueManager extends Auth_Controller { parent::__construct( array( - 'getJobsByType' => 'admin:r', + 'getLastJobs' => 'admin:r', 'addNewJobsToQueue' => 'admin:rw' ) ); @@ -46,6 +49,18 @@ class JobsQueueManager extends Auth_Controller $type = $this->input->post(JobsQueueLib::PARAM_JOB_TYPE); $jobs = $this->input->post(JobsQueueLib::PARAM_JOBS); - $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $jobs)); + // Loads permission lib + $this->load->library('PermissionLib'); + + // Checks if the caller has the permissions to add new jobs with the given type in the queue + if (!$this->permissionlib->isEntitled($this->config->item(self::JOB_TYPE_PERMISSIONS_WHITE_LIST), $type)) + { + // Permissions NOT valid + $this->outputJsonError('You are not allowed to access to this content'); + } + else // Otherwise call JobsQueueLib library + { + $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $jobs)); + } } } diff --git a/application/libraries/PermissionLib.php b/application/libraries/PermissionLib.php index 348c8b87b..09f89abee 100644 --- a/application/libraries/PermissionLib.php +++ b/application/libraries/PermissionLib.php @@ -147,7 +147,7 @@ class PermissionLib $accessType = ''; - // Checks if the required access type is compliant with the HTTP method (GET => r, POST => w) + // Set the access type if (strpos($requiredAccessType, PermissionLib::READ_RIGHT) !== false) { $accessType = PermissionLib::SELECT_RIGHT; // S @@ -184,12 +184,12 @@ class PermissionLib } else { - show_error('The given permission array does not contain the called method or is not correctly set'); + show_error('The given permission array does not contain the given method or is not correctly set'); } } else { - show_error('You must give the permissions array as parameter to the constructor of the controller'); + show_error('The given permissions is not a valid array or it is an empty one'); } return $checkPermissions; diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 0440ee5ff..42a1b531a 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -3853,6 +3853,11 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobstatuses LIMIT 1')) COMMENT ON COLUMN system.tbl_jobstatuses.status IS \'Job status value and primary key\'; ALTER TABLE ONLY system.tbl_jobstatuses ADD CONSTRAINT pk_jobstatuses PRIMARY KEY (status); + + INSERT INTO system.tbl_jobstatuses(status) VALUES('new'); + INSERT INTO system.tbl_jobstatuses(status) VALUES('running'); + INSERT INTO system.tbl_jobstatuses(status) VALUES('done'); + INSERT INTO system.tbl_jobstatuses(status) VALUES('failed'); '; if (!$db->db_query($qry)) From ba566ab459d6e752b09636cb64fad85749c1eddf Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 6 Mar 2020 14:13:25 +0100 Subject: [PATCH 019/265] Added new models system/JobStatuses_model and system/JobTypes_model --- application/models/system/JobStatuses_model.php | 16 ++++++++++++++++ application/models/system/JobTypes_model.php | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 application/models/system/JobStatuses_model.php create mode 100644 application/models/system/JobTypes_model.php diff --git a/application/models/system/JobStatuses_model.php b/application/models/system/JobStatuses_model.php new file mode 100644 index 000000000..82d1ee31b --- /dev/null +++ b/application/models/system/JobStatuses_model.php @@ -0,0 +1,16 @@ +dbTable = 'system.tbl_jobstatuses'; + $this->pk = 'status'; + $this->hasSequence = false; + } +} diff --git a/application/models/system/JobTypes_model.php b/application/models/system/JobTypes_model.php new file mode 100644 index 000000000..1d578bcab --- /dev/null +++ b/application/models/system/JobTypes_model.php @@ -0,0 +1,16 @@ +dbTable = 'system.tbl_jobtypes'; + $this->pk = 'type'; + $this->hasSequence = false; + } +} From d2e7336f2ce6b91246a065158fcebe0783e6312e Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 6 Mar 2020 14:14:11 +0100 Subject: [PATCH 020/265] Granted permission to user fhcomplete and vilesci for sequence seq_jobsqueue_jobid --- system/dbupdate_3.3.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 42a1b531a..5bccd5e1a 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -3950,6 +3950,9 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobsqueue LIMIT 1')) ALTER TABLE ONLY system.tbl_jobsqueue ALTER COLUMN jobid SET DEFAULT nextval(\'system.seq_jobsqueue_jobid\'::regclass); + GRANT SELECT, UPDATE ON SEQUENCE system.seq_jobsqueue_jobid TO vilesci; + GRANT SELECT, UPDATE ON SEQUENCE system.seq_jobsqueue_jobid TO fhcomplete; + ALTER TABLE ONLY system.tbl_jobsqueue ADD CONSTRAINT pk_jobsqueue PRIMARY KEY (jobid); ALTER TABLE ONLY system.tbl_jobsqueue ADD CONSTRAINT fk_jobsqueue_status FOREIGN KEY (status) REFERENCES system.tbl_jobstatuses(status) ON UPDATE CASCADE ON DELETE RESTRICT; From e92880b79a76d0003968c4e82ff88aa1e9721da5 Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 6 Mar 2020 14:15:10 +0100 Subject: [PATCH 021/265] - Added new private methods _checkPermissions and _convertJobs to controller system/jq/JobsQueueManager - Added new public method updateJobsQueue to controller system/jq/JobsQueueManager - system/jq/JobsQueueManager->getLastJobs now checks permissions - Added new public method updateJobsQueue to JQW_Controller - Less redundant constansts in Library JobsQueueLib - JobsQueueLib constructor now loads models JobsQueueModel, JobTypesModel and JobStatusesModel - Added new public methods getLastJobs, addNewJobsToQueue and updateJobsQueue to JobsQueueLib - Added new private methods _checkNewJobStructure, _checkUpdateJobStructure, _checkJobType, _checkJobStatus, _inArray, _dropNotAllowedPropertiesNewJob and _dropNotAllowedPropertiesUpdateJob to --- .../system/jq/JobsQueueManager.php | 83 +++++- application/core/JQW_Controller.php | 14 + application/libraries/JobsQueueLib.php | 255 ++++++++++++++++-- 3 files changed, 324 insertions(+), 28 deletions(-) diff --git a/application/controllers/system/jq/JobsQueueManager.php b/application/controllers/system/jq/JobsQueueManager.php index 9275fa845..b6e4efe29 100644 --- a/application/controllers/system/jq/JobsQueueManager.php +++ b/application/controllers/system/jq/JobsQueueManager.php @@ -10,6 +10,8 @@ class JobsQueueManager extends Auth_Controller { // Config entry name for White list of permissions... const JOB_TYPE_PERMISSIONS_WHITE_LIST = 'job_type_permissions_white_list'; + // Parameter names + const PARAM_JOBS = 'jobs'; /** * Constructor @@ -19,12 +21,15 @@ class JobsQueueManager extends Auth_Controller parent::__construct( array( 'getLastJobs' => 'admin:r', - 'addNewJobsToQueue' => 'admin:rw' + 'addNewJobsToQueue' => 'admin:rw', + 'updateJobsQueue' => 'admin:rw' ) ); // Loads JobsQueueLib $this->load->library('JobsQueueLib'); + // Loads permission lib + $this->load->library('PermissionLib'); } //------------------------------------------------------------------------------------------------------------------ @@ -35,7 +40,9 @@ class JobsQueueManager extends Auth_Controller */ public function getLastJobs() { - $type = $this->input->get(JobsQueueLib::PARAM_JOB_TYPE); + $type = $this->input->get(JobsQueueLib::PROPERTY_TYPE); + + $this->_checkPermissions($type); $this->outputJson($this->jobsqueuelib->getLastJobs($type)); } @@ -46,21 +53,75 @@ class JobsQueueManager extends Auth_Controller */ public function addNewJobsToQueue() { - $type = $this->input->post(JobsQueueLib::PARAM_JOB_TYPE); - $jobs = $this->input->post(JobsQueueLib::PARAM_JOBS); + $type = $this->input->post(JobsQueueLib::PROPERTY_TYPE); + $jobs = $this->input->post(self::PARAM_JOBS); - // Loads permission lib - $this->load->library('PermissionLib'); + $this->_checkPermissions($type); + // Otherwise convert jobs from json to php and call JobsQueueLib library + $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $this->_convertJobs($jobs))); + } + + /** + * Add new jobs in the jobs queue with the given type + * jobs is an array of job objects + */ + public function updateJobsQueue() + { + $type = $this->input->post(JobsQueueLib::PROPERTY_TYPE); + $jobs = $this->input->post(self::PARAM_JOBS); + + $this->_checkPermissions($type); + + // Otherwise convert jobs from json to php and call JobsQueueLib library + $this->outputJson($this->jobsqueuelib->updateJobsQueue($type, $this->_convertJobs($jobs))); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * + */ + private function _checkPermissions($type) + { // Checks if the caller has the permissions to add new jobs with the given type in the queue if (!$this->permissionlib->isEntitled($this->config->item(self::JOB_TYPE_PERMISSIONS_WHITE_LIST), $type)) { // Permissions NOT valid - $this->outputJsonError('You are not allowed to access to this content'); - } - else // Otherwise call JobsQueueLib library - { - $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $jobs)); + $this->terminateWithJsonError('You are not allowed to access to this content'); } } + + /** + * + */ + private function _convertJobs($jobs) + { + if (isEmptyArray($jobs)) return null; // if not a valid array then return null + + $convertedJobsArray = array(); // returned values + + // Loops through all the provided jobs + foreach ($jobs as $job) + { + $tmpObj = json_decode($job); // Try to decode json to php + + // If decode was a success + if ($tmpObj != null) + { + $convertedJobsArray[] = $tmpObj; // then store the decoded object in the result array + } + else // otherwise + { + // Create a new object and store the error message in it + $tmpObj = new stdClass(); + $tmpObj->{JobsQueueLib::PROPERTY_ERROR} = 'A not valid json was provided'; + + $convertedJobsArray[] = $tmpObj; // store this object into the result array + } + } + + return $convertedJobsArray; + } } diff --git a/application/core/JQW_Controller.php b/application/core/JQW_Controller.php index 616eaf4fd..c6d2362e3 100644 --- a/application/core/JQW_Controller.php +++ b/application/core/JQW_Controller.php @@ -60,4 +60,18 @@ abstract class JQW_Controller extends JOB_Controller return $result; } + + /** + * Updates jobs already present in the jobs queue + * jobs is an array of job objects + */ + protected function updateJobsQueue($type, $jobs) + { + $result = $this->jobsqueuelib->updateJobsQueue($type, $jobs); + + // If an error occurred then log it in database + if (isError($result)) $this->logError(getError($result), $type); + + return $result; + } } diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index fe73b40c6..ac0e38786 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -7,23 +7,22 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); */ class JobsQueueLib { - // Job types - // SAP - const JOB_TYPE_SAP_STAMMDATEN_UPDATE = 'SAPStammdatenUpdate'; - const JOB_TYPE_SAP_PAYMENT = 'SAPPayment'; - // DVUH - const JOB_TYPE_OEH_PAYMENT = 'OEHPayment'; - // Job statuses const STATUS_NEW = 'new'; const STATUS_RUNNING = 'running'; const STATUS_DONE = 'done'; const STATUS_FAILED = 'failed'; - // Parameter names - const PARAM_JOB_TYPE = 'type'; - const PARAM_JOB_STATUS = 'status'; - const PARAM_JOBS = 'jobs'; + // Job object properties + const PROPERTY_JOBID = 'jobid'; + const PROPERTY_CREATIONTIME = 'creationtime'; + const PROPERTY_TYPE = 'type'; + const PROPERTY_STATUS = 'status'; + const PROPERTY_INPUT = 'input'; + const PROPERTY_OUTPUT = 'output'; + const PROPERTY_START_TIME = 'starttime'; + const PROPERTY_END_TIME = 'endtime'; + const PROPERTY_ERROR = 'error'; private $_ci; // CI instance @@ -34,29 +33,251 @@ class JobsQueueLib { // Gets CI instance $this->_ci =& get_instance(); + + // Loads JQM configuration + $this->_ci->config->load('jqm'); + + // Loads all needed models + $this->_ci->load->model('system/JobsQueue_model', 'JobsQueueModel'); + $this->_ci->load->model('system/JobTypes_model', 'JobTypesModel'); + $this->_ci->load->model('system/JobStatuses_model', 'JobStatusesModel'); } //------------------------------------------------------------------------------------------------------------------ // Public methods /** - * + * To get all the most recently added jobs using the given job type */ - public function getJobsByType() + public function getLastJobs($type) { + $this->_ci->JobsQueueModel->resetQuery(); + + $this->_ci->JobsQueueModel->addOrder('creationtime', 'DESC'); + + return $this->_ci->JobsQueueModel->loadWhere(array('status' => self::STATUS_NEW, 'type' => $type)); } /** - * + * Add new jobs in the jobs queue with the given type + * jobs is an array of job objects */ - public function addNewJobsToQueue() + public function addNewJobsToQueue($type, $jobs) { + // Checks parameters + if (isEmptyString($type)) return error('The provided type parameter is not a valid string'); + if (isEmptyArray($jobs)) return error('The provided jobs parameter is not a valid array'); + + // Get all the job types + $dbResult = $this->_ci->JobTypesModel->load(); + if (isError($dbResult)) return $dbResult; + $types = getData($dbResult); + + // If the given type is not present in database + if (!$this->_checkJobType($type, $types)) return error('The provided type parameter is not valid'); + + $results = $jobs; // returned values + $errorOccurred = false; // very optimistic + + // Get all the job statuses + $dbResult = $this->_ci->JobStatusesModel->load(); + if (isError($dbResult)) return $dbResult; + $statuses = getData($dbResult); + + // Loops through all the provided jobs + foreach ($results as $job) + { + // If the structure of the job object is valid AND the type is valid AND the status is valid + if ($this->_checkNewJobStructure($job) && $this->_checkJobStatus($job, $statuses)) + { + $this->_dropNotAllowedPropertiesNewJob($job); // remove the black listed properties from this object + + $job->{self::PROPERTY_TYPE} = $type; // What you asked is what you get! + + // Try to insert the single job into database + $dbResult = $this->_ci->JobsQueueModel->insert($job); + + // If an error occurred during while inserting in database + if (isError($dbResult)) + { + $job->{self::PROPERTY_ERROR} = getError($dbResult); // retrieve the cause and store it in job object + $errorOccurred = true; // set error occurred flag + } + else // otherwise + { + $job->{self::PROPERTY_JOBID} = getData($dbResult); // get the jobid and store it in job object + } + } + else // otherwise + { + $errorOccurred = true; // set error occurred flag + } + } + + // If an error occurred then returns the results in an error object + if ($errorOccurred) return error($results); + + return success($results); // otherwise return results in a success object } /** - * + * Updates jobs already present in the jobs queue + * jobs is an array of job objects */ - public function getJobsByStatus() + public function updateJobsQueue($type, $jobs) { + // Checks parameters + if (isEmptyArray($jobs)) return error('The provided jobs parameter is not a valid array'); + + $results = $jobs; // returned values + $errorOccurred = false; // very optimistic + + // Get all the job statuses + $dbResult = $this->_ci->JobStatusesModel->load(); + if (isError($dbResult)) return $dbResult; + $statuses = getData($dbResult); + + // Loops through all the provided jobs + foreach ($results as $job) + { + // If the structure of the job object is valid + if ($this->_checkUpdateJobStructure($job) && $this->_checkJobStatus($job, $statuses)) + { + $this->_dropNotAllowedPropertiesUpdateJob($job); // remove the black listed properties from this object + + $job->{self::PROPERTY_TYPE} = $type; // What you asked is what you get! + + // Try to update the single job into database + $dbResult = $this->_ci->JobsQueueModel->update($job->{self::PROPERTY_JOBID}, (array)$job); + + // If an error occurred during while updating in database + if (isError($dbResult)) + { + $job->{self::PROPERTY_ERROR} = getError($dbResult); // retrieve the cause and store it in job object + $errorOccurred = true; // set error occurred flag + } + } + else // otherwise + { + $errorOccurred = true; // set error occurred flag + } + } + + // If an error occurred then returns the results in an error object + if ($errorOccurred) return error($results); + + return success($results); // otherwise return results in a success object + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks the job object structure when needed for insert + */ + private function _checkNewJobStructure(&$job) + { + // If job is a valid object and contains the required properties AND does NOT already contain the property error + if (is_object($job) + && property_exists($job, self::PROPERTY_STATUS) + && !property_exists($job, self::PROPERTY_ERROR)) + { + return true; // it is valid! + } + + // If not object then object it! + if (!is_object($job)) $job = new stdClass(); + + // If an error property was not already previously stored then store an error message in job object + if (!property_exists($job, self::PROPERTY_ERROR)) + { + $job->{self::PROPERTY_ERROR} = 'The structure of the provided job is not valid'; + } + + return false; // better sorry than wrong + } + + /** + * Checks the job object structure when needed for update + */ + private function _checkUpdateJobStructure(&$job) + { + // If job is a valid object + if (is_object($job) && property_exists($job, self::PROPERTY_JOBID)) return true; // it is valid! + + // If not object then object it! + if (!is_object($job)) $job = new stdClass(); + + // If an error property was not already previously stored then store an error message in job object + if (!property_exists($job, self::PROPERTY_ERROR)) + { + $job->{self::PROPERTY_ERROR} = 'The structure of the provided job is not valid'; + } + + return false; // better sorry than wrong + } + + /** + * Checks if the given job contains a valid type + */ + private function _checkJobType($type, $types) + { + return $this->_inArray($type, $types, self::PROPERTY_TYPE); + } + + /** + * Checks if the given job contains a valid status + */ + private function _checkJobStatus(&$job, $statuses) + { + $found = $this->_inArray($job->{self::PROPERTY_STATUS}, $statuses, self::PROPERTY_STATUS); + + // No status was not found and does NOT already contain the property error + if (!$found && !property_exists($job, self::PROPERTY_ERROR)) + { + $job->{self::PROPERTY_ERROR} = 'The provided status of this job is not valid'; // store the error message in the object + } + + return $found; + } + + /** + * Search in an array the given value + * The elements of the given array are objects + * The given value is compared with the property specified by the $propertyName parameter of each object of the given array + */ + private function _inArray($value, $array, $propertyName) + { + $found = false; + + foreach ($array as $element) + { + if ($value == $element->{$propertyName}) + { + $found = true; + break; + } + } + + return $found; + } + + /** + * Drop not allowed properties from the given job + */ + private function _dropNotAllowedPropertiesNewJob(&$job) + { + unset($job->{self::PROPERTY_JOBID}); + unset($job->{self::PROPERTY_CREATIONTIME}); + unset($job->{self::PROPERTY_TYPE}); + } + + /** + * Drop not allowed properties from the given job + */ + private function _dropNotAllowedPropertiesUpdateJob(&$job) + { + unset($job->{self::PROPERTY_CREATIONTIME}); + unset($job->{self::PROPERTY_TYPE}); } } From 6b0bf895928e2e4ddb26af8f8e67ff23b8f7d4c8 Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 6 Mar 2020 14:25:52 +0100 Subject: [PATCH 022/265] Removed load config loads in JobsQueueLib --- application/libraries/JobsQueueLib.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index ac0e38786..ea79e099e 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -34,9 +34,6 @@ class JobsQueueLib // Gets CI instance $this->_ci =& get_instance(); - // Loads JQM configuration - $this->_ci->config->load('jqm'); - // Loads all needed models $this->_ci->load->model('system/JobsQueue_model', 'JobsQueueModel'); $this->_ci->load->model('system/JobTypes_model', 'JobTypesModel'); From 8363f0d26c6bc76d1753310c034d4406ddce6468 Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 6 Mar 2020 14:30:52 +0100 Subject: [PATCH 023/265] Fixed marker in JobsQueueViewer --- application/controllers/system/jq/JobsQueueViewer.php | 3 +++ application/views/system/jq/jobsQueueViewerData.php | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/application/controllers/system/jq/JobsQueueViewer.php b/application/controllers/system/jq/JobsQueueViewer.php index 7e8760209..2698d79d1 100644 --- a/application/controllers/system/jq/JobsQueueViewer.php +++ b/application/controllers/system/jq/JobsQueueViewer.php @@ -25,6 +25,9 @@ class JobsQueueViewer extends Auth_Controller // Loads WidgetLib $this->load->library('WidgetLib'); + // Loads JobsQueueLib + $this->load->library('JobsQueueLib'); + // Loads phrases system $this->loadPhrases( array( diff --git a/application/views/system/jq/jobsQueueViewerData.php b/application/views/system/jq/jobsQueueViewerData.php index be09e0baf..023ec5406 100644 --- a/application/views/system/jq/jobsQueueViewerData.php +++ b/application/views/system/jq/jobsQueueViewerData.php @@ -35,22 +35,22 @@ $mark = ''; - if ($datasetRaw->Status == 'Failed') + if ($datasetRaw->Status == JobsQueueLib::STATUS_FAILED) { $mark = 'text-red'; } - if ($datasetRaw->Status == 'Done') + if ($datasetRaw->Status == JobsQueueLib::STATUS_DONE) { $mark = 'text-green'; } - if ($datasetRaw->Status == 'Running') + if ($datasetRaw->Status == JobsQueueLib::STATUS_RUNNING) { $mark = 'text-orange'; } - if ($datasetRaw->Status == 'New') + if ($datasetRaw->Status == JobsQueueLib::STATUS_NEW) { $mark = 'text-info'; } From 4d1dbdfae98b4a51fd22613bbcf6cb7dcad0154a Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 12 Mar 2020 18:51:26 +0100 Subject: [PATCH 024/265] - Added new model system/JobTriggers_model - Loads jqm configuration in controller system/jq/JobsQueueManager - Added new table system.tbl_jobtriggers to system/dbupdate_3.3.php - Added new privacy method _addNewTriggeredJobToQueue to JobsQueueLib - JobsQueueLib is called by addNewJobsToQueue and updateJobsQueue --- .../system/jq/JobsQueueManager.php | 3 + application/libraries/JobsQueueLib.php | 64 +++++++++++++++++-- .../models/system/JobTriggers_model.php | 32 ++++++++++ system/dbupdate_3.3.php | 56 ++++++++++++++-- 4 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 application/models/system/JobTriggers_model.php diff --git a/application/controllers/system/jq/JobsQueueManager.php b/application/controllers/system/jq/JobsQueueManager.php index b6e4efe29..e72607675 100644 --- a/application/controllers/system/jq/JobsQueueManager.php +++ b/application/controllers/system/jq/JobsQueueManager.php @@ -26,6 +26,9 @@ class JobsQueueManager extends Auth_Controller ) ); + // Loading config file jqm + $this->config->load('jqm'); + // Loads JobsQueueLib $this->load->library('JobsQueueLib'); // Loads permission lib diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index ea79e099e..9aafc808d 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -38,6 +38,7 @@ class JobsQueueLib $this->_ci->load->model('system/JobsQueue_model', 'JobsQueueModel'); $this->_ci->load->model('system/JobTypes_model', 'JobTypesModel'); $this->_ci->load->model('system/JobStatuses_model', 'JobStatusesModel'); + $this->_ci->load->model('system/JobTriggers_model', 'JobTriggersModel'); } //------------------------------------------------------------------------------------------------------------------ @@ -92,17 +93,21 @@ class JobsQueueLib $job->{self::PROPERTY_TYPE} = $type; // What you asked is what you get! // Try to insert the single job into database - $dbResult = $this->_ci->JobsQueueModel->insert($job); + $dbNewJobResult = $this->_ci->JobsQueueModel->insert($job); // If an error occurred during while inserting in database - if (isError($dbResult)) + if (isError($dbNewJobResult)) { - $job->{self::PROPERTY_ERROR} = getError($dbResult); // retrieve the cause and store it in job object + $job->{self::PROPERTY_ERROR} = getError($dbNewJobResult); // retrieve the cause and store it in job object $errorOccurred = true; // set error occurred flag } else // otherwise { - $job->{self::PROPERTY_JOBID} = getData($dbResult); // get the jobid and store it in job object + $job->{self::PROPERTY_JOBID} = getData($dbNewJobResult); // get the jobid and store it in job object + + $dbNewTriggeredJobResult = $this->_addNewTriggeredJobToQueue($type, $job, array(self::STATUS_NEW)); + // If an error occurred during while inserting in database + if (isError($dbNewTriggeredJobResult)) return $dbNewTriggeredJobResult; } } else // otherwise @@ -137,6 +142,8 @@ class JobsQueueLib // Loops through all the provided jobs foreach ($results as $job) { + // TODO: find if present in database or not!!! + // If the structure of the job object is valid if ($this->_checkUpdateJobStructure($job) && $this->_checkJobStatus($job, $statuses)) { @@ -153,6 +160,16 @@ class JobsQueueLib $job->{self::PROPERTY_ERROR} = getError($dbResult); // retrieve the cause and store it in job object $errorOccurred = true; // set error occurred flag } + else // otherwise + { + $dbNewTriggeredJobResult = $this->_addNewTriggeredJobToQueue( + $type, + $job, + array($job->status) + ); + // If an error occurred during while inserting in database + if (isError($dbNewTriggeredJobResult)) return $dbNewTriggeredJobResult; + } } else // otherwise { @@ -277,4 +294,43 @@ class JobsQueueLib unset($job->{self::PROPERTY_CREATIONTIME}); unset($job->{self::PROPERTY_TYPE}); } + + /** + * Add e new triggered job to the jobs queue + * NOTE: + * - In this method there are less checks compared to addNewJobsToQueue method because + * the new jobs that will be added are generate in this method + * - Job ids in this case are not returned, therefore the caller is not going to be informed about these new jobs + */ + private function _addNewTriggeredJobToQueue($type, $job, $triggeredStatuses) + { + // Get all the job trigggers for the given type and for the given statuses + $dbTriggersResult = $this->_ci->JobTriggersModel->getJobtriggersByTypeStatuses($type, $triggeredStatuses); + + // If an error occurred while getting job triggers from database then return it + if (isError($dbTriggersResult)) return $dbTriggersResult; + if (hasData($dbTriggersResult)) // If triggers were retrieved + { + // The output of the trigging job is the input of the trigged job + $triggeredJobInput = null; + if (isset($job->{self::PROPERTY_OUTPUT})) $triggeredJobInput = $job->{self::PROPERTY_OUTPUT}; + + // For each trigger + foreach (getData($dbTriggersResult) as $trigger) + { + $triggeredJob = array( + self::PROPERTY_TYPE => $trigger->following_type, // the new type is the one defined in tbl_jobtriggers + self::PROPERTY_STATUS => self::STATUS_NEW, // new job status is new + self::PROPERTY_INPUT => $triggeredJobInput // new job input + ); + + // Try to insert the single job into database + $dbNewJob = $this->_ci->JobsQueueModel->insert($triggeredJob); + // If an error occurred during while inserting in database + if (isError($dbNewJob)) return $dbNewJob; + } + } + + return success(); // if here then it was a success! + } } diff --git a/application/models/system/JobTriggers_model.php b/application/models/system/JobTriggers_model.php new file mode 100644 index 000000000..176b4f5b1 --- /dev/null +++ b/application/models/system/JobTriggers_model.php @@ -0,0 +1,32 @@ +dbTable = 'system.tbl_jobtriggers'; + $this->pk = array('type', 'status', 'followingType'); + $this->hasSequence = false; + } + + /** + * + */ + public function getJobtriggersByTypeStatuses($type, $triggeredStatuses) + { + $query = 'SELECT jt.type, + jt.status, + jt.following_type + FROM system.tbl_jobtriggers jt + WHERE jt.type = ? + AND jt.status IN ? + ORDER BY jt.type, jt.status'; + + return $this->execQuery($query, array($type, $triggeredStatuses)); + } +} diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 5bccd5e1a..b54b28373 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -3846,7 +3846,7 @@ if ($result = $db->db_query("SELECT 1 FROM pg_class WHERE relname = 'unq_idx_abl if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobstatuses LIMIT 1')) { $qry = 'CREATE TABLE system.tbl_jobstatuses ( - status character varying NOT NULL + status character varying(64) NOT NULL ); COMMENT ON TABLE system.tbl_jobstatuses IS \'All possible job statuses\'; @@ -3854,10 +3854,10 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobstatuses LIMIT 1')) ALTER TABLE ONLY system.tbl_jobstatuses ADD CONSTRAINT pk_jobstatuses PRIMARY KEY (status); - INSERT INTO system.tbl_jobstatuses(status) VALUES('new'); - INSERT INTO system.tbl_jobstatuses(status) VALUES('running'); - INSERT INTO system.tbl_jobstatuses(status) VALUES('done'); - INSERT INTO system.tbl_jobstatuses(status) VALUES('failed'); + INSERT INTO system.tbl_jobstatuses(status) VALUES(\'new\'); + INSERT INTO system.tbl_jobstatuses(status) VALUES(\'running\'); + INSERT INTO system.tbl_jobstatuses(status) VALUES(\'done\'); + INSERT INTO system.tbl_jobstatuses(status) VALUES(\'failed\'); '; if (!$db->db_query($qry)) @@ -3882,7 +3882,7 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobstatuses LIMIT 1')) if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobtypes LIMIT 1')) { $qry = 'CREATE TABLE system.tbl_jobtypes ( - type character varying(256) NOT NULL, + type character varying(128) NOT NULL, description text NOT NULL ); @@ -3916,7 +3916,7 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobsqueue LIMIT 1')) { $qry = 'CREATE TABLE system.tbl_jobsqueue ( jobid integer NOT NULL, - type character varying(256) NOT NULL, + type character varying(128) NOT NULL, creationtime timestamp without time zone DEFAULT now(), status character varying(64) NOT NULL, input jsonb, @@ -3978,6 +3978,47 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobsqueue LIMIT 1')) echo '
Granted privileges to vilesci on system.tbl_jobsqueue'; } +// Creates table system.tbl_jobtriggers if it doesn't exist and grants privileges +if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobtriggers LIMIT 1')) +{ + $qry = 'CREATE TABLE system.tbl_jobtriggers ( + type character varying(128) NOT NULL, + status character varying(64) NOT NULL, + following_type character varying(128) NOT NULL + ); + + COMMENT ON TABLE system.tbl_jobtriggers IS \'Table to manage the job triggers\'; + COMMENT ON COLUMN system.tbl_jobtriggers.type IS \'Job type\'; + COMMENT ON COLUMN system.tbl_jobtriggers.status IS \'Job status\'; + COMMENT ON COLUMN system.tbl_jobtriggers.following_type IS \'New job type\'; + + ALTER TABLE ONLY system.tbl_jobtriggers ADD CONSTRAINT pk_jobtriggers PRIMARY KEY (type, status, following_type); + + ALTER TABLE ONLY system.tbl_jobtriggers ADD CONSTRAINT fk_jobtriggers_status FOREIGN KEY (status) REFERENCES system.tbl_jobstatuses(status) ON UPDATE CASCADE ON DELETE RESTRICT; + + ALTER TABLE ONLY system.tbl_jobtriggers ADD CONSTRAINT fk_jobtriggers_type FOREIGN KEY (type) REFERENCES system.tbl_jobtypes(type) ON UPDATE CASCADE ON DELETE RESTRICT; + + ALTER TABLE ONLY system.tbl_jobtriggers ADD CONSTRAINT fk_jobtriggers_following_type FOREIGN KEY (following_type) REFERENCES system.tbl_jobtypes(type) ON UPDATE CASCADE ON DELETE RESTRICT; + '; + + if (!$db->db_query($qry)) + echo 'system.tbl_jobtriggers: '.$db->db_last_error().'
'; + else + echo '
system.tbl_jobtriggers table created'; + + $qry = 'GRANT SELECT ON TABLE system.tbl_jobtriggers TO web;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobtriggers: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to web on system.tbl_jobtriggers'; + + $qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE system.tbl_jobtriggers TO vilesci;'; + if (!$db->db_query($qry)) + echo 'system.tbl_jobtriggers: '.$db->db_last_error().'
'; + else + echo '
Granted privileges to vilesci on system.tbl_jobtriggers'; +} + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -4238,6 +4279,7 @@ $tabellen=array( "system.tbl_filters" => array("filter_id","app","dataset_name","filter_kurzbz","person_id","description","sort","default_filter","filter","oe_kurzbz","statistik_kurzbz"), "system.tbl_jobsqueue" => array("jobid", "type", "creationtime", "status", "input", "output", "starttime", "endtime", "insertvon", "insertamum"), "system.tbl_jobstatuses" => array("status"), + "system.tbl_jobtriggers" => array("type", "status", "following_type"), "system.tbl_jobtypes" => array("type", "description"), "system.tbl_phrase" => array("phrase_id","app","phrase","insertamum","insertvon","category"), "system.tbl_phrasentext" => array("phrasentext_id","phrase_id","sprache","orgeinheit_kurzbz","orgform_kurzbz","text","description","insertamum","insertvon"), From 0245bff11c66c962fe37a7a0ae49e9aa13fff212 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 13 Mar 2020 19:23:50 +0100 Subject: [PATCH 025/265] =?UTF-8?q?admin/edit=5Fgebiet:=20Offsetpunkte=20w?= =?UTF-8?q?erden=20aufgerundet=20statt=20kaufm=C3=A4nnisch=20gerundet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cis/testtool/admin/edit_gebiet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cis/testtool/admin/edit_gebiet.php b/cis/testtool/admin/edit_gebiet.php index 2fe6af39f..405c908cf 100644 --- a/cis/testtool/admin/edit_gebiet.php +++ b/cis/testtool/admin/edit_gebiet.php @@ -265,7 +265,7 @@ if ($gebiet_id != '') { $offsetwarnung = strlen($gebiet->errormsg) > 0 ? ' (HINWEIS: '.$gebiet->errormsg.')' : ''; - $offsethinweis = ' empfohlene Offsetpunkteanzahl: '.round($offsetpunkte).(round($offsetpunkte) != $offsetpunkte ? ' ('.$offsetpunkte.' gerundet)' : '').''; + $offsethinweis = ' empfohlene Offsetpunkteanzahl: '.ceil($offsetpunkte).(ceil($offsetpunkte) != $offsetpunkte ? ' ('.$offsetpunkte.' gerundet)' : '').''; $offsethinweis .= ''.$offsetwarnung.''; } echo 'Offsetpunkte (maximale Negativpunkte)'.$offsethinweis.''; From d00aec9a726e8ca43360873d2e614f9a9ddd4686 Mon Sep 17 00:00:00 2001 From: alex Date: Fri, 13 Mar 2020 19:25:25 +0100 Subject: [PATCH 026/265] =?UTF-8?q?auswertung=5Ffhtw.php:=20-=20multiselec?= =?UTF-8?q?t=20von=20Reihungstests=20m=C3=B6glich=20-=20css=20in=20public/?= =?UTF-8?q?auswertung=5Ffhtw.css=20ausgelagert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/css/tools/auswertung_fhtw.css | 178 ++++++++ vilesci/stammdaten/auswertung_fhtw.php | 598 +++++++++++++++---------- 2 files changed, 541 insertions(+), 235 deletions(-) create mode 100644 public/css/tools/auswertung_fhtw.css diff --git a/public/css/tools/auswertung_fhtw.css b/public/css/tools/auswertung_fhtw.css new file mode 100644 index 000000000..d50927ef1 --- /dev/null +++ b/public/css/tools/auswertung_fhtw.css @@ -0,0 +1,178 @@ +.info +{ + color: #0c5460; + background-color: #d1ecf1; + padding: .75rem 1.25rem; + border: 1px solid #bee5eb;; +} +.warning +{ + color: #856404; + background-color: #fff3cd; + padding: .75rem 1.25rem; + border: 1px solid #ffeeba; +} +.error +{ + color: #721c24; + background-color: #f8d7da; + padding: .75rem 1.25rem; + border: 1px solid #f5c6cb; +} +.loaderIcon +{ + border: 8px solid #f3f3f3; /* Light grey */ + border-top: 8px solid #3498db; /* Blue */ + border-radius: 50%; + width: 30px; + height: 30px; + animation: spin 2s linear infinite; + margin-right: auto; + margin-left: auto; +} +@keyframes spin +{ + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} +.alert > .btn +{ + padding: 0 6px; +} +/*** Bootstrap popover ***/ +#popover-target label +{ + margin: 0 5px; + display: block; +} +#popover-target input +{ + margin-right: 5px; +} +#popover-target .disabled +{ + color: #ddd; +} +.glyphicon-remove +{ + font-size: 150%; + margin: -5px 0; + top: 4px; +} +.ui-autocomplete-loading +{ + background: white url("../../../skin/images/spinner.gif") right 5px center no-repeat; +} + +#paramstbl +{ + margin-bottom: 0; +} + +#rtwaehlen +{ + white-space: nowrap; + padding: 10px; +} + +.rtchkbox +{ + float: left; +} + +.rtchkboxlabel:hover +{ + color: white; + background-color: #337ab7; + cursor: pointer; +} + +/*.rtchkbox:hover,.rtchkbox input:hover,.rtchkbox label:hover +{ + cursor: pointer; +}*/ + +.rtchkbox label +{ + font-weight: normal; +} + +#rtcheckboxes +{ + height: 100%; + width: 500px; + left: 155px; + position: absolute; + z-index: 9999999; + overflow-y: auto; + border: 1px solid; + padding: 8px; + background-color: white; + display: none +} + +#auswertencell +{ + vertical-align: middle; + padding: 0 5px; + border-right: 1px solid #ddd; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +#addpers,#toggleDelete,#checkAllResButton,#showUebertragenOptionsButton,#punkteUebertragenButton +{ + margin-left: 10px; +} + +.loaderIcon +{ + display: none; + margin-top: 10px; +} + +.hiddenEl +{ + display: none; +} + +.textcentered +{ + text-align: center; +} + +th.smallcol +{ + width: 20px; +} + +th.toggletblchkboxcol +{ + width: 30px; +} + +.rightaligned +{ + text-align: right; + padding-right: 3px; +} + +.redcolor +{ + color: red; +} + +.darkredcolor +{ + color: #c82333; +} + +.darkyellowcolor +{ + color: #e0a800; +} + +.zerovalcolor +{ + color: #C10000; +} diff --git a/vilesci/stammdaten/auswertung_fhtw.php b/vilesci/stammdaten/auswertung_fhtw.php index 88e7ef4d8..7bcb33323 100644 --- a/vilesci/stammdaten/auswertung_fhtw.php +++ b/vilesci/stammdaten/auswertung_fhtw.php @@ -102,7 +102,7 @@ if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'prestudent if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'prestudentAdd') { $search = trim((isset($_REQUEST['term']) ? $_REQUEST['term'] : '')); - $studiensemester_kurzbz = trim((isset($_REQUEST['studiensemester_kurzbz']) ? $_REQUEST['studiensemester_kurzbz'] : '')); + $studiensemester_kurzbz = (isset($_REQUEST['studiensemester_kurzbz']) ? $_REQUEST['studiensemester_kurzbz'] : ''); if (is_null($search) || $search == '') { exit(); @@ -120,11 +120,21 @@ if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'prestudent lower(vorname) like '%" . $db->db_escape(mb_strtolower($search)) . "%' OR lower(nachname || ' ' || vorname) like '%" . $db->db_escape(mb_strtolower($search)) . "%' OR lower(vorname || ' ' || nachname) like '%" . $db->db_escape(mb_strtolower($search)) . "%' OR - prestudent_id::text like '%" . $db->db_escape(mb_strtolower($search)) . "%') - AND get_rolle_prestudent(prestudent_id, " . $db->db_add_param($studiensemester_kurzbz) . ") IN ('Interessent') - ORDER BY nachname,vorname,stg - LIMIT 10 - "; + prestudent_id::text like '%" . $db->db_escape(mb_strtolower($search)) . "%')"; + $first = true; + if (is_array($studiensemester_kurzbz)) + $qry .= " AND ("; + foreach ($studiensemester_kurzbz as $stsem) { + $stsem = trim($stsem); + if (!$first) + $qry .= 'OR '; + $qry .= "get_rolle_prestudent(prestudent_id, " . $db->db_add_param($stsem) . ") IN ('Interessent')"; + } + if (is_array($studiensemester_kurzbz)) + $qry .= ")"; + $qry .= + " ORDER BY nachname,vorname,stg + LIMIT 10"; if ($result = $db->db_query($qry)) { @@ -471,63 +481,80 @@ if ($rtFreischalten) $testende = filter_input(INPUT_POST, 'testende', FILTER_VALIDATE_BOOLEAN); if ($testende) { - if (isset($_POST['reihungstest_id']) && is_numeric($_POST['reihungstest_id'])) + /*if (isset($_POST['reihungstest_ids']) && is_array($_POST['reihungstest_ids'])) { - $reihungstest = new reihungstest($_POST['reihungstest_id']); - // Alle Bachelor-Studiengänge holen, bei denen der Bewerber Interessent ist, die Bewerbung abgeschickt hat und bestätigt wurde - // Mail an alle diese Studiengänge senden + $reihungstest = new reihungstest($_POST['reihungstest_id']);*/ + // Alle Bachelor-Studiengänge holen, bei denen der Bewerber Interessent ist, die Bewerbung abgeschickt hat und bestätigt wurde + // Mail an alle diese Studiengänge senden - if (isset($_POST['prestudent_ids'])) + if (isset($_POST['prestudents'])) + { + // Array mit allen Prestudenten aufbauen + $prestudentsrt = $_POST['prestudents']; + $prestudentArray = array(); + foreach ($prestudentsrt AS $prestrt) { - // Array mit allen Prestudenten aufbauen - $prestudentArray = array(); - foreach ($_POST['prestudent_ids'] AS $prest) + $prestudent_id = $prestrt['prestudent_id']; + $reihungstest_id = $prestrt['reihungstest_id']; + $prestudentrolle = new prestudent($prestudent_id); + $reihungstest = new reihungstest($reihungstest_id); + // Wenn der letzte Status Abgewiesener ist, wird der Bewerber ignoriert + $prestudentrolle->getLastStatus($prestudent_id, $reihungstest->studiensemester_kurzbz); + if ($prestudentrolle->status_kurzbz == 'Abgewiesener') { - $prestudentrolle = new prestudent($prest); - // Wenn der letzte Status Abgewiesener ist, wird der Bewerber ignoriert - $prestudentrolle->getLastStatus($prest, $reihungstest->studiensemester_kurzbz); - if ($prestudentrolle->status_kurzbz == 'Abgewiesener') - { - continue; - } - // Letzten Interessentenstatus laden - $prestudentrolle->getLastStatus($prest, $reihungstest->studiensemester_kurzbz, 'Interessent'); - $stg = new studiengang($prestudentrolle->studiengang_kz); + continue; + } + // Letzten Interessentenstatus laden + $prestudentrolle->getLastStatus($prestudent_id, $reihungstest->studiensemester_kurzbz, 'Interessent'); + $stg = new studiengang($prestudentrolle->studiengang_kz); - if ($prestudentrolle->bewerbung_abgeschicktamum != '' - && $prestudentrolle->bestaetigtam != '' - && $prestudentrolle->bestaetigtvon != '' - && $stg->typ == 'b') - { - $prestudentArray[$prestudentrolle->studiengang_kz][$prestudentrolle->orgform_kurzbz][] = $prest; - } + if ($prestudentrolle->bewerbung_abgeschicktamum != '' + && $prestudentrolle->bestaetigtam != '' + && $prestudentrolle->bestaetigtvon != '' + && $stg->typ == 'b') + { + $prestudentArray[$reihungstest_id][$prestudentrolle->studiengang_kz][$prestudentrolle->orgform_kurzbz][] = $prestudent_id; + } - // Setzt "teilgenommen" (Zum Reihungstest angetreten) auf TRUE - $teilgenommen = new reihungstest(); - $teilgenommen->getPersonReihungstest($prestudentrolle->person_id, $_POST['reihungstest_id'], $prestudentrolle->studienplan_id); + // Setzt "teilgenommen" (Zum Reihungstest angetreten) auf TRUE + $teilgenommen = new reihungstest(); + $teilgenommen->getPersonReihungstest($prestudentrolle->person_id, $reihungstest_id, $prestudentrolle->studienplan_id); - $teilgenommen->new = false; - $teilgenommen->teilgenommen = true; - $teilgenommen->updateamum = date('Y-m-d H:i:s'); - $teilgenommen->updatevon = $user; + $teilgenommen->new = false; + $teilgenommen->teilgenommen = true; + $teilgenommen->updateamum = date('Y-m-d H:i:s'); + $teilgenommen->updatevon = $user; - if (!$teilgenommen->savePersonReihungstest()) - { - echo json_encode(array( - 'status' => 'fehler', - 'msg' => 'Fehler beim speichern der Reihungstestteilnahme: '.$teilgenommen->errormsg - )); - exit(); - } + if (!$teilgenommen->savePersonReihungstest()) + { + echo json_encode(array( + 'status' => 'fehler', + 'msg' => 'Fehler beim Speichern der Reihungstestteilnahme: '.$teilgenommen->errormsg + )); + exit(); } } + } - $sendError = false; - $empfaengerArray = array(); - foreach ($prestudentArray AS $studiengang_kz => $OrgFormPrestudent) + $sendError = false; + $empfaengerArray = array(); + $rtidArray = array(); + + foreach ($prestudentsrt as $psrt) + { + if (!in_array($psrt['reihungstest_id'], $rtidArray)) + $rtidArray[] = $psrt['reihungstest_id']; + } + + $rtidparams = http_build_query(array('reihungstest' => $rtidArray)); + + foreach ($prestudentArray AS $reihungstest_id => $studiengang) + { + foreach ($studiengang AS $studiengang_kz => $OrgFormPrestudent) { foreach ($OrgFormPrestudent AS $orgForm => $prestudent_id) { + $rtest = new reihungstest($reihungstest_id); $empfaenger = getMailEmpfaenger($studiengang_kz, null, $orgForm); //Pfuschloesung fur BIF Dual if (CAMPUS_NAME == 'FH Technikum Wien' && $studiengang_kz == 257 && $orgForm == 'DUA') @@ -561,12 +588,12 @@ if ($testende) '; - $mailtext .= 'Der Reihungstest vom ' . $datum_obj->convertISODate($reihungstest->datum) . ' um ' . $datum_obj->formatDatum($reihungstest->uhrzeit, 'H:i') . ' Uhr ist beendet.'; - $mailtext .= '
Es haben '.$anzahl.' Person(en) aus dem Studiengang '.$stg->kuerzel.'-'.$orgForm.' teilgenommen.'; - $mailtext .= '

Link zur Auswertung'; - $mailtext .= '

Link zur Pivot-Tabelle für die Priorisierung'; - $mailtext .= '

Reihung der BewerberInnen: Prio 1 innerhalb von 2 Werktagen, Prio 2 am 3. Werktag und Prio 3 am 4. Werktag'; - $mailtext .= ' + $mailtext .= 'Der Reihungstest vom '.$datum_obj->convertISODate($rtest->datum).' um '.$datum_obj->formatDatum($rtest->uhrzeit, 'H:i').' Uhr ist beendet.'; + $mailtext .= '
Es haben '.$anzahl.' Person(en) aus dem Studiengang '.$stg->kuerzel.'-'.$orgForm.' teilgenommen.'; + $mailtext .= '

Link zur Auswertung'; + $mailtext .= '

Link zur Pivot-Tabelle für die Priorisierung'; + $mailtext .= '

Reihung der BewerberInnen: Prio 1 innerhalb von 2 Werktagen, Prio 2 am 3. Werktag und Prio 3 am 4. Werktag'; + $mailtext .= ' @@ -587,8 +614,8 @@ if ($testende) $mail = new mail($empfaenger, 'no-reply', 'Reihungstest vom '.$datum_obj->convertISODate($reihungstest->datum).' um '.$datum_obj->formatDatum($reihungstest->uhrzeit, 'H:i').' beendet', 'Bitte sehen Sie sich die Nachricht in HTML Sicht an, um den Link vollständig darzustellen.'); $mail->setHTMLContent($mailtext); - $mail->addEmbeddedImage(APP_ROOT . 'skin/images/sancho/sancho_header_min_bw.jpg', 'image/jpg', 'header_image', 'sancho_header'); - $mail->addEmbeddedImage(APP_ROOT . 'skin/images/sancho/sancho_footer_min_bw.jpg', 'image/jpg', 'footer_image', 'sancho_footer'); + $mail->addEmbeddedImage(APP_ROOT.'skin/images/sancho/sancho_header_min_bw.jpg', 'image/jpg', 'header_image', 'sancho_header'); + $mail->addEmbeddedImage(APP_ROOT.'skin/images/sancho/sancho_footer_min_bw.jpg', 'image/jpg', 'footer_image', 'sancho_footer'); $mail->setBCCRecievers('kindlm@technikum-wien.at'); if (!$mail->send()) @@ -610,7 +637,8 @@ if ($testende) $empfaengerArray = array_unique($empfaengerArray); echo json_encode(array( 'status' => 'ok', - 'msg' => 'Nachricht erfolgreich verschickt an: ' . implode(',',$empfaengerArray))); + 'msg' => 'Nachricht erfolgreich verschickt an: '.implode(',', $empfaengerArray) + )); exit(); } } @@ -718,9 +746,9 @@ if (isset($_POST['method']) && $_POST['method'] == 'addPerson') $punkteUebertragen = filter_input(INPUT_POST, 'punkteUebertragen', FILTER_VALIDATE_BOOLEAN); if ($punkteUebertragen) { - if (isset($_POST['reihungstest_id']) && is_numeric($_POST['reihungstest_id'])) - { - $reihungstest = new reihungstest($_POST['reihungstest_id']); +/* if (isset($_POST['reihungstest_id']) && is_numeric($_POST['reihungstest_id'])) + {*/ + //$reihungstest = new reihungstest(/*$_POST['reihungstest_id']*/); $msg_warning = ''; $msg_error = ''; $count_success_punkte = 0; @@ -731,6 +759,7 @@ if ($punkteUebertragen) { foreach ($_POST['prestudentPunkteArr'] AS $key => $array) { + $reihungstest = new reihungstest($array['reihungstest_id']); $rtpunkte = number_format(floatval(str_replace(',', '.', $array['ergebnis'])), 4); $prestudentrolle = new prestudent($array['prestudent_id']); $prestudentrolle->getLastStatus($array['prestudent_id'], null, 'Interessent'); @@ -742,10 +771,10 @@ if ($punkteUebertragen) } // Checken, ob Person-Reihungstest-Studienplan zuteilung existiert - if ($reihungstest->checkPersonRtStudienplanExists($prestudentrolle->person_id, $_POST['reihungstest_id'], $prestudentrolle->studienplan_id)) + if ($reihungstest->checkPersonRtStudienplanExists($prestudentrolle->person_id, $array['reihungstest_id'], $prestudentrolle->studienplan_id)) { $setRTPunkte = new reihungstest(); - $setRTPunkte->getPersonReihungstest($prestudentrolle->person_id, $_POST['reihungstest_id'], $prestudentrolle->studienplan_id); + $setRTPunkte->getPersonReihungstest($prestudentrolle->person_id, $array['reihungstest_id'], $prestudentrolle->studienplan_id); // Check, ob Punkte schon befüllt sind if ($setRTPunkte->punkte == '') @@ -774,20 +803,20 @@ if ($punkteUebertragen) $setRTPunkte = new reihungstest(); $ort_kurzbz = ''; // Checken, ob schon irgendeine Raumzuteilung existiert (Check ohne Studienplan) und diese ggf. übernehmen - $setRTPunkte->getPersonReihungstest($prestudentrolle->person_id, $_POST['reihungstest_id']); + $setRTPunkte->getPersonReihungstest($prestudentrolle->person_id, $array['reihungstest_id']); if ($setRTPunkte->ort_kurzbz != '') { $ort_kurzbz = $setRTPunkte->ort_kurzbz; } $setRTPunkte = new reihungstest(); - $setRTPunkte->getPersonReihungstest($prestudentrolle->person_id, $_POST['reihungstest_id'], $prestudentrolle->studienplan_id); + $setRTPunkte->getPersonReihungstest($prestudentrolle->person_id, $array['reihungstest_id'], $prestudentrolle->studienplan_id); // Check, ob Punkte schon befüllt sind if ($setRTPunkte->punkte == '') { $setRTPunkte->new = true; $setRTPunkte->person_id = $prestudentrolle->person_id; - $setRTPunkte->reihungstest_id = $_POST['reihungstest_id']; + $setRTPunkte->reihungstest_id = $array['reihungstest_id']; $setRTPunkte->anmeldedatum = ''; $setRTPunkte->teilgenommen = true; $setRTPunkte->ort_kurzbz = $ort_kurzbz; @@ -934,7 +963,6 @@ if ($punkteUebertragen) 'msg_warning' => $msg_warning, 'msg_error' => $msg_error)); exit(); - } } function sortByField($multArray, $sortField, $desc = true) @@ -1055,14 +1083,23 @@ $orgform_kurzbz = isset($_REQUEST['orgform_kurzbz']) ? $_REQUEST['orgform_kurzbz $format = (isset($_REQUEST['format']) ? $_REQUEST['format'] : ''); $rtStudiensemester = ''; -if ($reihungstest != '' && is_numeric($reihungstest)) +if ($reihungstest != '' && (is_array($reihungstest) || is_numeric($reihungstest))) { - $reihungstestObj = new reihungstest($reihungstest); - $rtStudiensemester = $reihungstestObj->studiensemester_kurzbz; + $rtStudiensemester = array(); + + if (is_numeric($reihungstest)) + $reihungstest = array($reihungstest); + + foreach ($reihungstest as $rt_id) + { + $reihungstestObj = new reihungstest($rt_id); + if (!in_array($reihungstestObj->studiensemester_kurzbz, $rtStudiensemester)) + $rtStudiensemester[] = $reihungstestObj->studiensemester_kurzbz; + } } -elseif ($reihungstest != '' && !is_numeric($reihungstest)) +elseif ($reihungstest != '' && !is_array($reihungstest) && !is_numeric($reihungstest)) { - die('ReihungstestID ist ungueltig'); + die('ReihungstestIDs sind ungueltig'); } if ($studiengang != '' && is_numeric($studiengang)) { @@ -1116,7 +1153,7 @@ $sql_query = "SELECT * FROM public.tbl_reihungstest WHERE date_part('year',datum // Wenn Reihungstest ID gesetzt ist, diesen Test zusaetzlich laden, um auch jene außerhalbs des Datumszeitraums zu erwischen if ($reihungstest != '') { - $sql_query .= "UNION SELECT * FROM public.tbl_reihungstest WHERE reihungstest_id=" . $db->db_add_param($reihungstest, FHC_INTEGER); + $sql_query .= "UNION SELECT * FROM public.tbl_reihungstest WHERE reihungstest_id IN (" . $db->implode4SQL($reihungstest) . ")"; } $sql_query .= " ORDER BY datum,uhrzeit"; @@ -1171,7 +1208,7 @@ if (isset($_REQUEST['reihungstest'])) AND NOT (testtool.tbl_ablauf.gebiet_id IN ( SELECT testtool.tbl_kategorie.gebiet_id FROM testtool.tbl_kategorie))"; if ($reihungstest != '') { - $query .= " AND rt_id = " . $db->db_add_param($reihungstest, FHC_INTEGER); + $query .= " AND rt_id IN (" . $db->implode4SQL($reihungstest) . ")"; } if ($studiengang != '') { @@ -1343,7 +1380,8 @@ if (isset($_REQUEST['reihungstest'])) AND testtool.tbl_frage.gebiet_id = tbl_gebiet.gebiet_id ) END AS punkte, - tbl_gebiet.gebiet_id, + rt.reihungstest_id, + tbl_gebiet.gebiet_id, tbl_gebiet.bezeichnung AS gebiet, tbl_pruefling.idnachweis, tbl_pruefling.registriert, @@ -1399,7 +1437,7 @@ if (isset($_REQUEST['reihungstest'])) "; if ($reihungstest != '') { - $query .= " AND rt_id = " . $db->db_add_param($reihungstest, FHC_INTEGER); + $query .= " AND rt_id IN (" . $db->implode4SQL($reihungstest) . ")"; } if ($studiengang != '') { @@ -1451,6 +1489,7 @@ if (isset($_REQUEST['reihungstest'])) $ergebnis[$row->prestudent_id]->prestudent_id = $row->prestudent_id; $ergebnis[$row->prestudent_id]->person_id = $row->person_id; + $ergebnis[$row->prestudent_id]->reihungstest_id = $row->reihungstest_id; //$ergebnis[$row->prestudent_id]->pruefling_id = $row->pruefling_id; $ergebnis[$row->prestudent_id]->nachname = $row->nachname; $ergebnis[$row->prestudent_id]->vorname = $row->vorname; @@ -1598,7 +1637,32 @@ if (isset($_REQUEST['format']) && $_REQUEST['format'] == 'xls') $workbook = new Spreadsheet_Excel_Writer(); // sending HTTP headers - $workbook->send("Auswertung " . ((isset ($_REQUEST['reihungstest']) && $_REQUEST['reihungstest'] != '') ? $stg_arr[$rtest[$reihungstest]->studiengang_kz] . " " . $datum_obj->formatDatum($rtest[$reihungstest]->datum, 'd.m.Y') : 'aller Reihungstests') . ".xls"); + $stgstr = ''; + if ((isset ($_REQUEST['reihungstest']) && $_REQUEST['reihungstest'] != '')) + { + $rtdates = array(); + foreach ($reihungstest as $index => $rt_id) + { + $rtdate = $datum_obj->formatDatum($rtest[$rt_id]->datum, 'd.m.Y'); + if (!isset($rtdates[$rtdate])) + $rtdates[$rtdate] = array(); + + $rtdates[$rtdate][] = $stg_arr[$rtest[$rt_id]->studiengang_kz]; + /*$stgstr .= " " . $stg_arr[$rtest[$rt_id]->studiengang_kz]; + if (isset($reihungstest[$index + 1]) && $reihungstest[$index + 1] !== ) + $stgstr .= ' ' . $rtdate; + *//*if (!in_array($rtdate, $rtdates)) + $rtdates[] = $rtdate;*//*. " " . $datum_obj->formatDatum($rtest[$rt_id]->datum, 'd.m.Y');*/ + } + foreach ($rtdates as $rtdate => $stgs) + { + $stgstr .= " " . implode("_", $stgs) . "_" . $rtdate; + } + } + else + $stgstr = "aller Reihungstests"; + + $workbook->send("Auswertung" . $stgstr . ".xls"); $workbook->setVersion(8); $workbook->setCustomColor(15, 192, 192, 192); //Setzen der HG-Farbe Hellgrau $workbook->setCustomColor(22, 193, 0, 0); //Setzen der HG-Farbe Dunkelrot @@ -1929,6 +1993,7 @@ else + @@ -1951,11 +2016,36 @@ else - @@ -2528,12 +2592,66 @@ else
- +
- + echo '';*/ + echo ''; echo ' -
- Reihungstest wählen: - + Reihungstest wählen: '; + $selectedrtstr = ''; + $checkbxstr = ''; + $first = true; + //$maxeachline = 1; + foreach ($rtest as $rt) + { + $rtstr = $rt->datum . ' ' . $datum_obj->formatDatum($rt->uhrzeit,'H:i') . ' ' . (isset($stg_arr[$rt->studiengang_kz]) ? $stg_arr[$rt->studiengang_kz] : '') . ' ' . $rt->ort_kurzbz . ' ' . $rt->anmerkung; + + $checked = ''; + if (isset($reihungstest) && is_array($reihungstest)) + { + foreach ($reihungstest as $rttest) + { + if ($rttest === $rt->reihungstest_id) + { + $checked = ' checked'; + + if (!$first) + $selectedrtstr .= '
'; + + $selectedrtstr .= $rtstr; + $first = false; + break; + } + } + } +/* if ($rt->reihungstest_id == $reihungstest && !$select) + { + //$selected = 'selected'; + $select = true; + } + elseif ($prestudent_id == '' && $reihungstest == '' && $rt->datum == date('Y-m-d') && $datum_von == '' && $datum_bis == '' && $studiengang == '' && $semester == '' && !$select) + { + //$selected = 'selected'; + $select = true; + } + else + { + $selected = ''; + }*/ + +/* $checkbxstr .= ''; + $checkbxstr .= '

';*/ + $checkbxstr .= '
'; + $checkbxstr .= '
' . ' ' . $rtstr . '
'; + //echo '\n"; + } + + //var_dump($selectedrtstr); + $btntxt = $selectedrtstr === '' ? '-- keine Auswahl --' : $selectedrtstr; + echo ' +
'; + echo $checkbxstr; + + /*echo '
Studiengang: '; - echo 'von Datum:  '; + echo ' von Datum:  '; echo 'bis Datum: '; echo '
'; echo 'PrestudentIn: '; echo '
'; +
'; echo '

'; echo ' -
'; + &' . http_build_query(array('reihungstest' => $reihungstest)) . '"> +
'; echo '
'; + $disabledZuteilen = true; + $disabledTestende = true; + $rt_id_val = ''; if ($reihungstest != '') { - $disabled = false; - } - else - { - $disabled = true; + $disabledTestende = false; + if (count($reihungstest) == 1) + { + $rt_id_val = $reihungstest[0]; + $disabledZuteilen = false; + } } // Button um Assistenz über Testende zu informieren // Nur aktiv, wenn Reihungstest ausgewählt if ($rechte->isBerechtigtMultipleOe('lehre/reihungstestAufsicht', $berechtigteOes, 'su')) { - echo ''; + echo ''; } // Input um Personen hinzuzufügen @@ -2696,13 +2819,13 @@ else if ($rechte->isBerechtigt('lehre/reihungstestAufsicht', null, 'sui')) { echo ' -
- +
+ - + - @@ -2711,15 +2834,15 @@ else } if ($rechte->isBerechtigt('lehre/reihungstestAufsicht', null, 'suid')) { - echo ''; + echo ''; } echo '

'; echo ''; - echo ''; - echo ''; + echo ''; + echo ''; echo '
'; echo '
-

@@ -111,14 +133,15 @@ ?>
-
-
+

diff --git a/public/js/messaging/messageWrite.js b/public/js/messaging/messageWrite.js index 3a3a23792..1978fc08c 100644 --- a/public/js/messaging/messageWrite.js +++ b/public/js/messaging/messageWrite.js @@ -46,7 +46,12 @@ $(document).ready(function () { tinymce.init({ selector: "#bodyTextArea", - plugins: "autoresize" + plugins: "autoresize", + autoresize_on_init: false, + autoresize_min_height: 400, + autoresize_max_height: 400, + autoresize_bottom_margin: 10, + auto_focus: "bodyTextArea" }); tinymce.init({ From 7ab2155d6a0098b3127e353ad4ed29a85170f63c Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 27 May 2020 11:49:35 +0200 Subject: [PATCH 105/265] Added method to retrieve data of logged in user in Message model Signed-off-by: Cris --- application/models/system/Message_model.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 764c3ae14..5ebcc5ee9 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -191,4 +191,23 @@ class Message_model extends DB_Model return $this->execQuery(sprintf($query, is_array($person_id) ? 'IN' : '='), array($person_id)); } + + /** + * Get message vars for logged in user + * @param string $uid + * @return array|null + */ + public function getMsgVarsDataLoggedInUser() + { + $result = $this->db->query('SELECT * FROM public.vw_msg_vars_user WHERE uid = \''. getAuthUID(). '\''); + + if ($result) + { + return success($result->list_fields()); + } + else + { + return error($this->db->error(), FHC_DB_ERROR); + } + } } From a5e0c9ca5a89020cf0796f00bba657400a147a34 Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 27 May 2020 11:52:12 +0200 Subject: [PATCH 106/265] Added logic to provide fields of logged in user in Messaging system Signed-off-by: Cris --- application/libraries/MessageLib.php | 25 ++++++++++++++++++++++++ application/models/CL/Messages_model.php | 21 ++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/application/libraries/MessageLib.php b/application/libraries/MessageLib.php index fd2051f48..31d33eda4 100644 --- a/application/libraries/MessageLib.php +++ b/application/libraries/MessageLib.php @@ -215,6 +215,31 @@ class MessageLib return $messageVars; // otherwise returns the error } + + /** + * Retrieves message vars of the logged in user from view vw_msg_vars_user + */ + public function getMessageVarsLoggedInUser() + { + // Retrieves message vars from view vw_msg_vars + $messageVars = $this->_ci->MessageModel->getMsgVarsDataLoggedInUser(); + if (isSuccess($messageVars)) // if everything is ok + { + $variablesArray = array(); + $tmpVariablesArray = getData($messageVars); + + // Starts from 1 to skip the first element which is uid + for ($i = 1; $i < count($tmpVariablesArray); $i++) + { + $variablesArray['{my_'.str_replace(' ', '_', strtolower($tmpVariablesArray[$i])).'}'] + = 'my_'. strtoupper($tmpVariablesArray[$i]); + } + + return success($variablesArray); + } + + return $messageVars; // otherwise returns the error + } /** * Retrieves organisation units for each role that a user plays inside that organisation unit diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index 67e7ff969..2bec3dd9c 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -833,6 +833,26 @@ class Messages_model extends CI_Model $variables[] = $tmpVar; } + + // --------------------------------------------------------------------------------------- + // Retrieves message vars of logged in user from database view vw_msg_vars_person + $result = null; + + // If data contains a prestudent id + $result = $this->messagelib->getMessageVarsLoggedInUser(); + + if (isError($result)) show_error(getError($result)); + + // Then builds an array that contains objects with field name and field description of logged in user data + $user_fields = array(); + foreach (getData($result) as $id => $description) + { + $obj = new stdClass(); + $obj->id = $id; + $obj->description = $description; + + $user_fields[] = $obj; + } // --------------------------------------------------------------------------------------- // Retrieves the sender id @@ -853,6 +873,7 @@ class Messages_model extends CI_Model 'subject' => $replySubject, 'body' => $replyBody, 'variables' => $variables, + 'user_fields' => $user_fields, 'organisationUnits' => getData($organisationUnits), 'senderIsAdmin' => getData($senderIsAdmin), 'recipientsArray' => $recipientsArray, From 046994f14b667effcd07e120eaf153b3b508954e Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 27 May 2020 11:53:56 +0200 Subject: [PATCH 107/265] Added phrase 'meineFelder' Signed-off-by: Cris --- system/phrasesupdate.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 14af8e733..2672d5b91 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -6766,6 +6766,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'meineFelder', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Meine Felder', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'My fields', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); From 744cf8945a904833382d191ff2cb568f06e5ebc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Wed, 27 May 2020 12:06:52 +0200 Subject: [PATCH 108/265] =?UTF-8?q?Wartende=20Jobs=20angepasst=20damit=20T?= =?UTF-8?q?age=20als=20Parameter=20akzeptiert=20werden=20statt=20Monate=20?= =?UTF-8?q?Emfp=C3=A4nger=20korrigiert=20damit=20nur=20ein=20Infomail=20pr?= =?UTF-8?q?o=20Person=20verschickt=20wird?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/controllers/jobs/OneTimeMessages.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/controllers/jobs/OneTimeMessages.php b/application/controllers/jobs/OneTimeMessages.php index 39e0a946c..58bc1fb7c 100644 --- a/application/controllers/jobs/OneTimeMessages.php +++ b/application/controllers/jobs/OneTimeMessages.php @@ -27,11 +27,11 @@ class OneTimeMessages extends JOB_Controller * - Status set as "Wartender" * - The given study course type (b = bachelor, m = master) * - The given semester (ex WS2020) - * - How long since applicant (months) + * - How long since applicant (days) * - The given template id to be used as message subject and body (vorlage_kurzbz) * The sender of all the messages is specified by the parameter senderId (sender person_id) */ - public function sendMessageToApplicantsStillWaiting($senderId, $studyCourseType, $semester, $months, $messageTemplate) + public function sendMessageToApplicantsStillWaiting($senderId, $studyCourseType, $semester, $days, $messageTemplate) { $this->logInfo('Send message to applicants still waiting start'); @@ -47,13 +47,13 @@ class OneTimeMessages extends JOB_Controller $dbModel = new DB_Model(); $dbPrestudents = $dbModel->execReadOnlyQuery( - 'SELECT p.prestudent_id + 'SELECT distinct on(person_id) p.prestudent_id FROM public.tbl_prestudent p JOIN public.tbl_prestudentstatus ps USING (prestudent_id) JOIN public.tbl_studiengang s USING (studiengang_kz) WHERE ps.status_kurzbz = \'Wartender\' AND ps.studiensemester_kurzbz = ? - AND ps.datum <= NOW() - \''.$months.' months\'::interval + AND ps.datum <= NOW() - \''.$days.' days\'::interval AND s.typ = ? AND NOT EXISTS ( SELECT pp.person_id From 634401485a5f857842e8a08a6431e7a7f1191526 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 28 May 2020 09:42:51 +0200 Subject: [PATCH 109/265] Renamed 'Meine Felder'-msg names and small method adaptation to retrieve fields Signed-off-by: Cris --- application/libraries/MessageLib.php | 6 +++--- application/models/system/Message_model.php | 17 +++++++++++++++++ system/dbupdate_3.3.php | 10 +++++----- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/application/libraries/MessageLib.php b/application/libraries/MessageLib.php index 31d33eda4..e0622e664 100644 --- a/application/libraries/MessageLib.php +++ b/application/libraries/MessageLib.php @@ -222,7 +222,7 @@ class MessageLib public function getMessageVarsLoggedInUser() { // Retrieves message vars from view vw_msg_vars - $messageVars = $this->_ci->MessageModel->getMsgVarsDataLoggedInUser(); + $messageVars = $this->_ci->MessageModel->getMsgVarsLoggedInUser(); if (isSuccess($messageVars)) // if everything is ok { $variablesArray = array(); @@ -231,8 +231,8 @@ class MessageLib // Starts from 1 to skip the first element which is uid for ($i = 1; $i < count($tmpVariablesArray); $i++) { - $variablesArray['{my_'.str_replace(' ', '_', strtolower($tmpVariablesArray[$i])).'}'] - = 'my_'. strtoupper($tmpVariablesArray[$i]); + $variablesArray['{'.str_replace(' ', '_', strtolower($tmpVariablesArray[$i])).'}'] + = strtoupper($tmpVariablesArray[$i]); } return success($variablesArray); diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 5ebcc5ee9..0972f127f 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -171,6 +171,23 @@ class Message_model extends DB_Model return error($this->db->error(), FHC_DB_ERROR); } } + + /** + * Get message variables for logged in user + */ + public function getMsgVarsLoggedInUser() + { + $result = $this->db->query('SELECT * FROM public.vw_msg_vars_user WHERE 0 = 1'); + + if ($result) + { + return success($result->list_fields()); + } + else + { + return error($this->db->error(), FHC_DB_ERROR); + } + } /** * getMsgVarsDataByPrestudentId diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 3112bacbb..f0da8fab6 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -202,11 +202,11 @@ if(!$result = @$db->db_query("SELECT 1 FROM public.vw_msg_vars_user LIMIT 1")) $qry = ' CREATE OR REPLACE VIEW public.vw_msg_vars_user AS ( SELECT DISTINCT ON - (b.uid) b.uid, - p.vorname, - p.nachname, - b.alias, - ma.telefonklappe AS "durchwahl" + (b.uid) b.uid AS "my_uid", + p.vorname AS "my_vorname", + p.nachname AS "my_nachname", + b.alias AS "my_alias", + ma.telefonklappe AS "my_durchwahl" FROM public.tbl_person p JOIN public.tbl_benutzer b USING (person_id) JOIN public.tbl_mitarbeiter ma ON ma.mitarbeiter_uid = b.uid From 772c4fa308fd16f278a26eaec91aa71460ad16d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Thu, 28 May 2020 09:44:52 +0200 Subject: [PATCH 110/265] =?UTF-8?q?Pr=C3=BCfungsprotokoll=20=C3=9Cbersicht?= =?UTF-8?q?sliste=20f=C3=BCr=20Vorsitz=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/lehre/Pruefungsprotokoll.php | 10 ++- .../lehre/pruefungsprotokollUebersicht.php | 46 ++++++++++++ .../pruefungsprotokollUebersichtData.php | 67 +++++++++++++++++ public/js/TableWidget.js | 73 +++++++++++-------- system/phrasesupdate.php | 40 ++++++++++ 5 files changed, 206 insertions(+), 30 deletions(-) create mode 100644 application/views/lehre/pruefungsprotokollUebersicht.php create mode 100644 application/views/lehre/pruefungsprotokollUebersichtData.php diff --git a/application/controllers/lehre/Pruefungsprotokoll.php b/application/controllers/lehre/Pruefungsprotokoll.php index 9ac439fe1..0a5c13646 100644 --- a/application/controllers/lehre/Pruefungsprotokoll.php +++ b/application/controllers/lehre/Pruefungsprotokoll.php @@ -28,7 +28,10 @@ class Pruefungsprotokoll extends Auth_Controller // Load language phrases $this->loadPhrases( array( - 'abschlusspruefung' + 'abschlusspruefung', + 'global', + 'person', + 'lehre' ) ); @@ -39,6 +42,11 @@ class Pruefungsprotokoll extends Auth_Controller // ----------------------------------------------------------------------------------------------------------------- // Public methods + public function index() + { + $this->load->library('WidgetLib'); + $this->load->view('lehre/pruefungsprotokollUebersicht.php'); + } /** */ diff --git a/application/views/lehre/pruefungsprotokollUebersicht.php b/application/views/lehre/pruefungsprotokollUebersicht.php new file mode 100644 index 000000000..a827bcf5b --- /dev/null +++ b/application/views/lehre/pruefungsprotokollUebersicht.php @@ -0,0 +1,46 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'Prüfungsprotokoll', + 'jquery' => true, + 'jqueryui' => true, + 'jquerycheckboxes' => true, + 'bootstrap' => true, + 'fontawesome' => true, + 'tablesorter' => true, + 'ajaxlib' => true, + 'dialoglib' => true, + 'tablewidget' => true, + 'phrases' => array( + 'ui' => array( + 'keineDatenVorhanden', + ) + ), + 'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css'), + 'customJSs' => array('public/js/bootstrapper.js') + ) + ); +?> + + +
+
+
+
+ +
+
+ p->t('abschlusspruefung','einfuehrungstext'); ?> +
+
+ load->view('lehre/pruefungsprotokollUebersichtData.php'); ?> +
+
+
+
+ + +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/lehre/pruefungsprotokollUebersichtData.php b/application/views/lehre/pruefungsprotokollUebersichtData.php new file mode 100644 index 000000000..b2d8b9948 --- /dev/null +++ b/application/views/lehre/pruefungsprotokollUebersichtData.php @@ -0,0 +1,67 @@ +='2020-05-27' +ORDER BY datum +"; + +$filterWidgetArray = array( + 'query' => $query, + 'tableUniqueId' => 'pruefungsprotokoll', + 'requiredPermissions' => 'lehre/pruefungsbeurteilung', + 'datasetRepresentation' => 'tablesorter', + 'columnsAliases' => array( + ucfirst($this->p->t('global', 'details')), + ucfirst($this->p->t('global', 'name')), + ucfirst($this->p->t('lehre', 'studiengang')), + ucfirst($this->p->t('global', 'datum')), + ucfirst($this->p->t('global', 'status')), + ), + 'formatRow' => function($datasetRaw) { + + /* NOTE: Dont use $this here for PHP Version compatibility */ + $datasetRaw->{'abschlusspruefung_id'} = sprintf( + 'Protokoll ausfüllen', + site_url('lehre/Pruefungsprotokoll/Protokoll'), + $datasetRaw->{'abschlusspruefung_id'} + ); + + if ($datasetRaw->{'datum'} == null) + { + $datasetRaw->{'datum'} = '-'; + } + else + { + $datasetRaw->{'datum'} = date_format(date_create($datasetRaw->{'datum'}),'d.m.Y'); + } + if ($datasetRaw->{'freigabedatum'} == null) + { + $datasetRaw->{'freigabedatum'} = 'offen'; + } + else + { + $datasetRaw->{'freigabedatum'} = 'Freigegeben am: '.date_format(date_create($datasetRaw->{'freigabedatum'}),'d.m.Y'); + } + return $datasetRaw; + }, +); + +echo $this->widgetlib->widget('TableWidget', $filterWidgetArray); + +?> diff --git a/public/js/TableWidget.js b/public/js/TableWidget.js index 60dde8ccf..049959796 100644 --- a/public/js/TableWidget.js +++ b/public/js/TableWidget.js @@ -336,47 +336,62 @@ var FHC_TableWidget = { if (typeof tableWidgetDiv.find("#tableWidgetTableDataset").checkboxes === 'function') tableWidgetDiv.find("#tableWidgetTableDataset").checkboxes("range", true); } - - for (var i = 0; i < data.dataset.length; i++) + if (data.dataset.length == 0) { - var record = data.dataset[i]; - - if ($.isEmptyObject(record)) + // Display placeholder if Table is empty + var numColumns = arrayFieldsToDisplay.length; + if (data.hasOwnProperty("additionalColumns") && $.isArray(data.additionalColumns)) { - continue; + numColumns += data.additionalColumns.length; } - - var strHtml = ""; - - if (data.checkboxes != null && data.checkboxes != "") + var strHtml = ''; + strHtml += FHC_PhrasesLib.t('ui', 'keineDatenVorhanden'); + strHtml += ''; + tableWidgetDiv.find("#tableWidgetTableDataset > tbody").append(strHtml); + } + else + { + for (var i = 0; i < data.dataset.length; i++) { - strHtml += ""; - strHtml += ""; - strHtml += ""; - } + var record = data.dataset[i]; - $.each(arrayFieldsToDisplay, function(i, fieldToDisplay) { - - if (record.hasOwnProperty(data.fields[i])) + if ($.isEmptyObject(record)) { - strHtml += "" + record[data.fields[i]] + ""; + continue; } - }); - if (data.additionalColumns != null && $.isArray(data.additionalColumns)) - { - $.each(data.additionalColumns, function(i, additionalColumn) { + var strHtml = ""; - if (record.hasOwnProperty(additionalColumn)) + if (data.checkboxes != null && data.checkboxes != "") + { + strHtml += ""; + strHtml += ""; + strHtml += ""; + } + + $.each(arrayFieldsToDisplay, function(i, fieldToDisplay) { + + if (record.hasOwnProperty(data.fields[i])) { - strHtml += "" + record[additionalColumn] + ""; + strHtml += "" + record[data.fields[i]] + ""; } }); + + if (data.additionalColumns != null && $.isArray(data.additionalColumns)) + { + $.each(data.additionalColumns, function(i, additionalColumn) { + + if (record.hasOwnProperty(additionalColumn)) + { + strHtml += "" + record[additionalColumn] + ""; + } + }); + } + + strHtml += ""; + + tableWidgetDiv.find("#tableWidgetTableDataset > tbody").append(strHtml); } - - strHtml += ""; - - tableWidgetDiv.find("#tableWidgetTableDataset > tbody").append(strHtml); } } } @@ -540,7 +555,7 @@ var FHC_TableWidget = { options.columnVisibilityChanged = function(column, visible) { _func_columnVisibilityChanged(column, visible); }; - + // Renders the tabulator tableWidgetDiv.find("#tableWidgetTabulator").tabulator(options); } diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 45d4183de..78bcebad3 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -4174,6 +4174,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'global', + 'phrase' => 'status', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Status', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'global', @@ -6766,6 +6786,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'einfuehrungstext', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Hier sehen Sie alle Abschlussprüfungen zu denen Sie als Vorsitz zugeteilt sind. Klicken Sie auf den entsprechenden Link um das Prüfungsprotokoll zu erstellen.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Here you can see all the Examination where you are assigned as a chair. Select the entry to create the protocol.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'abschlusspruefung', From ebd9c2c0ba8fc1efe22f3e0933c20d165e5a8b6e Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 28 May 2020 09:46:15 +0200 Subject: [PATCH 111/265] Added method to retrieve message vars data of the logged in user This method retrieves the specific data of the logged in user to be used in 'Meine Felder' Signed-off-by: Cris --- application/models/system/Message_model.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 0972f127f..6f2a3c7ed 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -210,21 +210,13 @@ class Message_model extends DB_Model } /** - * Get message vars for logged in user - * @param string $uid + * Get message vars data for logged in user * @return array|null */ - public function getMsgVarsDataLoggedInUser() + public function getMsgVarsDataByLoggedInUser() { - $result = $this->db->query('SELECT * FROM public.vw_msg_vars_user WHERE uid = \''. getAuthUID(). '\''); + $query = 'SELECT * FROM public.vw_msg_vars_user WHERE my_uid = ?'; - if ($result) - { - return success($result->list_fields()); - } - else - { - return error($this->db->error(), FHC_DB_ERROR); - } + return $this->execQuery($query, array(getAuthUID())); } } From 4f1796ee9d969812273f1e637d9ad5ad3c657a39 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 28 May 2020 09:48:31 +0200 Subject: [PATCH 112/265] Added logic to add message vars data of logged in user into message body Signed-off-by: Cris --- application/models/CL/Messages_model.php | 39 ++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index 2bec3dd9c..d0676c5dd 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -393,7 +393,10 @@ class Messages_model extends CI_Model // Looping on receivers data foreach (getData($msgVarsData) as $receiver) { - $msgVarsDataArray = $this->_lowerReplaceSpaceArrayKeys((array)$receiver); // replaces array keys + // Merge receivers data with logged in user data + $msgVarsDataArray = $this->_addMsgVarsDataOfLoggedInUser($receiver); + + $msgVarsDataArray = $this->_lowerReplaceSpaceArrayKeys((array)getData($msgVarsDataArray)[0]); // replaces array keys $parsedSubject = parseText($subject, $msgVarsDataArray); $parsedBody = parseText($body, $msgVarsDataArray); @@ -600,6 +603,9 @@ class Messages_model extends CI_Model $parseMessageText = error('The given person_id is not a valid number'); if (is_numeric($person_id)) $parseMessageText = $this->MessageModel->getMsgVarsDataByPersonId($person_id); + + // Add message vars data of the logged in user + $parseMessageText = $this->_addMsgVarsDataOfLoggedInUser($parseMessageText); if (hasData($parseMessageText)) { @@ -623,7 +629,10 @@ class Messages_model extends CI_Model $parseMessageText = error('The given prestudent_id is not a valid number'); if (is_numeric($prestudent_id)) $parseMessageText = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id); - + + // Add message vars data of the logged in user + $parseMessageText = $this->_addMsgVarsDataOfLoggedInUser($parseMessageText); + if (hasData($parseMessageText)) { $parseMessageText = success( @@ -882,4 +891,30 @@ class Messages_model extends CI_Model 'type' => $type ); } + + /** + * Adds message vars data of the logged in user to the given object (that should also have message vars data) + * @param object $otherMsgVarsDataObj Can be success object or simple object. + * @return object Returns success object. + */ + public function _addMsgVarsDataOfLoggedInUser($otherMsgVarsDataObj) + { + // First check if param type is object + if (!is_object($otherMsgVarsDataObj)) show_error('Must pass an object to merge with data of logged in user'); + + // If it is a return object, extract the simple data object + if (isSuccess($otherMsgVarsDataObj)) + { + $otherMsgVarsDataObj = getData($otherMsgVarsDataObj)[0]; + } + + // Retrieve message vars data of the logged in user + if (!$msgVarsDataLoggedInUser = getData($this->MessageModel->getMsgVarsDataByLoggedInUser())[0]) + { + return success($otherMsgVarsDataObj); // If failed, return at least given object as expected success object + } + + return success(array((object)(array_merge((array) $otherMsgVarsDataObj, (array) $msgVarsDataLoggedInUser)))); + + } } From 2ab70b5fa1986338a0fefdd821bd8511c561298c Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Thu, 28 May 2020 10:11:54 +0200 Subject: [PATCH 113/265] Spalte sort bei lehre.tbl_abschlussbeurteilung --- system/dbupdate_3.3.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index ed0a31d0b..148757aaf 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -4171,6 +4171,17 @@ if(!$result = @$db->db_query("SELECT protokoll,endezeit,pruefungsantritt_kurzbz, echo '
lehre.tbl_abschlusspruefung: Spalten protokoll,endezeit,pruefungsantritt_kurzbz,freigabedatum hinzugefuegt'; } +// Spalte sort in lehre.tbl_abschlussbeurteilung (gibt Reihenfolge der Beurteilungen an) +if(!$result = @$db->db_query("SELECT sort FROM lehre.tbl_abschlussbeurteilung LIMIT 1;")) +{ + $qry = "ALTER TABLE lehre.tbl_abschlussbeurteilung ADD COLUMN sort smallint;"; + + if(!$db->db_query($qry)) + echo 'lehre.tbl_abschlussbeurteilung: '.$db->db_last_error().'
'; + else + echo '
lehre.tbl_abschlussbeurteilung: Spalte sort hinzugefuegt!
'; +} + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -4273,7 +4284,7 @@ $tabellen=array( "fue.tbl_ressource" => array("ressource_id","student_uid","mitarbeiter_uid","betriebsmittel_id","firma_id","bezeichnung","beschreibung","insertamum","insertvon","updateamum","updatevon"), "fue.tbl_scrumteam" => array("scrumteam_kurzbz","bezeichnung","punkteprosprint","tasksprosprint","gruppe_kurzbz"), "fue.tbl_scrumsprint" => array("scrumsprint_id","scrumteam_kurzbz","sprint_kurzbz","sprintstart","sprintende","insertamum","insertvon","updateamum","updatevon"), - "lehre.tbl_abschlussbeurteilung" => array("abschlussbeurteilung_kurzbz","bezeichnung","bezeichnung_english"), + "lehre.tbl_abschlussbeurteilung" => array("abschlussbeurteilung_kurzbz","bezeichnung","bezeichnung_english","sort"), "lehre.tbl_abschlusspruefung" => array("abschlusspruefung_id","student_uid","vorsitz","pruefer1","pruefer2","pruefer3","abschlussbeurteilung_kurzbz","akadgrad_id","pruefungstyp_kurzbz","datum","uhrzeit","sponsion","anmerkung","updateamum","updatevon","insertamum","insertvon","ext_id","note","protokoll","endezeit","pruefungsantritt_kurzbz","freigabedatum"), "lehre.tbl_abschlusspruefung_antritt" => array("pruefungsantritt_kurzbz","bezeichnung","bezeichnung_english"), "lehre.tbl_akadgrad" => array("akadgrad_id","akadgrad_kurzbz","studiengang_kz","titel","geschlecht"), From f1a346c5458c0ebc00809dc0c6470f0bdf6efd18 Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Thu, 28 May 2020 11:08:38 +0200 Subject: [PATCH 114/265] =?UTF-8?q?Pr=C3=BCfungsprotokoll:=20-=20new=20fie?= =?UTF-8?q?lds:=20beginnzeit,=20endezeit,=20Pr=C3=BCfungsantritt=20-=20Ein?= =?UTF-8?q?verst=C3=A4ndniserkl=C3=A4rung:=20if=20not=20checked=20no=20sav?= =?UTF-8?q?e=20possible=20-=20can=20be=20saved=20and=20freigegeben=20-=20a?= =?UTF-8?q?dded=20phrases?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/lehre/Pruefungsprotokoll.php | 131 ++++++++- .../education/Abschlusspruefung_model.php | 14 +- .../views/lehre/pruefungsprotokoll.php | 147 +++++++--- public/css/lehre/pruefungsprotokoll.css | 30 +- .../sbadmin2/admintemplate_contentonly.css | 3 +- public/js/bootstrapper.js | 2 +- public/js/lehre/pruefungsprotokoll.js | 135 +++++++++ system/phrasesupdate.php | 277 +++++++++++++----- 8 files changed, 612 insertions(+), 127 deletions(-) create mode 100644 public/js/lehre/pruefungsprotokoll.js diff --git a/application/controllers/lehre/Pruefungsprotokoll.php b/application/controllers/lehre/Pruefungsprotokoll.php index 0a5c13646..a88568daf 100644 --- a/application/controllers/lehre/Pruefungsprotokoll.php +++ b/application/controllers/lehre/Pruefungsprotokoll.php @@ -16,8 +16,9 @@ class Pruefungsprotokoll extends Auth_Controller // Set required permissions parent::__construct( array( - 'index' => 'lehre:r', - 'Protokoll' => 'lehre:r' + 'index' => 'lehre/pruefungsbeurteilung:r', + 'Protokoll' => 'lehre/pruefungsbeurteilung:r', + 'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw', ) ); @@ -25,12 +26,17 @@ class Pruefungsprotokoll extends Auth_Controller $this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel'); $this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel'); + $this->load->library('PermissionLib'); + $this->load->library('AuthLib'); + // Load language phrases $this->loadPhrases( array( + 'ui', + 'global', + 'person', 'abschlusspruefung', - 'global', - 'person', + 'password', 'lehre' ) ); @@ -49,6 +55,7 @@ class Pruefungsprotokoll extends Auth_Controller } /** + * Show Pruefungsprotokoll. */ public function Protokoll() { @@ -57,13 +64,18 @@ class Pruefungsprotokoll extends Auth_Controller if (!is_numeric($abschlusspruefung_id)) show_error('invalid abschlusspruefung'); - $abschlusspruefung = $this->AbschlusspruefungModel->getAbschlusspruefung($abschlusspruefung_id); + $abschlusspruefung_saved = false; + $abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id); if (isError($abschlusspruefung)) show_error(getError($abschlusspruefung)); else + { $abschlusspruefung = getData($abschlusspruefung); + $abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz); + } + $this->AbschlussbeurteilungModel->addOrder("sort", "ASC"); $this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1 WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2 WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3 @@ -80,12 +92,70 @@ class Pruefungsprotokoll extends Auth_Controller $data = array( 'abschlusspruefung' => $abschlusspruefung, - 'abschlussbeurteilung' => $abschlussbeurteilung + 'abschlussbeurteilung' => $abschlussbeurteilung, + 'abschlusspruefung_saved' => $abschlusspruefung_saved ); $this->load->view('lehre/pruefungsprotokoll.php', $data); } + /** + * Save Pruefungsprotokoll (including possible Freigabe) + */ + public function saveProtokoll() + { + $abschlusspruefung_id = $this->input->post('abschlusspruefung_id'); + $data = $this->input->post('protocoldata'); + + if (isset($abschlusspruefung_id) && is_numeric($abschlusspruefung_id) && isset($data)) + { + // check permission + $berechtigt = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id); + if (isError($berechtigt)) + $this->outputJsonError(getError($berechtigt)); + else + { + $freigabe = isset($data['freigabedatum']) && $data['freigabedatum']; + + if ($freigabe) + { + // Verify password + $password = $data['password']; + unset($data['password']); + if (!isEmptyString($password)) + { + $result = $this->authlib->checkUserAuthByUsernamePassword($this->_uid, $password); + if (isError($result)) + { + return $this->outputJsonError('Falsches Passwort'); // exit if password is incorrect + } + } + else + { + return $this->outputJsonError('Passwort fehlt'); + } + } + + $data = $this->_prepareAbschlusspruefungDataForSave($data); + $result = $this->AbschlusspruefungModel->update($abschlusspruefung_id, $data); + + if (hasData($result)) + { + $abschlusspruefung_id = getData($result); + $updateresult = array('abschlusspruefung_id' => $abschlusspruefung_id); + if ($freigabe) + $updateresult['freigabedatum'] = date_format(date_create($data['freigabedatum']), 'd.m.Y'); + + $this->outputJsonSuccess($updateresult); + } + else + $this->outputJsonError('Fehler beim Speichern des Prüfungsprotokolls'); + } + } + else + $this->outputJsonError('Ungültige Parameter'); + } + // ----------------------------------------------------------------------------------------------------------------- // Private methods @@ -98,4 +168,53 @@ class Pruefungsprotokoll extends Auth_Controller if (!$this->_uid) show_error('User authentification failed'); } + + /** + * Retrieves an Abschlussprüfung, with permission check + * permission: admin, assistance of study programe or Vorsitz of the Prüfung + * @param $abschlusspruefung_id + * @return object success or error + */ + private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id) + { + $result = error('Error when getting Abschlusspruefung'); + + if (isset($this->_uid)) + { + $abschlusspruefung = $this->AbschlusspruefungModel->getAbschlusspruefung($abschlusspruefung_id); + + if (hasData($abschlusspruefung)) + { + $abschlusspruefung_data = getData($abschlusspruefung); + if ($this->permissionlib->isBerechtigt('admin') || + (isset($abschlusspruefung_data->studiengang_kz) && $this->permissionlib->isBerechtigt('assistenz', 'suid', $abschlusspruefung_data->studiengang_kz)) + || $this->_uid === $abschlusspruefung_data->uid_vorsitz) + $result = $abschlusspruefung; + else + $result = error('Permission denied'); + } + } + + return $result; + } + + /** + * Prepares Abschlussprüfung for save in database, replaces '' with null, sets Freigabedatum + * @param $data + * @return array + */ + private function _prepareAbschlusspruefungDataForSave($data) + { + $nullfields = array('uhrzeit', 'endezeit', 'abschlussbeurteilung_kurzbz', 'protokoll'); + foreach ($data as $idx => $item) + { + if (in_array($idx, $nullfields) & $item === '') + $data[$idx] = null; + } + + if (isset($data['freigabedatum']) && $data['freigabedatum']) + $data['freigabedatum'] = date('Y-m-d'); + + return $data; + } } diff --git a/application/models/education/Abschlusspruefung_model.php b/application/models/education/Abschlusspruefung_model.php index d1649a990..2762496f9 100644 --- a/application/models/education/Abschlusspruefung_model.php +++ b/application/models/education/Abschlusspruefung_model.php @@ -26,12 +26,14 @@ class Abschlusspruefung_model extends DB_Model $abschlusspruefungdata = array(); - $this->addSelect('tbl_abschlusspruefung.datum, tbl_abschlusspruefung.abschlussbeurteilung_kurzbz, - studentpers.vorname AS vorname_student, studentpers.nachname AS nachname_student, studentpers.titelpre AS titelpre_student, studentpers.titelpost AS titelpost_student, studentben.uid AS uid_student, matrikelnr, - vorsitzenderpers.vorname AS vorname_vorsitz, vorsitzenderpers.nachname AS nachname_vorsitz, vorsitzenderpers.titelpre AS titelpre_vorsitz, vorsitzenderpers.titelpost AS titelpost_vorsitz, - erstprueferpers.vorname AS vorname_erstpruefer, erstprueferpers.nachname AS nachname_erstpruefer, erstprueferpers.titelpre AS titelpre_erstpruefer, erstprueferpers.titelpost AS titelpost_erstpruefer, - zweitprueferpers.vorname AS vorname_zweitpruefer, zweitprueferpers.nachname AS nachname_zweitpruefer, zweitprueferpers.titelpre AS titelpre_zweitpruefer, zweitprueferpers.titelpost AS titelpost_zweitpruefer - '); + $this->addSelect('tbl_abschlusspruefung.abschlusspruefung_id, tbl_abschlusspruefung.datum, tbl_abschlusspruefung.abschlussbeurteilung_kurzbz, tbl_abschlusspruefung.uhrzeit AS pruefungsbeginn, tbl_abschlusspruefung.endezeit AS pruefungsende, + tbl_abschlusspruefung.freigabedatum, tbl_abschlusspruefung_antritt.bezeichnung AS pruefungsantritt_bezeichnung, tbl_abschlusspruefung_antritt.bezeichnung_english AS pruefungsantritt_bezeichnung_english, tbl_abschlusspruefung.protokoll, + studentpers.vorname AS vorname_student, studentpers.nachname AS nachname_student, studentpers.titelpre AS titelpre_student, studentpers.titelpost AS titelpost_student, studentben.uid AS uid_student, matrikelnr, + vorsitzenderben.uid AS uid_vorsitz, vorsitzenderpers.vorname AS vorname_vorsitz, vorsitzenderpers.nachname AS nachname_vorsitz, vorsitzenderpers.titelpre AS titelpre_vorsitz, vorsitzenderpers.titelpost AS titelpost_vorsitz, + erstprueferpers.vorname AS vorname_erstpruefer, erstprueferpers.nachname AS nachname_erstpruefer, erstprueferpers.titelpre AS titelpre_erstpruefer, erstprueferpers.titelpost AS titelpost_erstpruefer, + zweitprueferpers.vorname AS vorname_zweitpruefer, zweitprueferpers.nachname AS nachname_zweitpruefer, zweitprueferpers.titelpre AS titelpre_zweitpruefer, zweitprueferpers.titelpost AS titelpost_zweitpruefer + '); + $this->addJoin('lehre.tbl_abschlusspruefung_antritt', 'pruefungsantritt_kurzbz', 'LEFT'); $this->addJoin('public.tbl_benutzer studentben', 'tbl_abschlusspruefung.student_uid = studentben.uid'); $this->addJoin('public.tbl_person studentpers', 'studentben.person_id = studentpers.person_id'); $this->addJoin('public.tbl_student', 'studentben.uid = tbl_student.student_uid'); diff --git a/application/views/lehre/pruefungsprotokoll.php b/application/views/lehre/pruefungsprotokoll.php index 4d8705510..336741891 100644 --- a/application/views/lehre/pruefungsprotokoll.php +++ b/application/views/lehre/pruefungsprotokoll.php @@ -4,17 +4,28 @@ $this->load->view( array( 'title' => 'Pruefungsprotokoll', 'jquery' => true, + 'jqueryui' => true, 'bootstrap' => true, 'fontawesome' => true, 'dialoglib' => true, 'ajaxlib' => true, 'sbadmintemplate' => true, + 'phrases' => array( + 'pruefungsprotokoll' => array( + 'freigegebenAm' + ), + 'ui' => array( + 'stunde', + 'minute' + ) + ), 'customCSSs' => array( 'public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/lehre/pruefungsprotokoll.css' ), 'customJSs' => array( - 'public/js/bootstrapper.js' + 'public/js/lehre/pruefungsprotokoll.js', + 'vendor/fgelinas/timepicker/jquery.ui.timepicker.js' ) ) ); @@ -25,8 +36,10 @@ $this->load->view(
studiengangstyp == 'b' ? 'Bachelor' : 'Master'; - $pruefung_name = $abschlusspruefung->studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'PruefungBachelor') : $this->p->t('abschlusspruefung', 'PruefungMaster'); - $arbeit_name = $abschlusspruefung->studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'ArbeitBachelor') : $this->p->t('abschlusspruefung', 'ArbeitMaster'); + $pruefung_name = $abschlusspruefung->studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'pruefungBachelor') : $this->p->t('abschlusspruefung', 'pruefungMaster'); + $arbeit_name = $abschlusspruefung->studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'arbeitBachelor') : $this->p->t('abschlusspruefung', 'arbeitMaster'); + $protokolltextvorlage = $abschlusspruefung->studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'pruefungsnotizenBachelor') : $this->p->t('abschlusspruefung', 'pruefungsnotizenMaster'); + $protokolltext = isset($abschlusspruefung->protokoll) ? $abschlusspruefung->protokoll : $protokolltextvorlage; ?>
@@ -34,8 +47,8 @@ $this->load->view( p->t('abschlusspruefung', 'Protokoll') ?> 

- studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'AbgehaltenAmBachelor') : $this->p->t('abschlusspruefung', 'AbgehaltenAmMaster'); ?> - studiengangbezeichnung?>, p->t('abschlusspruefung', 'Studiengangskennzahl') ?>  + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'abgehaltenAmBachelor') : $this->p->t('abschlusspruefung', 'abgehaltenAmMaster'); ?> + studiengangbezeichnung?>, p->t('abschlusspruefung', 'studiengangskennzahl') ?>  studiengang_kz ?>

@@ -45,95 +58,118 @@ $this->load->view(

titelpre_student . ' ' . $abschlusspruefung->vorname_student . ' ' . $abschlusspruefung->nachname_student . ' ' . $abschlusspruefung->titelpost_student?>

-

p->t('abschlusspruefung', 'Personenkennzeichen') ?>: matrikelnr ?>

+

p->t('abschlusspruefung', 'personenkennzeichen') ?>: matrikelnr ?>


- + + - - - - - - - - - - + + + + + + + + + + - - - - - @@ -146,12 +155,12 @@ $this->load->view( p->t('abschlusspruefung', 'pruefungsgegenstand') ?> @@ -172,7 +181,7 @@ $this->load->view( abschlussbeurteilung_kurzbz == $abschlusspruefung->abschlussbeurteilung_kurzbz ? " selected" : "" ?> - + diff --git a/public/css/lehre/pruefungsprotokoll.css b/public/css/lehre/pruefungsprotokoll.css index a73e67950..b5db9b0b5 100644 --- a/public/css/lehre/pruefungsprotokoll.css +++ b/public/css/lehre/pruefungsprotokoll.css @@ -1,4 +1,4 @@ -/* threshold for form full screen */ +/* threshold for full screen form */ @media (max-width:1075px) { #page-wrapper { margin-right: 0; @@ -18,6 +18,7 @@ background-color: #f5f5f5; } +/* table date and time cell widths */ .timecellwidth { width: 20%; } @@ -35,3 +36,10 @@ margin-top: 10px; margin-bottom: 10px; } + +/* timepicker */ +.ui-timepicker-table td a { + width: inherit; + line-height: 1; + text-align: center; +} diff --git a/public/js/lehre/pruefungsprotokoll.js b/public/js/lehre/pruefungsprotokoll.js index c11bc9ee7..1834737ff 100644 --- a/public/js/lehre/pruefungsprotokoll.js +++ b/public/js/lehre/pruefungsprotokoll.js @@ -16,29 +16,26 @@ $("document").ready(function() { data.password = $("#password").val(); } - if ($("#verfCheck").prop('checked')) + var checkFields = Pruefungsprotokoll.checkFields(data, $("#verfCheck").prop('checked')); + $("#protocolform td").removeClass('has-error'); + if (checkFields.length > 0) { - var checkFields = Pruefungsprotokoll.checkFields(data, $("#verfCheck").prop('checked')); - $("#protocolform td").removeClass('has-error'); - if (checkFields.length > 0) + var errortext = ''; + for (var i = 0; i < checkFields.length; i++) { - var errortext = ''; - for (var i = 0; i < checkFields.length; i++) + var error = checkFields[i]; + $.each(error, function(i, n) { - var error = checkFields[i]; - $.each(error, function(i, n) - { - console.log($("#"+i).closest('td')); - $("#"+i).closest('td').addClass('has-error'); - if (errortext !== '') - errortext += '; '; - errortext += n; - }); - } - - FHC_DialogLib.alertError(errortext); - return; + console.log($("#"+i).closest('td')); + $("#"+i).closest('td').addClass('has-error'); + if (errortext !== '') + errortext += '; '; + errortext += n; + }); } + + FHC_DialogLib.alertError(errortext); + return; } Pruefungsprotokoll.saveProtokoll($("#abschlusspruefung_id").val(),data); @@ -49,17 +46,12 @@ $("document").ready(function() { function() { // if student not mentally and physically fit (checkbox), no form entry if ($(this).prop('checked')) { - $("#abschlussbeurteilung_kurzbz, #pruefungsbeginn, #pruefungsende").prop('disabled', false); - $("#abschlussbeurteilung_kurzbz").val($("#abschlussbeurteilung_kurzbz option").first().val()); + $("#abschlussbeurteilung_kurzbz").prop('disabled', false).val($("#abschlussbeurteilung_kurzbz option").first().val()); } else { - $("#abschlussbeurteilung_kurzbz, #pruefungsbeginn, #pruefungsende").prop('disabled', true).val(null); + $("#abschlussbeurteilung_kurzbz").prop('disabled', true).val(null); } - - $("#pruefungsbeginn").val(null); - $("#pruefungsende").val(null); - } ); @@ -94,10 +86,10 @@ var Pruefungsprotokoll = { if (dataresponse.freigabedatum) { $("#saveProtocolBtn").prop("disabled", true); - $("#freigegebenText").html('  ' + FHC_PhrasesLib.t("pruefungsprotokoll", "freigegebenAm") + + $("#freigegebenText").html('  ' + FHC_PhrasesLib.t("abschlusspruefung", "freigegebenAm") + ' ' + dataresponse.freigabedatum) } - FHC_DialogLib.alertSuccess("Prüfung erfolgreich gespeichert!"); + FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("abschlusspruefung", "pruefungGespeichert")); } else if(FHC_AjaxClient.isError(data)) { @@ -105,30 +97,39 @@ var Pruefungsprotokoll = { } }, errorCallback: function() { - FHC_DialogLib.alertError("Fehler beim Speichern der Prüfung"); + FHC_DialogLib.alertError(FHC_PhrasesLib.t("abschlusspruefung", "pruefungSpeichernFehler")); }, veilTimeout: 0 } ); }, - checkFields: function(data) + checkFields: function(data, verfChecked) { var errors = []; - if (data.abschlussbeurteilung_kurzbz == "") - errors.push({"abschlussbeurteilung_kurzbz": "Abschlussbeurteilung darf nicht leer sein!"}); // TODO phrases + if (data.abschlussbeurteilung_kurzbz == "" && verfChecked) + errors.push({"abschlussbeurteilung_kurzbz": FHC_PhrasesLib.t("abschlusspruefung", "abschlussbeurteilungLeer")}); var zeitregex = /^[0-2][0-9]:[0-5][0-9]$/; if (data.uhrzeit == "") - errors.push({"pruefungsbeginn": "Beginnzeit darf nicht leer sein!"}); + { + if (verfChecked) + errors.push({"pruefungsbeginn": FHC_PhrasesLib.t("abschlusspruefung", "beginnzeitLeer")}); + } else if(!zeitregex.test(data.uhrzeit)) - errors.push({"pruefungsbeginn": "Beginnzeit muss Format Stunden:Minuten haben!"}); + errors.push({"pruefungsbeginn": FHC_PhrasesLib.t("abschlusspruefung", "beginnzeitFormatError")}); if (data.endezeit == "") - errors.push({"pruefungsende": "Endzeit darf nicht leer sein!"}); + { + if (verfChecked) + errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitLeer")}); + } else if(!zeitregex.test(data.endezeit)) - errors.push({"pruefungsende": "Endzeit muss Format Stunden:Minuten haben!"}); + errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitFormatError")}); + + if (data.uhrzeit > data.endezeit && data.endezeit != "" && data.uhrzeit != "") + errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitBeforeError")}); return errors; } diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 9e501aaf2..944f931b9 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -4174,6 +4174,46 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'password', + 'phrase' => 'wrongPassword', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Falsches Passwort', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Wrong password', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'password', + 'phrase' => 'passwordMissing', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Passwort fehlt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Password missing', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'global', @@ -5714,6 +5754,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'lehrauftrag', + 'category' => 'ui', + 'phrase' => 'ungueltigeParameter', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ungültige Parameter', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Invalid parameters', + 'description' => 'Hours', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'table', @@ -6900,7 +6960,7 @@ When on hold, the date is only a reminder.', ), array( 'sprache' => 'English', - 'text' => 'Bachelor paper', + 'text' => 'Bachelor Paper', 'description' => '', 'insertvon' => 'system' ) @@ -7220,7 +7280,7 @@ When on hold, the date is only a reminder.', ), array( 'sprache' => 'English', - 'text' => '', + 'text' => 'Declaration of Agreement', 'description' => '', 'insertvon' => 'system' ) @@ -7448,19 +7508,19 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => 'Assesment and criteria Bachelor Examination

+ 'text' => 'Assessment and criteria Bachelor Examination

  • Passed with distinction
    - Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau. + The candidate is within the scope of the task able to apply knowledge from various learning areas to new situations in a technically correct manner, far beyond what is essential, and at a very high level of argument.
  • Passed with merit
    - Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau. + The candidate is within the scope of the task able to apply knowledge from various learning areas in a technically correct manner to an extent beyond what is essential to new situations, and at a high level of argument.
  • Passed
    - Alle Lehrveranstaltungen (einschl. Bachelorarbeit) und Bachelorprüfung wurden positiv beurteilt. + Bachelor thesis and Bachelor examination were successfully completed.
  • Failed @@ -7491,7 +7551,7 @@ Any unusual occurrences
  • Bestanden
    - Alle Lehrveranstaltungen (einschl. Bachelorarbeit) und Bachelorprüfung wurden positiv beurteilt. + Alle Lehrveranstaltungen (einschl. Masterarbeit) und Masterprüfung wurden positiv beurteilt.
  • Nicht bestanden @@ -7502,24 +7562,26 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => '\'Assesment and criteria Masters Examination

    + 'text' => 'Assessment and criteria Masters Examination

    • Passed with distinction
      - Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau. + Master thesis was graded "excellent"
      + The candidate is within the scope of the task able to apply knowledge from various learning areas to new situations in a technically correct manner, far beyond what is essential, and at a very high level of argument.
    • Passed with merit
      - Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau. + Master thesis graded not worse than "good"
      + The candidate is within the scope of the task able to apply knowledge from various learning areas in a technically correct manner to an extent beyond what is essential to new situations, and at a high level of argument.
    • Passed
      - Alle Lehrveranstaltungen (einschl. Bachelorarbeit) und Bachelorprüfung wurden positiv beurteilt. + Master thesis and Master examination were successfully completed.
    • Failed
    • -
    \'', +
', 'description' => '', 'insertvon' => 'system' ) @@ -7584,6 +7646,166 @@ Any unusual occurrences 'insertvon' => 'system' ) ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'pruefungGespeichert', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prüfung erfolgreich gespeichert!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Examination successfully saved!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'pruefungSpeichernFehler', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Fehler beim Speichern der Prüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Error when saving examination', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'abschlussbeurteilungLeer', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abschlussbeurteilung darf nicht leer sein!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assessment cannot be empty!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'beginnzeitLeer', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Beginnzeit darf nicht leer sein!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Start time cannot be empty!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'endezeitLeer', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Endzeit darf nicht leer sein!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'End time cannot be empty!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'beginnzeitFormatError', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Beginnzeit muss Format Stunden:Minuten haben!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Start time must have format Hours:Minutes!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'endezeitFormatError', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Endezeit muss Format Stunden:Minuten haben!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'End time must have format Hours:Minutes!', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'endezeitBeforeError', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Endezeit darf nicht kleiner als Beginnzeit sein!', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'End time cannot be before begin time!', + 'description' => '', + 'insertvon' => 'system' + ) + ) ) ); From f03ed2f66641b00ae7bdcbfe13b9b8820ab329c7 Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Fri, 29 May 2020 10:48:00 +0200 Subject: [PATCH 118/265] =?UTF-8?q?Pr=C3=BCfungsprotokoll:=20Verfassungsch?= =?UTF-8?q?eck=20is=20not=20checked=20by=20default,=20if=20no=20grade=20fi?= =?UTF-8?q?lled=20out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/lehre/pruefungsprotokoll.php | 4 +- public/js/lehre/pruefungsprotokoll.js | 92 ++++++++++--------- 2 files changed, 53 insertions(+), 43 deletions(-) diff --git a/application/views/lehre/pruefungsprotokoll.php b/application/views/lehre/pruefungsprotokoll.php index 12024f981..42edfd57a 100644 --- a/application/views/lehre/pruefungsprotokoll.php +++ b/application/views/lehre/pruefungsprotokoll.php @@ -135,7 +135,7 @@ $this->load->view( p->t('abschlusspruefung', 'einverstaendniserklaerungName') ?> @@ -155,7 +155,7 @@ $this->load->view( p->t('abschlusspruefung', 'pruefungsgegenstand') ?> diff --git a/public/js/lehre/pruefungsprotokoll.js b/public/js/lehre/pruefungsprotokoll.js index 1834737ff..0e0715198 100644 --- a/public/js/lehre/pruefungsprotokoll.js +++ b/public/js/lehre/pruefungsprotokoll.js @@ -1,6 +1,13 @@ const CALLED_PATH = FHC_JS_DATA_STORAGE_OBJECT.called_path; $("document").ready(function() { + // if no abschlussbeurteilung is not filled out, new formular -> verfassungscheck is by default not checked. + // If abschlussbeurteilung is filled out -> already graded, verfassungscheck is checked. + Pruefungsprotokoll.abschlussbeurteilung_kurzbz = $("#abschlussbeurteilung_kurzbz").val(); + if (Pruefungsprotokoll.abschlussbeurteilung_kurzbz != '') + $("#verfCheck").prop('checked', true); + Pruefungsprotokoll.checkVerfassung(); + $("#saveProtocolBtn, #freigebenProtocolBtn").click( function() { var data = { @@ -43,16 +50,7 @@ $("document").ready(function() { ) $("#verfCheck").change( - function() { // if student not mentally and physically fit (checkbox), no form entry - if ($(this).prop('checked')) - { - $("#abschlussbeurteilung_kurzbz").prop('disabled', false).val($("#abschlussbeurteilung_kurzbz option").first().val()); - } - else - { - $("#abschlussbeurteilung_kurzbz").prop('disabled', true).val(null); - } - } + Pruefungsprotokoll.checkVerfassung ); $( ".timepicker" ).timepicker({ @@ -67,9 +65,51 @@ $("document").ready(function() { }) var Pruefungsprotokoll = { + abschlussbeurteilung_kurzbz: '', + checkVerfassung: function() + { + // if student not mentally and physically fit (checkbox), no grade can be set + if ($("#verfCheck").prop('checked')) + { + $("#abschlussbeurteilung_kurzbz").prop('disabled', false).val(Pruefungsprotokoll.abschlussbeurteilung_kurzbz); + } + else + { + $("#abschlussbeurteilung_kurzbz").prop('disabled', true).val(null); + } + }, + checkFields: function(data, verfChecked) + { + var errors = []; - // ----------------------------------------------------------------------------------------------------------------- + if (data.abschlussbeurteilung_kurzbz == "" && verfChecked) + errors.push({"abschlussbeurteilung_kurzbz": FHC_PhrasesLib.t("abschlusspruefung", "abschlussbeurteilungLeer")}); + + var zeitregex = /^[0-2][0-9]:[0-5][0-9]$/; + + if (data.uhrzeit == "") + { + if (verfChecked) + errors.push({"pruefungsbeginn": FHC_PhrasesLib.t("abschlusspruefung", "beginnzeitLeer")}); + } + else if(!zeitregex.test(data.uhrzeit)) + errors.push({"pruefungsbeginn": FHC_PhrasesLib.t("abschlusspruefung", "beginnzeitFormatError")}); + + if (data.endezeit == "") + { + if (verfChecked) + errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitLeer")}); + } + else if(!zeitregex.test(data.endezeit)) + errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitFormatError")}); + + if (data.uhrzeit > data.endezeit && data.endezeit != "" && data.uhrzeit != "") + errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitBeforeError")}); + + return errors; + }, // ajax calls + // ----------------------------------------------------------------------------------------------------------------- saveProtokoll: function(abschlusspruefung_id, data) { FHC_AjaxClient.ajaxCallPost( @@ -102,35 +142,5 @@ var Pruefungsprotokoll = { veilTimeout: 0 } ); - }, - checkFields: function(data, verfChecked) - { - var errors = []; - - if (data.abschlussbeurteilung_kurzbz == "" && verfChecked) - errors.push({"abschlussbeurteilung_kurzbz": FHC_PhrasesLib.t("abschlusspruefung", "abschlussbeurteilungLeer")}); - - var zeitregex = /^[0-2][0-9]:[0-5][0-9]$/; - - if (data.uhrzeit == "") - { - if (verfChecked) - errors.push({"pruefungsbeginn": FHC_PhrasesLib.t("abschlusspruefung", "beginnzeitLeer")}); - } - else if(!zeitregex.test(data.uhrzeit)) - errors.push({"pruefungsbeginn": FHC_PhrasesLib.t("abschlusspruefung", "beginnzeitFormatError")}); - - if (data.endezeit == "") - { - if (verfChecked) - errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitLeer")}); - } - else if(!zeitregex.test(data.endezeit)) - errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitFormatError")}); - - if (data.uhrzeit > data.endezeit && data.endezeit != "" && data.uhrzeit != "") - errors.push({"pruefungsende": FHC_PhrasesLib.t("abschlusspruefung", "endezeitBeforeError")}); - - return errors; } } From 466264befe95ae7f2fcee3469e276780dcb088be Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Fri, 29 May 2020 13:00:31 +0200 Subject: [PATCH 119/265] =?UTF-8?q?Pr=C3=BCfungsprotokoll:=20-=20changed?= =?UTF-8?q?=20phrases=20-=20added=20notice=20=20that=20grade=20cannot=20be?= =?UTF-8?q?=20set=20when=20Einverst=C3=A4ndniserkl=C3=A4rung=20is=20not=20?= =?UTF-8?q?checked?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/lehre/pruefungsprotokoll.php | 8 +- public/js/lehre/pruefungsprotokoll.js | 2 + system/phrasesupdate.php | 136 +++++++++++++----- 3 files changed, 106 insertions(+), 40 deletions(-) diff --git a/application/views/lehre/pruefungsprotokoll.php b/application/views/lehre/pruefungsprotokoll.php index 42edfd57a..7a06f3286 100644 --- a/application/views/lehre/pruefungsprotokoll.php +++ b/application/views/lehre/pruefungsprotokoll.php @@ -20,7 +20,8 @@ $this->load->view( 'beginnzeitFormatError', 'endezeitLeer', 'endezeitFormatError', - 'endezeitBeforeError' + 'endezeitBeforeError', + 'verfNotice' ), 'ui' => array( 'stunde', @@ -171,12 +172,12 @@ $this->load->view(
+ - p->t('abschlusspruefung', 'Pruefungssenat') ?> + p->t('abschlusspruefung', 'pruefungssenat') ?>
- p->t('abschlusspruefung', 'Vorsitz') ?> + p->t('abschlusspruefung', 'vorsitz') ?> + titelpre_vorsitz . ' ' . $abschlusspruefung->vorname_vorsitz . ' ' . $abschlusspruefung->nachname_vorsitz . ' ' . $abschlusspruefung->titelpost_vorsitz ?>
- p->t('abschlusspruefung', 'Erstpruefer') ?> + p->t('abschlusspruefung', 'erstpruefer') ?> + titelpre_erstpruefer . ' ' . $abschlusspruefung->vorname_erstpruefer . ' ' . $abschlusspruefung->nachname_erstpruefer . ' ' . $abschlusspruefung->titelpost_erstpruefer ?>
- p->t('abschlusspruefung', 'Zweitpruefer') ?> + p->t('abschlusspruefung', 'zweitpruefer') ?> + titelpre_zweitpruefer . ' ' . $abschlusspruefung->vorname_zweitpruefer . ' ' . $abschlusspruefung->nachname_zweitpruefer . ' ' . $abschlusspruefung->titelpost_zweitpruefer ?>
- p->t('abschlusspruefung', 'Pruefungsdatum') ?> + + p->t('abschlusspruefung', 'pruefungsdatum') ?> + datum), 'd.m.Y'); ?>
- p->t('abschlusspruefung', 'EinverstaendniserklaerungName') ?> + + p->t('abschlusspruefung', 'pruefungsbeginn') ?> - - p->t('abschlusspruefung', 'EinverstaendniserklaerungText') ?> + + + + p->t('abschlusspruefung', 'pruefungsende') ?> + +
- p->t('abschlusspruefung', 'ThemaBeurteilung') ?>  + p->t('abschlusspruefung', 'pruefungsantritt') ?> + pruefungsantritt_bezeichnung; ?> +
+ p->t('abschlusspruefung', 'einverstaendniserklaerungName') ?> + + + p->t('abschlusspruefung', 'einverstaendniserklaerungText') ?> +
+ p->t('abschlusspruefung', 'themaBeurteilung') ?>  + abschlussarbeit_titel) ? $abschlusspruefung->abschlussarbeit_titel : '' ?> - p->t('abschlusspruefung', 'Note') ?>: abschlussarbeit_note) ? $abschlusspruefung->abschlussarbeit_note : '' ?> + p->t('lehre', 'note') ?>: abschlussarbeit_note) ? $abschlusspruefung->abschlussarbeit_note : '' ?>
- p->t('abschlusspruefung', 'Pruefungsgegenstand') ?> + p->t('abschlusspruefung', 'pruefungsgegenstand') ?> + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'PruefungsgegenstandBachelor') : $this->p->t('abschlusspruefung', 'PruefungsgegenstandMaster')) ?>
- p->t('abschlusspruefung', 'Notizen') ?> + + p->t('global', 'notizen') ?>
- + + +
- studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'BeurteilungKriterienBachelor') : $this->p->t('abschlusspruefung', 'BeurteilungKriterienMaster')) ?> + + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'beurteilungKriterienBachelor') : $this->p->t('abschlusspruefung', 'beurteilungKriterienMaster')) ?>
- p->t('abschlusspruefung', 'Beurteilung') ?>: - + p->t('abschlusspruefung', 'beurteilung') ?>: + + + + + + + + +
+
+ \ No newline at end of file diff --git a/public/css/lehre/pruefungsprotokoll.css b/public/css/lehre/pruefungsprotokoll.css index 7511ed8e2..a73e67950 100644 --- a/public/css/lehre/pruefungsprotokoll.css +++ b/public/css/lehre/pruefungsprotokoll.css @@ -1,3 +1,11 @@ +/* threshold for form full screen */ +@media (max-width:1075px) { + #page-wrapper { + margin-right: 0; + margin-left: 0; + } +} + #protocoltbl textarea { /* notiz field should stay in table */ -webkit-box-sizing: border-box; @@ -6,6 +14,24 @@ width: 100%; } -#protocoltbl td:nth-child(1) { +#protocoltbl td:nth-child(1), .cellbg { background-color: #f5f5f5; -} \ No newline at end of file +} + +.timecellwidth { + width: 20%; +} + +.namecellwidth { + width: 15%; +} + +.datevalcellwidth { + width: 10%; +} + +#hrbottom { + border-top: 2px solid #eee; + margin-top: 10px; + margin-bottom: 10px; +} diff --git a/public/css/sbadmin2/admintemplate_contentonly.css b/public/css/sbadmin2/admintemplate_contentonly.css index d5a69d07d..4420ab602 100644 --- a/public/css/sbadmin2/admintemplate_contentonly.css +++ b/public/css/sbadmin2/admintemplate_contentonly.css @@ -3,7 +3,8 @@ @media (min-width:768px) { #page-wrapper { - margin-right: 250px; + margin-right: 180px; + margin-left: 180px; margin-top: 8px; border: 1px solid #e7e7e7; } diff --git a/public/js/bootstrapper.js b/public/js/bootstrapper.js index 5d1749e9a..6bc1372e2 100644 --- a/public/js/bootstrapper.js +++ b/public/js/bootstrapper.js @@ -9,7 +9,7 @@ $(document).ready(function() { var Bootstrapper = { bootstraphtml: function () { - $("input[type=text], select").addClass("form-control"); + $("input[type=text], select, textarea").addClass("form-control"); $("button, input[type=button]").addClass("btn btn-default"); $("table").addClass("table-condensed"); } diff --git a/public/js/lehre/pruefungsprotokoll.js b/public/js/lehre/pruefungsprotokoll.js new file mode 100644 index 000000000..c11bc9ee7 --- /dev/null +++ b/public/js/lehre/pruefungsprotokoll.js @@ -0,0 +1,135 @@ +const CALLED_PATH = FHC_JS_DATA_STORAGE_OBJECT.called_path; + +$("document").ready(function() { + $("#saveProtocolBtn, #freigebenProtocolBtn").click( + function() { + var data = { + abschlussbeurteilung_kurzbz: $("#abschlussbeurteilung_kurzbz").val(), + protokoll: $("#protokoll").val(), + uhrzeit: $("#pruefungsbeginn").val(), + endezeit: $("#pruefungsende").val() + } + + if ($(this).prop("id") === 'freigebenProtocolBtn') + { + data.freigabedatum = true; + data.password = $("#password").val(); + } + + if ($("#verfCheck").prop('checked')) + { + var checkFields = Pruefungsprotokoll.checkFields(data, $("#verfCheck").prop('checked')); + $("#protocolform td").removeClass('has-error'); + if (checkFields.length > 0) + { + var errortext = ''; + for (var i = 0; i < checkFields.length; i++) + { + var error = checkFields[i]; + $.each(error, function(i, n) + { + console.log($("#"+i).closest('td')); + $("#"+i).closest('td').addClass('has-error'); + if (errortext !== '') + errortext += '; '; + errortext += n; + }); + } + + FHC_DialogLib.alertError(errortext); + return; + } + } + + Pruefungsprotokoll.saveProtokoll($("#abschlusspruefung_id").val(),data); + } + ) + + $("#verfCheck").change( + function() { // if student not mentally and physically fit (checkbox), no form entry + if ($(this).prop('checked')) + { + $("#abschlussbeurteilung_kurzbz, #pruefungsbeginn, #pruefungsende").prop('disabled', false); + $("#abschlussbeurteilung_kurzbz").val($("#abschlussbeurteilung_kurzbz option").first().val()); + } + else + { + $("#abschlussbeurteilung_kurzbz, #pruefungsbeginn, #pruefungsende").prop('disabled', true).val(null); + } + + $("#pruefungsbeginn").val(null); + $("#pruefungsende").val(null); + + } + ); + + $( ".timepicker" ).timepicker({ + showPeriodLabels: false, + hours: {starts: 7,ends: 22}, + timeFormat: 'hh:mm', + defaultTime: '', + hourText: FHC_PhrasesLib.t("ui", "stunde"), + minuteText: FHC_PhrasesLib.t("ui", "minute"), + rows: 4 + }); +}) + +var Pruefungsprotokoll = { + + // ----------------------------------------------------------------------------------------------------------------- + // ajax calls + saveProtokoll: function(abschlusspruefung_id, data) + { + FHC_AjaxClient.ajaxCallPost( + CALLED_PATH + '/saveProtokoll', + { + abschlusspruefung_id: abschlusspruefung_id, + protocoldata: data + }, + { + successCallback: function(data, textStatus, jqXHR) { + if (FHC_AjaxClient.hasData(data)) + { + var dataresponse = FHC_AjaxClient.getData(data); + if (dataresponse.freigabedatum) + { + $("#saveProtocolBtn").prop("disabled", true); + $("#freigegebenText").html('  ' + FHC_PhrasesLib.t("pruefungsprotokoll", "freigegebenAm") + + ' ' + dataresponse.freigabedatum) + } + FHC_DialogLib.alertSuccess("Prüfung erfolgreich gespeichert!"); + } + else if(FHC_AjaxClient.isError(data)) + { + FHC_DialogLib.alertError(FHC_AjaxClient.getError(data)); + } + }, + errorCallback: function() { + FHC_DialogLib.alertError("Fehler beim Speichern der Prüfung"); + }, + veilTimeout: 0 + } + ); + }, + checkFields: function(data) + { + var errors = []; + + if (data.abschlussbeurteilung_kurzbz == "") + errors.push({"abschlussbeurteilung_kurzbz": "Abschlussbeurteilung darf nicht leer sein!"}); // TODO phrases + + var zeitregex = /^[0-2][0-9]:[0-5][0-9]$/; + + if (data.uhrzeit == "") + errors.push({"pruefungsbeginn": "Beginnzeit darf nicht leer sein!"}); + else if(!zeitregex.test(data.uhrzeit)) + errors.push({"pruefungsbeginn": "Beginnzeit muss Format Stunden:Minuten haben!"}); + + if (data.endezeit == "") + errors.push({"pruefungsende": "Endzeit darf nicht leer sein!"}); + else if(!zeitregex.test(data.endezeit)) + errors.push({"pruefungsende": "Endzeit muss Format Stunden:Minuten haben!"}); + + return errors; + } +} diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 78bcebad3..7ecbfde77 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -5334,6 +5334,46 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'stunde', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Stunde', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Hour', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'minute', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Minute', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Minute', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'global', @@ -6809,7 +6849,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'PruefungBachelor', + 'phrase' => 'pruefungBachelor', 'insertvon' => 'system', 'phrases' => array( array( @@ -6829,7 +6869,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'PruefungMaster', + 'phrase' => 'pruefungMaster', 'insertvon' => 'system', 'phrases' => array( array( @@ -6849,7 +6889,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'ArbeitBachelor', + 'phrase' => 'arbeitBachelor', 'insertvon' => 'system', 'phrases' => array( array( @@ -6869,7 +6909,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'ArbeitMaster', + 'phrase' => 'arbeitMaster', 'insertvon' => 'system', 'phrases' => array( array( @@ -6889,7 +6929,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Protokoll', + 'phrase' => 'protokoll', 'insertvon' => 'system', 'phrases' => array( array( @@ -6909,7 +6949,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'AbgehaltenAmBachelor', + 'phrase' => 'abgehaltenAmBachelor', 'insertvon' => 'system', 'phrases' => array( array( @@ -6929,7 +6969,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'AbgehaltenAmMaster', + 'phrase' => 'abgehaltenAmMaster', 'insertvon' => 'system', 'phrases' => array( array( @@ -6949,7 +6989,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Studiengangskennzahl', + 'phrase' => 'studiengangskennzahl', 'insertvon' => 'system', 'phrases' => array( array( @@ -6969,7 +7009,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Personenkennzeichen', + 'phrase' => 'personenkennzeichen', 'insertvon' => 'system', 'phrases' => array( array( @@ -6989,7 +7029,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Pruefungssenat', + 'phrase' => 'pruefungssenat', 'insertvon' => 'system', 'phrases' => array( array( @@ -7009,7 +7049,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Vorsitz', + 'phrase' => 'vorsitz', 'insertvon' => 'system', 'phrases' => array( array( @@ -7029,7 +7069,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Erstpruefer', + 'phrase' => 'erstpruefer', 'insertvon' => 'system', 'phrases' => array( array( @@ -7049,7 +7089,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Zweitpruefer', + 'phrase' => 'zweitpruefer', 'insertvon' => 'system', 'phrases' => array( array( @@ -7069,7 +7109,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Pruefungsdatum', + 'phrase' => 'pruefungsdatum', 'insertvon' => 'system', 'phrases' => array( array( @@ -7089,7 +7129,67 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'EinverstaendniserklaerungName', + 'phrase' => 'pruefungsbeginn', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prüfungsbeginn', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Time of Start', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'pruefungsende', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prüfungsende', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Time of Finish', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'pruefungsantritt', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prüfungsantritt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Examination Attempt', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'einverstaendniserklaerungName', 'insertvon' => 'system', 'phrases' => array( array( @@ -7109,7 +7209,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'EinverstaendniserklaerungText', + 'phrase' => 'einverstaendniserklaerungText', 'insertvon' => 'system', 'phrases' => array( array( @@ -7121,7 +7221,7 @@ When on hold, the date is only a reminder.', ), array( 'sprache' => 'English', - 'text' => '', + 'text' => 'The student confirms being in a healthy physical and mental condition and that the technical requirements are met for taking the exam.', 'description' => '', 'insertvon' => 'system' ) @@ -7130,7 +7230,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'ThemaBeurteilung', + 'phrase' => 'themaBeurteilung', 'insertvon' => 'system', 'phrases' => array( array( @@ -7150,27 +7250,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Note', - 'insertvon' => 'system', - 'phrases' => array( - array( - 'sprache' => 'German', - 'text' => 'Note', - 'description' => '', - 'insertvon' => 'system' - ), - array( - 'sprache' => 'English', - 'text' => 'Grade', - 'description' => '', - 'insertvon' => 'system' - ) - ) - ), - array( - 'app' => 'core', - 'category' => 'abschlusspruefung', - 'phrase' => 'Pruefungsgegenstand', + 'phrase' => 'pruefungsgegenstand', 'insertvon' => 'system', 'phrases' => array( array( @@ -7190,27 +7270,7 @@ When on hold, the date is only a reminder.', array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Notizen', - 'insertvon' => 'system', - 'phrases' => array( - array( - 'sprache' => 'German', - 'text' => 'Notizen', - 'description' => '', - 'insertvon' => 'system' - ), - array( - 'sprache' => 'English', - 'text' => 'Notes', - 'description' => '', - 'insertvon' => 'system' - ) - ) - ), - array( - 'app' => 'core', - 'category' => 'abschlusspruefung', - 'phrase' => 'PruefungsnotizenBachelor', + 'phrase' => 'pruefungsnotizenBachelor', 'insertvon' => 'system', 'phrases' => array( array( @@ -7254,7 +7314,7 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'PruefungsnotizenMaster', + 'phrase' => 'pruefungsnotizenMaster', 'insertvon' => 'system', 'phrases' => array( array( @@ -7300,7 +7360,7 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'PruefungsgegenstandBachelor', + 'phrase' => 'pruefungsgegenstandBachelor', 'insertvon' => 'system', 'phrases' => array( array( @@ -7320,7 +7380,7 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'PruefungsgegenstandMaster', + 'phrase' => 'pruefungsgegenstandMaster', 'insertvon' => 'system', 'phrases' => array( array( @@ -7340,12 +7400,12 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'BeurteilungKriterienBachelor', + 'phrase' => 'beurteilungKriterienBachelor', 'insertvon' => 'system', 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Beurteilung und Kriterien Bachelorprüfung
+ 'text' => 'Beurteilung und Kriterien Bachelorprüfung

  • Mit ausgezeichnetem Erfolg bestanden
    @@ -7368,7 +7428,24 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => '', + 'text' => 'Assesment and criteria Bachelor Examination

    +
      +
    • + Passed with distinction
      + Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau. +
    • +
    • + Passed with merit
      + Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau. +
    • +
    • + Passed
      + Alle Lehrveranstaltungen (einschl. Bachelorarbeit) und Bachelorprüfung wurden positiv beurteilt. +
    • +
    • + Failed +
    • +
    ', 'description' => '', 'insertvon' => 'system' ) @@ -7377,12 +7454,12 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'BeurteilungKriterienMaster', + 'phrase' => 'beurteilungKriterienMaster', 'insertvon' => 'system', 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Beurteilung und Kriterien Masterprüfung
    + 'text' => 'Beurteilung und Kriterien Masterprüfung

    • Mit ausgezeichnetem Erfolg bestanden
      @@ -7405,7 +7482,24 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => '', + 'text' => '\'Assesment and criteria Masters Examination

      +
        +
      • + Passed with distinction
        + Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau. +
      • +
      • + Passed with merit
        + Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau. +
      • +
      • + Passed
        + Alle Lehrveranstaltungen (einschl. Bachelorarbeit) und Bachelorprüfung wurden positiv beurteilt. +
      • +
      • + Failed +
      • +
      \'', 'description' => '', 'insertvon' => 'system' ) @@ -7414,13 +7508,12 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'Beurteilung', + 'phrase' => 'beurteilung', 'insertvon' => 'system', 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Beurteilung - ', + 'text' => 'Beurteilung', 'description' => '', 'insertvon' => 'system' ), @@ -7431,6 +7524,46 @@ Any unusual occurrences 'insertvon' => 'system' ) ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'ueberpruefenFreigeben', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Überprüfen und Freigeben', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Check and Approve', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'freigegebenAm', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Freigegeben am', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Approved on', + 'description' => '', + 'insertvon' => 'system' + ) + ) ) ); From c0bde2a6cd0259601b63d65510f413c852ba1adc Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 28 May 2020 12:49:36 +0200 Subject: [PATCH 115/265] Removed Bundesadler and Logo for direct FAS Dokumente Download While Bundesadler and Logo should be printed in archived documents, it should NOT be printed in direct download via menu tab 'Dokumente'. Signed-off-by: Cris --- content/pdfExport.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/content/pdfExport.php b/content/pdfExport.php index 22f0110f4..f61a61486 100644 --- a/content/pdfExport.php +++ b/content/pdfExport.php @@ -459,12 +459,6 @@ else $dokument->setFilename($filename); - if ($vorlage->archivierbar) - { - // XML-tag archivierbar ergaenzen - $dokument->setXMLTag_archivierbar(); - } - if ($sign === true) { $dokument->sign($user); From 2fc0b0f0ce6e65117dba3d24cfae39881ed465df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Thu, 28 May 2020 19:36:08 +0200 Subject: [PATCH 116/265] =?UTF-8?q?Pr=C3=BCfungsprotokoll=20-=20L=C3=B6sch?= =?UTF-8?q?en=20von=20Abschlussarbeiten=20mit=20freigegebenem=20Protokoll?= =?UTF-8?q?=20wird=20verhindert=20-=20Berechtigungen=20f=C3=BCr=20web=20Us?= =?UTF-8?q?er=20erteilt=20damit=20protokoll=20gespeichert=20werden=20kann?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lehre/pruefungsprotokollUebersicht.php | 2 +- .../pruefungsprotokollUebersichtData.php | 2 +- content/student/studentDBDML.php | 21 ++++++++++++++++--- system/dbupdate_3.3.php | 7 +++++++ system/phrasesupdate.php | 20 ++++++++++++++++++ 5 files changed, 47 insertions(+), 5 deletions(-) diff --git a/application/views/lehre/pruefungsprotokollUebersicht.php b/application/views/lehre/pruefungsprotokollUebersicht.php index a827bcf5b..d14ec670a 100644 --- a/application/views/lehre/pruefungsprotokollUebersicht.php +++ b/application/views/lehre/pruefungsprotokollUebersicht.php @@ -29,7 +29,7 @@
      diff --git a/application/views/lehre/pruefungsprotokollUebersichtData.php b/application/views/lehre/pruefungsprotokollUebersichtData.php index b2d8b9948..d7bf3c9d0 100644 --- a/application/views/lehre/pruefungsprotokollUebersichtData.php +++ b/application/views/lehre/pruefungsprotokollUebersichtData.php @@ -18,7 +18,7 @@ FROM WHERE vorsitz='".$UID."' AND datum>='2020-05-27' -ORDER BY datum +ORDER BY datum, nachname, vorname "; $filterWidgetArray = array( diff --git a/content/student/studentDBDML.php b/content/student/studentDBDML.php index 2345141c7..b625cd927 100644 --- a/content/student/studentDBDML.php +++ b/content/student/studentDBDML.php @@ -3806,10 +3806,25 @@ if(!$error) if(isset($_POST['abschlusspruefung_id']) && is_numeric($_POST['abschlusspruefung_id'])) { $pruefung = new abschlusspruefung(); - - if($pruefung->delete($_POST['abschlusspruefung_id'])) + if($pruefung->load($_POST['abschlusspruefung_id'])) { - $return = true; + if ($pruefung->freigabedatum == '') + { + if($pruefung->delete($_POST['abschlusspruefung_id'])) + { + $return = true; + } + else + { + $errormsg = $pruefung->errormsg; + $return = false; + } + } + else + { + $errormsg = 'Löschen ist nicht möglich da bereits ein freigegebenes Protokoll vorhanden ist'; + $return = false; + } } else { diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 148757aaf..52aef74d0 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -4149,6 +4149,13 @@ if (!@$db->db_query("SELECT 0 FROM lehre.tbl_abschlusspruefung_antritt WHERE 0 = else echo '
      Granted privileges to vilesci on lehre.tbl_abschlusspruefung_antritt'; + // GRANT SELECT, UPDATE ON TABLE lehre.tbl_abschlusspruefung TO web; + $qry = 'GRANT SELECT, UPDATE ON lehre.tbl_abschlusspruefung TO web;'; + if (!$db->db_query($qry)) + echo 'lehre.tbl_abschlusspruefung '.$db->db_last_error().'
      '; + else + echo '
      Granted privileges to web on lehre.tbl_abschlusspruefung'; + // COMMENT ON TABLE lehre.tbl_abschlusspruefung_antritt $qry = 'COMMENT ON TABLE lehre.tbl_abschlusspruefung_antritt IS \'Type of Abschlusspruefung depending on number of attempts\';'; if (!$db->db_query($qry)) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 7ecbfde77..9e501aaf2 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -6926,6 +6926,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'pruefungsprotokoll', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prüfungsprotokoll', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Record of Examination', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'abschlusspruefung', From bc32a643f19a717603bfb209f5f4df916b749c39 Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Thu, 28 May 2020 20:53:21 +0200 Subject: [PATCH 117/265] =?UTF-8?q?Pr=C3=BCfungsprotokoll:=20-=20phrases:?= =?UTF-8?q?=20multilingual=20database=20fields=20shown=20depending=20on=20?= =?UTF-8?q?language=20(e.g.=20beurteilung,=20studiengang,...=20-=20added?= =?UTF-8?q?=20phrases=20-=20added=20timepicker=20css=20-=20if=20student=20?= =?UTF-8?q?not=20in=20condition,=20time=20can=20still=20be=20filled=20out?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/lehre/Pruefungsprotokoll.php | 11 +- .../views/lehre/pruefungsprotokoll.php | 29 ++- public/css/lehre/pruefungsprotokoll.css | 10 +- public/js/lehre/pruefungsprotokoll.js | 73 +++--- system/phrasesupdate.php | 246 +++++++++++++++++- 5 files changed, 306 insertions(+), 63 deletions(-) diff --git a/application/controllers/lehre/Pruefungsprotokoll.php b/application/controllers/lehre/Pruefungsprotokoll.php index a88568daf..594d3a9e1 100644 --- a/application/controllers/lehre/Pruefungsprotokoll.php +++ b/application/controllers/lehre/Pruefungsprotokoll.php @@ -90,10 +90,13 @@ class Pruefungsprotokoll extends Auth_Controller else $abschlussbeurteilung = getData($abschlussbeurteilung); + $language = getUserLanguage(); + $data = array( 'abschlusspruefung' => $abschlusspruefung, 'abschlussbeurteilung' => $abschlussbeurteilung, - 'abschlusspruefung_saved' => $abschlusspruefung_saved + 'abschlusspruefung_saved' => $abschlusspruefung_saved, + 'language' => $language ); $this->load->view('lehre/pruefungsprotokoll.php', $data); @@ -127,12 +130,12 @@ class Pruefungsprotokoll extends Auth_Controller $result = $this->authlib->checkUserAuthByUsernamePassword($this->_uid, $password); if (isError($result)) { - return $this->outputJsonError('Falsches Passwort'); // exit if password is incorrect + return $this->outputJsonError($this->p->t('password', 'wrongPassword')); // exit if password is incorrect } } else { - return $this->outputJsonError('Passwort fehlt'); + return $this->outputJsonError($this->p->t('password', 'passwordMissing')); } } @@ -153,7 +156,7 @@ class Pruefungsprotokoll extends Auth_Controller } } else - $this->outputJsonError('Ungültige Parameter'); + $this->outputJsonError($this->p->t('ui', 'ungueltigeParameter')); } // ----------------------------------------------------------------------------------------------------------------- diff --git a/application/views/lehre/pruefungsprotokoll.php b/application/views/lehre/pruefungsprotokoll.php index 336741891..12024f981 100644 --- a/application/views/lehre/pruefungsprotokoll.php +++ b/application/views/lehre/pruefungsprotokoll.php @@ -11,8 +11,16 @@ $this->load->view( 'ajaxlib' => true, 'sbadmintemplate' => true, 'phrases' => array( - 'pruefungsprotokoll' => array( - 'freigegebenAm' + 'abschlusspruefung' => array( + 'freigegebenAm', + 'pruefungGespeichert', + 'pruefungSpeichernFehler', + 'abschlussbeurteilungLeer', + 'beginnzeitLeer', + 'beginnzeitFormatError', + 'endezeitLeer', + 'endezeitFormatError', + 'endezeitBeforeError' ), 'ui' => array( 'stunde', @@ -21,11 +29,12 @@ $this->load->view( ), 'customCSSs' => array( 'public/css/sbadmin2/admintemplate_contentonly.css', + 'vendor/fgelinas/timepicker/jquery.ui.timepicker.css', 'public/css/lehre/pruefungsprotokoll.css' ), 'customJSs' => array( - 'public/js/lehre/pruefungsprotokoll.js', - 'vendor/fgelinas/timepicker/jquery.ui.timepicker.js' + 'vendor/fgelinas/timepicker/jquery.ui.timepicker.js', + 'public/js/lehre/pruefungsprotokoll.js' ) ) ); @@ -44,11 +53,11 @@ $this->load->view(

      studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'abgehaltenAmBachelor') : $this->p->t('abschlusspruefung', 'abgehaltenAmMaster'); ?> - studiengangbezeichnung?>, p->t('abschlusspruefung', 'studiengangskennzahl') ?>  + studiengangbezeichnung : $abschlusspruefung->studiengangbezeichnung_englisch ?>, p->t('abschlusspruefung', 'studiengangskennzahl') ?>  studiengang_kz ?>

      @@ -118,7 +127,7 @@ $this->load->view( p->t('abschlusspruefung', 'pruefungsantritt') ?>
- pruefungsantritt_bezeichnung; ?> + pruefungsantritt_bezeichnung : $abschlusspruefung->pruefungsantritt_bezeichnung_english; ?>
- studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'PruefungsgegenstandBachelor') : $this->p->t('abschlusspruefung', 'PruefungsgegenstandMaster')) ?> + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'pruefungsgegenstandBachelor') : $this->p->t('abschlusspruefung', 'PruefungsgegenstandMaster')) ?>
- p->t('global', 'notizen') ?> + p->t('global', 'notizen')); ?>
- + p->t('abschlusspruefung', 'einverstaendniserklaerungText') ?>
- studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'pruefungsgegenstandBachelor') : $this->p->t('abschlusspruefung', 'PruefungsgegenstandMaster')) ?> + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'pruefungsgegenstandBachelor') : $this->p->t('abschlusspruefung', 'pruefungsgegenstandMaster')) ?>
- studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'beurteilungKriterienBachelor') : $this->p->t('abschlusspruefung', 'beurteilungKriterienMaster')) ?> + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'beurteilungKriterienBachelor') : $this->p->t('abschlusspruefung', 'beurteilungKriterienMaster') ?>
- p->t('abschlusspruefung', 'beurteilung') ?>: + studiengangstyp == 'b' ? $this->p->t('abschlusspruefung', 'beurteilungBachelor') : $this->p->t('abschlusspruefung', 'beurteilungMaster') ?>: +
diff --git a/public/js/lehre/pruefungsprotokoll.js b/public/js/lehre/pruefungsprotokoll.js index 0e0715198..b14bc6153 100644 --- a/public/js/lehre/pruefungsprotokoll.js +++ b/public/js/lehre/pruefungsprotokoll.js @@ -72,10 +72,12 @@ var Pruefungsprotokoll = { if ($("#verfCheck").prop('checked')) { $("#abschlussbeurteilung_kurzbz").prop('disabled', false).val(Pruefungsprotokoll.abschlussbeurteilung_kurzbz); + $("#verfNotice").html(""); } else { $("#abschlussbeurteilung_kurzbz").prop('disabled', true).val(null); + $("#verfNotice").html(FHC_PhrasesLib.t("abschlusspruefung", "verfNotice")); } }, checkFields: function(data, verfChecked) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 944f931b9..4af518247 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -7280,7 +7280,7 @@ When on hold, the date is only a reminder.', ), array( 'sprache' => 'English', - 'text' => 'Declaration of Agreement', + 'text' => 'Statement of agreement', 'description' => '', 'insertvon' => 'system' ) @@ -7295,13 +7295,13 @@ When on hold, the date is only a reminder.', array( 'sprache' => 'German', 'text' => 'Der/Die Studierende bestätigt, sich in guter körperlicher und geistiger Verfassung zu befinden, - um die Prüfung durchzuführen und dass die technischen Voraussetzungen und gegeben sind.', + um die Prüfung durchzuführen und dass die technischen Voraussetzungen gegeben sind.', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'The student confirms being in a healthy physical and mental condition and that the technical requirements are met for taking the exam.', + 'text' => 'The student confirms to be in a physical and mental condition to take the exam and that the technical requirements are met.', 'description' => '', 'insertvon' => 'system' ) @@ -7341,7 +7341,7 @@ When on hold, the date is only a reminder.', ), array( 'sprache' => 'English', - 'text' => 'Subject of Examination', + 'text' => 'Subject of the Examination', 'description' => '', 'insertvon' => 'system' ) @@ -7421,7 +7421,7 @@ Allfällige besondere Vorkommnisse 'text' => 'Parts of the examination held in English (Optional - in line with the degree program\'s guidelines): << Delete as appropriate >> * Presentation of the Master\'s Thesis -* Examination interview on the Master\'s Thesis and its links to subjects of the curriculum +* Examination interview on the Master\'s Thesis and its links to the subjects of the curriculum * Examination interview on other subjects relevant to the curriculum Question(s) to open the examination interview @@ -7451,7 +7451,7 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => 'Presentation and Examination interview on the Bachelor Paper', + 'text' => 'Presentation and Examination interview on the Bachelor Paper and its links to subjects of the curriculum', 'description' => '', 'insertvon' => 'system' ) @@ -7471,8 +7471,8 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => '', - 'description' => 'Examination interview on the Master’s Thesis and its links to subjects of the curriculum as well as examination interview on a curricular theme', + 'text' => 'Examination interview on the Master’s Thesis and its links to subjects of the curriculum as well as examination interview on a curricular theme', + 'description' => '', 'insertvon' => 'system' ) ) @@ -7488,19 +7488,22 @@ Any unusual occurrences 'text' => 'Beurteilung und Kriterien Bachelorprüfung

  • - Mit ausgezeichnetem Erfolg bestanden
    + Mit ausgezeichnetem Erfolg bestanden
    Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau.
  • +
  • - Mit gutem Erfolg bestanden
    + Mit gutem Erfolg bestanden
    Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau.
  • +
  • - Bestanden
    + Bestanden
    Alle Lehrveranstaltungen (einschl. Bachelorarbeit) und Bachelorprüfung wurden positiv beurteilt.
  • +
  • - Nicht bestanden + Nicht bestanden
', 'description' => '', @@ -7508,22 +7511,25 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => 'Assessment and criteria Bachelor Examination

+ 'text' => 'Criteria for the assessment of the Bachelor Examination

  • - Passed with distinction
    + Passed with distinction
    The candidate is within the scope of the task able to apply knowledge from various learning areas to new situations in a technically correct manner, far beyond what is essential, and at a very high level of argument.
  • +
  • - Passed with merit
    + Passed with merit
    The candidate is within the scope of the task able to apply knowledge from various learning areas in a technically correct manner to an extent beyond what is essential to new situations, and at a high level of argument.
  • +
  • - Passed
    - Bachelor thesis and Bachelor examination were successfully completed. + Passed
    + All courses (including Bachelor thesis) and Bachelor examination were successfully completed.
  • +
  • - Failed + Failed
', 'description' => '', @@ -7542,19 +7548,28 @@ Any unusual occurrences 'text' => 'Beurteilung und Kriterien Masterprüfung

  • - Mit ausgezeichnetem Erfolg bestanden
    - Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau. + Mit ausgezeichnetem Erfolg bestanden
    +
      +
    • Masterarbeit mit "Sehr gut" beurteilt
    • +
    • Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem weit über das Wesentliche hinausgehenden Ausmaß souverän auf neue Situationen anzuwenden, und das noch dazu auf einem sehr hohen argumentativen Niveau.
    • +
  • +
  • - Mit gutem Erfolg bestanden
    - Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau. + Mit gutem Erfolg bestanden
    +
      +
    • Masterarbeit mit "Sehr gut" oder mit "Gut" beurteilt
    • +
    • Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau.
    • +
  • +
  • - Bestanden
    - Alle Lehrveranstaltungen (einschl. Masterarbeit) und Masterprüfung wurden positiv beurteilt. + Bestanden
    + Masterarbeit und Masterprüfung wurden positiv beurteilt.
  • +
  • - Nicht bestanden + Nicht bestanden
', 'description' => '', @@ -7562,24 +7577,31 @@ Any unusual occurrences ), array( 'sprache' => 'English', - 'text' => 'Assessment and criteria Masters Examination

+ 'text' => 'Criteria for the assessment of the Master Examination

  • - Passed with distinction
    - Master thesis was graded "excellent"
    - The candidate is within the scope of the task able to apply knowledge from various learning areas to new situations in a technically correct manner, far beyond what is essential, and at a very high level of argument. + Passed with distinction
    +
      +
    • Master thesis was graded "excellent"
    • +
    • The candidate is within the scope of the task able to apply knowledge from various learning areas to new situations in a technically correct manner, far beyond what is essential, and at a very high level of argument.
    • +
  • +
  • - Passed with merit
    - Master thesis graded not worse than "good"
    - The candidate is within the scope of the task able to apply knowledge from various learning areas in a technically correct manner to an extent beyond what is essential to new situations, and at a high level of argument. + Passed with merit
    +
      +
    • Master thesis graded not worse than "good"
    • +
    • The candidate is within the scope of the task able to apply knowledge from various learning areas in a technically correct manner to an extent beyond what is essential to new situations, and at a high level of argument.
    • +
  • +
  • - Passed
    + Passed
    Master thesis and Master examination were successfully completed.
  • +
  • - Failed + Failed
', 'description' => '', @@ -7590,18 +7612,38 @@ Any unusual occurrences array( 'app' => 'core', 'category' => 'abschlusspruefung', - 'phrase' => 'beurteilung', + 'phrase' => 'beurteilungBachelor', 'insertvon' => 'system', 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Beurteilung', + 'text' => 'Beurteilung Bachelorprüfung', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'Assessment', + 'text' => 'Assessment of the Bachelor Examination', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'beurteilungMaster', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Beurteilung Masterprüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assessment of the Master Examination', 'description' => '', 'insertvon' => 'system' ) @@ -7806,6 +7848,26 @@ Any unusual occurrences 'insertvon' => 'system' ) ) + ), + array( + 'app' => 'core', + 'category' => 'abschlusspruefung', + 'phrase' => 'verfNotice', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => '(Beurteilung kann nur nach Bestätigung der Einverständniserklärung erfolgen)', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => '(Assessment can only be selected after confirming the statement of agreement)', + 'description' => '', + 'insertvon' => 'system' + ) + ) ) ); From 8d9cc078bdce43b8a3ae0ad343a184e78fd0872d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Fri, 29 May 2020 15:08:51 +0200 Subject: [PATCH 120/265] =?UTF-8?q?Spalte=20sort=20von=20Abschlusspruefung?= =?UTF-8?q?santritt=20zu=20Gegencheck=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- system/dbupdate_3.3.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 52aef74d0..22fffe2cc 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -4293,7 +4293,7 @@ $tabellen=array( "fue.tbl_scrumsprint" => array("scrumsprint_id","scrumteam_kurzbz","sprint_kurzbz","sprintstart","sprintende","insertamum","insertvon","updateamum","updatevon"), "lehre.tbl_abschlussbeurteilung" => array("abschlussbeurteilung_kurzbz","bezeichnung","bezeichnung_english","sort"), "lehre.tbl_abschlusspruefung" => array("abschlusspruefung_id","student_uid","vorsitz","pruefer1","pruefer2","pruefer3","abschlussbeurteilung_kurzbz","akadgrad_id","pruefungstyp_kurzbz","datum","uhrzeit","sponsion","anmerkung","updateamum","updatevon","insertamum","insertvon","ext_id","note","protokoll","endezeit","pruefungsantritt_kurzbz","freigabedatum"), - "lehre.tbl_abschlusspruefung_antritt" => array("pruefungsantritt_kurzbz","bezeichnung","bezeichnung_english"), + "lehre.tbl_abschlusspruefung_antritt" => array("pruefungsantritt_kurzbz","bezeichnung","bezeichnung_english","sort"), "lehre.tbl_akadgrad" => array("akadgrad_id","akadgrad_kurzbz","studiengang_kz","titel","geschlecht"), "lehre.tbl_anrechnung" => array("anrechnung_id","prestudent_id","lehrveranstaltung_id","begruendung_id","lehrveranstaltung_id_kompatibel","genehmigt_von","insertamum","insertvon","updateamum","updatevon","ext_id"), "lehre.tbl_anrechnung_begruendung" => array("begruendung_id","bezeichnung"), From 87686ebd703f324ab3901fd3c95c86e410b12833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Fri, 29 May 2020 16:47:41 +0200 Subject: [PATCH 121/265] Phrasen angepasst --- system/phrasesupdate.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 4af518247..c2afb39c8 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -7356,7 +7356,7 @@ When on hold, the date is only a reminder.', array( 'sprache' => 'German', 'text' => 'Prüfungsteil/e in Englisch (Optional - entsprechend der Vorgabe des Studiengangs): -<< Nichtzutreffendes Streichen >> +<< Nichtzutreffendes löschen >> * Präsentation der Bachelorarbeit * Prüfungsgespräch über die Bachelorarbeit @@ -7400,7 +7400,7 @@ Any unusual occurrences array( 'sprache' => 'German', 'text' => 'Prüfungsteil/e in Englisch (Optional - entsprechend der Vorgabe des Studiengangs): -<< Nichtzutreffendes Streichen >> +<< Nichtzutreffendes löschen >> * Präsentation der Masterarbeit * Prüfungsgespräch über die Masterarbeit und Querverbindungen zu Fächern des Studienplans * Prüfungsgespräch über sonstige studienplanrelevante Inhalte @@ -7559,7 +7559,7 @@ Any unusual occurrences Mit gutem Erfolg bestanden
  • Masterarbeit mit "Sehr gut" oder mit "Gut" beurteilt
  • -
  • Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau.
  • +
  • Der oder die KandidatIn ist in der Lage, Wissen aus verschiedenen Lernbereichen fachlich korrekt in einem über das Wesentliche hinausgehenden Ausmaß auf neue Situationen anzuwenden, und das noch dazu auf einem hohen argumentativen Niveau.

@@ -7592,7 +7592,7 @@ Any unusual occurrences
  • Master thesis graded not worse than "good"
  • The candidate is within the scope of the task able to apply knowledge from various learning areas in a technically correct manner to an extent beyond what is essential to new situations, and at a high level of argument.
  • -
+
  • @@ -7657,13 +7657,13 @@ Any unusual occurrences 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Überprüfen und Freigeben', + 'text' => 'Speichern und Freigeben', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'Check and Approve', + 'text' => 'Save and Approve', 'description' => '', 'insertvon' => 'system' ) From 8b80f2226e63c3b3471082946cdd91113a7540e5 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 2 Jun 2020 15:03:31 +0200 Subject: [PATCH 122/265] Added logic for cronjob to add senders fields into message body Signed-off-by: Cris --- application/models/CL/Messages_model.php | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index d0676c5dd..ac3a16e3e 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -48,6 +48,9 @@ class Messages_model extends CI_Model $this->load->model('system/Benutzerrolle_model', 'BenutzerrolleModel'); // Loads model Prestudent_model $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + // Loads model Benutzer_model + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + } //------------------------------------------------------------------------------------------------------------------ @@ -463,6 +466,14 @@ class Messages_model extends CI_Model if (!hasData($msgVarsData)) show_error('No recipients were given'); $prestudentsData = $this->PrestudentModel->getOrganisationunits($prestudents); + + // Get the senders uid + $this->BenutzerModel->addSelect('uid'); + if (!$result = getData($this->BenutzerModel->getFromPersonId($sender_id))) + { + show_error('No sender_uid found'); + } + $sender_uid = $result[0]->uid; // Adds the organisation unit to each prestudent if (isEmptyString($oe_kurzbz) && hasData($msgVarsData) && hasData($prestudentsData)) @@ -472,7 +483,15 @@ class Messages_model extends CI_Model foreach (getData($msgVarsData) as $receiver) { - $msgVarsDataArray = $this->_lowerReplaceSpaceArrayKeys((array)$receiver); // replaces array keys + /** + * Merge receivers data with senders data + * NOTE: _addMsgVarsDataOfLoggedInUser usually retrieves data of the logged in user that is set in the + * templates user fields. As sendExplicitTemplateSenderId is run by a job, a sender uid is passed to be used + * instead the logged in user. + */ + $msgVarsDataArray = $this->_addMsgVarsDataOfLoggedInUser($receiver, $sender_uid); + + $msgVarsDataArray = $this->_lowerReplaceSpaceArrayKeys((array)getData($msgVarsDataArray)[0]); // replaces array keys // Additional message variables if (is_array($msgVars)) $msgVarsDataArray = array_merge($msgVarsDataArray, $msgVars); @@ -897,7 +916,7 @@ class Messages_model extends CI_Model * @param object $otherMsgVarsDataObj Can be success object or simple object. * @return object Returns success object. */ - public function _addMsgVarsDataOfLoggedInUser($otherMsgVarsDataObj) + public function _addMsgVarsDataOfLoggedInUser($otherMsgVarsDataObj, $uid = null) { // First check if param type is object if (!is_object($otherMsgVarsDataObj)) show_error('Must pass an object to merge with data of logged in user'); @@ -909,7 +928,7 @@ class Messages_model extends CI_Model } // Retrieve message vars data of the logged in user - if (!$msgVarsDataLoggedInUser = getData($this->MessageModel->getMsgVarsDataByLoggedInUser())[0]) + if (!$msgVarsDataLoggedInUser = getData($this->MessageModel->getMsgVarsDataByLoggedInUser($uid))[0]) { return success($otherMsgVarsDataObj); // If failed, return at least given object as expected success object } From d35ee0c834becab5700ba448284864d4b49f749e Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 2 Jun 2020 15:06:22 +0200 Subject: [PATCH 123/265] Adapted method to retrieve user fields when method is called by a cronjob Signed-off-by: Cris --- application/models/system/Message_model.php | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index 6f2a3c7ed..d9f8585ed 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -211,12 +211,23 @@ class Message_model extends DB_Model /** * Get message vars data for logged in user + * @param string uid The UID should ONLY be passed if this method is called by a cronjob. + * This is to enable jobs to use templates which use logged-in-user fields ('Eigene Felder'). * @return array|null */ - public function getMsgVarsDataByLoggedInUser() + public function getMsgVarsDataByLoggedInUser($uid = null) { + if (is_string($uid)) + { + $params = array($uid); + } + else + { + $params = array(getAuthUID()); + } + $query = 'SELECT * FROM public.vw_msg_vars_user WHERE my_uid = ?'; - return $this->execQuery($query, array(getAuthUID())); + return $this->execQuery($query, $params); } } From 2906c1803e9d0caf5cac630730eb1de18ce2cdac Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 2 Jun 2020 16:29:51 +0200 Subject: [PATCH 124/265] Changed 'Eigene Felder'-Alias: if alias is NULL, uid is used as alias This is to ensure the email is built correctly. Signed-off-by: Cris --- system/dbupdate_3.3.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index f0da8fab6..f03718116 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -205,7 +205,7 @@ if(!$result = @$db->db_query("SELECT 1 FROM public.vw_msg_vars_user LIMIT 1")) (b.uid) b.uid AS "my_uid", p.vorname AS "my_vorname", p.nachname AS "my_nachname", - b.alias AS "my_alias", + COALESCE(b.alias, b.uid) AS "my_alias", ma.telefonklappe AS "my_durchwahl" FROM public.tbl_person p JOIN public.tbl_benutzer b USING (person_id) From 8304b4a1ae50668156b127e17bda2948a70057aa Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 2 Jun 2020 16:31:52 +0200 Subject: [PATCH 125/265] Adapted GUI: display user fields in tinymce-editor on doubleclick Signed-off-by: Cris --- public/js/messaging/messageWrite.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/public/js/messaging/messageWrite.js b/public/js/messaging/messageWrite.js index 1978fc08c..8b1d73bdf 100644 --- a/public/js/messaging/messageWrite.js +++ b/public/js/messaging/messageWrite.js @@ -78,6 +78,21 @@ $(document).ready(function () }); } + if ($("#user_fields")) + { + $("#user_fields").dblclick(function () + { + if ($("#bodyTextArea")) + { + //if editor active add at cursor position, otherwise at end + if (tinymce.activeEditor.id === "bodyTextArea") + tinymce.activeEditor.execCommand('mceInsertContent', false, $(this).children(":selected").val()); + else + tinyMCE.get("bodyTextArea").setContent(tinyMCE.get("bodyTextArea").getContent() + $(this).children(":selected").val()); + } + }); + } + if ($("#recipients")) { $("#recipients").change(tinymcePreviewSetContent); From b2644d2a17565a025a88d408209dcd33fb7e8a44 Mon Sep 17 00:00:00 2001 From: Nikolaus Krondraf Date: Wed, 3 Jun 2020 14:00:05 +0200 Subject: [PATCH 126/265] Anzeige von Fehler- und Erfolgsmeldungen optimiert --- cis/private/lehre/pruefung/pruefung.js.php | 60 ++++++++++++---------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/cis/private/lehre/pruefung/pruefung.js.php b/cis/private/lehre/pruefung/pruefung.js.php index 247ee950e..f91a2c585 100644 --- a/cis/private/lehre/pruefung/pruefung.js.php +++ b/cis/private/lehre/pruefung/pruefung.js.php @@ -178,7 +178,7 @@ function loadPruefungsfenster() success: function(data){ if(data.result.length === 0) { - messageBox("message", "t('pruefung/keinFensterVorhanden'); ?>", "red", "highlight", 1000); + messageBox("message", "t('pruefung/keinFensterVorhanden'); ?>", "red", "highlight", 10000); $("#pruefungsfenster").html(""); } else @@ -617,7 +617,7 @@ function saveAnmeldung(lehrveranstaltung_id, termin_id) else { //Wenn Anmeldung durch Lektor - showAnmeldungen(termin_id, lehrveranstaltung_id); + showAnmeldungen(termin_id, lehrveranstaltung_id, false, false); } } }); @@ -763,9 +763,10 @@ function convertDateTime(string, type) * @param {type} pruefungstermin_id ID des Prüfungstermins * @param {type} lehrveranstaltung_id ID der Lehrveranstaltung * @param saveReihungAfterShow speichert Reihung neu wenn true + * @param showMessage steuert ob Meldung angzeigt werden soll * @returns {undefined} */ -function showAnmeldungen(pruefungstermin_id, lehrveranstaltung_id, saveReihungAfterShow = false) +function showAnmeldungen(pruefungstermin_id, lehrveranstaltung_id, saveReihungAfterShow = false, showMessage = true) { $("#kommentar").empty(); $("#kommentarSpeichernButton").empty(); @@ -780,7 +781,7 @@ function showAnmeldungen(pruefungstermin_id, lehrveranstaltung_id, saveReihungAf }, error: loadError, success: function(data){ - writeAnmeldungen(data); + writeAnmeldungen(data, showMessage); $("#sortable").sortable(); $("#sortable").disableSelection(); @@ -790,7 +791,7 @@ function showAnmeldungen(pruefungstermin_id, lehrveranstaltung_id, saveReihungAf }); } -function writeAnmeldungen(data) +function writeAnmeldungen(data, showMessage = true) { if(data.error === 'false') { @@ -862,7 +863,10 @@ function writeAnmeldungen(data) $("#kommentarSpeichernButton").empty(); $("#raumLink").empty(); $("#listeDrucken").empty(); - messageBox("message", data.errormsg, "red", "highlight", 1000); + + if (showMessage) + messageBox("message", data.errormsg, "red", "highlight", 10000); + if (data.lv_bezeichnung) { $("#lvdaten").html(data.lv_bezeichnung+" ("+data.termin_datum+")"); @@ -910,11 +914,11 @@ function saveReihung(terminId, lehrveranstaltung_id) success: function(data){ if(data.error === 'false' && data.result === true) { - messageBox("message", "t('pruefung/reihunghErfolgreichGeaendert'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/reihunghErfolgreichGeaendert'); ?>", "green", "highlight", 10000); } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } showAnmeldungen(terminId, lehrveranstaltung_id); @@ -951,7 +955,7 @@ function anmeldungBestaetigen(pruefungsanmeldung_id, termin_id, lehrveranstaltun } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } } }); @@ -988,7 +992,7 @@ function anmeldungLoeschen(pruefungsanmeldung_id, termin_id, lehrveranstaltung_i } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } } }); @@ -1022,7 +1026,7 @@ function alleBestaetigen(termin_id, lehrveranstaltung_id) } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } } }); @@ -1074,7 +1078,7 @@ function loadStudiengaenge() } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } } }); @@ -1133,7 +1137,7 @@ function loadPruefungStudiengang(studiengang_kz, studiensemester) } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } } }); @@ -1178,7 +1182,7 @@ function saveKommentar(pruefungsanmeldung_id, termin_id, lehrveranstaltung_id) }, error: loadError, success: function(data){ - messageBox("message", "t('pruefung/kommentarErfolgreichGespeichert'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/kommentarErfolgreichGespeichert'); ?>", "green", "highlight", 10000); showAnmeldungen(termin_id, lehrveranstaltung_id); } }); @@ -1396,7 +1400,7 @@ function savePruefungstermin() if(error) { - messageBox("message", "t('pruefung/formulardatenNichtKorrekt'); ?>", "red", "highlight", 3000); + messageBox("message", "t('pruefung/formulardatenNichtKorrekt'); ?>", "red", "highlight", 10000); } else { @@ -1422,12 +1426,12 @@ function savePruefungstermin() unmarkMissingFormEntry(); if(data.error === "false") { - messageBox("message", "t('pruefung/pruefungErfolgreichGespeichert'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/pruefungErfolgreichGespeichert'); ?>", "green", "highlight", 10000); resetPruefungsverwaltung(); } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } } }); @@ -1530,7 +1534,7 @@ function loadPruefungsDetails(prfId) }).done(function(data){ if(data.result.length === 0) { - messageBox("message", "t('pruefung/keinePruefungsfensterGespeichert'); ?>", "red", "highlight", 1000); + messageBox("message", "t('pruefung/keinePruefungsfensterGespeichert'); ?>", "red", "highlight", 10000); $("#pruefungsfenster").html(""); } else @@ -1823,7 +1827,7 @@ function updatePruefung(prfId) if(error) { - messageBox("message", "t('pruefung/formulardatenNichtKorrekt'); ?>", "red", "highlight", 3000); + messageBox("message", "t('pruefung/formulardatenNichtKorrekt'); ?>", "red", "highlight", 10000); } else { @@ -1851,12 +1855,12 @@ function updatePruefung(prfId) unmarkMissingFormEntry(); if(data.error === "false") { - messageBox("message", "t('pruefung/pruefungErfolgreichGespeichert'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/pruefungErfolgreichGespeichert'); ?>", "green", "highlight", 10000); resetPruefungsverwaltung(); } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } }).always(function(){ loadAllPruefungen(); @@ -1886,11 +1890,11 @@ function deleteLehrveranstaltungFromPruefung(lvId, pruefung_id) }).done(function(data){ if(data.error === "false") { - messageBox("message", "t('pruefung/lvErfolgreichEntfernt'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/lvErfolgreichEntfernt'); ?>", "green", "highlight", 10000); } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } }).always(function(){ loadPruefungsDetails(pruefung_id); @@ -1917,11 +1921,11 @@ function stornoPruefung(pruefung_id) }).done(function(data){ if(data.error === "false") { - messageBox("message", "t('pruefung/pruefungStorniert'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/pruefungStorniert'); ?>", "green", "highlight", 10000); } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } }).always(function(){ loadAllPruefungen(); @@ -1950,11 +1954,11 @@ function terminLoeschen(pruefung_id, pruefungstermin_id) }).done(function(data){ if(data.error === "false") { - messageBox("message", "t('pruefung/terminGeloescht'); ?>", "green", "highlight", 1000); + messageBox("message", "t('pruefung/terminGeloescht'); ?>", "green", "highlight", 10000); } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } }).always(function(){ loadPruefungsDetails(pruefung_id); @@ -2009,7 +2013,7 @@ function loadAllPruefungen() } else { - messageBox("message", data.errormsg, "red", "highlight", 1000); + messageBox("message", data.errormsg, "red", "highlight", 10000); } }).always(function(event, xhr, settings){ if($("#prfTable")[0].hasInitialized !== true) From d5019289f5bcd55ec76034e7bcb8706e7825b431 Mon Sep 17 00:00:00 2001 From: Nikolaus Krondraf Date: Thu, 4 Jun 2020 09:49:33 +0200 Subject: [PATCH 127/265] =?UTF-8?q?Absolventen=20k=C3=B6nnen=20sich=20nun?= =?UTF-8?q?=20auch=20zu=20Pr=C3=BCfungen=20anmelden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lehre/pruefung/pruefungsanmeldung.json.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cis/private/lehre/pruefung/pruefungsanmeldung.json.php b/cis/private/lehre/pruefung/pruefungsanmeldung.json.php index ce7479cf0..d52236861 100644 --- a/cis/private/lehre/pruefung/pruefungsanmeldung.json.php +++ b/cis/private/lehre/pruefung/pruefungsanmeldung.json.php @@ -612,13 +612,14 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) $stdsem = $aktStudiensemester; $prestudenten = array(); + $gueltigerStatus = array("Student", "Unterbrecher", "Absolvent"); foreach ($prestudent->result as $ps) { // prüfen ob Student zum Zeitpunkt der LV oder zumindest irgendwann Student im Studiengang war/ist if ($ps->getLaststatus($ps->prestudent_id, $stdsem_lv_besuch) || $ps->studiengang_kz == $studiengang_kz) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher") || ($ps->status_kurzbz == "")) + if (in_array($ps->status_kurzbz, $gueltigerStatus) || ($ps->status_kurzbz == "")) { array_push($prestudenten, $ps); } @@ -634,7 +635,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) { if ($ps->getLaststatus($ps->prestudent_id, $stdsem)) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher")) + if (in_array($ps->status_kurzbz, $gueltigerStatus)) { $prestudent_id = $ps->prestudent_id; } @@ -642,7 +643,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) { if ($ps->getLaststatus($ps->prestudent_id, $stdsem_lv_besuch)) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher")) + if (in_array($ps->status_kurzbz, $gueltigerStatus)) { $prestudent_id = $ps->prestudent_id; } @@ -653,7 +654,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) { if ($ps->getLaststatus($ps->prestudent_id, $stdsem_lv_besuch)) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher")) + if (in_array($ps->status_kurzbz, $gueltigerStatus)) { $prestudent_id = $ps->prestudent_id; } @@ -667,7 +668,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) { if ($ps->getLaststatus($ps->prestudent_id, $stdsem)) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher")) + if (in_array($ps->status_kurzbz, $gueltigerStatus)) { $prestudent_id = $ps->prestudent_id; } @@ -675,7 +676,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) { if ($ps->getLaststatus($ps->prestudent_id, $stdsem_lv_besuch)) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher")) + if (in_array($ps->status_kurzbz, $gueltigerStatus)) { $prestudent_id = $ps->prestudent_id; } @@ -686,7 +687,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) { if ($ps->getLaststatus($ps->prestudent_id, $stdsem_lv_besuch)) { - if (($ps->status_kurzbz == "Student") || ($ps->status_kurzbz == "Unterbrecher")) + if (in_array($ps->status_kurzbz, $gueltigerStatus)) { $prestudent_id = $ps->prestudent_id; } From 742c9fa8572745b9f7c4a570bf6bb4550eac30df Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 4 Jun 2020 11:33:58 +0200 Subject: [PATCH 128/265] Check that user is an active employee in message-cronjob Signed-off-by: Cris --- application/models/CL/Messages_model.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index ac3a16e3e..f24e16086 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -467,8 +467,9 @@ class Messages_model extends CI_Model $prestudentsData = $this->PrestudentModel->getOrganisationunits($prestudents); - // Get the senders uid + // Get the senders uid (if user is an active employee) $this->BenutzerModel->addSelect('uid'); + $this->BenutzerModel->addJoin('public.tbl_mitarbeiter ma', 'ma.mitarbeiter_uid = uid'); if (!$result = getData($this->BenutzerModel->getFromPersonId($sender_id))) { show_error('No sender_uid found'); From c2e9d2790900ae4682bdb0f248fc01deceb2cfec Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 9 Jun 2020 13:09:35 +0200 Subject: [PATCH 129/265] - Pruefungsprotokoll can be saved even when no grade provided - removed console log --- public/js/lehre/pruefungsprotokoll.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/js/lehre/pruefungsprotokoll.js b/public/js/lehre/pruefungsprotokoll.js index b14bc6153..8cb72cbf6 100644 --- a/public/js/lehre/pruefungsprotokoll.js +++ b/public/js/lehre/pruefungsprotokoll.js @@ -33,7 +33,6 @@ $("document").ready(function() { var error = checkFields[i]; $.each(error, function(i, n) { - console.log($("#"+i).closest('td')); $("#"+i).closest('td').addClass('has-error'); if (errortext !== '') errortext += '; '; @@ -84,7 +83,7 @@ var Pruefungsprotokoll = { { var errors = []; - if (data.abschlussbeurteilung_kurzbz == "" && verfChecked) + if (data.abschlussbeurteilung_kurzbz == "" && data.freigabedatum === true && verfChecked) errors.push({"abschlussbeurteilung_kurzbz": FHC_PhrasesLib.t("abschlusspruefung", "abschlussbeurteilungLeer")}); var zeitregex = /^[0-2][0-9]:[0-5][0-9]$/; From 7ce489e8472f816f5e01e0c73ec0d0192a8b1f8f Mon Sep 17 00:00:00 2001 From: alex Date: Wed, 10 Jun 2020 10:11:19 +0200 Subject: [PATCH 130/265] - added iso3166_1_a3 field to bis.tbl_nation - person/kontakt_model: renamed getFirmenTelefon to getFirmentelefon, separated vorwahl from telefonklappe --- application/models/person/Kontakt_model.php | 8 ++++---- system/dbupdate_3.3.php | 14 +++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/application/models/person/Kontakt_model.php b/application/models/person/Kontakt_model.php index 36ba05be4..33dc66c86 100644 --- a/application/models/person/Kontakt_model.php +++ b/application/models/person/Kontakt_model.php @@ -80,10 +80,10 @@ class Kontakt_model extends DB_Model } /** - * Gets Firmentelefon for a uid, can be Vorwahl with Telefonklappe or Formenhandy + * Gets Firmentelefon for a uid, can be Vorwahl with Telefonklappe or Firmenhandy * @param $uid */ - public function getFirmenTelefon($uid) + public function getFirmentelefon($uid) { $firmentelefon = success(array()); @@ -103,7 +103,7 @@ class Kontakt_model extends DB_Model if (hasData($firmenhandy)) { $firmenhandy = getData($firmenhandy); - $firmentelefon = success($firmenhandy[0]->kontakt); + $firmentelefon = success(array('kontakt' => $firmenhandy[0]->kontakt, 'telefonklappe' => '')); } } else @@ -113,7 +113,7 @@ class Kontakt_model extends DB_Model { $vorwahl = getData($firmaKontakttyp); $vorwahl = $vorwahl[0]->kontakt; - $firmentelefon = success(array($vorwahl.'-'.$mitarbeiter[0]->telefonklappe)); + $firmentelefon = success(array('kontakt' => $vorwahl, 'telefonklappe' => $mitarbeiter[0]->telefonklappe)); } } } diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index b54b28373..504a048a1 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -4019,6 +4019,18 @@ if (!$result = @$db->db_query('SELECT 1 FROM system.tbl_jobtriggers LIMIT 1')) echo '
    Granted privileges to vilesci on system.tbl_jobtriggers'; } +// Add column iso3166_1_a3 to tbl_nation +if(!$result = @$db->db_query("SELECT iso3166_1_a3 FROM bis.tbl_nation LIMIT 1")) +{ + $qry = "ALTER table bis.tbl_nation ADD COLUMN iso3166_1_a3 VARCHAR(3); + COMMENT ON COLUMN bis.tbl_nation.iso3166_1_a3 IS 'ISO 3166-1 alpha-3 country code';"; + + if(!$db->db_query($qry)) + echo 'bis.tbl_nation: '.$db->db_last_error().'
    '; + else + echo '
    bis.tbl_nation: Spalte iso3166_1_a3 hinzugefuegt'; +} + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

    Pruefe Tabellen und Attribute!

    '; @@ -4048,7 +4060,7 @@ $tabellen=array( "bis.tbl_mobilitaet" => array("mobilitaet_id","prestudent_id","mobilitaetstyp_kurzbz","studiensemester_kurzbz","mobilitaetsprogramm_code","gsprogramm_id","firma_id","status_kurzbz","ausbildungssemester","insertvon","insertamum","updatevon","updateamum"), "bis.tbl_mobilitaetstyp" => array("mobilitaetstyp_kurzbz","bezeichnung","aktiv"), "bis.tbl_mobilitaetsprogramm" => array("mobilitaetsprogramm_code","kurzbz","beschreibung","sichtbar","sichtbar_outgoing"), - "bis.tbl_nation" => array("nation_code","entwicklungsstand","eu","ewr","kontinent","kurztext","langtext","engltext","sperre","nationengruppe_kurzbz"), + "bis.tbl_nation" => array("nation_code","entwicklungsstand","eu","ewr","kontinent","kurztext","langtext","engltext","sperre","nationengruppe_kurzbz","iso3166_1_a3"), "bis.tbl_nationengruppe" => array("nationengruppe_kurzbz","nationengruppe_bezeichnung","aktiv"), "bis.tbl_orgform" => array("orgform_kurzbz","code","bezeichnung","rolle","bisorgform_kurzbz","bezeichnung_mehrsprachig"), "bis.tbl_verwendung" => array("verwendung_code","verwendungbez"), From e8272a17579312d77e33aa770ff13df1369b91f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Mon, 15 Jun 2020 14:33:42 +0200 Subject: [PATCH 131/265] =?UTF-8?q?Datenverbund=20Schnittstelle=20UUID=20z?= =?UTF-8?q?u=20Simple=20Requests=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/dvb.class.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/dvb.class.php b/include/dvb.class.php index 78bde58c0..1f4b7d5d1 100644 --- a/include/dvb.class.php +++ b/include/dvb.class.php @@ -394,10 +394,12 @@ class dvb extends basis_db $this->debug('getMatrikelnrBySVNR'); + $uuid = $this->getUUID(); $curl = curl_init(); $url = self::DVB_URL_WEBSERVICE_SVNR; $url .= '?sozialVersicherungsNummer='.curl_escape($curl, $svnr); + $url .= '&uuid='.curl_escape($curl, $uuid); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); @@ -507,9 +509,10 @@ class dvb extends basis_db $this->debug('getMatrikelnrByErsatzkennzeichen'); $curl = curl_init(); - + $uuid = $this->getUUID(); $url = self::DVB_URL_WEBSERVICE_ERSATZKZ; $url .= '?ersatzKennzeichen='.curl_escape($curl, $ersatzkennzeichen); + $url .= '&uuid='.curl_escape($curl, $uuid); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); @@ -1349,9 +1352,12 @@ class dvb extends basis_db $geburtsdatum = str_replace("-", "", $geburtsdatum); + $uuid = $this->getUUID(); + $url = self::DVB_URL_WEBSERVICE_NACHNAME; $url .= '?nachName='.curl_escape($curl, $nachname); $url .= '&geburtsDatum='.curl_escape($curl, $geburtsdatum); + $url .= '&uuid='.curl_escape($curl, $uuid); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); @@ -1472,11 +1478,13 @@ class dvb extends basis_db $curl = curl_init(); $geburtsdatum = str_replace("-", "", $geburtsdatum); + $uuid = $this->getUUID(); $url = self::DVB_URL_WEBSERVICE_NAME; $url .= '?nachName='.curl_escape($curl, $nachname); $url .= '&vorName='.curl_escape($curl, $vorname); $url .= '&geburtsDatum='.curl_escape($curl, $geburtsdatum); + $url .= '&uuid='.curl_escape($curl, $uuid); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); From 596494708d3a6f5c4db10ee343d85b13bf472ac2 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 17 Jun 2020 14:57:01 +0200 Subject: [PATCH 132/265] CL/Messages_model->prepareHtmlRead changed to redirect to an authenticated controller to reply to a message in case the receiver is the the system sender --- application/models/CL/Messages_model.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/application/models/CL/Messages_model.php b/application/models/CL/Messages_model.php index f023c9150..17824bbb8 100644 --- a/application/models/CL/Messages_model.php +++ b/application/models/CL/Messages_model.php @@ -284,9 +284,11 @@ class Messages_model extends CI_Model $sender = getData($senderResult)[0]; // Found sender data - // If the sender is not the system sender and are present configurations to reply + // If the sender is not the system sender and the receiver is not the system sender + // and are present configurations to reply $hrefReply = ''; if ($message->sender_id != $this->config->item(MessageLib::CFG_SYSTEM_PERSON_ID) + && $message->receiver_id != $this->config->item(MessageLib::CFG_SYSTEM_PERSON_ID) && !isEmptyString($this->config->item(MessageLib::CFG_REDIRECT_VIEW_MESSAGE_URL))) { $hrefReply = $this->config->item(MessageLib::CFG_MESSAGE_SERVER). @@ -294,6 +296,13 @@ class Messages_model extends CI_Model $token; } + // If the receiver is the system sender (the message was sent to an organization unit) + // redirect the reply to an authenticated controller to reply + if ($message->receiver_id == $this->config->item(MessageLib::CFG_SYSTEM_PERSON_ID)) + { + $hrefReply = site_url('system/messages/MessageClient/writeReply?token='.$token); + } + return array ( 'sender' => $sender, 'message' => $message, From 8a52169bdafc10f3d0218a5a6af227dc6909aa06 Mon Sep 17 00:00:00 2001 From: Manfred Kindl Date: Thu, 18 Jun 2020 13:58:22 +0200 Subject: [PATCH 133/265] Textkorrektur Diplomasupplement --- rdf/diplomasupplement.xml.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rdf/diplomasupplement.xml.php b/rdf/diplomasupplement.xml.php index 742de2c5f..a88df9533 100644 --- a/rdf/diplomasupplement.xml.php +++ b/rdf/diplomasupplement.xml.php @@ -266,7 +266,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml") echo ' UNESCO ISCED 7'; echo ' '; echo ' '; - echo ' '; + echo ' '; echo ' '; echo ' '; echo ' '; @@ -278,8 +278,8 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml") echo ' UNESCO ISCED 6'; echo ' '; echo ' '; - echo ' '; - echo ' '; + echo ' '; + echo ' '; echo ' '; echo ' '; echo ' Bachelorstudium (UNESCO ISCED 6)'; From 7604b0ae64111411915d889a3624fc0a53082a2a Mon Sep 17 00:00:00 2001 From: Manfred Kindl Date: Thu, 18 Jun 2020 13:59:01 +0200 Subject: [PATCH 134/265] Anzeige Protokoll im FAS --- content/student/studentabschlusspruefung.js.php | 2 ++ content/student/studentabschlusspruefungoverlay.xul.php | 2 ++ rdf/abschlusspruefung.rdf.php | 1 + 3 files changed, 5 insertions(+) diff --git a/content/student/studentabschlusspruefung.js.php b/content/student/studentabschlusspruefung.js.php index caaa32051..f46d7b2b9 100644 --- a/content/student/studentabschlusspruefung.js.php +++ b/content/student/studentabschlusspruefung.js.php @@ -352,6 +352,7 @@ function StudentAbschlusspruefungAuswahl() sponsion = getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#sponsion" )); pruefungstyp_kurzbz = getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#pruefungstyp_kurzbz" )); anmerkung = getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#anmerkung" )); + protokoll = getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#protokoll" )); stg_kz = studiengang_kz = document.getElementById('student-detail-menulist-studiengang_kz').value; @@ -410,6 +411,7 @@ function StudentAbschlusspruefungAuswahl() document.getElementById('student-abschlusspruefung-textbox-anmerkung').value=anmerkung; document.getElementById('student-abschlusspruefung-textbox-abschlusspruefung_id').value=abschlusspruefung_id; document.getElementById('student-abschlusspruefung-checkbox-neu').checked=false; + document.getElementById('student-abschlusspruefung-textbox-protokoll').value=protokoll; StudentAbschlusspruefungTypChange(); } diff --git a/content/student/studentabschlusspruefungoverlay.xul.php b/content/student/studentabschlusspruefungoverlay.xul.php index e281a7a16..0f52650ec 100644 --- a/content/student/studentabschlusspruefungoverlay.xul.php +++ b/content/student/studentabschlusspruefungoverlay.xul.php @@ -339,6 +339,8 @@ echo ''; +
  • From 153ca3a9617fb4a725457f80a5f302df8ec8aaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Mon, 31 Aug 2020 20:37:21 +0200 Subject: [PATCH 184/265] Bei der archivierung von Ausbildungsvertraegen wird die UID nicht uebergeben da diese sonst doppelt erstellt werden wenn die Person bereits inskribiert ist --- content/student/studentoverlay.js.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/content/student/studentoverlay.js.php b/content/student/studentoverlay.js.php index 2b511a0de..bea20cb8e 100644 --- a/content/student/studentoverlay.js.php +++ b/content/student/studentoverlay.js.php @@ -3205,6 +3205,11 @@ function StudentZeugnisDokumentArchivieren() alert('Dieses Dokument kann nur für Studierende erstellt werden. Mindestens eine ausgewählte Person hat keine UID'); continue; } + if(vorlage == 'Ausbildungsver' || vorlage == 'AusbVerEng') + { + // Ausbildungsvertrag nimmt nur PrestudentID + uid = ''; + } var req = new phpRequest(url,'',''); req.add('xsl', vorlage); From 1e97ac7278e08444c5f0d6ded3f60cdf0054a8dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Tue, 1 Sep 2020 19:40:16 +0200 Subject: [PATCH 185/265] =?UTF-8?q?UUID=20f=C3=BCr=20Matrikelnummernabfrag?= =?UTF-8?q?e=20hinzugef=C3=BCgt=20damit=20eine=20manuelle=20Suche=20nach?= =?UTF-8?q?=20Matrikelnummer=20m=C3=B6glich=20ist?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/dvb.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/dvb.class.php b/include/dvb.class.php index 1a1f867d9..0eab0e3f0 100644 --- a/include/dvb.class.php +++ b/include/dvb.class.php @@ -1608,8 +1608,11 @@ class dvb extends basis_db $curl = curl_init(); - $url = self::DVB_URL_WEBSERVICE_MATRIKELNUMMER; + $uuid = $this->getUUID(); + + $url = self::DVB_URL_WEBSERVICE_MATRIKELNUMMER; $url .= '?matrikelNummer='.curl_escape($curl, $matrikelnr); + $url .= '&uuid='.curl_escape($curl, $uuid); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); From 82ceb274502c125498bd92ae6a2698c3f1737092 Mon Sep 17 00:00:00 2001 From: Nikolaus Krondraf Date: Thu, 3 Sep 2020 13:08:33 +0200 Subject: [PATCH 186/265] =?UTF-8?q?Filter=20f=C3=BCr=20Semester=20entfernt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lehre/pruefung/pruefungsanmeldung.php | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/cis/private/lehre/pruefung/pruefungsanmeldung.php b/cis/private/lehre/pruefung/pruefungsanmeldung.php index 545c28d66..c969c51aa 100644 --- a/cis/private/lehre/pruefung/pruefungsanmeldung.php +++ b/cis/private/lehre/pruefung/pruefungsanmeldung.php @@ -187,22 +187,15 @@ $studiensemester->getAll(); ".$p->t('pruefung/anmeldungFuer')." ".$benutzer->vorname." ".$benutzer->nachname." (".$uid.")"; - echo '

    '.$p->t('pruefung/filter').'

    '; - echo '

    '.$p->t('global/studiensemester').': '; + echo '

    '.$p->t('pruefung/filter').'

    '; + echo '

    '.$p->t('global/studiensemester').': '; echo '

    '; ?>
    @@ -241,7 +234,7 @@ $studiensemester->getAll();
    -
    +