mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-16 22:42:16 +00:00
teilnoten/punkte berechnen für notenvorschläge; vorschläge übernehmen; noten freigabe mit passwort; prüfungen generisch anzeigen nach datum gruppiert; prüfungen anlegen/bearbeiten auf mapping termin1/2/3 möglich.
This commit is contained in:
@@ -15,6 +15,8 @@ class Benotungstool extends Auth_Controller
|
||||
parent::__construct([
|
||||
'index' => self::PERM_LOGGED
|
||||
]);
|
||||
|
||||
$this->_ci =& get_instance();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
@@ -26,8 +28,12 @@ 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?
|
||||
$viewData = array(
|
||||
'uid'=>getAuthUID(),
|
||||
'CIS_GESAMTNOTE_UEBERSCHREIBEN' => CIS_GESAMTNOTE_UEBERSCHREIBEN
|
||||
);
|
||||
|
||||
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Benotungstool']);
|
||||
|
||||
@@ -32,7 +32,8 @@ class Lehre extends FHCAPI_Controller
|
||||
'LV' => self::PERM_LOGGED,
|
||||
'Pruefungen' => self::PERM_LOGGED,
|
||||
'getLvViewData' => self::PERM_LOGGED,
|
||||
'getZugewieseneLv' => self::PERM_LOGGED
|
||||
'getZugewieseneLv' => self::PERM_LOGGED,
|
||||
'getLeForLv' => self::PERM_LOGGED
|
||||
]);
|
||||
|
||||
// Loads phrases system
|
||||
@@ -129,6 +130,17 @@ class Lehre extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
|
||||
public function getLeForLv() {
|
||||
$lv_id = $this->input->get("lv_id",TRUE);
|
||||
$sem_kurzbz = $this->input->get("sem_kurzbz",TRUE);
|
||||
|
||||
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
|
||||
|
||||
// $this->terminateWithSuccess($this->LehreinheitModel->getLesForLv($lv_id, $sem_kurzbz));
|
||||
$this->terminateWithSuccess($this->LehreinheitModel->getAllLehreinheitenForLvaAndMaUid($lv_id, getAuthUID(), $sem_kurzbz));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@ class Noten extends FHCAPI_Controller
|
||||
parent::__construct([
|
||||
'getStudentenNoten' => self::PERM_LOGGED, // todo: berechtigung
|
||||
'getNoten' => self::PERM_LOGGED,
|
||||
'saveStudentenNoten' => self::PERM_LOGGED // todo: berechtigungen!
|
||||
'saveStudentenNoten' => self::PERM_LOGGED, // todo: berechtigungen!
|
||||
'getNotenvorschlagStudent' => self::PERM_LOGGED,
|
||||
'saveNotenvorschlag' => self::PERM_LOGGED,
|
||||
'saveStudentPruefung' => self::PERM_LOGGED
|
||||
]);
|
||||
|
||||
$this->load->library('AuthLib', null, 'AuthLib');
|
||||
@@ -40,9 +43,16 @@ class Noten extends FHCAPI_Controller
|
||||
$this->loadPhrases([
|
||||
'global'
|
||||
]);
|
||||
|
||||
require_once(FHCPATH . 'include/mobilitaet.class.php');
|
||||
require_once(FHCPATH . 'include/student.class.php');
|
||||
require_once(FHCPATH . 'include/lvgesamtnote.class.php');
|
||||
require_once(FHCPATH . 'include/lehrveranstaltung.class.php');
|
||||
require_once(FHCPATH . 'include/lehreinheit.class.php');
|
||||
require_once(FHCPATH . 'include/studiengang.class.php');
|
||||
require_once(FHCPATH . 'include/pruefung.class.php');
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getStudentenNoten() {
|
||||
$lv_id = $this->input->get("lv_id",TRUE);
|
||||
$sem_kurzbz = $this->input->get("sem_kurzbz",TRUE);
|
||||
@@ -58,18 +68,44 @@ class Noten extends FHCAPI_Controller
|
||||
|
||||
// get studenten for lva & sem with zeugnisnote if available
|
||||
$studenten = $this->LehrveranstaltungModel->getStudentsByLv($sem_kurzbz, $lv_id);
|
||||
$studentenData = $this->getDataOrTerminateWithError($studenten);
|
||||
// $studentenData = $this->getDataOrTerminateWithError($studenten);
|
||||
$studentenData = getData($studenten);
|
||||
$this->addMeta('$studentenData', $studentenData);
|
||||
|
||||
$func = function ($value) {
|
||||
return $value->uid;
|
||||
};
|
||||
|
||||
|
||||
$grades = array();
|
||||
$student_uids = array_map($func, $studentenData);
|
||||
foreach($student_uids as $uid) {
|
||||
$grades[$uid]['grades'] = [];
|
||||
|
||||
$student = new student();
|
||||
$student->load($uid);
|
||||
$student->result[]= $student;
|
||||
$prestudent_id = $student->prestudent_id;
|
||||
|
||||
$mobility = new mobilitaet();
|
||||
$mobility->loadPrestudent($prestudent_id);
|
||||
$output = $mobility->result;
|
||||
$eintrag = '';
|
||||
foreach ($output as $k)
|
||||
{
|
||||
if(($k->mobilitaetstyp_kurzbz == 'GS') && ($k->studiensemester_kurzbz == $sem_kurzbz))
|
||||
$eintrag = ' (d.d.)';
|
||||
}
|
||||
$grades[$uid]['mobility'] = $eintrag;
|
||||
|
||||
if ($lvgesamtnote = new lvgesamtnote($lv_id, $uid, $sem_kurzbz))
|
||||
{
|
||||
$grades[$uid]['note_lv'] = $lvgesamtnote->note;
|
||||
$grades[$uid]['freigabedatum'] = $lvgesamtnote->freigabedatum;
|
||||
$grades[$uid]['benotungsdatum'] = $lvgesamtnote->benotungsdatum;
|
||||
$grades[$uid]['punkte_lv'] = $lvgesamtnote->punkte;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// send $grades reference to moodle addon
|
||||
Events::trigger(
|
||||
'moodleGrades',
|
||||
@@ -82,18 +118,81 @@ class Noten extends FHCAPI_Controller
|
||||
'stsem' => $sem_kurzbz
|
||||
]
|
||||
);
|
||||
$this->addMeta('$grades', $grades);
|
||||
|
||||
// calculate notenvorschläge from teilnoten, TODO: seperate function + own endpoint
|
||||
foreach($studentenData as $student) {
|
||||
$g = $grades[$student->uid]['grades'];
|
||||
$note_lv = $grades[$student->uid]['note_lv'];
|
||||
|
||||
// overwrite any calculation with lv note once available
|
||||
if(!is_null($note_lv)) {
|
||||
$student->note_vorschlag = $note_lv;
|
||||
} else if(count($g) > 0) {
|
||||
|
||||
$notensumme = 0;
|
||||
$notensumme_gewichtet = 0;
|
||||
$gewichtsumme = 0;
|
||||
$punktesumme = 0;
|
||||
$punktesumme_gewichtet = 0;
|
||||
$anzahlnoten = 0;
|
||||
foreach($g as $teilnote) {
|
||||
if (is_numeric($teilnote['grade']) || (is_null($teilnote['grade']) && is_numeric($teilnote['points'])))
|
||||
{
|
||||
$notensumme += $teilnote['grade'];
|
||||
$punktesumme += $teilnote['points'];
|
||||
$notensumme_gewichtet += $teilnote['grade'] * $teilnote['weight'];
|
||||
$punktesumme_gewichtet += $teilnote['points'] * $teilnote['weight'];
|
||||
$gewichtsumme += $teilnote['weight'];
|
||||
$anzahlnoten += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate grades points from notenschlüssel
|
||||
if (CIS_GESAMTNOTE_PUNKTE)
|
||||
{
|
||||
if (defined('CIS_GESAMTNOTE_GEWICHTUNG') && CIS_GESAMTNOTE_GEWICHTUNG)
|
||||
{
|
||||
// Lehreinheitsgewichtung
|
||||
$punkte_vorschlag = round($punktesumme_gewichtet / $gewichtsumme, 2);
|
||||
$notenschluessel = new notenschluessel();
|
||||
$note_vorschlag = $notenschluessel->getNote($punkte_vorschlag, $lv_id, $sem_kurzbz);
|
||||
}
|
||||
else
|
||||
{
|
||||
$punkte_vorschlag = round($punktesumme / $anzahlnoten, 2);
|
||||
$notenschluessel = new notenschluessel();
|
||||
$note_vorschlag = $notenschluessel->getNote($punkte_vorschlag, $lv_id, $sem_kurzbz);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defined('CIS_GESAMTNOTE_GEWICHTUNG') && CIS_GESAMTNOTE_GEWICHTUNG)
|
||||
{
|
||||
$note_vorschlag = round($notensumme_gewichtet / $gewichtsumme);
|
||||
}
|
||||
else
|
||||
{
|
||||
$note_vorschlag = round($notensumme / $anzahlnoten);
|
||||
}
|
||||
}
|
||||
|
||||
$student->note_vorschlag = $note_vorschlag;
|
||||
}
|
||||
}
|
||||
|
||||
// get all prüfungen with noten held in that semester in that lva
|
||||
$pruefungen = $this->PruefungModel->getPruefungenByLvStudiensemester($lv_id, $sem_kurzbz);
|
||||
$pruefungenData = $this->getDataOrTerminateWithError($pruefungen);
|
||||
|
||||
$pruefungenData = getData($pruefungen);
|
||||
// $pruefungenData = $this->getDataOrTerminateWithError($pruefungen);
|
||||
$this->addMeta('$pruefungenData', $pruefungenData);
|
||||
$this->terminateWithSuccess(array($studentenData, $pruefungenData, DOMAIN, $grades));
|
||||
}
|
||||
|
||||
public function getNoten() {
|
||||
$this->load->model('education/Note_model', 'NoteModel');
|
||||
|
||||
$result = $this->NoteModel->getAll();
|
||||
$result = $this->NoteModel->getAllActive();
|
||||
$noten = $this->getDataOrTerminateWithError($result);
|
||||
$this->terminateWithSuccess($noten);
|
||||
}
|
||||
@@ -101,13 +200,345 @@ class Noten extends FHCAPI_Controller
|
||||
public function saveStudentenNoten() {
|
||||
$result = $this->getPostJSON();
|
||||
|
||||
if(!property_exists($result, 'password')) {
|
||||
if(!property_exists($result, 'sem_kurzbz') || !property_exists($result, 'lv_id') ||
|
||||
!property_exists($result, 'password') || !property_exists($result, 'noten')) {
|
||||
$this->terminateWithError($this->p->t('global', 'missingParameters'), 'general');
|
||||
}
|
||||
|
||||
if(!$this->AuthLib->checkUserAuthByUsernamePassword(getAuthUID(), $result->password)->retval) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongPassword'), 'general');
|
||||
}
|
||||
|
||||
$lv_id = $result->lv_id;
|
||||
$sem_kurzbz = $result->sem_kurzbz;
|
||||
|
||||
$ret = [];
|
||||
|
||||
// TODO: also do something similar when updating/creating a pruefung!
|
||||
|
||||
foreach($result->noten as $note) {
|
||||
$lvgesamtnote = new lvgesamtnote();
|
||||
if ($lvgesamtnote->load($lv_id, $note->uid, $sem_kurzbz))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
if (defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE)
|
||||
{
|
||||
// TODO: infomail an studiengangsassistenz
|
||||
// Enthalten sind MatrikelNr., Vorname, Nachname und Note der neuen oder geänderten Einträge.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
$this->terminateWithSuccess($ret);
|
||||
}
|
||||
|
||||
public function getNotenvorschlagStudent() {
|
||||
// TODO: Notenvorschlag laden allgemeiner Endpunkt, der im Backend mit Logik (z.B. Moodle) angepasst werden kann.
|
||||
|
||||
$this->terminateWithSuccess();
|
||||
}
|
||||
|
||||
public function saveStudentPruefung() { // einzelne pruefung speichern
|
||||
$result = $this->getPostJSON();
|
||||
|
||||
if(!property_exists($result, 'datum') || !property_exists($result, 'lva_id') ||
|
||||
!property_exists($result, 'student_uid') || !property_exists($result, 'note')) {
|
||||
$this->terminateWithError($this->p->t('global', 'missingParameters'), 'general');
|
||||
}
|
||||
|
||||
// TODO: send & save noten
|
||||
$student_uid = $result->student_uid;
|
||||
$note = $result->note;
|
||||
$punkte = $result->punkte;
|
||||
$datum = $result->datum;
|
||||
$lva_id = $result->lva_id;
|
||||
$lehreinheit_id = $result->lehreinheit_id;
|
||||
|
||||
$this.$this->terminateWithSuccess($this->AuthLib->checkUserAuthByUsernamePassword(getAuthUID(), $result->password));
|
||||
// $lehreinheit_id_pr = $result->lehreinheit_id_pr; // todo: very rare, refactor?
|
||||
$stsem = $result->sem_kurzbz;
|
||||
$typ = $result->typ;
|
||||
|
||||
$jetzt = date("Y-m-d H:i:s");
|
||||
|
||||
// nachpruefungeintragen.php script calls query on campus.student_lehrveranstaltung to find a
|
||||
// lehreinheit_id for lva_id -> lehreinheit should be determined prior to that in new benotungstool
|
||||
// by retrieving it from students row in campus.vw_student_lehrveranstaltung earlier on
|
||||
|
||||
// $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem);
|
||||
$lehreinheit_id = $result->lehreinheit_id;
|
||||
|
||||
$punkte = str_replace(',', '.', $punkte);
|
||||
|
||||
if($punkte!='')
|
||||
{
|
||||
// Bei Punkteeingabe wird die Note nochmals geprueft und ggf korrigiert
|
||||
$notenschluessel = new notenschluessel();
|
||||
$note_pruef = $notenschluessel->getNote($punkte, $lva_id, $stsem);
|
||||
if($note_pruef!=$note)
|
||||
{
|
||||
$note = $note_pruef;
|
||||
$note_dirty=true;
|
||||
}
|
||||
}
|
||||
|
||||
if($note=='')
|
||||
$note = 9;
|
||||
|
||||
$old_note = $note;
|
||||
|
||||
//Laden der Lehrveranstaltung
|
||||
$lv_obj = new lehrveranstaltung();
|
||||
if(!$lv_obj->load($lva_id))
|
||||
die($lv_obj->errormsg);
|
||||
|
||||
//Studiengang laden
|
||||
$stg_obj = new studiengang($lv_obj->studiengang_kz);
|
||||
|
||||
// $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte);
|
||||
$savedPruefung = null;
|
||||
$extraPruefung = null;
|
||||
if($typ == "Termin2") {
|
||||
|
||||
$pr = new Pruefung();
|
||||
|
||||
// Wenn eine Pruefung angelegt wird, wird zuerst eine Pruefung mit 1. Termin angelegt
|
||||
// und dort die Zeugnisnote gespeichert
|
||||
if($pr->getPruefungen($student_uid, "Termin1", $lva_id, $stsem))
|
||||
{
|
||||
if ($pr->result)
|
||||
{
|
||||
// TODO: is this filler if branch really necessary?
|
||||
$termin1 = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$lvnote = new lvgesamtnote();
|
||||
// update Termin1 note
|
||||
if ($lvnote->load($lva_id, $student_uid, $stsem))
|
||||
{
|
||||
$pr_note = $lvnote->note;
|
||||
$pr_punkte = $lvnote->punkte;
|
||||
$benotungsdatum = $lvnote->benotungsdatum;
|
||||
}
|
||||
else // set Termin1 note to "noch nicht eingetragen"
|
||||
{
|
||||
$pr_note = 9;
|
||||
$pr_punkte = '';
|
||||
$benotungsdatum = $jetzt;
|
||||
}
|
||||
|
||||
$pr_1 = new Pruefung();
|
||||
$pr_1->lehreinheit_id = $lehreinheit_id;
|
||||
$pr_1->student_uid = $student_uid;
|
||||
$pr_1->mitarbeiter_uid = getAuthUID();
|
||||
$pr_1->note = $pr_note;
|
||||
$pr_1->punkte = $pr_punkte;
|
||||
$pr_1->pruefungstyp_kurzbz = "Termin1";
|
||||
$pr_1->datum = $benotungsdatum;
|
||||
$pr_1->anmerkung = "";
|
||||
$pr_1->insertamum = $jetzt;
|
||||
$pr_1->insertvon = getAuthUID();
|
||||
$pr_1->updateamum = null;
|
||||
$pr_1->updatevon = null;
|
||||
$pr_1->ext_id = null;
|
||||
$pr_1->new = true;
|
||||
$pr_1->save();
|
||||
$extraPruefung = $pr_1; //"neu T1";
|
||||
}
|
||||
|
||||
$prTermin2 = new Pruefung();
|
||||
$pr_2 = new Pruefung();
|
||||
|
||||
// Die Pruefung wird als Termin2 eingetragen
|
||||
if ($prTermin2->getPruefungen($student_uid, 'Termin2', $lva_id, $stsem))
|
||||
{
|
||||
if ($prTermin2->result)
|
||||
{
|
||||
$pr_2->load($prTermin2->result[0]->pruefung_id);
|
||||
$pr_2->new = null;
|
||||
$pr_2->updateamum = $jetzt;
|
||||
$pr_2->updatevon = getAuthUID();
|
||||
$old_note = $pr_2->note;
|
||||
$pr_2->note = $note;
|
||||
$pr_2->punkte = $punkte;
|
||||
$pr_2->datum = $datum;
|
||||
$pr_2->anmerkung = "";
|
||||
$savedPruefung = $pr_2;//"update T2";
|
||||
}
|
||||
else
|
||||
{
|
||||
$pr_2->lehreinheit_id = $lehreinheit_id;
|
||||
$pr_2->student_uid = $student_uid;
|
||||
$pr_2->mitarbeiter_uid = getAuthUID();
|
||||
$pr_2->note = $note;
|
||||
$pr_2->punkte = $punkte;
|
||||
$pr_2->pruefungstyp_kurzbz = $typ;
|
||||
$pr_2->datum = $datum;
|
||||
$pr_2->anmerkung = "";
|
||||
$pr_2->insertamum = $jetzt;
|
||||
$pr_2->insertvon = getAuthUID();
|
||||
$pr_2->updateamum = null;
|
||||
$pr_2->updatevon = null;
|
||||
$pr_2->ext_id = null;
|
||||
$pr_2->new = true;
|
||||
$old_note = -1;
|
||||
$savedPruefung = $pr_2;//"new T2";
|
||||
}
|
||||
$pr_2->save();
|
||||
}
|
||||
}
|
||||
|
||||
} else if($typ == "Termin3") {
|
||||
|
||||
$prTermin3 = new Pruefung();
|
||||
$pr_3 = new Pruefung();
|
||||
|
||||
if ($prTermin3->getPruefungen($student_uid, 'Termin3', $lva_id, $stsem))
|
||||
{
|
||||
if ($prTermin3->result)
|
||||
{
|
||||
$pr_3->load($prTermin3->result[0]->pruefung_id);
|
||||
$pr_3->new = null;
|
||||
$pr_3->updateamum = $jetzt;
|
||||
$pr_3->updatevon = getAuthUID();
|
||||
$old_note = $pr_3->note;
|
||||
$pr_3->note = $note;
|
||||
$pr_3->punkte = $punkte;
|
||||
$pr_3->datum = $datum;
|
||||
$pr_3->anmerkung = "";
|
||||
$savedPruefung = $pr_3; //"update T3";
|
||||
}
|
||||
else
|
||||
{
|
||||
$pr_3->lehreinheit_id = $lehreinheit_id;
|
||||
$pr_3->student_uid = $student_uid;
|
||||
$pr_3->mitarbeiter_uid = getAuthUID();
|
||||
$pr_3->note = $note;
|
||||
$pr_3->punkte = $punkte;
|
||||
$pr_3->pruefungstyp_kurzbz = $typ;
|
||||
$pr_3->datum = $datum;
|
||||
$pr_3->anmerkung = "";
|
||||
$pr_3->insertamum = $jetzt;
|
||||
$pr_3->insertvon = getAuthUID();
|
||||
$pr_3->updateamum = null;
|
||||
$pr_3->updatevon = null;
|
||||
$pr_3->ext_id = null;
|
||||
$pr_3->new = true;
|
||||
$old_note = -1;
|
||||
$savedPruefung = $pr_3; //"new T3";
|
||||
}
|
||||
$pr_3->save();
|
||||
}
|
||||
} else {
|
||||
$this->terminateWithError("typ is not termin2 or termin3", 'general');
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Gesamtnote updaten
|
||||
$lvgesamtnote = new lvgesamtnote();
|
||||
if (!$lvgesamtnote->load($lva_id, $student_uid, $stsem))
|
||||
{
|
||||
$lvgesamtnote->student_uid = $student_uid;
|
||||
$lvgesamtnote->lehrveranstaltung_id = $lva_id;
|
||||
$lvgesamtnote->studiensemester_kurzbz = $stsem;
|
||||
$lvgesamtnote->note = $note;
|
||||
$lvgesamtnote->punkte = $punkte;
|
||||
$lvgesamtnote->mitarbeiter_uid = getAuthUID();
|
||||
$lvgesamtnote->benotungsdatum = $jetzt;
|
||||
$lvgesamtnote->freigabedatum = null;
|
||||
$lvgesamtnote->freigabevon_uid = null;
|
||||
$lvgesamtnote->bemerkung = null;
|
||||
$lvgesamtnote->updateamum = null;
|
||||
$lvgesamtnote->updatevon = null;
|
||||
$lvgesamtnote->insertamum = $jetzt;
|
||||
$lvgesamtnote->insertvon = getAuthUID();
|
||||
$new = true;
|
||||
// $response = "neu";
|
||||
}
|
||||
else
|
||||
{
|
||||
$lvgesamtnote->note = $note;
|
||||
$lvgesamtnote->punkte = $punkte;
|
||||
$lvgesamtnote->benotungsdatum = $jetzt;
|
||||
$lvgesamtnote->updateamum = $jetzt;
|
||||
$lvgesamtnote->updatevon = getAuthUID();
|
||||
$new = false;
|
||||
// if ($lvgesamtnote->freigabedatum)
|
||||
// $response = "update_f";
|
||||
// else
|
||||
// $response = "update";
|
||||
}
|
||||
|
||||
$saved = $lvgesamtnote->save($new);
|
||||
|
||||
$this->terminateWithSuccess(array($savedPruefung, $lvgesamtnote, $saved, $extraPruefung));
|
||||
}
|
||||
|
||||
public function saveNotenvorschlag() {
|
||||
$result = $this->getPostJSON();
|
||||
|
||||
if(!property_exists($result, 'lv_id') || !property_exists($result, 'sem_kurzbz') ||
|
||||
!property_exists($result, 'student_uid') || !property_exists($result, 'note')) {
|
||||
$this->terminateWithError($this->p->t('global', 'missingParameters'), 'general');
|
||||
}
|
||||
|
||||
$lv_id = $result->lv_id;
|
||||
$student_uid = $result->student_uid;
|
||||
$sem_kurzbz = $result->sem_kurzbz;
|
||||
$note = $result->note;
|
||||
|
||||
$lvgesamtnote = new lvgesamtnote();
|
||||
if (!$lvgesamtnote->load($lv_id, $student_uid, $sem_kurzbz))
|
||||
{
|
||||
$lvgesamtnote->student_uid = $student_uid;
|
||||
$lvgesamtnote->lehrveranstaltung_id = $lv_id;
|
||||
$lvgesamtnote->studiensemester_kurzbz = $sem_kurzbz;
|
||||
$lvgesamtnote->note = trim($note);
|
||||
$lvgesamtnote->mitarbeiter_uid = getAuthUID();
|
||||
$lvgesamtnote->benotungsdatum = date("Y-m-d H:i:s");
|
||||
$lvgesamtnote->freigabedatum = null;
|
||||
$lvgesamtnote->freigabevon_uid = null;
|
||||
$lvgesamtnote->bemerkung = null;
|
||||
$lvgesamtnote->updateamum = null;
|
||||
$lvgesamtnote->updatevon = null;
|
||||
$lvgesamtnote->insertamum = date("Y-m-d H:i:s");
|
||||
$lvgesamtnote->insertvon = getAuthUID();
|
||||
$lvgesamtnote->punkte =// TODO: deprecated?
|
||||
$new = true;
|
||||
$response = "neu";
|
||||
}
|
||||
else
|
||||
{
|
||||
$lvgesamtnote->note = trim($note);
|
||||
$lvgesamtnote->punkte = null; // TODO: deprecated?
|
||||
$lvgesamtnote->benotungsdatum = date("Y-m-d H:i:s");
|
||||
$lvgesamtnote->updateamum = date("Y-m-d H:i:s");
|
||||
$lvgesamtnote->updatevon = getAuthUID();
|
||||
$new = false;
|
||||
if ($lvgesamtnote->freigabedatum)
|
||||
$response = "update_f";
|
||||
else
|
||||
$response = "update";
|
||||
}
|
||||
if (!$lvgesamtnote->save($new))
|
||||
$ret = $lvgesamtnote->errormsg;
|
||||
else
|
||||
$ret = $response;
|
||||
|
||||
$lvgesamtnote->load($lv_id, $student_uid, $sem_kurzbz);
|
||||
|
||||
$this->terminateWithSuccess(array($ret, $lvgesamtnote));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -303,4 +303,26 @@ EOSQL;
|
||||
|
||||
return $this->execQuery($query, $params);
|
||||
}
|
||||
|
||||
public function getAllLehreinheitenForLvaAndMaUid($lva_id, $ma_uid, $sem_kurzbz)
|
||||
{
|
||||
$query = "SELECT DISTINCT tbl_lehreinheitmitarbeiter.lehreinheit_id, tbl_lehreinheit.lehrveranstaltung_id, tbl_lehreinheit.lehrform_kurzbz,
|
||||
tbl_lehreinheitmitarbeiter.mitarbeiter_uid,
|
||||
tbl_lehreinheitgruppe.semester,
|
||||
tbl_lehreinheitgruppe.verband,
|
||||
tbl_lehreinheitgruppe.gruppe,
|
||||
tbl_lehreinheitgruppe.gruppe_kurzbz,
|
||||
tbl_lehrveranstaltung.kurzbz,
|
||||
tbl_studiengang.kurzbzlang,
|
||||
(SELECT COUNT(DISTINCT datum) FROM campus.vw_stundenplan WHERE lehreinheit_id = lehre.tbl_lehreinheit.lehreinheit_id) as termincount,
|
||||
(SELECT COUNT(*) FROM campus.vw_student_lehrveranstaltung WHERE lehreinheit_id = lehre.tbl_lehreinheit.lehreinheit_id) as studentcount
|
||||
FROM lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
|
||||
JOIN lehre.tbl_lehreinheitgruppe USING(lehreinheit_id)
|
||||
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
|
||||
JOIN public.tbl_studiengang ON (tbl_lehreinheitgruppe.studiengang_kz = tbl_studiengang.studiengang_kz)
|
||||
WHERE lehrveranstaltung_id = ? AND studiensemester_kurzbz = ? AND mitarbeiter_uid = ?
|
||||
ORDER BY tbl_lehreinheitgruppe.gruppe_kurzbz";
|
||||
|
||||
return $this->execQuery($query, [$lva_id, $sem_kurzbz, $ma_uid]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +316,8 @@ class Lehrveranstaltung_model extends DB_Model
|
||||
(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,
|
||||
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as kuerzel, tbl_studiengang.orgform_kurzbz, vw_student_lehrveranstaltung.semester, vw_student_lehrveranstaltung.studiensemester_kurzbz, vw_student_lehrveranstaltung.bezeichnung
|
||||
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as kuerzel, tbl_studiengang.orgform_kurzbz, vw_student_lehrveranstaltung.semester, vw_student_lehrveranstaltung.studiensemester_kurzbz, vw_student_lehrveranstaltung.bezeichnung,
|
||||
campus.vw_student_lehrveranstaltung.lehreinheit_id
|
||||
|
||||
FROM
|
||||
campus.vw_student_lehrveranstaltung
|
||||
@@ -343,7 +344,7 @@ class Lehrveranstaltung_model extends DB_Model
|
||||
|
||||
$query .=
|
||||
" ORDER BY nachname, vorname, person_id, tbl_bisio.bis DESC";
|
||||
|
||||
|
||||
return $this->execQuery($query, array($studiensemester_kurzbz, $lehrveranstaltung_id));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ class Note_model extends DB_Model
|
||||
$this->pk = 'note';
|
||||
}
|
||||
|
||||
public function getAll() {
|
||||
public function getAllActive() {
|
||||
$qry ="SELECT *
|
||||
FROM lehre.tbl_note";
|
||||
FROM lehre.tbl_note
|
||||
WHERE aktiv = true";
|
||||
|
||||
return $this->execReadOnlyQuery($qry);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ $includesArray = array(
|
||||
'vue3' => true,
|
||||
'primevue3' => true,
|
||||
'customCSSs' => array(
|
||||
'vendor/vuejs/vuedatepicker_css/main.css',
|
||||
'public/css/components/verticalsplit.css',
|
||||
'public/css/components/searchbar/searchbar.css',
|
||||
'public/css/Fhc.css',
|
||||
|
||||
@@ -36,24 +36,18 @@ export default {
|
||||
url: `/api/frontend/v1/Lehre/Pruefungen/${lehrveranstaltung_id}`
|
||||
};
|
||||
},
|
||||
getStudentenNoten(lv_id, sem_kurzbz) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Noten/getStudentenNoten',
|
||||
params: { lv_id, sem_kurzbz }
|
||||
};
|
||||
},
|
||||
getNoten(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Noten/getNoten'
|
||||
};
|
||||
},
|
||||
getZugewieseneLv(uid, sem_kurzbz){
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Lehre/getZugewieseneLv',
|
||||
params: { uid, sem_kurzbz}
|
||||
};
|
||||
},
|
||||
getLeForLv(lv_id, sem_kurzbz) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Lehre/getLeForLv',
|
||||
params: { lv_id, sem_kurzbz }
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -29,11 +29,25 @@ export default {
|
||||
url: '/api/frontend/v1/Noten/getNoten'
|
||||
};
|
||||
},
|
||||
saveStudentenNoten(password) {
|
||||
saveStudentenNoten(password, noten, lv_id, sem_kurzbz) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Noten/saveStudentenNoten',
|
||||
params: { password }
|
||||
params: { password, noten, lv_id, sem_kurzbz }
|
||||
};
|
||||
},
|
||||
saveNotenvorschlag(lv_id, sem_kurzbz, student_uid, note) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Noten/saveNotenvorschlag',
|
||||
params: { lv_id, sem_kurzbz, student_uid, note }
|
||||
};
|
||||
},
|
||||
saveStudentPruefung(student_uid, note, punkte, datum, lva_id, lehreinheit_id, sem_kurzbz, typ){
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Noten/saveStudentPruefung',
|
||||
params: { student_uid, note, punkte, datum, lva_id, lehreinheit_id, sem_kurzbz, typ }
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import ApiLehre from "../../../api/factory/lehre.js";
|
||||
import ApiNoten from "../../../api/factory/noten.js";
|
||||
import ApiStudiensemester from "../../../api/factory/studiensemester.js";
|
||||
import BsModal from '../../Bootstrap/Modal.js';
|
||||
import VueDatePicker from '../../vueDatepicker.js.php';
|
||||
|
||||
export const Benotungstool = {
|
||||
name: "Benotungstool",
|
||||
@@ -10,7 +11,8 @@ export const Benotungstool = {
|
||||
BsModal,
|
||||
CoreFilterCmpt,
|
||||
Dropdown: primevue.dropdown,
|
||||
Password: primevue.password
|
||||
Password: primevue.password,
|
||||
Datepicker: VueDatePicker
|
||||
},
|
||||
props: {
|
||||
lv_id: {
|
||||
@@ -32,9 +34,18 @@ export const Benotungstool = {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedLehreinheit: null,
|
||||
lehreinheiten: null,
|
||||
tabulatorCanBeBuilt: false,
|
||||
selectedPruefungNote: null,
|
||||
selectedPruefungDate: new Date(), // v-model for pruefung edit datepicker
|
||||
pruefungStudent: null,
|
||||
pruefung: null,
|
||||
password: '',
|
||||
changedNotenCounter: 0,
|
||||
tabulatorUuid: Vue.ref(0),
|
||||
domain: '',
|
||||
teilnoten: null,
|
||||
lv: null,
|
||||
studenten: null,
|
||||
pruefungen: null,
|
||||
@@ -44,78 +55,311 @@ export const Benotungstool = {
|
||||
selectedLehrveranstaltung: null,
|
||||
tableBuiltResolve: null,
|
||||
notenOptions: null,
|
||||
notenOptionsLehre: null,
|
||||
notenOptionsPromise: null,
|
||||
tableBuiltPromise: null,
|
||||
notenTableOptions: {
|
||||
height: 700,
|
||||
index: 'student_uid',
|
||||
layout: 'fitDataStretch',
|
||||
placeholder: this.$p.t('global/noDataAvailable'),
|
||||
columns: [
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, widthGrow: 1},
|
||||
{title: 'UID', field: 'uid', tooltip: false, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4vorname')), field: 'vorname', tooltip: false, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4teilnoten')), field: 'teilnote', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4note')), field: 'note_vorschlag',
|
||||
editor: 'list',
|
||||
editorParams: {
|
||||
values: Vue.computed(()=>this.notenOptions.map(opt => {
|
||||
return {
|
||||
label: opt.bezeichnung,
|
||||
value: opt.note
|
||||
}
|
||||
}))
|
||||
},
|
||||
formatter: (cell) => {
|
||||
const value = cell.getValue()
|
||||
const match = this.notenOptions.find(opt => opt.note === value)
|
||||
return match ? match.bezeichnung : value
|
||||
},
|
||||
widthGrow: 1},
|
||||
{title: '', width: 50, hozAlign: 'center', formatter: this.arrowFormatter, cellClick: this.saveNote},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4lvnote')), field: 'lv_note',
|
||||
formatter: this.notenFormatter,
|
||||
widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4freigabe')), field: 'freigegeben', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4zeugnisnote')), field: 'note', formatter: this.notenFormatter, widthGrow: 1}
|
||||
// {title: Vue.computed(() => this.$p.t('benotungstool/c4termin1')), field: 'termin1', widthGrow: 1},
|
||||
// {title: Vue.computed(() => this.$p.t('benotungstool/c4termin2')), field: 'termin2', widthGrow: 1},
|
||||
// {title: Vue.computed(() => this.$p.t('benotungstool/c4termin3')), field: 'termin3', widthGrow: 1}
|
||||
],
|
||||
persistence: false,
|
||||
},
|
||||
notenTableOptions: null, // built later when noten are available
|
||||
notenTableEventHandlers: [{
|
||||
event: "tableBuilt",
|
||||
handler: async () => {
|
||||
this.tableBuiltResolve()
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "cellClick",
|
||||
handler: async (e, cell) => {
|
||||
|
||||
|
||||
{
|
||||
event: "cellClick",
|
||||
handler: async (e, cell) => {
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "cellEdited",
|
||||
handler: async (cell) => {
|
||||
const field = cell.getField()
|
||||
|
||||
if(field === 'note_vorschlag') {
|
||||
const rowData = cell.getRow().getData();
|
||||
const newValue = cell.getValue();
|
||||
const original = rowData._originalNoteVorschlag;
|
||||
|
||||
// If nothing was selected, restore
|
||||
if (newValue == null || newValue === "" || newValue === original) {
|
||||
// revert value
|
||||
cell.setValue(original, true);
|
||||
}
|
||||
|
||||
delete rowData._originalNoteVorschlag; // Clean up
|
||||
|
||||
const row = cell.getRow()
|
||||
row.reformat() // trigger reformat of arrow
|
||||
}
|
||||
}
|
||||
}
|
||||
]};
|
||||
},
|
||||
methods: {
|
||||
getNotenTableOptions() {
|
||||
return {
|
||||
height: 700,
|
||||
index: 'uid',
|
||||
layout: 'fitDataStretch',
|
||||
placeholder: this.$p.t('global/noDataAvailable'),
|
||||
columns: [
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, widthGrow: 1},
|
||||
{title: 'UID', field: 'uid', tooltip: false, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4vorname')), field: 'vorname', tooltip: false, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4teilnoten')), field: 'teilnote', widthGrow: 1, formatter: this.teilnotenFormatter},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4note')), field: 'note_vorschlag',
|
||||
editor: 'list',
|
||||
editorParams: (cell) => {
|
||||
// write original cell value into row to it can be retrieved if edit is cancelled without selection
|
||||
const rowData = cell.getRow().getData();
|
||||
rowData._originalNoteVorschlag = cell.getValue();
|
||||
|
||||
return {
|
||||
values: this.notenOptionsLehre.map(opt => ({
|
||||
label: opt.bezeichnung,
|
||||
value: opt.note
|
||||
}))
|
||||
};
|
||||
},
|
||||
editable: (cell) => {
|
||||
const rowData = cell.getRow().getData();
|
||||
const noteOption = this.notenOptions.find(opt => opt.note == rowData.note)
|
||||
if(!noteOption) return true
|
||||
|
||||
// also if student has any pruefungsnote disable noten selection
|
||||
if(this.pruefungen.find(p => p.student_uid == rowData.uid)) return false
|
||||
|
||||
return noteOption.lkt_ueberschreibbar
|
||||
},
|
||||
formatter: (cell) => {
|
||||
const rowData = cell.getRow().getData();
|
||||
const value = cell.getValue()
|
||||
const match = this.notenOptions?.find(opt => opt.note == value)
|
||||
const val = match ? match.bezeichnung : value
|
||||
const p = this.pruefungen.find(p => p.student_uid == rowData.uid)
|
||||
let style = ''
|
||||
|
||||
if(val === undefined) return ''
|
||||
if(p || !match?.lkt_ueberschreibbar) style = 'color: gray;font-style: italic; background-color: #f0f0f0;pointer-events: none;opacity: 0.6;user-select: none;cursor: not-allowed;'
|
||||
return '<div style="'+style+'">' + val + '</div>'
|
||||
},
|
||||
widthGrow: 1},
|
||||
{title: '', width: 50, hozAlign: 'center', formatter: this.arrowFormatter, cellClick: this.saveNote},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4lvnote')), field: 'lv_note',
|
||||
formatter: this.notenFormatter,
|
||||
widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4freigabe')), field: 'freigegeben', widthGrow: 1, formatter: this.freigabeFormatter},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4zeugnisnote')), field: 'note', formatter: this.notenFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('benotungstool/c4kommPruef')), field: 'kommPruef', widthGrow: 1, formatter: this.pruefungFormatter, hozAlign:"center", minWidth: 150}
|
||||
// {title: Vue.computed(() => this.$p.t('benotungstool/c4termin1')), field: 'termin1', widthGrow: 1},
|
||||
// {title: Vue.computed(() => this.$p.t('benotungstool/c4termin2')), field: 'termin2', widthGrow: 1},
|
||||
// {title: Vue.computed(() => this.$p.t('benotungstool/c4termin3')), field: 'termin3', widthGrow: 1}
|
||||
],
|
||||
persistence: false,
|
||||
}
|
||||
},
|
||||
parseDate(timestamp) {
|
||||
if(!timestamp) return null
|
||||
const [datePart, timePart] = timestamp.split(" ");
|
||||
const [year, month, day] = datePart.split("-").map(Number);
|
||||
const [hour, minute, second] = timePart.split(":").map(Number);
|
||||
return new Date(year, month - 1, day, hour, minute, second);
|
||||
},
|
||||
checkFreigabe(freigabedatum, benotungsdatum, uid) {
|
||||
if(!freigabedatum) {
|
||||
// check for change -> set freigabe to 'changed' on change
|
||||
return 'offen'
|
||||
} else if(benotungsdatum > freigabedatum) {
|
||||
return 'changed'
|
||||
} else {
|
||||
return 'ok'
|
||||
}
|
||||
},
|
||||
notenFormatter(cell) {
|
||||
const value = cell.getValue()
|
||||
const match = this.notenOptions.find(opt => opt.note === value)
|
||||
return match ? match.bezeichnung : value
|
||||
const field = cell.getField()
|
||||
let style = 'display: flex; justify-content: center; align-items: center; height: 100%;';
|
||||
// Wenn sich die Zeugnisnote von der von Ihnen freigegebenen Note unterscheidet,
|
||||
// wird erstere rot umrandet markiert.
|
||||
|
||||
|
||||
const data = cell.getData()
|
||||
if(field == 'note' && data.note && data.note != data.lv_note) {
|
||||
style += 'color:red; border-color:red; border-style:solid; border-width:1px;'
|
||||
}
|
||||
|
||||
const match = this.notenOptions.find(opt => opt.note == value)
|
||||
const val = match ? match.bezeichnung : value
|
||||
if(val) return '<div style="'+style+'">' + val + '</div>'
|
||||
else return ''
|
||||
|
||||
},
|
||||
freigabeFormatter(cell) {
|
||||
const value = cell.getValue()
|
||||
|
||||
if(value === 'ok') {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<i class="fa fa-circle-check" style="color:green"></i></div>'
|
||||
} else if (value === 'offen') {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<i class="fa-regular fa-circle"></i></div>'
|
||||
} else if (value === 'changed') {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<i class="fa fa-circle-check"></i></div>'
|
||||
}
|
||||
|
||||
return value
|
||||
},
|
||||
handlePasswordChanged(pw) {
|
||||
console.log('pw:', pw)
|
||||
// console.log('pw:', pw)
|
||||
},
|
||||
saveNote(e, cell) {
|
||||
saveNote(e, cell) { // Notenvorschlag freigeben
|
||||
const row = cell.getRow()
|
||||
const data = row.getData()
|
||||
|
||||
row.update({ note: data.note_vorschlag })
|
||||
if(!data.note_vorschlag) return
|
||||
this.$api.call(ApiNoten.saveNotenvorschlag(this.lv_id, this.sem_kurzbz, data.uid, data.note_vorschlag))
|
||||
.then((res) => {
|
||||
if (res.meta.status === 'success') {
|
||||
const s = this.studenten.find(s => s.uid === data.uid)
|
||||
this.teilnoten[s.uid].note_lv = data.note_vorschlag
|
||||
s.freigabedatum = this.parseDate(res.data[1]['freigabedatum'])
|
||||
s.benotungsdatum = this.parseDate(res.data[1]['benotungsdatum'])
|
||||
|
||||
s.freigegeben = this.checkFreigabe(s.freigabedatum, s.benotungsdatum, s.uid);
|
||||
|
||||
row.update({ lv_note: data.note_vorschlag })
|
||||
row.update({ freigegeben: 'changed' })
|
||||
row.reformat() // trigger reformat of arrow
|
||||
this.changedNotenCounter++;
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
},
|
||||
teilnotenFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
return '<div style="white-space: pre-line;">'+val+'</div>'
|
||||
},
|
||||
pruefungFormatter(cell) {
|
||||
const data = cell.getData()
|
||||
|
||||
const noteDef = data.note ? this.notenOptions.find(n => n.note == data.note) : null
|
||||
if(!data.note || !noteDef?.lkt_ueberschreibbar) {
|
||||
return ''
|
||||
}
|
||||
|
||||
// TODO: check for some time limit maybe? old pruefungen can be changed/created
|
||||
|
||||
// Create root row div
|
||||
const rowDiv = document.createElement('div');
|
||||
rowDiv.className = 'row';
|
||||
rowDiv.style.display = 'flex';
|
||||
rowDiv.style.justifyContent = 'center';
|
||||
rowDiv.style.alignItems = 'center';
|
||||
rowDiv.style.height = '100%';
|
||||
|
||||
function createCol(content) {
|
||||
const colDiv = document.createElement('div');
|
||||
colDiv.className = 'col-4';
|
||||
colDiv.style.justifyContent = 'center';
|
||||
colDiv.style.alignItems = 'center';
|
||||
colDiv.style.height = '100%';
|
||||
|
||||
if (typeof content === 'string') {
|
||||
colDiv.textContent = content;
|
||||
} else if (content instanceof HTMLElement) {
|
||||
colDiv.appendChild(content);
|
||||
}
|
||||
|
||||
return colDiv;
|
||||
}
|
||||
|
||||
const field = cell.getColumn().getField()
|
||||
if(data[field]) {
|
||||
const dateParts = data[field].datum.split('-')
|
||||
const date = `${dateParts[2]}.${dateParts[1]}.${dateParts[0]}`
|
||||
|
||||
// First column (date)
|
||||
rowDiv.appendChild(createCol(date));
|
||||
|
||||
// Second column (note_bezeichnung)
|
||||
rowDiv.appendChild(createCol(data[field].note_bezeichnung || ''));
|
||||
|
||||
if(field === 'kommPruef' || field === 'pruefungNr0') {// no actions on kommPruef allowed
|
||||
rowDiv.appendChild(createCol('')); // append empty col4 to have formatting similar
|
||||
return rowDiv
|
||||
}
|
||||
|
||||
// Third column (button)
|
||||
const button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary';
|
||||
button.textContent = 'Change'; // TODO: phrase
|
||||
button.addEventListener('click', () => {
|
||||
this.openPruefungModal(data, data[field]);
|
||||
});
|
||||
|
||||
rowDiv.appendChild(createCol(button));
|
||||
|
||||
return rowDiv;
|
||||
|
||||
} else if (field !== 'kommPruef' && field !== 'pruefungNr0') { // return new btn action
|
||||
const button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary';
|
||||
button.textContent = 'Add'; // TODO: phrase
|
||||
button.addEventListener('click', () => {
|
||||
this.openPruefungModal(data)
|
||||
});
|
||||
|
||||
rowDiv.appendChild(createCol(button));
|
||||
|
||||
return rowDiv;
|
||||
} else return ''
|
||||
},
|
||||
openPruefungModal(student, pruefung = null) {
|
||||
this.pruefungStudent = student
|
||||
this.pruefung = pruefung
|
||||
debugger
|
||||
if(this.pruefung?.datum) {
|
||||
const pruefungDateParts = this.pruefung?.datum?.split('-')
|
||||
|
||||
// new date obj so datepicker picks ob the change by ref
|
||||
const newDate = new Date()
|
||||
newDate.setFullYear(pruefungDateParts[0])
|
||||
newDate.setMonth(pruefungDateParts[1])
|
||||
newDate.setDate(pruefungDateParts[2])
|
||||
this.selectedPruefungDate = newDate
|
||||
} else {
|
||||
const newDate = new Date()
|
||||
newDate.setTime(Date.now())
|
||||
this.selectedPruefungDate = newDate
|
||||
}
|
||||
|
||||
if(this.pruefung?.note) {
|
||||
this.selectedPruefungNote = this.notenOptions.find(n => n.note == this.pruefung.note)
|
||||
} else {
|
||||
this.selectedPruefungNote = null
|
||||
}
|
||||
|
||||
this.$refs.modalContainerPruefung.show()
|
||||
},
|
||||
pruefungTitleFormatter(cell) {
|
||||
const col = cell.getColumn()
|
||||
if(col.getField() === "pruefungNr0") return this.$p.t('benotungstool/c4originalZnote')
|
||||
return col.getDefinition().title;
|
||||
},
|
||||
arrowFormatter(cell) {
|
||||
const row = cell.getRow()
|
||||
const data = row.getData()
|
||||
|
||||
if(!data.note_vorschlag || (data.note_vorschlag == data.lv_note)) { // uncolored arrow
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<i class="fa fa-arrow-right"></i></div>'
|
||||
}
|
||||
|
||||
// can save a notenvorschlag -> colored
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<i class="fa fa-arrow-right" style="color:#00649C"></i></div>'
|
||||
},
|
||||
@@ -130,41 +374,103 @@ export const Benotungstool = {
|
||||
tableResolve(resolve) {
|
||||
this.tableBuiltResolve = resolve
|
||||
},
|
||||
notenOptionsResolve(resolve) {
|
||||
this.notenOptionsResolve = resolve
|
||||
},
|
||||
setupData(data){
|
||||
this.studenten = data[0]
|
||||
this.pruefungen = data[1]
|
||||
this.studenten = data[0] ?? []
|
||||
this.studenten.forEach(s => s.pruefungen = [])
|
||||
this.pruefungen = data[1] ?? []
|
||||
this.domain = data[2]
|
||||
this.teilnoten = data[3]
|
||||
|
||||
this.pruefungen.forEach(p => {
|
||||
// contains notenvorschläge from moodle, lv_note
|
||||
this.teilnoten = data[3] ?? []
|
||||
|
||||
// let pruefungenRegularColCount = 0;
|
||||
const distinctPruefungsDates = []
|
||||
const cols = [...this.notenTableOptions.columns.slice(0, -1)];
|
||||
const kommCol = this.notenTableOptions.columns[this.notenTableOptions.columns.length - 1];
|
||||
|
||||
this.pruefungen?.forEach(p => {
|
||||
const student = this.studenten.find(s => s.uid === p.student_uid)
|
||||
|
||||
if(!student) return
|
||||
// TODO: fetch typen and remove hardcoded strings
|
||||
// TODO: dynamic amount of termin columns!
|
||||
// if(p.pruefungstyp_kurzbz == "Termin1") {
|
||||
// student.termin1 = p
|
||||
// } else if (p.pruefungstyp_kurzbz == "Termin2") {
|
||||
// student.termin2 = p
|
||||
// } else if (p.pruefungstyp_kurzbz == "Termin3") {
|
||||
// student.termin3 = p
|
||||
// }
|
||||
|
||||
// TODO: LE TEILNOTEN IN BACKEND LADEN, BERECHNEN UND VORSCHLAG PASTEN
|
||||
// if(p.negativ)
|
||||
if(!distinctPruefungsDates.includes(p.datum)) distinctPruefungsDates.push(p.datum)
|
||||
|
||||
// seperate kommPruefungen from previous pruefungen counts since the column count variability always ends with this
|
||||
if(p.pruefungstyp_kurzbz == 'kommPruef') {
|
||||
student['kommPruef'] = p
|
||||
} else {
|
||||
student.pruefungen.push(p)
|
||||
}
|
||||
|
||||
// if(student.pruefungen.length > pruefungenRegularColCount) pruefungenRegularColCount = student.pruefungen.length
|
||||
})
|
||||
|
||||
this.studenten.forEach(s => {
|
||||
s.email = this.buildMailToLink(s)
|
||||
|
||||
// TODO: check if note is überschreibbar!
|
||||
this.studenten?.forEach(s => {
|
||||
// sort students regular pruefungen by datum
|
||||
s.pruefungen.sort((p1, p2) => {
|
||||
if(p1.datum > p2.datum) {
|
||||
return 1
|
||||
} else if (p1.datum < p2.datum) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
// set the sorted pruefungen to their respective column fields
|
||||
s.pruefungen.forEach((p, i) => {
|
||||
s[p.datum] = p
|
||||
})
|
||||
|
||||
s.email = this.buildMailToLink(s)
|
||||
s.lv_note = this.teilnoten[s.uid].note_lv
|
||||
s.freigabedatum = this.parseDate(this.teilnoten[s.uid]['freigabedatum'])
|
||||
s.benotungsdatum = this.parseDate(this.teilnoten[s.uid]['benotungsdatum'])
|
||||
s.freigegeben = this.checkFreigabe(s.freigabedatum, s.benotungsdatum, s.uid);
|
||||
|
||||
const grades = this.teilnoten[s.uid].grades
|
||||
s.teilnote = ''
|
||||
grades.forEach(g => s.teilnote += g.text + ' ')
|
||||
|
||||
grades.forEach(g => {
|
||||
const notenOption = this.notenOptions.find(n=>n.note == g.grade)
|
||||
if(notenOption.positiv) s.teilnote += ('<span>'+g.text +'</span>'+ '<br/>')
|
||||
else s.teilnote += ('<span style="color: red;">'+g.text +'</span>'+ '<br/>')
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
distinctPruefungsDates.sort((d1, d2) => {
|
||||
if(d1 > d2) {
|
||||
return 1
|
||||
} else if (d1 < d2) {
|
||||
return -1
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})
|
||||
distinctPruefungsDates.forEach((date, index)=>{
|
||||
// TODO date format dd.mm.yyyy
|
||||
cols.push({
|
||||
title: date,//this.$p.t('benotungstool/pruefungNr', [index+1]),
|
||||
field: date,
|
||||
formatter: this.pruefungFormatter,
|
||||
titleFormatter: this.pruefungTitleFormatter,
|
||||
hozAlign:"center",
|
||||
widthGrow: 1,
|
||||
minWidth: 150
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
cols.push(kommCol) // keep kommPruef Col as last
|
||||
|
||||
this.$refs.notenTable.tabulator.clearSort()
|
||||
this.$refs.notenTable.tabulator.setColumns(this.notenTableOptions.columns)
|
||||
this.$refs.notenTable.tabulator.setColumns(cols)
|
||||
this.$refs.notenTable.tabulator.setData(this.studenten);
|
||||
this.$refs.notenTable.tabulator.redraw(true);
|
||||
},
|
||||
loadNoten(lv_id, sem_kurzbz) {
|
||||
this.$api.call(ApiNoten.getStudentenNoten(lv_id, sem_kurzbz))
|
||||
@@ -184,10 +490,9 @@ export const Benotungstool = {
|
||||
this.notenTableOptions.height = window.visualViewport.height - rect.top
|
||||
this.$refs.notenTable.tabulator.setHeight(this.notenTableOptions.height)
|
||||
},
|
||||
async setupCreated() {
|
||||
setupCreated() {
|
||||
// fetch lva dropdown
|
||||
this.$api.call(ApiLehre.getZugewieseneLv(this.viewData?.uid, this.sem_kurzbz)).then(res => {
|
||||
console.log(res)
|
||||
this.lehrveranstaltungen = res.data
|
||||
|
||||
// build dropdown option string
|
||||
@@ -198,24 +503,66 @@ export const Benotungstool = {
|
||||
this.selectedLehrveranstaltung = this.lehrveranstaltungen.find(lva => lva.lehrveranstaltung_id == this.lv_id)
|
||||
})
|
||||
|
||||
//fetch sem_kurzbz dropdown
|
||||
this.$api.call(ApiLehre.getLeForLv(this.lv_id, this.sem_kurzbz)).then(res => {
|
||||
|
||||
const data = []
|
||||
// TODO: could be done on server in some shared function, copied from anw extension for now
|
||||
res.data?.retval?.forEach(entry => {
|
||||
|
||||
const existing = data.find(e => e.lehreinheit_id === entry.lehreinheit_id)
|
||||
if (existing) {
|
||||
// supplement info
|
||||
existing.infoString += ', '
|
||||
if (entry.gruppe_kurzbz !== null) {
|
||||
existing.infoString += entry.gruppe_kurzbz
|
||||
} else {
|
||||
existing.infoString += entry.kurzbzlang + '-' + entry.semester
|
||||
+ (entry.verband ? entry.verband : '')
|
||||
+ (entry.gruppe ? entry.gruppe : '')
|
||||
}
|
||||
} else {
|
||||
// entries are supposed to be fetched ordered by non null gruppe_kurzbz first
|
||||
// so a new entry will always start with those groups, others are appended afterwards
|
||||
entry.infoString = entry.kurzbz + ' - ' + entry.lehrform_kurzbz + ' - '
|
||||
if (entry.gruppe_kurzbz !== null) {
|
||||
entry.infoString += entry.gruppe_kurzbz
|
||||
} else {
|
||||
entry.infoString += entry.kurzbzlang + '-' + entry.semester
|
||||
+ (entry.verband ? entry.verband : '')
|
||||
+ (entry.gruppe ? entry.gruppe : '')
|
||||
}
|
||||
|
||||
data.push(entry)
|
||||
}
|
||||
})
|
||||
|
||||
data.forEach(entry => {
|
||||
entry.infoString += ' | 👥' + entry.studentcount + ' | 📅' + entry.termincount
|
||||
})
|
||||
|
||||
this.lehreinheiten = [...data]
|
||||
|
||||
})
|
||||
|
||||
// fetch sem_kurzbz dropdown
|
||||
this.$api.call(ApiStudiensemester.getStudiensemester()).then(res => {
|
||||
this.studiensemester = res.data[0]
|
||||
this.selectedSemester = this.studiensemester.find(sem => sem.studiensemester_kurzbz === this.sem_kurzbz)
|
||||
})
|
||||
|
||||
// fetch noten dropdown
|
||||
await this.$api.call(ApiNoten.getNoten()).then(res => {
|
||||
this.$api.call(ApiNoten.getNoten()).then(res => {
|
||||
this.notenOptions = res.data
|
||||
this.notenOptionsLehre = res.data.filter(n => n.lehre === true)
|
||||
this.notenTableOptions = this.getNotenTableOptions()
|
||||
this.tabulatorCanBeBuilt = true // because promises would be more work and not much better here
|
||||
})
|
||||
|
||||
},
|
||||
async setupMounted() {
|
||||
this.tableBuiltPromise = new Promise(this.tableResolve)
|
||||
await this.tableBuiltPromise
|
||||
|
||||
this.loadNoten(this.lv_id, this.sem_kurzbz)
|
||||
|
||||
this.calcMaxTableHeight()
|
||||
|
||||
},
|
||||
@@ -241,8 +588,20 @@ export const Benotungstool = {
|
||||
}
|
||||
})
|
||||
|
||||
// reload data
|
||||
this.loadNoten(this.lv_id, e.value.studiensemester_kurzbz)
|
||||
// diff lv_id -> reload zugewiesene lv
|
||||
this.$api.call(ApiLehre.getZugewieseneLv(this.viewData?.uid, this.sem_kurzbz)).then(res => {
|
||||
this.lehrveranstaltungen = res.data
|
||||
|
||||
// build dropdown option string
|
||||
this.lehrveranstaltungen.forEach(lva => {
|
||||
lva.fullString = `${lva.stg_kurzbz} - ${lva.lv_semester}: ${lva.lv_bezeichnung}`
|
||||
})
|
||||
|
||||
this.selectedLehrveranstaltung = this.lehrveranstaltungen.find(lva => lva.lehrveranstaltung_id == this.lv_id)
|
||||
}).then(()=>{
|
||||
// reload data
|
||||
this.loadNoten(this.lv_id, e.value.studiensemester_kurzbz)
|
||||
})
|
||||
|
||||
},
|
||||
getOptionLabel(option) {
|
||||
@@ -251,23 +610,146 @@ export const Benotungstool = {
|
||||
getOptionLabelLv(option) {
|
||||
return option.fullString
|
||||
},
|
||||
saveNoteneingabe() {
|
||||
getOptionLabelLe(option) {
|
||||
return option.infoString
|
||||
},
|
||||
savePruefungEingabe() {
|
||||
const year = this.selectedPruefungDate.getFullYear();
|
||||
const month = String(this.selectedPruefungDate.getMonth() + 1).padStart(2, '0'); // Months are 0-based
|
||||
const day = String(this.selectedPruefungDate.getDate()).padStart(2, '0');
|
||||
const dateStr = `${year}-${month}-${day}`;
|
||||
|
||||
this.$api.call(ApiNoten.saveStudentenNoten(this.password))
|
||||
// TODO: test this hypothesis
|
||||
// first pruefung is always "Termin2" since normal note counts as Termin1
|
||||
const pOffset = this.pruefung === null && this.pruefungStudent.pruefungen.length === 0 ? 2 : 1
|
||||
const typ = this.pruefung ? this.pruefung.pruefungstyp_kurzbz : ('Termin'+(this.pruefungStudent.pruefungen.length + pOffset))
|
||||
|
||||
this.$api.call(ApiNoten.saveStudentPruefung(
|
||||
this.pruefungStudent.uid,
|
||||
this.selectedPruefungNote.note,
|
||||
this.pruefung?.punkte ?? '',
|
||||
dateStr,
|
||||
this.lv_id,
|
||||
this.pruefungStudent.lehreinheit_id,
|
||||
this.sem_kurzbz,
|
||||
typ
|
||||
)).then(res => {
|
||||
if(res.meta.status === 'success') {
|
||||
const s = this.studenten.find(s => s.uid === res.data[1]?.student_uid)
|
||||
console.log('old student freigabedatum', s.freigabedatum)
|
||||
console.log('old student benotungsdatum', s.benotungsdatum)
|
||||
|
||||
s.freigabedatum = this.parseDate(res.data[1]?.['freigabedatum'])
|
||||
s.benotungsdatum = this.parseDate(res.data[1]?.['benotungsdatum'])
|
||||
|
||||
console.log('new student freigabedatum', s.freigabedatum)
|
||||
console.log('new student benotungsdatum', s.benotungsdatum)
|
||||
s.freigegeben = this.checkFreigabe(s.freigabedatum, s.benotungsdatum, s.uid);
|
||||
|
||||
// todo: update student subject grade/lv_note
|
||||
s.lv_note = res.data[1]?.note
|
||||
|
||||
// find the exact student pruefung and update that
|
||||
|
||||
// add new pruefung to row
|
||||
if(res.data[0]?.new) {
|
||||
// TODO: if new pruefung was of typ "Termin2", "Termin1" shadow pruefung is not available
|
||||
this.handleAddNewTermin(res.data, s)
|
||||
} else { // update existing
|
||||
const oldIndex = s.pruefungen.findIndex(p => p.pruefung_id == res.data[0]?.pruefung_id)
|
||||
if(oldIndex !== -1) {
|
||||
s.pruefungen.splice(oldIndex, 1, res.data[0])
|
||||
s['pruefungNr'+oldIndex] = res.data[0]
|
||||
}
|
||||
}
|
||||
|
||||
// // TODO: manual row update!
|
||||
// const row = this.$refs.notenTable.tabulator.getRow(s.uid)
|
||||
// row.update()
|
||||
|
||||
this.$refs.notenTable.tabulator.redraw(true)
|
||||
|
||||
this.$fhcAlert.alertSuccess('Prüfung gespeichert') // TODO: phrase
|
||||
}
|
||||
})
|
||||
|
||||
this.$refs.modalContainerPruefung.hide()
|
||||
},
|
||||
handleAddNewTermin(data, student){
|
||||
|
||||
},
|
||||
saveNoteneingabe() {
|
||||
this.$api.call(ApiNoten.saveStudentenNoten(this.password, this.changedNoten, this.lv_id, this.sem_kurzbz))
|
||||
.then((res) => {
|
||||
if(res.meta.status === 'success') {
|
||||
this.$fhcAlert.alertSuccess('Noten gespeichert')
|
||||
}
|
||||
|
||||
res.data.forEach(d => {
|
||||
const s = this.studenten.find(s => s.uid === d.uid)
|
||||
s.freigabedatum = this.parseDate(d.freigabedatum)
|
||||
s.benotungsdatum = this.parseDate(d.benotungsdatum)
|
||||
s.freigegeben = this.checkFreigabe(s.freigabedatum, s.benotungsdatum, s.uid);
|
||||
})
|
||||
this.changedNotenCounter++;
|
||||
|
||||
this.$refs.notenTable.tabulator.redraw(true)
|
||||
})
|
||||
|
||||
this.$refs.modalContainerNotenSpeichern.hide()
|
||||
},
|
||||
openSaveModal() {
|
||||
this.$refs.modalContainerNotenSpeichern.show()
|
||||
},
|
||||
handleChangePruefungDatum(e) {
|
||||
// console.log('handleChangePruefungDatum', e)
|
||||
},
|
||||
handleChangePruefungNote(e) {
|
||||
// console.log(e)
|
||||
},
|
||||
getOptionLabelNotePruefung(option) {
|
||||
return option.bezeichnung
|
||||
},
|
||||
leChanged(e) {
|
||||
this.selectedLehreinheit = e.value
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
selectedLehreinheit(newVal) {
|
||||
if(!this.$refs.notenTable) return
|
||||
this.$refs.notenTable.tabulator.clearFilter();
|
||||
if(newVal) this.$refs.notenTable.tabulator.setFilter("lehreinheit_id", "=", newVal.lehreinheit_id);
|
||||
},
|
||||
getKommPruefCount(newVal) {
|
||||
if(this.$refs.notenTable?.tabulator && newVal > 0) {
|
||||
const kommPruefCol = this.$refs.notenTable?.tabulator.getColumn("kommPruef")
|
||||
kommPruefCol.show()
|
||||
} else if(this.$refs.notenTable?.tabulator && newVal == 0) {
|
||||
const kommPruefCol = this.$refs.notenTable?.tabulator.getColumn("kommPruef")
|
||||
kommPruefCol.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getKommPruefCount(){
|
||||
let counter = 0
|
||||
this.studenten?.forEach(s => {if(s['kommPruef']){counter++}})
|
||||
return counter
|
||||
},
|
||||
getSaveBtnClass() {
|
||||
return "btn btn-primary ml-2"
|
||||
// return !this.changedData.length ? "btn btn-secondary ml-2" : "btn btn-primary ml-2"
|
||||
},
|
||||
changedNoten() {
|
||||
const v = this.changedNotenCounter // hack to trigger computed
|
||||
const cs = this.studenten.reduce((acc, cur) => {
|
||||
const teilnote = this.teilnoten[cur.uid]
|
||||
if(teilnote.note_lv && (cur.benotungsdatum > cur.freigabedatum)) {
|
||||
acc.push(cur)
|
||||
}
|
||||
return acc
|
||||
}, [])
|
||||
return cs
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -287,12 +769,47 @@ export const Benotungstool = {
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button type="button" class="btn btn-primary" @click="saveNoteneingabe">{{ $p.t('global/noteneingabeBestätigen') }}</button>
|
||||
<button type="button" class="btn btn-primary" @click="saveNoteneingabe">{{ $p.t('benotungstool/noteneingabeBestätigen') }}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
|
||||
<bs-modal ref="modalContainerPruefung" class="bootstrap-prompt" dialogClass="modal-lg">
|
||||
<template v-slot:title>{{ $p.t('benotungstool/createPruefungFor') }} {{pruefungStudent?.vorname}} {{pruefungStudent?.nachname}}</template>
|
||||
<template v-slot:default>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-1 text-center">{{$p.t('benotungstool/c4date')}}:</div>
|
||||
<div class="col-6">
|
||||
<datepicker
|
||||
v-model="selectedPruefungDate"
|
||||
@update:model-value="handleChangePruefungDatum"
|
||||
:clearable="false"
|
||||
:time-picker="false"
|
||||
:text-input="true"
|
||||
:auto-apply="true">
|
||||
</datepicker>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row justify-content-center mt-4">
|
||||
<div class="col-1 text-center">{{$p.t('lehre/note')}}:</div>
|
||||
<div class="col-6">
|
||||
<Dropdown @change="handleChangePruefungNote" :placeholder="$p.t('lehre/note')"
|
||||
:style="{'width': '100%'}" :optionLabel="getOptionLabelNotePruefung"
|
||||
v-model="selectedPruefungNote" :options="notenOptionsLehre" showClear>
|
||||
<template #optionsgroup="slotProps">
|
||||
<div> {{ option.bezeichnung }} </div>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button type="button" class="btn btn-primary" @click="savePruefungEingabe">{{ $p.t('global/speichern') }}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<div class="col-4">
|
||||
<h2>{{$p.t('benotungstool/benotungstoolTitle')}}</h2>
|
||||
<h4>{{ lv?.bezeichnung }}</h4>
|
||||
</div>
|
||||
@@ -306,6 +823,18 @@ export const Benotungstool = {
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-2">
|
||||
<div class="col-lg-auto">
|
||||
<Dropdown @change="leChanged" :style="{'width': '100%'}" :optionLabel="getOptionLabelLe"
|
||||
v-model="selectedLehreinheit" :options="lehreinheiten" showClear>
|
||||
<template #optionsgroup="slotProps">
|
||||
<div> {{ option.infoString }} </div>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-2">
|
||||
<div class="col-lg-auto">
|
||||
<Dropdown @change="ssChanged" :style="{'width': '100%'}" :optionLabel="getOptionLabel"
|
||||
@@ -321,6 +850,7 @@ export const Benotungstool = {
|
||||
|
||||
|
||||
<core-filter-cmpt
|
||||
v-if="tabulatorCanBeBuilt"
|
||||
@uuidDefined="handleUuidDefined"
|
||||
:title="''"
|
||||
ref="notenTable"
|
||||
@@ -331,7 +861,7 @@ export const Benotungstool = {
|
||||
>
|
||||
<template #actions>
|
||||
<button @click="openSaveModal" role="button" :class="getSaveBtnClass">
|
||||
<i class="fa fa-save"></i>
|
||||
{{$p.t('benotungstool/approveGrades')}} <i class="fa fa-save"></i>
|
||||
</button>
|
||||
</template>
|
||||
</core-filter-cmpt>
|
||||
|
||||
+142
-2
@@ -42159,7 +42159,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'c4termin3',
|
||||
'phrase' => 'c4kommPruef',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
@@ -42295,7 +42295,147 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'pruefungNr',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Prüfung Nr. {0}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Examination No. {0}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'noteneingabeSpeichern',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Noteneingabe speichern',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Save note entry',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'noteneingabeSpeichern',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Noteneingabe speichern',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Save note entry',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'noteneingabeBestätigen',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Noten bestätigen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Confirm grades',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'createPruefungFor',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Prüfung erstellen für',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Create examination for',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'approveGrades',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Noten freigeben',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Approve Grades',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'benotungstool',
|
||||
'phrase' => 'c4originalZnote',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Ursprüngliche Zeugnisnote',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Original Transcript Grade',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
// CIS4 GESAMTNOTENEINGABE ENDE ------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user