diff --git a/application/controllers/api/frontend/v1/Noten.php b/application/controllers/api/frontend/v1/Noten.php index b10713e99..4655fcc71 100644 --- a/application/controllers/api/frontend/v1/Noten.php +++ b/application/controllers/api/frontend/v1/Noten.php @@ -41,17 +41,24 @@ class Noten extends FHCAPI_Controller ]); $this->load->library('AuthLib', null, 'AuthLib'); + $this->load->library('PhrasesLib'); // Loads phrases system $this->loadPhrases([ - 'global' + 'global', + 'benotungstool' ]); require_once(FHCPATH . 'include/mobilitaet.class.php'); $this->load->model('education/LePruefung_model', 'LePruefungModel'); $this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel'); $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); $this->load->model('crm/Student_model', 'StudentModel'); + + $this->load->helper('hlp_sancho_helper'); + } public function getStudentenNoten() { @@ -125,8 +132,6 @@ class Noten extends FHCAPI_Controller } // send $grades reference to moodle addon - - // TODO: event getExterneNoten Events::trigger( 'getExternalGrades', function & () use (&$grades) @@ -239,36 +244,141 @@ class Noten extends FHCAPI_Controller // TODO: also do something similar when updating/creating a pruefung! + $res = $this->LehrveranstaltungModel->load($lv_id); + if(isError($res) || !hasData($res)) { + $this->terminateWithError('Keine gültige Lehrveranstaltung gefunden für ID: '.$lv_id); + } + + $lv = getData($res)[0]; + + $studiengang_kz = $lv->studiengang_kz; + $res = $this->StudiengangModel->load($studiengang_kz); + if(isError($res) || !hasData($res)) { + $this->terminateWithError('Kein gültiger Studiengang gefunden für ID: '.$studiengang_kz); + } + $sg = getData($res)[0]; + $lvaFullName = $sg->kurzbzlang . ' ' . $lv->semester . '.Semester + ' . $lv->bezeichnung . " - " .$lv->lehrform_kurzbz. " " . $lv->orgform_kurzbz . " - " . $sem_kurzbz; + + $emails = explode(', ', $sg->email); + + + $res = $this->PersonModel->load(getAuthPersonId()); + if(isError($res) || !hasData($res)) { + $this->terminateWithError('Keine gültige Person gefunden für ID: '.getAuthPersonId()); + } + $pers = getData($res)[0]; + $lektorFullName = $pers->anrede.' '.$pers->vorname.' '.$pers->nachname; //.' ('.$pers->kurzbz.')'; + + + $res = $this->StudienplanModel->getStudienplanByLvaSemKurzbz($lv_id, $sem_kurzbz); + $data = getData($res); + $studienplan_bezeichnung = ''; + foreach ($data as $row) { + $studienplan_bezeichnung .= $row->bezeichnung . ' '; + } + $betreff = 'Notenfreigabe ' . $lv->bezeichnung . ' ' . $lv->orgform_kurzbz . ' - ' . $studienplan_bezeichnung; + + $studlist = " + + + + + "; + $studlist .= ""; + $studlist .= ""; + + foreach($result->noten as $note) { - $result = $this->LvgesamtnoteModel->getLvGesamtNoten($lv_id, $note->uid, $sem_kurzbz); - - if (!isError($result) && hasData($result)) + $resultLVGes = $this->LvgesamtnoteModel->getLvGesamtNoten($lv_id, $note->uid, $sem_kurzbz); + + if (!isError($resultLVGes) && hasData($resultLVGes)) { - $lvgesamtnote = getData($result)[0]; + $lvgesamtnote = getData($resultLVGes)[0]; + $this->addMeta($note->uid, $lvgesamtnote); if ($lvgesamtnote->benotungsdatum > $lvgesamtnote->freigabedatum) { - $lvgesamtnote->freigabedatum = date("Y-m-d H:i:s"); - $lvgesamtnote->freigabevon_uid = getAuthUID(); - if($lvgesamtnote->save()) { - $ret[] = array('uid' => $note->uid, 'freigabedatum' => $lvgesamtnote->freigabedatum, 'benotungsdatum' => $lvgesamtnote->benotungsdatum); + + $id = $this->LvgesamtnoteModel->update( + [$lvgesamtnote->student_uid, $lvgesamtnote->studiensemester_kurzbz, $lvgesamtnote->lehrveranstaltung_id], + array( + 'note' => $note->note, + 'freigabevon_uid' => getAuthUID(), + 'freigabedatum' => date("Y-m-d H:i:s"), + 'updateamum' => date("Y-m-d H:i:s"), + 'updatevon' => getAuthUID() + ) + ); + + if($id) { + $res = $this->LvgesamtnoteModel->load($id->retval); + if(hasData($res)) { + $lvgesamtnote = getData($res)[0]; + $ret[] = array('uid' => $note->uid, 'freigabedatum' => $lvgesamtnote->freigabedatum, 'benotungsdatum' => $lvgesamtnote->benotungsdatum); + } } - if (defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE) + // TODO: find the real config for that + // defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE + if (true) { - // TODO: infomail an studiengangsassistenz - // Enthalten sind MatrikelNr., Vorname, Nachname und Note der neuen oder geänderten Einträge. - } + $studlist .= ""; + $studlist .= ""; + $studlist .= ""; + $studlist .= ""; + // TODO: if defined(CIS_PUNKTE) ... + + // TODO: note bezeichnung + $studlist .= ""; + + $studlist .= ""; + } } } + } + $studlist .= "
" . $this->p->t('global','personenkz') . "" . $this->p->t('global','studiengang') . "" . $this->p->t('global','nachname') . "" . $this->p->t('global','vorname') . "" . $this->p->t('benotungstool','note') . "" . $this->p->t('benotungstool','bearbeitetvon') . "
" . trim($note->matrikelnr) . "
" . trim($note->kuerzel) . "
" . trim($note->nachname) . "
" . trim($note->vorname) . "" .$note->note. "" . $lvgesamtnote->mitarbeiter_uid; +// if ($lvgesamtnote->updatevon != '') +// $studlist .= " (" . $lvgesamtnote->updatevon . ")"; + $studlist .= "
"; + // TODO: find the real config for that + // defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE + if (true) + { + $this->sendEmail($lektorFullName, $lvaFullName, count($result->noten), $emails, $studlist, $betreff); } + $this->addMeta('studlist', $studlist); $this->terminateWithSuccess($ret); } + private function sendEmail($lektorFullName, $lvaFullName, $notenCount, $emailAdressen, $studlist, $betreff) + { + foreach ($emailAdressen as $email) + { + // Prepare mail content + $body_fields = array( + 'lektor' => $lektorFullName, + 'lvaname' => $lvaFullName, + 'studlist' => $studlist, + 'notencount' => $notenCount, + 'adressen' => $emailAdressen + ); + + // Send mail + sendSanchoMail( + 'Notenfreigabe', + $body_fields, + $email, + $betreff + ); + } + + } + public function getNotenvorschlagStudent() { // TODO: Notenvorschlag laden allgemeiner Endpunkt, der im Backend mit Logik (z.B. Moodle) angepasst werden kann. diff --git a/public/js/components/Cis/Benotungstool/Benotungstool.js b/public/js/components/Cis/Benotungstool/Benotungstool.js index a917e8879..b13239c12 100644 --- a/public/js/components/Cis/Benotungstool/Benotungstool.js +++ b/public/js/components/Cis/Benotungstool/Benotungstool.js @@ -73,16 +73,10 @@ export const Benotungstool = { this.tableBuiltResolve() } }, - { - event: "cellClick", - handler: async (e, cell) => { - console.log('cellClick Handler normal') - } - }, { event: "rowSelectionChanged", handler: async (data, rows) => { - this.selectedUids = data; + this.selectedUids = data.filter(d => d.selectable); } }, { @@ -436,18 +430,33 @@ export const Benotungstool = { rowFormatter: this.fixTabulatorSelectionFormatter, columns: [ { - formatter: "rowSelection", + formatter: function (cell, formatterParams, onRendered) { + // create the built-in checkbox + let checkbox = document.createElement("input"); + checkbox.type = "checkbox"; + + // Handle select manually + checkbox.addEventListener("click", (e) => { + e.stopPropagation(); + + // call our function + if (formatterParams && formatterParams.handleClick) { + formatterParams.handleClick(e, cell); + } + }); + + return checkbox; + }, titleFormatter: function (cell, formatterParams, onRendered) { - // Create the built-in checkbox + // create the built-in checkbox let checkbox = document.createElement("input"); checkbox.type = "checkbox"; // Handle "select all" manually checkbox.addEventListener("click", (e) => { e.stopPropagation(); - console.log("Custom select all handler"); - // Or call your function + // call our function if (formatterParams && formatterParams.handleClick) { formatterParams.handleClick(e, cell); } @@ -457,13 +466,12 @@ export const Benotungstool = { }, hozAlign: "center", headerSort: false, + formatterParams: { + handleClick: this.selectHandler + }, titleFormatterParams: { handleClick: this.selectAllHandler }, - cellClick: function (e, cell) { - - cell.getRow().toggleSelect(); - }, width: 50, }, {title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, widthGrow: 1}, @@ -540,8 +548,21 @@ export const Benotungstool = { persistence: false, } }, - selectAllHandler(e, col) { - const table = col.getTable(); + selectHandler(e, cell) { + const row = cell.getRow(); + + if(row.isSelected()){ + row.deselect(); + } else { + row.select(); + } + + // stop Tabulator’s built-in handler + e.stopPropagation(); + return false; + }, + selectAllHandler(e, cell) { + const table = cell.getTable(); const rows = table.getRows(); // custom select all logic @@ -564,7 +585,9 @@ export const Benotungstool = { const data = row.getData() const notSelectable = data.pruefungen?.find(p => p.pruefungstyp_kurzbz == 'kommPruef') || data.hoechsterAntritt >= 3 - if(notSelectable) row.getElement().children[0]?.children[0]?.remove() + if(notSelectable) { + row.getElement().children[0]?.children[0]?.remove() + } }, terminCalcFunc(entries) { return entries.reduce((acc, cur) => { @@ -1402,8 +1425,12 @@ export const Benotungstool = { const found = newVal.find(stud => stud.uid == rowData.uid) if (found) { row.select(); // ensure row is selected + const cb = row.getElement().children[0]?.children[0] + if(cb) cb.checked = true } else { row.deselect(); // ensure row is deselected + const cb = row.getElement().children[0]?.children[0] + if(cb) cb.checked = false } }); },