diff --git a/application/controllers/Cis/Benotungstool.php b/application/controllers/Cis/Benotungstool.php index c22ed42f3..94faeff98 100644 --- a/application/controllers/Cis/Benotungstool.php +++ b/application/controllers/Cis/Benotungstool.php @@ -27,22 +27,8 @@ class Benotungstool extends Auth_Controller */ public function index() { - - - // TODO: check if related CIS config is also loaded when being routed in Cis4 by vuerouter - // TODO: check if new benotungstool should be configurable the exact same way? - // TODO: move this to some config api? - $viewData = array( 'uid'=>getAuthUID(), - 'CIS_GESAMTNOTE_UEBERSCHREIBEN' => CIS_GESAMTNOTE_UEBERSCHREIBEN, - 'CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF' => CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF, - 'CIS_GESAMTNOTE_PRUEFUNG_TERMIN3' => CIS_GESAMTNOTE_PRUEFUNG_TERMIN3, - 'CIS_GESAMTNOTE_PRUEFUNG_TERMIN2' => CIS_GESAMTNOTE_PRUEFUNG_TERMIN2, - 'CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE' => CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE, - 'CIS_GESAMTNOTE_PUNKTE' => CIS_GESAMTNOTE_PUNKTE, - 'CIS_GESAMTNOTE_GEWICHTUNG' => CIS_GESAMTNOTE_GEWICHTUNG, - 'CIS_ANWESENHEITSLISTE_NOTENLISTE_ANZEIGEN' => CIS_ANWESENHEITSLISTE_NOTENLISTE_ANZEIGEN ); $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Benotungstool']); diff --git a/application/controllers/api/frontend/v1/Noten.php b/application/controllers/api/frontend/v1/Noten.php index d4321c5a5..6244e3a62 100644 --- a/application/controllers/api/frontend/v1/Noten.php +++ b/application/controllers/api/frontend/v1/Noten.php @@ -37,7 +37,8 @@ class Noten extends FHCAPI_Controller 'saveStudentPruefung' => array('lehre/benotungstool:rw'), 'createPruefungen' => array('lehre/benotungstool:rw'), 'saveNotenvorschlagBulk' => array('lehre/benotungstool:rw'), - 'savePruefungenBulk' => array('lehre/benotungstool:rw') + 'savePruefungenBulk' => array('lehre/benotungstool:rw'), + 'getCisConfig' => array('lehre/benotungstool:rw') ]); $this->load->library('AuthLib', null, 'AuthLib'); @@ -66,6 +67,31 @@ class Noten extends FHCAPI_Controller } + public function getCisConfig() { + $this->terminateWithSuccess( + array( + // Punkte bei der Noteneingabe anzeigen + 'CIS_GESAMTNOTE_PUNKTE' => CIS_GESAMTNOTE_PUNKTE, + // Gibt an ob der Lektor erneut eine LVNote eintragen kann wenn bereits eine Zeugnisnote vorhanden ist (true | false) DEFAULT true + 'CIS_GESAMTNOTE_UEBERSCHREIBEN' => CIS_GESAMTNOTE_UEBERSCHREIBEN, + // Gewichtung der Lehreinheiten bei Noteneintragung true|false + 'CIS_GESAMTNOTE_GEWICHTUNG' => CIS_GESAMTNOTE_GEWICHTUNG, + // Bei Gesamtnote eine zusaetzliche Spalte fuer den 2. Termin anzeigen + 'CIS_GESAMTNOTE_PRUEFUNG_TERMIN2' => CIS_GESAMTNOTE_PRUEFUNG_TERMIN2, + // Bei Gesamtnote eine zusaetzliche Spalte fuer den 3. Termin anzeigen + // Erfordert den Eintrag "Termin3" in der Tabelle lehre.tbl_pruefungstyp + 'CIS_GESAMTNOTE_PRUEFUNG_TERMIN3' => CIS_GESAMTNOTE_PRUEFUNG_TERMIN3, + // Bei Gesamtnote eine zusaetzliche Spalte fuer die kommissionelle Pruefung anlegen + 'CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF' => CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF, + // Bei Gesamtnote eine zusaetzliche Spalte fuer die kommissionelle Pruefung anlegen + 'CIS_GESAMTNOTE_PRUEFUNG_MOODLE_NOTE' => CIS_GESAMTNOTE_PRUEFUNG_MOODLE_NOTE, + // Bei Gesamtnote die Spalte fuer die Quelle der Noten anzeigen (Moodle oder LE) + 'CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE' => CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE, + // Gibt an ob die Note im Notenfreigabemail enthalten ist oder nicht + 'CIS_GESAMTNOTE_FREIGABEMAIL_NOTE' => CIS_GESAMTNOTE_FREIGABEMAIL_NOTE + ) + ); + } /** * GET METHOD @@ -93,6 +119,12 @@ class Noten extends FHCAPI_Controller $grades = array(); $student_uids = array_map($func, $studentenData); + + $funcpre = function ($value) { + return $value->prestudent_id; + }; + + $prestudent_ids = array_map($funcpre, $studentenData); if(count($student_uids) > 0) { $mobres = $this->MobilitaetModel->getMobilityZusatzForUids($student_uids); @@ -146,8 +178,14 @@ class Noten extends FHCAPI_Controller $this->addMeta('getExternalGradesError', $t->getMessage()); } + // assign the anw% to the students in the studentData loop + $anwresult = $this->getAnwesenheiten($prestudent_ids, $lv_id, $sem_kurzbz); + // calculate notenvorschläge from teilnoten foreach($studentenData as $student) { + + $student->anwquote = $anwresult[$student->prestudent_id]; + $g = $grades[$student->uid]['grades']; $note_lv = $grades[$student->uid]['note_lv']; @@ -214,7 +252,7 @@ class Noten extends FHCAPI_Controller $pruefungen = $this->LePruefungModel->getPruefungenByLvStudiensemester($lv_id, $sem_kurzbz); $pruefungenData = getData($pruefungen); - $this->terminateWithSuccess(array($studentenData, $pruefungenData, DOMAIN, $grades)); + $this->terminateWithSuccess(array($studentenData, $pruefungenData, DOMAIN, $grades, $anwresult)); } /** @@ -536,6 +574,15 @@ class Noten extends FHCAPI_Controller private function savePruefungstermin($typ, $student_uid, $lva_id, $stsem, $lehreinheit_id, $note, $punkte, $datum) { + // extra check if the student has lvnote and a zeugnisnote in the relevant lva + $resultLV = $this->LvgesamtnoteModel->getLvGesamtNoten($lva_id, $student_uid, $stsem); + + $lvgesamtnoteData = getData($resultLV); + $this->addMeta('lvgesamtnoteData', $lvgesamtnoteData); + + // allocating pruefungen before lv note is forbidden + if($lvgesamtnoteData == null) return $this->p->t('benotungstool', 'c4keineLvNoteEingetragen'); + $status = []; // send $grades reference to moodle addon @@ -928,6 +975,32 @@ class Noten extends FHCAPI_Controller $this->terminateWithSuccess($ret); } + + private function getAnwesenheiten($prestudent_ids, $lv_id, $sem_kurzbz) { + + $anwesenheiten = []; + try { + $downloadFunc = function ($anwesenheitenResult) use (&$anwesenheiten) { + // map result rows by prestudent_uid to retrieve them by that key later on + foreach ($anwesenheitenResult as $anw) { + $anwesenheiten[$anw->prestudent_id] = $anw->sum; + } + }; + + Events::trigger( + 'getAnwesenheitenForLvAndSemester', + $prestudent_ids, + $lv_id, + $sem_kurzbz, + $downloadFunc + ); + } catch (Throwable $t) { + $this->addMeta('getAnwesenheitenForLvAndSemester', $t->getMessage()); + } + + return $anwesenheiten; + + } } diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 093b2b02c..8604de233 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -312,7 +312,7 @@ class Lehrveranstaltung_model extends DB_Model { $query = "SELECT distinct on(nachname, vorname, person_id) vorname, nachname, matrikelnr, - tbl_studentlehrverband.semester, tbl_studentlehrverband.verband, tbl_studentlehrverband.gruppe, + tbl_studentlehrverband.semester, tbl_studentlehrverband.verband, tbl_studentlehrverband.gruppe, tbl_student.prestudent_id, (SELECT status_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=tbl_student.prestudent_id ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1) as status, tbl_bisio.bisio_id, tbl_bisio.von, tbl_bisio.bis, tbl_student.studiengang_kz AS stg_kz_student, tbl_zeugnisnote.note, tbl_mitarbeiter.mitarbeiter_uid, tbl_person.matr_nr, tbl_benutzer.uid, diff --git a/public/js/api/factory/noten.js b/public/js/api/factory/noten.js index 2ac91ad21..51e1900e6 100644 --- a/public/js/api/factory/noten.js +++ b/public/js/api/factory/noten.js @@ -16,6 +16,12 @@ */ export default { + getCisConfig(){ + return { + method: 'get', + url: '/api/frontend/v1/Noten/getCisConfig' + }; + }, getStudentenNoten(lv_id, sem_kurzbz) { return { method: 'get', diff --git a/public/js/components/Cis/Benotungstool/Benotungstool.js b/public/js/components/Cis/Benotungstool/Benotungstool.js index fb4bede2a..cf0ed83e0 100644 --- a/public/js/components/Cis/Benotungstool/Benotungstool.js +++ b/public/js/components/Cis/Benotungstool/Benotungstool.js @@ -44,6 +44,7 @@ export const Benotungstool = { }, data() { return { + config: null, // cis config neuesPruefungsdatumModalVisible: false, loading: false, selectedUids: [], // shared selection state @@ -362,7 +363,8 @@ export const Benotungstool = { // add col to table const cols = [...this.notenTableOptions.columns.slice(0, -1)]; - const kommCol = this.notenTableOptions.columns[this.notenTableOptions.columns.length - 1]; + let kommCol = null + if(this.config?.CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) kommCol = this.notenTableOptions.columns[this.notenTableOptions.columns.length - 1]; // TODO: could reuse cols instead of recreating all from a variable maybe this.distinctPruefungsDates.forEach((date, index)=>{ @@ -385,7 +387,7 @@ export const Benotungstool = { }) }) - cols.push(kommCol) // keep kommPruef Col as last + if(this.config?.CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) cols.push(kommCol) // keep kommPruef Col as last // redraw table this.loading = false @@ -516,7 +518,8 @@ export const Benotungstool = { {title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, visible: false, widthGrow: 1, variableHeight: true}, {title: Vue.computed(() => this.$p.t('benotungstool/c4antrittCountv2')), field: 'hoechsterAntritt', tooltip: false, widthGrow: 1}, {title: Vue.computed(() => this.$p.t('benotungstool/c4vorname')), field: 'vorname', headerFilter: true, tooltip: false, widthGrow: 1}, - {title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', headerFilter: true, widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', headerFilter: true, widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4anwesenheitsquote')), field: 'anwquote', widthGrow: 1, formatter: this.percentFormatter}, {title: Vue.computed(() => this.$p.t('benotungstool/c4mobility')), field: 'mobility_zusatz', headerFilter: true, widthGrow: 1, visible: false}, {title: Vue.computed(() => this.$p.t('benotungstool/c4teilnoten')), field: 'teilnote', widthGrow: 1, formatter: this.teilnotenFormatter, variableHeight: true}, {title: Vue.computed(() => this.$p.t('benotungstool/c4note')), field: 'note_vorschlag', @@ -953,6 +956,11 @@ export const Benotungstool = { return '
' }, + percentFormatter(cell) { + const data = cell.getData() + const val = data.anwquote ?? '-' + return '