diff --git a/application/config/Events.php b/application/config/Events.php new file mode 100644 index 000000000..191a1eb98 --- /dev/null +++ b/application/config/Events.php @@ -0,0 +1,14 @@ + 'TEST', + 'component' => './Stv/Studentenverwaltung/Details/Notizen.js' + ]; + }); + */ diff --git a/application/config/db_crypt.php b/application/config/db_crypt.php new file mode 100644 index 000000000..b9360861b --- /dev/null +++ b/application/config/db_crypt.php @@ -0,0 +1,29 @@ +. + */ + +if (!defined('BASEPATH')) exit('No direct script access allowed'); + +// NOTE: if database encryption is _not_ used then leave this array empty! +$config['encryption_passwords'] = array( + // 'password name 1' => 'password 1' + // 'password name 2' => 'password 2' + // 'password name ...' => 'password ...' + // 'password name N' => 'password N' +); + diff --git a/application/config/navigation.php b/application/config/navigation.php index 56d142d08..3680930d0 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -31,6 +31,14 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 20, 'requiredPermissions' => 'admin:w' + ), + 'bismeldestichtagsverwaltung' => array( + 'link' => site_url('codex/Bismeldestichtag'), + 'icon' => '', + 'description' => 'BIS-Meldestichtagsverwaltung', + 'expand' => true, + 'sort' => 30, + 'requiredPermissions' => 'admin:w' ) ) ), diff --git a/application/config/studierendenantrag.php b/application/config/studierendenantrag.php new file mode 100644 index 000000000..4e25aef28 --- /dev/null +++ b/application/config/studierendenantrag.php @@ -0,0 +1,170 @@ + null, 'dokument_kurzbz' => null, 'kategorie_kurzbz' => null]; +$config['unterbrechung_dms'] = ['oe_kurzbz' => null, 'dokument_kurzbz' => null, 'kategorie_kurzbz' => 'Akte']; + +/** + * UPLOAD + */ + +/** + * Allowed filetypes for attachment upload in unterbrechung antrag + * + * @var array An array of fileextensions + */ +$config['unterbrechung_dms_filetypes'] = ['jpg', 'pdf']; + + +/** + * GRADES + */ + +/** + * On wiederholung the student must repeat certain lvs. + * This lvs will be graded with this id + * + * @var integer tbl_note.note + */ +$config['wiederholung_note_angerechnet'] = 19; + +/** + * On wiederholung the student can not attend certain lvs. + * Those lvs will be graded with this id + * + * @var integer tbl_note.note + */ +$config['wiederholung_note_nicht_zugelassen'] = 20; + + +/** + * JOBS + */ + +/** + * The Job will remind for every Unterbrecher who has a + * wiedereinstieg_datum between the date the Job is run + * and the modified date + * e.g.: If the Job is running on 2023-04-20 and the modifier + * is '+3 days' it will remind of everyone that + * has a wiedereinstiegs_datum between 2023-04-20 and 2023-04-23 + * + * @var string A string formated as PHP DateTime modifier + * @see https://www.php.net/manual/de/datetime.modify.php + */ +$config['unterbrechung_job_remind_wiedereinstieg_date_modifier'] = '+3 days'; + +/** + * The Job will sent a request to everyone who faild the 3rd committee exam + * and respecting the given conditions (not repeated yet, stg not in blacklist) + * to decide if he/she will repeat or not + * + * First request + * + * @var string A string formated as PHP DateTime modifier + * @see https://www.php.net/manual/de/datetime.modify.php + */ +$config['wiederholung_job_request_1_date_modifier'] = '+0 days'; + +/** + * Second request + * + * @var string A string formated as PHP DateTime modifier + * @see https://www.php.net/manual/de/datetime.modify.php + */ +$config['wiederholung_job_request_2_date_modifier'] = '+3 weeks'; + +/** + * Final deadline - after this the student will be abgemeldet if he hasn't chosen yet + * + * @var string A string formated as PHP DateTime modifier + * @see https://www.php.net/manual/de/datetime.modify.php + */ +$config['wiederholung_job_deadline_date_modifier'] = '+1 month'; + +/** + * before this exam dates for Wiederholer will be ignored + * + * @var string A string formated as Date + * + */ +$config['digitalization_start'] = '2022-07-01'; + + + + +/** + * Objection period - the student will be abgemeldet if he hasn't objected in this period + * + * @var string A string formated as PHP DateTime modifier + * @see https://www.php.net/manual/de/datetime.modify.php + */ +$config['abmeldung_job_deadline_date_modifier'] = '+2 weeks'; + + + +/** + * System User - uid of a user that is allowed to set prestudentstatus + * + * @var string + */ +$config['antrag_job_systemuser'] = ''; + + +/** + * WHITELISTS + */ + +/** + * List of stati who entitle a prestudent to create an Antrag + * + * @var array Array of tbl_status.status_kurzbz's + */ +$config['antrag_prestudentstatus_whitelist'] = ['Student', 'Diplomand']; +$config['antrag_prestudentstatus_whitelist_abmeldung'] = ['Student', 'Diplomand', 'Unterbrecher']; + + +/** + * BLACKLISTS + */ + +/** + * List of Statusgründe that prevent a prestudent from create an Wiederholungsantrag + * + * @var array An array of tbl_status_grund.statusgrund_id's + */ +$config['status_gruende_wiederholer'] = [16, 15]; + +/** + * Blacklisted for abmeldung anträge + * + * @var array An array of tbl_studiengang.studiengang_kz's + */ +$config['stgkz_blacklist_abmeldung'] = []; + +/** + * Blacklisted for unterbrechung anträge + * + * @var array An array of tbl_studiengang.studiengang_kz's + */ +$config['stgkz_blacklist_unterbrechung'] = []; + +/** + * Blacklisted for wiederholung anträge + * + * @var array An array of tbl_studiengang.studiengang_kz's + */ +$config['stgkz_blacklist_wiederholung'] = []; + +/** + * Blacklisted noten for negative committee exams + * noten with this ids won't be seen as negative + * + * @var array An array of noten ids + */ +$config['note_blacklist_wiederholung'] = []; diff --git a/application/controllers/Test.php b/application/controllers/Test.php new file mode 100644 index 000000000..2a7aa4e4e --- /dev/null +++ b/application/controllers/Test.php @@ -0,0 +1,16 @@ + 'admin:r', + 'getStudiensemester' => 'admin:r', + 'getBismeldestichtage' => 'admin:r', + 'addBismeldestichtag' => 'admin:rw', + 'deleteBismeldestichtag' => 'admin:rw' + ) + ); + + // Load models + $this->load->model('codex/Bismeldestichtag_model', 'BismeldestichtagModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + // Loads phrases system + $this->loadPhrases( + array( + 'bismeldestichtag' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index() + { + $this->load->view('codex/bismeldestichtag.php'); + } + + public function getStudiensemester() + { + // load semester list + $semList = array(); + $this->StudiensemesterModel->addSelect('studiensemester_kurzbz'); + $this->StudiensemesterModel->addOrder('start', 'DESC'); + $semRes = $this->StudiensemesterModel->load(); + + if (hasData($semRes)) + { + $semList = getData($semRes); + } + + // load current semester + $currSem = null; + $semRes = $this->StudiensemesterModel->getAkt(); + + if (hasData($semRes)) + { + $currSem = getData($semRes)[0]->studiensemester_kurzbz; + } + + // output data + $this->outputJsonSuccess( + array('semList' => $semList, 'currSem' => $currSem) + ); + } + + public function getBismeldestichtage() + { + $this->BismeldestichtagModel->addSelect( + 'meldestichtag_id, meldestichtag, + tbl_bismeldestichtag.studiensemester_kurzbz, sem.start AS semester_start, + tbl_bismeldestichtag.insertamum, tbl_bismeldestichtag.insertvon, tbl_bismeldestichtag.updateamum, tbl_bismeldestichtag.updatevon' + ); + $this->BismeldestichtagModel->addJoin('public.tbl_studiensemester sem', 'studiensemester_kurzbz', 'LEFT'); + $this->BismeldestichtagModel->addOrder('semester_start'); + $this->BismeldestichtagModel->addOrder('meldestichtag', 'DESC'); + $this->BismeldestichtagModel->addOrder('meldestichtag_id', 'DESC'); + $this->outputJson($this->BismeldestichtagModel->load()); + } + + public function addBismeldestichtag() + { + // get request data + $request = $this->getPostJSON(); + + // check request data + if (!property_exists($request, 'meldestichtag') || isEmptyString($request->meldestichtag)) + $this->terminateWithJsonError('Error occured: Meldestichtag missing'); + if (!property_exists($request, 'studiensemester_kurzbz') || isEmptyString($request->studiensemester_kurzbz)) + $this->terminateWithJsonError('Error occured: Studiensemester missing'); + + $meldestichtag = $request->meldestichtag; + $studiensemester_kurzbz = $request->studiensemester_kurzbz; + + // check if Bismeldestichtag already exists + $this->BismeldestichtagModel->addSelect('1'); + $bismeldestichtagRes = $this->BismeldestichtagModel->loadWhere( + array('meldestichtag' => $meldestichtag, 'studiensemester_kurzbz' => $studiensemester_kurzbz) + ); + + // return success if already exists + if (hasData($bismeldestichtagRes)) + $this->outputJsonSuccess('Bismeldestichtag already exists'); + else + { + // insert new if Stichtag does not exist + $this->outputJson($this->BismeldestichtagModel->insert( + array( + 'meldestichtag' => $request->meldestichtag, + 'studiensemester_kurzbz' => $request->studiensemester_kurzbz, + 'insertvon' => getAuthUID() + ) + )); + } + } + + public function deleteBismeldestichtag() + { + // get request data + $request = $this->getPostJSON(); + + // check request data + if (!property_exists($request, 'meldestichtag_id')) + $this->terminateWithJsonError('Error occured: Meldestichtag Id missing'); + + $meldestichtag_id = $request->meldestichtag_id; + + // deletetion + $this->outputJson($this->BismeldestichtagModel->delete($meldestichtag_id)); + } +} diff --git a/application/controllers/codex/UHSTAT1.php b/application/controllers/codex/UHSTAT1.php new file mode 100644 index 000000000..4486f9d74 --- /dev/null +++ b/application/controllers/codex/UHSTAT1.php @@ -0,0 +1,438 @@ +load->library('form_validation'); + + // load ci helpers + $this->load->helper(array('form', 'url')); + + // load libraries + $this->load->library('AuthLib'); + $this->load->library('PermissionLib'); + + // load models + $this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->load->model('codex/Abschluss_model', 'AbschlussModel'); + $this->load->model('codex/Uhstat1daten_model', 'Uhstat1datenModel'); + + $this->loadPhrases( + array( + 'ui', + 'uhstat' + ) + ); + + $this->_uid = getAuthUID(); + + // set form field information + $this->_uhstat1Fields = array( + 'mutter_geburtsstaat' => array('name' => 'Geburtsstaat Mutter'), + 'mutter_geburtsjahr' => array('name' => 'Geburtsjahr Mutter'), + 'mutter_bildungsstaat' => array('name' => 'Bildungsstaat Mutter'), + 'mutter_bildungmax' => array( + 'name' => 'Geburtsjahr Mutter', + 'rules' => array( + 'callback_bildungsstaat_bildungmax_check[m]' => array( + 'bildungsstaat_bildungmax_check' => $this->p->t('uhstat', 'ausbildungBildungsstaatUebereinstimmung') + ) + ) + ), + 'vater_geburtsstaat' => array('name' => 'Geburtsstaat Vater'), + 'vater_geburtsjahr' => array('name' => 'Geburtsjahr Vater'), + 'vater_bildungsstaat' => array('name' => 'Bildungsstaat Vater'), + 'vater_bildungmax' => array('name' => 'Geburtsjahr Vater'), + 'vater_bildungmax' => array( + 'name' => 'Geburtsjahr Vater', + 'rules' => array( + 'callback_bildungsstaat_bildungmax_check[v]' => array( + 'bildungsstaat_bildungmax_check' => $this->p->t('uhstat', 'ausbildungBildungsstaatUebereinstimmung') + ) + ) + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + public function index() + { + $formMetaData = $this->_getFormMetaData(); + + if (isError($formMetaData)) show_error(getError($formMetaData)); + + if (!hasData($formMetaData)) show_error("No form meta data could be loaded"); + + $uhstatData = $this->_getUHSTAT1Data(); + + if (isError($uhstatData)) show_error(getError($uhstatData)); + + $this->load->view("codex/uhstat1.php", array( + 'formMetaData' => getData($formMetaData), + 'uhstatData' => getData($uhstatData) + ) + ); + } + + /** + * Add or update UHSTAT1 data + */ + public function saveUHSTAT1Data() + { + $saved = false; + + $person_id = $this->_getValidPersonId('sui'); + + $this->form_validation->set_error_delimiters('', ''); + + foreach ($this->_uhstat1Fields as $field => $params) + { + // all fields are required + $ruleNames = 'required'; + $ruleMessages = array('required' => $this->p->t('uhstat', 'angabeFehlt')); + + // add additional rules + if (isset($params['rules'])) + { + foreach ($params['rules'] as $ruleName => $ruleMessage) + { + $ruleNames .= '|'.$ruleName; + $ruleMessages = array_merge($ruleMessages, $ruleMessage); + } + } + + $this->form_validation->set_rules( + $field, + $params['name'], + $ruleNames, + $ruleMessages + ); + } + + $uhstat1datenRes = null; + if ($this->form_validation->run()) // if valid + { + // get post fields + $uhstatData = array(); + foreach ($this->_uhstat1Fields as $field => $params) + { + $uhstatData[$field] = $this->input->post($field); + } + + // check if entry already exists + $uhstat1datenloadRes = $this->Uhstat1datenModel->loadWhere(array('person_id' => $person_id)); + + // if yes, update + if (hasData($uhstat1datenloadRes)) + { + $uhstatData['updateamum'] = 'NOW()'; + $uhstatData['updatevon'] = $this->_uid; + $uhstat1datenRes = $this->Uhstat1datenModel->update( + array('person_id' => $person_id), + $uhstatData + ); + } + else // otherwise insert + { + $uhstatData['insertamum'] = 'NOW()'; + $uhstatData['insertvon'] = $this->_uid; + $uhstat1datenRes = $this->Uhstat1datenModel->insert( + array_merge($uhstatData, array('person_id' => $person_id)) + ); + } + } + + $formMetaData = $this->_getFormMetaData(); + + if (isError($formMetaData)) show_error(getError($formMetaData)); + + if (!hasData($formMetaData)) show_error("No form meta data could be loaded"); + + $successMessage = ''; + $errorMessage = ''; + // pass success/error messages to view + if (isset($uhstat1datenRes)) + { + if (isSuccess($uhstat1datenRes)) + { + $successMessage = $this->p->t('uhstat', 'erfolgreichGespeichert'); + $saved = true; + } + else + $errorMessage = $this->p->t('uhstat', 'fehlerBeimSpeichern'); + } + + // load view with form data + $this->load->view("codex/uhstat1.php", array( + 'formMetaData' => getData($formMetaData), + 'saved' => $saved, + 'successMessage' => $successMessage, + 'errorMessage' => $errorMessage + ) + ); + } + + /** + * Check callback for Bildungsstaat - if Bildungsstaat is Austria, a highest education should be in Austria. + * @param $bildungmax + * @param $bildungsstaat_typ - mother (m) or father (v) + * @return bool true if valid, false otherwise + */ + public function bildungsstaat_bildungmax_check($bildungmax, $bildungsstaat_typ) + { + // valid if no type passed + if (!isset($bildungsstaat_typ) || !isset($bildungmax)) return true; + + // get correct input + if ($bildungsstaat_typ == 'm') // mutter + $bildungsstaat = $this->input->post('mutter_bildungsstaat'); + elseif ($bildungsstaat_typ == 'v') // vater + $bildungsstaat = $this->input->post('vater_bildungsstaat'); + else + return true; + + if (!isset($bildungsstaat)) return true; + + // find out if abschluss is in Austria + $this->AbschlussModel->addSelect("in_oesterreich"); + $abschlussRes = $this->AbschlussModel->load($bildungmax); + + if (hasData($abschlussRes)) + { + $in_oesterreich = getData($abschlussRes)[0]->in_oesterreich; + // invalid if abschluss in Austria, but not Bildungsstaat, or abschluss not in Austria, but Bildungsstaat in Austria + return ($in_oesterreich && $bildungsstaat == self::CODEX_OESTERREICH) || (!$in_oesterreich && $bildungsstaat != self::CODEX_OESTERREICH); + } + + return false; + } + + /** + * Deletes UHSTAT1 entry. + */ + public function deleteUHSTAT1Data() + { + $saved = false; + + // uhstat data can only be deleted with permission + if (!$this->_checkPermission('suid')) show_error('no permission'); + + $person_id = $this->_getValidPersonId('suid'); + + $uhstat1datenRes = $this->Uhstat1datenModel->delete( + array('person_id' => $person_id) + ); + + $formMetaData = $this->_getFormMetaData(); + + if (isError($formMetaData)) show_error(getError($formMetaData)); + + if (!hasData($formMetaData)) show_error("No form meta data could be loaded"); + + $successMessage = ''; + $errorMessage = ''; + // pass success/error messages to view + if (isset($uhstat1datenRes)) + { + if (isSuccess($uhstat1datenRes)) + { + $successMessage = $this->p->t('uhstat', 'erfolgreichGeloescht'); + } + else + $errorMessage = $this->p->t('uhstat', 'fehlerBeimLoeschen'); + } + + // load view with form data + $this->load->view("codex/uhstat1.php", array( + 'formMetaData' => getData($formMetaData), + 'successMessage' => $successMessage, + 'errorMessage' => $errorMessage + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Private methods + + /** + * Gets initial data needed to display UHSTAT1 form. + */ + private function _getFormMetaData() + { + $person_id = $this->_getValidPersonId('s'); + + // read only display param + $readOnly = $this->input->get('readOnly'); + + // depending on permissions, editing or deleting is possible + $editPermission = $this->_checkPermission('sui'); + $deletePermission = $this->_checkPermission('suid'); + + $languageIdx = $this->_getLanguageIndex(); + + $formMetaData = array( + 'nation' => array(), + 'abschluss_oesterreich' => array(), + 'abschluss_nicht_oesterreich' => array(), + 'jahre' => array(), + 'person_id' => $person_id, + 'editPermission' => $editPermission, + 'deletePermission' => $deletePermission, + 'readOnly' => $readOnly + ); + + // get person data + $this->load->model('person/Person_model', 'PersonModel'); + $this->PersonModel->addSelect("vorname, nachname"); + $personRes = $this->PersonModel->load($person_id); + + if (isError($personRes)) return $personRes; + + if (hasData($personRes)) + { + $person = getData($personRes)[0]; + $formMetaData['vorname'] = $person->vorname; + $formMetaData['nachname'] = $person->nachname; + } + + $nationTextFieldName = $languageIdx == 1 ? 'langtext' : 'engltext'; + + // get nation list + $this->load->model('codex/Nation_model', 'NationModel'); + + $this->NationModel->addSelect("nation_code, $nationTextFieldName AS nation_text"); + $this->NationModel->addOrder("nation_text"); + $nationRes = $this->NationModel->loadWhere('sperre IS NULL OR sperre = FALSE'); + + if (isError($nationRes)) return $nationRes; + + if (hasData($nationRes)) + { + $nations = getData($nationRes); + + // put austria in beginning of selection + foreach ($nations as $nation) + { + if ($nation->nation_code == self::CODEX_OESTERREICH) array_unshift($nations, $nation); + } + + $formMetaData['nation'] = $nations; + } + + // get abschluss list + $abschlussRes = $this->AbschlussModel->getActiveAbschluesse($languageIdx); + + if (isError($abschlussRes)) return $abschlussRes; + + $abschlussData = getData($abschlussRes); + + if (hasData($abschlussRes)) + { + foreach (getData($abschlussRes) as $abschluss) + { + if ($abschluss->in_oesterreich === true) + $formMetaData['abschluss_oesterreich'][] = $abschluss; + elseif ($abschluss->in_oesterreich === false) + $formMetaData['abschluss_nicht_oesterreich'][] = $abschluss; + else + { + $formMetaData['abschluss_oesterreich'][] = $abschluss; + $formMetaData['abschluss_nicht_oesterreich'][] = $abschluss; + } + } + } + + // get realistic birth years, dated back from current year + $currYear = date("Y"); + $formMetaData['jahre'] = range($currYear - self::UPPER_BOUNDARY_YEARS, $currYear - self::LOWER_BOUNDARY_YEARS); + + return success($formMetaData); + } + + /** + * Gets initial data needed to display UHSTAT1 form. + */ + private function _getUHSTAT1Data() + { + $person_id = $this->_getValidPersonId('s'); + + $this->Uhstat1datenModel->addSelect( + implode(', ', array_keys($this->_uhstat1Fields)) + ); + $uhstatRes = $this->Uhstat1datenModel->loadWhere(array('person_id' => $person_id)); + + if (isError($uhstatRes)) return $uhstatRes; + + return success(hasData($uhstatRes) ? getData($uhstatRes)[0] : null); + } + + /** + * Gets language index of currently logged in user. + * @return int (the index, start at 1) + */ + private function _getLanguageIndex() + { + $idx = 1; + $this->SpracheModel->addSelect('index'); + $langRes = $this->SpracheModel->loadWhere(array('sprache' => getUserLanguage())); + + if (hasData($langRes)) + { + $idx = getData($langRes)[0]->index; + } + + return $idx; + } + + /** + * Gets Id of person having permissions to manage UHSTAT1 data. + * Can be passed as parameter or be in session. + * @return int person_id + */ + private function _getValidPersonId($berechtigungsArt) + { + // if coming from bewerbungstool - person id is in session (person must be logged in bewerbungstool) + if (isset($_SESSION[self::PERSON_ID_SESSION_INDEX]) && is_numeric($_SESSION[self::PERSON_ID_SESSION_INDEX])) + return $_SESSION[self::PERSON_ID_SESSION_INDEX]; + + // if person id passed directly... + $person_id = $this->input->post('person_id'); + if (!isset($person_id)) $person_id = $this->input->get('person_id'); + + if (!isset($person_id) || !is_numeric($person_id)) show_error("invalid person id"); + + // ...check if there is a permission for editing UHSTAT1 data + if ($this->_checkPermission($berechtigungsArt)) return $person_id; + + show_error("No permission"); + } + + /** + * Checks if logged user has the UHSTAT management permission. + * @param $art - type of permission, e.g. suid for full permissions + * @return bool + */ + private function _checkPermission($art) + { + return $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_UHSTAT_VERWALTEN, $art); + } +} diff --git a/application/controllers/components/Antrag/Abmeldung.php b/application/controllers/components/Antrag/Abmeldung.php new file mode 100644 index 000000000..f30de6803 --- /dev/null +++ b/application/controllers/components/Antrag/Abmeldung.php @@ -0,0 +1,218 @@ +load->library('AuthLib'); + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag' + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data of the current studiengang for the current user + */ + + public function getDetailsForNewAntrag($prestudent_id) + { + if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, true)) { + $this->output->set_status_header(403); + return $this->outputJsonError('Forbidden'); + } + $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id); + if (isError($result)) { + $this->output->set_status_header(500); + return $this->outputJsonError(getError($result)); + } + $result = $result->retval; + if (!$result) { + $this->output->set_status_header(403); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student')); + } + elseif ($result == -3) + { + $this->output->set_status_header(403); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist')); + } + elseif ($result == -1) + { + $result = $this->antraglib->getDetailsForLastAntrag( + $prestudent_id, + [ + Studierendenantrag_model::TYP_ABMELDUNG, + Studierendenantrag_model::TYP_ABMELDUNG_STGL + ] + ); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $data = getData($result); + + $data->canCancel = ( + $data->status == Studierendenantragstatus_model::STATUS_CREATED && + $this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id) + ); + + return $this->outputJsonSuccess($data); + } + + $result = $this->antraglib->getDetailsForNewAntrag($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $this->outputJsonSuccess(getData($result)); + } + + public function getDetailsForAntrag($studierendenantrag_id) + { + if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) return show_404(); + + $result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $data = getData($result); + + if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL && $data->typ !== Studierendenantrag_model::TYP_ABMELDUNG) + return show_404(); + + $data->canCancel = ( + $data->status == Studierendenantragstatus_model::STATUS_CREATED && + $this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id) + ); + + $this->outputJsonSuccess($data); + } + + public function createAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required'); + $this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required'); + $this->form_validation->set_rules('grund', 'Grund', 'required'); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $grund = $this->input->post('grund'); + $studiensemester = $this->input->post('studiensemester'); + $prestudent_id = $this->input->post('prestudent_id'); + + $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(['db' => getError($result)]); + } + $result = $result->retval; + if (!$result) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]); + } + elseif ($result == -3) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]); + } + elseif ($result < 0) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]); + } + + $result = $this->antraglib->createAbmeldung($prestudent_id, $studiensemester, getAuthUID(), $grund); + if (isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + $result = $this->antraglib->getDetailsForAntrag(getData($result)); + if (!hasData($result)) + return $this->outputJsonSuccess(true); + + $data = getData($result); + $data->canCancel = (boolean)$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id); + + $this->outputJsonSuccess($data); + } + + public function cancelAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required'); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $antrag_id = $this->input->post('antrag_id'); + if(!$this->antraglib->isEntitledToCancelAntrag($antrag_id)) + { + $this->output->set_status_header(403); + + return $this->outputJsonError('Forbidden'); + } + + $result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID()); + if(isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + $result = $this->antraglib->getDetailsForAntrag($antrag_id); + + if (!hasData($result)) + return $this->outputJsonSuccess($antrag_id); + $this->outputJsonSuccess(getData($result)); + } + + public function getStudiengaengeAssistenz() + { + $this->load->library('PermissionLib'); + + $_POST = json_decode($this->input->raw_input_stream, true); + $query = $this->input->post('query'); + + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + + $result = $this->antraglib->getAktivePrestudentenInStgs($studiengaenge, $query); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + $result = getData($result); + if (!$result) { + return $this->outputJsonSuccess([]); + } + + return $this->outputJsonSuccess($result); + } +} diff --git a/application/controllers/components/Antrag/Leitung.php b/application/controllers/components/Antrag/Leitung.php new file mode 100644 index 000000000..8d333d5b8 --- /dev/null +++ b/application/controllers/components/Antrag/Leitung.php @@ -0,0 +1,389 @@ +load->library('AuthLib'); + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag' + ]); + } + + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getActiveStgs() + { + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; + $studiengaenge = array_merge($studiengaenge, $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []); + + $result = $this->StudierendenantragModel->loadStgsWithAntraege($studiengaenge); + if (isError($result)) { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); + } + $this->outputJson($result); + } + + public function getAntraege($studiengang = null, $extra = null) + { + if ($studiengang && $studiengang == 'todo') { + $studiengang = $extra; + $extra = true; + } else { + $extra = false; + } + + if ($studiengang) { + $studiengaenge = [$studiengang]; + } else { + $studiengaenge =$this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); + if(!is_array($studiengaenge)) + $studiengaenge = []; + + + $stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + if(!is_array($stgsNeuanlage)) + $stgsNeuanlage = []; + + $studiengaenge = array_unique(array_merge($studiengaenge, $stgsNeuanlage)); + } + + + $antraege = []; + if ($studiengaenge) { + $result = $extra + ? $this->StudierendenantragModel->loadActiveForStudiengaenge($studiengaenge) + : $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); + if (isError($result)) { + $this->output->set_status_header(500); + return $this->outputJson('Internal Server Error'); + } + if(hasData($result)) + { + $antraege = getData($result); + } + } + + $this->outputJson($antraege); + } + + public function reopenAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToReopenAntrag', + [ + 'isEntitledToReopenAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->reopenWiederholung($studierendenantrag_id, getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); + + $this->outputJsonSuccess($studierendenantrag_id); + } + + public function objectAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToObjectAntrag|callback_canBeObjected', + [ + 'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'canBeObjected' => $this->p->t('studierendenantrag', 'error_no_objection') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->objectAbmeldung($studierendenantrag_id, getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); + + $this->outputJsonSuccess($studierendenantrag_id); + } + + public function objectionDeny() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToObjectAntrag|callback_isObjected', + [ + 'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'isObjected' => $this->p->t('studierendenantrag', 'error_not_objected') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + $grund = $this->input->post('grund'); + + $result = $this->antraglib->denyObjectionAbmeldung($studierendenantrag_id, getAuthUID(), $grund); + + if (isError($result)) + return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); + + $this->outputJsonSuccess($studierendenantrag_id); + } + + public function objectionApprove() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToObjectAntrag|callback_isObjected', + [ + 'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'isObjected' => $this->p->t('studierendenantrag', 'error_not_objected') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->cancelAntrag($studierendenantrag_id, getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); + + $this->outputJsonSuccess($studierendenantrag_id); + } + + public function isEntitledToReopenAntrag($studierendenantrag_id) + { + return $this->antraglib->isEntitledToReopenAntrag($studierendenantrag_id); + } + + public function isEntitledToObjectAntrag($studierendenantrag_id) + { + return $this->antraglib->isEntitledToObjectAntrag($studierendenantrag_id); + } + + public function isEntitledToRejectAntrag($studierendenantrag_id) + { + return $this->antraglib->isEntitledToRejectAntrag($studierendenantrag_id); + } + + public function canBeObjected($studierendenantrag_id) + { + return $this->antraglib->hasType($studierendenantrag_id, Studierendenantrag_model::TYP_ABMELDUNG_STGL); + } + + public function isObjected($studierendenantrag_id) + { + return $this->antraglib->hasStatus($studierendenantrag_id, Studierendenantragstatus_model::STATUS_OBJECTED); + } + + + public function approveAbmeldung() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToApproveAntrag', + [ + 'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->approveAbmeldung([$studierendenantrag_id], getAuthUID()); + if (isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + return $this->outputJsonSuccess($studierendenantrag_id); + } + + public function approveAbmeldungStgl() + { + return $this->approveAbmeldung(); + } + + public function approveUnterbrechung() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToApproveAntrag', + [ + 'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->approveUnterbrechung([$studierendenantrag_id], getAuthUID()); + if (isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + return $this->outputJsonSuccess($studierendenantrag_id); + } + + public function rejectUnterbrechung() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToRejectAntrag', + [ + 'isEntitledToRejectAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + $this->form_validation->set_rules('grund', 'Grund', 'required'); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + $grund = $this->input->post('grund'); + + $result = $this->antraglib->rejectUnterbrechung([$studierendenantrag_id], getAuthUID(), $grund); + if (isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + return $this->outputJsonSuccess($studierendenantrag_id); + } + + public function approveWiederholung() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + 'required|callback_isEntitledToApproveAntrag', + [ + 'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->approveWiederholung($studierendenantrag_id, getAuthUID()); + if (isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + return $this->outputJsonSuccess($studierendenantrag_id); + } + + public function isEntitledToApproveAntrag($studierendenantrag_id) + { + return $this->antraglib->isEntitledToApproveAntrag($studierendenantrag_id); + } + + public function getHistory($studierendenantrag_id) + { + if (!$this->antraglib->isEntitledToSeeHistoryForAntrag($studierendenantrag_id)) { + $this->output->set_status_header(403); + return $this->outputJson('Forbidden'); + } + + $result = $this->antraglib->getAntragHistory($studierendenantrag_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $this->outputJsonSuccess(getData($result) ?: []); + } +} diff --git a/application/controllers/components/Antrag/Unterbrechung.php b/application/controllers/components/Antrag/Unterbrechung.php new file mode 100644 index 000000000..33bd0035d --- /dev/null +++ b/application/controllers/components/Antrag/Unterbrechung.php @@ -0,0 +1,233 @@ +load->config('studierendenantrag'); + + // Libraries + $this->load->library('AuthLib'); + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag', + 'ui' + ]); + } + + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getDetailsForNewAntrag($prestudent_id) + { + if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) { + $this->output->set_status_header(403); + return $this->outputJsonError('Forbidden'); + } + $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id); + if (isError($result)) { + $this->output->set_status_header(500); + return $this->outputJsonError(getError($result)); + } + $result = $result->retval; + if (!$result) { + $this->output->set_status_header(403); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student')); + } + elseif ($result == -1) + { + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_UNTERBRECHUNG); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + return $this->outputJsonSuccess(getData($result)); + } + elseif ($result == -2) + { + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $result = getData($result); + $this->output->set_status_header(400); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_pending', [ + 'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ) + ])); + } + elseif ($result == -3) + { + $this->output->set_status_header(403); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist')); + } + $result = $this->antraglib->getDetailsForNewAntrag($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $data = getData($result); + + $data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($data->studiensemester_kurzbz); + + $this->outputJsonSuccess($data); + } + + public function getDetailsForAntrag($studierendenantrag_id) + { + if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) return show_404(); + + $result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $data = getData($result); + + if ($data->typ !== Studierendenantrag_model::TYP_UNTERBRECHUNG) + return show_404(); + + $this->outputJsonSuccess($data); + } + + public function createAntrag() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required'); + $this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required'); + $this->form_validation->set_rules('grund', 'Grund', 'required'); + $this->form_validation->set_rules( + 'datum_wiedereinstieg', + 'Datum Wiedereinstieg', + 'required|callback_isValidDate|callback_isDateInFuture', + [ + 'isValidDate' => $this->p->t('ui', 'error_invalid_date'), + 'isDateInFuture' => $this->p->t('ui', 'error_invalid_date') + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $grund = $this->input->post('grund'); + $studiensemester = $this->input->post('studiensemester'); + $prestudent_id = $this->input->post('prestudent_id'); + $datum_wiedereinstieg = $this->input->post('datum_wiedereinstieg'); + $dms_id = null; + + $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(['db' => getError($result)]); + } + $result = $result->retval; + if (!$result) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]); + } + elseif ($result == -3) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]); + } + elseif ($result < 0) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]); + } + + if(isset($_FILES['attachment']) && (!isset($_FILES['attachment']['error']) || $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE)) + { + $this->load->library('DmsLib'); + + $dms = $this->config->item('unterbrechung_dms'); + if (!count(array_filter($dms, function ($v) { + return $v !== null; + }))) + $dms = ['kategorie_kurzbz' => 'Akte']; + $dms['version'] = 0; + + $allowed_filetypes = $this->config->item('unterbrechung_dms_filetypes') ?: ['*']; + $result = $this->dmslib->upload($dms, 'attachment', $allowed_filetypes); + if(isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + $dms_id = getData($result)['dms_id']; + } + + $result = $this->antraglib->createUnterbrechung($prestudent_id, $studiensemester, getAuthUID(), $grund, $datum_wiedereinstieg, $dms_id); + if(isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + $antragId = getData($result); + $result = $this->antraglib->getDetailsForAntrag($antragId); + + if(!hasData($result)) + return $this->outputJsonSuccess($antragId); + $this->outputJsonSuccess(getData($result)); + } + + public function cancelAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required'); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $antrag_id = $this->input->post('antrag_id'); + + $result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID()); + if (isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + $result = $this->antraglib->getDetailsForAntrag($antrag_id); + + if (!hasData($result)) + return $this->outputJsonSuccess($antrag_id); + $this->outputJsonSuccess(getData($result)); + } + + public function isValidDate($date) + { + try { + new DateTime($date); + } catch (Exception $e) { + return false; + } + return true; + } + + public function isDateInFuture($date) + { + return new DateTime() < new DateTime($date); + } +} diff --git a/application/controllers/components/Antrag/Wiederholung.php b/application/controllers/components/Antrag/Wiederholung.php new file mode 100644 index 000000000..418d05f45 --- /dev/null +++ b/application/controllers/components/Antrag/Wiederholung.php @@ -0,0 +1,371 @@ +load->config('studierendenantrag'); + + // Libraries + $this->load->library('AuthLib'); + $this->load->library('PermissionLib'); + $this->load->library('AntragLib'); + + $requiredPermissions = [ + 'saveLvs' => ['student/studierendenantrag:w'], + 'getLvsAsRdf' => ['student/studierendenantrag:r', 'student/noten:r'], + 'moveLvsToZeugnis' => ['student/studierendenantrag:w', 'student/noten:w'] + ]; + + if (isset($requiredPermissions[$this->router->method])) { + if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method)) { + $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); + $this->outputJson('Forbidden'); + exit; + } + } + + // Load language phrases + $this->loadPhrases([ + 'global', + 'studierendenantrag' + ]); + } + + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Retrieves data of the current studiengang for the current user + */ + + public function getDetailsForNewAntrag($prestudent_id) + { + if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) { + $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); + return $this->outputJsonError('Forbidden'); + } + $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id); + if (isError($result)) { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); + return $this->outputJsonError(getError($result)); + } + $result = $result->retval; + if (!$result) { + $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student_no_failed_exam')); + } + elseif ($result == -1) + { + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_WIEDERHOLUNG); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + $data = getData($result); + + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id, $data->datum, $data->studiensemester_kurzbz); + // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() + $pruefungsdata = current(getData($result)); + + $data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz; + $data->lvbezeichnung = $pruefungsdata->lvbezeichnung; + $data->pruefungsdatum = $pruefungsdata->datum; + + return $this->outputJsonSuccess($data); + } + elseif ($result == -2) + { + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $result = getData($result); + $this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_pending', [ + 'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ) + ])); + } + elseif ($result == -3) + { + $this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST); + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist')); + } + + $result = $this->antraglib->getDetailsForNewAntrag($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $data = getData($result); + + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id); + // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() + $pruefungsdata = current(getData($result)); + + $data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz; + $data->lvbezeichnung = $pruefungsdata->lvbezeichnung; + $data->pruefungsdatum = $pruefungsdata->datum; + + $this->outputJsonSuccess($data); + } + + public function createAntrag() + { + $this->createAntragWithStatus(true); + } + + public function cancelAntrag() + { + $this->createAntragWithStatus(false); + } + + protected function createAntragWithStatus($repeat) + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required'); + $this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required'); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $prestudent_id = $this->input->post('prestudent_id'); + $studiensemester = $this->input->post('studiensemester'); + + $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id); + if (isError($result)) { + return $this->outputJsonError(['db' => getError($result)]); + } + $result = $result->retval; + if (!$result) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]); + } + elseif ($result == -2) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]); + } + elseif ($result == -3) + { + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]); + } + + $result = $this->antraglib->createWiederholung($prestudent_id, $studiensemester, getAuthUID(), $repeat); + if(isError($result)) + { + return $this->outputJsonError(['db' => getError($result)]); + } + + $antragId = getData($result); + $result = $this->antraglib->getDetailsForAntrag($antragId); + + if(!hasData($result)) + return $this->outputJsonSuccess(true); + + $data = getData($result); + + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id); + // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() + $pruefungsdata = current(getData($result)); + + $data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz; + $data->lvbezeichnung = $pruefungsdata->lvbezeichnung; + $data->pruefungsdatum = $pruefungsdata->datum; + + $this->outputJsonSuccess($data); + } + + + public function getLvs($antrag_id) + { + $result = $this->antraglib->getLvsForAntrag($antrag_id); + if (isError($result)) { + $error = getError($result); + if ($error == 'Forbidden') + $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); + return $this->outputJsonError(getError($result)); + } + $lvs = getData($result); + + $this->outputJsonSuccess($lvs); + } + + public function saveLvs() + { + $result = $this->getPostJSON(); + $antragsLvs = array_merge($result->forbiddenLvs, $result->mandatoryLvs); + + $insert = array_map(function ($lv) { + return [ + 'studierendenantrag_id' => $lv->studierendenantrag_id, + 'lehrveranstaltung_id' => $lv->lehrveranstaltung_id, + 'note' => $lv->zugelassen + ? ($lv->zugelassen == 1 ? 0 : $this->config->item('wiederholung_note_angerechnet')) + : $this->config->item('wiederholung_note_nicht_zugelassen'), + 'anmerkung' => $lv->anmerkung, + 'insertvon' => getAuthUID(), + 'studiensemester_kurzbz' => $lv->studiensemester_kurzbz + ]; + }, $antragsLvs); + + $antrag_ids = array_unique(array_map(function ($lv) { + return $lv['studierendenantrag_id']; + }, $insert)); + + foreach ($antrag_ids as $antrag_id) { + $result = $this->StudierendenantragModel->loadIdAndStatusWhere([ + 'studierendenantrag_id' => $antrag_id + ]); + if (isError($result)) + return $this->outputJsonError(getError($result)); + if (!hasData($result)) + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id])); + $antrag = current(getData($result)); + if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED && $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED) + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_locked')); + } + + if(!$antragsLvs) + return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_lv')); + + $result = $this->antraglib->saveLvs($insert); + + if (isError($result)) + return $this->outputJsonError(getError($result)); + + $this->outputJsonSuccess(getData($result)); + } + + public function getLvsAsRdf($prestudent_id) + { + // header für no cache + $this->output->set_header("Cache-Control: no-cache"); + $this->output->set_header("Cache-Control: post-check=0, pre-check=0", false); + $this->output->set_header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + $this->output->set_header("Pragma: no-cache"); + $this->output->set_header("Content-type: application/xhtml+xml"); + + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $sem_akt = $this->variablelib->getVar('semester_aktuell'); + + + $result = $this->antraglib->getLvsForPrestudent($prestudent_id, $sem_akt); + if (isError($result)) { + return $this->outputJsonError(getError($result)); + } + + $lvs = getData($result) ?: []; + $rdf_url = 'http://www.technikum-wien.at/antragnote'; + + $this->load->view('lehre/Antrag/Wiederholung/getLvs.rdf.php', [ + 'url' => $rdf_url, + 'lvs' => $lvs + ]); + } + + public function moveLvsToZeugnis() + { + $anzahl = $this->input->post('anzahl'); + $student_uid = $this->input->post('student_uid'); + $this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel'); + $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + + $errormsg = array(); + + for($i=0; $i<$anzahl; $i++) + { + $id = $this->input->post('studierendenantrag_lehrveranstaltung_id_' . $i); + $result =$this->StudierendenantraglehrveranstaltungModel->load($id); + if(isError($result)) + { + $errormsg[] = getError($result); + } + elseif(!hasData($result)) + { + $errormsg[] = $this->p->t('studierendenantrag', 'error_no_lv_in_application'); + } + else + { + $antragLv = getData($result)[0]; + $result= $this->ZeugnisnoteModel->load([ + 'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id, + 'student_uid'=> $student_uid, + 'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz + ]); + if(isError($result)) + { + $errormsg[] = getError($result); + } + else + { + if (hasData($result)) + { + $result = $this->ZeugnisnoteModel->update( + [ + 'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id, + 'student_uid'=> $student_uid, + 'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz + ], + [ + 'note'=> $antragLv->note, + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $antragLv->insertamum, + 'updateamum' => date('c'), + 'bemerkung'=>$antragLv->anmerkung, + 'updatevon'=>getAuthUID() + ] + ); + } + else + { + $result = $this->ZeugnisnoteModel->insert([ + 'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id, + 'student_uid'=> $student_uid, + 'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz, + 'note'=> $antragLv->note, + 'uebernahmedatum' => date('c'), + 'benotungsdatum' => $antragLv->insertamum, + 'insertamum' => date('c'), + 'bemerkung'=>$antragLv->anmerkung, + 'insertvon'=>getAuthUID() + ]); + } + if(isError($result)) + { + $errormsg[] = getError($result); + } + } + } + } + + if($errormsg) + $return = false; + else + $return = true; + + $this->load->view('lehre/Antrag/Wiederholung/moveLvs.rdf.php', [ + 'return' => $return, + 'errormsg' => $errormsg + ]); + } +} diff --git a/application/controllers/components/Filter.php b/application/controllers/components/Filter.php index ab7e1493e..bde7d7ed7 100644 --- a/application/controllers/components/Filter.php +++ b/application/controllers/components/Filter.php @@ -26,6 +26,9 @@ class Filter extends FHC_Controller // Loads authentication library and starts authentication $this->load->library('AuthLib'); + // Loads the FiltersModel + $this->load->model('system/Filters_model', 'FiltersModel'); + // Loads the FilterCmptLib with HTTP GET/POST parameters $this->_startFilterCmptLib(); } diff --git a/application/controllers/components/Phrasen.php b/application/controllers/components/Phrasen.php new file mode 100644 index 000000000..87516ce00 --- /dev/null +++ b/application/controllers/components/Phrasen.php @@ -0,0 +1,22 @@ +load->library('PhrasesLib', [$module], 'pj'); + $this->outputJsonSuccess(json_decode($this->pj->getJSON())); + } +} diff --git a/application/controllers/components/SearchBar.php b/application/controllers/components/SearchBar.php index dd3c22690..d19113177 100644 --- a/application/controllers/components/SearchBar.php +++ b/application/controllers/components/SearchBar.php @@ -17,11 +17,17 @@ class SearchBar extends FHC_Controller { parent::__construct(); - // Loads the AuthLib and starts the authentication - $this->load->library('AuthLib'); + // Loads the AuthLib _without_ starting the authentication + // NOTE: + // - A user must be authenticated via another controller to access this one + // - It is loaded to be able to call the isLogged function later + $this->load->library('AuthLib', array(false)); // Load the library SearchBarLib $this->load->library('SearchBarLib'); + + // Checks if the user is authenticated, otherwise returns an error code in JSON format + if (!isLogged()) $this->terminateWithJsonError(SearchBarLib::ERROR_NOT_AUTH); } //------------------------------------------------------------------------------------------------------------------ diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php new file mode 100644 index 000000000..131cfdced --- /dev/null +++ b/application/controllers/jobs/AntragJob.php @@ -0,0 +1,627 @@ +load->config('studierendenantrag'); + + // Loads SanchoHelper + $this->load->helper('hlp_sancho_helper'); + + // Load Model + $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + $this->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel'); + $this->load->model('education/Pruefung_model', 'PruefungModel'); + $this->load->model('person/Kontakt_model', 'KontaktModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + } + + /** + * Send infomail to Stgl + */ + public function sendStglSammelmail() + { + $this->load->model('person/Person_model', 'PersonModel'); + + $this->logInfo('Start Job sendStglSammelmail'); + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $this->StudierendenantragModel->addJoin('public.tbl_prestudent', 'prestudent_id'); + $this->db->group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); + + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); + + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_UNTERBRECHUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); + + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_WIEDERHOLUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_LVSASSIGNED); + $this->db->group_end(); + + $result = $this->StudierendenantragModel->load(); + if(isError($result)) + return $this->logError(getError($result)); + + if(!hasData($result)) + return $this->logInfo('End Job sendStglSammelmail: 0 Mails sent'); + + $antraege = getData($result); + + $stgs = array(); + $stgLeitungen = array(); + + foreach ($antraege as $antrag) + { + if (!isset($stgs[$antrag->studiengang_kz])) + { + $result = $this->StudiengangModel->getLeitung($antrag->studiengang_kz); + if (isError($result)) + { + $this->logError(getError($result)); + continue; + } + if (!hasData($result)) + { + $this->logError('Keine Leitung für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); + continue; + } + + $leitung = current(getData($result)); + if (!isset($stgLeitungen[$leitung->uid])) + { + $stgLeitungen[$leitung->uid] = [ 'Details' => $leitung, 'stgs' => [] ]; + } + $stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz; + + $result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); + if (isError($result)) + { + $this->logError(getError($result)); + continue; + } + if (!hasData($result)) + { + $this->logError('Keine Details für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); + continue; + } + $details = current(getData($result)); + + $stgs[$antrag->studiengang_kz] = [ + 'Abmeldung' => [], + 'Unterbrechung' => [], + 'Wiederholung' => [], + 'Details' => $details + ]; + } + $stgs[$antrag->studiengang_kz][str_replace('Stgl', '', $antrag->typ)] = $antrag; + } + + $this->load->model('system/Sprache_model', 'SpracheModel'); + $result = $this->SpracheModel->loadWhere(['content' => true]); + if (isError($result)) { + $this->logError(getError($result)); + $languages = [DEFAULT_LANGUAGE]; + } elseif (!hasData($result)) { + $languages = [DEFAULT_LANGUAGE]; + } else { + $languages = array_map(function ($row) { + return $row->sprache; + }, getData($result)); + } + + $count = 0; + foreach ($stgLeitungen as $leitung) + { + $data = [ + 'name' => trim($leitung['Details']->vorname . ' ' . $leitung['Details']->nachname), + 'vorname' => $leitung['Details']->vorname, + 'nachname' => $leitung['Details']->nachname + ]; + + foreach ($languages as $lang) { + unset($this->p); + $this->loadPhrases(['studierendenantrag'], $lang); + + $table = ''; + foreach ($leitung['stgs'] as $studiengang_kz) { + $rows = ''; + $stg = $stgs[$studiengang_kz]; + foreach (['Abmeldung', 'Unterbrechung', 'Wiederholung'] as $typ) { + $c = count($stg[$typ]); + if ($c) { + $rows .= $this->p->t('studierendenantrag', 'mail_part_x_new_' . $typ, ['count' => $c]); + } + } + $table .= $this->p->t('studierendenantrag', 'mail_part_table', [ + 'stg_bezeichnung' => $stg['Details']->bezeichnung, + 'stg_orgform_kurzbz' => $stg['Details']->orgform_kurzbz, + 'rows' => $rows + ]); + } + $data['table_' . $lang] = $table; + } + + $data['table'] = $data['table_' . DEFAULT_LANGUAGE]; + $data['leitungLink'] = APP_ROOT. 'index.ci.php/lehre/Studierendenantrag/leitung'; + + //Mail an Stgl und Assistenz + $to = $leitung['Details']->uid . '@' . DOMAIN; + $cc = $leitung['Details']->email; + + // NOTE(chris): Sancho mail + if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $to, 'Anträge - Aktion(en) erforderlich', DEFAULT_SANCHO_HEADER_IMG, DEFAULT_SANCHO_FOOTER_IMG, '', $cc)) + $count++; + } + + $this->logInfo($count . " Emails erfolgreich versandt"); + + $this->logInfo('End Job sendStglSammelmail'); + } + + /** + * Send reminder to Assistant for Wiedereinstieg Unterbrecher + * + */ + public function sendReminderWiedereinstieg() + { + $now = new DateTime(); + $modifier = $this->config->item('unterbrechung_job_remind_wiedereinstieg_date_modifier'); + if (!$modifier) + return $this->logError('Konnte Job nicht starten: Config "unterbrechung_job_remind_wiedereinstieg_date_modifiers" nicht gesetzt'); + + $end = new DateTime(); + $end->modify($modifier); + + $this->logInfo(sprintf( + 'Start Job sendReminderWiedereinstieg (Wiedereinstieg zwischen %s - %s)', + $now->format('Y-m-d'), + $end->format('Y-m-d') + )); + + $result = $this->StudierendenantragModel->getAntraegeWhereWiedereinstiegBetween($now, $end); + + if(isError($result)) + { + $this->logError(getError($result)); + $this->logInfo('Ende Job sendReminderWiedereinstieg'); + return; + } + + $antraege = getData($result) ?: []; + $count = 0; + foreach ($antraege as $antrag) + { + $res = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); + $stg = ''; + $orgform = ''; + if (hasData($res)) { + $studiengang = current(getData($res)); + $stg = $studiengang->bezeichnung; + $orgform = $studiengang->orgform_kurzbz; + } + + $datum = new DateTime($antrag->datum_wiedereinstieg); + $data = array( + 'prestudent' => $antrag->prestudent_id, + 'name' => trim($antrag->vorname . ' '. $antrag->nachname), + 'datum_wiedereinstieg' => $datum->format('d.m.Y'), + 'vorname' => $antrag->vorname, + 'nachname' => $antrag->nachname, + 'Orgform' => $orgform, + 'stg' => $stg + ); + $result = $this->StudentModel->loadWhere(['prestudent_id'=> $antrag->prestudent_id]); + if (hasData($result)) { + $student = current(getData($result)); + $data['UID'] = $student->student_uid; + } + + // NOTE(chris): Sancho mail + if(sendSanchoMail('Sancho_Mail_Antrag_U_Reminder', $data, $antrag->email, 'Reminder: Unterbrechung Wiedereinstieg')) + { + $count++; + $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag->studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_REMINDERSENT, + 'insertvon' => 'AntragJob' + ]); + } + } + $this->logInfo($count . ' Reminder gesendet - Ende Job sendReminderWiedereinstieg'); + } + + /** + * Set Wiederholer after deadline to Abbrecher + * + */ + public function handleWiederholerDeadline() + { + $this->logInfo('Start Job handleWiederholerDeadline'); + + $this->load->library('PrestudentLib'); + + $insertvon = $this->config->item('antrag_job_systemuser'); + if (!$insertvon) { + $this->logError('Config "antrag_job_systemuser" nicht gesetzt'); + $this->logInfo('Ende Job handleWiederholerDeadline'); + return; + } + + $modifier_deadline = $this->config->item('wiederholung_job_deadline_date_modifier'); + if (!$modifier_deadline) { + $this->logError('Config "wiederholung_job_deadline_date_modifier" nicht gesetzt'); + $this->logInfo('Ende Job handleWiederholerDeadline'); + return; + } + + $digi_start= $this->config->item('digitalization_start'); + if($digi_start) + $digi_start = new DateTime($digi_start); + + $dateDeadline = new DateTime(); + $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + + $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( + [ + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + Studierendenantragstatus_model::STATUS_REQUESTSENT_2 + ], + $dateDeadline, + $digi_start + ); + if(isError($result)) + { + $this->logError(getError($result)); + } + else + { + $prestudents = getData($result) ?: []; + $count = 0; + + $prestudents = $this->prestudentsGetUnique($prestudents); + + + foreach ($prestudents as $prestudent) + { + $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); + if (isError($result)) + $this->logError(getError($result)); + else + $count++; + } + $this->logInfo($count . " Students set to Abbrecher"); + } + + $this->logInfo('Ende Job handleWiederholerDeadline'); + } + + /** + * Set Abmeldungen after deadline to Abbrecher + * + */ + public function handleAbmeldungenStglDeadline() + { + $this->logInfo('Start Job handleAbmeldungenStglDeadline'); + + $this->load->library('AntragLib'); + + $insertvon = $this->config->item('antrag_job_systemuser'); + if (!$insertvon) { + $this->logError('Config "antrag_job_systemuser" nicht gesetzt'); + $this->logInfo('Ende Job handleAbmeldungenStglDeadline'); + return; + } + + $modifier_deadline = $this->config->item('abmeldung_job_deadline_date_modifier'); + if (!$modifier_deadline) { + $this->logError('Config "abmeldung_job_deadline_date_modifier" nicht gesetzt'); + $this->logInfo('Ende Job handleAbmeldungenStglDeadline'); + return; + } + + $dateDeadline = new DateTime(); + $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + + $this->StudierendenantragModel->addSelect('tbl_studierendenantrag.studierendenantrag_id'); + $this->StudierendenantragModel->addSelect('prestudent_id'); + $this->StudierendenantragModel->addSelect('studiensemester_kurzbz'); + $this->StudierendenantragModel->addSelect('s.insertamum'); + $this->StudierendenantragModel->addSelect('s.insertvon'); + + $this->StudierendenantragModel->db->where_in('public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)', $this->config->item('antrag_prestudentstatus_whitelist')); + + $result = $this->StudierendenantragModel->getWithLastStatusWhere([ + 'typ' => Studierendenantrag_model::TYP_ABMELDUNG_STGL, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, + 's.insertamum <=' => $dateDeadline->format('c') + ]); + + if(isError($result)) + { + $this->logError(getError($result)); + } + else + { + $antraege = getData($result) ?: []; + $count = 0; + + foreach ($antraege as $antrag) + { + $result = $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag->studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED, + 'insertvon' => 'AntragJob' + ]); + if (isError($result)) + $this->logError(getError($result)); + else { + $deregisterStatus = getData($result); + + $result = $this->prestudentlib->setAbbrecher( + $antrag->prestudent_id, + $antrag->studiensemester_kurzbz, + 'AntragJob', + 'abbrecherStgl', + $antrag->insertamum, + null, + $antrag->insertvon ?: $insertvon + ); + if (isError($result)) { + $this->StudierendenantragstatusModel->delete($deregisterStatus); + $this->logError(getError($result)); + } else { + $count++; + $result = $this->PrestudentModel->load($antrag->prestudent_id); + if(!hasData($result)) { + $this->logWarning('No Prestudent found'); + continue; + } + $prestudent = current(getData($result)); + $result = $this->StudiengangModel->load($prestudent->studiengang_kz); + if(!hasData($result)) { + $this->logWarning('No Studiengang found'); + continue; + } + $studiengang = current(getData($result)); + $result = $this->PersonModel->loadPrestudent($antrag->prestudent_id); + if(!hasData($result)) + { + $this->logWarning('No Person found'); + continue; + } + $person = current(getData($result)); + $email = $studiengang->email; + $dataMail = array( + 'prestudent' => $antrag->prestudent_id, + 'studiensemester' => $antrag->studiensemester_kurzbz, + 'name' => trim($person->vorname . ' '. $person->nachname), + ); + + if(!sendSanchoMail('Sancho_Mail_Antrag_A_Assist', $dataMail, $email, 'Einspruchsfrist abgelaufen')) + { + $this->logWarning("Failed to send Notification to " . $email); + } + } + + } + } + $this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher"); + } + $this->logInfo('Ende Job handleAbmeldungenStglDeadline'); + } + + /** + * Send Request to Student do Decide between Wiederholung and Verzicht + * + */ + public function sendAufforderungWiederholer() + { + $this->logInfo('Start Job sendAufforderungWiederholer'); + + $modifier_request_1 = $this->config->item('wiederholung_job_request_1_date_modifier'); + $modifier_request_2 = $this->config->item('wiederholung_job_request_2_date_modifier'); + $modifier_deadline = $this->config->item('wiederholung_job_deadline_date_modifier'); + + $digi_start = $this->config->item('digitalization_start'); + if ($digi_start) { + try { + $digi_start = new DateTime($digi_start); + } catch(Exception $e) { + } + } + + if ($modifier_deadline) { + $dateDeadline = new DateTime(); + $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + + if ($digi_start) + $dateDeadline = max($digi_start, $dateDeadline); + } else { + $dateDeadline = $digi_start ?: null; + } + + //first request + if ($modifier_request_1) { + $dateStichtag = new DateTime(); + $dateStichtag->sub(DateInterval::createFromDateString($modifier_request_1)); + if (!$dateDeadline || $dateStichtag > $dateDeadline) + $this->sendReminder( + 'Request1', + null, + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + $dateDeadline, + $dateStichtag, + $modifier_deadline, + 'Aufforderung: Bekanntgabe Wiederholung' + ); + } else + $this->logError('Config "wiederholung_job_request_1_date_modifier" nicht gesetzt'); + + //second request + if ($modifier_request_2) { + $dateStichtag = new DateTime(); + $dateStichtag->sub(DateInterval::createFromDateString($modifier_request_2)); + if (!$dateDeadline || $dateStichtag > $dateDeadline) + $this->sendReminder( + 'Request2', + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + Studierendenantragstatus_model::STATUS_REQUESTSENT_2, + $dateDeadline, + $dateStichtag, + $modifier_deadline, + 'Reminder Aufforderung: Bekanntgabe Wiederholung' + ); + } else + $this->logError('Config "wiederholung_job_request_2_date_modifier" nicht gesetzt'); + + $this->logInfo('Ende Job sendAufforderungWiederholer'); + } + + protected function prestudentsGetUnique($prestudents) + { + $result = []; + foreach ($prestudents as $prestudent) { + if (!isset($result[$prestudent->prestudent_id])) + $result[$prestudent->prestudent_id] = $prestudent; + else { + if ($result[$prestudent->prestudent_id]->datum > $prestudent->datum) + $result[$prestudent->prestudent_id] = $prestudent; + } + } + return $result; + } + + protected function sendReminder($name, $status_from, $status_to, $deadline, $date_stichtag, $modifier_deadline, $subject) + { + $this->logInfo('Start Job sendAufforderungWiederholer ' . $name); + + $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed($status_from, $date_stichtag, $deadline); + + if(isError($result)) + { + $this->logError(getError($result)); + } + else + { + $prestudents = getData($result) ?: []; + $count = 0; + + $prestudents = $this->prestudentsGetUnique($prestudents); + + foreach ($prestudents as $prestudent) + { + $stg_kz = $prestudent->studiengang_kz; + if (in_array($stg_kz, $this->config->item('stgkz_blacklist_wiederholung'))) + continue; + $url = site_url('lehre/Studierendenantrag/wiederholung/' . $prestudent->prestudent_id); + $urlCIS = CIS_ROOT . 'index.ci.php/lehre/Studierendenantrag/wiederholung/' . $prestudent->prestudent_id; + $email = $this->StudentModel->getEmailFH($this->StudentModel->getUID($prestudent->prestudent_id)); + + $fristende = new DateTime($prestudent->datum); + $fristende->add(DateInterval::createFromDateString($modifier_deadline)); + + $datum_kp = new DateTime($prestudent->datum); + + $result = $this->StudiensemesterModel->getNextFrom($prestudent->studiensemester_kurzbz); + $next_sem = ""; + $sem_after_next_sem = ""; + if (hasData($result)) { + $next_sem = current(getData($result))->studiensemester_kurzbz; + $result = $this->StudiensemesterModel->getNextFrom($next_sem); + if (hasData($result)) { + $sem_after_next_sem = current(getData($result))->studiensemester_kurzbz; + } + } + + $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + $result = $this->PrestudentstatusModel->loadLastWithStgDetails($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz); + if (hasData($result)) { + $ausbildungssemester = current(getData($result))->semester; + } + + $dataMail = array( + 'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname), + 'vorname' => $prestudent->vorname, + 'nachname' => $prestudent->nachname, + 'pers_kz'=> $prestudent->matrikelnr, + 'stg' => $prestudent->bezeichnung, + 'lvbezeichnung' => $prestudent->lvbezeichnung, + 'datum_kp' => $datum_kp->format('d.m.Y'), + 'studiensemester'=> $prestudent->studiensemester_kurzbz, + 'Orgform'=> $prestudent->orgform, + 'prestudent_id' => $prestudent->prestudent_id, + 'url' => $url, + 'urlCIS' => $urlCIS, + 'fristablauf' => $fristende->format('d.m.Y'), + 'pre_wiederholer_sem' => $next_sem, + 'wiederholer_sem' => $sem_after_next_sem, + 'sem' => $ausbildungssemester + ); + + // NOTE(chris): Sancho mail + if(sendSanchoMail('Sancho_Mail_Antrag_W_' . $name, $dataMail, $email, $subject)) + { + $antrag_id = null; + $result = $this->StudierendenantragModel->loadWhere([ + 'prestudent_id' => $prestudent->prestudent_id, + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG + ]); + if (isError($result)) + $this->logError(getError($result)); + elseif (hasData($result)) + $antrag_id = current(getData($result) ?: []) -> studierendenantrag_id; + if ($antrag_id == null) + { + $result = $this->StudierendenantragModel->insert([ + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz'=> $prestudent->studiensemester_kurzbz, + 'datum' => date('c'), + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, + 'insertvon' => 'AntragJob' + ]); + if (isError($result)) + $this->logError(getError($result)); + else + $antrag_id = getData($result); + } + if ($antrag_id) + { + $result = $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => $status_to, + 'insertvon' => 'AntragJob' + ]); + if (isError($result)) + $this->logError(getError($result)); + } + $count++; + } + } + $this->logInfo($count . " Mails '" . $subject . "' sent"); + } + $this->logInfo('Ende Job sendAufforderungWiederholer ' . $name); + } +} diff --git a/application/controllers/jobs/ReihungstestJob.php b/application/controllers/jobs/ReihungstestJob.php index 431ac5b04..c31ed54c9 100644 --- a/application/controllers/jobs/ReihungstestJob.php +++ b/application/controllers/jobs/ReihungstestJob.php @@ -467,7 +467,7 @@ class ReihungstestJob extends JOB_Controller $this->PrestudentstatusModel->addJoin('public.tbl_person', 'person_id'); $yesterdays_applicants_arr = $this->PrestudentstatusModel->loadWhere(' - status_kurzbz = \'Interessent\' AND + status_kurzbz IN (\'Interessent\', \'Bewerber\') AND typ = \'b\' AND bestaetigtam = current_date - 1 '); @@ -730,33 +730,27 @@ class ReihungstestJob extends JOB_Controller tbl_reihungstest.reihungstest_id, tbl_studienplan.studienplan_id, tbl_reihungstest.studiensemester_kurzbz, - tbl_studienordnung.studiengang_kz + tbl_studienordnung.studiengang_kz, + tbl_studienplan.orgform_kurzbz FROM public.tbl_reihungstest - JOIN public.tbl_rt_studienplan ON(tbl_rt_studienplan.reihungstest_id=tbl_reihungstest.reihungstest_id) - JOIN lehre.tbl_studienplan USING(studienplan_id) - JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN public.tbl_rt_studienplan ON(tbl_rt_studienplan.reihungstest_id=tbl_reihungstest.reihungstest_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) WHERE - NOT EXISTS( - SELECT 1 FROM lehre.tbl_studienplan_semester - WHERE studienplan_id=tbl_rt_studienplan.studienplan_id - AND tbl_studienplan_semester.studiensemester_kurzbz=tbl_reihungstest.studiensemester_kurzbz + EXISTS ( + SELECT studienplan_id + FROM lehre.tbl_studienordnung sordnung + JOIN lehre.tbl_studienplan USING (studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING (studienplan_id) + WHERE sordnung.studiengang_kz = tbl_studienordnung.studiengang_kz + AND tbl_studienplan_semester.studiensemester_kurzbz = tbl_reihungstest.studiensemester_kurzbz + AND tbl_studienplan.studienplan_id NOT IN + ( + SELECT studienplan_id FROM tbl_rt_studienplan WHERE reihungstest_id = tbl_reihungstest.reihungstest_id + ) ) - AND tbl_reihungstest.datum >= now() - AND NOT EXISTS( - SELECT - 1 - FROM - public.tbl_rt_studienplan rtstp - JOIN lehre.tbl_studienplan stp USING(studienplan_id) - JOIN lehre.tbl_studienordnung sto USING(studienordnung_id) - JOIN lehre.tbl_studienplan_semester stpsem USING(studienplan_id) - WHERE - sto.studiengang_kz=tbl_studienordnung.studiengang_kz - AND rtstp.reihungstest_id=tbl_reihungstest.reihungstest_id - AND stpsem.studiensemester_kurzbz=tbl_reihungstest.studiensemester_kurzbz - ) - "; + AND tbl_reihungstest.datum >= now()"; $db = new DB_Model(); $result_rt = $db->execReadOnlyQuery($qry); @@ -766,7 +760,9 @@ class ReihungstestJob extends JOB_Controller // find an active studyplan for the same degree program with is valid in this semester $result_stpl = $this->StudienplanModel->getStudienplaeneBySemester( $row_rt->studiengang_kz, - $row_rt->studiensemester_kurzbz + $row_rt->studiensemester_kurzbz, + null, + $row_rt->orgform_kurzbz ); if (hasData($result_stpl)) { diff --git a/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php b/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php new file mode 100644 index 000000000..d22ddb85f --- /dev/null +++ b/application/controllers/jobs/vertragsbestandteil_test/VertragsbestandteilTest.php @@ -0,0 +1,114 @@ +load->library('vertragsbestandteil/VertragsbestandteilLib', + null, 'VertragsbestandteilLib'); + $this->load->library('vertragsbestandteil/GehaltsbestandteilLib', + null, 'GehaltsbestandteilLib'); + } + + public function testFetch() + { + $dienstverhaeltnis_id = 1; + $stichtag = null; + + foreach($this->VertragsbestandteilLib->fetchVertragsbestandteile( + $dienstverhaeltnis_id, $stichtag) as $vertragsbestandteil) + { + //print_r($vertragsbestandteil); + echo $vertragsbestandteil . "\n"; + } + } + + public function testUpdate() + { + $now = new DateTime(); + + $data = new stdClass(); + $data->vertragsbestandteil_id = 32; + $data->von = '2022-12-05'; + + $data->wochenstunden = 45.0; + $data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN; + + $vb = VertragsbestandteilFactory::getVertragsbestandteil($data); + + try + { + $this->VertragsbestandteilLib->storeVertragsbestandteil($vb); + echo "Update successful.\n"; + } + catch( Exception $ex ) + { + echo "Update failed.\n"; + } + } + + + public function testInsert() + { + $now = new DateTime(); + + $data = new stdClass(); + $data->dienstverhaeltnis_id = 1; + $data->von = '2022-12-01'; + $data->insertamum = $now->format(DateTime::ATOM); + $data->insertvon = 'ma0080'; + $data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION; + + $data->benutzerfunktion_id = 112667; + $data->anmerkung = 'test funkton'; + $data->kuendigungsrelevant = false; + + $vb = VertragsbestandteilFactory::getVertragsbestandteil($data); + + try + { + $this->VertragsbestandteilLib->storeVertragsbestandteil($vb); + echo "Insert successful.\n"; + } + catch( Exception $ex ) + { + echo "Insert failed.\n"; + } + } + + public function testGehaltsbestandteilInsert() + { + $data = new stdClass(); + $data->gehaltsbestandteil_id = 2; + /* + $data->dienstverhaeltnis_id = 39; + $data->vertragsbestandteil_id = 123; + $data->gehaltstyp_kurzbz = 'zulage'; + $data->von = '2023-04-01'; + $data->bis = '2023-08-31'; + $data->anmerkung = 'test anmerkung'; + $data->grundbetrag = 100; + $data->betrag_valorisiert = 100; + $data->valorisierung = true; + */ + $data->auszahlungen = 12; + + $gb = new \vertragsbestandteil\Gehaltsbestandteil(); + $gb->hydrateByStdClass($data); + + print_r($gb->toStdClass()); + + $this->GehaltsbestandteilLib->storeGehaltsbestandteil($gb); + } +} diff --git a/application/controllers/lehre/Antrag/Attachment.php b/application/controllers/lehre/Antrag/Attachment.php new file mode 100644 index 000000000..073a03df0 --- /dev/null +++ b/application/controllers/lehre/Antrag/Attachment.php @@ -0,0 +1,82 @@ +load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + + $this->load->library('DmsLib'); + $this->load->library('AuthLib'); + $this->load->library('PermissionLib'); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @param integer $dms_id + * + * @return void + */ + public function show($dms_id) + { + $result = $this->StudierendenantragModel->loadWhere(['dms_id' => $dms_id]); + if (!getData($result)) + return show_404(); + + if (!$this->permissionlib->isBerechtigt('student/antragfreigabe')) + { + $isSamePerson = false; + $antraege = getData($result); + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + foreach ($antraege as $antrag) + { + $prestudent = $this->PrestudentModel->load($antrag->prestudent_id); + if(hasData($prestudent)) + { + if(current(getData($prestudent))->person_id == getAuthPersonId()) + { + $isSamePerson = true; + break; + } + } + } + + if ($isSamePerson == false) + { + $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); // set the HTTP header as unauthorized + + $this->load->library('EPrintfLib'); // loads the EPrintfLib to format the output + + // Prints the main error message + $this->eprintflib->printError('You are not allowed to access to this content'); + // Prints the called controller name + $this->eprintflib->printInfo('Controller name: '.$this->router->class); + // Prints the called controller method name + $this->eprintflib->printInfo('Method name: '.$this->router->method); + // Prints the required permissions needed to access to this method + $this->eprintflib->printInfo('Required permissions: student/antragfreigabe'); + + return show_error('You are not entitled to read this document'); + } + } + + $result = $this->dmslib->download($dms_id); + if (isError($result)) + return show_error(getError($result)); + + $this->outputFile(getData($result)); + } +} diff --git a/application/controllers/lehre/Antrag/Wiederholung.php b/application/controllers/lehre/Antrag/Wiederholung.php new file mode 100644 index 000000000..2aa57d733 --- /dev/null +++ b/application/controllers/lehre/Antrag/Wiederholung.php @@ -0,0 +1,48 @@ + 'student/studierendenantrag:w' + ]); + + $this->load->library('AntragLib'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag' + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + public function assistenz($antrag_id) + { + + $result = $this->antraglib->getDetailsForAntrag($antrag_id); + + if (isError($result)) + return show_error(getError($result)); + + if (!hasData($result)) + return show_404(); + + $this->load->view('lehre/Antrag/Wiederholung/Student', [ + 'antrag_id' => $antrag_id, + 'antrag' => getData($result) + ]); + } +} diff --git a/application/controllers/lehre/Studierendenantrag.php b/application/controllers/lehre/Studierendenantrag.php new file mode 100644 index 000000000..d6d6b2c50 --- /dev/null +++ b/application/controllers/lehre/Studierendenantrag.php @@ -0,0 +1,188 @@ +load->library('AuthLib'); + $this->load->library('AntragLib'); + + // Load Models + $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + + // Load language phrases + $this->loadPhrases([ + 'studierendenantrag' + ]); + + if (strtolower($this->router->method) === 'leitung') + $this->_isAllowed([ + 'leitung' => ['student/studierendenantrag:r', 'student/antragfreigabe:r'] + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + public function index() + { + $dataAntrag = $this->StudierendenantragModel->loadForPerson(getAuthPersonId()); + if (isError($dataAntrag)) + return show_error(getError($dataAntrag)); + $dataAntrag = (getData($dataAntrag) ? : []); + $prestudentenArr = array(); + + foreach ($dataAntrag as $antrag) + { + if (!isset($prestudentenArr[$antrag->prestudent_id])) + { + $prestudentenArr[$antrag->prestudent_id] = array( + 'allowedNewTypes' => array(), + 'antraege'=> array(), + 'bezeichnungStg' => $antrag->bezeichnung, + 'bezeichnungOrgform' => $antrag->orgform + ); + + $result = $this->antraglib->getPrestudentWiederholungsBerechtigt($antrag->prestudent_id); + if (getData($result) == 1) + $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Wiederholung'; + + $result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($antrag->prestudent_id); + if (getData($result) == 1) + $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Unterbrechung'; + + $result = $this->antraglib->getPrestudentAbmeldeBerechtigt($antrag->prestudent_id); + if (getData($result) == 1) + $prestudentenArr[$antrag->prestudent_id]['allowedNewTypes'][] = 'Abmeldung'; + } + if ($antrag->studierendenantrag_id == null) + continue; + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL && (!$antrag->isapproved)) + continue; + + $prestudentenArr[$antrag->prestudent_id]['antraege'][] = $antrag; + } + + $this->load->view('lehre/Antrag/Student/List', [ + 'antraege' => $prestudentenArr + ]); + } + + public function leitung() + { + $stgL = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; + + $stgA = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []; + + $this->load->view('lehre/Antrag/Leitung/List', [ + 'stgA' => $stgA, + 'stgL' => $stgL + ]); + } + + public function abmeldung($prestudent_id, $studierendenantrag_id = null) + { + $this->load->view('lehre/Antrag/Create', [ + 'prestudent_id' => $prestudent_id, + 'studierendenantrag_id' => $studierendenantrag_id, + 'antrag_type' => 'Abmeldung' + ]); + } + + public function abmeldungstgl($prestudent_id, $studierendenantrag_id = null) + { + $this->load->view('lehre/Antrag/Create', [ + 'prestudent_id' => $prestudent_id, + 'studierendenantrag_id' => $studierendenantrag_id, + 'antrag_type' => 'AbmeldungStgl' + ]); + } + + public function unterbrechung($prestudent_id, $studierendenantrag_id = null) + { + $this->load->view('lehre/Antrag/Create', [ + 'prestudent_id' => $prestudent_id, + 'studierendenantrag_id' => $studierendenantrag_id, + 'antrag_type' => 'Unterbrechung' + ]); + } + + public function wiederholung($prestudent_id, $studierendenantrag_id = null) + { + $this->load->view('lehre/Antrag/Create', [ + 'prestudent_id' => $prestudent_id, + 'studierendenantrag_id' => $studierendenantrag_id, + 'antrag_type' => 'Wiederholung' + ]); + } + + /** + * Checks if the caller is allowed to access to this content with the given permissions + * If it is not allowed will set the HTTP header with code 401 + * Wrapper for permissionlib->isEntitled + */ + private function _isAllowed($requiredPermissions) + { + // Loads permission lib + $this->load->library('PermissionLib'); + + // Checks if this user is entitled to access to this content + if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method)) + { + $this->output->set_status_header(REST_Controller::HTTP_UNAUTHORIZED); // set the HTTP header as unauthorized + + $this->load->library('EPrintfLib'); // loads the EPrintfLib to format the output + + // Prints the main error message + $this->eprintflib->printError('You are not allowed to access to this content'); + // Prints the called controller name + $this->eprintflib->printInfo('Controller name: '.$this->router->class); + // Prints the called controller method name + $this->eprintflib->printInfo('Method name: '.$this->router->method); + // Prints the required permissions needed to access to this method + $this->eprintflib->printInfo('Required permissions: '.$this->_rpsToString($requiredPermissions, $this->router->method)); + + exit; // immediately terminate the execution + } + } + + /** + * Converts an array of permissions to a string that contains them as a comma separated list + * Ex: ", , " + */ + private function _rpsToString($requiredPermissions, $method) + { + $strRequiredPermissions = ''; // string that contains all the required permissions needed to access to this method + + if (isset($requiredPermissions[$method])) // if the called method is present in the permissions array + { + // If it is NOT then convert it into an array + $rpsMethod = $requiredPermissions[$method]; + if (!is_array($rpsMethod)) + { + $rpsMethod = array($rpsMethod); + } + + // Copy all the permissions into $strRequiredPermissions separated by a comma + for ($i = 0; $i < count($rpsMethod); $i++) + { + $strRequiredPermissions .= $rpsMethod[$i].', '; + } + + $strRequiredPermissions = rtrim($strRequiredPermissions, ', '); + } + + return $strRequiredPermissions; + } +} diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index 1922bacda..3cba756cf 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -152,10 +152,10 @@ class requestAnrechnung extends Auth_Controller return $this->outputJsonError($this->p->t('anrechnung', 'antragBereitsGestellt')); } - // Exit if application is not for actual studysemester - if (!self::_applicationIsForActualSS($studiensemester_kurzbz)) + // Exit if application is a past ( < actual ) studysemester + if (self::_applicationIsPastSS($studiensemester_kurzbz)) { - return $this->outputJsonError($this->p->t('anrechnung', 'antragNurImAktSS')); + return $this->outputJsonError($this->p->t('anrechnung', 'antragNichtFuerVerganganeSS')); } // Upload document @@ -312,18 +312,21 @@ class requestAnrechnung extends Auth_Controller } /** - * Check if applications' study semester is actual study semester. + * Check if applications' study semester is < actual study semester. * * @param $studiensemester_kurzbz * @return bool */ - private function _applicationIsForActualSS($studiensemester_kurzbz) + private function _applicationIsPastSS($studiensemester_kurzbz) { $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $result = $this->StudiensemesterModel->getNearest(); - $actual_ss = getData($result)[0]->studiensemester_kurzbz; + $actual_ss = getData($result)[0]; - return $studiensemester_kurzbz == $actual_ss; + $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); + $anrechnung_ss = getData($result)[0]; + + return $anrechnung_ss->ende < $actual_ss->start; } private function _LVhasBlockingGrades($studiensemester_kurzbz, $lehrveranstaltung_id) diff --git a/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php b/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php index 6ac2da887..4abb1c400 100644 --- a/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php +++ b/application/controllers/lehre/lehrauftrag/LehrauftragAkzeptieren.php @@ -35,6 +35,7 @@ class LehrauftragAkzeptieren extends Auth_Controller $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); $this->load->model('codex/Bisverwendung_model', 'BisverwendungModel'); $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model', 'DienstverhaeltnisModel'); // Load libraries $this->load->library('WidgetLib'); @@ -94,9 +95,9 @@ class LehrauftragAkzeptieren extends Auth_Controller 'lektor' => true, 'aktiv' => true )); - + $is_external_lector = hasData($result) ? true : false; - + $view_data = array( 'studiensemester_selected' => $studiensemester_kurzbz, 'is_external_lector' => $is_external_lector @@ -207,15 +208,41 @@ class LehrauftragAkzeptieren extends Auth_Controller */ public function checkInkludierteLehre() { - $result = $this->BisverwendungModel->getLast($this->_uid, false); - - if (hasData($result)) + if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT) { - $this->outputJsonSuccess(!is_null($result->retval[0]->inkludierte_lehre) && $result->retval[0]->inkludierte_lehre != 0); + // Bei neuer Vertragsstruktur wird nur anhand des echten DVs entschieden ob eine Anzeige + // des Stundensatzes erfolgt oder nicht. + $result = $this->DienstverhaeltnisModel->getDVByPersonUID($this->_uid, null, date('Y-m-d')); + + if (hasData($result)) + { + $data = getData($result); + foreach($data as $row) + { + if($row->vertragsart_kurzbz == 'echterdv') + $this->outputJsonSuccess(true); + else + $this->outputJsonSuccess(false); + } + } + else + { + $this->outputJsonError(getError($result)); + } } else { - $this->outputJsonError(getError($result)); + // DEPRECATED + $result = $this->BisverwendungModel->getLast($this->_uid, false); + + if (hasData($result)) + { + $this->outputJsonSuccess(!is_null($result->retval[0]->inkludierte_lehre) && $result->retval[0]->inkludierte_lehre != 0); + } + else + { + $this->outputJsonError(getError($result)); + } } } diff --git a/application/controllers/public/js/Components.php b/application/controllers/public/js/Components.php new file mode 100644 index 000000000..830e7ea65 --- /dev/null +++ b/application/controllers/public/js/Components.php @@ -0,0 +1,43 @@ +output->set_content_type('text/javascript'); + $this->output->set_output($contents); + } +} diff --git a/application/controllers/system/MigrateContract.php b/application/controllers/system/MigrateContract.php new file mode 100644 index 000000000..99b894473 --- /dev/null +++ b/application/controllers/system/MigrateContract.php @@ -0,0 +1,680 @@ +load->model('codex/bisverwendung_model', 'BisVerwendungModel'); + $this->load->model('person/benutzerfunktion_model', 'BenutzerfunktionModel'); + + $this->matching_ba1_vertragsart = array( + '101'=>'externerlehrender', + '102'=>'DV anderen Gebietskörperschaft', + '103'=>'echterdv', + '104'=>'studentischehilfskr', + '105'=>'externerlehrender', + '106'=>'Andere Bildungseinrichtung', + '107'=>'werkvertrag', + '108'=>'studentischehilfskr', + '109'=>'ueberlassungsvertrag', + '110'=>'echterfreier', + '111'=>'echterdv', //All-In + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index($user = null) + { + if (!is_null($user)) + { + $contracts = $this->_transformUser($user); + + /* + Format: + $contracts['dv'][]['vbs'][] + */ + //$this->outputJson($contracts); + var_dump($contracts); + $this->_saveJSON($contracts); + } + else + { + $qry = "SELECT distinct mitarbeiter_uid FROM bis.tbl_bisverwendung"; + $db = new DB_Model(); + + $resultUser = $db->execReadOnlyQuery($qry); + if (hasData($resultUser)) + { + $users = getData($resultUser); + foreach($users as $user) + { + $contracts = $this->_transformUser($user->mitarbeiter_uid); + $this->_saveJSON($contracts); + } + } + + } + } + + private function _saveJSON($contracts) + { + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $this->load->model('vertragsbestandteil/Vertragsbestandteil_model','VertragsbestandteilModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model','VertragsbestandteilZeitaufzeichnungModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilKarenz_model','VertragsbestandteilKarenzModel'); + + $failed = false; + $this->db->trans_begin(); + + foreach($contracts['dv'] as $row_dv) + { + // Dienstvertrag erstellen + $resultDV = $this->DienstverhaeltnisModel->insert( + array( + 'mitarbeiter_uid' => $row_dv['mitarbeiter_uid'], + 'vertragsart_kurzbz' => $row_dv['vertragsart_kurzbz'], + 'oe_kurzbz' => $row_dv['oe_kurzbz'], + 'von' => $row_dv['von'], + 'bis' => $row_dv['bis'], + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateContract' + ) + ); + + if (isSuccess($resultDV) && hasData($resultDV)) + { + $dv_id = getData($resultDV); + + // Vertragsbetandteile erstellen + foreach($row_dv['vbs'] as $row_vbs) + { + $resultVBS = $this->VertragsbestandteilModel->insert( + array( + 'dienstverhaeltnis_id' => $dv_id, + 'vertragsbestandteiltyp_kurzbz' => $row_vbs['vertragsbestandteiltyp_kurzbz'], + 'von' => $row_vbs['von'], + 'bis' => $row_vbs['bis'], + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateContract' + ) + ); + + if (isSuccess($resultVBS) && hasData($resultVBS)) + { + $vbs_id = getData($resultVBS); + echo 'VBS:'.$vbs_id; + + switch($row_vbs['vertragsbestandteiltyp_kurzbz']) + { + case 'stunden': + $resultVBS = $this->_insertVBSStunden($vbs_id, $row_vbs); + break; + case 'zeitaufzeichnung': + $resultVBS = $this->_insertVBSZeitaufzeichnung($vbs_id, $row_vbs); + break; + case 'funktion': + $resultVBS = $this->_insertVBSFunktion($vbs_id, $row_vbs); + break; + case 'freitext': + $resultVBS = $this->_insertVBSFreitext($vbs_id, $row_vbs); + break; + case 'karenz': + $resultVBS = $this->_insertVBSKarenz($vbs_id, $row_vbs); + break; + } + + if (isError($resultVBS)) + { + echo "FAILED:".getError($resultVBS); + $failed = true; + } + } + else + { + $failed = true; + } + } + } + else + { + $failed = true; + } + } + + if(!$failed) + { + $this->db->trans_commit(); + } + else + { + echo "ROLLBACK"; + $this->db->trans_rollback(); + } + } + + private function _insertVBSKarenz($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilKarenzModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'karenztyp_kurzbz' => $row_vbs['karenztyp_kurzbz'] + ) + ); + } + + private function _insertVBSFreitext($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilFreitextModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'freitexttyp_kurzbz' => $row_vbs['freitexttyp_kurzbz'], + 'titel' => $row_vbs['titel'], + 'anmerkung' => $row_vbs['anmerkung'] + ) + ); + } + + private function _insertVBSFunktion($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilFunktionModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'benutzerfunktion_id' => $row_vbs['benutzerfunktion_id'] + ) + ); + } + + private function _insertVBSZeitaufzeichnung($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilZeitaufzeichnungModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'zeitaufzeichnung' => $row_vbs['zeitaufzeichnung'], + 'azgrelevant' => $row_vbs['azgrelevant'], + 'homeoffice' => $row_vbs['homeoffice'] + ) + ); + } + + private function _insertVBSStunden($vbs_id, $row_vbs) + { + return $this->VertragsbestandteilStundenModel->insert( + array( + 'vertragsbestandteil_id' => $vbs_id, + 'wochenstunden' => $row_vbs['wochenstunden'], + 'teilzeittyp_kurzbz' => $row_vbs['teilzeittyp_kurzbz'] + ) + ); + } + + /** + * Ermittelt die neue Vertragsstruktur fuer einen User + */ + private function _transformUser($user) + { + $contracts = array(); + $this->BisVerwendungModel->addOrder('beginn'); + $result_verwendung = $this->BisVerwendungModel->loadWhere(array("mitarbeiter_uid" => $user)); + + if (isError($result_verwendung)) + die("Failed to load Verwendung"); + + if (hasData($result_verwendung)) + { + $verwendung = getData($result_verwendung); + + foreach ($verwendung as $row_verwendung) + { + $dv = $this->_getOrCreateDV($contracts, $row_verwendung); + + // Ende des DV aktualisieren + if ($contracts['dv'][$dv]['bis'] < $row_verwendung->ende || $row_verwendung->ende == '') + $contracts['dv'][$dv]['bis'] = $row_verwendung->ende; + + // Stundenbestandteil pruefen + $this->_addVertragsbestandteilStunden($contracts, $dv, $row_verwendung); + + // Befristung + $this->_addVertragsbestandteilFreitextBefristung($contracts, $dv, $row_verwendung); + + // All-In + $this->_addVertragsbestandteilFreitextAllIn($contracts, $dv, $row_verwendung); + + // Zeitaufzeichnung + $this->_addVertragsbestandteilZeitaufzeichnung($contracts, $dv, $row_verwendung); + + // Karenz + $this->_addVertragsbestandteilKarenz($contracts, $dv, $row_verwendung); + + // Inkludierte Lehre + // Kuendigungsfrist + // Urlaubsanspruch + } + + // Funktion + $this->_addVertragsbestandteilFunktion($contracts, $user); + + } + + return $contracts; + } + + /** + * Fuegt Karenzierungseintraege zu bestehenden Dienstverhaeltnissen hinzu + */ + private function _addVertragsbestandteilKarenz(&$contracts, $dv, $row_verwendung) + { + if ($row_verwendung->beschausmasscode == 5) + { + $dtstart = new DateTime($row_verwendung->beginn); + $dtende = new DateTime($row_verwendung->ende); + $interval = $dtende->diff($dtstart); + $dauer = $interval->format('%a'); + + // TODO: klären ob das so machbar ist + if ($dauer < 65) + $karenztyp = 'papamonat'; + elseif ($dauer < 120) + $karenztyp = 'bildungskarenz'; + else + $karenztyp = 'elternkarenz'; + + // VBS anlegen und Funktion zuweisen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'karenz'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['karenztyp_kurzbz'] = $karenztyp; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['geplanter_geburtstermin'] = null; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['tatsaechlicher_geburtstermin'] = null; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['hint'] = 'Dauer:'.$dauer; + } + } + + /** + * Holt die Funktionen die Vertragsrelevant sind und verknüpft diese + */ + private function _addVertragsbestandteilFunktion(&$contracts, $user) + { + // Alle Funktionen holen die Vertragsrelevant sind + $this->BenutzerfunktionModel->addOrder('datum_von'); + $this->BenutzerfunktionModel->addJoin('public.tbl_funktion','funktion_kurzbz'); + $resultFunktionen = $this->BenutzerfunktionModel->loadWhere(array('uid' => $user, 'vertragsrelevant' => true)); + + if (isSuccess($resultFunktionen) && hasData($resultFunktionen)) + { + $funktionen = getData($resultFunktionen); + + foreach ($funktionen as $row_funktion) + { + $funktion_added = 0; + $dv = ''; + + // Passendes DV suchen + foreach ($contracts['dv'] as $key_dv => $row_contract) + { + // Eine Funktion kann zu mehreren DV zugeordnet sein + // es werden daher alle durchsucht ob es reinfaellt und ggf mehrfach zugeordnet + if ((isset($row_funktion->datum_von) && $row_funktion->datum_von >= $row_contract['von']) + && ($row_contract['bis'] == '' || $row_contract['bis'] >= $row_funktion->datum_von) + && ( + ( + isset($row_funktion->datum_bis) && isset($row_contract['bis']) + && $row_funktion->datum_bis <= $row_contract['bis'] + ) + || $row_funktion->datum_bis == '' + || (isset($row_funktion->datum_bis) && !isset($row_contract['bis'])) + ) + ) + { + + $dv = $key_dv; + + // Startdatum und Endedatum ermitteln wenn die Funktion ueber das DV hinausgeht + // Wenn die Dauer laenger ist, wird beim Beginn/Ende des DV abgegrenzt + $dtstart_fkt = new DateTime($row_funktion->datum_von); + $dtstart_dv = new DateTime($row_contract['von']); + if ($dtstart_fkt < $dtstart_dv) + $startdatum = $row_contract['von']; + else + $startdatum = $row_funktion->datum_von; + + $dtende_fkt = new DateTime($row_funktion->datum_bis); + $dtende_dv = new DateTime($row_contract['bis']); + if ($dtende_fkt < $dtende_dv) + $endedatum = $row_funktion->datum_bis; + else + $endedatum = $row_contract['bis']; + + // VBS anlegen und Funktion zuweisen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'funktion'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $startdatum; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $endedatum; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['benutzerfunktion_id'] = $row_funktion->benutzerfunktion_id; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['hint'] = $row_funktion->funktion_kurzbz.' '.$row_funktion->datum_von.' - '.$row_funktion->datum_bis; + $funktion_added++; + } + } + if ($funktion_added == 0) + { + echo "\nFunktion nicht zugeordnet: ".$row_funktion->funktion_kurzbz.' '.$row_funktion->datum_von.' - '.$row_funktion->datum_bis; + } + } + } + } + + /** + * Prueft ob schon ein Vertragsbestandteil fuer Zeitaufzeichnung vorhanden ist das in den Zeitraum passt + * bzw direkt anschließt. Wenn es direkt anschließend ist und die Art gleich sind wird die Laufzeit verlaengert + * Ansonsten wird ein neuer VBS angelegt + */ + private function _addVertragsbestandteilZeitaufzeichnung(&$contracts, $dv, $row_verwendung) + { + if (isset($contracts['dv'][$dv]['vbs'])) + { + foreach ($contracts['dv'][$dv]['vbs'] as $index_vbs=>$row_vbs) + { + if ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'zeitaufzeichnung') + { + if ($this->_isVBSAngrenzend($row_verwendung, $row_vbs) + && $row_vbs['zeitaufzeichnung'] == $row_verwendung->zeitaufzeichnungspflichtig + && $row_vbs['azgrelevant'] == $row_verwendung->azgrelevant + && $row_vbs['homeoffice'] == $row_verwendung->homeoffice + ) + { + // Zeitaufzeichnungsarten bleiben gleich - Ende des VBS verlaengern + $contracts['dv'][$dv]['vbs'][$index_vbs]['bis'] = $row_verwendung->ende; + return true; + } + } + } + } + + // kein passender VBS gefunden - neuen anlegen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'zeitaufzeichnung'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['zeitaufzeichnung'] = $row_verwendung->zeitaufzeichnungspflichtig; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['azgrelevant'] = $row_verwendung->azgrelevant; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['homeoffice'] = $row_verwendung->homeoffice; + + return true; + } + + /** + * Fueg einen Freitextbestandteil fuer All-In zum DV hinzu + */ + private function _addVertragsbestandteilFreitextAllIn(&$contracts, $dv, $row_verwendung) + { + if ($row_verwendung->ba1code == 111) // All-In + { + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'freitext'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['freitexttyp_kurzbz'] = 'allin'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['titel'] = 'allin'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['anmerkung'] = 'allin'; + } + return true; + } + + /** + * Fueg einen Freitextbestandteil fuer die Berfristung zum DV hinzu + */ + private function _addVertragsbestandteilFreitextBefristung(&$contracts, $dv, $row_verwendung) + { + if ($row_verwendung->ba2code == 1) // Befristung + { + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'freitext'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['freitexttyp_kurzbz'] = 'befristung'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['titel'] = 'befristung'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['anmerkung'] = 'befristung'; + } + return true; + } + + /** + * Prueft ob schon ein Vertragsbestandteil mit diesem Stundenausmass vorhanden ist das in den Zeitraum passt + * bzw direkt anschließt. Wenn es direkt anschließend ist und die Stunden gleich sind wird die Laufzeit verlaengert + * Ansonsten wird ein neuer VBS angelegt + */ + private function _addVertragsbestandteilStunden(&$contracts, $dv, $row_verwendung) + { + // Nur anlegen wenn im aktuellen Eintrag auch Stunden eingetragen sind + if ($row_verwendung->vertragsstunden != '') + { + if (isset($contracts['dv'][$dv]['vbs'])) + { + foreach ($contracts['dv'][$dv]['vbs'] as $index_vbs=>$row_vbs) + { + if ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'stunden' || ($row_vbs['vertragsbestandteiltyp_kurzbz'] == 'karenz' && $row_verwendung->vertragsstunden === '0.00')) + { + if ($this->_isVBSAngrenzend($row_verwendung, $row_vbs) && ((isset($row_vbs['wochenstunden']) && $row_vbs['wochenstunden'] == $row_verwendung->vertragsstunden) || $row_verwendung->vertragsstunden === '0.00')) + { + // stunden bleiben gleich - Ende des VBS verlaengern + $contracts['dv'][$dv]['vbs'][$index_vbs]['bis'] = $row_verwendung->ende; + return true; + } + } + } + } + + // kein passender VBS gefunden - neuen anlegen + $newVBSIndex = $this->_getNewVBSIndex($contracts, $dv); + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['vertragsbestandteiltyp_kurzbz'] = 'stunden'; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['wochenstunden'] = $row_verwendung->vertragsstunden; + $contracts['dv'][$dv]['vbs'][$newVBSIndex]['teilzeittyp_kurzbz'] = null; + } + return true; + } + + /** + * Prueft ob die Verwendung direkt an den Vertragsbestandteil angrenzt + * @return boolean true wenn ja, sonst false + */ + private function _isVBSAngrenzend($verwendung, $vbs) + { + // Beginn Minus 1 Tag + $dtstart = new DateTime($verwendung->beginn); + $dtstartMinus1 = $dtstart->sub(new DateInterval('P1D'))->format('Y-m-d'); + + if ($vbs['bis'] == '' + || $vbs['bis'] == $dtstartMinus1) + { + return true; + } + + return false; + } + + /** + * Create a new DV or Returns the Index of an existing + */ + private function _getOrCreateDV(&$contracts, $row_verwendung) + { + $unternehmen = $this->OE_DEFAULT; + $resultUnternehmen = $this->_getUnternehmen($row_verwendung); + if(hasData($resultUnternehmen)) + { + $unternehmen = getData($resultUnternehmen)[0]->oe_kurzbz; + } + else + { + // Fallback Unternehmen wird verwendet falls keine Zuordnung ermittelt werden kann + } + + if (isset($contracts['dv']) && is_array($contracts['dv'])) + { + foreach($contracts['dv'] as $indexdv => $row_dv) + { + // Vertragsart ist die selbe und selbes Unternehmen + if ($row_dv['vertragsart_kurzbz'] == $this->matching_ba1_vertragsart[$row_verwendung->ba1code] + && $row_dv['oe_kurzbz'] == $unternehmen + ) + { + + $dtstart = new DateTime($row_verwendung->beginn); + + // Zeitraum passt zur Verwendung + if ($row_dv['von'] <= $row_verwendung->beginn // Beginn Datum Pruefen + && ( // Ende innerhalb des DV + (isset($row_dv['bis']) && $row_verwendung->ende != '' && ($row_dv['bis'] == '' || $row_dv['bis'] >= $row_verwendung->ende) + ) + || // direkt angrenzend an dieses DV + (isset($row_dv['bis']) + && ($row_dv['bis'] == '' + || $row_dv['bis'] == $dtstart->sub(new DateInterval('P1D'))->format('Y-m-d') + ) + ) + ) + ) + { + return $indexdv; + } + } + } + } + + $newDvIndex = $this->_getNewDVIndex($contracts); + $contracts['dv'][$newDvIndex]['mitarbeiter_uid'] = $row_verwendung->mitarbeiter_uid; + $contracts['dv'][$newDvIndex]['von'] = $row_verwendung->beginn; + $contracts['dv'][$newDvIndex]['bis'] = $row_verwendung->ende; + $contracts['dv'][$newDvIndex]['oe_kurzbz'] = $unternehmen; + $contracts['dv'][$newDvIndex]['vertragsart_kurzbz'] = $this->matching_ba1_vertragsart[$row_verwendung->ba1code]; + + return $newDvIndex; + } + + /** + * Ermittelt in welchem Unternehmen die Person zum betreffenden Zeitpunkt ist. + */ + private function _getUnternehmen($row_verwendung) + { + + $resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung'", $row_verwendung->beginn); + + // Wenn zeitlich keine passende Unternehmenszuordnung vorhanden ist, dann suchen ob generell eine Zuordnung ermittelt werden kann + if(!hasData($resultUnternehmen)) + { + $resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung'"); + + // Falls nicht wird nach erweiterten Funktionen gesucht um die Zuordnung zu ermitteln. + if(!hasData($resultUnternehmen)) + { + $resultUnternehmen = $this->_findUnternehmen($row_verwendung->mitarbeiter_uid, "'kstzuordnung', 'oezuordnung','hilfskraft','Leitung','fbk','fbl'"); + } + } + + return $resultUnternehmen; + } + + /** + * Detailsuche fuer die Ermittlung des Unternehmenszuordnung einer Person + */ + private function _findUnternehmen($uid, $fkt=null, $datum=null) + { + $db = new DB_Model(); + + $qry = " + WITH RECURSIVE meine_oes(oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz) as + ( + SELECT + oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit + WHERE + oe_kurzbz=(SELECT + oe_kurzbz + FROM + public.tbl_benutzerfunktion + WHERE + uid=".$db->escape($uid); + + if(!is_null($datum)) + $qry.=" AND ".$db->escape($datum)." BETWEEN datum_von AND COALESCE(datum_bis, '2999-12-31')"; + + if(!is_null($fkt)) + $qry.=" AND funktion_kurzbz in ($fkt)"; + + $qry.=" + ORDER BY funktion_kurzbz, datum_von LIMIT 1) + UNION ALL + SELECT + o.oe_kurzbz, o.oe_parent_kurzbz, o.organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit o, meine_oes + WHERE + o.oe_kurzbz=meine_oes.oe_parent_kurzbz + ) + SELECT + oe_kurzbz + FROM + meine_oes + WHERE + oe_parent_kurzbz is null + LIMIT 1 + "; + + $resultUnternehmen = $db->execReadOnlyQuery($qry); + return $resultUnternehmen; + } + + /** + * Ermittelt den nächsten (freien) Index für den Vertragsbetandteil + */ + private function _getNewVBSIndex($contracts, $dv) + { + if (isset($contracts['dv'][$dv]['vbs'])) + return max(array_keys($contracts['dv'][$dv]['vbs'])) + 1; + else + return 0; + } + + /** + * Ermittelt den nächsten (freien) Index für das Dienstverhältnis + */ + private function _getNewDVIndex($contracts) + { + if (isset($contracts['dv']) && is_array($contracts['dv'])) + return max(array_keys($contracts['dv'])) + 1; + else + return 0; + } +} diff --git a/application/controllers/system/MigrateHourlyRate.php b/application/controllers/system/MigrateHourlyRate.php new file mode 100644 index 000000000..4fed2f585 --- /dev/null +++ b/application/controllers/system/MigrateHourlyRate.php @@ -0,0 +1,188 @@ +_ci = & get_instance(); + + $this->load->model('codex/Bisverwendung_model', 'BisVerwendungModel'); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + $this->load->model('ressource/Stundensatz_model', 'StundensatzModel'); + } + + public function index($user = null) + { + $mitarbeiterResult = $this->_getMitarbeiterStunden($user); + if (isError($mitarbeiterResult)) return $mitarbeiterResult; + if (!hasData($mitarbeiterResult)) return error('Keine Mitarbeiterstunden gefunden'); + + $mitarbeiterArray = getData($mitarbeiterResult); + + foreach ($mitarbeiterArray as $mitarbeiter) + { + $this->_getUnternehmen($mitarbeiter); + $insertResult = $this->_addStundensatz($mitarbeiter, self::STUNDENSTAZTYP_LEHRE, self::DEFAULT_DATE); + if (isError($insertResult)) return $insertResult; + } + + $sapResult = $this->_getSapStunden($user); + if (isError($sapResult)) return $sapResult; + if (!hasData($sapResult)) return error('Keinen kalkulatorischen Stundensaetze gefunden'); + + $mitarbeiterArray = getData($sapResult); + + foreach ($mitarbeiterArray as $mitarbeiter) + { + $this->_getUnternehmen($mitarbeiter); + $insertResult = $this->_addStundensatz($mitarbeiter, self::STUNDENSTAZTYP_KALKULATORISCH, date_format(date_create($mitarbeiter->beginn), 'Y-m-d')); + if (isError($insertResult)) return $insertResult; + } + } + + private function _getSapStunden($user = null) + { + $dbModel = new DB_Model(); + $params = array(); + + $qry = "SELECT ss.mitarbeiter_uid as uid, + ss.sap_kalkulatorischer_stundensatz as stundensatz, + ss.insertamum as beginn + FROM sync.tbl_sap_stundensatz ss + WHERE ss.sap_kalkulatorischer_stundensatz IS NOT NULL"; + + if (!is_null($user)) + { + $qry .= " AND ss.mitarbeiter_uid = ? "; + $params[] = $user; + } + $qry .= " ORDER BY ss.mitarbeiter_uid"; + + return $dbModel->execReadOnlyQuery($qry, $params); + } + + private function _getMitarbeiterStunden($user = null) + { + $dbModel = new DB_Model(); + $params = array(); + + $qry = "SELECT mitarbeiter.mitarbeiter_uid as uid, + stundensatz + FROM public.tbl_mitarbeiter mitarbeiter + WHERE mitarbeiter.stundensatz != 0.00 + AND mitarbeiter.stundensatz IS NOT NULL"; + + if (!is_null($user)) + { + $qry .= " AND mitarbeiter.mitarbeiter_uid = ?"; + $params[] = $user; + } + + $qry .= " ORDER BY mitarbeiter.mitarbeiter_uid"; + + return $dbModel->execReadOnlyQuery($qry, $params); + } + + private function _addStundensatz($mitarbeiter, $stundensatztyp, $gueltig_von) + { + return $this->_ci->StundensatzModel->insert( + array( + 'uid' => $mitarbeiter->uid, + 'stundensatztyp' => $stundensatztyp, + 'stundensatz' => $mitarbeiter->stundensatz, + 'oe_kurzbz' => $mitarbeiter->unternehmen, + 'gueltig_von' => $gueltig_von, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateHours' + ) + ); + } + + private function _getUnternehmen(&$mitarbeiter) + { + $bvResult = $this->_ci->BisVerwendungModel->getLast($mitarbeiter->uid); + + $beginn = null; + if (hasData($bvResult)) + { + $beginn = getData($bvResult)[0]->beginn; + } + + $unternehmenResult = $this->_findUnternehmen($mitarbeiter->uid, "'kstzuordnung', 'oezuordnung'", $beginn); + + if(!hasData($unternehmenResult)) //&& hasData($bvResult) + { + $unternehmenResult = $this->_findUnternehmen($mitarbeiter->uid, "'kstzuordnung', 'oezuordnung'"); + } + + $unternehmen = self::DEFAULT_OE; + + if (hasData($unternehmenResult)) + $unternehmen = getData($unternehmenResult)[0]->oe_kurzbz; + + $mitarbeiter->unternehmen = $unternehmen; + } + + /** + * Detailsuche fuer die Ermittlung des Unternehmenszuordnung einer Person + */ + private function _findUnternehmen($uid, $fkt=null, $datum=null) + { + $dbModel = new DB_Model(); + + $qry = " + WITH RECURSIVE meine_oes(oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz) as + ( + SELECT + oe_kurzbz, oe_parent_kurzbz, organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit + WHERE + oe_kurzbz=(SELECT + oe_kurzbz + FROM + public.tbl_benutzerfunktion + WHERE + uid=".$dbModel->escape($uid); + + if(!is_null($datum)) + $qry.=" AND ".$dbModel->escape($datum)." BETWEEN datum_von AND COALESCE(datum_bis, '2999-12-31')"; + + if(!is_null($fkt)) + $qry.=" AND funktion_kurzbz in ($fkt)"; + + $qry.=" + ORDER BY funktion_kurzbz, datum_von LIMIT 1) + UNION ALL + SELECT + o.oe_kurzbz, o.oe_parent_kurzbz, o.organisationseinheittyp_kurzbz + FROM + public.tbl_organisationseinheit o, meine_oes + WHERE + o.oe_kurzbz=meine_oes.oe_parent_kurzbz + ) + SELECT + oe_kurzbz + FROM + meine_oes + WHERE + oe_parent_kurzbz is null + LIMIT 1 + "; + + return $dbModel->execReadOnlyQuery($qry); + } + +} diff --git a/application/controllers/system/MigrateSalary.php b/application/controllers/system/MigrateSalary.php new file mode 100644 index 000000000..e8771f913 --- /dev/null +++ b/application/controllers/system/MigrateSalary.php @@ -0,0 +1,465 @@ + G + private $INDEX_LOHNART = 4; + private $INDEX_BEZEICHNUNG = 5; + + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + + $this->load->model('vertragsbestandteil/Gehaltsbestandteil_model', 'GehaltsbestandteilModel'); + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $this->load->model('vertragsbestandteil/Vertragsbestandteil_model','VertragsbestandteilModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel'); + $this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel'); + + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function import($file) + { + + // CSV Laden + $file = urldecode($file); + if($handle = fopen($file, "r")) + { + $csvrow = -1; + $lastuser = ''; + $monate = array(); + $gehaltsarr = array(); + $gehaltsindex = 0; + + while (($data = fgetcsv($handle, null, ';')) !== FALSE) + { + $csvrow++; + // Kopfzeile ueberspringen + if($csvrow == 0) + { + for($i = $this->GEHALT_BEGINN_SPALTE; $i < count($data); $i++) + { + $monate[] = $data[$i]; + } + continue; + } + + // User zur SVNR ermitteln + $svnr = str_replace(' ', '',$data[0]); + $resultuser = $this->_getUser($svnr); + + if(!hasData($resultuser)) + { + echo getError($resultuser); + break; + } + + $user = getData($resultuser)[0]->mitarbeiter_uid; + echo "\nUser:".$user; + + if($user != $lastuser && $lastuser != '') + { + $this->_saveGehalt($lastuser, $gehaltsarr); + $gehaltsarr = array(); + $gehaltsindex = 0; + $lastuser = $user; + } + else + { + $lastuser = $user; + } + + // Gehalt Clustern + + $monat = 0; + for ($i = $this->GEHALT_BEGINN_SPALTE; $i < count($data); $i++) + { + if (count($gehaltsarr) == 0 && $data[$i] != '') + { + $gehaltsarr[$gehaltsindex]['betrag'] = $data[$i]; + $gehaltsarr[$gehaltsindex]['lohnart'] = $data[$this->INDEX_LOHNART]; + $gehaltsarr[$gehaltsindex]['bezeichnung'] = $data[$this->INDEX_BEZEICHNUNG]; + $gehaltsarr[$gehaltsindex]['beginn'] = $monate[$monat]; + } + else + { + if ($data[$i] != '' + && isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag']) + && $gehaltsarr[$gehaltsindex]['betrag'] == $data[$i]) + { + // Gehalt bleibt gleich + } + else + { + if ($data[$i] != '') + { + // Gehalt hat sich geändert + if ($monat != 0 && isset($gehaltsarr[$gehaltsindex])) + $gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1]; + + $gehaltsindex++; + + $gehaltsarr[$gehaltsindex]['betrag'] = $data[$i]; + $gehaltsarr[$gehaltsindex]['lohnart'] = $data[$this->INDEX_LOHNART]; + $gehaltsarr[$gehaltsindex]['bezeichnung'] = $data[$this->INDEX_BEZEICHNUNG]; + $gehaltsarr[$gehaltsindex]['beginn'] = $monate[$monat]; + } + elseif(isset($gehaltsarr[$gehaltsindex])) + { + // Gehalt wurde beendet + if($monat!=0) + $gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1]; + $gehaltsindex++; + } + } + } + + $monat++; + } + + // Zeile zu Ende - Ende Datum setzen wenn nicht für alle Monate ein Eintrag vorhanden ist + if($monat < count($monate) && isset($gehaltsarr[$gehaltsindex])) + $gehaltsarr[$gehaltsindex]['ende'] == $monate[$monat-1]; + + } + $this->_saveGehalt($lastuser, $gehaltsarr); + } + } + + /** + * Ermittelt das passende Dienstverhaeltnis uns speichert den + * Gehaltsbestandteil + */ + private function _saveGehalt($uid, $gehaltsarr) + { + $failed = false; + $this->db->trans_begin(); + + foreach($gehaltsarr as $row_gehalt) + { + $auszahlungen = 14; + $dvid = ''; + $vbsid = ''; + $typ = ''; + $allin = false; + + //DV und VBS Ermitteln + $dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $row_gehalt['beginn']); + + if (!hasData($dv)) + { + $date = new DateTime($row_gehalt['beginn']); + $date->modify('last day of this month'); + $last_day_this_month = $date->format('Y-m-d'); + + // Wenn mit Monatsersten kein DV gefunden wird, wird stattdessen mit Monatsletzten gesucht um DVs zu finden + // für Personen die erst später im Monat in ihr DV einsteigen + $dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $last_day_this_month); + + if (!hasData($dv)) + { + echo "\nKein passendes DV gefunden für User ".$uid." und Datum ".$row_gehalt['beginn']." -> ROLLBACK\n"; + $failed = true; + break; + } + else + { + // Gehaltsstart wird auf den Start des DV korrigiert wenn nicht der Monatserste + $row_gehalt['beginn'] = getData($dv)[0]->von; + } + } + + $resultdata = getData($dv); + if (count($resultdata) !== 1) + { + echo "Kein oder Mehrere DVs gefunden -> ROLLBACK"; + $failed = true; + break; + } + + $dvid = $resultdata[0]->dienstverhaeltnis_id; + + $allin = $this->_isAllIn($dvid, $row_gehalt['beginn']); + + $db = new DB_Model(); + + $resultVBS = $this->_getVBS($dvid, $row_gehalt['beginn']); + + if (hasData($resultVBS)) + { + $vbsid = getData($resultVBS)[0]->vertragsbestandteil_id; + } + else + { + echo "Vertragsbestandteil wurde nicht gefunden -> ROLLBACK"; + $failed = true; + break; + } + + if ($row_gehalt['lohnart'] == 1000) + { + if($allin) + $typ = 'grundgehalt'; + else + $typ = 'basisgehalt'; + } + elseif ($row_gehalt['lohnart']==1041 // 14x + || $row_gehalt['lohnart']==1042 // 12x + || $row_gehalt['lohnart']==3410) // USTDPausch + { + $typ = 'zusatzvereinbarung'; + + // Freitextbestandteil anlegen fuer die Zulage + // Gaehalt wird der Zuglage zugeordnet + + $data = array( + 'dienstverhaeltnis_id' => $dvid, + 'von' => $row_gehalt['beginn'], + 'vertragsbestandteiltyp_kurzbz' => 'freitext', + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateSalary' + ); + if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='') + $data['bis'] = $row_gehalt['ende']; + + $resultVBS = $this->VertragsbestandteilModel->Insert($data); + if(!isSuccess($resultVBS)) + { + echo "VBS kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + $vbsid = getData($resultVBS); + + $data = array( + 'vertragsbestandteil_id' => $vbsid, + 'freitexttyp_kurzbz' => 'zusatzvereinbarung', + 'titel' => $row_gehalt['bezeichnung'], + 'anmerkung' => $row_gehalt['bezeichnung'], + ); + $resultVBSFreitext = $this->VertragsbestandteilFreitextModel->Insert($data); + if(!isSuccess($resultVBSFreitext)) + { + echo "VBS Freitext Zusatz kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + } + elseif ($row_gehalt['lohnart']==9999) // All-In Custom Lohnart nicht per Default vorhanden + { + $typ = 'zulage'; + + // Freitextbestandteil anlegen fuer die Zulage + // Gaehalt wird der Zuglage zugeordnet + + $data = array( + 'dienstverhaeltnis_id' => $dvid, + 'von' => $row_gehalt['beginn'], + 'vertragsbestandteiltyp_kurzbz' => 'freitext', + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateSalary' + ); + if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='') + $data['bis'] = $row_gehalt['ende']; + + $resultVBS = $this->VertragsbestandteilModel->Insert($data); + if(!isSuccess($resultVBS)) + { + echo "VBS AllIn kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + $vbsid = getData($resultVBS); + + $data = array( + 'vertragsbestandteil_id' => $vbsid, + 'freitexttyp_kurzbz' => 'allin', + 'titel' => $row_gehalt['bezeichnung'], + 'anmerkung' => $row_gehalt['bezeichnung'], + ); + $resultVBSFreitext = $this->VertragsbestandteilFreitextModel->Insert($data); + if(!isSuccess($resultVBSFreitext)) + { + echo "VBS Freitext AllIn Zusatz kann nicht erstellt werden -> ROLLBACK"; + $failed = true; + break; + } + } + elseif($row_gehalt['lohnart']==5500) // ATZ + { + $typ = 'lohnausgleichatz'; + } + else + { + $typ = 'unbekannt - '.$row_gehalt['lohnart']; + echo "\nGehaltstyp unbekannt Lohnart: ".$row_gehalt['lohnart']." -> ROLLBACK"; + $failed = true; + break; + } + + // Zulage 12x und Zulage 14x aus der Bezeichnung ermitteln + if(strstr($row_gehalt['bezeichnung'], '12x')) + { + $auszahlungen = 12; + } + + // Format ist 7.777,77 und wird umformattiert in 7777.77 + $betrag = str_replace('.','', $row_gehalt['betrag']); + $betrag = str_replace(',','.',$betrag); + + $data = array( + 'dienstverhaeltnis_id' => $dvid, + 'vertragsbestandteil_id' => $vbsid, + 'gehaltstyp_kurzbz' => $typ, + 'von' => $row_gehalt['beginn'], + 'grundbetrag' => $betrag, + 'betrag_valorisiert' => $betrag, + 'anmerkung' => $row_gehalt['bezeichnung'], + 'valorisierung' => true, + 'auszahlungen' => $auszahlungen, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => 'MigrateSalary', + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => 'MigrateSalary' + ); + + if (isset($row_gehalt['ende']) && $row_gehalt['ende'] != '') + { + // Im Ende steht noch der Monatserste des letzten Monats + // Das muss geaendert werden auf den Monatsletzten oder das Ende des DVs + $date = new DateTime($row_gehalt['ende']); + $date->modify('last day of this month'); + $last_day_this_month = $date->format('Y-m-d'); + + // TODO: wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist, + // dann muss hier das Ende Datum des DV stehen bzw das Ende + // oder das Ende des VBS falls die Person in der Monatsmitte Stunden wechselt + $data['bis'] = $last_day_this_month; + } + + $ret = $this->GehaltsbestandteilModel->insert($data, + $this->GehaltsbestandteilModel->getEncryptedColumns() + ); + } + + if(!$failed) + { + $this->db->trans_commit(); + } + else + { + echo "ROLLBACK"; + $this->db->trans_rollback(); + } + } + + /** + * Prueft ob ein AllIn Vertrag vorhanden ist + */ + private function _isAllIn($dvid, $datum) + { + $db = new DB_Model(); + + $qry = " + SELECT + * + FROM + hr.tbl_vertragsbestandteil + JOIN hr.tbl_vertragsbestandteil_freitext USING(vertragsbestandteil_id) + WHERE + dienstverhaeltnis_id=".$db->escape($dvid)." + AND vertragsbestandteiltyp_kurzbz='freitext' + AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31') + AND freitexttyp_kurzbz='allin'"; + + $resultAllIn = $db->execReadOnlyQuery($qry); + + if (hasData($resultAllIn)) + return true; + else + return false; + } + + private function _getVBS($dvid, $datum) + { + $db = new DB_Model(); + + $qry = " + SELECT + * + FROM + hr.tbl_vertragsbestandteil + WHERE + dienstverhaeltnis_id=".$db->escape($dvid)." + AND vertragsbestandteiltyp_kurzbz='stunden' + AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31')"; + + $resultVBS = $db->execReadOnlyQuery($qry); + + return $resultVBS; + } + + /** + * Ermittelt den User zu einer SVNR + */ + private function _getUser($svnr) + { + $db = new DB_Model(); + + $qry = " + SELECT + mitarbeiter_uid + FROM + public.tbl_person + JOIN public.tbl_benutzer using(person_id) + JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) + WHERE + tbl_person.svnr = ". $db->escape($svnr)." + AND EXISTS( + SELECT + 1 + FROM + hr.tbl_dienstverhaeltnis + WHERE + mitarbeiter_uid=tbl_mitarbeiter.mitarbeiter_uid + AND oe_kurzbz=". $db->escape($this->OE_DEFAULT)." + ) + ORDER BY tbl_benutzer.aktiv DESC + LIMIT 1; + "; + + $result = $db->execReadOnlyQuery($qry); + + if (hasdata($result)) + { + return $result; + } + else + return error('Kein Benutzer mit DV und SVNR:'.$svnr.' gefunden'); + } +} diff --git a/application/controllers/system/TestVBform.php b/application/controllers/system/TestVBform.php new file mode 100644 index 000000000..9923bf05b --- /dev/null +++ b/application/controllers/system/TestVBform.php @@ -0,0 +1,32 @@ + 'system/developer:r' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index() + { + $this->load->view('system/logs/testVBform.php'); + } +} diff --git a/application/controllers/system/messages/FASMessages.php b/application/controllers/system/messages/FASMessages.php index 55d1da25f..e2169af9b 100644 --- a/application/controllers/system/messages/FASMessages.php +++ b/application/controllers/system/messages/FASMessages.php @@ -37,7 +37,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents) ); } @@ -53,7 +53,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents, $message_id, $recipient_id) ); } diff --git a/application/core/CI3_Events.php b/application/core/CI3_Events.php new file mode 100644 index 000000000..33a96b89e --- /dev/null +++ b/application/core/CI3_Events.php @@ -0,0 +1,51 @@ +. + */ + +use \stdClass as stdClass; + if (!defined('BASEPATH')) exit('No direct script access allowed'); /** @@ -27,6 +46,15 @@ class DB_Model extends CI_Model const PGSQL_INT8_TYPE = 'int8'; const PGSQL_FLOAT4_TYPE = 'float4'; const PGSQL_FLOAT8_TYPE = 'float8'; + const PGSQL_BYTEA_TYPE = 'bytea'; + + // Name of the config entry containing an array of password that can be used to encrypt/decrypt + const CRYPT_CONF_PASSWORDS = 'encryption_passwords'; + const CRYPT_CAST = 'cast'; + const CRYPT_PASSWORD_NAME = 'passwordName'; + const CRYPT_SELECT_TEMPLATE = 'PGP_SYM_DECRYPT(%s, \'%s\')::%s AS %s'; + const CRYPT_WHERE_TEMPLATE = 'PGP_SYM_DECRYPT(%s, \'%s\')::%s'; + const CRYPT_WRITE_TEMPLATE = 'PGP_SYM_ENCRYPT(\'%s\', \'%s\')'; protected $dbTable; // Name of the DB-Table for CI-Insert, -Update, ... protected $pk; // Name of the PrimaryKey for DB-Update, Load, ... @@ -36,7 +64,7 @@ class DB_Model extends CI_Model private $executedQueryMetaData; private $executedQueryListFields; - private $debugMode; + private $debugMode; // Debug mode enable (true) or disabled (false) /** * Constructor @@ -46,20 +74,23 @@ class DB_Model extends CI_Model // Call parent constructor parent::__construct(); - // Set properties - $this->hasSequence = true; - - // Loads DB conns and confs + // Loads DB connections and configs $this->load->database($dbtype); + // Loads the DB config to encrypt/decrypt data + $this->config->load('db_crypt'); + + // Set properties + $this->hasSequence = true; + $this->debugMode = isset($this->db->db_debug) && $this->db->db_debug === true; + + // Loads UDF model $this->load->model('system/UDF_model', 'UDFModel'); // Loads the UDF library $this->load->library('UDFLib'); // Loads the logs library $this->load->library('LogLib'); - - $this->debugMode = isset($this->db->db_debug) && $this->db->db_debug === true; } // ------------------------------------------------------------------------------------------ @@ -85,13 +116,20 @@ class DB_Model extends CI_Model * @param array $data DataArray for Insert * @return array */ - public function insert($data) + public function insert($data, $encryptedColumns = null) { // Check class properties if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); // If this table has UDF and the validation of them is ok - if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable))) return $validate; + $validate = $this->_prepareUDFsWrite($data, $this->dbTable); + if (isError($validate)) return $validate; + + // Add the pgp_sym_eccrypt postgresql function to the set clause if needed + $this->_addEncrypt($encryptedColumns, $data); + + // Add the pgp_sym_eccrypt postgresql function to the set clause if needed + if (!empty($encryptedColumns)) $this->_addEncrypt($encryptedColumns, $data); // DB-INSERT $insert = $this->db->insert($this->dbTable, $data); @@ -135,14 +173,15 @@ class DB_Model extends CI_Model * @param array $data DataArray for Insert * @return array */ - public function update($id, $data) + public function update($id, $data, $encryptedColumns = null) { // Check class properties if (is_null($this->pk)) return error('The given primary key is not valid', EXIT_MODEL); if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); // If this table has UDF and the validation of them is ok - if (isError($validate = $this->_prepareUDFsWrite($data, $this->dbTable, $id))) return $validate; + $validate = $this->_prepareUDFsWrite($data, $this->dbTable, $id); + if (isError($validate)) return $validate; $tmpId = $id; @@ -161,6 +200,9 @@ class DB_Model extends CI_Model $this->db->where($tmpId); + // Add the pgp_sym_eccrypt postgresql function to the set clause if needed + $this->_addEncrypt($encryptedColumns, $data); + // DB-UPDATE $update = $this->db->update($this->dbTable, $data); @@ -224,7 +266,7 @@ class DB_Model extends CI_Model * @param string $id ID (Primary Key) for SELECT ... WHERE * @return array */ - public function load($id = null) + public function load($id = null, $encryptedColumns = null) { // Check class properties if (is_null($this->pk)) return error('The given primary key is not valid', EXIT_MODEL); @@ -245,7 +287,7 @@ class DB_Model extends CI_Model $tmpId = array($this->pk => $id); } - return $this->loadWhere($tmpId); + return $this->loadWhere($tmpId, $encryptedColumns); } /** @@ -253,11 +295,14 @@ class DB_Model extends CI_Model * * @return array */ - public function loadWhere($where = null) + public function loadWhere($where = null, $encryptedColumns = null) { // Check class properties if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); + // Add the pgp_sym_decrypt postgresql function to the select and where clause if needed + $this->_addDecryptLoad($encryptedColumns, $where); + // Execute query $result = $this->db->get_where($this->dbTable, $where); @@ -265,7 +310,7 @@ class DB_Model extends CI_Model if ($result) { - return success($this->_toPhp($result)); + return success($this->_toPhp($result, $encryptedColumns)); } else { @@ -303,7 +348,8 @@ class DB_Model extends CI_Model // NOTE: $this->db->list_fields($tables[$t]) doesn't work if there are two tables with // the same name in two different schemas, use this workaround $fields = array(); - if (isSuccess($lstColumns = $this->_list_columns($schemaAndTable->schema, $schemaAndTable->table))) + $lstColumns = $this->_list_columns($schemaAndTable->schema, $schemaAndTable->table); + if (isSuccess($lstColumns)) { $fields = $lstColumns->retval; } @@ -381,7 +427,8 @@ class DB_Model extends CI_Model $tmpFilteredArray = array_filter(get_object_vars($sideTableObj)); if (isset($tmpFilteredArray) && count($tmpFilteredArray) > 0) { - if (($k = $this->_findMainTable($mainTableObj, $returnArray)) === false) + $k = $this->_findMainTable($mainTableObj, $returnArray); + if ($k === false) { $mainTableObj->{$sideTableProperty} = array($sideTableObj); $returnArray[$returnArrayCounter++] = $mainTableObj; @@ -758,14 +805,13 @@ class DB_Model extends CI_Model /** * Like execQuery, but it allows only to perform queries to read data */ - public function execReadOnlyQuery($query, $parametersArray = null) + public function execReadOnlyQuery($query, $parametersArray = null, $encryptedColumns = null) { $result = error('You are allowed to run only query for reading data'); // $cleanedQuery = trim(preg_replace('/\t|\n|\r|;/', '', $query)); // // - if ( - (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) @@ -775,7 +821,7 @@ class DB_Model extends CI_Model { $queryToExec = str_replace(';', '', $query); // - $result = $this->execQuery($queryToExec, $parametersArray); + $result = $this->execQuery($queryToExec, $parametersArray, $encryptedColumns); } return $result; @@ -790,13 +836,16 @@ class DB_Model extends CI_Model * boolean if the query is of the write type (INSERT, UPDATE, DELETE...) * array that represents DB data */ - protected function execQuery($query, $parametersArray = null) + protected function execQuery($query, $parametersArray = null, $encryptedColumns = null) { $result = null; // If the query is empty don't lose time if (!isEmptyString($query)) { + // Add the pgp_sym_decrypt postgresql function to the given query + $this->_addDecryptQuery($encryptedColumns, $query); + // If there are parameters to bind to the query if (is_array($parametersArray) && count($parametersArray) > 0) { @@ -812,7 +861,7 @@ class DB_Model extends CI_Model // If no errors occurred if ($resultDB) { - $result = success($this->_toPhp($resultDB)); + $result = success($this->_toPhp($resultDB, $encryptedColumns)); } else { @@ -840,7 +889,8 @@ class DB_Model extends CI_Model $result->schema = DB_Model::DEFAULT_SCHEMA; // If a schema is specified - if (($pos = strpos($schemaAndTable, '.')) !== false) + $pos = strpos($schemaAndTable, '.'); + if ($pos !== false) { $result->schema = substr($schemaAndTable, 0, $pos); $result->table = substr($schemaAndTable, $pos + 1); @@ -851,6 +901,207 @@ class DB_Model extends CI_Model // ------------------------------------------------------------------------------------------ // Private methods + // + // + + /** + * To add the pgp_sym_encrypt function to the set clause where needed + */ + private function _addEncrypt($encryptedColumns, &$data) + { + // If encryptedColumns is not defined then exit + if (isEmptyArray($encryptedColumns)) return; + + $tmpData = array(); // Temporary array used to copy not encrypted columns + + // For each column that is going to be inserted/updated + foreach ($data as $column => $value) + { + // If the current column is in the list of the columns to be encrypted + // and contains the password name element + if (array_key_exists($column, $encryptedColumns) + && array_key_exists(self::CRYPT_PASSWORD_NAME, $encryptedColumns[$column])) + { + // Password to encrypt data + $cryptConfPasswords = $this->config->item(self::CRYPT_CONF_PASSWORDS); + $encryptionPassword = $cryptConfPasswords[$encryptedColumns[$column][self::CRYPT_PASSWORD_NAME]]; + + // Add the encrypted column to the set clause without escaping + $this->db->set( + $column, + sprintf( + self::CRYPT_WRITE_TEMPLATE, + $value, + $encryptionPassword + ), + false // no escaping + ); + } + else // otherwise copy this element as it is + { + $tmpData[$column] = $value; + } + } + + $data = $tmpData; // this array does not contain encrypted columns + } + + /** + * To add the pgp_sym_decrypt function to the given query + */ + private function _addDecryptQuery($encryptedColumns, &$query) + { + // If it is request to get encrypted columns + if (!isEmptyArray($encryptedColumns)) + { + // For each requested encrypted column + foreach ($encryptedColumns as $encryptedColumn => $definition) + { + // If the requested encrypted column is well defined + if (!isEmptyArray($definition) + && array_key_exists(self::CRYPT_CAST, $definition) + && array_key_exists(self::CRYPT_PASSWORD_NAME, $definition)) + { + // And if exists the wanted password to decrypt in the configs + if (array_key_exists($definition[self::CRYPT_PASSWORD_NAME], $this->config->item(self::CRYPT_CONF_PASSWORDS))) + { + // Password to decrypt data + $cryptConfPasswords = $this->config->item(self::CRYPT_CONF_PASSWORDS); + $decryptionPassword = $cryptConfPasswords[$definition[self::CRYPT_PASSWORD_NAME]]; + + // Find and replace all the occurrences of the provided encrypted columns + // with the postgresql decryption function + $query = str_replace( + $encryptedColumn, + sprintf( + self::CRYPT_WHERE_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST] + ), + $query + ); + } + } + } + } + } + + /** + * To add the pgp_sym_decrypt function to the select and where clause where needed + */ + private function _addDecryptLoad($encryptedColumns, &$where) + { + // If it is request to get encrypted columns + if (!isEmptyArray($encryptedColumns)) + { + // For each requested encrypted column + foreach ($encryptedColumns as $encryptedColumn => $definition) + { + // If the requested encrypted column is well defined + if (!isEmptyArray($definition) + && array_key_exists(self::CRYPT_CAST, $definition) + && array_key_exists(self::CRYPT_PASSWORD_NAME, $definition)) + { + // And if exists the wanted password to decrypt in the configs + if (array_key_exists($definition[self::CRYPT_PASSWORD_NAME], $this->config->item(self::CRYPT_CONF_PASSWORDS))) + { + // Password to decrypt data + $cryptConfPasswords = $this->config->item(self::CRYPT_CONF_PASSWORDS); + $decryptionPassword = $cryptConfPasswords[$definition[self::CRYPT_PASSWORD_NAME]]; + + // ----------------------------------------- + // SELECT + + // Add to the select clause the column to be decrypted + // NOTE: this is going to override any previously added column with the same name + $this->addSelect( + sprintf( + self::CRYPT_SELECT_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST], + $encryptedColumn + ) + ); + + // ----------------------------------------- + // WHERE + + // If the where parameter is a valid array + if (!isEmptyArray($where)) + { + $tmpWhere = array(); + + // For each condition of the where clause + foreach ($where as $column => $condition) + { + $operator = null; // operator not found in the column name + + // Custom operators with 2 chars + if (strpos($column, '>=') != false + || strpos($column, '<=') != false + || strpos($column, '!=') != false + || strpos($column, '<>') != false + ) + { + $operator = ' '.substr(trim($column), -2).' '; + } + // Custom operators with 1 chars + elseif (strpos($column, '>') != false + || strpos($column, '<') != false + || strpos($column, '=') != false + ) + { + $operator = ' '.substr(trim($column), -1).' '; + } + else // default operator + { + $operator = ' = '; + } + + // If the column from the where clause is the same from the encrypted columns definition + if (trim($column) == $encryptedColumn + || ($operator != null && substr(trim($column), 0, strlen(trim($column)) - 2) == $encryptedColumn) + ) + { + // Then rename the column using the postgresql decryption function + $tmpWhere[sprintf( + self::CRYPT_WHERE_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST] + ).$operator] = $condition; + } + else // otherwise copy the column as it is + { + $tmpWhere[$column] = $condition; + } + } + + $where = $tmpWhere; // replace with the new where + } + // Otherwise if the where parameter is a valid string + elseif (!isEmptyString($where)) + { + // Find and replace all the occurrences of the provided encrypted columns + // with the postgresql decryption function + $where = str_replace( + $encryptedColumn, + sprintf( + self::CRYPT_WHERE_TEMPLATE, + $encryptedColumn, + $decryptionPassword, + $definition[self::CRYPT_CAST] + ), + $where + ); + } + } + } + } + } + } /** * Invalid ID @@ -877,11 +1128,11 @@ class DB_Model extends CI_Model { if ($id != null) { - $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $this->dbTable, $this->_getUDFsNoPerms($id)); + $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $schemaAndTable, $this->_getUDFsNoPerms($id)); } else { - $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $this->dbTable); + $prepareUDFsWrite = $this->udflib->prepareUDFsWrite($data, $schemaAndTable); } } @@ -895,7 +1146,7 @@ class DB_Model extends CI_Model * - A FALSE value on failure * - Otherwise an object filled with data on success */ - private function _toPhp($result) + private function _toPhp($result, $encryptedColumns = null) { $udfs = false; // if UDFs are inside the given result set $toPhp = $result; // if there is nothing to convert then return the result from DB @@ -911,7 +1162,9 @@ class DB_Model extends CI_Model // Looking for booleans, arrays and UDFs foreach ($this->executedQueryMetaData as $eqmd) { - // If array type, boolean type OR a UDF + // If array type, boolean type, numeric type + // Or bytea type + // Or UDF type if (strpos($eqmd->type, DB_Model::PGSQL_ARRAY_TYPE) !== false || $eqmd->type == DB_Model::PGSQL_BOOLEAN_TYPE || $eqmd->type == DB_Model::PGSQL_INT2_TYPE @@ -919,6 +1172,7 @@ class DB_Model extends CI_Model || $eqmd->type == DB_Model::PGSQL_INT8_TYPE || $eqmd->type == DB_Model::PGSQL_FLOAT4_TYPE || $eqmd->type == DB_Model::PGSQL_FLOAT8_TYPE + || $eqmd->type == DB_Model::PGSQL_BYTEA_TYPE || $this->udflib->isUDFColumn($eqmd->name, $eqmd->type)) { // If UDFs are inside this result set @@ -981,6 +1235,21 @@ class DB_Model extends CI_Model { $resultElement->{$toBeConverted->name} = $this->pgFloatPhp($resultElement->{$toBeConverted->name}); } + // Byte A type + elseif ($toBeConverted->type == DB_Model::PGSQL_BYTEA_TYPE) + { + // If encrypted columns are defined + // and if the byte a column is defined as encrypted column + if (!isEmptyArray($encryptedColumns) + && array_key_exists($toBeConverted->name, $encryptedColumns)) + { + // keep the column + } + else // otherwise remove the column from the result + { + unset($resultElement->{$toBeConverted->name}); + } + } } } } diff --git a/application/core/IEncryption.php b/application/core/IEncryption.php new file mode 100644 index 000000000..6b9132c23 --- /dev/null +++ b/application/core/IEncryption.php @@ -0,0 +1,24 @@ +. + */ + +interface IEncryption +{ + public function getEncryptedColumns(): array; +} + diff --git a/application/helpers/hlp_common_helper.php b/application/helpers/hlp_common_helper.php index 913d29b54..3e682e56c 100644 --- a/application/helpers/hlp_common_helper.php +++ b/application/helpers/hlp_common_helper.php @@ -18,6 +18,8 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); +use \DateTime as DateTime; + // ------------------------------------------------------------------------ // Collection of utility functions for general purpose // ------------------------------------------------------------------------ @@ -354,7 +356,8 @@ function sanitizeProblemChars($str) 'ss' => '/ß/' ); - return preg_replace($acentos, array_keys($acentos), htmlentities($str, ENT_NOQUOTES | ENT_HTML5, $enc)); + $tmp = preg_replace($acentos, array_keys($acentos), htmlentities($str, ENT_NOQUOTES | ENT_HTML5, $enc)); + return html_entity_decode($tmp, ENT_NOQUOTES | ENT_HTML5, $enc); } /** @@ -405,3 +408,17 @@ function findResource($path, $resource, $subdir = false, $extraDir = null) return null; } +/** + * check if String can be converted to a date + */ +function isValidDate($dateString) +{ + try + { + return (new DateTime($dateString)) !== false; + } + catch(Exception $e) + { + return false; + } +} diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index 05bba48c4..ea1795ad5 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -96,7 +96,8 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod) app_root: "'.APP_ROOT.'", ci_router: "'.$indexPage.'", called_path: "'.$calledPath.'", - called_method: "'.$calledMethod.'" + called_method: "'.$calledMethod.'", + user_language: "'.$user_language.'" };'; $toPrint .= "\n"; $toPrint .= ''; diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php new file mode 100644 index 000000000..298c3652f --- /dev/null +++ b/application/libraries/AntragLib.php @@ -0,0 +1,1987 @@ +_ci =& get_instance(); + + // Configs + $this->_ci->load->config('studierendenantrag'); + + // Models + $this->_ci->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + $this->_ci->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel'); + $this->_ci->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel'); + $this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->_ci->load->model('crm/Prestudent_model', 'PrestudentModel'); + $this->_ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + $this->_ci->load->model('person/Person_model', 'PersonModel'); + $this->_ci->load->model('education/Pruefung_model', 'PruefungModel'); + + // Helper + $this->_ci->load->helper('hlp_sancho_helper'); + + // Libraries + $this->_ci->load->library('PermissionLib'); + $this->_ci->load->library('PrestudentLib'); + } + + /** + * @param integer $antrag_id + * @param string $insertvon + * + * @return stdClass + */ + public function cancelAntrag($antrag_id, $insertvon) + { + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CANCELLED, + 'insertvon' => $insertvon + ]); + + // NOTE(chris): remove "preabbrecher" statusgrund for Stgl-Abmeldungen if set + $res = $this->_ci->StudierendenantragModel->load($antrag_id); + if (hasData($res) && current(getData($res))->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) { + $this->_ci->PrestudentstatusModel->addSelect('tbl_status_grund.statusgrund_kurzbz'); + $res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail(current(getData($res))->prestudent_id, '', 'Student'); + if (hasData($res) && current(getData($res))->statusgrund_kurzbz == 'preabbrecher') { + $prestudentstatus = current(getData($res)); + $this->_ci->PrestudentstatusModel->update([ + 'prestudent_id' => $prestudentstatus->prestudent_id, + 'status_kurzbz'=>$prestudentstatus->status_kurzbz, + 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, + 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester + ], [ + 'statusgrund_id' => null + ]); + } + } + + return $result; + } + + /** + * NOTE(chris): permissions & verification must be handled outside + * + * @param integer $prestudent_id + * @param string $studiensemester_kurzbz + * @param string $insertvon + * @param string $grund + * + * @return stdClass + */ + public function createAbmeldung($prestudent_id, $studiensemester_kurzbz, $insertvon, $grund) + { + $result = $this->_ci->PrestudentModel->load($prestudent_id); + if (isError($result)) + return $result; + if(!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', "error_no_prestudent", ['prestudent_id' => $prestudent_id])); + + $prestudent = getData($result)[0]; + if($prestudent->person_id == getAuthPersonId()) + $typ = Studierendenantrag_model::TYP_ABMELDUNG; + else + $typ = Studierendenantrag_model::TYP_ABMELDUNG_STGL; + + $result = $this->_ci->StudierendenantragModel->insert([ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz'=> $studiensemester_kurzbz, + 'datum' => date('c'), + 'typ' => $typ, + 'insertvon' => $insertvon, + 'grund' => $grund + ]); + + if (isError($result)) + return $result; + + $antrag_id = getData($result); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CREATED, + 'insertvon' => $insertvon + ]); + + if (isError($result)) + return $result; + + return success($antrag_id); + } + + /** + * @param array $studierendenantrag_ids + * @param string $insertvon + * + * @return stdClass + */ + public function approveAbmeldung($studierendenantrag_ids, $insertvon) + { + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + + $errors = []; + foreach ($studierendenantrag_ids as $studierendenantrag_id) { + $result = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); + if (isError($result)) + { + $errors[] = getError($result); + continue; + } + if(!hasData($result)) + { + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id]); + continue; + } + $antrag = getData($result)[0]; + + $insertam = date('c'); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, + 'insertvon' => $insertvon, + 'insertamum' => $insertam + ]); + if (isError($result)) + $errors[] = getError($result); + else { + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps','studiengang_kz'); + $result = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + $stg = ''; + $orgform = ''; + if (hasData($result)) { + $studiengang = current(getData($result)); + $stg = $studiengang->bezeichnung; + } + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG) + { + $resultPrestudentStatus = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id); + if (isError($resultPrestudentStatus)) + $errors[] = getError($resultPrestudentStatus); + + else { + $prestudent_status = getData($resultPrestudentStatus)[0]; + $orgform = $prestudent_status->orgform_kurzbz; + + $vorlage ='Sancho_Mail_Antrag_A_Approve'; + $subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_A_Approve'); + + $result = $this->_ci->prestudentlib->setAbbrecher( + $antrag->prestudent_id, + $antrag->studiensemester_kurzbz, + $insertvon, + 'abbrecherStud', + $antrag->datum, + $insertam + ); + if (isError($result)) + { + $errors[] = getError($result); + return $errors; + } + + $result = $this->_ci->PersonModel->loadPrestudent($antrag->prestudent_id); + $data = [ + 'student' => $this->_ci->p->t('person', 'studentIn'), + 'sem' => $antrag->studiensemester_kurzbz, + 'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' . $antrag->typ . '.xml.php&xsl=Antrag' . $antrag->typ . '&id=' . $antrag->studierendenantrag_id . '&output=pdf') + ]; + if (hasData($result)) { + $person = current(getData($result)); + $data['student'] = trim($person->vorname . ' ' . $person->nachname); + $data['vorname'] = $person->vorname; + $data['nachname'] = $person->nachname; + } + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id'=> $antrag->prestudent_id]); + if (hasData($result)) { + $student = current(getData($result)); + $data['UID'] = $student->student_uid; + } + + $data['Orgform'] = $prestudent_status->orgform; + $data['stg'] = $stg; + + // NOTE(chris): Sancho mail + sendSanchoMail($vorlage, $data, $prestudent_status->email, $subject); + } + } else { // ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) + $result = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id, '', 'Student'); + if (isError($result)) + { + $errors[] = getError($result); + continue; + } + if(!hasData($result)) + { + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $antrag->prestudent_id]); + continue; + } + $prestudentstatus = getData($result)[0]; + $orgform = $prestudentstatus->orgform_kurzbz; + + $result = $this->_ci->PrestudentstatusModel->withGrund('preabbrecher')->update([ + 'prestudent_id' => $prestudentstatus->prestudent_id, + 'status_kurzbz'=>$prestudentstatus->status_kurzbz, + 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, + 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester + ], []); + if (isError($result)) + { + $errors[] = getError($result); + continue; + } + } + + $res = $this->_ci->PrestudentModel->load($antrag->prestudent_id); + + if (hasData($res)) { + $prestudent = current(getData($res)); + $res = $this->_ci->PersonModel->load($prestudent->person_id); + if (hasData($res)) { + $person = current(getData($res)); + $name = trim($person->vorname . ' ' . $person->nachname); + $vorname = $person->vorname; + $nachname = $person->nachname; + } else { + $name = $this->_ci->p->t('person', 'studentIn'); + $vorname = ''; + $nachname = $name; + } + $res = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + if (hasData($res)) { + $email = $this->_ci->StudentModel->getEmailFH(current(getData($res))->student_uid); + $vorlage = $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG ? 'Student' : 'Stgl'; + + // NOTE(chris): Sancho mail + sendSanchoMail( + 'Sancho_Mail_Antrag_A_' . $vorlage, + [ + 'name' => $name, + 'grund' => $antrag->grund, + 'vorname' => $vorname, + 'nachname' => $nachname, + 'Orgform' => $orgform, + 'stg' => $stg + ], + $email, + $this->_ci->p->t('studierendenantrag', 'mail_subject_A_' . $vorlage) + ); + } + } + } + } + + if (count($errors)) + return error(implode(',', $errors)); + + return success(); + } + + /** + * @param integer $studierendenantrag_id + * @param string $insertvon + * + * @return stdClass + */ + public function denyObjectionAbmeldung($studierendenantrag_id, $insertvon, $grund = null) + { + $result = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); + if (isError($result)) + { + return $result; + } + if(!hasData($result)) + { + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id])); + } + $antrag = getData($result)[0]; + + $result = $this->_ci->StudierendenantragstatusModel->loadWhere([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED + ]); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_not_approved')); + + $status = current(getData($result)); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, + 'grund' => $grund, + 'insertvon' => $insertvon + ]); + if (isError($result)) + return $result; + else { + $result = $this->_ci->prestudentlib->setAbbrecher( + $antrag->prestudent_id, + $antrag->studiensemester_kurzbz, + $insertvon, + 'abbrecherStgl', + $status->insertamum + ); + + if (isError($result)) + return $result; + + $res = $this->_ci->PrestudentModel->load($antrag->prestudent_id); + + if (hasData($res)) { + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + + $prestudent = current(getData($res)); + $res = $this->_ci->PersonModel->load($prestudent->person_id); + if (hasData($res)) { + $person = current(getData($res)); + $name = trim($person->vorname . ' ' . $person->nachname); + $vorname = $person->vorname; + $nachname = $person->nachname; + } else { + $name = $this->_ci->p->t('person', 'studentIn'); + } + + $res = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + if (hasData($res)) { + $email = $this->_ci->StudentModel->getEmailFH(current(getData($res))->student_uid); + + $res = $this->_ci->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); + $stg = ''; + $orgform = ''; + if (hasData($res)) { + $studiengang = current(getData($res)); + $stg = $studiengang->bezeichnung; + $orgform = $studiengang->orgform_kurzbz; + } + + sendSanchoMail( + 'Sancho_Mail_Antrag_A_ObjDenied', + [ + 'name' => $name, + 'vorname' => $vorname, + 'nachname' => $nachname, + 'grund' => $grund, + 'Orgform' => $orgform, + 'stg' => $stg + ], + $email, + $this->_ci->p->t('studierendenantrag', 'mail_subject_A_ObjectionDenied') + ); + } + } + } + + return success(); + } + + /** + * NOTE(chris): permissions & verification must be handled outside + * + * @param integer $prestudent_id + * @param string $studiensemester_kurzbz + * @param string $insertvon + * @param string $grund + * @param string $datum_wiedereinstieg + * + * @return stdClass + */ + public function createUnterbrechung($prestudent_id, $studiensemester_kurzbz, $insertvon, $grund, $datum_wiedereinstieg, $dms_id) + { + $datum_wiedereinstieg = new DateTime($datum_wiedereinstieg); + $datum_wiedereinstieg = $datum_wiedereinstieg->format("Y-m-d"); + $result = $this->_ci->StudierendenantragModel->insert([ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz'=> $studiensemester_kurzbz, + 'datum' => date('c'), + 'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG, + 'insertvon' => $insertvon, + 'grund' => $grund, + 'datum_wiedereinstieg' => $datum_wiedereinstieg, + 'dms_id' => $dms_id + ]); + + if (isError($result)) + return $result; + + $antrag_id = getData($result); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CREATED, + 'insertvon' => $insertvon + ]); + + if (isError($result)) + return $result; + + return success($antrag_id); + } + + + /** + * @param array $studierendenantrag_ids + * @param string $insertvon + * + * @return stdClass + */ + public function approveUnterbrechung($studierendenantrag_ids, $insertvon) + { + $this->_ci->load->model('person/Kontakt_model', 'KontaktModel'); + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + + $errors = []; + + foreach ($studierendenantrag_ids as $studierendenantrag_id) + { + $data = $this->getDataForUnterbrechung($studierendenantrag_id); + + if (isError($data)) { + $error_msg = getError($data); + if (is_array($error_msg) && isset($error_msg['message'])) + $error_msg = $error_msg['message']; + + $errors['failed_' . $studierendenantrag_id] = 'Could not approve Unterbrechung for studierendenantrag_id: ' . + $studierendenantrag_id . + '
Details:
' . + $error_msg; + } else { + + $data = getData($data); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, + 'insertvon' => $insertvon + ]); + if (isError($result)) + { + $errors['failed_' . $studierendenantrag_id] = $this->_ci->p->t('studierendenantrag', 'error_U_Approve', [ + 'studierendenantrag_id' => $studierendenantrag_id, + 'message' => getError($result)['message'] + ]); + } + else + { + $studierendenantrag_status_id = getData($result); + $resultAntrag = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); + if (isError($resultAntrag)) + return $resultAntrag; + $resultAntrag = getData($resultAntrag); + if (!$resultAntrag) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id])); + $resultAntrag = current($resultAntrag); + + // Prestudentstatus und Unterbrechungsfolgeaktionen setzen + $result = $this->_ci->prestudentlib->setUnterbrecher( + $resultAntrag->prestudent_id, + $resultAntrag->studiensemester_kurzbz, + $studierendenantrag_id + ); + + if (isError($result)) { + $this->_ci->StudierendenantragstatusModel->delete($studierendenantrag_status_id); + return $result; + } + + + //Mail + $subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_U_Approve'); + $mail = []; + + if (isset($data['errors']['person_id'])) + { + //send assistenz mit id + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail_and_name', ['message' => $data['errors']['person_id']]); + $mail['ass'] = $this->_ci->p->t('studierendenantrag', 'StudentIn', ['prestudent_id' => $data['antrag']->prestudent_id]); + } + elseif (isset($data['errors']['email'])) + { + if (isset($data['errors']['person'])) + { + //send assistenz mit id + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail_and_name', [ + 'message' => $data['errors']['email'] . '
' . $data['errors']['person'] + ]); + $mail['ass'] = $this->_ci->p->t('studierendenantrag', 'StudentIn', ['prestudent_id' => $data['antrag']->prestudent_id]); + } + else + { + //send assistenz mit name + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail', ['message' => $data['errors']['email']]); + $mail['ass'] = trim($data['person']->vorname . ' ' . $data['person']->nachname); + } + } + else + { + if (isset($data['errors']['person'])) + { + //send assistenz mit id & student mit "Student/in" + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_name', ['message' => $data['errors']['person']]); + $mail['ass'] = $this->_ci->p->t('studierendenantrag', 'StudentIn', ['prestudent_id' => $data['antrag']->prestudent_id]); + $mail['stu'] = $this->_ci->p->t('person', 'StudentIn'); + } + else + { + //send normal + $mail['ass'] = $mail['stu'] = trim($data['person']->vorname . ' ' . $data['person']->nachname); + } + } + + if (isset($mail['ass'])) { + // NOTE(chris): Sancho mail + $mailVorlage = 'Sancho_Mail_Antrag_U_Approve'; + + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id'=> $data['antrag']->prestudent_id]); + if (hasData($result)) { + $student = current(getData($result)); + $data['UID'] = $student->student_uid; + } + + $result = $this->_ci->PersonModel->getFullName($insertvon); + if (isError($result)) + return $result; + $approvedBy = $insertvon; + if (hasData($result)) + { + $approvedBy = getData($result); + } + + if (!sendSanchoMail( + $mailVorlage, + [ + 'name' => $mail['ass'], + 'stg' => $data['studiengang']->bezeichnung, + 'Orgform' => $data['prestudent_status']->orgform_kurzbz, + 'vorname' => $data['person']->vorname, + 'nachname' => $data['person']->nachname, + 'UID' => $data['UID'], + 'sem' => $resultAntrag->studiensemester_kurzbz, + 'linkPdf' => base_url('content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' . $studierendenantrag_id . '&output=pdf'), + 'insertvon' => $approvedBy + ], + $data['prestudent_status']->email, + $subject + )) { + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail_to', $data['prestudent_status']); + } + } + if (isset($mail['stu'])) { + // NOTE(chris): Sancho mail + $mailVorlage = 'Sancho_Mail_Antrag_U_Student'; + if ($data['studienbeitrag']) + $mailVorlage .= '_SB'; + if (!sendSanchoMail( + $mailVorlage, + [ + 'name' => $mail['stu'], + 'stg' => $data['studiengang']->bezeichnung, + 'Orgform' => $data['prestudent_status']->orgform_kurzbz, + 'vorname' => $data['person']->vorname, + 'nachname' => $data['person']->nachname + ], + $data['email'], + $subject + )) { + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail_to', $data); + } + } + } + } + } + + if (count($errors)) + return error($errors); + + return success(); + } + + /** + * @param array $studierendenantrag_ids + * @param string $insertvon + * @param string $grund + * + * @return stdClass + */ + public function rejectUnterbrechung($studierendenantrag_ids, $insertvon, $grund) + { + $this->_ci->load->model('person/Kontakt_model', 'KontaktModel'); + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + + $errors = []; + + foreach ($studierendenantrag_ids as $studierendenantrag_id) { + $data = $this->getDataForUnterbrechung($studierendenantrag_id); + + if (isError($data)) { + $error_msg = getError($data); + if (is_array($error_msg) && isset($error_msg['message'])) + $error_msg = $error_msg['message']; + + $errors['failed_' . $studierendenantrag_id] = $this->_ci->p->t('studierendenantrag', 'error_U_Reject', [ + 'studierendenantrag_id' => $studierendenantrag_id, + 'message' => $error_msg + ]); + } else { + $data = getData($data); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_REJECTED, + 'insertvon' => $insertvon, + 'grund' => $grund + ]); + if (isError($result)) { + $errors['failed_' . $studierendenantrag_id] = $this->_ci->p->t('studierendenantrag', 'error_U_Reject', [ + 'studierendenantrag_id' => $studierendenantrag_id, + 'message' => getError($result)['message'] + ]); + } else { + $name = ''; + + if (isset($data['errors']['person_id']) || isset($data['errors']['email'])) { + $error_msg = []; + if (isset($data['errors']['person_id'])) + $error_msg[] = $data['errors']['person_id']; + if (isset($data['errors']['email'])) + $error_msg[] = $data['errors']['email']; + $error_msg = $this->_ci->p->t('studierendenantrag', 'error_mail', ['message' => implode('
', $error_msg)]); + $errors[] = $error_msg; + } else { + if (isset($data['errors']['person'])) { + //send student mit "Student/in" + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_name', ['message' => $data['errors']['person']]); + $name = $this->_ci->p->t('person', 'studentIn'); + $vorname = ""; + $nachname = $name; + } else { + //send normal + $name = trim($data['person']->vorname . ' ' . $data['person']->nachname); + $vorname = $data['person']->vorname; + $nachname = $data['person']->nachname; + } + } + if ($name) + // NOTE(chris): Sancho mail + if (!sendSanchoMail( + 'Sancho_Mail_Antrag_U_Reject', + [ + 'name' => $name, + 'vorname' => $vorname, + 'nachname' => $nachname, + 'grund' => $grund, + 'stg' => $data['studiengang']->bezeichnung, + 'Orgform' => $data['prestudent_status']->orgform_kurzbz, + 'prestudent_id' => $data['prestudent_status']->prestudent_id, + 'abmeldungLink' => site_url('lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id), + 'abmeldungLinkCIS' => CIS_ROOT . 'index.ci.php/lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id + ], + $data['email'], + $this->_ci->p->t('studierendenantrag', 'mail_subject_U_Reject') + )) + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_mail_to', $data); + } + } + } + + if (count($errors)) + return error($errors); + + return success(); + } + + /** + * @param integer $studierendenantrag_id + * + * @return array + */ + private function getDataForUnterbrechung($studierendenantrag_id) + { + $result = []; + $errors = []; + + $res = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); + if (isError($res)) + return $res; + + $res = getData($res); + if (!$res) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id])); + + $result['antrag'] = $antrag = current($res); + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps','studiengang_kz'); + $res = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + if (hasData($res)) { + $result['studiengang'] = current(getData($res)); + } + else{ + $result['studiengang'] = new stdClass(); + $result['studiengang']->bezeichnung = ""; + } + + $res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id); + if (isError($res)) + return $res; + + $res = getData($res); + if (!$res) + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', $antrag)); + + $result['prestudent_status'] = current($res); + + + $res = $this->_ci->PrestudentModel->load($antrag->prestudent_id); + + if (isError($res)) { + $errors['person_id'] = getError($res); + } else { + $res = getData($res); + if (!$res) { + $errors['person_id'] = $this->_ci->p->t('studierendenantrag', 'error_no_prestudent', $antrag); + } else { + $person_id = current($res)->person_id; + + $res = $this->_ci->PersonModel->load($person_id); + if (isError($res)) { + $errors['person'] = getError($res); + } else { + $res = getData($res); + if (!$res) { + $errors['person'] = $this->_ci->p->t('studierendenantrag', 'error_no_person', ['person_id' => $person_id]); + } else { + $result['person'] = current($res); + } + } + + $res = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); + if (isError($res)) { + $errors['email'] = getError($res); + } else { + $res = getData($res); + + if (!$res) { + $errors['email'] = $this->_ci->p->t('studierendenantrag', 'error_no_email', ['person_id' => $person_id]); + } else { + $result['email'] = $this->_ci->StudentModel->getEmailFH(current($res)->student_uid); + } + } + } + } + + $result['studienbeitrag'] = false; + if (!isset($errors['person_id'])) { + $date_target = new DateTime( + $this->_ci->config->item('frist_rueckzahlung_studiengebuer_' . substr($result['antrag']->studiensemester_kurzbz, 0, 2)) . + substr($result['antrag']->studiensemester_kurzbz, 2) + ); + $date_created = new DateTime($result['antrag']->datum); + if ($date_created < $date_target) { + $this->_ci->load->model('crm/Konto_model', 'KontoModel'); + $result['studienbeitrag'] = $this->_ci->KontoModel->checkStudienbeitragFromPerson( + $person_id, + $result['antrag']->studiensemester_kurzbz + ); + } + } + + $result['errors'] = $errors; + + return success($result); + } + + /** + * @param integer $prestudent_id + * @param string $studiensemester_kurzbz + * @param string $insertvon + * @param boolean $repeat + * + * @return stdClass + */ + public function createWiederholung($prestudent_id, $studiensemester_kurzbz, $insertvon, $repeat) + { + $result = $this->_ci->StudierendenantragModel->loadIdAndStatusWhere([ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz'=> $studiensemester_kurzbz, + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG + ]); + + $antrag_id = null; + if (hasData($result)) { + $antrag = current(getData($result)); + if ($antrag->status == Studierendenantragstatus_model::STATUS_REOPENED || + $antrag->status == Studierendenantragstatus_model::STATUS_REQUESTSENT_1 || + $antrag->status == Studierendenantragstatus_model::STATUS_REQUESTSENT_2) + { + $antrag_id = $antrag->studierendenantrag_id; + } + else + { + return error($this->_ci->p->t('global', 'antragBereitsGestellt')); + } + } + + if ($antrag_id === null) { + $result = $this->_ci->StudierendenantragModel->insert([ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz'=> $studiensemester_kurzbz, + 'datum' => date('c'), + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, + 'insertvon' => $insertvon + ]); + + if (isError($result)) + return $result; + + $antrag_id = getData($result); + } + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => $repeat ? Studierendenantragstatus_model::STATUS_CREATED : Studierendenantragstatus_model::STATUS_PASS, + 'insertvon' => $insertvon + ]); + + if ($repeat) { + $res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($prestudent_id); + if (isError($res)) + return $res; + $res = getData($res); + if (!$res) + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $prestudent_id])); + + $prestudent_status = current($res); + $email = $prestudent_status->email; + // NOTE(chris): Sancho mail + $lvzuweisungLink = site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id); + if( defined('VILESCI_ROOT') ) + { + $lvzuweisungLink = VILESCI_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id; + } + sendSanchoMail( + 'Sancho_Mail_Antrag_W_New', + [ + 'antrag_id' => $antrag_id, + 'stg' => $prestudent_status->stg_bezeichnung, + 'Orgform' => $prestudent_status->orgform, + 'lvzuweisungLink' => $lvzuweisungLink + ], + $email, + $this->_ci->p->t('studierendenantrag', 'mail_subject_W_New') + ); + } + + if (isError($result)) + return $result; + + return success($antrag_id); + } + + /** + * @param integer $studierendenantrag_id + * @param string $insertvon + * + * @return stdClass + */ + public function reopenWiederholung($studierendenantrag_id, $insertvon) + { + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_REOPENED, + 'insertvon' => $insertvon + ]); + return $result; + } + + /** + * @param integer $studierendenantrag_id + * @param string $objectedvon + * + * @return stdClass + */ + public function objectAbmeldung($studierendenantrag_id, $objectedvon) + { + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_OBJECTED, + 'insertvon' => $objectedvon + ]); + return $result; + } + + public function getWiederholungsAntraege($status) + { + $studiengaenge = $this->_ci->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + $result = $this->_ci->StudierendenantragModel->loadForStudiengaenge( + $studiengaenge, + Studierendenantrag_model::TYP_WIEDERHOLUNG, + $status + ); + if (!getData($result)) + return $result; + $result = getData($result); + $grouped = []; + + foreach ($result as $item) { + if (!isset($grouped[$item->studiengang_kz])) { + $grouped[$item->studiengang_kz] = [ + 'bezeichnung' => $item->bezeichnung, + 'bezeichnung_mehrsprachig' => $item->bezeichnung_mehrsprachig, + 'antraege' => [] + ]; + } + $grouped[$item->studiengang_kz]['antraege'][] = $item; + } + + return success($grouped); + } + + public function getLvsForAntrag($antrag_id) + { + $this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); + + $result = $this->_ci->StudierendenantragModel->load($antrag_id); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id])); + $antrag = current($result); + + + $result = $this->_ci->StudierendenantragModel->getStgAndSem($antrag_id); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_and_sem', ['id' => $antrag_id])); + $result = current($result); + $studiengang_kz = $result->studiengang_kz; + $orgform_kurzbz = $result->orgform_kurzbz; + $ausbildungssemester = $result->ausbildungssemester; + $sprache = $result->sprache; + + // NOTE(chris): check permission + $allowedStgs = $this->_ci->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []; + if (!in_array($studiengang_kz, $allowedStgs)) { + $allowedStgs = $this->_ci->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; + if (!in_array($studiengang_kz, $allowedStgs)) { + if(!$this->isOwnAntrag($antrag_id)) + return error('Forbidden'); + } + } + + + $result = $this->_ci->StudiensemesterModel->getNextFrom($antrag->studiensemester_kurzbz); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_sem_after', ['semester' => $antrag->studiensemester_kurzbz])); + $semA = current($result)->studiensemester_kurzbz; + + $result = $this->_ci->StudiensemesterModel->getNextFrom($semA); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_sem_after', ['semester' => $semA])); + $semB = current($result)->studiensemester_kurzbz; + + $result = $this->_ci->StudierendenantraglehrveranstaltungModel->loadWhere(['studierendenantrag_id' => $antrag_id]); + if (isError($result)) + return $result; + $result = getData($result) ?: []; + + $lvszugewiesen = array(); + foreach ($result as $lv) + { + $lvszugewiesen[$lv->lehrveranstaltung_id] = $lv; + } + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $semA, + $ausbildungssemester + 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + $lvsA = $result->retval; // NOTE(chris): don't use getData() because we want to differenciate [] and null + $repeat_last = false; + if ($lvsA) { + foreach($lvsA as $lv) + { + if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && + ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == $this->_ci->config->item('wiederholung_note_nicht_zugelassen'))) + { + $lv->antrag_zugelassen = true; + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + } + } + } elseif ($lvsA === null) { + // NOTE(chris): We are repeating the last semester + $repeat_last = true; + + $result = $this->_ci->PrestudentstatusModel->getStatusByFilter($antrag->prestudent_id, 'Student', $ausbildungssemester - 1); + if (isError($result)) + return $result; + + $stdsems = getData($result) ?: []; + $stdsem = null; + + $result = $this->_ci->StudiensemesterModel->load($antrag->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stdsem', ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz])); + $asem = current(getData($result)); + + foreach ($stdsems as $sem) { + $result = $this->_ci->StudiensemesterModel->load($sem->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (hasData($result)) { + if (current(getData($result))->start < $asem->start) { + $stdsem = $sem->studiensemester_kurzbz; + break; + } + } + } + + // NOTE(chris): if we don't find a status in the previous semester there is something wrong + if (!$stdsem) + return error($this->_ci->p->t('studierendenantrag', 'error_no_status_in_prev_sem')); + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $semA, + $ausbildungssemester - 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + + $lvsA = getData($result) ?: []; + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $stdsem, + $ausbildungssemester - 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + + $lvsAtest = getData($result) ?: []; + + if (count(array_intersect(array_map(function ($a) { + return $a->lehrveranstaltung_id; + }, $lvsA), array_map(function ($a) { + return $a->lehrveranstaltung_id; + }, $lvsAtest)))) { + foreach ($lvsA as $lv) { + if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == 0)) { + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + $lv->antrag_zugelassen = true; + } + + } + } else { + $lvsA = null; + } + } + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $semB, + $ausbildungssemester, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + $lvsB = getData($result) ?: []; + foreach($lvsB as $lv) + { + if(isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == 0)) + { + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + $lv->antrag_zugelassen = true; + } + // TODO(manu): eventuelle Änderungen taggen + } + + $result = [ + '1' . $semA => $lvsA, + '2' . $semB => $lvsB ?: [] + ]; + if ($repeat_last) + $result['repeat_last'] = true; + + return success($result); + } + + public function getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $studiensemester_kurzbz, + $ausbildungssemester, + $prestudent_id, + $sprache + ) { + $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); + + $result = $this->_ci->StudienplanModel->getStudienplaeneBySemester( + $studiengang_kz, + $studiensemester_kurzbz, + $ausbildungssemester, + $orgform_kurzbz + ); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) { + $result = $this->_ci->StudiengangModel->load($studiengang_kz); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stg', ['studiengang_kz' => $studiengang_kz])); + $stg = current(getData($result)); + + if ($ausbildungssemester > $stg->max_semester) + return success(); + return error($this->_ci->p->t('studierendenantrag', 'error_no_studienplan', [ + 'studiengang_kz' => $studiengang_kz, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'semester' => $ausbildungssemester + ])); + } + if (count($result) > 1) { + $langmap = array_unique(array_map(function ($a) { + return $a->sprache; + }, $result)); + if ($sprache + && count($langmap) == count($result) + && in_array($sprache, $langmap) + ) { + $result = array_filter($result, function ($a) use ($sprache) { + return $a->sprache == $sprache; + }); + } else { + return error($this->_ci->p->t('studierendenantrag', 'error_multiple_studienplan', [ + 'studiengang_kz' => $studiengang_kz, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'semester' => $ausbildungssemester + ])); + } + } + $studienplan = current($result); + + return $this->_ci->StudienplanModel->getStudienplanLehrveranstaltungForPrestudent( + $studienplan->studienplan_id, + $ausbildungssemester, + $prestudent_id + ); + } + + /** + * Checks if a prestudent can submit an Antrag for Abmeldung + * + * @param integer $prestudent_id + * + * @return \stdClass on success retval 0 means not a student; + * retval 1 means Berechtigt; + * retval -1 means has already an Antrag pending; + * retval -2 means other Antrag pending; + * retval -3 means in blacklist stg + */ + public function getPrestudentAbmeldeBerechtigt($prestudent_id) + { + $result = $this->_ci->PrestudentModel->load($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + $result = current(getData($result)); + $stg_kz = $result->studiengang_kz; + if (in_array($stg_kz, $this->_ci->config->item('stgkz_blacklist_abmeldung'))) + return success(-3); + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + $result = current(getData($result)); + $datumStatus = $result->datum; + + if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist_abmeldung'))) { + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ + 'prestudent_id' => $prestudent_id, + 'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED + ], [ + Studierendenantrag_model::TYP_ABMELDUNG, + Studierendenantrag_model::TYP_ABMELDUNG_STGL + ]); + if (isError($result)) + return $result; + if (hasData($result)) + return success(-1); + + return success(0); + } + + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere(['prestudent_id' => $prestudent_id]); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(1); + $result= getData($result); + foreach ($result as $antrag) + { + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG || $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) + { + if ($antrag->status == Studierendenantragstatus_model::STATUS_CREATED) + return success(-1); + elseif ($antrag->status == Studierendenantragstatus_model::STATUS_APPROVED && $antrag->datum > $datumStatus) + return success(-1); + } + if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG) + { + if($antrag->status == Studierendenantragstatus_model::STATUS_PASS) + return success(-2); + } + } + + return success(1); + } + + /** + * Checks if a prestudent can submit an Antrag for Unterbrechung + * + * @param integer $prestudent_id + * @param string $studiensemester_kurzbz (optional) + * + * @return \stdClass on success retval 0 means not a student; + * retval 1 means Berechtigt; + * retval -1 means has already an Antrag pending; + * retval -2 means other Antrag pending; + * retval -3 means in blacklist stg + */ + public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null) + { + $result = $this->_ci->PrestudentModel->load($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + $result = current(getData($result)); + $stg_kz = $result->studiengang_kz; + if (in_array($stg_kz, $this->_ci->config->item('stgkz_blacklist_unterbrechung'))) + return success(-3); + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + $result = current(getData($result)); + $datumStatus = $result->datum; + if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))) { + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ + 'prestudent_id' => $prestudent_id, + 'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG, + 'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED + ]); + if (isError($result)) + return $result; + if (hasData($result)) + return success(-1); + + return success(0); + } + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere(['prestudent_id' => $prestudent_id]); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(1); + $result= getData($result); + foreach ($result as $antrag) + { + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG || $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) + { + if($antrag->status == Studierendenantragstatus_model::STATUS_CREATED) + return success(-2); + elseif($antrag->status == Studierendenantragstatus_model::STATUS_APPROVED && $antrag->datum > $datumStatus) + return success(-2); + } + if ($studiensemester_kurzbz && $antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG) + { + // NOTE(chris): check if this is an old or canceled one + if ($antrag->studiensemester_kurzbz == $studiensemester_kurzbz && $antrag->status != Studierendenantragstatus_model::STATUS_CANCELLED) + return success(-1); + } + if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG) + { + if($antrag->status == Studierendenantragstatus_model::STATUS_PASS) + return success(-2); + } + } + + return success(1); + } + + /** + * Checks if a prestudent can submit an Antrag for Wiederholung + * + * @param integer $prestudent_id + * + * @return \stdClass on success retval 0 means not a student; + * retval 1 means Berechtigt; + * retval -1 means has already an Antrag pending; + * retval -2 means other Antrag pending; + * retval -3 means in blacklist stg + */ + public function getPrestudentWiederholungsBerechtigt($prestudent_id) + { + $result = $this->_ci->PrestudentModel->load($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + $result = current(getData($result)); + $stg_kz = $result->studiengang_kz; + if (in_array($stg_kz, $this->_ci->config->item('stgkz_blacklist_wiederholung'))) + return success(-3); + + $result = $this->getFailedExamForPrestudent($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(0); + + $result = current(getData($result)); + $datumStatus = $result->datum; + if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))) { + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ + 'prestudent_id' => $prestudent_id, + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, + 'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED + ]); + if (isError($result)) + return $result; + if (hasData($result)) + return success(-1); + + return success(0); + } + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere(['prestudent_id' => $prestudent_id]); + if (isError($result)) + return $result; + if (!hasData($result)) + return success(1); + $result= getData($result); + foreach ($result as $antrag) + { + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG || $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) + { + if($antrag->status == Studierendenantragstatus_model::STATUS_CREATED) + return success(-2); + elseif($antrag->status == Studierendenantragstatus_model::STATUS_APPROVED && $antrag->datum > $datumStatus) + return success(-2); + } + if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG) + { + return success(-1); + } + } + + return success(1); + } + + /** + * Gets details for a new Antrag + * + * @param integer $prestudent_id + * + * @return \stdClass + */ + public function getDetailsForNewAntrag($prestudent_id) + { + $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $prestudent_id])); + $result = current(getData($result)); + return success($result); + } + + public function getDetailsForLastAntrag($prestudent_id, $typ = null) + { + $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $prestudent_id])); + $resultDetails = current(getData($result)); + + $where = [ + 'prestudent_id' => $prestudent_id + ]; + $types = null; + if ($typ) { + if (is_array($typ)) + $types = $typ; + else + $where['typ'] = $typ; + } + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where, $types); + if (isError($result)) + return $result; + + $antraege = getData($result) ?: []; + $resultAntrag = null; + foreach ($antraege as $antrag) { + if ($antrag->status != Studierendenantragstatus_model::STATUS_CANCELLED) { + $resultAntrag = $antrag; + break; + } + } + if (!$resultAntrag) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found_prestudent', [ + 'typ' => $typ ?: '', + 'prestudent_id' => $prestudent_id + ])); + + $resultDetails->status = $resultAntrag->status; + $resultDetails->statustyp = $resultAntrag->statustyp; + $resultDetails->grund = $resultAntrag->grund; + $resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id; + $resultDetails->typ = $resultAntrag->typ; + $resultDetails->datum = $resultAntrag->datum; + $resultDetails->studiensemester_kurzbz = $resultAntrag->studiensemester_kurzbz; + + return success($resultDetails); + } + + public function getDetailsForAntrag($studierendenantrag_id) + { + $where = [ + 'studierendenantrag_id' => $studierendenantrag_id + ]; + + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where); + if (isError($result)) + return $result; + + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', "error_no_antrag_found", ['id' => $studierendenantrag_id])); + $resultAntrag = current(getData($result)); + + $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id, $resultAntrag->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (!hasData($result)) { + $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', $resultAntrag)); + } + $resultDetails = current(getData($result)); + + $resultDetails->status = $resultAntrag->status; + $resultDetails->statustyp = $resultAntrag->statustyp; + $resultDetails->grund = $resultAntrag->grund; + $resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id; + $resultDetails->typ = $resultAntrag->typ; + $resultDetails->dms_id = $resultAntrag->dms_id; + $resultDetails->datum_wiedereinstieg = $resultAntrag->datum_wiedereinstieg; + + return success($resultDetails); + } + + public function getSemesterForUnterbrechung($studiensemester_kurzbz) + { + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + $semester = []; + + $result = $this->_ci->StudiensemesterModel->getNextFrom($studiensemester_kurzbz); + if (!hasData($result)) + return $semester; + $nextSem = current(getData($result)); + + $semester[0] = [ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'wiedereinstieg' => [$nextSem] + ]; + + $result = $this->_ci->StudiensemesterModel->getNextFrom($nextSem->studiensemester_kurzbz); + if (!hasData($result)) + return $semester; + + $currSemester = current(getData($result)); + $followingSemester = [$currSemester]; + + $max = $this->_ci->config->item('unterbrecher_semester_max_length'); + if(!$max || $max < 1) + $max = 2; + + for ($i = 1; $i < $max; $i++) { + $result = $this->_ci->StudiensemesterModel->getNextFrom($currSemester->studiensemester_kurzbz); + if (!hasData($result)) + break; + $currSemester = current(getData($result)); + $followingSemester[] = $currSemester; + } + + $semester[1] = [ + 'studiensemester_kurzbz' => $nextSem->studiensemester_kurzbz, + 'wiedereinstieg' => $followingSemester + ]; + + //remove last Semester of the array + array_pop($followingSemester); + + foreach ($followingSemester as $sem) + $semester[0]['wiedereinstieg'][] = $sem; + + return $semester; + } + + public function getAktivePrestudentenInStgs($studiengaenge, $query) + { + $blacklist = $this->_ci->config->item('stgkz_blacklist_abmeldung'); + $studiengaenge = array_diff($studiengaenge, $blacklist); + return $this->_ci->StudiengangModel->getAktivePrestudenten( + $studiengaenge, + [ Studierendenantrag_model::TYP_ABMELDUNG ], + $query + ); + } + + public function getFailedExamForPrestudent($prestudent_id, $max_date = null, $studiensemester_kurzbz = null) + { + return $this->_ci->PruefungModel->loadWhereCommitteeExamFailedForPrestudent($prestudent_id, $max_date, $studiensemester_kurzbz); + } + + public function saveLvs($lvArray) + { + $result = $this->_ci->StudierendenantraglehrveranstaltungModel->deleteWhere([ + 'studierendenantrag_id' => $lvArray[0]['studierendenantrag_id'] + ]); + if (isError($result)) + return $result; + + $result = $this->_ci->StudierendenantraglehrveranstaltungModel->insertBatch($lvArray); + if (isError($result)) + return $result; + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $lvArray[0]['studierendenantrag_id'], + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_LVSASSIGNED, + 'insertvon' => $lvArray[0]['insertvon'] + ]); + if (isError($result)) + return $result; + + $antrag_status_id = getData($result); + $result = $this->_ci->StudierendenantragstatusModel->loadWithTyp($antrag_status_id); + + return $result; + } + + public function approveWiederholung($antrag_id, $insertvon) + { + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, + 'insertvon' => $insertvon + ]); + + if (isError($result)) { + return $result; + } + + $result = $this->_ci->StudierendenantragModel->getStgEmail($antrag_id); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_email', ['id' => $antrag_id])); + + $email = current($result)->email; + + $result = $this->_ci->StudierendenantragModel->getStgAndSem($antrag_id); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_antrag', ['id' => $antrag_id])); + + $stg = current($result); + $studiengang_kz = $stg->studiengang_kz; + $semester = $stg->ausbildungssemester; + + $result = $this->_ci->StudierendenantragModel->load($antrag_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id])); + $result = current(getData($result)); + $prestudent_id = $result->prestudent_id; + + $result = $this->_ci->PersonModel->loadPrestudent($prestudent_id); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_person_prestudent', ['prestudent_id' => $prestudent_id])); + $person = current(getData($result)); + $student = trim($person->vorname . ' ' . $person->nachname); + + $result = $this->_ci->PersonModel->getFullName($insertvon); + if (isError($result)) + return $result; + $mitarbeiter = $insertvon; + if (hasData($result)) { + $mitarbeiter = getData($result); + } + + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id'=> $prestudent_id]); + if (hasData($result)) { + $studentObj = current(getData($result)); + $student_uid = $studentObj->student_uid; + } + else + $student_uid = ''; + + // NOTE(chris): Sancho mail + if (!sendSanchoMail( + 'Sancho_Mail_Antrag_W_Approve', + [ + 'antrag_id' => $antrag_id, + 'stg' => $stg->bezeichnung, + 'sem' => $semester, + 'student' => $student, + 'mitarbeiter' => $mitarbeiter, + 'Orgform' => $stg->orgform_kurzbz, + 'UID' => $student_uid + ], + $email, + $this->_ci->p->t('studierendenantrag', 'mail_subject_W_Approve') + )) + return error($this->_ci->p->t('studierendenantrag', 'error_mail_to', ['email' => $email])); + + if ($student_uid) { + $email = $this->_ci->StudentModel->getEmailFH($student_uid); + $vorlage = 'Sancho_Mail_Antrag_W_Student'; + + $sem_not_allowed = $sem_to_repeat = ''; + $list_not_allowed = $list_to_repeat = $this->_ci->p->t('studierendenantrag', 'mail_part_error_no_lvs'); + + $result = $this->getLvsForAntrag($antrag_id); + if (hasData($result)) { + $lvs = getData($result); + $repeat_last = false; + if (isset($lvs['repeat_last'])) { + $repeat_last = true; + unset($lvs['repeat_last']); + $vorlage .= '_Lst'; + } + foreach ($lvs as $sem => $lv_list) { + $lvs_filtered = array_filter($lv_list, function ($el) { + return property_exists($el, 'antrag_zugelassen') && $el->antrag_zugelassen; + }); + if (substr($sem, 0, 1) == '1') { + $sem_not_allowed = substr($sem, 1); + $list_not_allowed = array_map(function ($el) { + return $el->bezeichnung . '(' . $el->lehrform_kurzbz . ')'; + }, $lvs_filtered); + $list_not_allowed = '
  • ' . implode('
  • ', $list_not_allowed) . '
'; + } else { + $sem_to_repeat = substr($sem, 1); + $list_to_repeat = array_map(function ($el) { + return $el->bezeichnung . '(' . $el->lehrform_kurzbz . ')'; + }, $lvs_filtered); + $list_to_repeat = '
  • ' . implode('
  • ', $list_to_repeat) . '
'; + } + } + } + + // NOTE(chris): Sancho mail + sendSanchoMail( + $vorlage, + [ + 'antrag_id' => $antrag_id, + 'stg' => $stg->bezeichnung, + 'sem' => $semester, + 'mitarbeiter' => $mitarbeiter, + 'student' => $student, + 'sem_not_allowed' => $sem_not_allowed, + 'list_not_allowed' => $list_not_allowed, + 'sem_to_repeat' => $sem_to_repeat, + 'list_to_repeat' => $list_to_repeat, + 'Orgform' => $stg->orgform_kurzbz + ], + $email, + $this->_ci->p->t('studierendenantrag', 'mail_subject_W_Student') + ); + } + + + return success(); + } + + public function getAntragHistory($antrag_id) + { + $result = $this->_ci->StudierendenantragstatusModel->loadWithTypWhere([ + 'studierendenantrag_id' => $antrag_id + ]); + return $result; + } + + + /** + * @param integer $studierendenantrag_id + * + * @return boolean + */ + protected function isOwnAntrag($studierendenantrag_id) + { + if ($studierendenantrag_id == null) + return false; + $result = $this->_ci->StudierendenantragModel->loadForPerson(getAuthPersonId()); + if (!hasData($result)) + return false; + $antraege = array_map(function ($antrag) { + return $antrag->studierendenantrag_id; + }, getData($result)); + + return in_array($studierendenantrag_id, $antraege); + } + + /** + * @param integer $studierendenantrag_id + * @param string $permission either 'student/antragfreigabe' or 'student/studierendenantrag' + * + * @return boolean + */ + protected function hasAccessToAntrag($studierendenantrag_id, $permission) + { + $studiengaenge = $this->_ci->permissionlib->getSTG_isEntitledFor($permission); + if (!$studiengaenge) + return false; + $result = $this->_ci->StudierendenantragModel->isInStudiengang($studierendenantrag_id, $studiengaenge); + return (boolean)getData($result); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToShowAntrag($antrag_id) + { + return + ( + $this->isOwnAntrag($antrag_id) || + $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe') || + $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag') + ); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToSeeHistoryForAntrag($antrag_id) + { + return + ( + $this->isOwnAntrag($antrag_id) || + $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe') || + $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag') + ); + } + + /** + * @param integer $prestudent_id + * @param boolean $checkAssistencePermission + * + * @return boolean + */ + public function isEntitledToCreateAntragFor($prestudent_id, $checkAssistencePermission = false) + { + $result = $this->_ci->PrestudentModel->load($prestudent_id); + if (!hasData($result)) + return false; + + $result = getData($result)[0]; + $person_id = $result->person_id; + + if (getAuthPersonId() == $person_id) + return true; + + if ($checkAssistencePermission) + { + $studiengaenge = $this->_ci->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + if (in_array($result->studiengang_kz, $studiengaenge ?: [])) + return true; + } + + return false; + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToCancelAntrag($antrag_id) + { + $result = $this->_ci->StudierendenantragModel->load($antrag_id); + if (!hasData($result)) + return false; + $antrag = current(getData($result)); + + if ($antrag->typ != Studierendenantrag_model::TYP_ABMELDUNG_STGL) + return $this->isOwnAntrag($antrag_id); + + return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag'); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToReopenAntrag($antrag_id) + { + return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag'); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToObjectAntrag($antrag_id) + { + return ($this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe') || $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag')); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToApproveAntrag($antrag_id) + { + return $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe'); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToRejectAntrag($antrag_id) + { + return $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe'); + } + + /** + * @param integer $antrag_id + * @param string|array $status + * + * @return boolean + */ + public function hasStatus($antrag_id, $status) + { + $result = $this->_ci->StudierendenantragModel->getWithLastStatusWhere(['s.studierendenantrag_id' => $antrag_id]); + if (!hasData($result)) + return false; + $lastStatus = getData($result)[0]; + + if (!is_array($status)) + $status = [$status]; + + return in_array($lastStatus->studierendenantrag_statustyp_kurzbz, $status); + } + + /** + * @param integer $antrag_id + * @param string|array $type + * + * @return boolean + */ + public function hasType($antrag_id, $type) + { + $result = $this->_ci->StudierendenantragModel->load($antrag_id); + if (!hasData($result)) + return false; + $antrag = getData($result)[0]; + + if (!is_array($type)) + $type = [$type]; + + return in_array($antrag->typ, $type); + } + + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz) + { + $result = $this->_ci->StudierendenantraglehrveranstaltungModel->getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz); + return $result; + } +} diff --git a/application/libraries/DmsLib.php b/application/libraries/DmsLib.php index fccfe503b..774ebdc79 100644 --- a/application/libraries/DmsLib.php +++ b/application/libraries/DmsLib.php @@ -595,6 +595,8 @@ class DmsLib if (isError($insDmsResult)) return $insDmsResult; $upload_data['dms_id'] = getData($insDmsResult); + if(isset($upload_data['file_type']) && !isset($dms['mimetype'])) + $dms['mimetype'] = $upload_data['file_type']; // Insert DMS version $insVersionResult = $this->_ci->DmsVersionModel->insert( diff --git a/application/libraries/FilterCmptLib.php b/application/libraries/FilterCmptLib.php index 9d6dfa681..8b13ae3e5 100644 --- a/application/libraries/FilterCmptLib.php +++ b/application/libraries/FilterCmptLib.php @@ -1,4 +1,5 @@ _setSessionElement(FilterCmptLib::SESSION_SIDE_MENU, - $this->_generateFilterMenu($this->_app, $this->_datasetName)); + $this->_setSessionElement( + FilterCmptLib::SESSION_SIDE_MENU, + $this->_generateFilterMenu($this->_app, $this->_datasetName) + ); } return $saveCustomFilter; @@ -717,6 +723,7 @@ class FilterCmptLib $this->_filterKurzbz = null; $this->_query = null; $this->_requiredPermissions = null; + $this->_encryptedColumns = null; $this->_reloadDataset = true; // by default the dataset is NOT cached in session $this->_sessionTimeout = FilterCmptLib::SESSION_DEFAULT_TIMEOUT; @@ -727,6 +734,12 @@ class FilterCmptLib $this->_requiredPermissions = $filterCmptArray[FilterCmptLib::REQUIRED_PERMISSIONS]; } + // Retrieved the encrypted columns parameter if present + if (isset($filterCmptArray[FilterCmptLib::ENCRYPTED_COLUMNS])) + { + $this->_encryptedColumns = $filterCmptArray[FilterCmptLib::ENCRYPTED_COLUMNS]; + } + // Parameters needed to retrieve univocally a filter from DB if (isset($filterCmptArray[FilterCmptLib::APP])) { @@ -1129,7 +1142,7 @@ class FilterCmptLib $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // Execute the given SQL statement suppressing error messages - $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $this->_encryptedColumns); } return $dataset; diff --git a/application/libraries/FilterWidgetLib.php b/application/libraries/FilterWidgetLib.php index 19cdec848..9968767d9 100644 --- a/application/libraries/FilterWidgetLib.php +++ b/application/libraries/FilterWidgetLib.php @@ -1,7 +1,26 @@ . + */ + if (! defined('BASEPATH')) exit('No direct script access allowed'); +use \stdClass as stdClass; + /** * FilterWidget logic */ @@ -16,6 +35,7 @@ class FilterWidgetLib const SESSION_SELECTED_FIELDS = 'selectedFields'; const SESSION_COLUMNS_ALIASES = 'columnsAliases'; const SESSION_ADDITIONAL_COLUMNS = 'additionalColumns'; + const SESSION_ENCRYPTED_COLUMNS = 'encryptedColumns'; const SESSION_CHECKBOXES = 'checkboxes'; const SESSION_FILTERS = 'filters'; const SESSION_METADATA = 'datasetMetadata'; @@ -56,6 +76,7 @@ class FilterWidgetLib const ADDITIONAL_COLUMNS = 'additionalColumns'; const CHECKBOXES = 'checkboxes'; const COLUMNS_ALIASES = 'columnsAliases'; + const ENCRYPTED_COLUMNS = 'encryptedColumns'; // ...to format/mark records of a dataset const FORMAT_ROW = 'formatRow'; @@ -120,7 +141,7 @@ class FilterWidgetLib /** * Gets the CI instance and loads message helper */ - public function __construct($params = null) + public function __construct() { $this->_ci =& get_instance(); // get code igniter instance } @@ -367,7 +388,7 @@ class FilterWidgetLib /** * Retrieves the dataset from the DB */ - public function getDataset($datasetQuery) + public function getDataset($datasetQuery, $encryptedColumns) { $dataset = null; @@ -376,7 +397,7 @@ class FilterWidgetLib $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // Execute the given SQL statement suppressing error messages - $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $encryptedColumns); } return $dataset; @@ -390,7 +411,7 @@ class FilterWidgetLib public function getFilterName($filterJson) { $filterName = $filterJson->name; // always present, used as default - $trimedname = (isset($filterJson->namePhrase)?trim($filterJson->namePhrase):''); + // Filter name from phrases system if (isset($filterJson->namePhrase) && !isEmptyString($filterJson->namePhrase)) { @@ -451,7 +472,8 @@ class FilterWidgetLib if (in_array($selectedField, $fields)) { // If the selected field is present in the list of the selected fields by the current filter - if (($pos = array_search($selectedField, $selectedFields)) !== false) + $pos = array_search($selectedField, $selectedFields); + if ($pos !== false) { // Then remove it and shift the rest of elements by one if needed array_splice($selectedFields, $pos, 1); @@ -750,7 +772,6 @@ class FilterWidgetLib $this->_ci->load->library('NavigationLib', array(self::NAVIGATION_PAGE => $navigationPage)); $filterMenu = null; - $currentMenu = $this->_ci->navigationlib->getSessionMenu(); // The navigation menu currently stored in session $session = $this->getSession(); // The filter currently stored in session (the one that is currently used) if ($session != null) diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php new file mode 100644 index 000000000..989e14585 --- /dev/null +++ b/application/libraries/PrestudentLib.php @@ -0,0 +1,412 @@ +_ci =& get_instance(); + + // // Configs + // $this->_ci->load->config('studierendenantrag'); + + // // Models + $this->_ci->load->model('crm/Prestudent_model', 'PrestudentModel'); + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + $this->_ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + $this->_ci->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + $this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel'); + $this->_ci->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); + $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel'); + } + + public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null, $statusgrund_kurzbz = null, $datum = null, $bestaetigtam = null, $bestaetigtvon = null) + { + if (!$insertvon) + $insertvon = getAuthUID(); + if (!$bestaetigtvon) + $bestaetigtvon = $insertvon; + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id, $studiensemester_kurzbz); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', [ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz' => $studiensemester_kurzbz + ])); + + $prestudent_status = current($result); + + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $prestudent_id]); + + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_student_for_prestudent', ['prestudent_id' => $prestudent_id])); + + $student = current($result); + + if(!$datum) + $datum = date('c'); + + if(!$bestaetigtam) + $bestaetigtam = date('c'); + + //Status und Statusgrund updaten + $result = $this->_ci->PrestudentstatusModel->withGrund($statusgrund_kurzbz)->insert([ + 'prestudent_id' => $prestudent_id, + 'status_kurzbz' => Prestudentstatus_model::STATUS_ABBRECHER, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'ausbildungssemester' => $prestudent_status->ausbildungssemester, + 'datum' => $datum, + 'insertvon' => $insertvon, + 'insertamum' => date('c'), + 'orgform_kurzbz'=> $prestudent_status->orgform_kurzbz, + 'studienplan_id'=> $prestudent_status->studienplan_id, + 'bestaetigtvon' => $bestaetigtvon, + 'bestaetigtam' => $bestaetigtam + ]); + + if (isError($result)) + return $result; + + + //Verband anlegen + $result = $this->_ci->LehrverbandModel->load([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'A', + 'gruppe' => '' + ]); + + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + { + $result = $this->_ci->LehrverbandModel->load([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => '', + 'gruppe' => '' + ]); + if (isError($result)) + return $result; + $result = getData($result); + + if(!$result) + { + $this->_ci->LehrverbandModel->insert([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => '', + 'gruppe' => '', + 'bezeichnung' => 'Ab-Unterbrecher', + 'aktiv' => true, + ]); + } + + $this->_ci->LehrverbandModel->insert([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'A', + 'gruppe' => '', + 'bezeichnung' => 'Abbrecher', + 'aktiv' => true + ]); + } + + //noch nicht eingetragene Zeugnisnoten auf 9 setzen + $result = $this->_ci->ZeugnisnoteModel->getZeugnisnoten($student->student_uid, $studiensemester_kurzbz); + if (isError($result)) + return $result; + $result = getData($result) ?: []; + + foreach ($result as $lv) + { + if (!$lv->note) + { + $result = $this->_ci->ZeugnisnoteModel->insert([ + 'note' => 9, + 'studiensemester_kurzbz' => $lv->studiensemester_kurzbz, + 'student_uid' => $lv->uid, + 'lehrveranstaltung_id' => $lv->lehrveranstaltung_id + ]); + if (isError($result)) { + $result = $this->_ci->ZeugnisnoteModel->update([ + 'studiensemester_kurzbz' => $lv->studiensemester_kurzbz, + 'student_uid' => $lv->uid, + 'lehrveranstaltung_id' => $lv->lehrveranstaltung_id + ], [ + 'note' => 9 + ]); + + if (isError($result)) + return $result; + } + } + } + + + //Update Aktionen + + //StudentModel updaten + $this->_ci->StudentModel->update([ + 'student_uid' => $student->student_uid + ], [ + 'verband' => 'A', + 'gruppe' => '', + 'semester' => 0, + 'updatevon' => $insertvon, + 'updateamum' => date('c') + ]); + + //Studentlehrverband setzen + $this->_ci->StudentlehrverbandModel->update([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student->student_uid + ], [ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'A', + 'gruppe' => '', + 'updateamum' => date('c'), + 'updatevon' => $insertvon + ]); + + //Benutzer inaktiv setzen + $this->_ci->BenutzerModel->update([ + 'uid' => $student->student_uid + ], [ + 'aktiv' => false, + 'updateaktivvon' => $insertvon, + 'updateaktivam' => date('c'), + 'updatevon' => $insertvon, + 'updateamum' => date('c') + ]); + + return success(); + } + + public function setUnterbrecher($prestudent_id, $studiensemester_kurzbz, $studierendenantrag_id, $insertvon = null) + { + $ausbildungssemester_plus = 0; + if (!$insertvon) + $insertvon = getAuthUID(); + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id, $studiensemester_kurzbz); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) { + //NOTE(manu): only valid if nextSemester focus max + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + $result = getData($result); + + //check if ausbildungssemester is last + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent p', 'studiengang_kz'); + $res = $this->_ci->StudiengangModel->loadWhere(['p.prestudent_id' => $prestudent_id]); + if(isError($res)) + return $res; + if(!hasData($res)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_for_prestudent', [ + 'prestudent_id' => $prestudent_id + ])); + + $studiengang = current(getData($res)); + $prestudent_status = current($result); + if($prestudent_status->ausbildungssemester + 1 < $studiengang->max_semester) + $ausbildungssemester_plus = 1; + + if(!$result) + { + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', [ + 'prestudent_id' => $prestudent_id, + 'studiensemester_kurzbz' => $studiensemester_kurzbz + ])); + } + } + + $prestudent_status = current($result); + $result = $this->_ci->StudentModel->loadWhere(['prestudent_id' => $prestudent_id]); + + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + return error($this->_ci->p->t('studierendenantrag', 'error_no_student_for_prestudent', ['prestudent_id' => $prestudent_id])); + + $student = current($result); + + $resultAntrag = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); + if (isError($resultAntrag)) + return $resultAntrag; + $resultAntrag = getData($resultAntrag); + if (!$resultAntrag) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id])); + + $antrag = current($resultAntrag); + + //Status updaten + $result = $this->_ci->PrestudentstatusModel->insert([ + 'prestudent_id' => $prestudent_id, + 'status_kurzbz' => Prestudentstatus_model::STATUS_UNTERBRECHER, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'ausbildungssemester' => $prestudent_status->ausbildungssemester + $ausbildungssemester_plus, + 'datum' => date('c'), + 'insertvon' => $insertvon, + 'insertamum' => date('c'), + 'orgform_kurzbz'=> $prestudent_status->orgform_kurzbz, + 'studienplan_id'=> $prestudent_status->studienplan_id, + 'bestaetigtvon' => $insertvon, + 'bestaetigtam' => date('c'), + 'anmerkung'=> 'Wiedereinstieg ' . $antrag->datum_wiedereinstieg + ]); + + if (isError($result)) + return $result; + + //Verband anlegen + $result = $this->_ci->LehrverbandModel->load([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'B', + 'gruppe' => '' + ]); + + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) + { + $result = $this->_ci->LehrverbandModel->load([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => '', + 'gruppe' => '' + ]); + if (isError($result)) + return $result; + $result = getData($result); + + if(!$result) + { + $this->_ci->LehrverbandModel->insert([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => '', + 'gruppe' => '', + 'bezeichnung' => 'Ab-Unterbrecher', + 'aktiv' => true, + ]); + } + + $this->_ci->LehrverbandModel->insert([ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'B', + 'gruppe' => '', + 'bezeichnung' => 'Unterbrecher', + 'aktiv' => true + ]); + } + + //noch nicht eingetragene Zeugnisnoten auf 9 setzen + $result = $this->_ci->ZeugnisnoteModel->getZeugnisnoten($student->student_uid, $studiensemester_kurzbz); + if (isError($result)) + return $result; + $result = getData($result) ?: []; + + foreach ($result as $lv) + { + if (!$lv->note) + { + $result = $this->_ci->ZeugnisnoteModel->insert([ + 'note' => 9, + 'studiensemester_kurzbz' => $lv->studiensemester_kurzbz, + 'student_uid' => $lv->uid, + 'lehrveranstaltung_id' => $lv->lehrveranstaltung_id + ]); + if (isError($result)) { + $result = $this->_ci->ZeugnisnoteModel->update([ + 'studiensemester_kurzbz' => $lv->studiensemester_kurzbz, + 'student_uid' => $lv->uid, + 'lehrveranstaltung_id' => $lv->lehrveranstaltung_id + ], [ + 'note' => 9 + ]); + + if (isError($result)) + return $result; + } + } + } + + + //Update Aktionen + + //StudentModel updaten + $this->_ci->StudentModel->update([ + 'student_uid' => $student->student_uid + ], [ + 'verband' => 'B', + 'gruppe' => '', + 'semester' => 0, + 'updatevon' => $insertvon, + 'updateamum' => date('c') + ]); + + //Studentlehrverband setzen + $result = $this->_ci->StudentlehrverbandModel->loadWhere([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student->student_uid + ]); + if (hasData($result)) { + $this->_ci->StudentlehrverbandModel->update([ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student->student_uid + ], [ + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'B', + 'gruppe' => '', + 'updateamum' => date('c'), + 'updatevon' => $insertvon + ]); + } else { + $this->_ci->StudentlehrverbandModel->insert([ + 'student_uid' => $student->student_uid, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiengang_kz' => $student->studiengang_kz, + 'semester' => 0, + 'verband' => 'B', + 'gruppe' => '', + 'insertamum' => date('c'), + 'insertvon' => $insertvon + ]); + } + + return success(); + } +} diff --git a/application/libraries/SearchBarLib.php b/application/libraries/SearchBarLib.php index 3a9d06d13..7197eae6a 100644 --- a/application/libraries/SearchBarLib.php +++ b/application/libraries/SearchBarLib.php @@ -30,9 +30,10 @@ class SearchBarLib const ERROR_WRONG_SEARCHSTR = 'ERR002'; const ERROR_NO_TYPES = 'ERR003'; const ERROR_WRONG_TYPES = 'ERR004'; + const ERROR_NOT_AUTH = 'ERR005'; // List of allowed types of search - const ALLOWED_TYPES = ['mitarbeiter', 'organisationunit', 'raum', 'person', 'student', 'prestudent', 'document', 'cms']; + const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student', 'prestudent', 'document', 'cms']; const PHOTO_IMG_URL = '/cis/public/bild.php?src=person&person_id='; @@ -108,6 +109,92 @@ class SearchBarLib return $result; } + private function _mitarbeiter_ohne_zuordnung($searchstr, $type) + { + $dbModel = new DB_Model(); + + $sql = ' + SELECT + \''.$type.'\' AS type, + b.uid AS uid, + p.person_id AS person_id, + p.vorname || \' \' || p.nachname AS name, + ARRAY_AGG(DISTINCT(org.bezeichnung)) AS organisationunit_name, + COALESCE(b.alias, b.uid) || \''.'@'.DOMAIN.'\' AS email, + TRIM(COALESCE(k.kontakt, \'\') || \' \' || COALESCE(m.telefonklappe, \'\')) AS phone, + \''.base_url(self::PHOTO_IMG_URL).'\' || p.person_id AS photo_url, + ARRAY_AGG(DISTINCT(stdkst.bezeichnung)) AS standardkostenstelle + FROM public.tbl_mitarbeiter m + JOIN public.tbl_benutzer b ON(b.uid = m.mitarbeiter_uid) + LEFT JOIN ( + SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) + WHERE bf.funktion_kurzbz = \'kstzuordnung\' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid + ) stdkst ON stdkst.uid = b.uid + JOIN public.tbl_person p USING(person_id) + LEFT JOIN ( + SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) + WHERE bf.funktion_kurzbz = \'oezuordnung\' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid + ) org ON org.uid = b.uid + LEFT JOIN ( + SELECT kontakt, standort_id + FROM public.tbl_kontakt + WHERE kontakttyp = \'telefon\' + ) k ON(k.standort_id = m.standort_id) + WHERE + (stdkst.bezeichnung IS NULL + OR org.bezeichnung IS NULL) + AND ( + ' . + $this->buildSearchClause( + $dbModel, + array('b.uid', 'p.vorname', 'p.nachname'), + $searchstr + ) . + ' + ) + GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone + '; + + $employees = $dbModel->execReadOnlyQuery($sql); + + // If something has been found then return it + if (hasData($employees)) return getData($employees); + + // Otherwise return an empty array + return array(); + } + + protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr) + { + $document = implode(' || \' \' || ', $columns); + $query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\''; + $reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\''; + $nospacequery = '\'' . implode('', explode(' ', trim($searchstr))) . ':*\''; + + $searchclause = <<= NOW()) - GROUP BY o.bezeichnung, bf.uid + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) stdkst ON stdkst.uid = b.uid JOIN public.tbl_person p USING(person_id) JOIN ( - SELECT o.bezeichnung, bf.uid + SELECT \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS bezeichnung, bf.uid FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) WHERE bf.funktion_kurzbz = \'oezuordnung\' AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) - GROUP BY o.bezeichnung, bf.uid + GROUP BY o.bezeichnung, ot.bezeichnung, bf.uid ) org ON org.uid = b.uid LEFT JOIN ( SELECT kontakt, standort_id FROM public.tbl_kontakt WHERE kontakttyp = \'telefon\' ) k ON(k.standort_id = m.standort_id) - WHERE b.uid ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR p.vorname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR p.nachname ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR org.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR stdkst.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' + WHERE ' . + $this->buildSearchClause( + $dbModel, + array('b.uid', 'p.vorname', 'p.nachname', 'org.bezeichnung', 'stdkst.bezeichnung'), + $searchstr + ) . + ' GROUP BY type, b.uid, p.person_id, name, email, m.telefonklappe, phone '); @@ -178,15 +269,17 @@ class SearchBarLib SELECT \''.$type.'\' AS type, o.oe_kurzbz AS oe_kurzbz, - o.bezeichnung AS name, + \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS name, oParent.oe_kurzbz AS parentoe_kurzbz, - oParent.bezeichnung AS parentoe_name, + (CASE WHEN oParent.bezeichnung IS NOT NULL THEN \'[\' || otParent.bezeichnung || \'] \' || oParent.bezeichnung END) AS parentoe_name, ARRAY_AGG(DISTINCT(bfLeader.uid)) AS leader_uid, ARRAY_AGG(DISTINCT(bfLeader.vorname || \' \' || bfLeader.nachname)) AS leader_name, COUNT(bfCount.benutzerfunktion_id) AS number_of_people, (CASE WHEN o.mailverteiler = TRUE THEN o.oe_kurzbz || \''.'@'.DOMAIN.'\' END) AS mailgroup FROM public.tbl_organisationseinheit o + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) LEFT JOIN public.tbl_organisationseinheit oParent ON(oParent.oe_kurzbz = o.oe_parent_kurzbz) + LEFT JOIN public.tbl_organisationseinheittyp otParent ON(oParent.organisationseinheittyp_kurzbz = otParent.organisationseinheittyp_kurzbz) LEFT JOIN ( SELECT benutzerfunktion_id, oe_kurzbz FROM public.tbl_benutzerfunktion @@ -204,9 +297,14 @@ class SearchBarLib AND (datum_bis IS NULL OR datum_bis >= NOW()) AND b.aktiv = TRUE ) bfLeader ON(bfLeader.oe_kurzbz = o.oe_kurzbz) - WHERE o.oe_kurzbz ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - OR o.bezeichnung ILIKE \'%'.$dbModel->escapeLike($searchstr).'%\' - GROUP BY type, o.oe_kurzbz, o.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung + WHERE ' . + $this->buildSearchClause( + $dbModel, + array('o.oe_kurzbz', 'o.bezeichnung', 'ot.bezeichnung'), + $searchstr + ) . + ' + GROUP BY type, o.oe_kurzbz, o.bezeichnung, ot.bezeichnung, oParent.oe_kurzbz, oParent.bezeichnung, otParent.bezeichnung '); // If something has been found diff --git a/application/libraries/TableWidgetLib.php b/application/libraries/TableWidgetLib.php index dc746b6d5..3af99cca7 100644 --- a/application/libraries/TableWidgetLib.php +++ b/application/libraries/TableWidgetLib.php @@ -1,5 +1,22 @@ . + */ + if (! defined('BASEPATH')) exit('No direct script access allowed'); /** @@ -16,6 +33,7 @@ class TableWidgetLib const SESSION_FIELDS = 'fields'; const SESSION_COLUMNS_ALIASES = 'columnsAliases'; const SESSION_ADDITIONAL_COLUMNS = 'additionalColumns'; + const SESSION_ENCRYPTED_COLUMNS = 'encryptedColumns'; const SESSION_CHECKBOXES = 'checkboxes'; const SESSION_METADATA = 'datasetMetadata'; const SESSION_ROW_NUMBER = 'rowNumber'; @@ -49,6 +67,7 @@ class TableWidgetLib const ADDITIONAL_COLUMNS = 'additionalColumns'; const CHECKBOXES = 'checkboxes'; const COLUMNS_ALIASES = 'columnsAliases'; + const ENCRYPTED_COLUMNS = 'encryptedColumns'; // ...to format/mark records of a dataset const FORMAT_ROW = 'formatRow'; @@ -74,7 +93,7 @@ class TableWidgetLib /** * Gets the CI instance and loads message helper */ - public function __construct($params = null) + public function __construct() { $this->_ci =& get_instance(); // get code igniter instance } @@ -177,7 +196,7 @@ class TableWidgetLib /** * Retrieves the dataset from the DB */ - public function getDataset($datasetQuery) + public function getDataset($datasetQuery, $encryptedColumns) { $dataset = null; @@ -186,7 +205,7 @@ class TableWidgetLib $this->_ci->load->model('system/Filters_model', 'FiltersModel'); // Execute the given SQL statement suppressing error messages - $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery); + $dataset = @$this->_ci->FiltersModel->execReadOnlyQuery($datasetQuery, null, $encryptedColumns); } return $dataset; diff --git a/application/libraries/vertragsbestandteil/AbstractBestandteil.php b/application/libraries/vertragsbestandteil/AbstractBestandteil.php new file mode 100644 index 000000000..ccd05f5e2 --- /dev/null +++ b/application/libraries/vertragsbestandteil/AbstractBestandteil.php @@ -0,0 +1,69 @@ +isvalid = false; + $this->validationerrors = array(); + + $this->modifiedcolumns = array(); + $this->fromdb = false; + } + + public function isDirty() { + return count($this->modifiedcolumns) > 0; + } + + protected function markDirty($columnname, $old_value, $new_value) { + if( $this->fromdb ) { + // data comes from db dont check for changes + if( isset($this->modifiedcolumns[$columnname]) ) { + unset($this->modifiedcolumns[$columnname]); + } + return; + } + + if( is_bool($new_value) && ($old_value !== $new_value) ) { + $this->modifiedcolumns[$columnname] = $columnname; + } else if($old_value != $new_value) { + $this->modifiedcolumns[$columnname] = $columnname; + } + } + + public function isValid() + { + return $this->isvalid; + } + + public function getValidationErrors() + { + return $this->validationerrors; + } + + + public function addValidationError($errormsg) + { + if( !in_array($errormsg, $this->validationerrors, true) ) + { + $this->validationerrors[] = $errormsg; + } + $this->isvalid = false; + } + + abstract public function hydrateByStdClass($data, $fromdb=false); +} diff --git a/application/libraries/vertragsbestandteil/Dienstverhaeltnis.php b/application/libraries/vertragsbestandteil/Dienstverhaeltnis.php new file mode 100644 index 000000000..5745c2196 --- /dev/null +++ b/application/libraries/vertragsbestandteil/Dienstverhaeltnis.php @@ -0,0 +1,265 @@ +checkoverlap = true; + } + + public function hydrateByStdClass($data, $fromdb=false) + { + $this->fromdb = $fromdb; + isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id); + isset($data->mitarbeiter_uid) && $this->setMitarbeiter_uid($data->mitarbeiter_uid); + isset($data->vertragsart_kurzbz) && $this->setVertragsart_kurzbz($data->vertragsart_kurzbz); + isset($data->checkoverlap) && $this->setCheckoverlap($data->checkoverlap); + isset($data->oe_kurzbz) && $this->setOe_kurzbz($data->oe_kurzbz); + isset($data->von) && $this->setVon($data->von); + isset($data->bis) && $this->setBis($data->bis); + isset($data->insertamum) && $this->setInsertamum($data->insertamum); + isset($data->insertvon) && $this->setInsertvon($data->insertvon); + isset($data->updateamum) && $this->setUpdateamum($data->updateamum); + isset($data->updatevon) && $this->setUpdatevon($data->updatevon); + $this->fromdb = false; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(), + 'mitarbeiter_uid' => $this->getMitarbeiter_uid(), + 'vertragsart_kurzbz' => $this->getVertragsart_kurzbz(), + 'oe_kurzbz' => $this->getOe_kurzbz(), + 'von' => $this->getVon(), + 'bis' => $this->getBis(), + 'insertamum' => $this->getInsertamum(), + 'insertvon' => $this->getInsertvon(), + 'updateamum' => $this->getUpdateamum(), + 'updatevon' => $this->getUpdatevon() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + + public function __toString() + { + $txt = <<getDienstverhaeltnis_id()} + mitarbeiter_uid: {$this->getMitarbeiter_uid()} + vertragsart_kurzbz: {$this->getVertragsart_kurzbz()} + oe_kurzbz: {$this->getOe_kurzbz()} + von: {$this->getVon()} + bis: {$this->getBis()} + +EOTXT; + return $txt; + } + + public function getDienstverhaeltnis_id() + { + return $this->dienstverhaeltnis_id; + } + + public function getMitarbeiter_uid() + { + return $this->mitarbeiter_uid; + } + + public function getVertragsart_kurzbz() + { + return $this->vertragsart_kurzbz; + } + + public function getOe_kurzbz() + { + return $this->oe_kurzbz; + } + + public function getVon() + { + return $this->von; + } + + public function getBis() + { + return $this->bis; + } + + public function getInsertamum() + { + return $this->insertamum; + } + + public function getInsertvon() + { + return $this->insertvon; + } + + public function getUpdateamum() + { + return $this->updateamum; + } + + public function getUpdatevon() + { + return $this->updatevon; + } + + public function setDienstverhaeltnis_id($dienstverhaeltnis_id) + { + $this->markDirty('dienstverhaeltnis_id', $this->dienstverhaeltnis_id, $dienstverhaeltnis_id); + $this->dienstverhaeltnis_id = $dienstverhaeltnis_id; + return $this; + } + + public function setMitarbeiter_uid($mitarbeiter_uid) + { + $this->markDirty('mitarbeiter_uid', $this->mitarbeiter_uid, $mitarbeiter_uid); + $this->mitarbeiter_uid = $mitarbeiter_uid; + return $this; + } + + public function setVertragsart_kurzbz($vertragsart_kurzbz) + { + $this->markDirty('vertragsart_kurzbz', $this->vertragsart_kurzbz, $vertragsart_kurzbz); + $this->vertragsart_kurzbz = $vertragsart_kurzbz; + return $this; + } + + public function setCheckoverlap(bool $checkoverlap) + { + $this->checkoverlap = $checkoverlap; + } + + public function setOe_kurzbz($oe_kurzbz) + { + $this->markDirty('oe_kurzbz', $this->oe_kurzbz, $oe_kurzbz); + $this->oe_kurzbz = $oe_kurzbz; + return $this; + } + + public function setVon($von) + { + $this->markDirty('von', $this->von, $von); + $this->von = $von; + return $this; + } + + public function setBis($bis) + { + $this->markDirty('bis', $this->bis, $bis); + $this->bis = $bis; + return $this; + } + + public function setInsertamum($insertamum) + { + $this->markDirty('insertamum', $this->insertamum, $insertamum); + $this->insertamum = $insertamum; + return $this; + } + + public function setInsertvon($insertvon) + { + $this->markDirty('insertvon', $this->insertvon, $insertvon); + $this->insertvon = $insertvon; + return $this; + } + + public function setUpdateamum($updateamum) + { + $this->markDirty('updateamum', $this->updateamum, $updateamum); + $this->updateamum = $updateamum; + return $this; + } + + public function setUpdatevon($updatevon) + { + $this->markDirty('updatevon', $this->updatevon, $updatevon); + $this->updatevon = $updatevon; + return $this; + } + + public function validate() { + //do Validation here + $ci = get_instance(); + $ci->load->library('vertragsbestandteil/VertragsbestandteilLib', + null, 'VertragsbestandteilLib'); + + if( empty($this->mitarbeiter_uid) ) { + $this->validationerrors[] = 'Mitarbeiter_UID fehlt.'; + } + + if( empty($this->oe_kurzbz) ) { + $this->validationerrors[] = 'Unternehmen fehlt.'; + } + + if( empty($this->vertragsart_kurzbz) ) { + $this->validationerrors[] = 'Vertragsart fehlt.'; + } + + $von = \DateTimeImmutable::createFromFormat('Y-m-d', $this->von); + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $von ) { + $this->validationerrors[] = 'Beginn muss ein gültiges Datum sein.'; + } + + if( $this->bis !== null && $bis === false ) { + $this->validationerrors[] = 'Ende muss ein gültiges Datum oder leer sein.'; + } + + if( $this-> bis !== null && $von && $bis && $von > $bis ) { + $this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.'; + } + + if( $this->checkoverlap && !($this->vertragsart_kurzbz === 'werkvertrag') + && $ci->VertragsbestandteilLib->isOverlappingExistingDV($this) ) + { + $this->validationerrors[] = 'Es existiert bereits ein überlappendes Dienstverhältnis'; + } + + // return status after Validation + if( count($this->validationerrors) > 0 ) { + $this->isvalid = false; + } else { + $this->isvalid = true; + } + + return $this->isvalid; + } +} \ No newline at end of file diff --git a/application/libraries/vertragsbestandteil/Gehaltsbestandteil.php b/application/libraries/vertragsbestandteil/Gehaltsbestandteil.php new file mode 100644 index 000000000..22f8ee2ae --- /dev/null +++ b/application/libraries/vertragsbestandteil/Gehaltsbestandteil.php @@ -0,0 +1,360 @@ +fromdb = $fromdb; + isset($data->gehaltsbestandteil_id) && $this->setGehaltsbestandteil_id($data->gehaltsbestandteil_id); + isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id); + isset($data->vertragsbestandteil_id) && $this->setVertragsbestandteil_id($data->vertragsbestandteil_id); + isset($data->gehaltstyp_kurzbz) && $this->setGehaltstyp_kurzbz($data->gehaltstyp_kurzbz); + isset($data->von) && $this->setVon($data->von); + isset($data->bis) && $this->setBis($data->bis); + isset($data->anmerkung) && $this->setAnmerkung($data->anmerkung); + isset($data->grundbetrag) && $this->setGrundbetrag($data->grundbetrag); + isset($data->betrag_valorisiert) && $this->setBetrag_valorisiert($data->betrag_valorisiert); + isset($data->valorisierungssperre) && $this->setValorisierungssperre($data->valorisierungssperre); + isset($data->valorisierung) && $this->setValorisierung($data->valorisierung); + isset($data->auszahlungen) && $this->setAuszahlungen($data->auszahlungen); + + isset($data->insertamum) && $this->setInsertamum($data->insertamum); + isset($data->insertvon) && $this->setInsertvon($data->insertvon); + isset($data->updateamum) && $this->setUpdateamum($data->updateamum); + isset($data->updatevon) && $this->setUpdatevon($data->updatevon); + $this->fromdb = false; + } + + public function getGehaltsbestandteil_id() + { + return $this->gehaltsbestandteil_id; + } + + public function getDienstverhaeltnis_id() + { + return $this->dienstverhaeltnis_id; + } + + public function getVertragsbestandteil_id() + { + return $this->vertragsbestandteil_id; + } + + public function getGehaltstyp_kurzbz() + { + return $this->gehaltstyp_kurzbz; + } + + public function getVon() + { + return $this->von; + } + + public function getBis() + { + return $this->bis; + } + + public function getVonDateTime() + { + return $this->toDateTime($this->von); + } + + public function getBisDateTime() + { + return $this->toDateTime($this->bis); + } + + protected function toDateTime($d) { + if ($d == null) return null; + return new DateTimeImmutable($d); + } + + public function getAnmerkung() + { + return $this->anmerkung; + } + + public function getGrundbetrag() + { + return $this->grundbetrag; + } + + public function getBetrag_valorisiert() + { + return $this->betrag_valorisiert; + } + + public function getValorisierungssperre() + { + return $this->valorisierungssperre; + } + + public function getValorisierung() + { + return $this->valorisierung; + } + + public function getAuszahlungen() + { + return $this->auszahlungen; + } + + public function getInsertamum() + { + return $this->insertamum; + } + + public function getInsertvon() + { + return $this->insertvon; + } + + public function getUpdateamum() + { + return $this->updateamum; + } + + public function getUpdatevon() + { + return $this->updatevon; + } + + public function setGehaltsbestandteil_id($gehaltsbestandteil_id) + { + $this->markDirty('gehaltsbestandteil_id', $this->gehaltsbestandteil_id, $gehaltsbestandteil_id); + $this->gehaltsbestandteil_id = $gehaltsbestandteil_id; + return $this; + } + + public function setDienstverhaeltnis_id($dienstverhaeltnis_id) + { + $this->markDirty('dienstverhaeltnis_id', $this->dienstverhaeltnis_id, $dienstverhaeltnis_id); + $this->dienstverhaeltnis_id = $dienstverhaeltnis_id; + return $this; + } + + public function setVertragsbestandteil_id($vertragsbestandteil_id) + { + $this->markDirty('vertragsbestandteil_id', $this->vertragsbestandteil_id, $vertragsbestandteil_id); + $this->vertragsbestandteil_id = $vertragsbestandteil_id; + return $this; + } + + public function setGehaltstyp_kurzbz($gehaltstyp_kurzbz) + { + $this->markDirty('gehaltstyp_kurzbz', $this->gehaltstyp_kurzbz, $gehaltstyp_kurzbz); + $this->gehaltstyp_kurzbz = $gehaltstyp_kurzbz; + return $this; + } + + public function setVon($von) + { + $this->markDirty('von', $this->von, $von); + $this->von = $von; + return $this; + } + + public function setBis($bis) + { + $this->markDirty('bis', $this->bis, $bis); + $this->bis = $bis; + return $this; + } + + public function setAnmerkung($anmerkung) + { + $this->markDirty('anmerkung', $this->anmerkung, $anmerkung); + $this->anmerkung = $anmerkung; + return $this; + } + + public function setGrundbetrag($grundbetrag) + { + $this->markDirty('grundbetrag', $this->grundbetrag, $grundbetrag); + $this->grundbetrag = $grundbetrag; + return $this; + } + + public function setBetrag_valorisiert($betrag_valorisiert) + { + $this->markDirty('betrag_valorisiert', $this->betrag_valorisiert, $betrag_valorisiert); + $this->betrag_valorisiert = $betrag_valorisiert; + return $this; + } + + public function setValorisierungssperre($valorisierungssperre) + { + $this->markDirty('valorisierungssperre', $this->valorisierungssperre, $valorisierungssperre); + $this->valorisierungssperre = $valorisierungssperre; + return $this; + } + + public function setValorisierung($valorisierung) + { + $this->markDirty('valorisierung', $this->valorisierung, $valorisierung); + $this->valorisierung = $valorisierung; + return $this; + } + + public function setAuszahlungen($auszahlungen) + { + $this->markDirty('auszahlungen', $this->auszahlungen, $auszahlungen); + $this->auszahlungen = $auszahlungen; + return $this; + } + + public function setInsertamum($insertamum) + { + $this->markDirty('insertamum', $this->insertamum, $insertamum); + $this->insertamum = $insertamum; + return $this; + } + + public function setInsertvon($insertvon) + { + $this->markDirty('insertvon', $this->insertvon, $insertvon); + $this->insertvon = $insertvon; + return $this; + } + + public function setUpdateamum($updateamum) + { + $this->markDirty('updateamum', $this->updateamum, $updateamum); + $this->updateamum = $updateamum; + return $this; + } + + public function setUpdatevon($updatevon) + { + $this->markDirty('updatevon', $this->updatevon, $updatevon); + $this->updatevon = $updatevon; + return $this; + } + + public function jsonSerialize() + { + $vars = get_object_vars($this); + unset($vars['CI']); + return $vars; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'gehaltsbestandteil_id' => $this->getGehaltsbestandteil_id(), + 'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(), + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'gehaltstyp_kurzbz' => $this->getGehaltstyp_kurzbz(), + 'von' => $this->getVon(), + 'bis' => $this->getBis(), + 'anmerkung' => $this->getAnmerkung(), + 'grundbetrag' => $this->getGrundbetrag(), + 'betrag_valorisiert' => $this->getBetrag_valorisiert(), + 'valorisierungssperre' => $this->getValorisierungssperre(), + 'valorisierung' => $this->getValorisierung(), + 'auszahlungen' => $this->getAuszahlungen(), + 'insertamum' => $this->getInsertamum(), + 'insertvon' => $this->getInsertvon(), + 'updateamum' => $this->getUpdateamum(), + 'updatevon' => $this->getUpdatevon() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getGehaltsbestandteil_id()} + dienstverhaeltnis_id: {$this->getDienstverhaeltnis_id()} + vertragsbestandteil_id: {$this->getVertragsbestandteil_id()} + gehaltstyp_kurzbz: {$this->getGehaltstyp_kurzbz()} + von: {$this->getVon()} + bis: {$this->getBis()} + anmerkung: {$this->getAnmerkung()} + grundbetrag: {$this->getGrundbetrag()} + betrag_valorisiert: {$this->getBetrag_valorisiert()} + valorisierungssperre: {$this->getValorisierungssperre()} + valorisierung: {$this->getValorisierung()} + auszahlungen: {$this->getAuszahlungen()} + insertamum: {$this->getInsertamum()} + insertvon: {$this->getInsertvon()} + updateamum: {$this->getUpdateamum()} + updatevon: {$this->getUpdatevon()} + +EOTXT; + return $txt; + } + + public function validate() { + //do Validation here + if( empty($this->gehaltstyp_kurzbz) ) + { + $this->validationerrors[] = "Ein Gehaltstyp muss ausgewählt sein."; + } + + if( empty($this->grundbetrag) ) + { + $this->validationerrors[] = "Betrag fehlt."; + } + + $von = \DateTimeImmutable::createFromFormat('Y-m-d', $this->von); + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $von ) { + $this->validationerrors[] = 'Beginn muss ein gültiges Datum sein.'; + } + + if( $this->bis !== null && $bis === false ) { + $this->validationerrors[] = 'Ende muss ein gültiges Datum oder leer sein.'; + } + + if( $this-> bis !== null && $von && $bis && $von > $bis ) { + $this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.'; + } + + // return status after Validation + if( count($this->validationerrors) > 0 ) { + $this->isvalid = false; + } else { + $this->isvalid = true; + } + + return $this->isvalid; + } +} diff --git a/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php b/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php new file mode 100644 index 000000000..b75bdd722 --- /dev/null +++ b/application/libraries/vertragsbestandteil/GehaltsbestandteilLib.php @@ -0,0 +1,149 @@ +loggedInUser = getAuthUID(); + $this->CI = get_instance(); + $this->CI->load->model('vertragsbestandteil/Gehaltsbestandteil_model', + 'GehaltsbestandteilModel'); + $this->CI->load->library('extensions/FHC-Core-Personalverwaltung/abrechnung/GehaltsLib'); + $this->GehaltsbestandteilModel = $this->CI->GehaltsbestandteilModel; + } + + public function fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + { + return $this->GehaltsbestandteilModel->getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); + } + + public function fetchGehaltsbestandteil($gehaltsbestandteil_id) + { + return $this->GehaltsbestandteilModel->getGehaltsbestandteil($gehaltsbestandteil_id); + } + + public function storeGehaltsbestandteile($gehaltsbestandteile) + { + foreach( $gehaltsbestandteile as $gehaltsbestandteil ) + { + $this->storeGehaltsbestandteil($gehaltsbestandteil); + } + } + + public function storeGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + try + { + $this->setUIDtoPGSQL(); + if( intval($gehaltsbestandteil->getGehaltsbestandteil_id()) > 0 ) + { + $this->updateGehaltsbestandteil($gehaltsbestandteil); + } + else + { + $this->insertGehaltsbestandteil($gehaltsbestandteil); + } + } + catch (Exception $ex) + { + log_message('debug', "Storing Gehaltsbestandteil failed. " . $ex->getMessage()); + throw new Exception('Storing Gehaltsbestandteil failed.'); + } + } + + protected function insertGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + $gehaltsbestandteil->setInsertvon($this->loggedInUser) + ->setInsertamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->GehaltsbestandteilModel->insert($gehaltsbestandteil->toStdClass(), + $this->GehaltsbestandteilModel->getEncryptedColumns()); + if( hasData($ret) ) + { + $gehaltsbestandteil->setGehaltsbestandteil_id(getData($ret)); + } + else + { + throw new Exception('error inserting gehaltsbestandteil'); + } + } + + protected function updateGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + if(!$gehaltsbestandteil->isDirty()) { + return; + } + + $gehaltsbestandteil->setUpdatevon($this->loggedInUser) + ->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->GehaltsbestandteilModel->update($gehaltsbestandteil->getGehaltsbestandteil_id(), + $gehaltsbestandteil->toStdClass(), + $this->GehaltsbestandteilModel->getEncryptedColumns()); + + if(isError($ret) ) + { + throw new Exception('error updating gehaltsbestandteil'); + } + } + + public function deleteGehaltsbestandteile($gehaltsbestandteile) + { + foreach( $gehaltsbestandteile as $gehaltsbestandteil ) + { + $this->deleteGehaltsbestandteil($gehaltsbestandteil); + } + } + + public function deleteGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + $this->setUIDtoPGSQL(); + + // delete Gehaltsabrechnung + $ret = $this->CI->gehaltslib->deleteAbrechnung($gehaltsbestandteil); + + // + $ret = $this->GehaltsbestandteilModel->delete($gehaltsbestandteil->getGehaltsbestandteil_id()); + + if (isError($ret)) + { + throw new Exception('error deleting gehaltsbestandteil'); + } + } + + public function endGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil, $enddate) + { + $this->setUIDtoPGSQL(); + if( $gehaltsbestandteil->getBis() !== null && $gehaltsbestandteil->getBis() < $enddate ) + { + return; + } + + $gehaltsbestandteil->setBis($enddate); + $this->updateGehaltsbestandteil($gehaltsbestandteil); + } + + protected function setUIDtoPGSQL() { + $ret = $this->GehaltsbestandteilModel + ->execReadOnlyQuery('SET LOCAL pv21.uid TO \'' + . $this->loggedInUser . '\''); + if(isError($ret)) + { + throw new Exception('error setting uid to pgsql'); + } + } +} diff --git a/application/libraries/vertragsbestandteil/IValidation.php b/application/libraries/vertragsbestandteil/IValidation.php new file mode 100644 index 000000000..c55e33bcd --- /dev/null +++ b/application/libraries/vertragsbestandteil/IValidation.php @@ -0,0 +1,18 @@ +CI = get_instance(); + $this->CI->load->model('vertragsbestandteil/Vertragsbestandteil_model', + 'VertragsbestandteilModel'); + $this->VertragsbestandteilModel = $this->CI->VertragsbestandteilModel; + $this->CI->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model', + 'VertragsbestandteilFreitextModel'); + $this->VertragsbestandteilFreitextModel = $this->CI->VertragsbestandteilFreitextModel; + $this->CI->load->model('vertragsbestandteil/Vertragsbestandteiltyp_model', + 'VertragsbestandteilTypModel'); + $this->VertragsbestandteilTypModel = $this->CI->VertragsbestandteilTypModel; + $this->CI->load->model('vertragsbestandteil/VertragsbestandteilFreitexttyp_model', + 'VertragsbestandteilFreitexttypModel'); + $this->VertragsbestandteilFreitexttypModel = $this->CI->VertragsbestandteilFreitexttypModel; + } + + public function overlapsVB(Vertragsbestandteil $vb) + { + $result = $this->VertragsbestandteilTypModel->load($vb->getVertragsbestandteiltyp_kurzbz()); + if( null === ($vertragsbestandteiltyp = getData($result)) ) + { + throw new Exception('vertragsbestandteiltyp: ' + . $vb->getVertragsbestandteiltyp_kurzbz() . ' not found.'); + } + + if( true === $vertragsbestandteiltyp[0]->ueberlappend ) + { + // vertragsbestandteiltyp can overlap + return false; + } + + if( $this->VertragsbestandteilModel->countOverlappingVBsOfSameType($vb) === 0 ) + { + return false; + } + else + { + return true; + } + } + + public function overlapsFreitext(VertragsbestandteilFreitext $vbft) + { + $result = $this->VertragsbestandteilFreitexttypModel->load($vbft->getFreitexttypKurzbz()); + if( null === ($vertragsbestandteilfreitexttyp = getData($result)) ) + { + throw new Exception('vertragsbestandteilfreitexttyp: ' + . $vbft->getFreitexttypKurzbz() . ' not found.'); + } + + if( true === $vertragsbestandteilfreitexttyp[0]->ueberlappend ) + { + // freitexttyp can overlap + return false; + } + + if( $this->VertragsbestandteilFreitextModel->countOverlappingVBFreitextsOfSameType($vbft) === 0 ) + { + return false; + } + else + { + return true; + } + } + + private function __clone() {} +} diff --git a/application/libraries/vertragsbestandteil/Vertragsbestandteil.php b/application/libraries/vertragsbestandteil/Vertragsbestandteil.php new file mode 100644 index 000000000..bf5ec6211 --- /dev/null +++ b/application/libraries/vertragsbestandteil/Vertragsbestandteil.php @@ -0,0 +1,265 @@ +gehaltsbestandteile = array(); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + $this->fromdb = $fromdb; + isset($data->vertragsbestandteil_id) && $this->setVertragsbestandteil_id($data->vertragsbestandteil_id); + isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id); + isset($data->von) && $this->setVon($data->von); + isset($data->bis) && $this->setBis($data->bis); + isset($data->vertragsbestandteiltyp_kurzbz) && $this->setVertragsbestandteiltyp_kurzbz($data->vertragsbestandteiltyp_kurzbz); + isset($data->insertamum) && $this->setInsertamum($data->insertamum); + isset($data->insertvon) && $this->setInsertvon($data->insertvon); + isset($data->updateamum) && $this->setUpdateamum($data->updateamum); + isset($data->updatevon) && $this->setUpdatevon($data->updatevon); + $this->fromdb = false; + } + + public function addGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil) + { + $gehaltsbestandteil->setDienstverhaeltnis_id($this->getDienstverhaeltnis_id()); + $gehaltsbestandteil->setVertragsbestandteil_id($this->getVertragsbestandteil_id()); + $this->gehaltsbestandteile[] = $gehaltsbestandteil; + return $this; + } + + public function getGehaltsbestandteile() + { + return $this->gehaltsbestandteile; + } + + public function getVertragsbestandteil_id() + { + return $this->vertragsbestandteil_id; + } + + public function getDienstverhaeltnis_id() + { + return $this->dienstverhaeltnis_id; + } + + public function getVon() + { + return $this->von; + } + + public function getBis() + { + return $this->bis; + } + + public function getVertragsbestandteiltyp_kurzbz() + { + return $this->vertragsbestandteiltyp_kurzbz; + } + + public function getInsertamum() + { + return $this->insertamum; + } + + public function getInsertvon() + { + return $this->insertvon; + } + + public function getUpdateamum() + { + return $this->updateamum; + } + + public function getUpdatevon() + { + return $this->updatevon; + } + + public function setGehaltsbestandteile($gehaltsbestandteile) + { + $this->gehaltsbestandteile = $gehaltsbestandteile; + return $this; + } + + public function setVertragsbestandteil_id($vertragsbestandteil_id) + { + $this->markDirty('vertragsbestandteil_id', $this->vertragsbestandteil_id, $vertragsbestandteil_id); + $this->vertragsbestandteil_id = $vertragsbestandteil_id; + foreach ($this->gehaltsbestandteile as $gehaltsbestandteil) + { + $gehaltsbestandteil->setVertragsbestandteil_id($vertragsbestandteil_id); + } + return $this; + } + + public function setDienstverhaeltnis_id($dienstverhaeltnis_id) + { + $this->markDirty('dienstverhaeltnis_id', $this->dienstverhaeltnis_id, $dienstverhaeltnis_id); + $this->dienstverhaeltnis_id = $dienstverhaeltnis_id; + foreach ($this->gehaltsbestandteile as $gehaltsbestandteil) + { + $gehaltsbestandteil->setDienstverhaeltnis_id($dienstverhaeltnis_id); + } + return $this; + } + + public function setVon($von) + { + $this->markDirty('von', $this->von, $von); + $this->von = $von; + return $this; + } + + public function setBis($bis) + { + $this->markDirty('bis', $this->bis, $bis); + $this->bis = $bis; + return $this; + } + + public function setVertragsbestandteiltyp_kurzbz($vertragsbestandteiltyp_kurzbz) + { + $this->markDirty('vertragsbestandteiltyp_kurzbz', $this->vertragsbestandteiltyp_kurzbz, $vertragsbestandteiltyp_kurzbz); + $this->vertragsbestandteiltyp_kurzbz = $vertragsbestandteiltyp_kurzbz; + return $this; + } + + public function setInsertamum($insertamum) + { + $this->markDirty('insertamum', $this->insertamum, $insertamum); + $this->insertamum = $insertamum; + return $this; + } + + public function setInsertvon($insertvon) + { + $this->markDirty('insertvon', $this->insertvon, $insertvon); + $this->insertvon = $insertvon; + return $this; + } + + public function setUpdateamum($updateamum) + { + $this->markDirty('updateamum', $this->updateamum, $updateamum); + $this->updateamum = $updateamum; + return $this; + } + + public function setUpdatevon($updatevon) + { + $this->markDirty('updatevon', $this->updatevon, $updatevon); + $this->updatevon = $updatevon; + return $this; + } + + public function baseToStdClass() { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(), + 'von' => $this->getVon(), + 'bis' => $this->getBis(), + 'vertragsbestandteiltyp_kurzbz' => $this->getVertragsbestandteiltyp_kurzbz(), + 'insertamum' => $this->getInsertamum(), + 'insertvon' => $this->getInsertvon(), + 'updateamum' => $this->getUpdateamum(), + 'updatevon' => $this->getUpdatevon(), + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function jsonSerialize() + { + $vars = get_object_vars($this); + unset($vars['CI']); + + // TODO cleanup workaroung for vb freitext where db column is anmerkung and formfield is freitext + if( isset($vars['anmerkung']) ) { + $vars['freitext'] = $vars['anmerkung']; + } + + return $vars; + } + + public function __toString() + { + return <<getVertragsbestandteil_id()} + dienstverhaeltnis_id: {$this->getDienstverhaeltnis_id()} + von: {$this->getVon()} + bis: {$this->getBis()} + vertragsbestandteiltyp_kurzbz: {$this->getVertragsbestandteiltyp_kurzbz()} + insertamum: {$this->getInsertamum()} + insertvon: {$this->getInsertvon()} + updateamum: {$this->getUpdateamum()} + updatevon: {$this->getUpdatevon()} + +EOTXT; + + } + + public function beforePersist() { + // can be overridden in childs + } + + public function afterDelete() { + // can be overridden in childs + } + + public function validate() { + $von = \DateTimeImmutable::createFromFormat('Y-m-d', $this->von); + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $von ) { + $this->validationerrors[] = 'Beginn muss ein gültiges Datum sein.'; + } + + if( $this->bis !== null && $bis === false ) { + $this->validationerrors[] = 'Ende muss ein gültiges Datum oder leer sein.'; + } + + if( $this-> bis !== null && $von && $bis && $von > $bis ) { + $this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.'; + } + + if( count($this->validationerrors) > 0 ) { + $this->isvalid = false; + } else { + $this->isvalid = true; + } + + return $this->isvalid; + } + + public abstract function toStdClass(); +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilFactory.php b/application/libraries/vertragsbestandteil/VertragsbestandteilFactory.php new file mode 100644 index 000000000..6e7b0af06 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilFactory.php @@ -0,0 +1,137 @@ +vertragsbestandteiltyp_kurzbz) + ? $data->vertragsbestandteiltyp_kurzbz : false; + if( false === $vertragsbestandteiltyp_kurzbz ) + { + throw new Exception('Missing Parameter vertragsbestandteiltyp_kurzbz'); + } + + $vertragsbestandteil = null; + switch ($vertragsbestandteiltyp_kurzbz) + { + case self::VERTRAGSBESTANDTEIL_FREITEXT: + $vertragsbestandteil = new VertragsbestandteilFreitext(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_FUNKTION: + $vertragsbestandteil = new VertragsbestandteilFunktion(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_KARENZ: + $vertragsbestandteil = new VertragsbestandteilKarenz(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_KUENDIGUNGSFRIST: + $vertragsbestandteil = new VertragsbestandteilKuendigungsfrist(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_STUNDEN: + $vertragsbestandteil = new VertragsbestandteilStunden(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH: + $vertragsbestandteil = new VertragsbestandteilUrlaubsanspruch(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + case self::VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG: + $vertragsbestandteil = new VertragsbestandteilZeitaufzeichnung(); + $vertragsbestandteil->hydrateByStdClass($data, $fromdb); + break; + + default: + throw new Exception('Unknown vertragsbestandteiltyp_kurzbz ' + . $vertragsbestandteiltyp_kurzbz); + } + + return $vertragsbestandteil; + } + + public static function getVertragsbestandteilDBModel($vertragsbestandteil_kurzbz): \DB_model + { + $CI = get_instance(); + + $vertragsbestandteildbmodel = null; + switch ($vertragsbestandteil_kurzbz) + { + case self::VERTRAGSBESTANDTEIL_FREITEXT: + $CI->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model', + 'VertragsbestandteilFreitext_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilFreitext_model; + break; + + case self::VERTRAGSBESTANDTEIL_FUNKTION: + $CI->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model', + 'VertragsbestandteilFunktion_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilFunktion_model; + break; + + case self::VERTRAGSBESTANDTEIL_KARENZ: + $CI->load->model('vertragsbestandteil/VertragsbestandteilKarenz_model', + 'VertragsbestandteilKarenz_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilKarenz_model; + break; + + case self::VERTRAGSBESTANDTEIL_KUENDIGUNGSFRIST: + $CI->load->model('vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model', + 'VertragsbestandteilKuendigungsfrist_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilKuendigungsfrist_model; + break; + + case self::VERTRAGSBESTANDTEIL_STUNDEN: + $CI->load->model('vertragsbestandteil/VertragsbestandteilStunden_model', + 'VertragsbestandteilStunden_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilStunden_model; + break; + + case self::VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH: + $CI->load->model('vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model', + 'VertragsbestandteilUrlaubsanspruch_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilUrlaubsanspruch_model; + break; + + case self::VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG: + $CI->load->model('vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model', + 'VertragsbestandteilZeitaufzeichnung_model'); + $vertragsbestandteildbmodel = $CI->VertragsbestandteilZeitaufzeichnung_model; + break; + + default: + throw new Exception('Unknown vertragsbestandteil_kurzbz ' + . $vertragsbestandteil_kurzbz); + } + + return $vertragsbestandteildbmodel; + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilFreitext.php b/application/libraries/vertragsbestandteil/VertragsbestandteilFreitext.php new file mode 100644 index 000000000..07e8a3c58 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilFreitext.php @@ -0,0 +1,134 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FREITEXT); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->freitexttyp) && $this->setFreitexttypKurzbz($data->freitexttyp); + isset($data->freitexttyp_kurzbz) && $this->setFreitexttypKurzbz($data->freitexttyp_kurzbz); + isset($data->titel) && $this->setTitel($data->titel); + isset($data->freitext) && $this->setAnmerkung($data->freitext); + isset($data->anmerkung) && $this->setAnmerkung($data->anmerkung); + $this->fromdb = false; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'freitexttyp_kurzbz' => $this->getFreitexttypKurzbz(), + 'titel' => $this->getTitel(), + 'anmerkung' => $this->getAnmerkung() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getAnmerkung()} + titel: {$this->getTitel()} + freitexttyp_kurzbz: {$this->getFreitexttypKurzbz()} + +EOTXT; + return parent::__toString() . $txt; + } + + /** + * Get the value of anmerkung + */ + public function getAnmerkung() + { + return $this->anmerkung; + } + + /** + * Set the value of anmerkung + */ + public function setAnmerkung($anmerkung): self + { + $this->markDirty('anmerkung', $this->anmerkung, $anmerkung); + $this->anmerkung = $anmerkung; + + return $this; + } + + /** + * Get the value of titel + */ + public function getTitel() + { + return $this->titel; + } + + /** + * Set the value of titel + */ + public function setTitel($titel): self + { + $this->markDirty('titel', $this->titel, $titel); + $this->titel = $titel; + + return $this; + } + + /** + * Get the value of freitexttyp_kurzbz + */ + public function getFreitexttypKurzbz() + { + return $this->freitexttyp_kurzbz; + } + + /** + * Set the value of freitexttyp_kurzbz + */ + public function setFreitexttypKurzbz($freitexttyp_kurzbz): self + { + $this->markDirty('freitexttyp_kurzbz', $this->freitexttyp_kurzbz, $freitexttyp_kurzbz); + $this->freitexttyp_kurzbz = $freitexttyp_kurzbz; + + return $this; + } + + public function validate() + { + if( empty($this->freitexttyp_kurzbz) ) { + $this->validationerrors[] = 'Bitte einen gültigen Freitexttyp auswählen.'; + } + + if( empty($this->titel) ) { + $this->validationerrors[] = 'Bitte einen Titel angeben.'; + } + + if( empty($this->anmerkung) ) { + $this->validationerrors[] = 'Bitte eine Beschreibung eingeben.'; + } + + return parent::validate(); + } + + +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilFunktion.php b/application/libraries/vertragsbestandteil/VertragsbestandteilFunktion.php new file mode 100644 index 000000000..ee5cd713f --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilFunktion.php @@ -0,0 +1,369 @@ +benutzerfunktiondata = null; + + $this->setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION); + + $this->CI = get_instance(); + $this->CI->load->model('person/Benutzerfunktion_model', + 'BenutzerfunktionModel'); + $this->CI->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model', + 'VertragsbestandteilFunktionModel'); + $this->CI->load->library('vertragsbestandteil/VertragsbestandteilLib', + null, 'VertragsbestandteilLib'); + } + + public function isDirty() + { + $isdirty = parent::isDirty(); + if( !$isdirty ) { + $bf = $this->loadBenutzerfunktion($this->getBenutzerfunktion_id()); + if( !$this->areVbAndBfInSync($bf) ) + { + $isdirty = true; + } + } + return $isdirty; + } + + public function beforePersist() + { + if( isset($this->benutzerfunktion_id) && intval($this->benutzerfunktion_id) > 0 ) + { + $this->beforePersitExisting(); + } + else + { + $this->beforePersitNew(); + } + } + + protected function loadBenutzerfunktion($bfid) + { + $bfres = $this->CI->BenutzerfunktionModel->load($bfid); + if(!hasData($bfres)) + { + throw new Exception('failed to load existing Benutzerfunktion'); + } + return (getData($bfres))[0]; + } + + protected function loadPersitedVB($vbid) + { + $vb = $this->CI->VertragsbestandteilLib->fetchVertragsbestandteil($vbid); + if( $vb === null ) + { + throw new Exception('failed to load persited Vertragsbestandteil'); + } + return $vb; + } + + protected function areVbAndBfInSync($bf) + { + $vbvon = $this->getVon(); + $vbbis = $this->getBis(); + if( intval($this->getVertragsbestandteil_id()) > 0 ) + { + $vb = $this->loadPersitedVB($this->getVertragsbestandteil_id()); + $vbvon = $vb->getVon(); + $vbbis = $vb->getBis(); + } + + if( ($bf->datum_von === $vbvon) && ($bf->datum_bis === $vbbis) ) + { + return true; + } + return false; + } + + protected function isBefore($a, $b) + { + if($a === null) { + return false; + } + elseif($b === null) { + return true; + } + else { + return $a < $b; + } + } + + protected function isAfter($a, $b) + { + if($b === null) { + return false; + } + elseif($a === null) { + return true; + } + else { + return $a > $b; + } + } + + protected function beforePersitExisting() + { + $bf = $this->loadBenutzerfunktion($this->getBenutzerfunktion_id()); + if( $this->areVbAndBfInSync($bf) ) + { + // vb or stored vb von bis is in sync so update benutzerfunktion + $this->updateBenutzerfunktion($bf, $this->getVon(), $this->getBis()); + } + else + { + $daybeforevon = \DateTime::createFromFormat('Y-m-d', $this->getVon(), + new \DateTimeZone('Europe/Vienna')); + $daybeforevon->sub(new \DateInterval('P1D')); + + if( $this->isBefore($bf->datum_von, $this->getVon()) && + $this->isBefore($bf->datum_von, $this->getBis()) ) + { + $data = (object) array( + 'mitarbeiter_uid' => $bf->uid, + 'funktion' => $bf->funktion_kurzbz, + 'orget' => $bf->oe_kurzbz + ); + $this->createBenutzerfunktionData($data); + $bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert()); + $this->setBenutzerfunktion_id($bfid); + } + elseif( $this->isBefore($bf->datum_von, $this->getVon()) && + $this->isAfter($this->getBis(), $bf->datum_von) ) + { + $this->updateBenutzerfunktion($bf, $bf->datum_von, $daybeforevon->format('Y-m-d')); + $data = (object) array( + 'mitarbeiter_uid' => $bf->uid, + 'funktion' => $bf->funktion_kurzbz, + 'orget' => $bf->oe_kurzbz + ); + $this->createBenutzerfunktionData($data); + $bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert()); + $this->setBenutzerfunktion_id($bfid); + } + else + { + $this->updateBenutzerfunktion($bf, $this->getVon(), $this->getBis()); + } + } + } + + protected function updateBenutzerfunktion($bf, $von, $bis) + { + $data = array(); + + if($von !== $bf->datum_von) + { + $data['datum_von'] = $von; + } + if($bis !== $bf->datum_bis) + { + $data['datum_bis'] = $bis; + } + + if( count($data) === 0 ) + { + return; + } + + $data['updateamum'] = strftime('%Y-%m-%d %H:%M:%S'); + $data['updatevon'] = getAuthUID(); + + $ret = $this->CI->BenutzerfunktionModel->update($bf->benutzerfunktion_id, $data); + + if(isError($ret) ) + { + throw new Exception('failed to update Benutzerfunktion'); + } + } + + protected function insertBenutzerfunktion($benutzerfunktiondata) + { + $ret = $this->CI->BenutzerfunktionModel->insert($benutzerfunktiondata); + + if(isError($ret) ) + { + throw new Exception('failed to create Benutzerfunktion'); + } + + return getData($ret); + } + + protected function deleteBenutzerfunktion($benutzerfunktion_id) + { + $ret = $this->CI->BenutzerfunktionModel->delete($benutzerfunktion_id); + + if(isError($ret) ) + { + throw new Exception('failed to delete Benutzerfunktion'); + } + } + + protected function beforePersitNew() { + if( $this->benutzerfunktiondata === null) + { + return; + } + + $bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert()); + + $this->setBenutzerfunktion_id($bfid); + } + + public function afterDelete() + { + if( !(intval($this->getBenutzerfunktion_id()) > 0) ) + { + return; + } + + $this->deleteBenutzerfunktion($this->getBenutzerfunktion_id()); + } + + public function toStdClass() + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'benutzerfunktion_id' => $this->getBenutzerfunktion_id() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getBenutzerfunktion_id()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->benutzerfunktionid) && $this->setBenutzerfunktion_id($data->benutzerfunktionid); + isset($data->benutzerfunktion_id) && $this->setBenutzerfunktion_id($data->benutzerfunktion_id); + isset($data->funktion) && isset($data->orget) + && isset($data->mitarbeiter_uid) && $this->createBenutzerfunktionData($data); + isset($data->funktion_bezeichnung) && isset($data->oe_bezeichnung) + && $this->createBenutzerfunktionData4Display($data); + $this->fromdb = false; + + } + + public function getBenutzerfunktion_id() + { + return $this->benutzerfunktion_id; + } + + public function setBenutzerfunktion_id($benutzerfunktion_id) + { + $this->markDirty('benutzerfunktion_id', $this->benutzerfunktion_id, $benutzerfunktion_id); + $this->benutzerfunktion_id = $benutzerfunktion_id; + return $this; + } + + protected function getBenutzerfunktionData4Insert() + { + if( null === $this->benutzerfunktiondata ) { + return null; + } + + $benutzerfunktiondata = (object) array( + 'funktion_kurzbz' => $this->benutzerfunktiondata->funktion_kurzbz, + 'oe_kurzbz' => $this->benutzerfunktiondata->oe_kurzbz, + 'uid' => $this->benutzerfunktiondata->uid, + 'datum_von' => $this->getVon(), + 'datum_bis' => $this->getBis(), + 'insertamum' => strftime('%Y-%m-%d %H:%M:%S'), + 'insertvon' => getAuthUID() + ); + + return $benutzerfunktiondata; + } + + protected function createBenutzerfunktionData($data) + { + if( empty($data->funktion) || empty($data->orget) ) + { + return; + } + + $this->benutzerfunktiondata = (object) array( + 'funktion_kurzbz' => $data->funktion, + 'oe_kurzbz' => $data->orget, + 'uid' => $data->mitarbeiter_uid + ); + } + + protected function createBenutzerfunktionData4Display($data) + { + if( empty($data->funktion_bezeichnung) || empty($data->oe_bezeichnung) ) + { + return; + } + + $this->benutzerfunktiondata = (object) array( + 'funktion_kurzbz' => $data->funktion_kurzbz, + 'funktion_bezeichnung' => $data->funktion_bezeichnung, + 'oe_kurzbz' => $data->oe_kurzbz, + 'oe_bezeichnung' => $data->oe_bezeichnung, + 'oe_kurzbz_sap' => $data->oe_kurzbz_sap, + 'oe_typ_kurzbz' => $data->oe_typ_kurzbz, + 'oe_typ_bezeichnung' => $data->oe_typ_bezeichnung, + 'uid' => $data->mitarbeiter_uid + ); + } + + public function validate() + { + if( (intval($this->benutzerfunktion_id) < 1) + && ($this->benutzerfunktiondata === NULL) ) { + $this->validationerrors[] = 'Eine bestehende Funktion oder eine ' + . 'Funktion und eine Organisationseinheit müssen ausgewählt sein.'; + } + + // TODO check if Benutzerfunktion is assigned to another vb + if( intval($this->benutzerfunktion_id) > 0 ) + { + if ( $this->CI->VertragsbestandteilFunktionModel + ->isBenutzerfunktionAlreadyAttachedToAnotherVB( + $this->benutzerfunktion_id, + $this->getVertragsbestandteil_id()) ) + { + $this->validationerrors[] = 'Die Benutzerfunktion ist bereits ' + . 'mit einem anderen Vertragsbestandteil verknüpft und kann ' + . 'nicht mehrfach verknüft werden.'; + } + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilKarenz.php b/application/libraries/vertragsbestandteil/VertragsbestandteilKarenz.php new file mode 100644 index 000000000..7b49bfe4c --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilKarenz.php @@ -0,0 +1,141 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_KARENZ); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->karenztyp_kurzbz) && $this->setKarenztypKurzbz($data->karenztyp_kurzbz); + isset($data->geplanter_geburtstermin) && $this->setGeplanterGeburtstermin($data->geplanter_geburtstermin); + isset($data->tatsaechlicher_geburtstermin) && $this->setTatsaechlicherGeburtstermin($data->tatsaechlicher_geburtstermin); + $this->fromdb = false; + } + + /** + * Get the value of karenztyp_kurzbz + */ + public function getKarenztypKurzbz() + { + return $this->karenztyp_kurzbz; + } + + /** + * Set the value of karenztyp_kurzbz + */ + public function setKarenztypKurzbz($karenztyp_kurzbz): self + { + $this->markDirty('karenztyp_kurzbz', $this->karenztyp_kurzbz, $karenztyp_kurzbz); + $this->karenztyp_kurzbz = $karenztyp_kurzbz; + + return $this; + } + + /** + * Get the value of tatsaechlicher_geburtstermin + */ + public function getTatsaechlicherGeburtstermin() + { + return $this->tatsaechlicher_geburtstermin; + } + + /** + * Set the value of tatsaechlicher_geburtstermin + */ + public function setTatsaechlicherGeburtstermin($tatsaechlicher_geburtstermin): self + { + $this->markDirty('tatsaechlicher_geburtstermin', $this->tatsaechlicher_geburtstermin, $tatsaechlicher_geburtstermin); + $this->tatsaechlicher_geburtstermin = $tatsaechlicher_geburtstermin; + + return $this; + } + + /** + * Get the value of geplanter_geburtstermin + */ + public function getGeplanterGeburtstermin() + { + return $this->geplanter_geburtstermin; + } + + /** + * Set the value of geplanter_geburtstermin + */ + public function setGeplanterGeburtstermin($geplanter_geburtstermin): self + { + $this->markDirty('geplanter_geburtstermin', $this->geplanter_geburtstermin, $geplanter_geburtstermin); + $this->geplanter_geburtstermin = $geplanter_geburtstermin; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'karenztyp_kurzbz' => $this->getKarenztypKurzbz(), + 'tatsaechlicher_geburtstermin' => $this->getTatsaechlicherGeburtstermin(), + 'geplanter_geburtstermin' => $this->getGeplanterGeburtstermin() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getKarenztypKurzbz()} + tatsaechlicher_geburtstermin: {$this->getTatsaechlicherGeburtstermin()} + geplanter_geburtstermin: {$this->getGeplanterGeburtstermin()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( empty($this->karenztyp_kurzbz) ) { + $this->validationerrors[] = 'Ein Karenztyp muss ausgewählt sein.'; + } + + if( $this->karenztyp_kurzbz === 'elternkarenz' ) { + $geplant = \DateTimeImmutable::createFromFormat('Y-m-d', $this->geplanter_geburtstermin); + $tatsaechlich = \DateTimeImmutable::createFromFormat('Y-m-d', $this->tatsaechlicher_geburtstermin); + + if( false === $geplant ) { + $this->validationerrors[] = 'Bei Elternkarenz muss der geplanter Geburtstermin ein gültiges Datum sein.'; + } + + if( !empty($this->tatsaechlicher_geburtstermin) && $tatsaechlich === false ) { + $this->validationerrors[] = 'Bei Elternkarenz muss der tatsaechliche Geburtstermin leer oder ein gültiges Datum sein.'; + } + } + + $bis = \DateTimeImmutable::createFromFormat('Y-m-d', $this->bis); + + if( false === $bis ) { + $this->validationerrors[] = 'Bei einer Karenz muss ein gültiges Ende-Datum angegeben werden.'; + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilKuendigungsfrist.php b/application/libraries/vertragsbestandteil/VertragsbestandteilKuendigungsfrist.php new file mode 100644 index 000000000..81ea0dcec --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilKuendigungsfrist.php @@ -0,0 +1,117 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_KUENDIGUNGSFRIST); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->arbeitgeber_frist) && $this->setArbeitgeberFrist($data->arbeitgeber_frist); + isset($data->arbeitnehmer_frist) && $this->setArbeitnehmerFrist($data->arbeitnehmer_frist); + $this->fromdb = false; + } + + /** + * Get the value of arbeitgeber_frist + */ + public function getArbeitgeberFrist() + { + return $this->arbeitgeber_frist; + } + + /** + * Set the value of arbeitgeber_frist + */ + public function setArbeitgeberFrist($arbeitgeber_frist): self + { + $this->markDirty('arbeitgeber_frist', $this->arbeitgeber_frist, $arbeitgeber_frist); + $this->arbeitgeber_frist = $arbeitgeber_frist; + + return $this; + } + + /** + * Get the value of arbeitnehmer_frist + */ + public function getArbeitnehmerFrist() + { + return $this->arbeitnehmer_frist; + } + + /** + * Set the value of arbeitnehmer_frist + */ + public function setArbeitnehmerFrist($arbeitnehmer_frist): self + { + $this->markDirty('arbeitnehmer_frist', $this->arbeitnehmer_frist, $arbeitnehmer_frist); + $this->arbeitnehmer_frist = $arbeitnehmer_frist; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'arbeitgeber_frist' => $this->getArbeitgeberFrist(), + 'arbeitnehmer_frist' => $this->getArbeitnehmerFrist() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getArbeitgeberFrist()} + arbeitnehmer_frist: {$this->getArbeitnehmerFrist()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( !(filter_var($this->arbeitgeber_frist, FILTER_VALIDATE_INT, + array( + 'options' => array( + 'min_range' => 0, + 'max_range' => 52 + ) + ) + )) ) { + $this->validationerrors[] = 'Arbeitgeberfrist muss eine Wochenanzahl im Bereich 1 bis 52 sein.'; + } + + if( !(filter_var($this->arbeitnehmer_frist, FILTER_VALIDATE_INT, + array( + 'options' => array( + 'min_range' => 1, + 'max_range' => 52 + ) + ) + )) ) { + $this->validationerrors[] = 'Arbeitnehmerfrist muss eine Wochenanzahl im Bereich 1 bis 52 sein.'; + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php b/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php new file mode 100644 index 000000000..8fb3900d5 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilLib.php @@ -0,0 +1,452 @@ +loggedInUser = getAuthUID(); + $this->CI = get_instance(); + $this->CI->load->model('vertragsbestandteil/Dienstverhaeltnis_model', + 'DienstverhaeltnisModel'); + $this->DienstverhaeltnisModel = $this->CI->DienstverhaeltnisModel; + $this->CI->load->model('vertragsbestandteil/Vertragsbestandteil_model', + 'VertragsbestandteilModel'); + $this->VertragsbestandteilModel = $this->CI->VertragsbestandteilModel; + $this->CI->load->library('vertragsbestandteil/GehaltsbestandteilLib', + null, 'GehaltsbestandteilLib'); + $this->GehaltsbestandteilLib = $this->CI->GehaltsbestandteilLib; + } + + public function handleGUIData($guidata, $employeeUID, $userUID) + { + $guiHandler = new GUIHandler($employeeUID, $userUID); + $ret = false; + try { + $ret = $guiHandler->handle($guidata, $employeeUID, $userUID); + } catch (Exception $ex) + { + log_message('debug', "Error handling json data from GUI. " . $ex->getMessage()); + } + + return $ret; + } + + public function fetchDienstverhaeltnis($dienstverhaeltnis_id) + { + $result = $this->DienstverhaeltnisModel->load($dienstverhaeltnis_id); + $dv = null; + if(null !== ($row = getData($result))) + { + $dv = new Dienstverhaeltnis(); + $dv->hydrateByStdClass($row[0], true); + } + return $dv; + } + + public function fetchVertragsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + { + $vbs = $this->VertragsbestandteilModel->getVertragsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); + $gbs = $this->GehaltsbestandteilLib->fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture); + + $gbsByVBid = array(); + foreach( $gbs as $gb ) + { + if( intval($gb->getVertragsbestandteil_id()) > 0 ) + { + if( !isset($gbsByVBid[$gb->getVertragsbestandteil_id()]) + || !is_array($gbsByVBid[$gb->getVertragsbestandteil_id()]) ) { + $gbsByVBid[$gb->getVertragsbestandteil_id()] = array(); + } + $gbsByVBid[$gb->getVertragsbestandteil_id()][] = $gb; + } + } + + foreach ($vbs as $vb) + { + if( isset($gbsByVBid[$vb->getVertragsbestandteil_id()]) ) + { + $vb->setGehaltsbestandteile($gbsByVBid[$vb->getVertragsbestandteil_id()]); + } + } + + return $vbs; + } + + public function fetchVertragsbestandteil($vertragsbestandteil_id) + { + return $this->VertragsbestandteilModel->getVertragsbestandteil($vertragsbestandteil_id); + } + + public function storeDienstverhaeltnis(Dienstverhaeltnis $dv) + { + if( intval($dv->getDienstverhaeltnis_id()) > 0 ) + { + $this->updateDienstverhaeltnis($dv); + } + else + { + $this->insertDienstverhaeltnis($dv); + } + } + + public function storeVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($vertragsbestandteil->getVertragsbestandteil_id()) > 0 ) + { + $this->updateVertragsbestandteil($vertragsbestandteil); + } + else + { + $this->insertVertragsbestandteil($vertragsbestandteil); + } + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + catch (Exception $ex) + { + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + throw new Exception('Storing Vertragsbestandteil failed.'); + } + } + + public function deleteDienstverhaeltnis(Dienstverhaeltnis $dv) + { + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($dv->getDienstverhaeltnis_id()) > 0 ) + { + $vbs = $this->fetchVertragsbestandteile($dv->getDienstverhaeltnis_id()); + foreach ($vbs as $vb) + { + $this->deleteVertragsbestandteil($vb); + } + + $ret = $this->DienstverhaeltnisModel->delete($dv->getDienstverhaeltnis_id()); + if(isError($ret) ) + { + log_message('debug', "Delete DV failed"); + throw new Exception('error deleting dienstverhaeltnis ' + . $dv->getDienstverhaeltnis_id()); + } + + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + } + catch (Exception $ex) + { + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + return $ex->getMessage(); + } + + return true; + + } + + public function deleteVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($vertragsbestandteil->getVertragsbestandteil_id()) > 0 ) + { + $this->deleteVertragsbestandteilHelper($vertragsbestandteil); + } + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + catch (Exception $ex) + { + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + throw new Exception('Delete Vertragsbestandteil failed.'); + } + } + + protected function insertDienstverhaeltnis(Dienstverhaeltnis $dv) + { + $dv->setInsertvon($this->loggedInUser) + ->setInsertamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->DienstverhaeltnisModel->insert($dv->toStdClass()); + if( hasData($ret) ) + { + $dv->setDienstverhaeltnis_id(getData($ret)); + } + else + { + throw new Exception('error inserting dienstverhaeltnis'); + } + } + + protected function insertVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + $vertragsbestandteil->setInsertvon($this->loggedInUser) + ->setInsertamum(strftime('%Y-%m-%d %H:%M:%S')); + $vertragsbestandteil->beforePersist(); + $ret = $this->VertragsbestandteilModel->insert($vertragsbestandteil->baseToStdClass()); + if( hasData($ret) ) + { + $vertragsbestandteil->setVertragsbestandteil_id(getData($ret)); + } + else + { + throw new Exception('error inserting vertragsbestandteil'); + } + + $specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel( + $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + $retspecial = $specialisedModel->insert($vertragsbestandteil->toStdClass()); + + if(isError($retspecial) ) + { + throw new Exception('error updating vertragsbestandteil ' + . $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + } + + try + { + $gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile(); + $this->GehaltsbestandteilLib->storeGehaltsbestandteile($gehaltsbestandteile); + } + catch(Exception $ex) + { + throw new Exception('VertragsbestandteilLib insertVertragsbestandteil ' + . 'failed to store Gehaltsbestandteile. ' . $ex->getMessage()); + } + } + + protected function updateDienstverhaeltnis(Dienstverhaeltnis $dv) + { + if(!$dv->isDirty()) { + return; + } + + $dv->setUpdatevon($this->loggedInUser) + ->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S')); + $ret = $this->DienstverhaeltnisModel->update($dv->getDienstverhaeltnis_id(), + $dv->toStdClass()); + if(isError($ret) ) + { + throw new Exception('error updating dienstverhaeltnis'); + } + } + + private function deleteVertragsbestandteilHelper(Vertragsbestandteil $vertragsbestandteil) + { + + $specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel( + $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + $retspecial = $specialisedModel->delete($vertragsbestandteil->getVertragsbestandteil_id()); + + if(isError($retspecial) ) + { + throw new Exception('error deleting vertragsbestandteil ' + . $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + } + + try + { + $gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile(); + $this->GehaltsbestandteilLib->deleteGehaltsbestandteile($gehaltsbestandteile); + } + catch(Exception $ex) + { + throw new Exception('VertragsbestandteilLib deleteVertragsbestandteil ' + . 'failed to delete Gehaltsbestandteile. ' . $ex->getMessage()); + } + + + $ret = $this->VertragsbestandteilModel->delete($vertragsbestandteil->getVertragsbestandteil_id()); + + if(isError($ret) ) + { + throw new Exception('error deleting vertragsbestandteil'); + } + + $vertragsbestandteil->afterDelete(); + } + + protected function updateVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil) + { + if($vertragsbestandteil->isDirty()) { + $vertragsbestandteil->setUpdatevon($this->loggedInUser) + ->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S')); + $vertragsbestandteil->beforePersist(); + $basedata = $vertragsbestandteil->baseToStdClass(); + if( count((array) $basedata) > 0 ) + { + $ret = $this->VertragsbestandteilModel->update( + $vertragsbestandteil->getVertragsbestandteil_id(), + $basedata); + + if(isError($ret) ) + { + throw new Exception('error updating vertragsbestandteil'); + } + } + + $specialisedData = $vertragsbestandteil->toStdClass(); + if( count((array) $specialisedData) > 0 ) + { + $specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel( + $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + $retspecial = $specialisedModel->update( + $vertragsbestandteil->getVertragsbestandteil_id(), + $specialisedData); + + if(isError($retspecial) ) + { + throw new Exception('error updating vertragsbestandteil ' + . $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz()); + } + } + } + + try + { + $gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile(); + $this->GehaltsbestandteilLib->storeGehaltsbestandteile($gehaltsbestandteile); + } + catch(Exception $ex) + { + throw new Exception('VertragsbestandteilLib updateVertragsbestandteil ' + . 'failed to store Gehaltsbestandteile. ' . $ex->getMessage()); + } + } + + public function isOverlappingExistingDV(Dienstverhaeltnis $dv) + { + return $this->DienstverhaeltnisModel->isOverlappingExistingDV( + $dv->getMitarbeiter_uid(), + $dv->getOe_kurzbz(), + $dv->getVon(), + $dv->getBis(), + $dv->getDienstverhaeltnis_id() + ); + } + + public function endDienstverhaeltnis(Dienstverhaeltnis $dv, $enddate) + { + if( $dv->getBis() !== null && $dv->getBis() < $enddate ) + { + return 'Dienstverhältnis ist bereits beendet.'; + } + + $this->CI->db->trans_begin(); + try + { + $this->setUIDtoPGSQL(); + if( intval($dv->getDienstverhaeltnis_id()) > 0 ) + { + $gbs = $this->GehaltsbestandteilLib->fetchGehaltsbestandteile($dv->getDienstverhaeltnis_id()); + foreach ($gbs as $gb) + { + $this->GehaltsbestandteilLib->endGehaltsbestandteil($gb, $enddate); + } + + $vbs = $this->fetchVertragsbestandteile($dv->getDienstverhaeltnis_id()); + foreach ($vbs as $vb) + { + $this->endVertragsbestandteil($vb, $enddate); + } + + $dv->setBis($enddate); + $this->updateDienstverhaeltnis($dv); + + if( $this->CI->db->trans_status() === false ) + { + log_message('debug', "Transaction failed"); + throw new Exception("Transaction failed"); + } + $this->CI->db->trans_commit(); + } + } + catch (Exception $ex) + { + log_message('debug', "end DV failed " . $dv->getDienstverhaeltnis_id()); + log_message('debug', "Transaction rolled back. " . $ex->getMessage()); + $this->CI->db->trans_rollback(); + return $ex->getMessage(); + } + return true; + } + + public function endVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil, $enddate) + { + if( $vertragsbestandteil->getBis() !== null && $vertragsbestandteil->getBis() < $enddate ) + { + return; + } + + $vertragsbestandteil->setBis($enddate); + $this->updateVertragsbestandteil($vertragsbestandteil); + } + + protected function setUIDtoPGSQL() { + $ret = $this->VertragsbestandteilModel + ->execReadOnlyQuery('SET LOCAL pv21.uid TO \'' + . $this->loggedInUser . '\''); + if(isError($ret)) + { + throw new Exception('error setting uid to pgsql'); + } + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilStunden.php b/application/libraries/vertragsbestandteil/VertragsbestandteilStunden.php new file mode 100644 index 000000000..f2d8c8081 --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilStunden.php @@ -0,0 +1,110 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->wochenstunden) && $this->setWochenstunden($data->wochenstunden); + isset($data->teilzeittyp_kurzbz) && $this->setTeilzeittyp_kurzbz($data->teilzeittyp_kurzbz); + $this->fromdb = false; + } + + public function getWochenstunden() + { + return $this->wochenstunden; + } + + public function getTeilzeittyp_kurzbz() + { + return $this->teilzeittyp_kurzbz; + } + + public function setWochenstunden($wochenstunden) + { + $this->markDirty('wochenstunden', $this->wochenstunden, $wochenstunden); + $this->wochenstunden = $wochenstunden; + return $this; + } + + public function setTeilzeittyp_kurzbz($teilzeittyp_kurzbz) + { + $teilzeittyp_kurzbz = ($teilzeittyp_kurzbz !== '') + ? $teilzeittyp_kurzbz : null; + $this->markDirty('teilzeittyp_kurzbz', $this->teilzeittyp_kurzbz, $teilzeittyp_kurzbz); + $this->teilzeittyp_kurzbz = $teilzeittyp_kurzbz; + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'wochenstunden' => $this->getWochenstunden(), + 'teilzeittyp_kurzbz' => $this->getTeilzeittyp_kurzbz() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getWochenstunden()} + teilzeittyp_kurzbz: {$this->getTeilzeittyp_kurzbz()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( false === filter_var($this->wochenstunden, FILTER_VALIDATE_FLOAT, + array( + 'options' => array( + 'min_range' => 0, + 'max_range' => 100 + ) + ) + ) ) { + $this->validationerrors[] = 'Stunden muss eine Kommazahl im Bereich 0 bis 100 sein.'; + } + else + { + if( floatval($this->wochenstunden) < floatval('0.01') && + $this->teilzeittyp_kurzbz !== 'altersteilzeit' ) + { + $this->validationerrors[] = '0 Wochenstunden ist nur in Kombination mit Altersteilzeit zulässig.'; + } + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch.php b/application/libraries/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch.php new file mode 100644 index 000000000..fe683211d --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch.php @@ -0,0 +1,83 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->tage) && $this->setTage($data->tage); + $this->fromdb = false; + } + + /** + * Get the value of tage + */ + public function getTage() + { + return $this->tage; + } + + /** + * Set the value of tage + */ + public function setTage($tage): self + { + $this->markDirty('tage', $this->tage, $tage); + $this->tage = $tage; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'tage' => $this->getTage(), + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getTage()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + if( !(filter_var($this->tage, FILTER_VALIDATE_INT, + array( + 'options' => array( + 'min_range' => 1, + 'max_range' => 50 + ) + ) + )) ) { + $this->validationerrors[] = 'Urlaubsanspruch muss eine Tagesanzahl im Bereich 1 bis 50 sein.'; + } + + return parent::validate(); + } +} diff --git a/application/libraries/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung.php b/application/libraries/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung.php new file mode 100644 index 000000000..5bbdaa36f --- /dev/null +++ b/application/libraries/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung.php @@ -0,0 +1,118 @@ +setVertragsbestandteiltyp_kurzbz( + VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG); + } + + public function hydrateByStdClass($data, $fromdb=false) + { + parent::hydrateByStdClass($data, $fromdb); + $this->fromdb = $fromdb; + isset($data->zeitaufzeichnung) && $this->setZeitaufzeichnung($data->zeitaufzeichnung); + isset($data->azgrelevant) && $this->setAzgrelevant($data->azgrelevant); + isset($data->homeoffice) && $this->setHomeoffice($data->homeoffice); + $this->fromdb = false; + } + + /** + * Get the value of zeitaufzeichnung + */ + public function getZeitaufzeichnung() + { + return $this->zeitaufzeichnung; + } + + /** + * Set the value of zeitaufzeichnung + */ + public function setZeitaufzeichnung($zeitaufzeichnung): self + { + $this->markDirty('zeitaufzeichnung', $this->zeitaufzeichnung, $zeitaufzeichnung); + $this->zeitaufzeichnung = $zeitaufzeichnung; + + return $this; + } + + /** + * Get the value of azgrelevant + */ + public function getAzgrelevant() + { + return $this->azgrelevant; + } + + /** + * Set the value of azgrelevant + */ + public function setAzgrelevant($azgrelevant): self + { + $this->markDirty('azgrelevant', $this->azgrelevant, $azgrelevant); + $this->azgrelevant = $azgrelevant; + + return $this; + } + + /** + * Get the value of homeoffice + */ + public function getHomeoffice() + { + return $this->homeoffice; + } + + /** + * Set the value of homeoffice + */ + public function setHomeoffice($homeoffice): self + { + $this->markDirty('homeoffice', $this->homeoffice, $homeoffice); + $this->homeoffice = $homeoffice; + + return $this; + } + + public function toStdClass(): \stdClass + { + $tmp = array( + 'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(), + 'zeitaufzeichnung' => $this->getZeitaufzeichnung(), + 'azgrelevant' => $this->getAzgrelevant(), + 'homeoffice' => $this->getHomeoffice() + ); + + $tmp = array_filter($tmp, function($k) { + return in_array($k, $this->modifiedcolumns); + }, ARRAY_FILTER_USE_KEY); + + return (object) $tmp; + } + + public function __toString() + { + $txt = <<getZeitaufzeichnung()} + azgrelevant: {$this->getAzgrelevant()} + homeoffice: {$this->getHomeoffice()} + +EOTXT; + return parent::__toString() . $txt; + } + + public function validate() + { + return parent::validate(); + } +} diff --git a/application/models/codex/Abschluss_model.php b/application/models/codex/Abschluss_model.php new file mode 100644 index 000000000..2907deff1 --- /dev/null +++ b/application/models/codex/Abschluss_model.php @@ -0,0 +1,30 @@ +dbTable = 'bis.tbl_abschluss'; + $this->pk = 'ausbildung_code'; + } + + public function getActiveAbschluesse($languageIndex) + { + return $this->execQuery( + ' + SELECT + ausbildung_code, bezeichnung[?], in_oesterreich + FROM + bis.tbl_abschluss + WHERE + aktiv + ORDER BY + CASE WHEN in_oesterreich THEN 0 ELSE 1 END, ausbildung_code', + array($languageIndex) + ); + } +} diff --git a/application/models/codex/Bismeldestichtag_model.php b/application/models/codex/Bismeldestichtag_model.php new file mode 100644 index 000000000..1a45f0fbd --- /dev/null +++ b/application/models/codex/Bismeldestichtag_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_bismeldestichtag'; + $this->pk = 'meldestichtag_id'; + } +} diff --git a/application/models/codex/Uhstat1daten_model.php b/application/models/codex/Uhstat1daten_model.php new file mode 100644 index 000000000..9bca44b58 --- /dev/null +++ b/application/models/codex/Uhstat1daten_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_uhstat1daten'; + $this->pk = 'uhstat1daten_id'; + } +} diff --git a/application/models/crm/Konto_model.php b/application/models/crm/Konto_model.php index 4b2a259c9..e76ed9e7a 100644 --- a/application/models/crm/Konto_model.php +++ b/application/models/crm/Konto_model.php @@ -100,8 +100,8 @@ class Konto_model extends DB_Model public function checkStudienbeitrag($uid, $stsem, $buchungstypen) { - $query = 'SELECT tbl_konto.buchungsnr, - tbl_konto.buchungsdatum + $query = 'SELECT tbl_konto.buchungsnr, + tbl_konto.buchungsdatum FROM public.tbl_konto, public.tbl_benutzer, public.tbl_student @@ -117,10 +117,47 @@ class Konto_model extends DB_Model FROM public.tbl_konto skonto WHERE skonto.buchungsnr = tbl_konto.buchungsnr_verweis OR skonto.buchungsnr_verweis = tbl_konto.buchungsnr_verweis - ) + ) ORDER BY buchungsnr DESC LIMIT 1 '; return $this->execQuery($query); } + + /** + * check if student has paid studienbeitrag for certain semester + * + * @param $person_id person_id + * @param $stsem stsem + * + * @return boolean + */ + public function checkStudienbeitragFromPerson($person_id, $stsem) + { + $this->addOrder('buchungsnr'); + $this->addLimit(1); + $result = $this->loadWhere([ + 'person_id'=>$person_id, + 'studiensemester_kurzbz' => $stsem, + 'buchungstyp_kurzbz' => 'Studiengebuehr' + ]); + + if (!getData($result)) + return false; + + $data = getData($result)[0]; + + $this->resetQuery(); + + $this->addSelect('sum(betrag) as differenz'); + $this->db->or_where('buchungsnr', $data->buchungsnr); + $this->db->or_where('buchungsnr_verweis', $data->buchungsnr); + + $result = $this->load(); + if (!getData($result)) + return false; + + $data = getData($result)[0]; + return $data->differenz >= 0; + } } diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index f39a41fda..08c081153 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -2,6 +2,10 @@ class Prestudentstatus_model extends DB_Model { + + const STATUS_ABBRECHER = 'Abbrecher'; + const STATUS_UNTERBRECHER = 'Unterbrecher'; + /** * Constructor */ @@ -226,4 +230,112 @@ class Prestudentstatus_model extends DB_Model return $this->execQuery($query, $parametersArray); } + + /** + * get Email of relevant Studiengang of prestudent + */ + public function getLastStatusWithStgEmail($prestudent_id, $studiensemester_kurzbz = '', $status_kurzbz = '') + { + $this->addSelect('tbl_prestudentstatus.*, + tbl_studienplan.bezeichnung AS studienplan_bezeichnung, + tbl_orgform.orgform_kurzbz AS orgform, + tbl_studienplan.sprache, + tbl_orgform.bezeichnung_mehrsprachig AS bezeichnung_orgform, + tbl_status.bezeichnung_mehrsprachig, + tbl_status_grund.bezeichnung_mehrsprachig AS bezeichnung_statusgrund, + tbl_studiengang.bezeichnung AS stg_bezeichnung, + tbl_studiengang.email'); + $this->addJoin('lehre.tbl_studienplan', 'studienplan_id', 'LEFT'); + $this->addJoin('lehre.tbl_studienordnung', 'studienordnung_id', 'LEFT'); + $this->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT'); + $this->addJoin('public.tbl_status', 'tbl_status.status_kurzbz = tbl_prestudentstatus.status_kurzbz'); + $this->addJoin('public.tbl_status_grund', 'statusgrund_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform', 'COALESCE(tbl_studienplan.orgform_kurzbz, ' . $this->dbTable . '.orgform_kurzbz, tbl_studiengang.orgform_kurzbz) = tbl_orgform.orgform_kurzbz', 'LEFT'); + $this->db->where('tbl_status.status_kurzbz = tbl_prestudentstatus.status_kurzbz'); + + $where = array('prestudent_id' => $prestudent_id); + if ($studiensemester_kurzbz) + $where['studiensemester_kurzbz'] = $studiensemester_kurzbz; + if ($status_kurzbz) + $where['tbl_prestudentstatus.status_kurzbz'] = $status_kurzbz; + + $this->addOrder('datum', 'DESC'); + $this->addOrder('insertamum', 'DESC'); + $this->addOrder('ext_id', 'DESC'); + $this->addLimit(1); + + return $this->loadWhere($where); + } + + public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null) + { + $this->load->config('studierendenantrag'); + + $lang = getUserLanguage(); + + $this->addSelect($this->dbTable . '.prestudent_id'); + $this->addSelect($this->dbTable . '.ausbildungssemester AS semester'); + $this->addSelect($this->dbTable . '.studiensemester_kurzbz'); + $this->addSelect('s.matrikelnr'); + $this->addSelect('ss.studienjahr_kurzbz'); + $this->addSelect('pers.vorname'); + $this->addSelect('pers.nachname'); + $this->addSelect('TRIM(CONCAT(pers.vorname, \' \', pers.nachname)) AS name'); + $this->addSelect('pers.person_id'); + $this->addSelect('g.studiengang_kz'); + $this->addSelect('g.bezeichnung'); + $this->addSelect('o.orgform_kurzbz'); + $this->addSelect( + 'o.bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=\'' . $lang . '\')] AS orgform_bezeichnung', + false + ); + + $this->addJoin('public.tbl_student s', 'prestudent_id'); + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_studiensemester ss', 'studiensemester_kurzbz'); + $this->addJoin('public.tbl_person pers', 'person_id'); + $this->addJoin('public.tbl_studiengang g', 'p.studiengang_kz=g.studiengang_kz'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, ' . $this->dbTable . '.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz'); + + $this->addOrder($this->dbTable . '.datum', 'DESC'); + $this->addOrder($this->dbTable . '.insertamum', 'DESC'); + $this->addOrder($this->dbTable . '.ext_id', 'DESC'); + + $this->addLimit(1); + + $this->db->where_in($this->dbTable . '.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist')); + + $whereArr = [ + $this->dbTable . '.prestudent_id' => $prestudent_id, + 'g.aktiv' => true + ]; + + if ($studiensemester_kurzbz !== null) + { + $whereArr[$this->dbTable. '.studiensemester_kurzbz'] = $studiensemester_kurzbz; + } + + return $this->loadWhere($whereArr); + } + + /** + * call like this: + * $this->PrestudentstatusModel->withGrund('grund_kurzbz')->update($id, $otherData); + * or: + * $this->PrestudentstatusModel->withGrund('grund_kurzbz')->insert($otherData); + * @param string $statusgrund_kurzbz + * @return object $this + */ + public function withGrund($statusgrund_kurzbz) + { + if($statusgrund_kurzbz) + $this->db->set( + 'statusgrund_id', + '(SELECT statusgrund_id FROM public.tbl_status_grund WHERE statusgrund_kurzbz =' . $this->db->escape($statusgrund_kurzbz) .')', + false + ); + + return $this; + } } diff --git a/application/models/crm/Reihungstest_model.php b/application/models/crm/Reihungstest_model.php index ec1982ea6..86ebfd0af 100644 --- a/application/models/crm/Reihungstest_model.php +++ b/application/models/crm/Reihungstest_model.php @@ -322,7 +322,7 @@ class Reihungstest_model extends DB_Model JOIN lehre.tbl_studienplan ON (tbl_prestudentstatus.studienplan_id = tbl_studienplan.studienplan_id) LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) WHERE rt_id = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL @@ -411,7 +411,7 @@ class Reihungstest_model extends DB_Model JOIN lehre.tbl_studienplan ON (tbl_prestudentstatus.studienplan_id = tbl_studienplan.studienplan_id) LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) WHERE rt.studiengang_kz = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL @@ -462,7 +462,7 @@ class Reihungstest_model extends DB_Model LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) LEFT JOIN PUBLIC.tbl_ort ON (tbl_rt_person.ort_kurzbz = tbl_ort.ort_kurzbz) WHERE rt_id = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL diff --git a/application/models/crm/Rueckstellung_model.php b/application/models/crm/Rueckstellung_model.php index d2c39ffde..c84c625eb 100644 --- a/application/models/crm/Rueckstellung_model.php +++ b/application/models/crm/Rueckstellung_model.php @@ -20,7 +20,7 @@ class Rueckstellung_model extends DB_Model $this->addLimit(1); $this->addJoin('tbl_rueckstellung_status', 'status_kurzbz'); $this->addSelect('*, - array_to_json(bezeichnung_mehrsprachig::varchar[])->>'.$language_index . 'as bezeichnung'); + array_to_json(bezeichnung_mehrsprachig::varchar[])->>'.$language_index . ' as bezeichnung'); $this->addOrder('datum_bis', 'DESC'); $where['person_id'] = $person_id; diff --git a/application/models/crm/Student_model.php b/application/models/crm/Student_model.php index 4404beb54..4b0a70b1a 100644 --- a/application/models/crm/Student_model.php +++ b/application/models/crm/Student_model.php @@ -82,4 +82,14 @@ class Student_model extends DB_Model return $result; } + + /** + * Get the FH-Email for a student (not the private kontakt email) + * @param $student_uid + * @return string + */ + public function getEmailFH($student_uid) + { + return $student_uid . '@' . DOMAIN; + } } diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index e3776c4ad..0d6ad4158 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -29,11 +29,232 @@ class Pruefung_model extends DB_Model JOIN lehre.tbl_pruefung prfg USING (student_uid) JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id) JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) - JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz + JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz WHERE pers.person_id = ? AND le.studiensemester_kurzbz = ? ORDER BY prfg.datum, pruefung_id'; return $this->execQuery($qry, array($person_id, $studiensemester_kurzbz)); } + + + /** + * NOTE(chris): not used + * @return string + */ + protected function loadWhereThreeExamsFailed() + { + $this->load->config('studierendenantrag'); + + $this->dbTable = 'lehre.tbl_pruefung p'; + + $sprache_index = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->addSelect('max(p.datum) as datum'); + $this->addSelect('pers.vorname'); + $this->addSelect('pers.nachname'); + $this->addSelect('pers.person_id'); + $this->addSelect('s.matrikelnr'); + $this->addSelect('g.bezeichnung'); + $this->addSelect('g.studiengang_kz'); + $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sprache_index . ')] AS orgform', false); + $this->addSelect('ps.prestudent_id'); + $this->addSelect('lv.bezeichnung as lvbezeichnung'); + $this->addSelect('le.studiensemester_kurzbz'); + $this->addSelect('a.typ'); + $this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status'); + $this->addSelect('count(1) as count'); + + $this->addGroupBy([ + 'pers.vorname', + 'pers.nachname', + 'pers.person_id', + 's.matrikelnr', + 'g.bezeichnung', + 'g.studiengang_kz', + 'o.bezeichnung_mehrsprachig', + 'ps.prestudent_id', + 'lv.bezeichnung', + 'le.studiensemester_kurzbz', + 'a.typ', + 'a.studierendenantrag_id' + ]); + $this->addJoin('lehre.tbl_note n', 'note'); + $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + $this->addJoin('public.tbl_student s', 'student_uid'); + $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); + $this->addJoin('public.tbl_person pers', 'person_id'); + $this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid'); + $this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz'); + $this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz'); + $this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false); + + $this->db->where("n.positiv", false); + /* $this->db->where_in("p.pruefungstyp_kurzbz1", ['kommPruef','zusKommPruef']);*/ + $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist')); + + $this->db->where("g.aktiv", true); + + $this->db->where('lv.studiengang_kz not in( + SELECT ps.studiengang_kz + FROM + public.tbl_prestudent ps1 + JOIN public.tbl_prestudentstatus pss USING (prestudent_id) + WHERE pss.statusgrund_id in ? + AND ps.prestudent_id = ps1.prestudent_id)', null, false); + + // NOTE(chris): is Wiederholer without set statusgrund (legacy?) + $this->db->where( + '(SELECT COUNT(*) + FROM (SELECT DISTINCT studiensemester_kurzbz + FROM tbl_prestudentstatus _s + WHERE ausbildungssemester=get_absem_prestudent(ps.prestudent_id, le.studiensemester_kurzbz) + AND prestudent_id=ps.prestudent_id) a) = 1', + null, + false + ); + + return $this->db->get_compiled_select($this->dbTable); + } + + /** + * @return stdClass + */ + public function loadWhereCommitteeExamsFailed() + { + $this->load->config('studierendenantrag'); + + $this->dbTable = 'lehre.tbl_pruefung p'; + + $this->addSelect('p.datum'); + + $this->addJoin('lehre.tbl_note n', 'note'); + + $this->db->where("n.positiv", false); + $note_blacklist = $this->config->item('note_blacklist_wiederholung'); + if ($note_blacklist) + $this->db->where_not_in("n.note", $note_blacklist); + $this->db->where_in("p.pruefungstyp_kurzbz", ['kommPruef','zusKommPruef']); + + $this->addOrder('p.datum', 'DESC'); + + return $this->load(); + } + + + /** + * @return void + */ + protected function withDetailsForStudierendenAntrag() + { + $this->load->config('studierendenantrag'); + + $sprache_index = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->addSelect('pers.vorname'); + $this->addSelect('pers.nachname'); + $this->addSelect('pers.person_id'); + $this->addSelect('s.matrikelnr'); + $this->addSelect('g.bezeichnung'); + $this->addSelect('g.studiengang_kz'); + $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sprache_index . ')] AS orgform', false); + $this->addSelect('ps.prestudent_id'); + $this->addSelect('lv.bezeichnung as lvbezeichnung'); + $this->addSelect('le.studiensemester_kurzbz'); + $this->addSelect('a.typ'); + $this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status'); + + $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + $this->addJoin('public.tbl_student s', 'student_uid'); + $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); + $this->addJoin('public.tbl_person pers', 'person_id'); + $this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid'); + $this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz'); + $this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz'); + $this->addJoin('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG), 'LEFT'); + + $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist')); + + $this->db->where("g.aktiv", true); + + $statusgruende = $this->config->item('status_gruende_wiederholer'); + if (is_array($statusgruende) && !isEmptyArray($statusgruende)) { + foreach ($statusgruende as $k => $v) { + $statusgruende[$k] = $this->db->escape($v); + } + $this->db->where('lv.studiengang_kz NOT IN( + SELECT ps1.studiengang_kz + FROM + public.tbl_prestudent ps1 + JOIN public.tbl_prestudentstatus pss USING (prestudent_id) + WHERE pss.statusgrund_id in (' . implode(',', $statusgruende) . ') + AND ps.prestudent_id = ps1.prestudent_id)', null, false); + } + } + + /** + * @param integer $prestudent_id student_uid + * + * @return stdClass + */ + public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id, $max_date = null, $studiensemester_kurzbz = null) + { + $this->withDetailsForStudierendenAntrag(); + + $this->db->where('ps.prestudent_id', $prestudent_id); + + if ($max_date !== null) { + $this->db->where('p.datum <=', $max_date); + } + if ($studiensemester_kurzbz !== null) { + $this->db->where('le.studiensemester_kurzbz', $studiensemester_kurzbz); + } + + return $this->loadWhereCommitteeExamsFailed(); + } + + /** + * @param string $status + * @param \DateTime $maxDate + * @param \DateTime $minDate + * + * @return stdClass + */ + public function getAllPrestudentsWhereCommitteeExamFailed($status, $maxDate, $minDate) + { + $this->withDetailsForStudierendenAntrag(); + + if ($maxDate) + $this->db->where("p.datum <= ", $maxDate->format('Y-m-d')); + if ($minDate) + $this->db->where("p.datum > ", $minDate->format('Y-m-d')); + + $this->db->where("b.aktiv", true); + + if (is_array($status)) { + if (in_array(null, $status)) { + $status = array_filter($status); + if (count($status)) { + $this->db->group_start(); + $this->db->where_in('campus.get_status_studierendenantrag(a.studierendenantrag_id)', $status); + $this->db->or_where('campus.get_status_studierendenantrag(a.studierendenantrag_id)', null); + $this->db->group_end(); + } else { + $this->db->where('campus.get_status_studierendenantrag(a.studierendenantrag_id)', null); + } + } else { + $this->db->where_in('campus.get_status_studierendenantrag(a.studierendenantrag_id)', $status); + } + } else { + $this->db->where('campus.get_status_studierendenantrag(a.studierendenantrag_id)', $status); + } + + return $this->loadWhereCommitteeExamsFailed(); + } } diff --git a/application/models/education/Studierendenantrag_model.php b/application/models/education/Studierendenantrag_model.php new file mode 100644 index 000000000..ea481ebef --- /dev/null +++ b/application/models/education/Studierendenantrag_model.php @@ -0,0 +1,290 @@ +dbTable = 'campus.tbl_studierendenantrag'; + $this->pk = 'studierendenantrag_id'; + + $this->load->config('studierendenantrag'); + + $this->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel'); + } + + public function loadCreatedForStudiengaenge($studiengaenge, $typ) + { + return $this->loadForStudiengaenge($studiengaenge, $typ, $this->StudierendenantragstatusModel::STATUS_CREATED); + } + + public function loadForStudiengaenge($studiengaenge, $typ = null, $status = null, $sql = null) + { + if ($sql == null) + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->addSelect('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung AS bezeichnung'); + $this->addSelect('bezeichnung_mehrsprachig[(' . $sql . ')] AS orgform', false); + $this->addSelect('s.studierendenantrag_id'); + $this->addSelect('matrikelnr'); + $this->addSelect('studienjahr_kurzbz'); + $this->addSelect('vorname'); + $this->addSelect('nachname'); + $this->addSelect('p.prestudent_id'); + $this->addSelect('p.studiengang_kz'); + $this->addSelect('semester'); + $this->addSelect($this->dbTable . '.grund'); + $this->addSelect($this->dbTable . '.datum'); + $this->addSelect('datum_wiedereinstieg'); + $this->addSelect($this->dbTable . '.typ'); + $this->addSelect('st.studierendenantrag_statustyp_kurzbz as status'); + $this->addSelect('dms_id'); + $this->addSelect('st.bezeichnung[(' . $sql . ')] as statustyp'); + + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_student', 'prestudent_id'); + $this->addJoin('public.tbl_person', 'person_id'); + $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); + $this->addJoin('public.tbl_studiensemester ss', 'studiensemester_kurzbz'); + $this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)'); + $this->addJoin( + 'campus.tbl_studierendenantrag_status as s', + 'campus.get_status_id_studierendenantrag('. $this->dbTable .'.studierendenantrag_id) = studierendenantrag_status_id' + ); + $this->addJoin('campus.tbl_studierendenantrag_statustyp as st', 'studierendenantrag_statustyp_kurzbz'); + + $this->db->where_in('p.studiengang_kz', $studiengaenge); + + $where = []; + if ($status !== null) + $where['st.studierendenantrag_statustyp_kurzbz'] = $status; + if ($typ !== null) + $where[$this->dbTable . '.typ'] = $typ; + + return $this->loadWhere($where); + } + + public function loadActiveForStudiengaenge($studiengaenge) + { + // NOTE(chris): get language before changing things in the global db object because getUserLanguage() might use it and it should not have been tampered with + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->db->group_start(); + $this->db->where_not_in('s.studierendenantrag_statustyp_kurzbz', [ + Studierendenantragstatus_model::STATUS_CANCELLED, + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_REJECTED, + Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, + Studierendenantragstatus_model::STATUS_DEREGISTERED + ]); + $this->db->or_group_start(); + $this->db->where('s.studierendenantrag_statustyp_kurzbz', Studierendenantragstatus_model::STATUS_APPROVED); + $this->db->where('tbl_studierendenantrag.typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); + $this->db->group_end(); + $this->db->group_end(); + + return $this->loadForStudiengaenge($studiengaenge, null, null, $sql); + } + + public function loadStgsWithAntraege($studiengaenge) + { + $this->addDistinct(); + $this->addSelect('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung AS bezeichnung'); + $this->addSelect('p.studiengang_kz'); + + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); + + $this->addOrder('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung'); + + $this->db->where_in('p.studiengang_kz', $studiengaenge); + + return $this->load(); + } + + public function isInStudiengang($studierendenantrag_id, $studiengaenge) + { + $this->addJoin('public.tbl_prestudent', 'prestudent_id'); + + $this->db->where_in('studiengang_kz', $studiengaenge); + + return $this->load($studierendenantrag_id); + } + + public function loadIdAndStatusWhere($where) + { + $this->addSelect('studierendenantrag_id'); + $this->addSelect('campus.get_status_studierendenantrag(studierendenantrag_id) status'); + return $this->loadWhere($where); + } + + public function loadWithStatusWhere($where, $types = null) + { + $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); + + $this->addSelect('*'); + $this->addSelect('campus.get_status_studierendenantrag(studierendenantrag_id) status'); + $this->addSelect('t.bezeichnung[(' . $lang . ')] statustyp'); + + $this->addJoin( + 'campus.tbl_studierendenantrag_statustyp t', + 'campus.get_status_studierendenantrag(studierendenantrag_id)=t.studierendenantrag_statustyp_kurzbz' + ); + + if ($types && is_array($types)) { + $this->db->where_in('typ', $types); + } + + $this->addOrder('datum', 'DESC'); + + return $this->loadWhere($where); + } + + /** + * Get the studiengang and ausbildungssemester the student was in + * for the studiensemester the antrag was committed for + * + * @param integer $antrag_id + * + * @return stdClass + */ + public function getStgAndSem($antrag_id) + { + $this->addSelect('p.studiengang_kz'); + $this->addSelect('stg.bezeichnung'); + $this->addSelect('s.ausbildungssemester'); + $this->addSelect('plan.sprache'); + $this->addSelect('COALESCE(plan.orgform_kurzbz, s.orgform_kurzbz, stg.orgform_kurzbz) AS orgform_kurzbz'); + + $this->addJoin( + 'public.tbl_prestudentstatus s', + $this->dbTable . '.prestudent_id=s.prestudent_id AND ' . $this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz' + ); + $this->addJoin('public.tbl_prestudent p', $this->dbTable . '.prestudent_id=p.prestudent_id'); + $this->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + + $this->addOrder('s.datum', 'DESC'); + $this->addOrder('s.insertamum', 'DESC'); + $this->addOrder('s.ext_id', 'DESC'); + + $this->addLimit(1); + + $this->db->where_in('s.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist')); + + return $this->loadWhere([ + $this->pk => $antrag_id + ]); + } + + /** + * Get the studiengang the student is in + * + * @param integer $antrag_id + * + * @return stdClass + */ + public function getStg($antrag_id) + { + $this->addSelect('p.studiengang_kz'); + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + + $this->addLimit(1); + + return $this->load( + $antrag_id + ); + } + + public function getStgEmail($antrag_id) + { + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_studiengang sg', 'studiengang_kz'); + $this->addSelect('sg.email'); + + return $this->load($antrag_id); + } + + public function loadForPerson($person_id) + { + $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); + $this->addSelect('stg.bezeichnung'); + $this->addSelect('bezeichnung_mehrsprachig[(' . $lang . ')] as orgform'); + $this->addSelect('p.studiengang_kz'); + $this->addSelect('st.studierendenantrag_statustyp_kurzbz as status'); + $this->addSelect('st.bezeichnung[(' . $lang . ')] as status_bezeichnung'); + $this->addSelect('p.prestudent_id'); + $this->addSelect($this->dbTable . '.studierendenantrag_id'); + $this->addSelect($this->dbTable . '.studiensemester_kurzbz'); + $this->addSelect($this->dbTable . '.datum'); + $this->addSelect($this->dbTable . '.typ'); + $this->addSelect($this->dbTable . '.insertamum'); + $this->addSelect($this->dbTable . '.insertvon'); + $this->addSelect($this->dbTable . '.datum_wiedereinstieg'); + $this->addSelect($this->dbTable . '.grund'); + $this->addSelect($this->dbTable . '.dms_id'); + $this->addSelect("(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " . $this->dbTable . ".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved", false); + + $this->addJoin('public.tbl_prestudent p', 'prestudent_id', 'RIGHT'); + $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); + $this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' . $this->dbTable . '.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' . $this->dbTable . '.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); + $this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)'); + $this->addJoin( + 'campus.tbl_studierendenantrag_statustyp st', + 'campus.get_status_studierendenantrag(studierendenantrag_id)=st.studierendenantrag_statustyp_kurzbz', + 'LEFT' + ); + + $this->db->where("(SELECT status_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=p.prestudent_id AND status_kurzbz='Student' LIMIT 1) IS NOT NULL", null, false); + + + return $this->loadWhere([ + 'p.person_id' => $person_id + ]); + } + + public function getAntraegeWhereWiedereinstiegBetween($start, $end) + { + $this->addSelect('sg.email'); + $this->addSelect('vorname'); + $this->addSelect('nachname'); + $this->addSelect($this->dbTable.'.*'); + + $this->addJoin( + 'campus.tbl_studierendenantrag_status s', + 'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id' + ); + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_person', 'person_id'); + $this->addJoin('public.tbl_studiengang sg', 'studiengang_kz'); + + $this->db->where('datum_wiedereinstieg >=', $start->format('Y-m-d')); + $this->db->where('datum_wiedereinstieg <=', $end->format('Y-m-d')); + + return $this->loadWhere([ + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, + $this->dbTable.'.typ' => self::TYP_UNTERBRECHUNG, + ]); + } + + public function getWithLastStatusWhere($where) + { + $this->addJoin( + 'campus.tbl_studierendenantrag_status s', + 'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id' + ); + + return $this->loadWhere($where); + } +} diff --git a/application/models/education/Studierendenantraglehrveranstaltung_model.php b/application/models/education/Studierendenantraglehrveranstaltung_model.php new file mode 100644 index 000000000..4318c773e --- /dev/null +++ b/application/models/education/Studierendenantraglehrveranstaltung_model.php @@ -0,0 +1,104 @@ +dbTable = 'campus.tbl_studierendenantrag_lehrveranstaltung'; + $this->pk = 'studierendenantrag_lehrveranstaltung_id'; + } + + public function insertBatch($data) + { + // Check class properties + if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); + + // DB-INSERT + $insert = $this->db->insert_batch($this->dbTable, $data); + + if ($insert) + { + return success(); + } + else + { + return error($this->db->error(), EXIT_DATABASE); + } + } + + public function deleteWhere($where) + { + if (is_null($this->dbTable)) return error('The given database table name is not valid', EXIT_MODEL); + + $delete = $this->db->delete($this->dbTable, $where); + + if ($delete) + { + return success(); + } + else + { + return error($this->db->error(), EXIT_DATABASE); + } + } + + public function getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz) + { + $this->addSelect($this->dbTable . '.*'); + $this->addSelect('a.prestudent_id'); + $this->addSelect('lv.bezeichnung as lv_bezeichnung'); + $this->addSelect('stat.insertamum as freigabedatum'); + $this->addSelect('n.bezeichnung as note_bezeichnung'); + $this->addSelect('stg.bezeichnung as stg_bezeichnung'); + + $this->addJoin('campus.tbl_studierendenantrag a', 'studierendenantrag_id'); + $this->addJoin('lehre.tbl_note n', 'note'); + $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); + $this->addJoin('public.tbl_studiengang stg', 'ps.studiengang_kz = stg.studiengang_kz'); + $this->addJoin( + 'campus.tbl_studierendenantrag_status stat', + 'stat.studierendenantrag_status_id = campus.get_status_id_studierendenantrag(a.studierendenantrag_id)' + ); + $this->addJoin('public.tbl_student s', 'prestudent_id'); + + // NOTE(chris): last offizell note + $this->addJoin('( + SELECT z.* + FROM lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs + USING(studiensemester_kurzbz) + JOIN ( + SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start + FROM lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin + USING(note) + LEFT JOIN public.tbl_studiensemester zis + USING(studiensemester_kurzbz) + WHERE zin.aktiv AND zin.offiziell + GROUP BY zi.lehrveranstaltung_id, zi.student_uid + ) zx + ON ( + z.lehrveranstaltung_id=zx.lehrveranstaltung_id + AND z.student_uid=zx.student_uid + AND zs.start = zx.start + )) z', 'z.lehrveranstaltung_id=lv.lehrveranstaltung_id AND z.student_uid=s.student_uid', 'LEFT'); + $this->addJoin('lehre.tbl_note zn', 'z.note = zn.note', 'LEFT'); + + $this->load->config('studierendenantrag'); + $note_intern_angerechntet = $this->config->item('wiederholung_note_angerechnet'); + + return $this->loadWhere([ + 'ps.prestudent_id' => $prestudent_id, + 'a.typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, + 'stat.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, + 'n.note <> ' => 0, + $this->dbTable . '.studiensemester_kurzbz' => $studiensemester_kurzbz, + '(n.note<>' . $this->db->escape($note_intern_angerechntet) . ' OR (z.note IS NOT NULL AND zn.positiv))' => null + ]); + } +} diff --git a/application/models/education/Studierendenantragstatus_model.php b/application/models/education/Studierendenantragstatus_model.php new file mode 100644 index 000000000..c134cc4ee --- /dev/null +++ b/application/models/education/Studierendenantragstatus_model.php @@ -0,0 +1,52 @@ +dbTable = 'campus.tbl_studierendenantrag_status'; + $this->pk = 'studierendenantrag_status_id'; + } + + public function loadWithTyp($studierendenantrag_status_id) + { + $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); + + $this->addSelect($this->dbTable . '.*'); + $this->addSelect('bezeichnung[(' . $lang . ')] AS typ'); + + $this->addJoin('campus.tbl_studierendenantrag_statustyp', 'studierendenantrag_statustyp_kurzbz'); + + return $this->load($studierendenantrag_status_id); + } + + public function loadWithTypWhere($where) + { + $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); + + $this->addSelect($this->dbTable . '.*'); + $this->addSelect('bezeichnung[(' . $lang . ')] AS typ'); + + $this->addJoin('campus.tbl_studierendenantrag_statustyp', 'studierendenantrag_statustyp_kurzbz'); + + return $this->loadWhere($where); + } +} diff --git a/application/models/education/Zeugnisnote_model.php b/application/models/education/Zeugnisnote_model.php index a4185a7f4..b4d909e37 100644 --- a/application/models/education/Zeugnisnote_model.php +++ b/application/models/education/Zeugnisnote_model.php @@ -102,7 +102,7 @@ class Zeugnisnote_model extends DB_Model JOIN lehre.tbl_zeugnisnote zgnisnote USING (student_uid) JOIN lehre.tbl_note note ON zgnisnote.note = note.note JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id) - JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz + JOIN public.tbl_studiengang stg ON prst.studiengang_kz = stg.studiengang_kz WHERE pers.person_id = ? AND zgnisnote.studiensemester_kurzbz = ?"; @@ -140,4 +140,83 @@ class Zeugnisnote_model extends DB_Model return $this->execQuery($qry, $params); } + + /** + * Gets courses (Zeugnisnoten) for a student. + * @param string $student_uid, + * @param string $studiensemester_kurzbz + * + * @return object + */ + public function getZeugnisnoten($student_uid, $studiensemester_kurzbz) + { + $params = array(); + $where=''; + + if ($student_uid != null) + { + $where .= " AND uid=?"; + $params[] = $student_uid; + } + if ($studiensemester_kurzbz !=null) + { + $where.=" AND vw_student_lehrveranstaltung.studiensemester_kurzbz= ?"; + $params[] = $studiensemester_kurzbz; + } + + $where2=''; + + if ($student_uid != null) + { + $where2 .= " AND student_uid=?"; + $params[] = $student_uid; + } + if ($studiensemester_kurzbz !=null) + { + $where2 .= " AND studiensemester_kurzbz= ?"; + $params[] = $studiensemester_kurzbz; + } + + $qry = "SELECT vw_student_lehrveranstaltung.lehrveranstaltung_id, uid, + vw_student_lehrveranstaltung.studiensemester_kurzbz, note, punkte, uebernahmedatum, benotungsdatum, + vw_student_lehrveranstaltung.ects, vw_student_lehrveranstaltung.semesterstunden, + tbl_zeugnisnote.updateamum, tbl_zeugnisnote.updatevon, tbl_zeugnisnote.insertamum, + tbl_zeugnisnote.insertvon, tbl_zeugnisnote.ext_id, + vw_student_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, + vw_student_lehrveranstaltung.bezeichnung_english as lehrveranstaltung_bezeichnung_english, + tbl_note.bezeichnung as note_bezeichnung, + tbl_note.positiv as note_positiv, + tbl_zeugnisnote.bemerkung as bemerkung, + vw_student_lehrveranstaltung.sort, + vw_student_lehrveranstaltung.zeugnis, + vw_student_lehrveranstaltung.studiengang_kz, + vw_student_lehrveranstaltung.lv_lehrform_kurzbz, + tbl_lehrveranstaltung.sws + FROM + ( + campus.vw_student_lehrveranstaltung LEFT JOIN lehre.tbl_zeugnisnote + ON(uid=student_uid + AND vw_student_lehrveranstaltung.studiensemester_kurzbz=tbl_zeugnisnote.studiensemester_kurzbz + AND vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_zeugnisnote.lehrveranstaltung_id + ) + ) LEFT JOIN lehre.tbl_note USING(note) + JOIN lehre.tbl_lehrveranstaltung ON(vw_student_lehrveranstaltung.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id) + WHERE true $where + + UNION + SELECT lehre.tbl_lehrveranstaltung.lehrveranstaltung_id,student_uid AS uid,studiensemester_kurzbz, note, punkte, + uebernahmedatum, benotungsdatum,lehre.tbl_lehrveranstaltung.ects,lehre.tbl_lehrveranstaltung.semesterstunden, tbl_zeugnisnote.updateamum, tbl_zeugnisnote.updatevon, tbl_zeugnisnote.insertamum, + tbl_zeugnisnote.insertvon, tbl_zeugnisnote.ext_id, lehre.tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, lehre.tbl_lehrveranstaltung.bezeichnung_english as lehrveranstaltung_bezeichnung_english, + tbl_note.bezeichnung as note_bezeichnung, tbl_note.positiv as note_positiv, tbl_zeugnisnote.bemerkung as bemerkung, tbl_lehrveranstaltung.sort, tbl_lehrveranstaltung.zeugnis, tbl_lehrveranstaltung.studiengang_kz, + tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.sws + FROM + lehre.tbl_zeugnisnote + JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) + JOIN lehre.tbl_note USING(note) + WHERE true $where2 + + ORDER BY sort"; + + return $this->execQuery($qry, $params); + } } diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index f4f8b3c9e..d232e14d6 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -511,10 +511,10 @@ class Studiengang_model extends DB_Model public function getStudiengangTyp($studiengang_kz, $typ = null) { $query = "SELECT DISTINCT(sgt.*) - FROM tbl_studiengangstyp sgt JOIN tbl_studiengang sg on sgt.typ = sg.typ + FROM tbl_studiengangstyp sgt JOIN tbl_studiengang sg on sgt.typ = sg.typ WHERE studiengang_kz IN ?"; - $params[] = $studiengang_kz; + $params = [$studiengang_kz]; if (!is_null($typ)) { @@ -524,4 +524,80 @@ class Studiengang_model extends DB_Model return $this->execQuery($query, $params); } + + /** + * @param array $studiengang_kzs + * @param array $not_antrag_typ (optional) If the prestudent has an antrag with one of the specified types it will be excluded from the result + * @param array $prestudent_stati (optional) + * + * @return stdClass + */ + public function getAktivePrestudenten($studiengang_kzs, $not_antrag_typ = null, $query = null) + { + $this->load->config('studierendenantrag'); + + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->addSelect($this->dbTable . '.studiengang_kz'); + $this->addSelect($this->dbTable . '.bezeichnung'); + $this->addSelect('o.orgform_kurzbz'); + $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sql . ')] AS orgform', false); + $this->addSelect('ps.ausbildungssemester AS semester'); + $this->addSelect('ps.studiensemester_kurzbz'); + $this->addSelect('p.prestudent_id'); + $this->addSelect('pers.vorname'); + $this->addSelect('pers.nachname'); + $this->addSelect("CONCAT(UPPER(pers.nachname), ' ', pers.vorname, ' (', " . $this->dbTable . ".bezeichnung, ')') AS name"); + + $this->addJoin('public.tbl_prestudent p', 'studiengang_kz'); + $this->addJoin( + 'public.tbl_prestudentstatus ps', + 'ps.prestudent_id=p.prestudent_id + AND ps.studiensemester_kurzbz=get_stdsem_prestudent(p.prestudent_id, NULL) + AND ps.ausbildungssemester=get_absem_prestudent(p.prestudent_id, NULL) + AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, NULL)' + ); + $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id'); + $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, ' . $this->dbTable . '.orgform_kurzbz)=o.orgform_kurzbz'); + $this->addJoin('public.tbl_person pers', 'person_id'); + $this->addJoin('public.tbl_student stud', 'p.prestudent_id=stud.prestudent_id', 'LEFT'); + + $this->db->where_in($this->dbTable . '.studiengang_kz', $studiengang_kzs); + $this->db->where_in('ps.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist')); + $this->db->where($this->dbTable . ".aktiv", true); + + if ($not_antrag_typ !== null && is_array($not_antrag_typ)) { + foreach($not_antrag_typ as $k => $v) + $not_antrag_typ[$k] = $this->db->escape($v); + $this->addJoin( + 'campus.tbl_studierendenantrag a', + 'a.prestudent_id=p.prestudent_id and a.typ in ('. + implode(',', $not_antrag_typ). + ") AND campus.get_status_studierendenantrag (a.studierendenantrag_id)<>'" . + Studierendenantragstatus_model::STATUS_CANCELLED . "'", + 'LEFT' + ); + $this->db->where('a.typ IS NULL'); + } + + if ($query) { + $query = explode(' ', $query); + $this->db->group_start(); + foreach ($query as $q) { + $this->db->group_start(); + $this->db->where('pers.vorname ILIKE', "%" . $q . "%"); + $this->db->or_where('pers.nachname ILIKE', "%" . $q . "%"); + $this->db->or_where('stud.student_uid ILIKE', "%" . $q . "%"); + $this->db->or_where($this->dbTable . '.bezeichnung ILIKE', "%" . $q . "%"); + if (is_numeric($q)) + $this->db->or_where('p.prestudent_id', $q); + $this->db->group_end(); + } + $this->db->group_end(); + } + + $this->addOrder('name'); + + return $this->load(); + } } diff --git a/application/models/organisation/Studienplan_model.php b/application/models/organisation/Studienplan_model.php index 0cc23b85d..8422f4607 100644 --- a/application/models/organisation/Studienplan_model.php +++ b/application/models/organisation/Studienplan_model.php @@ -45,7 +45,7 @@ class Studienplan_model extends DB_Model $whereArray["tbl_studienplan.sprache"] = $sprache; } - return $this->StudienplanModel->loadWhere($whereArray); + return $this->loadWhere($whereArray); } public function getStudienplanLehrveranstaltung($studienplan_id, $semester) @@ -53,6 +53,54 @@ class Studienplan_model extends DB_Model $this->addJoin('lehre.tbl_studienplan_lehrveranstaltung', 'studienplan_id'); $this->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); $this->addOrder('tbl_lehrveranstaltung.sort'); + + return $this->loadWhere(array( + 'studienplan_id' => $studienplan_id, + 'tbl_studienplan_lehrveranstaltung.semester' => $semester + )); + } + + public function getStudienplanLehrveranstaltungForPrestudent($studienplan_id, $semester, $prestudent_id) + { + $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); + $sql = 'SELECT student_uid FROM public.tbl_student WHERE prestudent_id=' . $this->escape($prestudent_id); + + $this->addSelect($this->dbTable . '.*'); + $this->addSelect('lv.*'); + $this->addSelect('COALESCE(n.bezeichnung_mehrsprachig[(' . $lang . ')], NULL) AS note'); + $this->addSelect('n.positiv'); + $this->addSelect('lehre.tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id'); + $this->addSelect('lehre.tbl_studienplan_lehrveranstaltung.sort plan_sort'); + $this->addSelect('lehre.tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent'); + + $this->addJoin('lehre.tbl_studienplan_lehrveranstaltung', 'studienplan_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + // NOTE(chris): last offizell note + $this->addJoin('( + SELECT z.* + FROM lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs + USING(studiensemester_kurzbz) + JOIN ( + SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start + FROM lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin + USING(note) + LEFT JOIN public.tbl_studiensemester zis + USING(studiensemester_kurzbz) + WHERE zin.aktiv AND zin.offiziell + GROUP BY zi.lehrveranstaltung_id, zi.student_uid + ) zx + ON ( + z.lehrveranstaltung_id=zx.lehrveranstaltung_id + AND z.student_uid=zx.student_uid + AND zs.start = zx.start + )) zn', 'zn.lehrveranstaltung_id=lv.lehrveranstaltung_id AND zn.student_uid=( ' . $sql . ')', 'LEFT'); + $this->addJoin('lehre.tbl_note n', 'n.note=zn.note', 'LEFT'); + + $this->addOrder('lehre.tbl_studienplan_lehrveranstaltung.sort'); + $this->addOrder('lv.sort'); + return $this->loadWhere(array( 'studienplan_id' => $studienplan_id, 'tbl_studienplan_lehrveranstaltung.semester' => $semester diff --git a/application/models/person/Benutzerfunktion_model.php b/application/models/person/Benutzerfunktion_model.php index 27f9b6184..e44281a92 100644 --- a/application/models/person/Benutzerfunktion_model.php +++ b/application/models/person/Benutzerfunktion_model.php @@ -180,4 +180,60 @@ class Benutzerfunktion_model extends DB_Model return $this->execQuery($query, $parameters_array); } + + + public function insertBenutzerfunktion($Json) + { + unset($Json['benutzerfunktion_id']); + unset($Json['updateamum']); + $Json['insertvon'] = getAuthUID(); + $Json['insertamum'] = $this->escape('NOW()'); + + if ($Json['datum_bis']=='') + { + unset($Json['datum_bis']); + } + + $result = $this->insert($Json); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + $record = $this->load($result->retval); + + return $record; + } + + function updateBenutzerfunktion($funktionJson) + { + $funktionJson['updatevon'] = getAuthUID(); + $funktionJson['updateamum'] = $this->escape('NOW()'); + + $result = $this->update($funktionJson['benutzerfunktion_id'], $funktionJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + $result = $this->load($funktionJson['benutzerfunktion_id']); + + return $result; + } + + function deleteBenutzerfunktion($funktionJson) + { + $result = $this->delete($funktionJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + return success($funktionJson); + } + + } diff --git a/application/models/person/Person_model.php b/application/models/person/Person_model.php index ed21082e2..88813220e 100644 --- a/application/models/person/Person_model.php +++ b/application/models/person/Person_model.php @@ -1,5 +1,22 @@ . + */ + class Person_model extends DB_Model { /** @@ -8,6 +25,7 @@ class Person_model extends DB_Model public function __construct() { parent::__construct(); + $this->dbTable = 'public.tbl_person'; $this->pk = 'person_id'; @@ -70,7 +88,7 @@ class Person_model extends DB_Model if (isset($person['svnr']) && $person['svnr'] != '') { $this->PersonModel->addOrder('svnr', 'DESC'); - $result = $this->PersonModel->loadWhere(array( + $result = $this->PersonModel->loadWhere(array( 'person_id != ' => $person['person_id'], 'SUBSTRING(svnr FROM 1 FOR 10) = ' => $person['svnr']) ); @@ -138,7 +156,8 @@ class Person_model extends DB_Model 'lower(nachname) like '.$this->db->escape('%'.$filter.'%')." OR lower(vorname) like ".$this->db->escape('%'.$filter.'%')." OR lower(nachname || ' ' || vorname) like ".$this->db->escape('%'.$filter.'%')." - OR lower(vorname || ' ' || nachname) like ".$this->db->escape('%'.$filter.'%')); + OR lower(vorname || ' ' || nachname) like ".$this->db->escape('%'.$filter.'%') + ); return $result; } @@ -152,8 +171,12 @@ class Person_model extends DB_Model */ public function getPersonStammdaten($person_id, $zustellung_only = false) { - $this->addSelect('public.tbl_person.*, tbl_person.staatsbuergerschaft AS staatsbuergerschaft_code, tbl_person.geburtsnation AS geburtsnation_code, - s.kurztext as staatsbuergerschaft, g.kurztext as geburtsnation'); + $this->addSelect('public.tbl_person.*, + tbl_person.staatsbuergerschaft AS staatsbuergerschaft_code, + tbl_person.geburtsnation AS geburtsnation_code, + s.kurztext as staatsbuergerschaft, + g.kurztext as geburtsnation' + ); $this->addJoin('bis.tbl_nation s', 'public.tbl_person.staatsbuergerschaft = s.nation_code', 'LEFT'); $this->addJoin('bis.tbl_nation g', 'public.tbl_person.geburtsnation = g.nation_code', 'LEFT'); @@ -258,7 +281,8 @@ class Person_model extends DB_Model */ public function getFullName($uid) { - if (!$result = getData($this->getByUid($uid))[0]) + $result = getData($this->getByUid($uid))[0]; + if (!$result) { show_error('Failed loading person'); } @@ -337,4 +361,18 @@ class Person_model extends DB_Model return $this->execQuery($qry, array($person_id, $person_id, $person_id)); } + + public function loadPrestudent($prestudent_id) + { + $this->addSelect($this->dbTable . '.*'); + + $this->addJoin('public.tbl_prestudent p', 'person_id'); + + $this->addLimit(1); + + return $this->loadWhere([ + 'prestudent_id' => $prestudent_id + ]); + } } + diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php index 90c30927f..900b88684 100644 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -144,10 +144,15 @@ class Mitarbeiter_model extends DB_Model * Checks if alias exists * @param $kurzbz */ - public function kurzbzExists($kurzbz) + public function kurzbzExists($kurzbz, $uid=null) { $this->addSelect('1'); - $result = $this->loadWhere(array('kurzbz' => $kurzbz)); + $where = array('kurzbz' => $kurzbz); + if ($uid != null) + { + $where['mitarbeiter_uid<>'] = $uid; + } + $result = $this->loadWhere($where); if (isSuccess($result)) { @@ -171,7 +176,6 @@ class Mitarbeiter_model extends DB_Model */ public function generateKurzbz($uid) { - $kurzbz = ''; $this->addLimit(1); $this->addSelect('vorname, nachname'); $this->addJoin('public.tbl_benutzer', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid'); @@ -181,25 +185,35 @@ class Mitarbeiter_model extends DB_Model if (hasData($nameresult)) { $kurzbzdata = getData($nameresult); - $nachname_clean = sanitizeProblemChars($kurzbzdata[0]->nachname); - $vorname_clean = sanitizeProblemChars($kurzbzdata[0]->vorname); + $genKurzbz = $this->generateKurzbzHelper($kurzbzdata[0]->vorname, $kurzbzdata[0]->nachname); - for ($nn = 6, $vn = 2; $nn != 0; $nn--, $vn++) - { - $kurzbz = mb_substr($nachname_clean, 0, $nn); - $kurzbz .= mb_substr($vorname_clean, 0, $vn); + return $genKurzbz; + } + return error('No Kurzbezeichnung could be generated'); + } - $kurzbzexists = $this->kurzbzExists($kurzbz); + public function generateKurzbzHelper($vorname, $nachname) + { + $nachname_clean = sanitizeProblemChars($nachname); + $vorname_clean = sanitizeProblemChars($vorname); + $kurzbz = ''; - if (hasData($kurzbzexists) && !getData($kurzbzexists)[0]) - break; - } + for ($nn = 6, $vn = 2; $nn != 0; $nn--, $vn++) + { + $kurzbz = mb_substr($nachname_clean, 0, $nn); + $kurzbz .= mb_substr($vorname_clean, 0, $vn); $kurzbzexists = $this->kurzbzExists($kurzbz); - if (hasData($kurzbzexists) && getData($kurzbzexists)[0]) - return error('No Kurzbezeichnung could be generated'); + if (hasData($kurzbzexists) && !getData($kurzbzexists)[0]) + break; } + + $kurzbzexists = $this->kurzbzExists($kurzbz); + + if (hasData($kurzbzexists) && getData($kurzbzexists)[0]) + return error('No Kurzbezeichnung could be generated'); + return success($kurzbz); } } diff --git a/application/models/ressource/Stundensatz_model.php b/application/models/ressource/Stundensatz_model.php new file mode 100644 index 000000000..c397d8573 --- /dev/null +++ b/application/models/ressource/Stundensatz_model.php @@ -0,0 +1,17 @@ +dbTable = 'hr.tbl_stundensatz'; + $this->pk = 'stundensatz_id'; + $this->hasSequence = true; + } + +} \ No newline at end of file diff --git a/application/models/ressource/Stundensatztyp_model.php b/application/models/ressource/Stundensatztyp_model.php new file mode 100644 index 000000000..8dfd54c7d --- /dev/null +++ b/application/models/ressource/Stundensatztyp_model.php @@ -0,0 +1,16 @@ +dbTable = 'hr.tbl_stundensatztyp'; + $this->pk = 'stundensatztyp'; + } + +} \ No newline at end of file diff --git a/application/models/system/PersonLog_model.php b/application/models/system/PersonLog_model.php index 7a66958b8..88b50487a 100644 --- a/application/models/system/PersonLog_model.php +++ b/application/models/system/PersonLog_model.php @@ -1,5 +1,22 @@ . + */ + class PersonLog_model extends DB_Model { /** @@ -17,7 +34,7 @@ class PersonLog_model extends DB_Model * @param array $data Data of Log Entry to save. * @return success object if true */ - public function insert($data) + public function insert($data, $encryptedColumns = null) { $result = $this->db->insert($this->dbTable, $data); if ($result) diff --git a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php new file mode 100644 index 000000000..5b276c55e --- /dev/null +++ b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php @@ -0,0 +1,176 @@ +dbTable = 'hr.tbl_dienstverhaeltnis'; + $this->pk = 'dienstverhaeltnis_id'; + } + + /** + * @return list of DV + */ + public function getDVByPersonUID($uid, $oe_kurzbz=null, $datum=null) + { + $result = null; + + $qry = " + SELECT + dv.dienstverhaeltnis_id, + tbl_benutzer.uid, + tbl_mitarbeiter.personalnummer, + tbl_mitarbeiter.kurzbz, + tbl_mitarbeiter.lektor, + tbl_mitarbeiter.fixangestellt, + tbl_person.person_id, + tbl_benutzer.alias, + org.oe_kurzbz, + org.bezeichnung oe_bezeichnung, + dv.von, + dv.bis, + dv.vertragsart_kurzbz, + dv.updateamum, + dv.updatevon + FROM tbl_mitarbeiter + JOIN tbl_benutzer ON tbl_mitarbeiter.mitarbeiter_uid::text = tbl_benutzer.uid::text + JOIN tbl_person USING (person_id) + JOIN hr.tbl_dienstverhaeltnis dv ON(tbl_benutzer.uid::text = dv.mitarbeiter_uid::text) + JOIN public.tbl_organisationseinheit org USING(oe_kurzbz) + WHERE tbl_benutzer.uid=?"; + $data = array($uid); + + if(!is_null($oe_kurzbz)) + { + $qry.=" AND oe_kurzbz=?"; + $data[] = $oe_kurzbz; + } + + if (!is_null($datum)) + { + $qry.=" AND ? BETWEEN dv.von AND COALESCE(dv.bis, '2999-12-31')"; + $data[] = $datum; + } + + $qry .=" + ORDER BY dv.von desc + "; + + return $this->execQuery($qry, $data); + + } + + public function getDVByID($dvid) { + $this->addSelect('hr.tbl_dienstverhaeltnis.*, public.tbl_organisationseinheit.bezeichnung as unternehmen'); + $this->addJoin('public.tbl_organisationseinheit', 'hr.tbl_dienstverhaeltnis.oe_kurzbz = public.tbl_organisationseinheit.oe_kurzbz'); + $result = $this->load($dvid); + + if (hasData($result)) { + return $result; + } + return error('could not fetch DV by ID'); + } + + + public function getCurrentDVByPersonUID($uid, $dateAsUnixTS) + { + + $date = DateTime::createFromFormat( 'U', $dateAsUnixTS ); + $datestring = $date->format("Y-m-d"); + + $qry = " + SELECT + dv.dienstverhaeltnis_id, + tbl_benutzer.uid, + tbl_mitarbeiter.personalnummer, + tbl_mitarbeiter.kurzbz, + tbl_mitarbeiter.lektor, + tbl_mitarbeiter.fixangestellt, + tbl_person.person_id, + tbl_benutzer.alias, + dv.von, + dv.bis, + dv.vertragsart_kurzbz, + dv.updateamum, + dv.updatevon + FROM tbl_mitarbeiter + JOIN tbl_benutzer ON tbl_mitarbeiter.mitarbeiter_uid::text = tbl_benutzer.uid::text + JOIN tbl_person USING (person_id) + JOIN hr.tbl_dienstverhaeltnis dv ON(tbl_benutzer.uid::text = dv.mitarbeiter_uid::text) + WHERE tbl_benutzer.uid=? and (dv.von<=? and (dv.bis is null OR dv.bis>=?)) + ORDER BY dv.von desc + "; + + return $this->execQuery($qry, array($uid, $datestring, $datestring)); + } + + public function isOverlappingExistingDV($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $dvid=null) + { + $params = array($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $von, $bis); + $dvidclause = ''; + if (intval($dvid) > 0) + { + $params = array_merge($params, array($dvid, $dvid)); + $dvidclause = <<= COALESCE(vb.von, '1970-01-01'::date) + AND + COALESCE(dv.bis::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31') + ) = 0 + AND dv.dienstverhaeltnis_id != ? +EODVIDC; + + } + + $query = <<= dv.von + AND ( + SELECT + COUNT(*) AS karenzen + FROM + hr.tbl_vertragsbestandteil vb + WHERE + vb.dienstverhaeltnis_id = dv.dienstverhaeltnis_id + AND + vb.vertragsbestandteiltyp_kurzbz = 'karenz' + AND + ?::date >= COALESCE(vb.von, '1970-01-01'::date) + AND + COALESCE(?::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31') + ) = 0 + {$dvidclause} +EOSQL; + + $ret = $this->execReadOnlyQuery($query, $params); + + if( ($dvcount = getData($ret)) && ($dvcount[0]->dvcount > 0) ) { + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php new file mode 100644 index 000000000..e9006dfc0 --- /dev/null +++ b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php @@ -0,0 +1,147 @@ +dbTable = 'hr.tbl_gehaltsbestandteil'; + $this->pk = 'gehaltsbestandteil_id'; + } + + public function getEncryptedColumns(): array + { + return array( + 'grundbetrag' => array( + DB_Model::CRYPT_CAST => 'numeric', + DB_Model::CRYPT_PASSWORD_NAME => 'ENCRYPTIONKEYGEHALT' + ), + 'betrag_valorisiert' => array( + DB_Model::CRYPT_CAST => 'numeric', + DB_Model::CRYPT_PASSWORD_NAME => 'ENCRYPTIONKEYGEHALT' + ) + ); + } + + public function getCurrentGBTByDV($dienstverhaeltnis_id, $dateAsUnixTS) + { + $date = DateTime::createFromFormat( 'U', $dateAsUnixTS ); + $datestring = $date->format("Y-m-d"); + + $qry = " + SELECT + gehaltsbestandteil_id, + gbt.von, + gbt.bis, + gbt.anmerkung, + gbt.dienstverhaeltnis_id, + gehaltstyp_kurzbz, + valorisierungssperre, + gbt.valorisierung, + grundbetrag as grund_betrag_decrypted, + betrag_valorisiert as betrag_val_decrypted, + gt.bezeichnung as gehaltstyp_bezeichnung, + vb.vertragsbestandteiltyp_kurzbz, + bf.funktion_kurzbz, + bf.oe_kurzbz, + fkt.beschreibung as fkt_beschreibung, + fb.bezeichnung as fb_bezeichnung, + org.bezeichnung as org_bezeichnung, + freitext.freitexttyp_kurzbz, + freitext.titel as freitext_titel + FROM hr.tbl_gehaltsbestandteil gbt LEFT JOIN hr.tbl_gehaltstyp gt using(gehaltstyp_kurzbz) + LEFT JOIN hr.tbl_vertragsbestandteil vb using(vertragsbestandteil_id) + LEFT JOIN hr.tbl_vertragsbestandteil_funktion vbf using(vertragsbestandteil_id) + LEFT JOIN public.tbl_benutzerfunktion bf using(benutzerfunktion_id) + LEFT JOIN public.tbl_funktion fkt using(funktion_kurzbz) + LEFT JOIN public.tbl_fachbereich fb using(fachbereich_kurzbz) + LEFT JOIN public.tbl_organisationseinheit org on (bf.oe_kurzbz=org.oe_kurzbz) + LEFT JOIN hr.tbl_vertragsbestandteil_freitext freitext on(vb.vertragsbestandteil_id=freitext.vertragsbestandteil_id) + WHERE gbt.dienstverhaeltnis_id=? AND + (gbt.von<=? and (gbt.bis is null OR gbt.bis>=?)) + ORDER BY gt.sort + "; + + return $this->execQuery($qry, + array($dienstverhaeltnis_id, $datestring, $datestring), + $this->getEncryptedColumns()); + } + + public function getGBTChartDataByDV_old($dienstverhaeltnis_id) + { + + $qry = " + WITH gbt as + (select von,bis,grundbetrag as grund_betrag_decrypted from hr.tbl_gehaltsbestandteil where dienstverhaeltnis_id=?) + select von,bis, (select sum(gbt.grund_betrag_decrypted) as sum_betrag + from gbt where gbt.von<=gbtmeta.von and (gbt.bis is null or gbt.bis>=gbtmeta.von) + ) as summe from gbt as gbtmeta order by von,bis + "; + + return $this->execQuery($qry, + array($dienstverhaeltnis_id), + $this->getEncryptedColumns()); + } + + + public function getGehaltsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false) + { + $stichtagclause = ''; + if( !is_null($stichtag) ) + { + $date = strftime('%Y-%m-%d', strtotime($stichtag)); + $stichtagclause = 'AND (' . $this->escape($date) + . ' BETWEEN COALESCE(von, \'1970-01-01\'::date)' + . ' AND COALESCE(bis, \'2170-01-01\'::date)'; + if( $includefuture ) + { + $stichtagclause .= ' OR COALESCE(von, \'1970-01-01\'::date) > ' + . $this->escape($date); + } + $stichtagclause .= ')'; + } + + $this->addSelect('*'); + $where = <<escape($dienstverhaeltnis_id)} + {$stichtagclause} +EOSQL; + + $query = $this->loadWhere( + $where, + $this->getEncryptedColumns() + ); + + $gehaltsbestandteile = array(); + if( null !== ($rows = getData($query)) ) + { + foreach( $rows as $row ) { + $tmpgb = new Gehaltsbestandteil(); + $tmpgb->hydrateByStdClass($row, true); + $gehaltsbestandteile[] = $tmpgb; + } + } + + return $gehaltsbestandteile; + } + + + public function getGehaltsbestandteil($id) + { + $this->addSelect('*'); + $query = $this->load($id, $this->getEncryptedColumns()); + $gehaltsbestandteil = null; + + if( null !== ($row = getData($query)) ) + { + $gehaltsbestandteil = new Gehaltsbestandteil(); + $gehaltsbestandteil->hydrateByStdClass($row[0], true); + } + + return $gehaltsbestandteil; + } +} diff --git a/application/models/vertragsbestandteil/IEncryption.php b/application/models/vertragsbestandteil/IEncryption.php new file mode 100644 index 000000000..ebfb437ea --- /dev/null +++ b/application/models/vertragsbestandteil/IEncryption.php @@ -0,0 +1,7 @@ +dbTable = 'hr.tbl_vertragsbestandteil_freitext'; + $this->pk = 'vertragsbestandteil_id'; + } + + public function countOverlappingVBFreitextsOfSameType(vertragsbestandteil\VertragsbestandteilFreitext $vbft) + { + $notselfclause = (intval($vbft->getVertragsbestandteil_id()) > 0) + ? 'AND v.vertragsbestandteil_id <> ' . $this->escape($vbft->getVertragsbestandteil_id()) + : ''; + $sql = <<= COALESCE(v.von, '1970-01-01'::date) + AND + ?::date <= COALESCE(v.bis, '2170-12-31') + {$notselfclause} +EOSQL; + $ret = $this->execReadOnlyQuery($sql, array( + $vbft->getDienstverhaeltnis_id(), + $vbft->getVertragsbestandteiltyp_kurzbz(), + $vbft->getFreitexttypKurzbz(), + $vbft->getBis(), + $vbft->getVon() + )); + + if( null === ($vbcount = getData($ret)) ) { + throw new Exception('failed to fetch overlappingvbs count'); + } + + return $vbcount[0]->overlappingvbs; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilFreitexttyp_model.php b/application/models/vertragsbestandteil/VertragsbestandteilFreitexttyp_model.php new file mode 100644 index 000000000..09d2380b6 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilFreitexttyp_model.php @@ -0,0 +1,12 @@ +dbTable = 'hr.tbl_vertragsbestandteil_freitexttyp'; + $this->pk = 'freitexttyp_kurzbz'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilFunktion_model.php b/application/models/vertragsbestandteil/VertragsbestandteilFunktion_model.php new file mode 100644 index 000000000..7263ac893 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilFunktion_model.php @@ -0,0 +1,35 @@ +dbTable = 'hr.tbl_vertragsbestandteil_funktion'; + $this->pk = 'vertragsbestandteil_id'; + } + + public function isBenutzerfunktionAlreadyAttachedToAnotherVB($benutzerfunktion_id, $vertragsbestandteil_id) + { + $where = array('benutzerfunktion_id' => $benutzerfunktion_id); + if( intval($vertragsbestandteil_id) > 0 ) + { + $where['vertragsbestandteil_id != '] = $vertragsbestandteil_id; + } + $this->addSelect('count(*) AS vbscount'); + $res = $this->loadWhere($where); + if(isError($res)) + { + throw new Exception('failed to check if benutzerfunktionid is already attached to another vertragsbestanteil'); + } + $count = (getData($res))[0]->vbscount; + return $count > 0; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilKarenz_model.php b/application/models/vertragsbestandteil/VertragsbestandteilKarenz_model.php new file mode 100644 index 000000000..525291439 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilKarenz_model.php @@ -0,0 +1,14 @@ +dbTable = 'hr.tbl_vertragsbestandteil_karenz'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model.php b/application/models/vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model.php new file mode 100644 index 000000000..ccb02dd88 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilKuendigungsfrist_model.php @@ -0,0 +1,14 @@ +dbTable = 'hr.tbl_vertragsbestandteil_kuendigungsfrist'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilStunden_model.php b/application/models/vertragsbestandteil/VertragsbestandteilStunden_model.php new file mode 100644 index 000000000..569c9a601 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilStunden_model.php @@ -0,0 +1,18 @@ +dbTable = 'hr.tbl_vertragsbestandteil_stunden'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilTyp_model.php b/application/models/vertragsbestandteil/VertragsbestandteilTyp_model.php new file mode 100644 index 000000000..f64cb70f4 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilTyp_model.php @@ -0,0 +1,12 @@ +dbTable = 'hr.tbl_vertragsbestandteiltyp'; + $this->pk = 'vertragsbestandteiltyp_kurzbz'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model.php b/application/models/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model.php new file mode 100644 index 000000000..561ed2932 --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilUrlaubsanspruch_model.php @@ -0,0 +1,11 @@ +dbTable = 'hr.tbl_vertragsbestandteil_urlaubsanspruch'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model.php b/application/models/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model.php new file mode 100644 index 000000000..8e2d45e1a --- /dev/null +++ b/application/models/vertragsbestandteil/VertragsbestandteilZeitaufzeichnung_model.php @@ -0,0 +1,12 @@ +dbTable = 'hr.tbl_vertragsbestandteil_zeitaufzeichnung'; + $this->pk = 'vertragsbestandteil_id'; + } +} diff --git a/application/models/vertragsbestandteil/Vertragsbestandteil_model.php b/application/models/vertragsbestandteil/Vertragsbestandteil_model.php new file mode 100644 index 000000000..6d8c18859 --- /dev/null +++ b/application/models/vertragsbestandteil/Vertragsbestandteil_model.php @@ -0,0 +1,181 @@ +dbTable = 'hr.tbl_vertragsbestandteil'; + $this->pk = 'vertragsbestandteil_id'; + } + + protected function getVertragsbestandteilSQL() + { + $sql = <<escape($date) + . ' BETWEEN COALESCE(v.von, \'1970-01-01\'::date)' + . ' AND COALESCE(v.bis, \'2170-01-01\'::date)'; + if( $includefuture ) + { + $stichtagclause .= ' OR COALESCE(v.von, \'1970-01-01\'::date) > ' + . $this->escape($date); + } + $stichtagclause .= ')'; + } + + $sql = <<getVertragsbestandteilSQL()} + WHERE + v.dienstverhaeltnis_id = {$this->escape($dienstverhaeltnis_id)} + {$stichtagclause} + ; +EOSQL; + + // echo $sql . "\n\n"; + $query = $this->execReadOnlyQuery($sql); // TODO add decryption + $data = getData($query); + + if ($data == null) + { + return array(); + } + + $vertragsbestandteile = array(); + foreach( $data as $row ) { + try + { + $vertragsbestandteile[] = VertragsbestandteilFactory::getVertragsbestandteil($row, true); + } + catch (Exception $ex) + { + echo $ex->getMessage() . "\n"; + } + } + + $dummy = json_encode($vertragsbestandteile); + return $vertragsbestandteile; + } + + + public function getVertragsbestandteil($id) + { + + $sql = <<getVertragsbestandteilSQL()} + WHERE + v.vertragsbestandteil_id = {$this->escape($id)} + ; +EOSQL; + + $query = $this->execReadOnlyQuery($sql); + + $vertragsbestandteil = null; + + if( hasData($query) ) + { + $data = getData($query)[0]; + try + { + $vertragsbestandteil = VertragsbestandteilFactory::getVertragsbestandteil($data, true); // TODO add decryption + } + catch (Exception $ex) + { + echo $ex->getMessage() . "\n"; + } + } + + return $vertragsbestandteil; + + } + + public function countOverlappingVBsOfSameType(vertragsbestandteil\Vertragsbestandteil $vb) + { + $notselfclause = (intval($vb->getVertragsbestandteil_id()) > 0) + ? 'AND v.vertragsbestandteil_id <> ' . $this->escape($vb->getVertragsbestandteil_id()) + : ''; + $sql = <<= COALESCE(v.von, '1970-01-01'::date) + AND + ?::date <= COALESCE(v.bis, '2170-12-31') + {$notselfclause} +EOSQL; + $ret = $this->execReadOnlyQuery($sql, array( + $vb->getDienstverhaeltnis_id(), + $vb->getVertragsbestandteiltyp_kurzbz(), + $vb->getBis(), + $vb->getVon() + )); + + if( null === ($vbcount = getData($ret)) ) { + throw new Exception('failed to fetch overlappingvbs count'); + } + + return $vbcount[0]->overlappingvbs; + } +} diff --git a/application/views/codex/bismeldestichtag.php b/application/views/codex/bismeldestichtag.php new file mode 100644 index 000000000..37af16cc6 --- /dev/null +++ b/application/views/codex/bismeldestichtag.php @@ -0,0 +1,75 @@ + 'Bismeldestichtage', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'filtercomponent' => true, + 'navigationcomponent' => true, + 'tabulator5' => true, + 'customCSSs' => array('vendor/vuejs/vuedatepicker_css/main.css'), + 'customJSs' => array('vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js'), + 'customJSModules' => array('public/js/apps/Bismeldestichtag/Bismeldestichtag.js') + ); + + $this->load->view('templates/FHC-Header', $includesArray); +?> +
+ + + + + + + + +
+ +
+
+ + +
+
+ +
+
+ +
+
+
+ +
+
+ + +
+
+
+
+ +load->view('templates/FHC-Footer', $includesArray); ?> diff --git a/application/views/codex/uhstat1.php b/application/views/codex/uhstat1.php new file mode 100644 index 000000000..78a30b3e5 --- /dev/null +++ b/application/views/codex/uhstat1.php @@ -0,0 +1,277 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'UHSTAT1Formular', + 'jquery3' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'phrases' => array( + 'ui' => array('speichern') + ), + 'customCSSs' => array('public/css/codex/uhstat1.css'), + 'customJSs' => array('public/js/codex/uhstat1.js') + ) +); +?> +mutter_geburtsjahr) ? $uhstatData->mutter_geburtsjahr : set_value('mutter_geburtsjahr'); +$mutter_geburtsstaat = isset($uhstatData->mutter_geburtsstaat) ? $uhstatData->mutter_geburtsstaat : set_value('mutter_geburtsstaat'); +$mutter_bildungsstaat = isset($uhstatData->mutter_bildungsstaat) ? $uhstatData->mutter_bildungsstaat : set_value('mutter_bildungsstaat'); +$mutter_bildungmax = isset($uhstatData->mutter_bildungmax) ? $uhstatData->mutter_bildungmax : set_value('mutter_bildungmax'); +$vater_geburtsjahr = isset($uhstatData->vater_geburtsjahr) ? $uhstatData->vater_geburtsjahr : set_value('vater_geburtsjahr'); +$vater_geburtsstaat = isset($uhstatData->vater_geburtsstaat) ? $uhstatData->vater_geburtsstaat : set_value('vater_geburtsstaat'); +$vater_bildungsstaat = isset($uhstatData->vater_bildungsstaat) ? $uhstatData->vater_bildungsstaat : set_value('vater_bildungsstaat'); +$vater_bildungmax = isset($uhstatData->vater_bildungmax) ? $uhstatData->vater_bildungmax : set_value('vater_bildungmax'); +$readOnly = isset($formMetaData['readOnly']); +$disabled = $readOnly ? ' disabled' : ''; +$editPermission = isset($formMetaData['editPermission']) && $formMetaData['editPermission'] === true; +$deletePermission = isset($formMetaData['deletePermission']) && $formMetaData['deletePermission'] === true; +$saved = isset($saved) && $saved === true; +?> + +
+

+ +

+
+ +

p->t('uhstat', 'uhstat1AnmeldungUeberschrift') ?>

+

+ p->t('uhstat', 'rechtsbelehrung') ?> +

+

+ p->t('uhstat', 'uhstat1AnmeldungEinleitungstext') ?> +

+

+ p->t('uhstat', 'uhstat1EinleitungSvnrtext') ?> +

+
+ + +
+ + +
+ + +
+ + +
+ ' /> +
+ p->t('uhstat', 'angabenErziehungsberechtigte') ?> +

+ p->t('uhstat', 'angabenErziehungsberechtigteEinleitungstext') ?> +

+
+

p->t('uhstat', 'erziehungsberechtigtePersonEins') ?>

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+

p->t('uhstat', 'erziehungsberechtigtePersonZwei') ?>

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+
+
+
+ +
+
+
+ +
+ +
+ ' /> +
+
+ +
+
+
+ +
+
+ +load->view('templates/FHC-Footer'); ?> diff --git a/application/views/lehre/Antrag/Create.php b/application/views/lehre/Antrag/Create.php new file mode 100644 index 000000000..2c9d0d382 --- /dev/null +++ b/application/views/lehre/Antrag/Create.php @@ -0,0 +1,54 @@ + 'Antrag auf Änderung des Studierendenstatus', + 'cis' => true, + 'vue3' => true, + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'phrases' => array( + ), + 'customJSModules' => array('public/js/apps/lehre/Antrag.js'), + 'customCSSs' => array( + 'public/css/Fhc.css', + 'vendor/vuejs/vuedatepicker_css/main.css' + ), + 'customJSs' => array( + ) +); + +$this->load->view( + 'templates/FHC-Header', + $sitesettings +); +?> + +
+
+

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

+
+ +
+
+ + +
+
+ + +
+
+
+ +load->view( + 'templates/FHC-Footer', + $sitesettings +); diff --git a/application/views/lehre/Antrag/Leitung/List.php b/application/views/lehre/Antrag/Leitung/List.php new file mode 100644 index 000000000..9c0749dae --- /dev/null +++ b/application/views/lehre/Antrag/Leitung/List.php @@ -0,0 +1,59 @@ + 'Anträge auf Änderung des Studierendenstatus', + 'cis' => true, + 'vue3' => true, + 'axios027' => true, + 'bootstrap5' => true, + 'tabulator5' => true, + 'fontawesome6' => true, + 'primevue3' => true, + 'phrases' => array( + 'global', + 'ui', + 'studierendenantrag', + 'lehre', + 'person', + ), + 'customJSModules' => array('public/js/apps/lehre/Antrag/Leitung.js'), + 'customCSSs' => array( + 'public/css/Fhc.css' + ), + 'customJSs' => array( + ) +); + +$this->load->view( + 'templates/FHC-Header', + $sitesettings +); +?> + +
+
+

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

+
+ +
+
+ + + + +
+
+
+
+
+ +load->view( + 'templates/FHC-Footer', + $sitesettings +); diff --git a/application/views/lehre/Antrag/Student/List.php b/application/views/lehre/Antrag/Student/List.php new file mode 100644 index 000000000..4ca99f951 --- /dev/null +++ b/application/views/lehre/Antrag/Student/List.php @@ -0,0 +1,139 @@ + 'Antrag auf Änderung des Studierendenstatus', + 'cis' => true, + 'vue3' => true, + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'phrases' => array( + ), + 'customJSModules' => array('public/js/apps/lehre/Antrag/Student.js'), + 'customCSSs' => array( + 'public/css/Fhc.css' + ), + 'customJSs' => array( + ) +); + +$this->load->view( + 'templates/FHC-Header', + $sitesettings +); +?> + +
+ +
+

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

+
+ +
+
+ + $array){ ?> +

()

+ + +
+

p->t('studierendenantrag', 'calltoaction_' . $type); ?>

+
+ + p->t('studierendenantrag', 'antrag_typ_' . $type); ?> + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#p->t('studierendenantrag', 'antrag_typ'); ?>p->t('studierendenantrag', 'antrag_status'); ?>p->t('studierendenantrag', 'antrag_studiensemester'); ?>p->t('studierendenantrag', 'antrag_erstelldatum'); ?>p->t('studierendenantrag', 'antrag_datum_wiedereinstieg'); ?>p->t('studierendenantrag', 'antrag_grund'); ?>p->t('studierendenantrag', 'antrag_dateianhaenge'); ?> 
studierendenantrag_id; ?>p->t('studierendenantrag', 'antrag_typ_' . $antrag->typ); ?>status_bezeichnung; ?>studiensemester_kurzbz; ?>datum))->format('d.m.Y'); ?>datum_wiedereinstieg ? (new DateTime($antrag->datum_wiedereinstieg))->format('d.m.Y') : ''; ?> + grund){ ?> + + p->t('studierendenantrag', 'antrag_grund'); ?> + + + + + + + dms_id) {?> + + p->t('studierendenantrag', 'antrag_anhang'); ?> + + + + + typ != Studierendenantrag_model::TYP_WIEDERHOLUNG && in_array($antrag->status, [ + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_OBJECTED, + Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, + Studierendenantragstatus_model::STATUS_REMINDERSENT + ])) { ?> + + + typ == Studierendenantrag_model::TYP_WIEDERHOLUNG && $antrag->status == Studierendenantragstatus_model::STATUS_APPROVED) { ?> + p->t('studierendenantrag', 'btn_show_lvs'); ?> + + p->t('studierendenantrag', 'my_lvs'); ?> + + +
+ + + + +
+
+
+
+
+ +load->view( + 'templates/FHC-Footer', + $sitesettings +); diff --git a/application/views/lehre/Antrag/Wiederholung/Student.php b/application/views/lehre/Antrag/Wiederholung/Student.php new file mode 100644 index 000000000..9c2db040e --- /dev/null +++ b/application/views/lehre/Antrag/Wiederholung/Student.php @@ -0,0 +1,41 @@ + 'Antrag Wiederholung vom Studium', + 'cis' => true, + 'vue3' => true, + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'tabulator5' => true, + 'phrases' => array( + 'ui', + 'lehre', + 'global' + ), + 'customJSModules' => array('public/js/apps/lehre/Antrag/Lvzuweisung.js'), + 'customCSSs' => array( + ), + 'customJSs' => array( + ) +); + +$this->load->view( + 'templates/FHC-Header', + $sitesettings +); +?> + +
+
+

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

+
+
+ status != Studierendenantragstatus_model::STATUS_CREATED && $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED) ? ' disabled' : ''; ?>> +
+
+ +load->view( + 'templates/FHC-Footer', + $sitesettings +); diff --git a/application/views/lehre/Antrag/Wiederholung/getLvs.rdf.php b/application/views/lehre/Antrag/Wiederholung/getLvs.rdf.php new file mode 100644 index 000000000..24eb1e23f --- /dev/null +++ b/application/views/lehre/Antrag/Wiederholung/getLvs.rdf.php @@ -0,0 +1,31 @@ + + + + + + freigabedatum); ?> + insertamum); ?> + + + studierendenantrag_lehrveranstaltung_id; ?>]]> + lehrveranstaltung_id; ?>]]> + prestudent_id; ?>]]> + insertvon; ?>]]> + studiensemester_kurzbz; ?>]]> + note; ?>]]> + format('c'); ?>]]> + format('d.m.Y'); ?>]]> + format('c'); ?>]]> + format('d.m.Y'); ?>]]> + note_bezeichnung; ?>]]> + lv_bezeichnung; ?>]]> + stg_bezeichnung; ?>]]> + + + + + + diff --git a/application/views/lehre/Antrag/Wiederholung/moveLvs.rdf.php b/application/views/lehre/Antrag/Wiederholung/moveLvs.rdf.php new file mode 100644 index 000000000..4ed31218d --- /dev/null +++ b/application/views/lehre/Antrag/Wiederholung/moveLvs.rdf.php @@ -0,0 +1,17 @@ + + + + + + + ]]> + + + + + + diff --git a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php index 92c896ce7..fcd9b953c 100644 --- a/application/views/lehre/lehrauftrag/acceptLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/acceptLehrauftragData.php @@ -142,7 +142,7 @@ FROM WHEN oe.organisationseinheittyp_kurzbz = \'Department\' THEN (\'DEP \' || oe.bezeichnung) ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung) END AS "lv_oe_kurzbz", - TRUNC(lema.semesterstunden, 1) AS "stunden", + TRUNC(lema.semesterstunden, 2) AS "stunden", TRUNC((lema.semesterstunden * lema.stundensatz), 2) AS "betrag", vertrag_id, vertragsstunden AS "vertrag_stunden", @@ -232,7 +232,7 @@ FROM SELECT pa.lehreinheit_id, lv.lehrveranstaltung_id, - pa.projektarbeit_id AS "projektarbeit_id", + pa.projektarbeit_id::text AS "projektarbeit_id", le.studiensemester_kurzbz, stg.studiengang_kz, upper(stg.typ || stg.kurzbz) AS "stg_typ_kurzbz", @@ -375,9 +375,9 @@ $filterWidgetArray = array( orgform_kurzbz: {visible: false, headerFilter:"input"}, person_id: {visible: false, headerFilter:"input"}, lv_oe_kurzbz: {visible: false, headerFilter:"input"}, - stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, + stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:2}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, - bottomCalc:"sum", bottomCalcParams:{precision:1} + bottomCalc:"sum", bottomCalcParams:{precision:2} }, betrag: {align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, diff --git a/application/views/lehre/lehrauftrag/approveLehrauftragData.php b/application/views/lehre/lehrauftrag/approveLehrauftragData.php index 0414ddbf6..4f0c61193 100644 --- a/application/views/lehre/lehrauftrag/approveLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/approveLehrauftragData.php @@ -149,7 +149,7 @@ FROM ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung) END AS "lv_oe_kurzbz", (person.nachname || \' \' || person.vorname) AS "lektor", - TRUNC(lema.semesterstunden, 1) AS "stunden", + TRUNC(lema.semesterstunden, 2) AS "stunden", lema.stundensatz, TRUNC((lema.semesterstunden * lema.stundensatz), 2) AS "betrag", vertrag_id, @@ -400,9 +400,9 @@ $filterWidgetArray = array( person_id: {visible: false, headerFilter:"input"}, lv_oe_kurzbz: {visible: false, headerFilter:"input"}, lektor: {headerFilter:"input", widthGrow: 2}, - stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, + stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:2}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, - bottomCalc:"sum", bottomCalcParams:{precision:1}}, + bottomCalc:"sum", bottomCalcParams:{precision:2}}, stundensatz: {visible: true, align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator}, betrag: {align:"right", formatter: form_formatNulltoStringNumber, diff --git a/application/views/lehre/lehrauftrag/orderLehrauftragData.php b/application/views/lehre/lehrauftrag/orderLehrauftragData.php index 5a2ad98bd..85b663d4a 100644 --- a/application/views/lehre/lehrauftrag/orderLehrauftragData.php +++ b/application/views/lehre/lehrauftrag/orderLehrauftragData.php @@ -159,7 +159,7 @@ FROM ( SELECT /* lehrauftraege also planned with dummies, therefore personalnummer is needed */ - ma.personalnummer, + ma.personalnummer::text, lema.lehreinheit_id, lv.lehrveranstaltung_id, lv.bezeichnung AS "lv_bezeichnung", @@ -179,7 +179,7 @@ FROM ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung) END AS "lv_oe_kurzbz", (person.nachname || \' \' || person.vorname) AS "lektor", - TRUNC(lema.semesterstunden, 1) AS "stunden", + TRUNC(lema.semesterstunden, 2) AS "stunden", lema.stundensatz, TRUNC((lema.semesterstunden * lema.stundensatz), 2) AS "betrag", vertrag_id, @@ -219,7 +219,7 @@ FROM (SELECT uid FROM - public.tbl_benutzer JOIN public.tbl_mitarbeiter ma + public.tbl_benutzer JOIN public.tbl_mitarbeiter ma ON tbl_benutzer.uid = ma.mitarbeiter_uid WHERE person_id = tmp_projektbetreuung.person_id @@ -272,7 +272,7 @@ FROM pa.lehreinheit_id, lv.lehrveranstaltung_id, lv.bezeichnung AS "lv_bezeichnung", - pa.projektarbeit_id AS "projektarbeit_id", + pa.projektarbeit_id::text AS "projektarbeit_id", le.studiensemester_kurzbz, stg.studiengang_kz, upper(stg.typ || stg.kurzbz) AS "stg_typ_kurzbz", @@ -414,7 +414,7 @@ $filterWidgetArray = array( row_index: {visible: false}, personalnummer: {visible: false, headerFilter:"input"}, auftrag: { - headerFilter:"input", widthGrow: 2, + headerFilter:"input", widthGrow: 2, bottomCalc:"count", bottomCalcFormatter:function(cell){return "'. ucfirst($this->p->t('global', 'anzahl')). ': " + cell.getValue();} }, stg_typ_kurzbz: {headerFilter:"input"}, @@ -432,9 +432,9 @@ $filterWidgetArray = array( person_id: {visible: false, headerFilter:"input"}, lv_oe_kurzbz: {headerFilter:"input"}, lektor: {headerFilter:"input", widthGrow: 2}, - stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1}, + stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:2}, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator, - bottomCalc:"sum", bottomCalcParams:{precision:1}}, + bottomCalc:"sum", bottomCalcParams:{precision:2}}, stundensatz: {visible: true, align:"right", formatter: form_formatNulltoStringNumber, headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator}, betrag: {align:"right", formatter: form_formatNulltoStringNumber, diff --git a/application/views/person/bpk/bpkDetails.php b/application/views/person/bpk/bpkDetails.php index 198065c24..bd6191c6a 100644 --- a/application/views/person/bpk/bpkDetails.php +++ b/application/views/person/bpk/bpkDetails.php @@ -9,7 +9,6 @@ 'jqueryui1' => true, 'ajaxlib' => true, 'tablesorter2' => true, - 'tinymce4' => true, 'sbadmintemplate3' => true, 'addons' => true, 'navigationwidget' => true, @@ -126,10 +125,18 @@
-
+ - +
diff --git a/application/views/system/infocenter/infocenterAbgewiesenData.php b/application/views/system/infocenter/infocenterAbgewiesenData.php index 2307ea87e..da816b2c7 100644 --- a/application/views/system/infocenter/infocenterAbgewiesenData.php +++ b/application/views/system/infocenter/infocenterAbgewiesenData.php @@ -31,21 +31,35 @@ $query = ' ORDER BY l.log_id DESC LIMIT 1 ) - AND '. $LOGDATA_VON .' = ( + AND ('. $LOGDATA_VON .' = ( SELECT l.insertvon FROM system.tbl_log l WHERE l.person_id = p.person_id ORDER BY l.log_id DESC LIMIT 1 ) + OR + ( + ( + SELECT l.insertvon + FROM system.tbl_log l + WHERE l.person_id = p.person_id + ORDER BY l.log_id DESC + LIMIT 1 + ) IS NULL + ) + ) AND l.zeitpunkt >= pss.insertamum ORDER BY l.log_id DESC LIMIT 1 ) AS "Nachricht", ( - SELECT SUM(konto.betrag) + SELECT + CASE + WHEN COUNT(CASE WHEN konto.betrag != 0 THEN 1 END) = 0 THEN null + ELSE SUM(konto.betrag) + END AS "Kaution" FROM public.tbl_konto konto - LEFT JOIN tbl_konto skonto ON (skonto.buchungsnr_verweis = konto.buchungsnr) WHERE konto.person_id = p.person_id AND konto.studiensemester_kurzbz = '. $STUDIENSEMESTER .' AND konto.buchungstyp_kurzbz = '. $STUDIENGEBUEHR_ANZAHLUNG .' diff --git a/application/views/system/infocenter/infocenterData.php b/application/views/system/infocenter/infocenterData.php index bb5b84479..61dc5a575 100644 --- a/application/views/system/infocenter/infocenterData.php +++ b/application/views/system/infocenter/infocenterData.php @@ -292,9 +292,12 @@ rueck.datum_bis AS "HoldDate", rueck.bezeichnung AS "Rueckstellgrund", ( - SELECT SUM(konto.betrag) + SELECT + CASE + WHEN COUNT(CASE WHEN konto.betrag != 0 THEN 1 END) = 0 THEN null + ELSE SUM(konto.betrag) + END AS "Kaution" FROM public.tbl_konto konto - LEFT JOIN tbl_konto skonto ON (skonto.buchungsnr_verweis = konto.buchungsnr) WHERE konto.person_id = p.person_id AND konto.studiensemester_kurzbz = '. $STUDIENSEMESTER .' AND konto.buchungstyp_kurzbz = '. $STUDIENGEBUEHR_ANZAHLUNG .' diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index c61bb3cd2..a8e6e3e13 100644 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -8,7 +8,7 @@ 'dialoglib' => true, 'ajaxlib' => true, 'tablesorter2' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'addons' => true, 'navigationwidget' => true, diff --git a/application/views/system/infocenter/infocenterFreigegebenData.php b/application/views/system/infocenter/infocenterFreigegebenData.php index 32315c145..8003b42e0 100644 --- a/application/views/system/infocenter/infocenterFreigegebenData.php +++ b/application/views/system/infocenter/infocenterFreigegebenData.php @@ -267,9 +267,12 @@ $query = ' LIMIT 1 ) AS "AktenId", ( - SELECT SUM(konto.betrag) + SELECT + CASE + WHEN COUNT(CASE WHEN konto.betrag != 0 THEN 1 END) = 0 THEN null + ELSE SUM(konto.betrag) + END AS "Kaution" FROM public.tbl_konto konto - LEFT JOIN tbl_konto skonto ON (skonto.buchungsnr_verweis = konto.buchungsnr) WHERE konto.person_id = p.person_id AND konto.studiensemester_kurzbz = '. $STUDIENSEMESTER .' AND konto.buchungstyp_kurzbz = '. $STUDIENGEBUEHR_ANZAHLUNG .' diff --git a/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php b/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php index e6b6d2495..7f9ee1288 100644 --- a/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php +++ b/application/views/system/infocenter/infocenterReihungstestAbsolviertData.php @@ -198,7 +198,11 @@ $query = ' LIMIT 1 ) AS "InfoCenterMitarbeiter", ( - SELECT SUM(konto.betrag) + SELECT + CASE + WHEN COUNT(CASE WHEN konto.betrag != 0 THEN 1 END) = 0 THEN null + ELSE SUM(konto.betrag) + END AS "Kaution" FROM public.tbl_konto konto WHERE konto.person_id = p.person_id AND konto.studiensemester_kurzbz = '. $STUDIENSEMESTER .' diff --git a/application/views/system/infocenter/infocenterZgvDetails.php b/application/views/system/infocenter/infocenterZgvDetails.php index 7636647ab..aefd95da0 100644 --- a/application/views/system/infocenter/infocenterZgvDetails.php +++ b/application/views/system/infocenter/infocenterZgvDetails.php @@ -10,7 +10,7 @@ 'dialoglib' => true, 'ajaxlib' => true, 'tablesorter2' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'addons' => true, 'navigationwidget' => true, @@ -131,7 +131,11 @@ p->t('infocenter', 'zgvNichtErfuellt') ?> - diff --git a/application/views/system/infocenter/zgvpruefungen.php b/application/views/system/infocenter/zgvpruefungen.php index 1d26b9d55..b021379a8 100644 --- a/application/views/system/infocenter/zgvpruefungen.php +++ b/application/views/system/infocenter/zgvpruefungen.php @@ -447,7 +447,6 @@
diff --git a/application/views/system/logs/testVBform.php b/application/views/system/logs/testVBform.php new file mode 100644 index 000000000..566abb1cb --- /dev/null +++ b/application/views/system/logs/testVBform.php @@ -0,0 +1,16 @@ + 'Test VBform', + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'customJSModules' => array('public/js/apps/vbform/vbform.js') + ); + + $this->load->view('templates/FHC-Header', $includesArray); +?> + +
+ +load->view('templates/FHC-Footer', $includesArray); ?> + diff --git a/application/views/system/messages/FAShtmlWriteTemplate.php b/application/views/system/messages/FAShtmlWriteTemplate.php new file mode 100644 index 000000000..83f895d14 --- /dev/null +++ b/application/views/system/messages/FAShtmlWriteTemplate.php @@ -0,0 +1,197 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'Write a new message or reply using templates', + 'jquery3' => true, + 'jqueryui1' => true, + 'bootstrap3' => true, + 'ajaxlib' => true, + 'fontawesome4' => true, + 'tinymce3' => true, + 'sbadmintemplate3' => true, + 'dialoglib' => true, + 'widgets' => true, + 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), + 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/fasMessageWrite.js') + ) + ); +?> + +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+   +
+ +
+
+
+
+
+
+ + +
+
+
+ + + 19 ? 19 : count($variables); + echo $this->widgetlib->widget( + 'MultipleDropdown_widget', + array('elements' => success($variables)), + array( + 'name' => 'variables[]', + 'id' => 'variables', + 'size' => $size, + 'multiple' => true + ) + ); + ?> +
+
+
+ + + 5 ? 5 : count($user_fields); + echo $this->widgetlib->widget( + 'MultipleDropdown_widget', + array('elements' => success($user_fields)), + array( + 'name' => 'user_fields[]', + 'id' => 'user_fields', + 'size' => $size, + 'multiple' => true + ) + ); + ?> +
+
+
+
+
+
+ + widgetlib->widget( + 'Vorlage_widget', + array('oe_kurzbz' => $organisationUnits, 'isAdmin' => $senderIsAdmin), + array('name' => 'vorlage', 'id' => 'vorlageDnD') + ); + ?> + +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ widgetlib->widget( + 'Dropdown_widget', + array( + 'elements' => success($recipientsArray), + 'emptyElement' => ucfirst($this->p->t('global', 'empfaenger')).'...' + ), + array( + 'name' => 'recipients[]', + 'id' => 'recipients' + ) + ); + ?> + + + p->t('ui', 'refresh')); ?> + + +
+
+
+
+
+ +
+ + + + + +
+
+
+
+ + +load->view("templates/FHC-Footer"); ?> + diff --git a/application/views/system/messages/ajaxRead.php b/application/views/system/messages/ajaxRead.php index 2cb88708e..4c1a77deb 100644 --- a/application/views/system/messages/ajaxRead.php +++ b/application/views/system/messages/ajaxRead.php @@ -12,7 +12,7 @@ 'tabulator4' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'phrases' => array('global', 'ui'), 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/read.js') diff --git a/application/views/system/messages/ajaxWrite.php b/application/views/system/messages/ajaxWrite.php index 3b1582f22..b3a598506 100644 --- a/application/views/system/messages/ajaxWrite.php +++ b/application/views/system/messages/ajaxWrite.php @@ -10,7 +10,7 @@ 'sbadmintemplate3' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'phrases' => array('global', 'ui'), 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/write.js') diff --git a/application/views/system/messages/ajaxWriteReply.php b/application/views/system/messages/ajaxWriteReply.php index 0a496c93e..08dc188fa 100644 --- a/application/views/system/messages/ajaxWriteReply.php +++ b/application/views/system/messages/ajaxWriteReply.php @@ -10,7 +10,7 @@ 'sbadmintemplate3' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'phrases' => array('global', 'ui'), 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/writeReply.js') diff --git a/application/views/system/messages/htmlWriteReply.php b/application/views/system/messages/htmlWriteReply.php index 9106d802b..d2150c1fb 100644 --- a/application/views/system/messages/htmlWriteReply.php +++ b/application/views/system/messages/htmlWriteReply.php @@ -6,7 +6,7 @@ 'jquery3' => true, 'bootstrap3' => true, 'fontawesome4' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/messageWriteReply.js') diff --git a/application/views/system/messages/htmlWriteTemplate.php b/application/views/system/messages/htmlWriteTemplate.php index 761e05f96..42a31f374 100644 --- a/application/views/system/messages/htmlWriteTemplate.php +++ b/application/views/system/messages/htmlWriteTemplate.php @@ -8,7 +8,7 @@ 'bootstrap3' => true, 'ajaxlib' => true, 'fontawesome4' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'dialoglib' => true, 'widgets' => true, diff --git a/application/views/system/vorlage/templatetextEdit.php b/application/views/system/vorlage/templatetextEdit.php index 42efc1519..cc2487959 100644 --- a/application/views/system/vorlage/templatetextEdit.php +++ b/application/views/system/vorlage/templatetextEdit.php @@ -1,5 +1,5 @@ load->view('templates/header', array('title' => 'VorlageEdit', 'tinymce4' => true, 'jsonforms' => true)); + $this->load->view('templates/header', array('title' => 'VorlageEdit', 'tinymce5' => true, 'jsonforms' => true)); ?>
diff --git a/application/views/templates/FHC-Common.php b/application/views/templates/FHC-Common.php index dd1d8ae1c..072ff1d7f 100644 --- a/application/views/templates/FHC-Common.php +++ b/application/views/templates/FHC-Common.php @@ -23,7 +23,7 @@ $tablesorter2 = isset($tablesorter2) ? $tablesorter2 : false; $tabulator4 = isset($tabulator4) ? $tabulator4 : false; $tabulator5 = isset($tabulator5) ? $tabulator5 : false; - $tinymce4 = isset($tinymce4) ? $tinymce4 : false; + $tinymce3 = isset($tinymce3) ? $tinymce3 : false; $tinymce5 = isset($tinymce5) ? $tinymce5 : false; $vue3 = isset($vue3) ? $vue3 : false; $primevue3 = isset($primevue3) ? $primevue3 : false; @@ -34,6 +34,7 @@ // Internal resources $ajaxlib = isset($ajaxlib) ? $ajaxlib : false; $bootstrapper = isset($bootstrapper) ? $bootstrapper : false; + $cis = isset($cis) ? $cis : false; $dialoglib = isset($dialoglib) ? $dialoglib : false; $filtercomponent = isset($filtercomponent) ? $filtercomponent : false; $filterwidget = isset($filterwidget) ? $filterwidget : false; @@ -43,4 +44,3 @@ $tablewidget = isset($tablewidget) ? $tablewidget : false; $udfs = isset($udfs) ? $udfs : false; $widgets = isset($widgets) ? $widgets : false; - diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index c461dd8b0..3daac26cd 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -100,14 +100,14 @@ // Tabulator 5 JS if ($tabulator5 === true) generateJSsInclude('vendor/olifolkerd/tabulator5/dist/js/tabulator.min.js'); - // Tinymce 4 JS - if ($tinymce4 === true) generateJSsInclude('vendor/tinymce/tinymce4/tinymce.min.js'); + // Tinymce 3 JS + if ($tinymce3 === true) generateJSsInclude('include/tiny_mce/tiny_mce.js'); // Tinymce 5 JS if ($tinymce5 === true) generateJSsInclude('vendor/tinymce/tinymce5/tinymce.min.js'); // Vue 3 JS - if ($vue3 === true) + if ($vue3 === true) { generateJSsInclude('vendor/vuejs/vuejs3/vue.global.prod.js'); generateJSsInclude('vendor/vuejs/vuerouter4/vue-router.global.js'); @@ -122,6 +122,11 @@ generateJSsInclude('vendor/npm-asset/primevue/column/column.min.js'); generateJSsInclude('vendor/npm-asset/primevue/calendar/calendar.min.js'); generateJSsInclude('vendor/npm-asset/primevue/skeleton/skeleton.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/timeline/timeline.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/multiselect/multiselect.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/autocomplete/autocomplete.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/overlaypanel/overlaypanel.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/datatable/datatable.min.js'); } // -------------------------------------------------------------------------------------------------------- diff --git a/application/views/templates/FHC-Header.php b/application/views/templates/FHC-Header.php index aa63541c5..ed9fa97b9 100644 --- a/application/views/templates/FHC-Header.php +++ b/application/views/templates/FHC-Header.php @@ -77,10 +77,7 @@ } // Tabulator 5 CSS - if ($tabulator5 === true) generateCSSsInclude('vendor/olifolkerd/tabulator5/dist/css/tabulator_bootstrap5.min.css'); - - // Tinymce 4 CSS - if ($tinymce4 === true) generateCSSsInclude('public/css/TinyMCE4.css'); + if ($tabulator5 === true) generateCSSsInclude('public/css/Tabulator5.css'); // Tinymce 5 CSS if ($tinymce5 === true) generateCSSsInclude('public/css/TinyMCE5.css'); @@ -118,6 +115,9 @@ // HTML Widget CSS if ($widgets === true) generateCSSsInclude('public/css/Widgets.css'); + // CIS + if ($cis === true) generateCSSsInclude('public/css/cis_bs5.css'); + // Eventually required CSS generateCSSsInclude($customCSSs); // Eventually required CSS ?> diff --git a/application/views/templates/header.php b/application/views/templates/header.php index 637eb3c7a..e75acca4f 100644 --- a/application/views/templates/header.php +++ b/application/views/templates/header.php @@ -95,7 +95,7 @@ if($jqueryV1 && $jqueryV2) show_error("Two JQuery versions used: composer and in - + diff --git a/application/views/widgets/tinymce.php b/application/views/widgets/tinymce.php index 3e2093e55..618cb4836 100644 --- a/application/views/widgets/tinymce.php +++ b/application/views/widgets/tinymce.php @@ -5,5 +5,6 @@ plugins: [], toolbar: "" }); - - < name="" style="">> + +< name="" style="">> + diff --git a/application/widgets/FilterWidget.php b/application/widgets/FilterWidget.php index 1cef91c15..45bcf7e04 100644 --- a/application/widgets/FilterWidget.php +++ b/application/widgets/FilterWidget.php @@ -1,5 +1,22 @@ . + */ + /** * To filter data using a SQL statement */ @@ -59,6 +76,8 @@ class FilterWidget extends Widget private $_sessionTimeout; // session expiring time + private $_encryptedColumns; // contains info about encrypted columns + private static $_FilterWidgetInstance; // static property that contains the instance of itself /** @@ -195,6 +214,7 @@ class FilterWidget extends Widget $this->_formatRow = null; $this->_markRow = null; $this->_checkboxes = null; + $this->_encryptedColumns = null; $this->_hideOptions = null; $this->_hideSelectFields = null; $this->_hideSelectFilters = null; @@ -252,6 +272,14 @@ class FilterWidget extends Widget $this->_additionalColumns = $args[FilterWidgetLib::ADDITIONAL_COLUMNS]; } + // Parameter is used to define the ecrypted columns + if (isset($args[FilterWidgetLib::ENCRYPTED_COLUMNS]) + && is_array($args[FilterWidgetLib::ENCRYPTED_COLUMNS]) + && count($args[FilterWidgetLib::ENCRYPTED_COLUMNS]) > 0) + { + $this->_encryptedColumns = $args[FilterWidgetLib::ENCRYPTED_COLUMNS]; + } + // Parameter is used to add use aliases for the columns fo the dataset if (isset($args[FilterWidgetLib::COLUMNS_ALIASES]) && is_array($args[FilterWidgetLib::COLUMNS_ALIASES]) @@ -441,7 +469,7 @@ class FilterWidget extends Widget ); // Then retrieve dataset from DB - $dataset = $this->filterwidgetlib->getDataset($datasetQuery); + $dataset = $this->filterwidgetlib->getDataset($datasetQuery, $this->_encryptedColumns); // Save changes into session if data are valid if (!isError($dataset)) @@ -476,7 +504,7 @@ class FilterWidget extends Widget $datasetQuery = $this->filterwidgetlib->generateDatasetQuery($this->_query, $parsedFilterJson->filters); // Then retrieve dataset from DB - $dataset = $this->filterwidgetlib->getDataset($datasetQuery); + $dataset = $this->filterwidgetlib->getDataset($datasetQuery, $this->_encryptedColumns); // Try to load the name of the filter using the PhrasesLib $filterName = $this->filterwidgetlib->getFilterName($parsedFilterJson); @@ -497,6 +525,7 @@ class FilterWidget extends Widget FilterWidgetLib::SESSION_SELECTED_FIELDS => $this->_getColumnsNames($parsedFilterJson->columns), // all the selected fields FilterWidgetLib::SESSION_COLUMNS_ALIASES => $this->_columnsAliases, // all the fields aliases FilterWidgetLib::SESSION_ADDITIONAL_COLUMNS => $this->_additionalColumns, // additional columns + FilterWidgetLib::SESSION_ENCRYPTED_COLUMNS => $this->_encryptedColumns, // encrypted columns FilterWidgetLib::SESSION_CHECKBOXES => $this->_checkboxes, // the name of the field used to build the checkboxes column FilterWidgetLib::SESSION_FILTERS => $parsedFilterJson->filters, // all the filters used to filter the dataset FilterWidgetLib::SESSION_METADATA => $this->FiltersModel->getExecutedQueryMetaData(), // the metadata of the dataset @@ -525,7 +554,7 @@ class FilterWidget extends Widget private function _setFilterMenu() { // Generates the filters structure array - $filterMenu = $this->filterwidgetlib->generateFilterMenu( + $this->filterwidgetlib->generateFilterMenu( $this->router->directory.$this->router->class.'/'.$this->router->method ); } @@ -604,7 +633,7 @@ class FilterWidget extends Widget { $columnsNames = array(); - foreach ($columns as $key => $obj) + foreach ($columns as $obj) { if (isset($obj->name)) { diff --git a/application/widgets/TableWidget.php b/application/widgets/TableWidget.php index 5a000601f..e59efce10 100644 --- a/application/widgets/TableWidget.php +++ b/application/widgets/TableWidget.php @@ -1,5 +1,22 @@ . + */ + /** * To display a table that shows data retriev by a SQL statement */ @@ -40,6 +57,8 @@ class TableWidget extends Widget private $_sessionTimeout; // session expiring time + private $_encryptedColumns; // contains info about encrypted columns + private static $_TableWidgetInstance; // static property that contains the instance of itself /** @@ -127,6 +146,7 @@ class TableWidget extends Widget $this->_datasetRepresentationOptions = null; $this->_datasetRepFieldsDefs = null; $this->_sessionTimeout = TableWidgetLib::SESSION_DEFAULT_TIMEOUT; + $this->_encryptedColumns = null; // Retrieved the required permissions parameter if present if (isset($args[TableWidgetLib::REQUIRED_PERMISSIONS])) @@ -206,6 +226,14 @@ class TableWidget extends Widget { $this->_sessionTimeout = $args[TableWidgetLib::SESSION_TIMEOUT]; } + + // Parameter is used to define the ecrypted columns + if (isset($args[TableWidgetLib::ENCRYPTED_COLUMNS]) + && is_array($args[TableWidgetLib::ENCRYPTED_COLUMNS]) + && count($args[TableWidgetLib::ENCRYPTED_COLUMNS]) > 0) + { + $this->_encryptedColumns = $args[TableWidgetLib::ENCRYPTED_COLUMNS]; + } } /** @@ -288,7 +316,7 @@ class TableWidget extends Widget $datasetQuery = $this->tablewidgetlib->generateDatasetQuery($this->_query); // Then retrieve dataset from DB - $dataset = $this->tablewidgetlib->getDataset($datasetQuery); + $dataset = $this->tablewidgetlib->getDataset($datasetQuery, $this->_encryptedColumns); // Save changes into session if data are valid if (!isError($dataset)) @@ -310,7 +338,7 @@ class TableWidget extends Widget $datasetQuery = $this->tablewidgetlib->generateDatasetQuery($this->_query); // Then retrieve dataset from DB - $dataset = $this->tablewidgetlib->getDataset($datasetQuery); + $dataset = $this->tablewidgetlib->getDataset($datasetQuery, $this->_encryptedColumns); // Save changes into session if data are valid if (!isError($dataset)) @@ -324,6 +352,7 @@ class TableWidget extends Widget TableWidgetLib::SESSION_FIELDS => $this->tablewidgetlib->getExecutedQueryListFields(), // all the fields of the dataset TableWidgetLib::SESSION_COLUMNS_ALIASES => $this->_columnsAliases, // all the fields aliases TableWidgetLib::SESSION_ADDITIONAL_COLUMNS => $this->_additionalColumns, // additional columns + TableWidgetLib::SESSION_ENCRYPTED_COLUMNS => $this->_encryptedColumns, // encrypted columns TableWidgetLib::SESSION_CHECKBOXES => $this->_checkboxes, // the name of the field used to build the checkboxes column TableWidgetLib::SESSION_METADATA => $this->tablewidgetlib->getExecutedQueryMetaData(), // the metadata of the dataset TableWidgetLib::SESSION_ROW_NUMBER => count($dataset->retval), // the number of loaded rows by this table @@ -411,24 +440,6 @@ class TableWidget extends Widget return !isset($class) ? '' : $class; } - /** - * Utility method that retrieves the name of the columns present in a table JSON definition - */ - private function _getColumnsNames($columns) - { - $columnsNames = array(); - - foreach ($columns as $key => $obj) - { - if (isset($obj->name)) - { - $columnsNames[] = $obj->name; - } - } - - return $columnsNames; - } - /** * Loads a view using the given viewName and eventually other parameters */ @@ -438,3 +449,4 @@ class TableWidget extends Widget $ci->load->view($viewName, $parameters); } } + diff --git a/cis/index.php b/cis/index.php index 38af9f50d..d490a201a 100644 --- a/cis/index.php +++ b/cis/index.php @@ -215,7 +215,13 @@ function loadampel()
- + t('menu/sucheOrtDokumentInhalt'); + else + $searchText = $p->t('menu/suchePersonOrtDokumentInhalt'); + ?> +
diff --git a/cis/private/lehre/abgabe_lektor_zusatz.php b/cis/private/lehre/abgabe_lektor_zusatz.php index 39488b6c3..b764fd556 100644 --- a/cis/private/lehre/abgabe_lektor_zusatz.php +++ b/cis/private/lehre/abgabe_lektor_zusatz.php @@ -121,15 +121,15 @@ echo ' - '.$p->t('abgabetool/kontrollierteSchlagwoerter').':* + '.$p->t('abgabetool/kontrollierteSchlagwoerter').': - '.$p->t('abgabetool/deutscheSchlagwoerter').': + '.$p->t('abgabetool/deutscheSchlagwoerter').':* - '.$p->t('abgabetool/englischeSchlagwoerter').': + '.$p->t('abgabetool/englischeSchlagwoerter').':* diff --git a/cis/private/lehre/abgabe_student.php b/cis/private/lehre/abgabe_student.php index 9b3cec6f6..2512d9831 100644 --- a/cis/private/lehre/abgabe_student.php +++ b/cis/private/lehre/abgabe_student.php @@ -124,7 +124,6 @@ $sql_query = "SELECT (SELECT nachname FROM public.tbl_person WHERE person_id=tb AND tbl_projektarbeit.student_uid=".$db->db_add_param($uid)." ORDER BY studiensemester_kurzbz desc, tbl_lehrveranstaltung.kurzbz"; -//AND tbl_projektarbeit.student_uid='$getuid' 'ie07m102'; if(!$erg=$db->db_query($sql_query)) { $errormsg=$p->t('global/fehlerBeimLesenAusDatenbank'); diff --git a/cis/private/lehre/abgabe_student_details.php b/cis/private/lehre/abgabe_student_details.php index 6575dcf70..860eb7579 100644 --- a/cis/private/lehre/abgabe_student_details.php +++ b/cis/private/lehre/abgabe_student_details.php @@ -64,7 +64,6 @@ if(!isset($_POST['uid'])) $fixtermin = false; $datum = '01.01.1980'; $kurzbz = ''; - $kontrollschlagwoerter = ''; $schlagwoerter = ''; $schlagwoerter_en = ''; $abstract = ''; @@ -88,7 +87,6 @@ else $kurzbz = (isset($_POST['kurzbz'])?$_POST['kurzbz']:''); $betreuer = (isset($_POST['betreuer'])?$_POST['betreuer']:'-1'); $sprache = (isset($_POST['sprache'])?$_POST['sprache']:'German'); - $kontrollschlagwoerter = (isset($_POST['kontrollschlagwoerter'])?$_POST['kontrollschlagwoerter']:'-1'); $schlagwoerter = (isset($_POST['schlagwoerter'])?$_POST['schlagwoerter']:'-1'); $schlagwoerter_en = (isset($_POST['schlagwoerter_en'])?$_POST['schlagwoerter_en']:'-1'); $abstract = (isset($_POST['abstract'])?$_POST['abstract']:'-1'); @@ -211,23 +209,7 @@ if($command=='add') { //zusätzliche Daten bearbeiten //Check der Eingabedaten - if(strlen($kontrollschlagwoerter)<1) - { - $error=true; - } - if(mb_strlen($kontrollschlagwoerter)>=150) - { - $kontrollschlagwoerter = mb_substr($kontrollschlagwoerter, 0, 146).'...'; - } - if(strlen($abstract)<1) - { - $error=true; - } - if(strlen($abstract_en)<1) - { - $error=true; - } - if($seitenanzahl<1) + if((strlen($schlagwoerter) < 1) || (strlen($schlagwoerter_en) < 1) || (strlen($abstract) < 1) || (strlen($abstract_en) < 1) || ($seitenanzahl < 1)) { $error=true; } @@ -237,7 +219,6 @@ if($command=='add') seitenanzahl = ".$db->db_add_param($seitenanzahl).", abgabedatum = now(), sprache = ".$db->db_add_param($sprache).", - kontrollschlagwoerter = ".$db->db_add_param($kontrollschlagwoerter).", schlagwoerter_en = ".$db->db_add_param($schlagwoerter_en).", schlagwoerter = ".$db->db_add_param($schlagwoerter).", abstract = ".$db->db_add_param($abstract).", @@ -413,19 +394,16 @@ if($command=="update" && $error!=true) $htmlstr .= " \n"; } $htmlstr .= "\n"; - $htmlstr .= ''.$p->t('abgabetool/kontrollierteSchlagwoerter').':* - - '."\n"; - $htmlstr .= ''.$p->t('abgabetool/deutscheSchlagwoerter').': - '."\n"; - $htmlstr .= ''.$p->t('abgabetool/englischeSchlagwoerter').': - '."\n"; + $htmlstr .= ''.$p->t('abgabetool/deutscheSchlagwoerter').':* + '."\n"; + $htmlstr .= ''.$p->t('abgabetool/englischeSchlagwoerter').':* + '."\n"; $htmlstr .= ''.$p->t('abgabetool/abstract').' '.$p->t('abgabetool/maxZeichen').':* - '."\n"; + '."\n"; $htmlstr .= ''.$p->t('abgabetool/abstractEng').''.$p->t('abgabetool/maxZeichen').':* - '."\n"; + '."\n"; $htmlstr .= ''.$p->t('abgabetool/seitenanzahl').':* - '."\n"; + '."\n"; $htmlstr .=" \n"; // If there are info about the signed document @@ -657,7 +635,6 @@ if($command!="add") $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; - $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; diff --git a/cis/private/lehre/pruefung/pruefungsanmeldung.json.php b/cis/private/lehre/pruefung/pruefungsanmeldung.json.php index e201fbe30..6757cf391 100644 --- a/cis/private/lehre/pruefung/pruefungsanmeldung.json.php +++ b/cis/private/lehre/pruefung/pruefungsanmeldung.json.php @@ -419,7 +419,7 @@ function saveAnmeldung($aktStudiensemester = null, $uid = null) $semCounter = $fakultaeten[1]["sem"]; break; default: - $semCounter = 2; + $semCounter = 3; break; } } diff --git a/cis/private/lehre/swd.php b/cis/private/lehre/swd.php deleted file mode 100644 index 248779aac..000000000 --- a/cis/private/lehre/swd.php +++ /dev/null @@ -1,11 +0,0 @@ - diff --git a/cis/private/pdfExport.php b/cis/private/pdfExport.php index 4535ff74d..6db6f885a 100644 --- a/cis/private/pdfExport.php +++ b/cis/private/pdfExport.php @@ -144,6 +144,8 @@ if (isset($_GET['projektarbeit_id'])) $params .= '&projektarbeit_id='. $_GET['projektarbeit_id']; if (isset($_GET['betreuerart_kurzbz'])) $params .= '&betreuerart_kurzbz='. $_GET['betreuerart_kurzbz']; +if (isset($_GET['id'])) + $params .= '&id='. $_GET['id']; // Logeintrag bei Download von Zahlungsbestaetigungen diff --git a/cis/private/profile/dokumente.php b/cis/private/profile/dokumente.php index f75529561..9e7f6bf5b 100644 --- a/cis/private/profile/dokumente.php +++ b/cis/private/profile/dokumente.php @@ -31,6 +31,7 @@ require_once('../../../include/akte.class.php'); require_once('../../../include/datum.class.php'); require_once('../../../include/benutzerberechtigung.class.php'); require_once('../../../include/webservicelog.class.php'); +require_once('../../../include/studierendenantrag.class.php'); $sprache = getSprache(); $p = new phrasen($sprache); @@ -228,6 +229,28 @@ echo '

'; // Wenn es für das übergebene Studiensemester keinen PreStudentStatus gibt, werden nur Abschlussdokumente angezeigt if (in_array($stsem, $stsem_arr)) { + $studierendenantrag = new studierendenantrag(); + if ($studierendenantrag->loadUserAntrag($student_studiengang->prestudent_id, $stsem) && $studierendenantrag->result) { + echo '

' . $p->t('studierendenantrag/antraege_header') . '

'; + echo ' + + + + + + + '; + foreach ($studierendenantrag->result as $antrag) { + $path = "../pdfExport.php?xsl=Antrag" . $antrag->typ . "&xml=Antrag" . $antrag->typ . ".xml.php&uid=" . $uid . "&id=" . $antrag->studierendenantrag_id; + echo ''; + echo ''; + echo ''; + echo ''; + } + echo '
'.$p->t('global/name').'
' . $p->t('studierendenantrag/title_' . $antrag->typ) . '
'; + } + + $konto = new konto(); $buchungstypen = array(); diff --git a/cis/private/profile/index.php b/cis/private/profile/index.php index ed3295287..26312d5be 100644 --- a/cis/private/profile/index.php +++ b/cis/private/profile/index.php @@ -276,15 +276,22 @@ if (!$ansicht) { if ($type === 'mitarbeiter') { - $verwendung = new bisverwendung(); - if($verwendung->getLastVerwendung($uid)) + if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT) { - if (!$verwendung->hauptberuflich) - { - echo 'Hauptberuf: '. $verwendung->hauptberuf; - } + // TODO Hauptberuf wieder anzeigen sobald verfuegbar } - echo "

"; + else + { + $verwendung = new bisverwendung(); + if($verwendung->getLastVerwendung($uid)) + { + if (!$verwendung->hauptberuflich) + { + echo 'Hauptberuf: '. $verwendung->hauptberuf; + } + } + echo "

"; + } } } @@ -606,9 +613,36 @@ function printFunctionsTable($query, $headingphrase, $tableid, $showVertragsstun if ($showVertragsstunden === true && $adminOrOwnUser) { $vertragsstunden = 0.00; - $qry = "SELECT sum(vertragsstunden) AS vertragsstdsumme from bis.tbl_bisverwendung - WHERE mitarbeiter_uid = ".$db->db_add_param($uid)." - AND (ende > now() OR ende IS NULL)"; + if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT) + { + $qry = "SELECT + sum(wochenstunden) AS vertragsstdsumme + FROM + hr.tbl_vertragsbestandteil_stunden vbs + JOIN + hr.tbl_vertragsbestandteil vb USING(vertragsbestandteil_id) + JOIN + hr.tbl_dienstverhaeltnis dv USING(dienstverhaeltnis_id) + WHERE + dv.mitarbeiter_uid = ".$db->db_add_param($uid)." + AND NOW() BETWEEN COALESCE(vb.von, '1970-01-01'::date) AND COALESCE(vb.bis, '2170-12-31'::date) + AND NOT EXISTS ( + SELECT + 1 + FROM + hr.tbl_vertragsbestandteil + WHERE + dienstverhaeltnis_id = dv.dienstverhaeltnis_id + AND vertragsbestandteiltyp_kurzbz = 'karenz' + AND NOW() BETWEEN COALESCE(von, '1970-01-01'::date) AND COALESCE(bis, '2170-12-31'::date) + )"; + } + else + { + $qry = "SELECT sum(vertragsstunden) AS vertragsstdsumme from bis.tbl_bisverwendung + WHERE mitarbeiter_uid = ".$db->db_add_param($uid)." + AND (ende > now() OR ende IS NULL)"; + } if ($result_vertragsstd = $db->db_query($qry)) { diff --git a/cis/private/profile/zeitsperre_resturlaub.php b/cis/private/profile/zeitsperre_resturlaub.php index 46d342971..ffd179401 100644 --- a/cis/private/profile/zeitsperre_resturlaub.php +++ b/cis/private/profile/zeitsperre_resturlaub.php @@ -79,7 +79,12 @@ else if (defined('CIS_ZEITAUFZEICHNUNG_GESPERRT_BIS') && CIS_ZEITAUFZEICHNUNG_GE else $gesperrt_bis = '2015-08-31'; -//echo $gesperrt_bis; +//Default-Wert für Max-Intervall in Tagen für Zeitsperre, über Config veränderbar +$maxDauerZS = 730; + +if (defined('CIS_ZEITSPERREN_MAX_DAUER') && CIS_ZEITSPERREN_MAX_DAUER != '') { + $maxDauerZS = CIS_ZEITSPERREN_MAX_DAUER; +} //Stundentabelleholen if(! $result_stunde=$db->db_query("SELECT * FROM lehre.tbl_stunde ORDER BY stunde")) @@ -204,66 +209,72 @@ function berechnen() function checkdatum() { - if(document.getElementById('vondatum').value.length<10) + if (document.getElementById('vondatum').value.length < 10) { alert('t('zeitsperre/vonDatumIstUngueltigNullenAngeben');?>'); return false; } - if(document.getElementById('bisdatum').value.length<10) + if (document.getElementById('bisdatum').value.length < 10) { alert('t('zeitsperre/bisDatumIstUngueltigNullenAngeben');?>'); return false; } - var Datum, Tag, Monat,Jahr,vonDatum,bisDatum, diff; + var Datum, Tag, Monat, Jahr, vonDatum, bisDatum, vonDatumDate, bisDatumDate, diff, diffTime, diffmax; - Datum=document.getElementById('vondatum').value; - Tag=Datum.substring(0,2); - Monat=Datum.substring(3,5); - if (parseInt(Monat,10)<1 || parseInt(Monat,10)>12) - { - alert('t('zeitsperre/vonDatumMonat');?>'+ document.getElementById('vondatum').value+ ' t('zeitsperre/istNichtRichtig');?>.'); + Datum = document.getElementById('vondatum').value; + Tag = Datum.substring(0, 2); + Monat = Datum.substring(3, 5); + if (parseInt(Monat, 10) < 1 || parseInt(Monat, 10) > 12) + { + alert('t('zeitsperre/vonDatumMonat');?>' + document.getElementById('vondatum').value + ' t('zeitsperre/istNichtRichtig');?>.'); document.getElementById('vondatum').focus(); - return false; - } + return false; + } - Jahr=Datum.substring(6,10); + Jahr = Datum.substring(6, 10); - vonDatum=Jahr+''+Monat+''+Tag; + vonDatum = Jahr + '' + Monat + '' + Tag; + vonDatumDate = Jahr + '-' + Monat + '-' + Tag; - Datum=document.getElementById('bisdatum').value; - Tag=Datum.substring(0,2); - Monat=Datum.substring(3,5); - if (parseInt(Monat,10)<1 || parseInt(Monat,10)>12) - { - alert('t('zeitsperre/bisDatumMonat');?>'+ document.getElementById('bisdatum').value+ ' t('zeitsperre/istNichtRichtig');?>.'); + Datum = document.getElementById('bisdatum').value; + Tag = Datum.substring(0, 2); + Monat = Datum.substring(3, 5); + if (parseInt(Monat, 10) < 1 || parseInt(Monat, 10) > 12) { + alert('t('zeitsperre/bisDatumMonat');?>' + document.getElementById('bisdatum').value + ' t('zeitsperre/istNichtRichtig');?>.'); document.getElementById('bisdatum').focus(); - return false; - } + return false; + } - Jahr=Datum.substring(6,10); + Jahr = Datum.substring(6, 10); + bisDatum = Jahr + '' + Monat + '' + Tag; + bisDatumDate = Jahr + '-' + Monat + '-' + Tag; - bisDatum=Jahr+''+Monat+''+Tag; + bisDatumDate = new Date(bisDatumDate); + vonDatumDate = new Date(vonDatumDate); - diff=bisDatum-vonDatum; + diffTime = bisDatumDate.getTime() - vonDatumDate.getTime(); + diff = Math.ceil(diffTime / (1000 * 60 * 60 * 24)); + diffmax = - if (vonDatum>bisDatum) - { - alert('t('zeitsperre/vonDatum');?> '+ document.getElementById('vondatum').value+ ' t('zeitsperre/istGroesserAlsBisDatum');?> '+document.getElementById('bisdatum').value); + if (vonDatum > bisDatum) { + alert('t('zeitsperre/vonDatum');?> ' + document.getElementById('vondatum').value + ' t('zeitsperre/istGroesserAlsBisDatum');?> ' + document.getElementById('bisdatum').value); document.getElementById('vondatum').focus(); - return false; - } - else if (diff>14) - { - Check = confirm('t('zeitaufzeichnung/zeitraumAuffallendHoch');?>'); + return false; + } + else if (diff > 14 && diff < diffmax) { + Check = confirm('t('zeitaufzeichnung/zeitraumAuffallendHoch');?>'); document.getElementById('bisdatum').focus(); - if (Check == false) - return false; - else - return true; - } - + if (Check == false) + return false; + else + return true; + } else if (diff >= diffmax) { + alert('t('zeitsperre/bisDatumGroesserMax');?> '); + document.getElementById('bisdatum').focus(); + return false; + } return true; } @@ -445,7 +456,8 @@ if(isset($_GET['type']) && ($_GET['type']=='edit_sperre' || $_GET['type']=='new_ $date=explode('.',$_POST['bisdatum']); if (@checkdate($date[1], $date[0], $date[2])) { - $bisdatum=$date[2].$date[1].$date[0]; + $bisdatum=$date[2].$date[1].$date[0]; + $bisdatum_iso = $date[2].'-'.$date[1].'-'.$date[0]; } else { @@ -464,6 +476,17 @@ if(isset($_GET['type']) && ($_GET['type']=='edit_sperre' || $_GET['type']=='new_ $error_msg .= $p->t('zeitsperre/vonDatumGroesserAlsBisDatum').'! '; } + //check if bis-Datum zu weit in der Zukunft + $bis = new DateTime($bisdatum); + $von = new DateTime($vondatum); + + $intervall = $bis->diff($von); + if ($intervall->days >= $maxDauerZS) + { + $error=true; + $error_msg = $p->t('zeitsperre/bisDatumGroesserMax'); + } + //von-datum pruefen TODO if($vondatum_iso < $gesperrt_bis && in_array($_POST['zeitsperretyp_kurzbz'],$typen_arr)) { diff --git a/cis/private/tools/suche.php b/cis/private/tools/suche.php index 52dbc2385..09d63b12a 100644 --- a/cis/private/tools/suche.php +++ b/cis/private/tools/suche.php @@ -126,6 +126,9 @@ if (!$searchPerson && !$searchOrt && !$searchDms && !$searchContent && !$searchO function searchPerson($searchItems) { + if (defined('CIS_ALLOW_PERSON_SEARCH') && !CIS_ALLOW_PERSON_SEARCH) + return false; + global $db, $p, $noalias, $uid; $bn = new benutzer(); //search only active and Mitarbeiter with positive Personalnr @@ -172,9 +175,6 @@ function searchPerson($searchItems) '; foreach($bn->result as $row) { - $bisverwendung = new bisverwendung(); - $bisverwendung->getLastAktVerwendung($row->uid); - echo ''; //echo '',$row->titelpre,''; echo '',$row->anrede,''; @@ -185,21 +185,16 @@ function searchPerson($searchItems) echo '',$row->vorname, ''; echo ''; - if(!defined('CIS_SUCHE_PROFIL_ANZEIGEN')) - echo '',$row->nachname,''; - else if(!CIS_SUCHE_PROFIL_ANZEIGEN) - { - $mitarbeiter = new Mitarbeiter($uid); - if($mitarbeiter->errormsg === NULL) - echo '',$row->nachname,''; - else + + $mitarbeiter = new Mitarbeiter(); + if (defined('CIS_SUCHE_PROFIL_ANZEIGEN') && CIS_SUCHE_PROFIL_ANZEIGEN === false && !$mitarbeiter->load($uid)) echo $row->nachname; - } else echo '',$row->nachname,''; + if($row->aktiv==false) echo ' (ausgeschieden)'; - elseif($bisverwendung->beschausmasscode=='5') + elseif(isKarenziert($row->uid)) echo ' (karenziert)'; echo ''; //echo '',$row->titelpost,''; @@ -262,6 +257,47 @@ function searchPerson($searchItems) else return false; } + +function isKarenziert($uid) +{ + global $db; + + if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT) + { + $qry =" + SELECT + 1 + FROM + hr.tbl_dienstverhaeltnis + JOIN hr.tbl_vertragsbestandteil USING(dienstverhaeltnis_id) + JOIN hr.tbl_vertragsbestandteil_karenz USING(vertragsbestandteil_id) + WHERE + tbl_dienstverhaeltnis.mitarbeiter_uid=".$db->db_add_param($uid)." + AND tbl_vertragsbestandteil.von<=now() AND tbl_vertragsbestandteil.bis>=now() + "; + + if($result = $db->db_query($qry)) + { + if($db->db_num_rows($result)>0) + return true; + else + return false; + } + else + return false; + } + else + { + $bisverwendung = new bisverwendung(); + $bisverwendung->getLastAktVerwendung($uid); + + if($bisverwendung->beschausmasscode=='5') + return true; + else + return false; + } +} + function searchOE($searchItems) { global $db, $p, $noalias; @@ -332,8 +368,6 @@ function searchOE($searchItems) $mitarbeiter->load($bf->uid); $kontakt = new kontakt(); $kontakt->loadFirmaKontakttyp($mitarbeiter->standort_id,'telefon'); - $bisverwendung = new bisverwendung(); - $bisverwendung->getLastAktVerwendung($bf->uid); $benutzer = new benutzer($bf->uid); if ($benutzer->bnaktiv) { @@ -341,8 +375,8 @@ function searchOE($searchItems) echo ''.$person->vorname.''; echo '',$person->nachname,''; echo ''.$bf->bezeichnung; - if($bisverwendung->beschausmasscode=='5') - echo ' (karenziert)'; + if( isKarenziert($bf->uid)) + echo ' (karenziert)'; echo ''; // Display phone number diff --git a/cis/private/tools/zeitaufzeichnung.php b/cis/private/tools/zeitaufzeichnung.php index 0eb86bdb1..46fd2c4c3 100644 --- a/cis/private/tools/zeitaufzeichnung.php +++ b/cis/private/tools/zeitaufzeichnung.php @@ -41,11 +41,10 @@ require_once('../../../include/service.class.php'); require_once('../../../include/mitarbeiter.class.php'); require_once('../../../include/betriebsmittelperson.class.php'); require_once('../../../include/globals.inc.php'); -require_once('../../../include/bisverwendung.class.php'); -require_once('../../../include/studiensemester.class.php'); require_once('../../../include/benutzerberechtigung.class.php'); require_once('../../../include/zeitaufzeichnung_import_csv.class.php'); require_once('../../../include/zeitaufzeichnung_import_post.class.php'); +require_once('../../../include/vertragsbestandteil.class.php'); $sprache = getSprache(); $p=new phrasen($sprache); @@ -229,6 +228,21 @@ $( document ).ready(function() '; +echo << + $(document).ready(function() { + const scrollDiv = document.createElement('div'); + scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;'; + document.body.appendChild(scrollDiv); + const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth; + document.body.removeChild(scrollDiv); + var marginright = Math.max((20 - scrollbarWidth), 0); + document.body.style.setProperty('width', 'calc(100% - ' + marginright + 'px)'); + }); + + +EOSBJS; + echo '