diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php index c2e38385c..768ec3197 100644 --- a/application/config/anrechnung.php +++ b/application/config/anrechnung.php @@ -6,10 +6,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); // Deadline for Application given as Time-Interval after Semesterstart. $config['interval_blocking_application'] = 'P1M'; -// Application submission period given by start- and enddate. -$config['submit_application_start'] = '05.09.2022'; -$config['submit_application_end'] = '22.09.2022'; - // Lehrveranstaltungen with these grades will be blocked for application $config['grades_blocking_application'] = array( 5, // nicht genügend @@ -19,4 +15,9 @@ $config['grades_blocking_application'] = array( 14, // nicht bestanden, 15, // nicht teilgenommen 18 // unentschuldigt -); \ No newline at end of file +); + +//Enables Fachbereichsleiter instead of LV Leiter +$config['fbl'] = FALSE; +//Enables Info Mails +$config['send_mail'] = TRUE; diff --git a/application/config/navigation.php b/application/config/navigation.php index 092c00cc5..928f5bae3 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -164,7 +164,14 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 20, 'requiredPermissions' => 'system/developer:r' - ) + ), + 'anrechnungen' => array( + 'link' => site_url('lehre/anrechnung/AdminAnrechnung'), + 'description' => 'Anrechnungen', + 'expand' => true, + 'sort' => 30, + 'requiredPermissions' => 'lehre/anrechnungszeitfenster:rw' + ) ) ) ) @@ -184,6 +191,15 @@ $config['navigation_menu']['Vilesci/index'] = array( ) ); +$config['navigation_menu']['Vilesci/index'] = array( + 'dashboard' => array( + 'link' => '#', + 'description' => 'Dashboard', + 'icon' => 'dashboard', + 'sort' => 1 + ) +); + $config['navigation_menu']['organisation/Reihungstest/index'] = array( 'reihungstestverwalung' => array( 'link' => base_url('vilesci/stammdaten/reihungstestverwaltung.php'), diff --git a/application/controllers/lehre/anrechnung/AdminAnrechnung.php b/application/controllers/lehre/anrechnung/AdminAnrechnung.php new file mode 100644 index 000000000..3c3fd3fc2 --- /dev/null +++ b/application/controllers/lehre/anrechnung/AdminAnrechnung.php @@ -0,0 +1,187 @@ + 'lehre/anrechnungszeitfenster:rw', + 'save' => 'lehre/anrechnungszeitfenster:rw', + 'edit' => 'lehre/anrechnungszeitfenster:rw', + 'delete' => 'lehre/anrechnungszeitfenster:rw' + ) + ); + + // Load models + $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); + $this->load->model('education/Anrechnungszeitraum_model', 'AnrechnungszeitraumModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + // Load libraries + $this->load->library('WidgetLib'); + $this->load->library('PermissionLib'); + $this->load->library('AnrechnungLib'); + + + // Load language phrases + $this->loadPhrases( + array( + 'global', + 'ui', + 'lehre', + 'anrechnung', + 'table' + ) + ); + + $this->_setAuthUID(); + + $this->setControllerId(); + } + + public function index() + { + // Set nearest Studiensemester as default + $result = $this->StudiensemesterModel->getNearest(); + $studiensemester_kurzbz = hasData($result) ? getData($result)[0]->studiensemester_kurzbz : ''; + + // Get existing Anrechnungszeitraeume + $this->AnrechnungszeitraumModel->addOrder('anrechnungszeitraum_id', 'DESC'); + $result = $this->AnrechnungszeitraumModel->load(); + $anrechnungszeitraum_arr = hasData($result) ? getData($result) : array(); + + $viewData = array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'anrechnungszeitraum_arr' => $anrechnungszeitraum_arr + ); + + $this->load->view('lehre/anrechnung/adminAnrechnung.php', $viewData); + } + + /** + * Save new Anrechnungszeitraum. + */ + public function save() + { + $this->_validate($this->input->post()); + + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + $anrechnungstart = $this->input->post('anrechnungstart'); + $anrechnungende = $this->input->post('anrechnungende'); + + $result = $this->AnrechnungszeitraumModel->insertAzr($studiensemester_kurzbz, $anrechnungstart, $anrechnungende); + + if (isError($result)) + { + $this->terminateWithJsonError(getError($result)); + } + + if (hasData($result)) + { + $this->outputJsonSuccess(array('anrechnungszeitraum_id' => getData($result))); + } + } + + /** + * Edit Anrechnungszeitraum. + */ + public function edit() + { + $this->_validate($this->input->post()); + + $anrechnungszeitraum_id = $this->input->post('anrechnungszeitraum_id'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + $anrechnungstart = $this->input->post('anrechnungstart'); + $anrechnungende = $this->input->post('anrechnungende'); + + $result = $this->AnrechnungszeitraumModel->updateAzr( + $anrechnungszeitraum_id, + $studiensemester_kurzbz, + $anrechnungstart, + $anrechnungende + ); + + if (isError($result)) + { + $this->terminateWithJsonError(getError($result)); + } + + if (hasData($result)) + { + $this->outputJsonSuccess(array('anrechnungszeitraum_id' => getData($result))); + } + } + + /** + * Delete Anrechnungszeitraum. + */ + public function delete() + { + $anrechnungszeitraum_id = $this->input->post('anrechnungszeitraum_id'); + + $result = $this->AnrechnungszeitraumModel->deleteAzr($anrechnungszeitraum_id); + + if (isError($result)) + { + $this->terminateWithJsonError(getError($result)); + } + + if (hasData($result)) + { + $this->outputJsonSuccess(array('anrechnungszeitraum_id' => getData($result))); + } + } + + /** + * Validates post parameters. + * + * @param $post + */ + private function _validate($post) + { + $studiensemester_kurzbz = $post['studiensemester_kurzbz']; + $anrechnungstart = $post['anrechnungstart']; + $anrechnungende = $post['anrechnungende']; + + if (isEmptyString($studiensemester_kurzbz) + || isEmptyString($anrechnungstart) + || isEmptyString($anrechnungende)) + { + $this->terminateWithJsonError($this->p->t('ui', 'errorFelderFehlen')); + } + + if ($anrechnungstart > $anrechnungende) + { + $this->terminateWithJsonError($this->p->t('ui', 'errorStartdatumNachEndedatum')); + } + + $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); + $studiensemester = getData($result)[0]; + + if ($anrechnungstart < $studiensemester->start || $anrechnungstart > $studiensemester->ende) + { + $this->terminateWithJsonError($this->p->t('ui', 'errorStartdatumNichtInStudiensemester')); + } + + if ($anrechnungende < $studiensemester->start || $anrechnungende > $studiensemester->ende) + { + $this->terminateWithJsonError($this->p->t('ui', 'errorEndedatumNichtInStudiensemester')); + } + + + } + + /** + * Retrieve the UID of the logged user and checks if it is valid + */ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) show_error('User authentification failed'); + } +} \ No newline at end of file diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 1f5c853db..8f71dc8d0 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -33,6 +33,9 @@ class approveAnrechnungDetail extends Auth_Controller ) ); + //Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -90,7 +93,8 @@ class approveAnrechnungDetail extends Auth_Controller $antragData = $this->anrechnunglib->getAntragData( $anrechnungData->prestudent_id, $anrechnungData->studiensemester_kurzbz, - $anrechnungData->lehrveranstaltung_id + $anrechnungData->lehrveranstaltung_id, + $anrechnungData->anrechnung_id ); // Get Empfehlung data @@ -209,48 +213,46 @@ class approveAnrechnungDetail extends Auth_Controller */ public function requestRecommendation() { - $data = $this->input->post('data'); + $anrechnung_id = $this->input->post('anrechnung_id'); - if(isEmptyArray($data)) + if(isEmptyString($anrechnung_id)) { return $this->outputJsonError('Fehler beim Übertragen der Daten.'); } $retval = array(); - $counter = 0; + + // Check if Anrechnungs-LV has lector + if (!$this->anrechnunglib->LVhasLector($anrechnung_id)) + { + $this->terminateWithJsonError('LV has no lector'); + } - foreach ($data as $item) - { - // Check if Anrechnungs-LV has lector - if (!$this->anrechnunglib->LVhasLector($item['anrechnung_id'])) - { - // Count up LV with no lector - $counter++; + // Get Fachbereichsleitung or LV Leitung. + if($this->config->item('fbl') === TRUE) + { + $result = $this->anrechnunglib->getLeitungOfLvOe($anrechnung_id); + } + else + { + // If LV Leitung is not present, gets all LV lectors. + $result = $this->anrechnunglib->getLectors($anrechnung_id); + } - // Break, if LV has no lector - break; - } + $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; - // Get full name of LV Leitung. - // If LV Leitung is not present, get full name of LV lectors. - $lector_arr = $this->anrechnunglib->getLectors($item['anrechnung_id']); - $empfehlungsanfrage_an = !isEmptyArray($lector_arr) - ? implode(', ', array_column($lector_arr, 'fullname')) - : ''; - - // Request Recommendation - if($this->anrechnunglib->requestRecommendation($item['anrechnung_id'])) - { - $retval[]= array( - 'anrechnung_id' => $item['anrechnung_id'], - 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, - 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR), - 'empfehlung_anrechnung' => null, - 'empfehlungsanfrageAm' => (new DateTime())->format('d.m.Y'), - 'empfehlungsanfrageAn' => $empfehlungsanfrage_an - ); - } - } + // Request Recommendation + if($this->anrechnunglib->requestRecommendation($anrechnung_id)) + { + $retval[]= array( + 'anrechnung_id' => $anrechnung_id, + 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, + 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR), + 'empfehlung_anrechnung' => null, + 'empfehlungsanfrageAm' => (new DateTime())->format('d.m.Y'), + 'empfehlungsanfrageAn' => $empfehlungsanfrage_an + ); + } /** * Send mails to lectors @@ -259,21 +261,24 @@ class approveAnrechnungDetail extends Auth_Controller * */ if (!isEmptyArray($retval)) { - self::_sendSanchoMailToLectors($retval); + if ($this->config->item('send_mail') === TRUE) + { + $this->_sendSanchoMailToLectors($anrechnung_id); + } // Output json to ajax return $this->outputJsonSuccess($retval); } // Output json to ajax - if (isEmptyArray($retval) && $counter > 0) + if (isEmptyArray($retval)) { - return $this->outputJsonError( + $this->terminateWithJsonError( "Empfehlung wurde nicht angefordert,\nDer LV sind keine LektorInnen zugeteilt." ); } - return $this->outputJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); + $this->terminateWithJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); } /** @@ -467,39 +472,33 @@ class approveAnrechnungDetail extends Auth_Controller /** * Send mail to lectors asking for recommendation. (first to LV-Leitung, if not present to all lectors of lv) - * @param $mail_params + * @param $anrechnung_id * @return bool */ - private function _sendSanchoMailToLectors($mail_params) + private function _sendSanchoMailToLectors($anrechnung_id) { - // Get Lehrveranstaltungen - $anrechnung_arr = array(); - - foreach ($mail_params as $item) - { - $this->AnrechnungModel->addSelect('lehrveranstaltung_id, studiensemester_kurzbz'); - $anrechnung_arr[]= array( - 'lehrveranstaltung_id' => $this->AnrechnungModel->load($item['anrechnung_id'])->retval[0]->lehrveranstaltung_id, - 'studiensemester_kurzbz' => $this->AnrechnungModel->load($item['anrechnung_id'])->retval[0]->studiensemester_kurzbz - ); - } - - $anrechnung_arr = array_unique($anrechnung_arr, SORT_REGULAR); - + $lehrveranstaltung_id = $this->AnrechnungModel->load($anrechnung_id)->retval[0]->lehrveranstaltung_id; + $studiensemester_kurzbz = $this->AnrechnungModel->load($anrechnung_id)->retval[0]->studiensemester_kurzbz; /** - * Get lectors (prio for LV-Leitung, if not present to all lectors of LV. + * Get mail receivers. + * If config is default (lectors): prio for LV-Leitung, if not present to all lectors of LV. * Anyway this function will receive a unique array to avoid sending more mails to one and the same lector. * **/ - $lector_arr = $this->_getLectors($anrechnung_arr); + if ($this->config->item('fbl') === TRUE) + { + $receiver_arr = $this->_getLeitungOfLvOe($lehrveranstaltung_id); + } + else + { + $receiver_arr = $this->_getLectors($studiensemester_kurzbz, $lehrveranstaltung_id); + } - - - // Send mail to lectors - foreach ($lector_arr as $lector) + // Send mail + foreach ($receiver_arr as $receiver) { - $to = $lector->uid; - $vorname = $lector->vorname; + $to = $receiver->uid. '@'. DOMAIN;; + $vorname = $receiver->vorname; // Get full name of stgl $this->load->model('person/Person_model', 'PersonModel'); @@ -537,35 +536,30 @@ class approveAnrechnungDetail extends Auth_Controller * @param $anrechnung_arr * @return array */ - private function _getLectors($anrechnung_arr) + private function _getLectors($studiensemester_kurzbz, $lehrveranstaltung_id) { $lector_arr = array(); - // Get lectors - foreach($anrechnung_arr as $anrechnung) - { - $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); - $result = $this->LehrveranstaltungModel->getLecturersByLv($anrechnung['studiensemester_kurzbz'], $anrechnung['lehrveranstaltung_id']); + $result = $this->LehrveranstaltungModel->getLecturersByLv($studiensemester_kurzbz, $lehrveranstaltung_id); - if (!$result = getData($result)) - { - show_error('Failed retrieving lectors of Lehrveranstaltung'); - } + if (!$result = getData($result)) + { + show_error('Failed retrieving lectors of Lehrveranstaltung'); + } - // Check if lv has LV-Leitung - $key = array_search(true, array_column($result, 'lvleiter')); + // Check if lv has LV-Leitung + $key = array_search(true, array_column($result, 'lvleiter')); - // If lv has LV-Leitung, keep only the one - if ($key !== false) - { - $lector_arr[]= $result[$key]; - } - // ...otherwise keep all lectors - else - { - $lector_arr = array_merge($lector_arr, $result); - } - } + // If lv has LV-Leitung, keep only the one + if ($key !== false) + { + $lector_arr[]= $result[$key]; + } + // ...otherwise keep all lectors + else + { + $lector_arr = array_merge($lector_arr, $result); + } /** * NOTE: This step is only done to make the array unique by uid, vorname and nachname in the following step @@ -584,6 +578,14 @@ class approveAnrechnungDetail extends Auth_Controller } + // Get Leitungen of Lehrveranstaltungs-Organisationseinheit + private function _getLeitungOfLvOe($lehrveranstaltung_id) + { + $result = $this->LehrveranstaltungModel->getLeitungOfLvOe($lehrveranstaltung_id); + + return hasData($result) ? getData($result) : show_error('Failed retrieving Leitung of Lehrveranstaltungs-Organisationseinheit'); + } + private function _saveEmpfehlungsNotiz($anrechnung_id, $empfehlungstext, $notiz_id) { $this->load->model('person/Notiz_model', 'NotizModel'); @@ -606,8 +608,5 @@ class approveAnrechnungDetail extends Auth_Controller trim($empfehlungstext), $this->_uid ); - - } - } diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index 9eb0c9734..f13814e66 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -28,6 +28,9 @@ class approveAnrechnungUebersicht extends Auth_Controller ) ); + // Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -78,6 +81,19 @@ class approveAnrechnungUebersicht extends Auth_Controller show_error(getError($studiengang_kz_arr)); } + // Get oes the user is entitled for + $oe_kurzbz_arr_schreibberechtigt = array(); + if ($oe_arr = $this->permissionlib->getOE_isEntitledFor(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN)) + { + foreach($oe_arr as $oe) + { + $berechtigt = $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 'suid', $oe); + + if ($berechtigt) $oe_kurzbz_arr_schreibberechtigt[]= $oe; + } + } + + // Check if permission is readonly $hasReadOnlyAccess = $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 's') && !$this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 'suid'); @@ -87,9 +103,11 @@ class approveAnrechnungUebersicht extends Auth_Controller $viewData = array( 'studiensemester_selected' => $studiensemester_kurzbz, - 'studiengaenge_entitled' => $studiengang_kz_arr, + 'studiengaenge_entitled' => $studiengang_kz_arr, // alle STG mit Lese- und Schreibberechtigung + 'oes_schreibberechtigt' => $oe_kurzbz_arr_schreibberechtigt, // alle STG nur mit Schreibberechtigung 'hasReadOnlyAccess' => $hasReadOnlyAccess, - 'hasCreateAnrechnungAccess' => $hasCreateAnrechnungAccess + 'hasCreateAnrechnungAccess' => $hasCreateAnrechnungAccess, + 'configFachbereichsleitung' => $this->config->item('fbl') ); $this->load->view('lehre/anrechnung/approveAnrechnungUebersicht.php', $viewData); @@ -207,14 +225,20 @@ class approveAnrechnungUebersicht extends Auth_Controller // Request Recommendation if($this->anrechnunglib->requestRecommendation($item['anrechnung_id'])) { - // Get full name of LV Leitung. - // If LV Leitung is not present, get full name of LV lectors. - $lector_arr = $this->anrechnunglib->getLectors($item['anrechnung_id']); - $empfehlungsanfrage_an = !isEmptyArray($lector_arr) - ? implode(', ', array_column($lector_arr, 'fullname')) - : ''; + // Get full name of Fachbereichsleitung or LV Leitung. + if($this->config->item('fbl') === TRUE) + { + $result = $this->anrechnunglib->getLeitungOfLvOe($item['anrechnung_id']); + } + else + { + // If LV Leitung is not present, get full name of LV lectors. + $result = $this->anrechnunglib->getLectors($item['anrechnung_id']); + } - $retval[]= array( + $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; + + $retval[]= array( 'anrechnung_id' => $item['anrechnung_id'], 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR), @@ -226,19 +250,27 @@ class approveAnrechnungUebersicht extends Auth_Controller } /** - * Send mails to lectors + * Send mails * NOTE: mails are sent at the end to ensure sending only ONE mail to each LV-Leitung or lector * even if they are required for more recommendations * */ if (!isEmptyArray($retval)) { - self::_sendSanchoMailToLectors($retval); + if ($this->config->item('send_mail') === TRUE) + { + $this->_sendSanchoMail($retval); + } } // Output json to ajax - if (isEmptyArray($retval) && $counter == 0) + if (isEmptyArray($retval)) { - return $this->outputJsonError('Es wurden keine Empfehlungen angefordert'); + if ($counter > 0) + { + $this->terminateWithJsonError('Bei '. $counter.' LV sind keine LektorInnen zugeteilt.'); + } + + $this->terminateWithJsonError('Es wurden keine Empfehlungen angefordert'); } return $this->outputJsonSuccess($retval); @@ -316,7 +348,7 @@ class approveAnrechnungUebersicht extends Auth_Controller * @param $mail_params * @return bool */ - private function _sendSanchoMailToLectors($mail_params) + private function _sendSanchoMail($mail_params) { // Get Lehrveranstaltungen $anrechnung_arr = array(); @@ -332,18 +364,25 @@ class approveAnrechnungUebersicht extends Auth_Controller $anrechnung_arr = array_unique($anrechnung_arr, SORT_REGULAR); - - /** - * Get lectors (prio for LV-Leitung, if not present to all lectors of LV. - * Anyway this function will receive a unique array to avoid sending more mails to one and the same lector. - * **/ - $lector_arr = $this->_getLectors($anrechnung_arr); + /** + * Get mail receivers. + * If retrieving lectors: prio for LV-Leitung, if not present to all lectors of LV. + * This function will receive a unique array to avoid sending more mails to one and the same user. + **/ + if($this->config->item('fbl') === TRUE) + { + $receiver_arr = $this->_getLeitungOfLvOe($anrechnung_arr); + } + else + { + $receiver_arr = $this->_getLectors($anrechnung_arr); + } // Send mail to lectors - foreach ($lector_arr as $lector) + foreach ($receiver_arr as $receiver) { - $to = $lector->uid; - $vorname = $lector->vorname; + $to = $receiver->uid. '@'. DOMAIN; + $vorname = $receiver->vorname; // Get full name of stgl $this->load->model('person/Person_model', 'PersonModel'); @@ -427,4 +466,34 @@ class approveAnrechnungUebersicht extends Auth_Controller return $lector_arr; } + + /** + * Get Leitungen of Lehrveranstaltungs-Organisationseinheit with unique uids. + * + * @param $anrechnung_arr + * @return array + */ + private function _getLeitungOfLvOe($anrechnung_arr) + { + $oeLeitung_arr = array(); + + // Get Leitungen + foreach($anrechnung_arr as $anrechnung) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $result = $this->LehrveranstaltungModel->getLeitungOfLvOe($anrechnung['lehrveranstaltung_id']); + + if (!hasData($result)) + { + show_error('No Leitung found'); + } + + $oeLeitung_arr = array_merge($oeLeitung_arr, getData($result)); + } + + // Make array unique + $oeLeitung_arr = array_unique($oeLeitung_arr, SORT_REGULAR); + + return $oeLeitung_arr; + } } diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index fbaac9b3e..e9059720b 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -80,11 +80,7 @@ class requestAnrechnung extends Auth_Controller $prestudent_id = getData($result)[0]->prestudent_id; // Check if application deadline is expired - $is_expired = self::_isExpired( - $this->config->item('submit_application_start'), - $this->config->item('submit_application_end'), - $studiensemester_kurzbz - ); + $is_expired = $this->_isExpired($studiensemester_kurzbz); // Check if Lehrveranstaltung was already graded with application blocking grades $is_blocked = self::_LVhasBlockingGrades($studiensemester_kurzbz, $lehrveranstaltung_id); @@ -93,7 +89,7 @@ class requestAnrechnung extends Auth_Controller $anrechnungData = $this->anrechnunglib->getAnrechnungDataByLv($lehrveranstaltung_id, $studiensemester_kurzbz, $prestudent_id); // Get Antrag data - $antragData = $this->anrechnunglib->getAntragData($prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id); + $antragData = $this->anrechnunglib->getAntragData($prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id, $anrechnungData->anrechnung_id); $viewData = array( 'antragData' => $antragData, @@ -234,32 +230,30 @@ class requestAnrechnung extends Auth_Controller * @return bool True if deadline is expired * @throws Exception */ - private function _isExpired($start, $ende, $studiensemester_kurzbz) + private function _isExpired($studiensemester_kurzbz) { - $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $today = new DateTime('today midnight'); - // If start is not given, set to Semesterstart. - if (!isset($start) || isEmptyString($start)) - { - $this->StudiensemesterModel->addSelect('start'); - $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); - $start = getData($result)[0]->start; - } + // Load all Anrechnungszeitfenster for this Studiensemester + $this->load->model('education/Anrechnungszeitraum_model', 'AnrechnungszeitraumModel'); + $result = $this->AnrechnungszeitraumModel->loadWhere(array('studiensemester_kurzbz' => $studiensemester_kurzbz)); - // If ende is not given, set to Semesterende. - if (!isset($ende) || isEmptyString($ende)) - { - $this->StudiensemesterModel->addSelect('ende'); - $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); - $ende = getData($result)[0]->ende; - } + if (hasData($result)) + { + // Loop through Anrechnungszeitfenster + foreach (getData($result) as $azrObj) + { + $start = new DateTime($azrObj->anrechnungstart); + $ende = new DateTime($azrObj->anrechnungende); - $today = new DateTime('today midnight'); - $start = new DateTime($start); - $ende = new DateTime($ende); + // Return false if today is at least within one Anrechnungszeitraum + if (($today >= $start && $today <= $ende)) return false; - // True if expired - return ($today < $start || $today > $ende); + } + } + + // Return true if today is in none Anrechnungszeitraum + return true; } /** diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 1bd92004d..d141a0635 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -28,6 +28,9 @@ class reviewAnrechnungDetail extends Auth_Controller ) ); + // Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -84,16 +87,21 @@ class reviewAnrechnungDetail extends Auth_Controller $antragData = $this->anrechnunglib->getAntragData( $anrechnungData->prestudent_id, $anrechnungData->studiensemester_kurzbz, - $anrechnungData->lehrveranstaltung_id + $anrechnungData->lehrveranstaltung_id, + $anrechnungData->anrechnung_id ); // Get Empfehlung data $empfehlungData = $this->anrechnunglib->getEmpfehlungData($anrechnung_id); + // False if LV-Leitung is present and user is not LV-Leitung. Otherwise always true. + $isEmpfehlungsberechtigt = $this->anrechnunglib->isEmpfehlungsberechtigt($anrechnung_id); + $viewData = array( 'antragData' => $antragData, 'anrechnungData' => $anrechnungData, - 'empfehlungData' => $empfehlungData + 'empfehlungData' => $empfehlungData, + 'isEmpfehlungsberechtigt' => $isEmpfehlungsberechtigt ); $this->load->view('lehre/anrechnung/reviewAnrechnungDetail.php', $viewData); @@ -140,10 +148,13 @@ class reviewAnrechnungDetail extends Auth_Controller * Send mails to STGL (if not present STGL, send to STGL assistance) * NOTE: mails are sent at the end to ensure sending only one mail to each STGL * */ - if (!$this->_sendSanchoMails($json, true)) - { - return $this->outputJsonError('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, true)) + { + return $this->outputJsonError('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } @@ -191,10 +202,13 @@ class reviewAnrechnungDetail extends Auth_Controller if (isset($json) && !isEmptyArray($json)) { // Send mails to STGL (if not present STGL, send to STGL assistance) - if (!$this->_sendSanchoMails($json, false)) - { - return $this->outputJsonError('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, false)) + { + return $this->outputJsonError('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } @@ -253,8 +267,14 @@ class reviewAnrechnungDetail extends Auth_Controller show_error('Failed retrieving Anrechnung'); } - $result = $this->LehrveranstaltungModel - ->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + if($this->config->item('fbl') === TRUE) + { + $result = $this->LehrveranstaltungModel->getLeitungOfLvOe($result->lehrveranstaltung_id); + } + else + { + $result = $this->LehrveranstaltungModel->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + } if($result = getData($result)) { @@ -282,14 +302,20 @@ class reviewAnrechnungDetail extends Auth_Controller show_error('Failed retrieving Anrechnung'); } - $result = $this->LehrveranstaltungModel - ->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + if($this->config->item('fbl') === TRUE) + { + $result = $this->LehrveranstaltungModel->getLeitungOfLvOe($result->lehrveranstaltung_id); + } + else + { + $result = $this->LehrveranstaltungModel->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + } if($result = getData($result)) { - $entitled_lector_arr = array_column($result, 'uid'); + $entitled_uid_arr = array_column($result, 'uid'); - if (in_array($this->_uid, $entitled_lector_arr)) + if (in_array($this->_uid, $entitled_uid_arr)) { return; } diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php index c63d0af69..6d4107936 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -26,6 +26,9 @@ class reviewAnrechnungUebersicht extends Auth_Controller ) ); + // Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -72,7 +75,8 @@ class reviewAnrechnungUebersicht extends Auth_Controller } $viewData = array( - 'studiensemester_selected' => $studiensemester_kurzbz + 'studiensemester_selected' => $studiensemester_kurzbz, + 'configFachbereichsleitung' => $this->config->item('fbl') ); $this->load->view('lehre/anrechnung/reviewAnrechnungUebersicht.php', $viewData); @@ -111,16 +115,19 @@ class reviewAnrechnungUebersicht extends Auth_Controller * Send mails to STGL (if not present STGL, send to STGL assistance) * NOTE: mails are sent at the end to ensure sending only one mail to each STGL * */ - if (!$this->_sendSanchoMails($json, true)) - { - show_error('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, true)) + { + show_error('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } else { - return $this->outputJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); + $this->terminateWithJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); } } @@ -154,10 +161,13 @@ class reviewAnrechnungUebersicht extends Auth_Controller if (isset($json) && !isEmptyArray($json)) { // Send mails to STGL (if not present STGL, send to STGL assistance) - if (!$this->_sendSanchoMails($json, false)) - { - show_error('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, false)) + { + show_error('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } @@ -217,14 +227,20 @@ class reviewAnrechnungUebersicht extends Auth_Controller show_error('Failed retrieving Anrechnung'); } - $result = $this->LehrveranstaltungModel - ->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + if ($this->config->item('fbl') === TRUE) + { + $result = $this->LehrveranstaltungModel->getLeitungOfLvOe($result->lehrveranstaltung_id); + } + else + { + $result = $this->LehrveranstaltungModel->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + } if($result = getData($result)) { - $entitled_lector_arr = array_column($result, 'uid'); + $entitled_uid_arr = array_column($result, 'uid'); - if (in_array($this->_uid, $entitled_lector_arr)) + if (in_array($this->_uid, $entitled_uid_arr)) { return; } diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index 86a81fb55..d8c4b1fd3 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -37,19 +37,30 @@ class AnrechnungLib * @param $lv_id * @return StdClass */ - public function getAntragData($prestudent_id, $studiensemester_kurzbz, $lv_id) + public function getAntragData($prestudent_id, $studiensemester_kurzbz, $lv_id, $anrechnung_id = null) { $antrag_data = new StdClass(); // Get students UID. $uid = $this->ci->StudentModel->getUID($prestudent_id); - - // Get lehrveranstaltung data. Break, if course is not assigned to student. - if(!$lv = getData($this->ci->LehrveranstaltungModel->getLvByStudent($uid, $studiensemester_kurzbz, $lv_id))[0]) + + // If Anrechnung exists + if (is_numeric($anrechnung_id)) { - show_error('You are not assigned to this course yet.'); + // Just load LV by lv_id + $result = $this->ci->LehrveranstaltungModel->load($lv_id); + $lv = getData($result)[0]; } - + // If Anrechnung not exists + else + { + // Load LV, but check if student is assigned to that LV. Break, if not. + if(!$lv = getData($this->ci->LehrveranstaltungModel->getLvByStudent($uid, $studiensemester_kurzbz, $lv_id))[0]) + { + show_error('You are not assigned to this course yet.'); + } + } + // Get the students personal data if (!$person = getData($this->ci->PersonModel->getByUid($uid))[0]) { @@ -274,14 +285,21 @@ class AnrechnungLib if (hasData($result)) { $empfehlung_data->empfehlungsanfrageAm = (new DateTime($result->retval[0]->insertamum))->format('d.m.Y'); - - // Get lectors who received request for recommendation - $lector_arr = self::getLectors($anrechnung_id); - - if (!isEmptyArray($lector_arr)) - { - $empfehlung_data->empfehlungsanfrageAn = implode(', ', array_column($lector_arr, 'fullname')); - } + + // Get users who received request for recommendation + if($this->ci->config->item('fbl') === TRUE) + { + $res = $this->getLeitungOfLvOe($anrechnung_id); + } + else + { + $res = $this->getLectors($anrechnung_id); + } + + if (!isEmptyArray($res)) + { + $empfehlung_data->empfehlungsanfrageAn = implode(', ', array_column($res, 'fullname')); + } } if (is_null($anrechnung->empfehlung_anrechnung)) @@ -741,6 +759,25 @@ class AnrechnungLib // Continue, if LV has no lector (there is no one to ask for recommendation) return hasData($result) ? true : false; } + + /** + * Check if user is allowed to recommend Anrechnung. + * + * @param $anrechnung_id + * @return bool + */ + public function isEmpfehlungsberechtigt($anrechnung_id) + { + if($this->ci->config->item('fbl') === TRUE) + { + return true; + } + // Get lv-leitungen or, if not present, all lectors of lv. + $lector_arr = $this->getLectors($anrechnung_id); + + // Return false if lv-leitung is present and user is not lv-leitung. Otherways return always true. + return in_array(getAuthUID(), array_column($lector_arr, 'uid')); + } /** * Get LV Leitung. If not present, get all LV lectors. @@ -774,11 +811,14 @@ class AnrechnungLib // Check if lv has LV-Leitung $key = array_search(true, array_column($result, 'lvleiter')); - - // If lv has LV-Leitung, keep only the one + + // If lv has 1 or more LV-Leitungen, keep only them if ($key !== false) { - $lector_arr[]= $result[$key]; + foreach ($result as $lector) + { + if ($lector->lvleiter) $lector_arr[]= $lector; + } } // ...otherwise keep all lectors else @@ -803,6 +843,40 @@ class AnrechnungLib return $lector_arr; } + /** + * Get Leitung of Lehrveranstaltungs-Organisationseinheit. + * + * @param $anrechnung_id + * @return false|mixed|null + */ + public function getLeitungOfLvOe($anrechnung_id) + { + $this->ci->AnrechnungModel->addSelect('lehrveranstaltung_id'); + $result = $this->ci->AnrechnungModel->load($anrechnung_id); + + $lehrveranstaltung_id = getData($result)[0]->lehrveranstaltung_id; + + // Get Leitungen + $result = $this->ci->LehrveranstaltungModel->getLeitungOfLvOe($lehrveranstaltung_id); + + if (!hasData($result)) + { + return false; + } + + $oeLeitung_arr = getData($result); + + foreach ($oeLeitung_arr as $oeLeitung) + { + $oeLeitung->fullname = $oeLeitung->vorname. ' '. $oeLeitung->nachname; + } + + // Now make the array unique + $oeLeitung_arr = array_unique($oeLeitung_arr, SORT_REGULAR); + + return $oeLeitung_arr; + } + // Return an object with Anrechnungdata private function _setAnrechnungDataObject($anrechnung) { diff --git a/application/models/education/Anrechnungszeitraum_model.php b/application/models/education/Anrechnungszeitraum_model.php new file mode 100644 index 000000000..e6f0f13d3 --- /dev/null +++ b/application/models/education/Anrechnungszeitraum_model.php @@ -0,0 +1,87 @@ +dbTable = 'lehre.tbl_anrechnungszeitraum'; + $this->pk = 'anrechnungszeitraum_id'; + } + + /** + * Save new Anrechnungszeitraum. + * + * @param $studiensemester_kurzbz + * @param $anrechnungstart + * @param $anrechnungende + * @return array|stdClass + */ + public function insertAzr($studiensemester_kurzbz, $anrechnungstart, $anrechnungende) + { + $result = $this->insert(array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'anrechnungstart' => $anrechnungstart, + 'anrechnungende' => $anrechnungende, + 'insertvon' => getAuthUID() + )); + + if (isError($result)) + { + return error('Fehler bei Anrechnungszeitraum speichern.'); + } + + // Return new anrechnungszeitraum_id + return success($result->retval); + } + + /** + * Delete Anrechnungszeitraum. + * + * @param $anrechnungszeitraum_id + * @return array|stdClass + */ + public function deleteAzr($anrechnungszeitraum_id) + { + $result = $this->delete(array('anrechnungszeitraum_id' => $anrechnungszeitraum_id)); + + if (isError($result)) + { + return error('Fehler bei Anrechnungszeitraum löschen.'); + } + + return success($result->retval); + } + + /** + * Update existing Anrechnungszeitraum. + * + * @param $anrechnungszeitraum_id + * @param $studiensemester_kurzbz + * @param $anrechnungstart + * @param $anrechnungende + * @return array|stdClass + */ + public function updateAzr($anrechnungszeitraum_id, $studiensemester_kurzbz, $anrechnungstart, $anrechnungende) + { + $result = $this->update( + $anrechnungszeitraum_id, + array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'anrechnungstart' => $anrechnungstart, + 'anrechnungende' => $anrechnungende + ) + ); + + if (isError($result)) + { + return error('Fehler bei Anrechnungszeitraum update.'); + } + + return success($result->retval); + } + +} diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index f54443955..1f1b90131 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -200,6 +200,28 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($query, array($lehrveranstaltung_id, $studiensemester_kurzbz)); } + /** + * Gets all Leiter of Lehrveranstaltungsorganisationseinheit + * @param $lehrveranstaltung_id + * @return array|null + */ + public function getLeitungOfLvOe($lehrveranstaltung_id) + { + $query = "select distinct vorname, nachname, uid + FROM + lehre.tbl_lehrveranstaltung lv + JOIN public.tbl_organisationseinheit og using (oe_kurzbz) + JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) + join public.tbl_benutzer b using (uid) + join public.tbl_person p using (person_id) + where + bf.datum_von <= now()::date + and (bf.datum_bis >= now()::date or bf.datum_bis is null) + and bf.funktion_kurzbz = 'Leitung' -- Leitung of LV-OE + and lehrveranstaltung_id = ?"; + + return $this->execQuery($query, array($lehrveranstaltung_id)); + } /** * Gets Lehrveranstaltungen of a student diff --git a/application/views/lehre/anrechnung/adminAnrechnung.php b/application/views/lehre/anrechnung/adminAnrechnung.php new file mode 100644 index 000000000..cb9a55c18 --- /dev/null +++ b/application/views/lehre/anrechnung/adminAnrechnung.php @@ -0,0 +1,137 @@ + $this->p->t('anrechnung', 'anrechnungenVerwalten'), + 'jquery3' => true, + 'jqueryui1' => true, + 'bootstrap3' => true, + 'fontawesome6' => true, + 'ajaxlib' => true, + 'dialoglib' => true, + 'tabulator4' => true, + 'tablewidget' => true, + 'sbadmintemplate3' => true, + 'navigationwidget' => true, + 'phrases' => array( + 'anrechnung' => array( + 'anrechnungenVerwalten', + 'anrechnungszeitraumFestlegen', + 'anrechnungszeitraumHinzufuegen', + 'anrechnungszeitraumSpeichern', + 'anrechnungszeitraumStart', + 'anrechnungszeitraumEnde' + ), + 'ui' => array( + 'aktion', + 'geloescht', + 'gespeichert', + 'frageSicherLoeschen', + 'spaltenEinstellen' + ), + 'lehre' => array('studiensemester'), + 'table' => array( + 'spaltenEinAusblenden', + 'spaltenEinAusblendenMitKlickOeffnen', + 'spaltenEinAusblendenAufEinstellungenKlicken', + 'spaltenEinAusblendenMitKlickAktivieren', + 'spaltenEinAusblendenMitKlickSchliessen', + 'spaltenbreiteVeraendern', + 'spaltenbreiteVeraendernText', + 'spaltenbreiteVeraendernInfotext', + 'zeilenAuswaehlen', + 'zeilenAuswaehlenEinzeln', + 'zeilenAuswaehlenBereich', + 'zeilenAuswaehlenAlle' + ) + ), + 'customJSs' => array( + 'public/js/bootstrapper.js', + 'public/js/lehre/anrechnung/adminAnrechnung.js' + ), + 'customCSSs' => array( + 'public/css/sbadmin2/tablesort_bootstrap.css' + ) +); + +$this->load->view('templates/FHC-Header', $includesArray); +?> + +