From 9b3b571bd9127dc5e18dcc806574107e53f7218b Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 6 Oct 2022 08:55:11 +0200 Subject: [PATCH 001/175] Erweiterung Phrasen --- locale/de-AT/benotungstool.php | 1 + locale/en-US/benotungstool.php | 1 + 2 files changed, 2 insertions(+) diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index 3c8063936..a38aa31f3 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -171,6 +171,7 @@ $this->phrasen['benotungstool/zeunis']='Zeugnis'; $this->phrasen['benotungstool/handbuch']='Handbuch'; $this->phrasen['benotungstool/punkte']='Punkte'; $this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten Personenkennzeichen und Note aus der Notenliste (bzw. StudentenUid und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; +$this->phrasen['benotungstool/importAnweisungNachp']='Kopieren Sie die Spalten Personenkennzeichen, Datum und Note aus der Notenliste (bzw. StudentenUid, Datum und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; $this->phrasen['benotungstool/pruefung']='Prüfung'; $this->phrasen['benotungstool/notenlisteImport']='Notenliste für den LV-Noten-Import (Excel)'; $this->phrasen['benotungstool/bearbeitetvon']='Bearbeitet von'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index 17f78d2ba..72f29256e 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -170,6 +170,7 @@ $this->phrasen['benotungstool/zeunis']='Transcript'; $this->phrasen['benotungstool/handbuch']='Handbook'; $this->phrasen['benotungstool/punkte']='Points'; $this->phrasen['benotungstool/importAnweisung']='Copy the columns "personal identifier" and "grade" from the grade list (or "student ID number" and "grade" from the moodle export file) and insert them in the following field'; +$this->phrasen['benotungstool/importAnweisungNachp']='Copy the columns "personal identifier", "date" and "grade" from the grade list (or "student ID number", "date" and "grade" from the moodle export file) and insert them in the following field'; $this->phrasen['benotungstool/pruefung']='Examination'; $this->phrasen['benotungstool/notenlisteImport']='Grade list for the subject grade import (Excel)'; $this->phrasen['benotungstool/geaenderteNotenVorhanden']='There are changed grades. Please send the changes to the assistant by clicking "Approval"'; From 54411f4de776fe238e6bd78d5b570f5f1e371bfb Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 12 Oct 2022 15:06:07 +0200 Subject: [PATCH 002/175] Benotungstool: Importfunktion Termin2 --- .../benotungstool/lvgesamtnoteverwalten.php | 144 ++++++- .../benotungstool/nachpruefungeintragen.php | 390 +++++++++++------- 2 files changed, 392 insertions(+), 142 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 916f2b4e3..6a160c646 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -402,6 +402,7 @@ foreach ($noten_obj->result as $row) url += '&typ='+typ; url += '&'+ts; + $.ajax({ type:"GET", url: url, @@ -602,6 +603,42 @@ foreach ($noten_obj->result as $row) $('#noteimporttextarea').focus(); } + // **** + // * Oeffnet ein Fenster fuer den Import von Noten für die Nachprüfung aus dem Excel + // **** + function GradeImportNachp() + { + var str = "
"; + str += ""; + var anlegendiv = document.getElementById("nachpruefung_div"); + var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; + str += ''; + str += ''; + str += "
X
t('benotungstool/importAnweisungNachp');?>:
' onclick='saveGradeBulkNachp(\"Termin2\");'>"; + str += "
"; + anlegendiv.innerHTML = str; + anlegendiv.style.visibility = "visible"; + $('#noteimporttextareaNachp').focus(); + } + + // **** + // * Oeffnet ein Fenster fuer den Import von Noten für Termin3 aus dem Excel + // **** + function GradeImportTermin3() + { + var str = "
"; + str += ""; + var anlegendiv = document.getElementById("nachpruefung_div"); + var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; + str += ''; + str += ''; + str += "
X
t('benotungstool/importAnweisungNachp');?>:
' onclick='saveGradeBulkNachp(\"Termin3\");'>"; + str += "
"; + anlegendiv.innerHTML = str; + anlegendiv.style.visibility = "visible"; + $('#noteimporttextareaTermin3').focus(); + } + // Speichert die Noten ueber den Import function saveGradeBulk() { @@ -698,6 +735,105 @@ foreach ($noten_obj->result as $row) } } + // Speichert die Noten der Nachprüfung ueber den Import + function saveGradeBulkNachp(typ) + { + data = $('#noteimporttextareaNachp').val(); + closeDiv(); + + //Reihen ermitteln + var rows = data.split("\n"); + var i=0; + var params=''; + alertMsg = ''; + + var gradedata = {}; + var validGrades = ''; + + result as $row_note) + { + if ($row_note->lehre && $row_note->aktiv) + $gradesArray[] = '"' . $row_note->anmerkung . '"'; + } + // Output JS variable with valid grades + echo 'var validGrades = [' . implode(',', $gradesArray) . '];'; + } + ?> + + for(row in rows) + { + zeile = rows[row].split(" "); + + + + if (zeile[0]!='' && zeile[1]!='' && zeile[2]!='') + { + gradedata['student_uid_'+i]=zeile[0]; + gradedata['datumNachp_'+i]=zeile[1]; + + + i++; + } + } + + if (alertMsg != "") + alert(alertMsg); + + if (i>0) + { + + var jetzt = new Date(); + var ts = jetzt.getTime(); + var url= ''; + url += '&sammel=1'; + url += '&typ=' + typ; + url += '&submit=1&'+ts; + $.ajax({ + type:"POST", + url: url, + data: gradedata, + success:function(result) + { + var resp = result; + if (resp!='') + { + alert(resp); + } + window.location.reload(); + }, + error:function(result) + { + alert('Request Nachprüfung fehlgeschlagen'); + } + }); + + } + else + { + alert('t('benotungstool/hilfeImport');?>'); + } + } + //--> @@ -1052,11 +1188,15 @@ $htmlstring .= "" . $p->t('benotungstool/punkte') . ' / ' . $p->t('benotungs if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) { - $htmlstring .= "" . $p->t('benotungstool/nachpruefung') . ""; + $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
+ + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { - $htmlstring .= "" . $p->t('benotungstool/nachpruefung2') . ""; + $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
+ + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF') && CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) { diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 0ad985e76..81545a7f6 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -41,10 +41,15 @@ require_once('../../../../include/benutzerfunktion.class.php'); require_once('../../../../include/benutzer.class.php'); require_once('../../../../include/student.class.php'); require_once('../../../../include/notenschluessel.class.php'); +require_once('../../../../include/phrasen.class.php'); + if (!$db = new basis_db()) die('Fehler beim Herstellen der Datenbankverbindung'); +$sprache = getSprache(); +$p = new phrasen($sprache); + $user = get_uid(); if(!check_lektor($user)) @@ -52,6 +57,7 @@ if(!check_lektor($user)) $lehreinheit_id=''; +$lehreinheit_id_pr=''; if(isset($_GET['lvid']) && is_numeric($_GET['lvid'])) //Lehrveranstaltung_id $lvid = $_GET['lvid']; @@ -62,60 +68,17 @@ if(isset($_GET['lehreinheit_id']) && is_numeric($_GET['lehreinheit_id'])) //Lehr $lehreinheit_id = $_GET['lehreinheit_id']; if(isset($_GET['lehreinheit_id_pr']) && is_numeric($_GET['lehreinheit_id_pr'])) //Lehreinheit_id der pruefung - $lehreinheit_id = $_GET['lehreinheit_id_pr']; - -if(isset($_GET['datum'])) -{ - $datum = $_GET['datum']; - $datum_obj = new datum(); - $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); -} -else - die('Fehlerhafte Parameteruebergabe'); - -//Laden der Lehrveranstaltung -$lv_obj = new lehrveranstaltung(); -if(!$lv_obj->load($lvid)) - die($lv_obj->errormsg); - -//Studiengang laden -$stg_obj = new studiengang($lv_obj->studiengang_kz); + $lehreinheit_id_pr = $_GET['lehreinheit_id_pr']; if(isset($_GET['stsem'])) $stsem = $_GET['stsem']; else $stsem = ''; - -$uebung_id = (isset($_GET['uebung_id'])?$_GET['uebung_id']:''); -$uid = (isset($_GET['uid'])?$_GET['uid']:''); - //Studiensemester laden $stsem_obj = new studiensemester(); if($stsem=='') $stsem = $stsem_obj->getaktorNext(); -$student_uid = $_REQUEST["student_uid"]; - -$note = $_REQUEST["note"]; -if(isset($_REQUEST['punkte'])) - $punkte = $_REQUEST['punkte']; -else - $punkte = ''; - -$punkte = str_replace(',','.',$punkte); - -if($punkte!='') -{ - // Bei Punkteeingabe wird die Note nochmals geprueft und ggf korrigiert - $notenschluessel = new notenschluessel(); - $note_pruef = $notenschluessel->getNote($punkte, $lvid, $stsem); - if($note_pruef!=$note) - { - $note = $note_pruef; - $note_dirty=true; - } -} - if(!isset($_GET['typ'])) { $typ='Termin2'; @@ -128,16 +91,151 @@ else die('Typ ist ungueltig'); } -if($note=='') - $note = 9; - -$old_note = $note; - -// lvgesamtnote für studenten speichern -if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) +if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) +{ + foreach ($_POST as $row=>$val) + { + if(mb_strstr(mb_strtolower($row), 'student_uid_')) + { + $id=mb_substr($row, mb_strlen('student_uid_')); + + $student_uid = $_POST['student_uid_'.$id]; + $note = null; + $punkte = null; + $datum = null; + if(isset($_POST['note_'.$id])) + $note = $_POST['note_'.$id]; + elseif(isset($_POST['punkte_'.$id])) + $punkte = $_POST['punkte_'.$id]; + else + { + $response.="\nNote oder Punkte fehlen"; + continue; + } + $punkte=str_replace(',','.', $punkte); + + $datum = $_POST['datumNachp_'.$id]; + + // //check ob Matrikelnummer anstelle der student_uid übergeben wurde + // + // + // $student = new student(); + // + // + // $response2 = true; + // if (!$student->checkIfValidStudentUID($student_uid)) + // { + // //UID ermitteln + // if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) + // { + // $response2 = false; + // $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); + // continue; + // } + // } + + + $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); + + if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) + { + // echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . + // $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . "\n"; + + $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); + + echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . + $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . " response" . $response . "\n"; + // echo $response; + + } + else + { + echo "\n fehlende oder fehlerhafte Inputparameter"; + } + } + } + +} +else +{ + // Einzelupdate + + if(isset($_GET['datum']) ) + { + $datum = $_GET['datum']; + $datum_obj = new datum(); + $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); + } + + // echo "Variante Einzel"; + else + die('Fehlerhafte Parameteruebergabe'); + + $student_uid = $_REQUEST["student_uid"]; + + $note = $_REQUEST["note"]; + if(isset($_REQUEST['punkte'])) + $punkte = $_REQUEST['punkte']; + else + $punkte = ''; + + $punkte = str_replace(',','.',$punkte); + + if($punkte!='') + { + // Bei Punkteeingabe wird die Note nochmals geprueft und ggf korrigiert + $notenschluessel = new notenschluessel(); + $note_pruef = $notenschluessel->getNote($punkte, $lvid, $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($lvid)) + die($lv_obj->errormsg); + + //Studiengang laden + $stg_obj = new studiengang($lv_obj->studiengang_kz); + + $uebung_id = (isset($_GET['uebung_id'])?$_GET['uebung_id']:''); + $uid = (isset($_GET['uid'])?$_GET['uid']:''); + + // lvgesamtnote für studenten speichern + if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) + { + // Die Pruefung muss einer Lehreinheit zugeordnet werden + // deshalb wird hier versucht eine passende Lehreinheit zu ermitteln. + + $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); + + $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note); + echo $response; + } + else + echo "Fehler beim Eintragen der Prüfungen"; + +} + +/** + * Berechnet Lehreinheit auf Basis LV-Daten + * @param string $db Datenbankvariable + * @param string $student_uid student_uid + * @param int $lvid Lehrveranstaltungsid + * @param string $stsem Studiensemester im Format 'WSYYYY' + * @return String LehreinheitId + */ +function getLehreinheit($db, $lvid, $student_uid, $stsem) { - // Die Pruefung muss einer Lehreinheit zugeordnet werden - // deshalb wird hier versucht eine passende Lehreinheit zu ermitteln. $le_arr = array(); $qry_stud = "SELECT lehreinheit_id, lehrform_kurzbz FROM @@ -158,104 +256,117 @@ if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) } } - if (!in_array($lehreinheit_id,$le_arr)) + //if (!in_array($lehreinheit_id,$le_arr)) $lehreinheit_id = $le_arr[0]; + return $lehreinheit_id; +} + +/** + * Prüfung speichern + */ +function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte=null) +{ $jetzt = date("Y-m-d H:i:s"); + global $user; //, $note, $punkte, $datum; - $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", $lvid, $stsem)) + if ($typ == "Termin2") { - if ($pr->result) + $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", $lvid, $stsem)) { - $termin1 = 1; - } - else - { - $lvnote = new lvgesamtnote(); - if ($lvnote->load($lvid, $student_uid, $stsem)) + if ($pr->result) { - $pr_note = $lvnote->note; - $pr_punkte = $lvnote->punkte; - $benotungsdatum = $lvnote->benotungsdatum; + $termin1 = 1; } else { - $pr_note = 9; - $pr_punkte = ''; - $benotungsdatum = $jetzt; + $lvnote = new lvgesamtnote(); + if ($lvnote->load($lvid, $student_uid, $stsem)) + { + $pr_note = $lvnote->note; + $pr_punkte = $lvnote->punkte; + $benotungsdatum = $lvnote->benotungsdatum; + } + else + { + $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 = $user; + $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 = $user; + $pr_1->updateamum = null; + $pr_1->updatevon = null; + $pr_1->ext_id = null; + $pr_1->new = true; + $pr_1->save(); + $response = "neu T1"; } - $pr_1 = new Pruefung(); - $pr_1->lehreinheit_id = $lehreinheit_id; - $pr_1->student_uid = $student_uid; - $pr_1->mitarbeiter_uid = $user; - $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 = $user; - $pr_1->updateamum = null; - $pr_1->updatevon = null; - $pr_1->ext_id = null; - $pr_1->new = true; - $pr_1->save(); + $prTermin2 = new Pruefung(); + $pr_2 = new Pruefung(); + + // Die Pruefung wird als Termin2 eingetragen + if ($prTermin2->getPruefungen($student_uid, 'Termin2', $lvid, $stsem)) + { + if ($prTermin2->result) + { + $pr_2->load($prTermin2->result[0]->pruefung_id); + $pr_2->new = null; + $pr_2->updateamum = $jetzt; + $pr_2->updatevon = $user; + $old_note = $pr_2->note; + $pr_2->note = $note; + $pr_2->punkte = $punkte; + $pr_2->datum = $datum; + $pr_2->anmerkung = ""; + $response = "update T2"; + } + else + { + $pr_2->lehreinheit_id = $lehreinheit_id; + $pr_2->student_uid = $student_uid; + $pr_2->mitarbeiter_uid = $user; + $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 = $user; + $pr_2->updateamum = null; + $pr_2->updatevon = null; + $pr_2->ext_id = null; + $pr_2->new = true; + $old_note = -1; + $response = "new T2"; + } + $pr_2->save(); + } } } - - - $prTermin2 = new Pruefung(); - $pr_2 = new Pruefung(); - - // Die Pruefung wird als Termin2 eingetragen - if ($prTermin2->getPruefungen($student_uid, $typ, $lvid, $stsem)) + else { - if ($prTermin2->result) - { - $pr_2->load($prTermin2->result[0]->pruefung_id); - $pr_2->new = null; - $pr_2->updateamum = $jetzt; - $pr_2->updatevon = $user; - $old_note = $pr_2->note; - $pr_2->note = $note; - $pr_2->punkte = $punkte; - $pr_2->datum = $datum; - $pr_2->anmerkung = ""; - } - else - { - $pr_2->lehreinheit_id = $lehreinheit_id; - $pr_2->student_uid = $student_uid; - $pr_2->mitarbeiter_uid = $user; - $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 = $user; - $pr_2->updateamum = null; - $pr_2->updatevon = null; - $pr_2->ext_id = null; - $pr_2->new = true; - $old_note = -1; - } - $pr_2->save(); + $response = "no existing T3"; } - - // Wenn eine Pruefung eingetragen wird, wird danach die LV-Note korrigiert - $jetzt = date("Y-m-d H:i:s"); - - $lvid = $_REQUEST["lvid"]; + //Gesamtnote updaten $lvgesamtnote = new lvgesamtnote(); - if (!$lvgesamtnote->load($lvid, $student_uid, $stsem)) - { + if (!$lvgesamtnote->load($lvid, $student_uid, $stsem)) + { $lvgesamtnote->student_uid = $student_uid; $lvgesamtnote->lehrveranstaltung_id = $lvid; $lvgesamtnote->studiensemester_kurzbz = $stsem; @@ -272,9 +383,9 @@ if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) $lvgesamtnote->insertvon = $user; $new = true; $response = "neu"; - } - else - { + } + else + { $lvgesamtnote->note = $note; $lvgesamtnote->punkte = $punkte; $lvgesamtnote->benotungsdatum = $jetzt; @@ -286,12 +397,11 @@ if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) else $response = "update"; } + if (!$lvgesamtnote->save($new)) - echo "".$lvgesamtnote->errormsg.""; + return $lvgesamtnote->errormsg; else - echo $response; + return $response; } -else - echo "Fehler beim Eintragen der Prüfungen"; ?> From 035d196ae5cb45b44a4f2f863e7bf5fd0ddbe872 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Oct 2022 08:04:10 +0200 Subject: [PATCH 003/175] Logik Matrikelnummer StudentenId --- .../benotungstool/nachpruefungeintragen.php | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 81545a7f6..d1a7e2326 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -99,6 +99,8 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) { $id=mb_substr($row, mb_strlen('student_uid_')); + $response2 = ''; + $student_uid = $_POST['student_uid_'.$id]; $note = null; $punkte = null; @@ -115,24 +117,21 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $punkte=str_replace(',','.', $punkte); $datum = $_POST['datumNachp_'.$id]; + $datum_obj = new datum(); + $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); // //check ob Matrikelnummer anstelle der student_uid übergeben wurde - // - // - // $student = new student(); - // - // - // $response2 = true; - // if (!$student->checkIfValidStudentUID($student_uid)) - // { - // //UID ermitteln - // if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) - // { - // $response2 = false; - // $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); - // continue; - // } - // } + + $student = new student(); + if (!$student->checkIfValidStudentUID($student_uid)) + { + //UID ermitteln + if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) + { + $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); + continue; + } + } $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); @@ -146,7 +145,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . " response" . $response . "\n"; - // echo $response; + echo $response2; } else @@ -168,7 +167,6 @@ else $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); } - // echo "Variante Einzel"; else die('Fehlerhafte Parameteruebergabe'); From 29fc5181bf237ba65337de647f1180c4d9420b9d Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Oct 2022 10:16:26 +0200 Subject: [PATCH 004/175] Importfunktion Termin3 --- .../benotungstool/lvgesamtnoteverwalten.php | 2 +- .../benotungstool/nachpruefungeintragen.php | 48 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 6a160c646..80bb7c5a5 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -1194,7 +1194,7 @@ if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN } if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { - $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
+ $htmlstring .= "
" . $p->t('benotungstool/nachpruefung2') . "
"; } diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index d1a7e2326..e8553ce7b 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -120,8 +120,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $datum_obj = new datum(); $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); - // //check ob Matrikelnummer anstelle der student_uid übergeben wurde - + //check ob Matrikelnummer anstelle der student_uid übergeben wurde $student = new student(); if (!$student->checkIfValidStudentUID($student_uid)) { @@ -138,9 +137,6 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) { - // echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . - // $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . "\n"; - $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . @@ -356,6 +352,48 @@ function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ } } } + elseif ($typ == "Termin3") + { + $prTermin3 = new Pruefung(); + $pr_3 = new Pruefung(); + + if ($prTermin3->getPruefungen($student_uid, 'Termin3', $lvid, $stsem)) + { + if ($prTermin3->result) + { + $pr_3->load($prTermin3->result[0]->pruefung_id); + $pr_3->new = null; + $pr_3->updateamum = $jetzt; + $pr_3->updatevon = $user; + $old_note = $pr_3->note; + $pr_3->note = $note; + $pr_3->punkte = $punkte; + $pr_3->datum = $datum; + $pr_3->anmerkung = ""; + $response = "Prüfung Termin3 aktualisiert"; + } + else + { + $pr_3->lehreinheit_id = $lehreinheit_id; + $pr_3->student_uid = $student_uid; + $pr_3->mitarbeiter_uid = $user; + $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 = $user; + $pr_3->updateamum = null; + $pr_3->updatevon = null; + $pr_3->ext_id = null; + $pr_3->new = true; + $old_note = -1; + $response = "neue Prüfung Termin3"; + } + $pr_3->save(); + } + } else { $response = "no existing T3"; From ce3cea5515721e933b621cf9f2902ddca5aecf21 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Oct 2022 15:36:08 +0200 Subject: [PATCH 005/175] Validierungen Format Datum, Matrikelnr, StudentId, Note --- .../benotungstool/lvgesamtnoteverwalten.php | 61 +++++++++---------- .../benotungstool/nachpruefungeintragen.php | 51 +++++++--------- locale/de-AT/benotungstool.php | 4 +- locale/en-US/benotungstool.php | 1 + 4 files changed, 56 insertions(+), 61 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 80bb7c5a5..8a428ff2a 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -20,33 +20,33 @@ * Gerald Simane-Sequens < gerald.simane-sequens@technikum-wien.at > * Manuela Thamer */ -require_once ('../../../../config/cis.config.inc.php'); -require_once ('../../../../config/global.config.inc.php'); -require_once ('../../../../include/functions.inc.php'); -require_once ('../../../../include/lehrveranstaltung.class.php'); -require_once ('../../../../include/studiengang.class.php'); -require_once ('../../../../include/studiensemester.class.php'); -require_once ('../../../../include/lehreinheit.class.php'); -require_once ('../../../../include/benutzerberechtigung.class.php'); -require_once ('../../../../include/uebung.class.php'); -require_once ('../../../../include/beispiel.class.php'); -require_once ('../../../../include/studentnote.class.php'); -require_once ('../../../../include/datum.class.php'); -require_once ('../../../../include/legesamtnote.class.php'); -require_once ('../../../../include/lvgesamtnote.class.php'); -require_once ('../../../../include/zeugnisnote.class.php'); -require_once ('../../../../include/pruefung.class.php'); -require_once ('../../../../include/person.class.php'); -require_once ('../../../../include/benutzer.class.php'); -require_once ('../../../../include/mitarbeiter.class.php'); -require_once ('../../../../include/mail.class.php'); -require_once ('../../../../include/phrasen.class.php'); -require_once ('../../../../include/note.class.php'); -require_once ('../../../../include/notenschluessel.class.php'); -require_once ('../../../../include/studienplan.class.php'); -require_once ('../../../../include/addon.class.php'); -require_once ('../../../../include/mobilitaet.class.php'); -require_once ('../../../../include/student.class.php'); +require_once('../../../../config/cis.config.inc.php'); +require_once('../../../../config/global.config.inc.php'); +require_once('../../../../include/functions.inc.php'); +require_once('../../../../include/lehrveranstaltung.class.php'); +require_once('../../../../include/studiengang.class.php'); +require_once('../../../../include/studiensemester.class.php'); +require_once('../../../../include/lehreinheit.class.php'); +require_once('../../../../include/benutzerberechtigung.class.php'); +require_once('../../../../include/uebung.class.php'); +require_once('../../../../include/beispiel.class.php'); +require_once('../../../../include/studentnote.class.php'); +require_once('../../../../include/datum.class.php'); +require_once('../../../../include/legesamtnote.class.php'); +require_once('../../../../include/lvgesamtnote.class.php'); +require_once('../../../../include/zeugnisnote.class.php'); +require_once('../../../../include/pruefung.class.php'); +require_once('../../../../include/person.class.php'); +require_once('../../../../include/benutzer.class.php'); +require_once('../../../../include/mitarbeiter.class.php'); +require_once('../../../../include/mail.class.php'); +require_once('../../../../include/phrasen.class.php'); +require_once('../../../../include/note.class.php'); +require_once('../../../../include/notenschluessel.class.php'); +require_once('../../../../include/studienplan.class.php'); +require_once('../../../../include/addon.class.php'); +require_once('../../../../include/mobilitaet.class.php'); +require_once('../../../../include/student.class.php'); $summe_stud = 0; $summe_t2 = 0; @@ -190,7 +190,7 @@ foreach ($noten_obj->result as $row) $noten_array[$row->note]['lehre'] = $row->lehre; $noten_array[$row->note]['lkt_ueberschreibbar'] = $row->lkt_ueberschreibbar; $noten_array[$row->note]['anmerkung'] = $row->anmerkung; - foreach ($sprachen->result AS $s) + foreach ($sprachen->result as $s) $noten_array[$row->note]['bezeichnung_mehrsprachig'][$s->sprache] = $row->bezeichnung_mehrsprachig[$s->sprache]; } @@ -376,7 +376,7 @@ foreach ($noten_obj->result as $row) var datum_test = datum.split("."); if (datum_test[0].length != 2 || datum_test[1].length != 2 || datum_test[2].length!=4 || isNaN(datum_test[2]) || datum_test[1]>12 || datum_test[1]<1 || datum_test[0]>31 || datum_test[0]<1) - alert("Invalid Date Format: DD.MM.YYYY"); + alert("Das Datum entspricht nicht dem Format TT.MM.JJJJ!"); else { var anlegendiv = document.getElementById("nachpruefung_div"); @@ -939,7 +939,6 @@ if (defined('CIS_ANWESENHEITSLISTE_NOTENLISTE_ANZEIGEN') && CIS_ANWESENHEITSLIST { $hrefpath = "../notenliste.xls.php?stg=$stg_obj->studiengang_kz&lvid=$lvid&stsem=$stsem"; echo "
" . $p->t('benotungstool/notenlisteImport') . ""; - } // eingetragene lv-gesamtnoten freigeben @@ -1333,7 +1332,6 @@ if (defined("CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE") && CIS_GESAMTNOTE_PRUEFUNG foreach ($grades as $uid => $data) //Ausgabe Array { - $htmlstring .= ' ' . $db->convert_html_chars($uid) . ' @@ -1465,7 +1463,6 @@ if (defined("CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE") && CIS_GESAMTNOTE_PRUEFUNG // Punkte if (CIS_GESAMTNOTE_PUNKTE) { - $htmlstring .= ' $val) + $errorMatrnr = ''; + $errorDatum = ''; + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'student_uid_')) { $id=mb_substr($row, mb_strlen('student_uid_')); - $response2 = ''; - $student_uid = $_POST['student_uid_'.$id]; $note = null; $punkte = null; @@ -114,35 +114,36 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $response.="\nNote oder Punkte fehlen"; continue; } - $punkte=str_replace(',','.', $punkte); + $punkte=str_replace(',', '.', $punkte); $datum = $_POST['datumNachp_'.$id]; + //check Datumsformat + $checkedDatum = $datum; $datum_obj = new datum(); - $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); + if(!$datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true)) + { + $errorDatum .="\n".$p->t('benotungstool/datumsformatUnzulaessig', array($checkedDatum)); + continue; + } //check ob Matrikelnummer anstelle der student_uid übergeben wurde $student = new student(); if (!$student->checkIfValidStudentUID($student_uid)) { + $checkedMatrnr = $student_uid; //UID ermitteln if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) { - $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); + $errorMatrnr.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht', array($checkedMatrnr)); continue; } } - $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) { $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); - - echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . - $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . " response" . $response . "\n"; - echo $response2; - } else { @@ -150,22 +151,18 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) } } } - + echo $errorMatrnr . $errorDatum; } else { // Einzelupdate - if(isset($_GET['datum']) ) + if(isset($_GET['datum'])) { $datum = $_GET['datum']; $datum_obj = new datum(); - $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); + $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) or die($p->t('benotungstool/datumsformatUnzulaessig', array($checkedDatum))); } - - else - die('Fehlerhafte Parameteruebergabe'); - $student_uid = $_REQUEST["student_uid"]; $note = $_REQUEST["note"]; @@ -174,7 +171,7 @@ else else $punkte = ''; - $punkte = str_replace(',','.',$punkte); + $punkte = str_replace(',', '.', $punkte); if($punkte!='') { @@ -205,11 +202,10 @@ else $uid = (isset($_GET['uid'])?$_GET['uid']:''); // lvgesamtnote für studenten speichern - if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) + if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '')) { // Die Pruefung muss einer Lehreinheit zugeordnet werden // deshalb wird hier versucht eine passende Lehreinheit zu ermitteln. - $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note); @@ -217,7 +213,6 @@ else } else echo "Fehler beim Eintragen der Prüfungen"; - } /** @@ -259,7 +254,7 @@ function getLehreinheit($db, $lvid, $student_uid, $stsem) /** * Prüfung speichern */ -function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte=null) +function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte = null) { $jetzt = date("Y-m-d H:i:s"); global $user; //, $note, $punkte, $datum; @@ -370,7 +365,7 @@ function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ $pr_3->punkte = $punkte; $pr_3->datum = $datum; $pr_3->anmerkung = ""; - $response = "Prüfung Termin3 aktualisiert"; + $response = "update T3"; } else { @@ -389,14 +384,14 @@ function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ $pr_3->ext_id = null; $pr_3->new = true; $old_note = -1; - $response = "neue Prüfung Termin3"; + $response = "new T3"; } $pr_3->save(); } } else { - $response = "no existing T3"; + $response = "fehlende oder fehlerhafte Inputparameter"; } //Gesamtnote updaten diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index a38aa31f3..b7c2af638 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -148,7 +148,9 @@ $this->phrasen['benotungstool/anzahlKommisionellePruefungen']='Anzahl kommission $this->phrasen['benotungstool/pruefungAnlegenFuer']='Prüfung anlegen für'; $this->phrasen['benotungstool/kreuzerltool']='Kreuzerltool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Der Student %s %s (%s) ist dieser Lehrveranstaltung nicht zugeordnet. Die Note wird nicht uebernommen!'; -$this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student mit Matrikelnummer %s existiert nicht.'; +$this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student*in mit Matrikelnummer %s existiert nicht.'; +$this->phrasen['benotungstool/datumsformatUnzulaessig']='Das Datum %s entspricht nicht dem Format TT.MM.JJJJ!'; +$this->phrasen['benotungstool/noteUnzulaessig']='Die Note %s ist nicht zulaessig. Die Zeile wurde uebersprungen.'; $this->phrasen['benotungstool/noteNichtUeberschreibbar']='Für Student mit Matrikelnummer %s eingetragene Zeugnisote %s ist nicht überschreibbar'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Fehlerhafte Note bei Student %s %s'; $this->phrasen['benotungstool/keineKreuzerllistenFuerDieseLehrveranstaltung']='Derzeit gibt es keine Kreuzerllisten für diese Lehrveranstaltung'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index 72f29256e..1f1dc89c6 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -148,6 +148,7 @@ $this->phrasen['benotungstool/pruefungAnlegenFuer']='Create an examination for ' $this->phrasen['benotungstool/kreuzerltool']='"Kreuzerl" tool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Student is not assigned to this course. The grade was not accepted!'; $this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student with student ID number %s does not exist.'; +$this->phrasen['benotungstool/datumsformatUnzulaessig']='The date %s is not in valid format TT.MM.JJJJ.'; $this->phrasen['benotungstool/noteNichtUeberschreibbar']='Transcript grade %2$s for student with Personal identifier %1$s is not rewritable'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Incorrect grade for student %s %s'; $this->phrasen['benotungstool/keineKreuzerllistenFuerDieseLehrveranstaltung']='There are currently no checklists for this course'; From 8754c46575f53bccffdcb1ec2dd6d51923fd0b48 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 17 Oct 2022 14:34:11 +0200 Subject: [PATCH 006/175] Refactor Import Termin2 und Termin3 --- .../benotungstool/lvgesamtnoteverwalten.php | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 8a428ff2a..b7bb74d54 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -606,7 +606,7 @@ foreach ($noten_obj->result as $row) // **** // * Oeffnet ein Fenster fuer den Import von Noten für die Nachprüfung aus dem Excel // **** - function GradeImportNachp() + function GradeImportNachp(termin) { var str = "
"; str += ""; @@ -614,31 +614,14 @@ foreach ($noten_obj->result as $row) var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; str += ''; str += ''; - str += "
X
t('benotungstool/importAnweisungNachp');?>:
' onclick='saveGradeBulkNachp(\"Termin2\");'>"; + + str += "
' onclick='saveGradeBulkNachp(\""+ termin +"\");'>"; str += "
"; anlegendiv.innerHTML = str; anlegendiv.style.visibility = "visible"; $('#noteimporttextareaNachp').focus(); } - // **** - // * Oeffnet ein Fenster fuer den Import von Noten für Termin3 aus dem Excel - // **** - function GradeImportTermin3() - { - var str = "
"; - str += ""; - var anlegendiv = document.getElementById("nachpruefung_div"); - var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; - str += ''; - str += ''; - str += "
X
t('benotungstool/importAnweisungNachp');?>:
' onclick='saveGradeBulkNachp(\"Termin3\");'>"; - str += "
"; - anlegendiv.innerHTML = str; - anlegendiv.style.visibility = "visible"; - $('#noteimporttextareaTermin3').focus(); - } - // Speichert die Noten ueber den Import function saveGradeBulk() { @@ -1188,13 +1171,13 @@ $htmlstring .= "" . $p->t('benotungstool/punkte') . ' / ' . $p->t('benotungs if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) { $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
- + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { $htmlstring .= "
" . $p->t('benotungstool/nachpruefung2') . "
- + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF') && CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) From 47d3ab33e78d0fbb68f5e484494a518c7e35033c Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 18 Oct 2022 09:17:07 +0200 Subject: [PATCH 007/175] =?UTF-8?q?Adaptierung=20Vorlage=20Notenliste.xls?= =?UTF-8?q?=20um=20Nachpr=C3=BCfung=20und=20Termin3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../benotungstool/lvgesamtnoteeintragen.php | 21 +++--- .../benotungstool/lvgesamtnoteverwalten.php | 4 +- .../benotungstool/nachpruefungeintragen.php | 1 + cis/private/lehre/notenliste.xls.php | 67 +++++++++++++++++++ locale/de-AT/benotungstool.php | 4 +- locale/en-US/benotungstool.php | 2 +- 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php b/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php index 73d0e6fca..8337b7c36 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php @@ -98,9 +98,9 @@ if($stsem=='') //$note = $_REQUEST["note"]; -if(!$rechte->isBerechtigt('admin',0) && - !$rechte->isBerechtigt('admin',$lv_obj->studiengang_kz) && - !$rechte->isBerechtigt('lehre',$lv_obj->studiengang_kz)) +if(!$rechte->isBerechtigt('admin', 0) && + !$rechte->isBerechtigt('admin', $lv_obj->studiengang_kz) && + !$rechte->isBerechtigt('lehre', $lv_obj->studiengang_kz)) { $qry = "SELECT lehreinheit_id FROM lehre.tbl_lehrveranstaltung JOIN lehre.tbl_lehreinheit USING(lehrveranstaltung_id) JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id) @@ -117,11 +117,11 @@ if(!$rechte->isBerechtigt('admin',0) && } } -function savenote($db,$lvid, $student_uid, $note, $punkte=null) +function savenote($db, $lvid, $student_uid, $note, $punkte = null) { global $stsem, $user, $p, $noten_anmerkung; $jetzt = date("Y-m-d H:i:s"); - $punkte = str_replace(',','.',$punkte); + $punkte = str_replace(',', '.', $punkte); //Ermitteln ob der Student diesem Kurs zugeteilt ist $qry = "SELECT 1 FROM campus.vw_student_lehrveranstaltung WHERE uid=".$db->db_add_param($student_uid)." AND lehrveranstaltung_id=".$db->db_add_param($lvid, FHC_INTEGER); if($result = $db->db_query($qry)) @@ -207,13 +207,12 @@ if (isset($_REQUEST["submit"])) $note = $_REQUEST["note"]; $punkte = (isset($_REQUEST["punkte"])?$_REQUEST["punkte"]:''); - $response = savenote($db,$lvid, $student_uid, $note, $punkte); + $response = savenote($db, $lvid, $student_uid, $note, $punkte); echo $response; } else { - - foreach ($_POST as $row=>$val) + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'matrikelnr_')) { @@ -232,7 +231,7 @@ if (isset($_REQUEST["submit"])) $response.="\nNote oder Punkte fehlen"; continue; } - $punkte=str_replace(',','.', $punkte); + $punkte=str_replace(',', '.', $punkte); //check ob statt Matrikelnummer nicht bereits student_uid (Moodle Grade Import) vorliegt.. $student = new student(); @@ -241,7 +240,7 @@ if (isset($_REQUEST["submit"])) //UID ermitteln if(!$student_uid = $student->getUidFromMatrikelnummer($matrikelnummer)) { - $response.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($matrikelnummer)); + $response.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht', array($matrikelnummer)); continue; } } @@ -268,7 +267,7 @@ if (isset($_REQUEST["submit"])) } } - $val=savenote($db,$lvid, $student_uid, $note, $punkte); + $val=savenote($db, $lvid, $student_uid, $note, $punkte); if($val!='neu' && $val!='update' && $val!='update_f') $response.=$val; } diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index b7bb74d54..64179a3e9 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -749,6 +749,7 @@ foreach ($noten_obj->result as $row) } ?> + for(row in rows) { zeile = rows[row].split(" "); @@ -779,6 +780,7 @@ foreach ($noten_obj->result as $row) } } + if (alertMsg != "") alert(alertMsg); @@ -1306,7 +1308,7 @@ if (defined("CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE") && CIS_GESAMTNOTE_PRUEFUNG foreach ($addon_obj->result as $row) { if (file_exists('../../../../addons/' . $row->kurzbz . '/cis/grades.inc.php')) - include ('../../../../addons/' . $row->kurzbz . '/cis/grades.inc.php'); + include('../../../../addons/' . $row->kurzbz . '/cis/grades.inc.php'); } } } diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 307c0ca30..290113179 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -105,6 +105,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $note = null; $punkte = null; $datum = null; + $response = ''; if(isset($_POST['note_'.$id])) $note = $_POST['note_'.$id]; elseif(isset($_POST['punkte_'.$id])) diff --git a/cis/private/lehre/notenliste.xls.php b/cis/private/lehre/notenliste.xls.php index 74cb7e7c1..4a6817a36 100644 --- a/cis/private/lehre/notenliste.xls.php +++ b/cis/private/lehre/notenliste.xls.php @@ -35,6 +35,7 @@ require_once('../../../include/note.class.php'); require_once('../../../include/notenschluessel.class.php'); require_once('../../../include/Excel/excel.php'); require_once('../../../include/phrasen.class.php'); +require_once('../../../include/pruefung.class.php'); $uid = get_uid(); @@ -191,6 +192,19 @@ else } //Studenten holen + + //Spaltengruppe für Nachprüfung + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->write($lines,8,$p->t('benotungstool/nachpruefung'),$format_bold); + } + + //Spaltengruppe für 2.Nebensprüfungstermin + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) + { + $worksheet->write($lines,12,$p->t('benotungstool/nachpruefung2'),$format_bold); + } + $lines++; $worksheet->write($lines,1,$p->t('global/uid'),$format_border_bottom); $worksheet->write($lines,2,$p->t('global/nachname'),$format_border_bottom); @@ -203,6 +217,26 @@ else else $worksheet->write($lines,6,$p->t('benotungstool/note'),$format_border_bottom); + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->write($lines,8,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,9,$p->t('global/datum'),$format_border_bottom); + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + $worksheet->write($lines,10,$p->t('benotungstool/punkte'),$format_border_bottom); + else + $worksheet->write($lines,10,$p->t('benotungstool/note'),$format_border_bottom); + } + + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) +{ + $worksheet->write($lines,12,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,13,$p->t('global/uid'),$format_border_bottom); + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + $worksheet->write($lines,14,$p->t('benotungstool/punkte'),$format_border_bottom); + else + $worksheet->write($lines,14,$p->t('benotungstool/note'),$format_border_bottom); +} + $stsem_obj = new studiensemester(); $stsem_obj->load($stsem); $stsemdatumvon = $stsem_obj->start; @@ -282,6 +316,39 @@ else $worksheet->write($lines,4,'="'.$elem->semester.$elem->verband.$elem->gruppe.'"'); $worksheet->write($lines,5,'="'.trim($elem->matrikelnr).'"',$format_highlight); $worksheet->write($lines,6, $note, $format_highlightright); + + // Nachprüfung + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->write($lines,8, $elem->uid, $format_highlightright); + $pr = new Pruefung(); + $pr->getPruefungen($elem->uid, "Termin2", $lvid, $sem); + $output2 = $pr->result; + + if ($output2) + { + $resultPr = $output2[0]; + $worksheet->write($lines,9, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright); + $worksheet->write($lines,10, $resultPr->note, $format_highlightright); + } + } + + // Nachprüfung + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) + { + $worksheet->write($lines,12, $elem->uid, $format_highlightright); + $pr = new Pruefung(); + $pr->getPruefungen($elem->uid, "Termin3", $lvid, $sem); + $output3 = $pr->result; + + if ($output3) + { + $resultPr = $output3[0]; + $worksheet->write($lines,13, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright); + $worksheet->write($lines,14, $resultPr->note, $format_highlightright); + } + } + $i++; $lines++; } diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index b7c2af638..feac092f6 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -172,8 +172,8 @@ $this->phrasen['benotungstool/eingetrageneNoten']='Eingetragene Noten'; $this->phrasen['benotungstool/zeunis']='Zeugnis'; $this->phrasen['benotungstool/handbuch']='Handbuch'; $this->phrasen['benotungstool/punkte']='Punkte'; -$this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten Personenkennzeichen und Note aus der Notenliste (bzw. StudentenUid und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; -$this->phrasen['benotungstool/importAnweisungNachp']='Kopieren Sie die Spalten Personenkennzeichen, Datum und Note aus der Notenliste (bzw. StudentenUid, Datum und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; +$this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten StudentenUid und Note aus der Notenliste (bzw. StudentenUid und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; +$this->phrasen['benotungstool/importAnweisungNachp']='Kopieren Sie die Spalten StudentenUid (bzw. Personenkennzeichen), Datum und Note aus der Notenliste bzw. dem Moodle Export File und fügen Sie diese in folgendes Feld ein'; $this->phrasen['benotungstool/pruefung']='Prüfung'; $this->phrasen['benotungstool/notenlisteImport']='Notenliste für den LV-Noten-Import (Excel)'; $this->phrasen['benotungstool/bearbeitetvon']='Bearbeitet von'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index 1f1dc89c6..f482409d8 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -171,7 +171,7 @@ $this->phrasen['benotungstool/zeunis']='Transcript'; $this->phrasen['benotungstool/handbuch']='Handbook'; $this->phrasen['benotungstool/punkte']='Points'; $this->phrasen['benotungstool/importAnweisung']='Copy the columns "personal identifier" and "grade" from the grade list (or "student ID number" and "grade" from the moodle export file) and insert them in the following field'; -$this->phrasen['benotungstool/importAnweisungNachp']='Copy the columns "personal identifier", "date" and "grade" from the grade list (or "student ID number", "date" and "grade" from the moodle export file) and insert them in the following field'; +$this->phrasen['benotungstool/importAnweisungNachp']='Copy the columns "student ID number" (or "personal identifier"), "date" and "grade" from the grade list or from the moodle export file and insert them in the following field'; $this->phrasen['benotungstool/pruefung']='Examination'; $this->phrasen['benotungstool/notenlisteImport']='Grade list for the subject grade import (Excel)'; $this->phrasen['benotungstool/geaenderteNotenVorhanden']='There are changed grades. Please send the changes to the assistant by clicking "Approval"'; From 540fc4bede933b704d2d69aeb0325bcc0da780c0 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 15 Nov 2022 11:22:47 +0100 Subject: [PATCH 008/175] 26198 Notenimport ausschliesslich bei vorhandener Note --- .../lehre/benotungstool/nachpruefungeintragen.php | 12 +++++++++++- locale/de-AT/benotungstool.php | 3 ++- locale/en-US/benotungstool.php | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 290113179..bf0d4b197 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -95,6 +95,8 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) { $errorMatrnr = ''; $errorDatum = ''; + $errorNachp = ''; + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'student_uid_')) @@ -140,6 +142,14 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) } } + //check ob eine Note vorhanden ist oder (intern) angerechnet wurde + $lvnote = new lvgesamtnote(); + if (!$lvnote->load($lvid, $student_uid, $stsem)) + { + $errorNachp.="\n".$p->t('benotungstool/NachpruefungNichtZulaessig', array($student_uid)); + continue; + } + $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) @@ -152,7 +162,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) } } } - echo $errorMatrnr . $errorDatum; + echo $errorMatrnr . $errorDatum . $errorNachp; } else { diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index feac092f6..d6e77d3ce 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -150,8 +150,9 @@ $this->phrasen['benotungstool/kreuzerltool']='Kreuzerltool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Der Student %s %s (%s) ist dieser Lehrveranstaltung nicht zugeordnet. Die Note wird nicht uebernommen!'; $this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student*in mit Matrikelnummer %s existiert nicht.'; $this->phrasen['benotungstool/datumsformatUnzulaessig']='Das Datum %s entspricht nicht dem Format TT.MM.JJJJ!'; +$this->phrasen['benotungstool/NachpruefungNichtZulaessig']='Nachprüfung für Student*in %s nicht zulässig.'; $this->phrasen['benotungstool/noteUnzulaessig']='Die Note %s ist nicht zulaessig. Die Zeile wurde uebersprungen.'; -$this->phrasen['benotungstool/noteNichtUeberschreibbar']='Für Student mit Matrikelnummer %s eingetragene Zeugnisote %s ist nicht überschreibbar'; +$this->phrasen['benotungstool/noteNichtUeberschreibbar']='Für Student mit Matrikelnummer %s eingetragene Zeugnisnote %s ist nicht überschreibbar'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Fehlerhafte Note bei Student %s %s'; $this->phrasen['benotungstool/keineKreuzerllistenFuerDieseLehrveranstaltung']='Derzeit gibt es keine Kreuzerllisten für diese Lehrveranstaltung'; $this->phrasen['benotungstool/notenuebersichtFuer']='Notenübersicht für'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index f482409d8..73a3bd343 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -148,6 +148,7 @@ $this->phrasen['benotungstool/pruefungAnlegenFuer']='Create an examination for ' $this->phrasen['benotungstool/kreuzerltool']='"Kreuzerl" tool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Student is not assigned to this course. The grade was not accepted!'; $this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student with student ID number %s does not exist.'; +$this->phrasen['benotungstool/NachpruefungNichtZulaessig']='Re-examination for student %s not allowed.'; $this->phrasen['benotungstool/datumsformatUnzulaessig']='The date %s is not in valid format TT.MM.JJJJ.'; $this->phrasen['benotungstool/noteNichtUeberschreibbar']='Transcript grade %2$s for student with Personal identifier %1$s is not rewritable'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Incorrect grade for student %s %s'; From d9098179a25cf789e29dc29a1407445112ce4d06 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 14 Dec 2022 12:40:38 +0100 Subject: [PATCH 009/175] - ermoeglicht es master bewerber sich ueber das bewerbungstool anzumelden --- include/reihungstest.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 0140816ab..5c8e5854e 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -685,11 +685,15 @@ class reihungstest extends basis_db tbl_reihungstest.studiensemester_kurzbz, tbl_reihungstest.stufe, tbl_reihungstest.anmeldefrist, - tbl_reihungstest.aufnahmegruppe_kurzbz + tbl_reihungstest.aufnahmegruppe_kurzbz, + tbl_studiengang.typ, + tbl_studiengang.kurzbzlang FROM public.tbl_rt_person JOIN public.tbl_reihungstest ON (rt_id=reihungstest_id) + LEFT JOIN + public.tbl_studiengang ON tbl_reihungstest.studiengang_kz = tbl_studiengang.studiengang_kz WHERE tbl_rt_person.person_id=".$this->db_add_param($person_id); @@ -728,6 +732,8 @@ class reihungstest extends basis_db $obj->stufe = $row->stufe; $obj->anmeldefrist = $row->anmeldefrist; $obj->aufnahmegruppe_kurzbz = $row->aufnahmegruppe_kurzbz; + $obj->typ = $row->typ; + $obj->kurzbzlang = $row->kurzbzlang; $this->result[] = $obj; } From ed99325bb933d7fee02fffc50014d28f287f8d01 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 10 Jan 2023 09:04:53 +0100 Subject: [PATCH 010/175] - anpassungen fuer master bewerbungen --- include/reihungstest.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 5c8e5854e..42af8ea7a 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -687,7 +687,7 @@ class reihungstest extends basis_db tbl_reihungstest.anmeldefrist, tbl_reihungstest.aufnahmegruppe_kurzbz, tbl_studiengang.typ, - tbl_studiengang.kurzbzlang + UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel FROM public.tbl_rt_person JOIN @@ -733,7 +733,7 @@ class reihungstest extends basis_db $obj->anmeldefrist = $row->anmeldefrist; $obj->aufnahmegruppe_kurzbz = $row->aufnahmegruppe_kurzbz; $obj->typ = $row->typ; - $obj->kurzbzlang = $row->kurzbzlang; + $obj->stg_kuerzel = $row->stg_kuerzel; $this->result[] = $obj; } From 84ca798dadc5ad814a949d69093ae3d113b369b9 Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Wed, 8 Mar 2023 13:50:33 +0100 Subject: [PATCH 011/175] add format to set text as format for date columns and highlight them --- cis/private/lehre/notenliste.xls.php | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/cis/private/lehre/notenliste.xls.php b/cis/private/lehre/notenliste.xls.php index 4a6817a36..42dcc8418 100644 --- a/cis/private/lehre/notenliste.xls.php +++ b/cis/private/lehre/notenliste.xls.php @@ -121,6 +121,13 @@ else $format_highlightright->setBorderColor('white'); $format_highlightright->setAlign('right'); + $format_highlightright_date=& $workbook->addFormat(); + $format_highlightright_date->setFgColor(15); + $format_highlightright_date->setBorder(1); + $format_highlightright_date->setBorderColor('white'); + $format_highlightright_date->setAlign('right'); + $format_highlightright_date->setNumFormat(49); + $format_border_bottom =& $workbook->addFormat(); $format_border_bottom ->setBottom(2); $format_border_bottom->setBold(); @@ -230,7 +237,7 @@ else if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { $worksheet->write($lines,12,$p->t('global/uid'),$format_border_bottom); - $worksheet->write($lines,13,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,13,$p->t('global/datum'),$format_border_bottom); if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) $worksheet->write($lines,14,$p->t('benotungstool/punkte'),$format_border_bottom); else @@ -328,9 +335,14 @@ else if ($output2) { $resultPr = $output2[0]; - $worksheet->write($lines,9, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright); + $worksheet->write($lines,9, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright_date); $worksheet->write($lines,10, $resultPr->note, $format_highlightright); } + else + { + $worksheet->write($lines,9, '', $format_highlightright_date); + $worksheet->write($lines,10, '', $format_highlightright); + } } // Nachprüfung @@ -344,9 +356,14 @@ else if ($output3) { $resultPr = $output3[0]; - $worksheet->write($lines,13, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright); + $worksheet->write($lines,13, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright_date); $worksheet->write($lines,14, $resultPr->note, $format_highlightright); } + else + { + $worksheet->write($lines,13, '', $format_highlightright_date); + $worksheet->write($lines,14, '', $format_highlightright); + } } $i++; From 3e056ebf3d35c6eacae1fd042e9358c3925c532c Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 24 Mar 2023 15:21:01 +0100 Subject: [PATCH 012/175] =?UTF-8?q?Notenimport=20Nachpr=C3=BCfung=20und=20?= =?UTF-8?q?3.Termin:=20Erg=C3=A4nzung=20um=20nicht=20numerische=20Noten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../benotungstool/nachpruefungeintragen.php | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index bf0d4b197..804ab34fb 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -42,6 +42,7 @@ require_once('../../../../include/benutzer.class.php'); require_once('../../../../include/student.class.php'); require_once('../../../../include/notenschluessel.class.php'); require_once('../../../../include/phrasen.class.php'); +require_once('../../../../include/note.class.php'); if (!$db = new basis_db()) @@ -79,6 +80,17 @@ $stsem_obj = new studiensemester(); if($stsem=='') $stsem = $stsem_obj->getaktorNext(); +//Notenanmerkung für Eintragung von nichtnumerischen Noten wie en (entschuldigt), ue(unentschuldigt) +$noten_anmerkung = array(); +$noten_arr = array(); +$note_obj = new note(); +$note_obj->getAll(); +foreach($note_obj->result as $row) +{ + $noten_anmerkung[$row->anmerkung] = $row->note; + $noten_arr[$row->note] = $row; +} + if(!isset($_GET['typ'])) { $typ='Termin2'; @@ -96,7 +108,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $errorMatrnr = ''; $errorDatum = ''; $errorNachp = ''; - + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'student_uid_')) @@ -154,6 +166,11 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) { + if(!is_numeric($note)) + { + if(isset($noten_anmerkung[$note])) + $note = $noten_anmerkung[$note]; + } $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); } else From 76c4c4a0e916226273063c30cc4463d051e36b62 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 27 Mar 2023 08:15:29 +0200 Subject: [PATCH 013/175] Termin 3 als pruefungstyp in lehre.tbl_pruefungstyp in dbupdate hinterlegt --- system/dbupdate_3.4.php | 1 + .../25003_notenimport_nachpruefung.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 system/dbupdate_3.4/25003_notenimport_nachpruefung.php diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index c3600d250..2597a0e4c 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -27,6 +27,7 @@ require_once('dbupdate_3.4/example.php'); require_once('dbupdate_3.4/example2.php'); ... */ +require_once('dbupdate_3.4/25003_notenimport_nachpruefung.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/25003_notenimport_nachpruefung.php b/system/dbupdate_3.4/25003_notenimport_nachpruefung.php new file mode 100644 index 000000000..7c2406d0e --- /dev/null +++ b/system/dbupdate_3.4/25003_notenimport_nachpruefung.php @@ -0,0 +1,15 @@ +db_query("SELECT 1 FROM lehre.tbl_pruefungstyp WHERE pruefungstyp_kurzbz='Termin3'")) +{ + if($db->db_num_rows($result)==0) + { + $qry = "INSERT INTO lehre.tbl_pruefungstyp(pruefungstyp_kurzbz, beschreibung, abschluss) VALUES('Termin3', '3.Termin', false);"; + + if(!$db->db_query($qry)) + echo 'Prüfungstyp: '.$db->db_last_error().'
'; + else + echo '
Prüfungstyp 3.Termin in lehre.tbl_pruefungstyp hinzugefügt'; + } +} From 80d5d09ed582462e1eb021799635d3f4246777c8 Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Tue, 4 Apr 2023 08:07:03 +0200 Subject: [PATCH 014/175] fix styling of textarea in import popup --- .../lehre/benotungstool/lvgesamtnoteverwalten.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 4dcd6c7cf..d498636ae 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -145,8 +145,8 @@ echo ' position:absolute; top:100px; left:300px; - width:400px; - height:200px; + min-width:450px; + min-height:200px; background-color:#cccccc; visibility:hidden; border-style:solid; @@ -594,8 +594,8 @@ foreach ($noten_obj->result as $row) str += "X"; var anlegendiv = document.getElementById("nachpruefung_div"); var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; - str += 't('benotungstool/importAnweisung');?>:'; - str += ''; + str += '
t('benotungstool/importAnweisung');?>:
'; + str += ''; str += "' onclick='saveGradeBulk();'>"; str += ""; anlegendiv.innerHTML = str; @@ -612,8 +612,8 @@ foreach ($noten_obj->result as $row) str += "X"; var anlegendiv = document.getElementById("nachpruefung_div"); var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; - str += 't('benotungstool/importAnweisungNachp');?>:'; - str += ''; + str += '
t('benotungstool/importAnweisungNachp');?>:
'; + str += ''; str += "' onclick='saveGradeBulkNachp(\""+ termin +"\");'>"; str += ""; From fb57ea5838731be8532efd2fc5c5e8add5d8feb6 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 4 Apr 2023 15:57:33 +0200 Subject: [PATCH 015/175] - splitten von reihungstest uebersichten --- include/reihungstest.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 42af8ea7a..2da424af5 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -687,7 +687,9 @@ class reihungstest extends basis_db tbl_reihungstest.anmeldefrist, tbl_reihungstest.aufnahmegruppe_kurzbz, tbl_studiengang.typ, - UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel + UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel, + tbl_studiengang.bezeichnung, + tbl_studiengang.english FROM public.tbl_rt_person JOIN @@ -734,6 +736,8 @@ class reihungstest extends basis_db $obj->aufnahmegruppe_kurzbz = $row->aufnahmegruppe_kurzbz; $obj->typ = $row->typ; $obj->stg_kuerzel = $row->stg_kuerzel; + $obj->bezeichnung = $row->bezeichnung; + $obj->english = $row->english; $this->result[] = $obj; } From da484fbbb07d7017fb232872e35562a292976294 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 25 Apr 2023 08:45:16 +0200 Subject: [PATCH 016/175] - die letzten 5 tage werden geprueft anstatt nur der vortag - neue bewerbungen nach dem aufgenommen status werden nich automatisch abgewiesen --- application/controllers/jobs/ReihungstestJob.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/application/controllers/jobs/ReihungstestJob.php b/application/controllers/jobs/ReihungstestJob.php index ab6c429a0..431ac5b04 100644 --- a/application/controllers/jobs/ReihungstestJob.php +++ b/application/controllers/jobs/ReihungstestJob.php @@ -3,6 +3,9 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); class ReihungstestJob extends JOB_Controller { + + const LAST_DAYS_PRESTUDENTSTATUS = 5; + /** * Constructor */ @@ -826,7 +829,7 @@ class ReihungstestJob extends JOB_Controller AND tbl_studiengang.typ IN ('b', 'm') ) SELECT * FROM prst - WHERE prestudenstatus_datum >= (SELECT CURRENT_DATE - 1) + WHERE prestudenstatus_datum >= (SELECT CURRENT_DATE - ". self::LAST_DAYS_PRESTUDENTSTATUS .") AND (studiengang_typ = 'b' OR (studiengang_typ = 'm' AND EXISTS (SELECT 1 /* Master Studiengänge berücksichtigen wenn auch Bachelor im gleichen Semester */ FROM prst prstb WHERE studiengang_typ = 'b' @@ -868,7 +871,8 @@ class ReihungstestJob extends JOB_Controller tbl_person.nachname, tbl_person.vorname, tbl_prestudent.*, - tbl_studiengang.typ AS studiengang_typ + tbl_studiengang.typ AS studiengang_typ, + tbl_prestudentstatus.datum FROM PUBLIC.tbl_person JOIN PUBLIC.tbl_prestudent USING (person_id) JOIN PUBLIC.tbl_prestudentstatus USING (prestudent_id) @@ -901,7 +905,7 @@ class ReihungstestJob extends JOB_Controller $mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['AufnahmeHoeherePrio'][] = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; } - elseif ($rowNiedrPrios->laststatus == 'Bewerber') + elseif ($rowNiedrPrios->laststatus == 'Bewerber' && $row_ps->prestudenstatus_datum > $rowNiedrPrios->datum) { // Abgewiesenen-Status mit Statusgrund "Aufnahme anderer Studiengang" (ID 5) setzen $lastStatus = $this->PrestudentstatusModel->getLastStatus($rowNiedrPrios->prestudent_id); @@ -927,7 +931,7 @@ class ReihungstestJob extends JOB_Controller = $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')'; } } - elseif ($rowNiedrPrios->laststatus == 'Wartender') + elseif ($rowNiedrPrios->laststatus == 'Wartender' && $row_ps->prestudenstatus_datum > $rowNiedrPrios->datum) { // Abgewiesenen-Status mit Statusgrund "Aufnahme anderer Studiengang" (ID 5) setzen // Mail zur Info an Assistenz schicken From 33e313a633a4001f01b1ce55c4dec39f62c2d2e1 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 8 May 2023 12:12:42 +0200 Subject: [PATCH 017/175] update Abfrage --- application/inputFileTest.csv | 8 +++++ application/tmp/inputFile.csv | 49 +++++++++++++++++++++++++++ application/tmp/inputFileMitError.csv | 11 ++++++ application/tmp/inputFileUltra.csv | 8 +++++ cis/private/lehre/notenliste.xls.php | 7 ++-- 5 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 application/inputFileTest.csv create mode 100644 application/tmp/inputFile.csv create mode 100644 application/tmp/inputFileMitError.csv create mode 100644 application/tmp/inputFileUltra.csv diff --git a/application/inputFileTest.csv b/application/inputFileTest.csv new file mode 100644 index 000000000..927dc0062 --- /dev/null +++ b/application/inputFileTest.csv @@ -0,0 +1,8 @@ +uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url +aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 +aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,Projekt,https://moodle.technikum-wien.at/course/view.php?id=3643 +adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 +adams,SS2016,BEW-DL-2-SS2016-ENG,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 +krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung,https://moodle.technikum-wien.at/course/view.php?id=3157 +krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 +krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 diff --git a/application/tmp/inputFile.csv b/application/tmp/inputFile.csv new file mode 100644 index 000000000..48411ca1a --- /dev/null +++ b/application/tmp/inputFile.csv @@ -0,0 +1,49 @@ +uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url +aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 +aburaia,SS2016,BMR6_MES_2016,BMR6_Mechatronische-Systeme_2016,https://moodle.technikum-wien.at/course/view.php?id=2951 +aburaia,SS2016,BMR-VZ-6-SS2016-EMS,Entwurf mechatronischer Systeme,https://moodle.technikum-wien.at/course/view.php?id=2833 +aburaia,WS2016,BMB-VZ-5-WS2016-DF,Industrierobotik in der Digitalen Fabrik,https://moodle.technikum-wien.at/course/view.php?id=4188 +aburaia,WS2016,BMR5_PRAK_2016,BMR5_Berufspraktikum_2016,https://moodle.technikum-wien.at/course/view.php?id=3746 +aburaia,WS2016,BMR-VZ-3-WS2016-PJM,Projektmanagement,https://moodle.technikum-wien.at/course/view.php?id=3452 +aburaia,WS2016,MMR-3-WS2016_PROJ,MMR-3-WS2016 - Projekt,https://moodle.technikum-wien.at/course/view.php?id=3351 +aburaia,WS2016,MMR-BB-1-WS2016-BMECH,Mechatronik 1,https://moodle.technikum-wien.at/course/view.php?id=4038 +aburaia,WS2016,MMR-VZ-1-WS2016-VMECH,Mechatronik 1,https://moodle.technikum-wien.at/course/view.php?id=4037 +aburaia,WS2016,MMR-VZ-4-WS2016-MT,Master Thesis,https://moodle.technikum-wien.at/course/view.php?id=3956 +aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,Projekt,https://moodle.technikum-wien.at/course/view.php?id=3643 +adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 +adams,SS2016,BEW-DL-2-SS2016-ENG,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 +adams,SS2016,BEW-DL-4-SS2016-DLPS,Business Communication for Engineers,https://moodle.technikum-wien.at/course/view.php?id=2883 +adams,SS2016,BEW-DL-6-SS2016-ADC,Advanced Communication,https://moodle.technikum-wien.at/course/view.php?id=2897 +adams,SS2016,BIC-BB-2-SS2016-ENG/68928/68931,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2898 +adams,SS2016,BIW-BB-2-SS2016-PTC/67947,BIW-BB-2-SS2016 - Professional & Technical Communication 2,https://moodle.technikum-wien.at/course/view.php?id=3020 +adams,SS2016,BWI-DL-4-SS2016-BUCdl,Business Communication,https://moodle.technikum-wien.at/course/view.php?id=2879 +adams,SS2016,EWU-VZ-1-SS2016-WUE1,Warm-up Englisch 1,https://moodle.technikum-wien.at/course/view.php?id=3415 +adams,SS2016,MGR-VZ-4-SS2016-ENG/67338,Intensiv Englisch,https://moodle.technikum-wien.at/course/view.php?id=3174 +adams,WS2016,BEW-DL-3-WS2016-DLGI,General Information,https://moodle.technikum-wien.at/course/view.php?id=3481 +adams,WS2016,BEW-DL-3-WS2016-EC,Economics Technology and Society,https://moodle.technikum-wien.at/course/view.php?id=3414 +adams,WS2016,BIC-BB-1-WS2016-PSC/70705/70740,Professional and Social Communication,https://moodle.technikum-wien.at/course/view.php?id=3559 +adams,WS2016,BIW-BB-1-WS2016-PTC/73126,BIW-BB-1-WS2016 - Professional and Technical Communication 1,https://moodle.technikum-wien.at/course/view.php?id=3403 +adams,WS2016,BIW-BB-3-WS2016-EBE/72699,English for Business and Engineering,https://moodle.technikum-wien.at/course/view.php?id=3938 +adams,WS2016,BSA-VZ-1-WS2016-PSC,Professional and Social Communication,https://moodle.technikum-wien.at/course/view.php?id=3747 +adams,WS2016,BSA-VZ-3-WS2016-TCC,Technical and Creative Communication ,https://moodle.technikum-wien.at/course/view.php?id=3748 +adams,WS2016,BWI-DL-3-WS2016-ENGdl,Econonmics Technology and Society,https://moodle.technikum-wien.at/course/view.php?id=3608 +adensam,SS2016,MEE-BB-2-SS2016-BEV,Bewertungsverfahren,https://moodle.technikum-wien.at/course/view.php?id=2955 +adensam,WS2016,MEE-BB-3-WS2016-ERT,Energierecht,https://moodle.technikum-wien.at/course/view.php?id=3964 +adensam,WS2016,MEE-BB-3-WS2016-EWT,Energiewirtschaft,https://moodle.technikum-wien.at/course/view.php?id=3794 +adensam,WS2016,MUT-BB-3-WS2016-EM,Energiemanagement,https://moodle.technikum-wien.at/course/view.php?id=3676 +kraft,WS2016,MWI-DL-3-WS2016-MBdl,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3589 +kraft,WS2016,MWI-PT-1-WS2016-ITSCpt,IT Strategy and IT Controlling,https://moodle.technikum-wien.at/course/view.php?id=3560 +kraft,WS2016,MWI-PT-3-WS2016-MBpt,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3590 +kralc,SS2016,MEE-BB-2-SS2020-AS Anlagentechnik und Simulation (mit Modelica und Dymola),Anlagentechnik und Simulation mit Modelica und Dymola,https://moodle.technikum-wien.at/course/view.php?id=3025 +krametz,WS2016,WS2016-BEE3-ALB,WS2016-BEE3-ALB,https://moodle.technikum-wien.at/course/view.php?id=3624 +kratochv,SS2016,BST-VZ-2-SS2016-MTL,Materialtechnologie - Labor I,https://moodle.technikum-wien.at/course/view.php?id=3332 +kravtche,WS2016,BEW-BB-1-WS2016-LAB,Labor 1,https://moodle.technikum-wien.at/course/view.php?id=3734 +krenn,SS2016,BEW-DL-2-SS2016-PHY/67684,Physics 1,https://moodle.technikum-wien.at/course/view.php?id=2862 +krenn,WS2016,BEW-BB-5-WS2016-WIA,Wissenschaftliches Arbeiten,https://moodle.technikum-wien.at/course/view.php?id=3716 +krenn,WS2016,BEW-DL-3-WS2016-DLGI,General Information,https://moodle.technikum-wien.at/course/view.php?id=3481 +krenn,WS2016,BEW-DL-3-WS2016-PHY,Physics 2,https://moodle.technikum-wien.at/course/view.php?id=3378 +krennk,WS2016,BST-VZ-5-WS2016-BA1-MBAP3,Bachelorarbeit 1 - MBA Projekt 3 ,https://moodle.technikum-wien.at/course/view.php?id=3527 +krennm,SS2016,BBE-VZ-4-SS2016-CSA,Circuitdesign and Signal Analysis,https://moodle.technikum-wien.at/course/view.php?id=2956 +krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung,https://moodle.technikum-wien.at/course/view.php?id=3157 +krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 +krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 diff --git a/application/tmp/inputFileMitError.csv b/application/tmp/inputFileMitError.csv new file mode 100644 index 000000000..26c53a78d --- /dev/null +++ b/application/tmp/inputFileMitError.csv @@ -0,0 +1,11 @@ +uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url +aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 +aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,,https://moodle.technikum-wien.at/course/view.php?id=3643 +adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 +adams,SS2016,,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 +krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung, +krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 +krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 +kraft,WS2016,MWI-DL-3-WS2016-MBdl,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3589 +kraft,,MWI-PT-1-WS2016-ITSCpt,IT Strategy and IT Controlling,https://moodle.technikum-wien.at/course/view.php?id=3560 +kraft,WS2016,MWI-PT-3-WS2016-MBpt,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3590 diff --git a/application/tmp/inputFileUltra.csv b/application/tmp/inputFileUltra.csv new file mode 100644 index 000000000..927dc0062 --- /dev/null +++ b/application/tmp/inputFileUltra.csv @@ -0,0 +1,8 @@ +uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url +aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 +aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,Projekt,https://moodle.technikum-wien.at/course/view.php?id=3643 +adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 +adams,SS2016,BEW-DL-2-SS2016-ENG,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 +krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung,https://moodle.technikum-wien.at/course/view.php?id=3157 +krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 +krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 diff --git a/cis/private/lehre/notenliste.xls.php b/cis/private/lehre/notenliste.xls.php index 42dcc8418..2e0403139 100644 --- a/cis/private/lehre/notenliste.xls.php +++ b/cis/private/lehre/notenliste.xls.php @@ -270,17 +270,18 @@ else AND tbl_zeugnisnote.student_uid=tbl_student.student_uid AND tbl_zeugnisnote.studiensemester_kurzbz=tbl_studentlehrverband.studiensemester_kurzbz) LEFT JOIN bis.tbl_bisio ON(uid=tbl_bisio.student_uid) - LEFT JOIN bis.tbl_mobilitaet USING(prestudent_id) + LEFT JOIN bis.tbl_mobilitaet ON (bis.tbl_mobilitaet.prestudent_id = public.tbl_student.prestudent_id) LEFT JOIN lehre.tbl_note USING(note) WHERE vw_student_lehrveranstaltung.lehrveranstaltung_id=".$db->db_add_param($lvid, FHC_INTEGER)." - AND vw_student_lehrveranstaltung.studiensemester_kurzbz=".$db->db_add_param($stsem);";"; + AND vw_student_lehrveranstaltung.studiensemester_kurzbz=".$db->db_add_param($stsem);";"; if($lehreinheit_id!='') $qry.=" AND vw_student_lehrveranstaltung.lehreinheit_id=".$db->db_add_param($lehreinheit_id, FHC_INTEGER); $qry.=' ORDER BY nachname, vorname, person_id, tbl_bisio.bis, doubledegree DESC'; + if($result = $db->db_query($qry)) { $i=1; @@ -338,7 +339,7 @@ else $worksheet->write($lines,9, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright_date); $worksheet->write($lines,10, $resultPr->note, $format_highlightright); } - else + else { $worksheet->write($lines,9, '', $format_highlightright_date); $worksheet->write($lines,10, '', $format_highlightright); From c086eddfaecccaf40c3dc055f56f4a7f0ed1905e Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 8 May 2023 14:18:07 +0200 Subject: [PATCH 018/175] update Abfrage, delete testfiles --- application/inputFileTest.csv | 8 ----- application/tmp/inputFile.csv | 49 --------------------------- application/tmp/inputFileMitError.csv | 11 ------ application/tmp/inputFileUltra.csv | 8 ----- 4 files changed, 76 deletions(-) delete mode 100644 application/inputFileTest.csv delete mode 100644 application/tmp/inputFile.csv delete mode 100644 application/tmp/inputFileMitError.csv delete mode 100644 application/tmp/inputFileUltra.csv diff --git a/application/inputFileTest.csv b/application/inputFileTest.csv deleted file mode 100644 index 927dc0062..000000000 --- a/application/inputFileTest.csv +++ /dev/null @@ -1,8 +0,0 @@ -uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url -aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 -aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,Projekt,https://moodle.technikum-wien.at/course/view.php?id=3643 -adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 -adams,SS2016,BEW-DL-2-SS2016-ENG,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 -krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung,https://moodle.technikum-wien.at/course/view.php?id=3157 -krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 -krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 diff --git a/application/tmp/inputFile.csv b/application/tmp/inputFile.csv deleted file mode 100644 index 48411ca1a..000000000 --- a/application/tmp/inputFile.csv +++ /dev/null @@ -1,49 +0,0 @@ -uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url -aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 -aburaia,SS2016,BMR6_MES_2016,BMR6_Mechatronische-Systeme_2016,https://moodle.technikum-wien.at/course/view.php?id=2951 -aburaia,SS2016,BMR-VZ-6-SS2016-EMS,Entwurf mechatronischer Systeme,https://moodle.technikum-wien.at/course/view.php?id=2833 -aburaia,WS2016,BMB-VZ-5-WS2016-DF,Industrierobotik in der Digitalen Fabrik,https://moodle.technikum-wien.at/course/view.php?id=4188 -aburaia,WS2016,BMR5_PRAK_2016,BMR5_Berufspraktikum_2016,https://moodle.technikum-wien.at/course/view.php?id=3746 -aburaia,WS2016,BMR-VZ-3-WS2016-PJM,Projektmanagement,https://moodle.technikum-wien.at/course/view.php?id=3452 -aburaia,WS2016,MMR-3-WS2016_PROJ,MMR-3-WS2016 - Projekt,https://moodle.technikum-wien.at/course/view.php?id=3351 -aburaia,WS2016,MMR-BB-1-WS2016-BMECH,Mechatronik 1,https://moodle.technikum-wien.at/course/view.php?id=4038 -aburaia,WS2016,MMR-VZ-1-WS2016-VMECH,Mechatronik 1,https://moodle.technikum-wien.at/course/view.php?id=4037 -aburaia,WS2016,MMR-VZ-4-WS2016-MT,Master Thesis,https://moodle.technikum-wien.at/course/view.php?id=3956 -aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,Projekt,https://moodle.technikum-wien.at/course/view.php?id=3643 -adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 -adams,SS2016,BEW-DL-2-SS2016-ENG,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 -adams,SS2016,BEW-DL-4-SS2016-DLPS,Business Communication for Engineers,https://moodle.technikum-wien.at/course/view.php?id=2883 -adams,SS2016,BEW-DL-6-SS2016-ADC,Advanced Communication,https://moodle.technikum-wien.at/course/view.php?id=2897 -adams,SS2016,BIC-BB-2-SS2016-ENG/68928/68931,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2898 -adams,SS2016,BIW-BB-2-SS2016-PTC/67947,BIW-BB-2-SS2016 - Professional & Technical Communication 2,https://moodle.technikum-wien.at/course/view.php?id=3020 -adams,SS2016,BWI-DL-4-SS2016-BUCdl,Business Communication,https://moodle.technikum-wien.at/course/view.php?id=2879 -adams,SS2016,EWU-VZ-1-SS2016-WUE1,Warm-up Englisch 1,https://moodle.technikum-wien.at/course/view.php?id=3415 -adams,SS2016,MGR-VZ-4-SS2016-ENG/67338,Intensiv Englisch,https://moodle.technikum-wien.at/course/view.php?id=3174 -adams,WS2016,BEW-DL-3-WS2016-DLGI,General Information,https://moodle.technikum-wien.at/course/view.php?id=3481 -adams,WS2016,BEW-DL-3-WS2016-EC,Economics Technology and Society,https://moodle.technikum-wien.at/course/view.php?id=3414 -adams,WS2016,BIC-BB-1-WS2016-PSC/70705/70740,Professional and Social Communication,https://moodle.technikum-wien.at/course/view.php?id=3559 -adams,WS2016,BIW-BB-1-WS2016-PTC/73126,BIW-BB-1-WS2016 - Professional and Technical Communication 1,https://moodle.technikum-wien.at/course/view.php?id=3403 -adams,WS2016,BIW-BB-3-WS2016-EBE/72699,English for Business and Engineering,https://moodle.technikum-wien.at/course/view.php?id=3938 -adams,WS2016,BSA-VZ-1-WS2016-PSC,Professional and Social Communication,https://moodle.technikum-wien.at/course/view.php?id=3747 -adams,WS2016,BSA-VZ-3-WS2016-TCC,Technical and Creative Communication ,https://moodle.technikum-wien.at/course/view.php?id=3748 -adams,WS2016,BWI-DL-3-WS2016-ENGdl,Econonmics Technology and Society,https://moodle.technikum-wien.at/course/view.php?id=3608 -adensam,SS2016,MEE-BB-2-SS2016-BEV,Bewertungsverfahren,https://moodle.technikum-wien.at/course/view.php?id=2955 -adensam,WS2016,MEE-BB-3-WS2016-ERT,Energierecht,https://moodle.technikum-wien.at/course/view.php?id=3964 -adensam,WS2016,MEE-BB-3-WS2016-EWT,Energiewirtschaft,https://moodle.technikum-wien.at/course/view.php?id=3794 -adensam,WS2016,MUT-BB-3-WS2016-EM,Energiemanagement,https://moodle.technikum-wien.at/course/view.php?id=3676 -kraft,WS2016,MWI-DL-3-WS2016-MBdl,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3589 -kraft,WS2016,MWI-PT-1-WS2016-ITSCpt,IT Strategy and IT Controlling,https://moodle.technikum-wien.at/course/view.php?id=3560 -kraft,WS2016,MWI-PT-3-WS2016-MBpt,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3590 -kralc,SS2016,MEE-BB-2-SS2020-AS Anlagentechnik und Simulation (mit Modelica und Dymola),Anlagentechnik und Simulation mit Modelica und Dymola,https://moodle.technikum-wien.at/course/view.php?id=3025 -krametz,WS2016,WS2016-BEE3-ALB,WS2016-BEE3-ALB,https://moodle.technikum-wien.at/course/view.php?id=3624 -kratochv,SS2016,BST-VZ-2-SS2016-MTL,Materialtechnologie - Labor I,https://moodle.technikum-wien.at/course/view.php?id=3332 -kravtche,WS2016,BEW-BB-1-WS2016-LAB,Labor 1,https://moodle.technikum-wien.at/course/view.php?id=3734 -krenn,SS2016,BEW-DL-2-SS2016-PHY/67684,Physics 1,https://moodle.technikum-wien.at/course/view.php?id=2862 -krenn,WS2016,BEW-BB-5-WS2016-WIA,Wissenschaftliches Arbeiten,https://moodle.technikum-wien.at/course/view.php?id=3716 -krenn,WS2016,BEW-DL-3-WS2016-DLGI,General Information,https://moodle.technikum-wien.at/course/view.php?id=3481 -krenn,WS2016,BEW-DL-3-WS2016-PHY,Physics 2,https://moodle.technikum-wien.at/course/view.php?id=3378 -krennk,WS2016,BST-VZ-5-WS2016-BA1-MBAP3,Bachelorarbeit 1 - MBA Projekt 3 ,https://moodle.technikum-wien.at/course/view.php?id=3527 -krennm,SS2016,BBE-VZ-4-SS2016-CSA,Circuitdesign and Signal Analysis,https://moodle.technikum-wien.at/course/view.php?id=2956 -krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung,https://moodle.technikum-wien.at/course/view.php?id=3157 -krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 -krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 diff --git a/application/tmp/inputFileMitError.csv b/application/tmp/inputFileMitError.csv deleted file mode 100644 index 26c53a78d..000000000 --- a/application/tmp/inputFileMitError.csv +++ /dev/null @@ -1,11 +0,0 @@ -uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url -aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 -aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,,https://moodle.technikum-wien.at/course/view.php?id=3643 -adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 -adams,SS2016,,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 -krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung, -krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 -krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 -kraft,WS2016,MWI-DL-3-WS2016-MBdl,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3589 -kraft,,MWI-PT-1-WS2016-ITSCpt,IT Strategy and IT Controlling,https://moodle.technikum-wien.at/course/view.php?id=3560 -kraft,WS2016,MWI-PT-3-WS2016-MBpt,Mobile Business,https://moodle.technikum-wien.at/course/view.php?id=3590 diff --git a/application/tmp/inputFileUltra.csv b/application/tmp/inputFileUltra.csv deleted file mode 100644 index 927dc0062..000000000 --- a/application/tmp/inputFileUltra.csv +++ /dev/null @@ -1,8 +0,0 @@ -uid,studiensemester,moodle_course_shortname,moodle_course_fullname,moodle_course_url -aburaia,SS2016,BMR4_MLAB2_2016,BMR4_Mechatronics-Lab2_2016,https://moodle.technikum-wien.at/course/view.php?id=2948 -aburaia,WS2016,MMR-VZB-3-WS2016-PRJ,Projekt,https://moodle.technikum-wien.at/course/view.php?id=3643 -adams,SS2016,BEW-BB-4-SS2016-ENG/67791,Business English 2,https://moodle.technikum-wien.at/course/view.php?id=3034 -adams,SS2016,BEW-DL-2-SS2016-ENG,Technical and Creative Communication,https://moodle.technikum-wien.at/course/view.php?id=2873 -krizek,SS2016,BVU-VZ-6-SS2016-PSB,Praxissemesterbegleitung,https://moodle.technikum-wien.at/course/view.php?id=3157 -krizek,SS2016,MIT-VZ-2-SS2016-ITS PRJ I,ITS Project I,https://moodle.technikum-wien.at/course/view.php?id=3175 -krizek,WS2016,MSC-VZ-3-WS2016-IP2,ITS Project II,https://moodle.technikum-wien.at/course/view.php?id=3713 From 08c594148bfb0f20a113b670fc67911e5b023e2d Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 17 May 2023 08:41:04 +0200 Subject: [PATCH 019/175] - details bei abgewiesenen --- .../controllers/system/infocenter/InfoCenter.php | 11 +++++++++-- .../system/infocenter/infocenterAbgewiesenData.php | 11 +++++++++++ .../views/system/infocenter/infocenterDetails.php | 3 ++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 548b071d3..1e6639d25 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -314,7 +314,7 @@ class InfoCenter extends Auth_Controller show_error('Person does not exist!'); $origin_page = $this->input->get(self::ORIGIN_PAGE); - if ($origin_page == self::INDEX_PAGE) + if (in_array($origin_page, array(self::INDEX_PAGE, self::ABGEWIESEN_PAGE))) { // mark person as locked for editing $result = $this->PersonLockModel->lockPerson($person_id, $this->_uid, self::APP); @@ -359,7 +359,14 @@ class InfoCenter extends Auth_Controller if (isError($result)) show_error(getError($result)); - $redirectLink = '/'.self::INFOCENTER_URI.'?'.self::FHC_CONTROLLER_ID.'='.$this->getControllerId(); + $origin_page = $this->input->get(self::ORIGIN_PAGE); + + if ($origin_page === self::ABGEWIESEN_PAGE) + $redirectLink = self::INFOCENTER_URI. '/' .self::ABGEWIESEN_PAGE; + else + $redirectLink = '/'.self::INFOCENTER_URI; + + $redirectLink .= '?'.self::FHC_CONTROLLER_ID.'='.$this->getControllerId(); // Force reload of Dataset after Unlock $redirectLink .= '&'.self::KEEP_TABLESORTER_FILTER.'=true'; diff --git a/application/views/system/infocenter/infocenterAbgewiesenData.php b/application/views/system/infocenter/infocenterAbgewiesenData.php index d09f0f41e..94d3d6ee1 100644 --- a/application/views/system/infocenter/infocenterAbgewiesenData.php +++ b/application/views/system/infocenter/infocenterAbgewiesenData.php @@ -70,6 +70,7 @@ $query = ' 'requiredPermissions' => 'infocenter', 'datasetRepresentation' => 'tablesorter', 'checkboxes' => 'PersonId', + 'additionalColumns' => array('Details'), 'columnsAliases' => array( 'PersonId', 'PreStudentID', @@ -82,6 +83,16 @@ $query = ' ), 'formatRow' => function($datasetRaw) { + /* NOTE: Dont use $this here for PHP Version compatibility */ + $datasetRaw->{'Details'} = sprintf( + 'Details', + site_url('system/infocenter/InfoCenter/showDetails'), + $datasetRaw->{'PersonId'}, + 'abgewiesen', + (isset($_GET['fhc_controller_id']) ? $_GET['fhc_controller_id'] : ''), + (isset($_GET['filter_id']) ? $_GET['filter_id'] : '') + ); + if ($datasetRaw->{'Nachricht'} === null) { $datasetRaw->{'Nachricht'} = 'Nein'; diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index 401e34099..c61bb3cd2 100644 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -57,10 +57,11 @@ if (isset($lockedby)): echo $this->p->t('global', 'wirdBearbeitetVon').': '; echo $lockedby; - if ($origin_page == 'index'): + if (in_array($origin_page, array('index', 'abgewiesen'))): $unlockpath = 'unlockPerson/'.$stammdaten->person_id; $unlockpath .= '?fhc_controller_id='.$fhc_controller_id; $unlockpath .= '&filter_id='.$prev_filter_id; + $unlockpath .= '&origin_page='.$origin_page; ?>    From 8584be651b00498d8d03395cfc3469e5fb46c528 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 17 May 2023 15:06:39 +0200 Subject: [PATCH 020/175] - sperren von rts bearbeitet --- vilesci/stammdaten/auswertung_fhtw.php | 103 +++++++++++++++++++------ 1 file changed, 79 insertions(+), 24 deletions(-) diff --git a/vilesci/stammdaten/auswertung_fhtw.php b/vilesci/stammdaten/auswertung_fhtw.php index e5975b651..2d3d1bc61 100644 --- a/vilesci/stammdaten/auswertung_fhtw.php +++ b/vilesci/stammdaten/auswertung_fhtw.php @@ -490,22 +490,58 @@ if ($rtprueflingEntSperren) exit(); } - if (isset($_POST['prestudent_id']) && is_numeric($_POST['prestudent_id']) + if (isset($_POST['person_id']) && is_numeric($_POST['person_id']) && isset($_POST['art'])) { - $qry = "UPDATE testtool.tbl_pruefling SET gesperrt =" . $db->db_add_param($_POST['art'], 'BOOLEAN') . " - WHERE prestudent_id IN - (SELECT prestudent_id FROM public.tbl_prestudent ps - JOIN public.tbl_person tp ON tp.person_id = ps.person_id - WHERE tp.person_id = (SELECT person_id FROM public.tbl_prestudent sps WHERE sps.prestudent_id = " . $db->db_add_param($_POST['prestudent_id']) . "));"; + $qry = "SELECT pruefling_id + FROM testtool.tbl_pruefling + WHERE prestudent_id IN ( + SELECT prestudent_id + FROM public.tbl_prestudent + WHERE person_id = ". $db->db_add_param($_POST['person_id']) . " + )"; + if ($result = $db->db_query($qry)) { - $msg = $_POST['art'] === 'false' ? 'Pruefling wurde gesperrt' : 'Pruefling wurde freigeschaltet'; - echo json_encode(array( - 'status' => 'ok', - 'msg' => $msg)); - exit(); + + if ($db->db_num_rows($result) === 0) + { + echo json_encode(array( + 'status' => 'warning', + 'msg' => 'Kein Pruefling gefunden!' + )); + exit(); + } + else + { + $pruefling_ids = array(); + while ($row = $db->db_fetch_object($result)) + { + $pruefling_ids[] = $row->pruefling_id; + } + + + $qry = "UPDATE testtool.tbl_pruefling SET gesperrt =" . $db->db_add_param($_POST['art'], 'BOOLEAN') . " + WHERE pruefling_id IN (" . $db->db_implode4SQL($pruefling_ids) . ")"; + + if ($result_update = $db->db_query($qry)) + { + $msg = $_POST['art'] === 'false' ? 'Pruefling wurde gesperrt' : 'Pruefling wurde freigeschaltet'; + echo json_encode(array( + 'status' => 'ok', + 'msg' => $msg)); + exit(); + } + else + { + echo json_encode(array( + 'status' => 'fehler', + 'msg' => 'Fehler beim speichern der Daten' + )); + exit(); + } + } } else { @@ -1650,6 +1686,7 @@ if (isset($_REQUEST['reihungstest']) || isset($_POST['rtauswsubmit'])) } $gebiete_arr = array(); + $gesperrt_arr = array(); while ($row = $db->db_fetch_object($result)) { // Hack für BEW-BB, wenn auch BEW-DL-Ergebnisse vorliegen @@ -1666,7 +1703,10 @@ if (isset($_REQUEST['reihungstest']) || isset($_POST['rtauswsubmit'])) $ergebnis[$row->prestudent_id] = new stdClass(); $gebiete_arr[$row->prestudent_id] = array(); } - + + if (!isset($gesperrt_arr[$row->person_id])) + $gesperrt_arr[$row->person_id] = new stdClass(); + $ergebnis[$row->prestudent_id]->prestudent_id = $row->prestudent_id; $ergebnis[$row->prestudent_id]->person_id = $row->person_id; $ergebnis[$row->prestudent_id]->reihungstest_id = $row->reihungstest_id; @@ -1678,7 +1718,6 @@ if (isset($_REQUEST['reihungstest']) || isset($_POST['rtauswsubmit'])) $ergebnis[$row->prestudent_id]->geschlecht = $row->geschlecht; $ergebnis[$row->prestudent_id]->idnachweis = $row->idnachweis; $ergebnis[$row->prestudent_id]->registriert = $row->registriert; - $ergebnis[$row->prestudent_id]->gesperrt = $row->gesperrt; $ergebnis[$row->prestudent_id]->stg_kurzbz = $row->stg_kurzbz; $ergebnis[$row->prestudent_id]->stg_bez = $row->stg_bez; $ergebnis[$row->prestudent_id]->ausbildungssemester = $row->ausbildungssemester; @@ -1690,6 +1729,13 @@ if (isset($_REQUEST['reihungstest']) || isset($_POST['rtauswsubmit'])) $ergebnis[$row->prestudent_id]->teilgenommen = $db->db_parse_bool($row->teilgenommen); $ergebnis[$row->prestudent_id]->qualifikationskurs = $db->db_parse_bool($row->qualifikationskurs); $ergebnis[$row->prestudent_id]->letzter_status = $row->letzter_status; + $ergebnis[$row->prestudent_id]->gesperrt = $row->gesperrt; + + $gesperrt = $db->db_parse_bool($row->gesperrt); + if (!isset($gesperrt_arr[$row->person_id]->gesperrt) || ($gesperrt_arr[$row->person_id]->gesperrt !== true && $gesperrt === true)) + { + $gesperrt_arr[$row->person_id]->gesperrt = $gesperrt; + } if (!isset($ergebnis[$row->prestudent_id]->gebiet[$row->gebiet_id])) { @@ -2440,7 +2486,7 @@ else }); } } - function prueflingEntSperren(prestudent_id, name, art) + function prueflingEntSperren(person_id, name, art) { if (art === true) var text = "sperren"; @@ -2450,7 +2496,7 @@ else if (confirm("Wollen Sie den Studenten "+ name + " wirklich " + text + "?")) { data = { - prestudent_id: prestudent_id, + person_id: person_id, art: art, rtprueflingEntSperren: true }; @@ -2464,21 +2510,30 @@ else { if(data.status !== "ok") { - $("#msgbox").attr("class","alert alert-danger"); - $("#msgbox").show(); - $("#msgbox").html(data["msg"]); + if (data.status === "warning") + { + $("#msgbox").attr("class","alert alert-warning"); + $("#msgbox").show(); + $("#msgbox").html(data["msg"]); + } + else + { + $("#msgbox").attr("class","alert alert-danger"); + $("#msgbox").show(); + $("#msgbox").html(data["msg"]); + } } else { if (art === true) { - $("#prueflingentsperren_" + prestudent_id).removeClass("hidden"); - $("#prueflingsperren_" + prestudent_id).addClass("hidden"); + $(".prueflingentsperren_" + person_id).removeClass("hidden"); + $(".prueflingsperren_" + person_id).addClass("hidden"); } else if (art === false) { - $("#prueflingsperren_" + prestudent_id).removeClass("hidden"); - $("#prueflingentsperren_" + prestudent_id).addClass("hidden"); + $(".prueflingsperren_" + person_id).removeClass("hidden"); + $(".prueflingentsperren_" + person_id).addClass("hidden"); } } }, @@ -3293,10 +3348,10 @@ else echo " - + - + "; From 54de577eee823a1e4def530cd2b43046fec1feae Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 17 May 2023 15:08:52 +0200 Subject: [PATCH 021/175] - ausblenden des warnings --- vilesci/stammdaten/auswertung_fhtw.php | 1 + 1 file changed, 1 insertion(+) diff --git a/vilesci/stammdaten/auswertung_fhtw.php b/vilesci/stammdaten/auswertung_fhtw.php index 2d3d1bc61..e72c03bc5 100644 --- a/vilesci/stammdaten/auswertung_fhtw.php +++ b/vilesci/stammdaten/auswertung_fhtw.php @@ -2515,6 +2515,7 @@ else $("#msgbox").attr("class","alert alert-warning"); $("#msgbox").show(); $("#msgbox").html(data["msg"]); + $("#msgbox").html(data["msg"]).delay(2000).fadeOut(); } else { From 2f573263ba5cb3d00ef3e018cf2684048ef32b7c Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 17 May 2023 16:00:34 +0200 Subject: [PATCH 022/175] - abfrage ob der pruefling bereits gesperrt ist --- cis/testtool/frage.php | 2 +- include/pruefling.class.php | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/cis/testtool/frage.php b/cis/testtool/frage.php index 6f47992a1..9f6cd4fb7 100644 --- a/cis/testtool/frage.php +++ b/cis/testtool/frage.php @@ -161,7 +161,7 @@ if(!isset($_SESSION['pruefling_id'])) $pruefling = new pruefling(); $pruefling->load($_SESSION['pruefling_id']); -if ($pruefling->gesperrt === 't') +if ($pruefling->isGesperrt($_SESSION['pruefling_id'])) die(""); if (!in_array($gebiet_id, $_SESSION['alleGebiete'])) diff --git a/include/pruefling.class.php b/include/pruefling.class.php index fc64d90c4..2a482d793 100644 --- a/include/pruefling.class.php +++ b/include/pruefling.class.php @@ -557,5 +557,31 @@ class pruefling extends basis_db return false; } } + + public function isGesperrt($pruefling_id) + { + $qry = "SELECT spruefling.gesperrt + FROM testtool.tbl_pruefling + JOIN public.tbl_prestudent USING(prestudent_id) + JOIN public.tbl_person USING (person_id) + JOIN public.tbl_prestudent pss ON pss.person_id = tbl_person.person_id + JOIN testtool.tbl_pruefling spruefling ON pss.prestudent_id = spruefling.prestudent_id + WHERE tbl_pruefling.pruefling_id = ".$this->db_add_param($pruefling_id, FHC_INTEGER)." + AND spruefling.gesperrt + LIMIT 1"; + + if($result = $this->db_query($qry)) + { + if ($this->db_num_rows($result) == 0) + return false; + else + return true; + } + else + { + $this->errormsg = 'Fehler bei einer Abfrage'; + return false; + } + } } ?> From 311d235fda8cad5e69ac78702ef50a4106c45c4c Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 17 May 2023 16:35:22 +0200 Subject: [PATCH 023/175] - abgewiesene gesperrt von spalte --- .../infocenter/infocenterAbgewiesenData.php | 33 +++++++++++++++++++ system/filtersupdate.php | 3 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/application/views/system/infocenter/infocenterAbgewiesenData.php b/application/views/system/infocenter/infocenterAbgewiesenData.php index 94d3d6ee1..2307ea87e 100644 --- a/application/views/system/infocenter/infocenterAbgewiesenData.php +++ b/application/views/system/infocenter/infocenterAbgewiesenData.php @@ -1,6 +1,7 @@ config->load('infocenter'); + $APP = '\'infocenter\''; $ABGEWIESENEN_STATUS = '\'Abgewiesener\''; $STUDIENGANG_TYP = '\''.$this->variablelib->getVar('infocenter_studiensgangtyp').'\''; $ADDITIONAL_STG = $this->config->item('infocenter_studiengang_kz'); @@ -17,6 +18,8 @@ $query = ' p.nachname AS "Nachname", so.studiengangkurzbzlang as "Studiengang", pss.insertamum AS "AbgewiesenAm", + pl.zeitpunkt AS "LockDate", + pl.lockuser AS "LockUser", ( SELECT l.zeitpunkt FROM system.tbl_log l @@ -54,6 +57,15 @@ $query = ' JOIN public.tbl_studiengang sg USING(studiengang_kz) JOIN lehre.tbl_studienplan sp USING(studienplan_id) JOIN lehre.tbl_studienordnung so USING(studienordnung_id) + LEFT JOIN ( + SELECT tpl.person_id, + tpl.zeitpunkt, + sp.nachname AS lockuser + FROM system.tbl_person_lock tpl + JOIN public.tbl_benutzer sb USING (uid) + JOIN public.tbl_person sp ON sb.person_id = sp.person_id + WHERE tpl.app = '.$APP.' + ) pl USING(person_id) WHERE pss.status_kurzbz = '. $ABGEWIESENEN_STATUS .' AND pss.studiensemester_kurzbz = '. $STUDIENSEMESTER .' AND (sg.typ IN ('. $STUDIENGANG_TYP .') @@ -78,6 +90,8 @@ $query = ' ucfirst($this->p->t('person', 'nachname')), ucfirst($this->p->t('lehre', 'studiengang')), ucfirst($this->p->t('infocenter', 'abgewiesenam')), + ucfirst($this->p->t('global', 'sperrdatum')), + ucfirst($this->p->t('global', 'gesperrtVon')), ucfirst($this->p->t('global', 'nachricht')), ucfirst($this->p->t('infocenter', 'kaution')) ), @@ -114,10 +128,29 @@ $query = ' { $datasetRaw->{'Kaution'} = 'Offen'; } + + if ($datasetRaw->{'LockDate'} == null) + { + $datasetRaw->{'LockDate'} = '-'; + } + + if ($datasetRaw->{'LockUser'} == null) + { + $datasetRaw->{'LockUser'} = '-'; + } $datasetRaw->{'AbgewiesenAm'} = date_format(date_create($datasetRaw->{'AbgewiesenAm'}),'Y-m-d H:i'); return $datasetRaw; + }, + + 'markRow' => function($datasetRaw) { + + if ($datasetRaw->LockDate != null) + { + return FilterWidget::DEFAULT_MARK_ROW_CLASS; + } } + ); echo $this->widgetlib->widget('FilterWidget', $filterWidgetArray); diff --git a/system/filtersupdate.php b/system/filtersupdate.php index 2ed253422..abdea4532 100644 --- a/system/filtersupdate.php +++ b/system/filtersupdate.php @@ -520,7 +520,8 @@ $filters = array( {"name": "Studiengang"}, {"name": "AbgewiesenAm"}, {"name": "Nachricht"}, - {"name": "Kaution"} + {"name": "Kaution"}, + {"name": "LockUser"} ], "filters": [] } From 5001713d16177e0470bb443337289e3ded3c9da7 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 19 May 2023 07:51:25 +0200 Subject: [PATCH 024/175] Erzwingen von Reload nach jeder Freigabe --- .../benotungstool/lvgesamtnoteverwalten.php | 288 +++++++++--------- 1 file changed, 146 insertions(+), 142 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index d498636ae..c32fa43e6 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -104,6 +104,152 @@ $sprachen->getAll(true); $errormsg = ''; +// eingetragene lv-gesamtnoten freigeben +if (isset($_REQUEST["freigabe"]) && ($_REQUEST["freigabe"] == 1)) +{ + // Passwort pruefen + if (checkldapuser($user, $_REQUEST['passwort'])) + { + $jetzt = date("Y-m-d H:i:s"); + $neuenoten = 0; + + $studlist = " + "; + + // entweder personenbezogene Daten einbinden + if (defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE) + { + $studlist .= " + + + + + "; + + if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + { + $studlist .= "\n"; + } + $studlist .= "\n"; + + $studlist .= "\n"; + } + // oder anonymisiert nur die UIDs einbinden + else + { + $studlist .= " + \n + "; + } + + // studentenquery + $qry_stud = "SELECT + DISTINCT uid, vorname, nachname, matrikelnr, kurzbzlang + FROM + campus.vw_student_lehrveranstaltung + JOIN campus.vw_student USING(uid) + JOIN public.tbl_studiengang ON campus.vw_student.studiengang_kz = public.tbl_studiengang.studiengang_kz + WHERE + studiensemester_kurzbz = " . $db->db_add_param($stsem) . " + AND lehrveranstaltung_id = " . $db->db_add_param($lvid, FHC_INTEGER) . " + ORDER BY nachname, vorname "; + if ($result_stud = $db->db_query($qry_stud)) + { + $i = 1; + while ($row_stud = $db->db_fetch_object($result_stud)) + { + $lvgesamtnote = new lvgesamtnote(); + if ($lvgesamtnote->load($lvid, $row_stud->uid, $stsem)) + { + if ($lvgesamtnote->benotungsdatum > $lvgesamtnote->freigabedatum) + { + $lvgesamtnote->freigabedatum = $jetzt; + $lvgesamtnote->freigabevon_uid = $user; + $lvgesamtnote->save(); + + if (defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE) + { + $studlist .= ""; + $studlist .= ""; + $studlist .= ""; + $studlist .= ""; + + if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + { + $studlist .= "\n"; + } + $studlist .= ""; + + $studlist .= "\n"; + } + else + { + $studlist .= "\n"; + } + + $neuenoten ++; + } + } + } + } + + $studlist .= "
" . $p->t('global/personenkz') . "" . $p->t('global/studiengang') . "" . $p->t('global/nachname') . "" . $p->t('global/vorname') . "" . $p->t('benotungstool/punkte') . "" . $p->t('benotungstool/note') . "" . $p->t('benotungstool/bearbeitetvon') . "
" . $p->t('global/uid') . "
" . trim($row_stud->matrikelnr) . "" . trim($row_stud->kurzbzlang) . "" . trim($row_stud->nachname) . "" . trim($row_stud->vorname) . ""; + if ($lvgesamtnote->punkte != '') + $studlist .= trim(number_format($lvgesamtnote->punkte, 2)); + $studlist .= "" . $noten_array[trim($lvgesamtnote->note)]['bezeichnung_mehrsprachig'][$sprache] . "" . $lvgesamtnote->mitarbeiter_uid; + if ($lvgesamtnote->updatevon != '') + $studlist .= " (" . $lvgesamtnote->updatevon . ")"; + $studlist .= "
" . trim($row_stud->uid) . "
"; + + // mail an assistentin und den user selber verschicken + if ($neuenoten > 0) + { + $lv = new lehrveranstaltung($lvid); + $sg = new studiengang($lv->studiengang_kz); + $lektor_adresse = $user . "@" . DOMAIN; + $adressen = $sg->email . ", " . $user . "@" . DOMAIN; + + $studienplan = new studienplan(); + $studienplan->getStudienplanLehrveranstaltung($lvid, $stsem); + $studienplan_bezeichnung = ''; + foreach ($studienplan->result as $row) + $studienplan_bezeichnung .= $row->bezeichnung . ' '; + + $mit = new mitarbeiter(); + $mit->load($user); + $name = $mit->anrede.' '.$mit->vorname.' '.$mit->nachname.' ('.$mit->kurzbz.')'; + + $betreff = 'Notenfreigabe ' . $lv->bezeichnung . ' ' . $lv->orgform_kurzbz . ' - ' . $studienplan_bezeichnung; + $mail = new mail($adressen, 'vilesci@' . DOMAIN, $betreff, ''); + $htmlcontent = " + + $name hat neue Noten für die Lehrveranstaltung\n\n
+ " . $sg->kuerzel . ' ' . $lv->semester . '.Semester + ' . $lv->bezeichnung . " " . $lv->orgform_kurzbz . " - " . $stsem . " +
eingetragen.\n

+ Die Noten können jetzt ins Zeugnis übernommen werden.\n"; + + $htmlcontent .= $studlist; + + $htmlcontent.= " +
Anzahl der Noten:" . $neuenoten . " +

" . $p->t('abgabetool/mailVerschicktAn') . ": " . $adressen . " + "; + $mail->setHTMLContent($htmlcontent); + $mail->setReplyTo($lektor_adresse); + $mail->send(); + } + + http_response_code(303); + header('Location: ' . $_SERVER['REQUEST_URI']); + exit; + } + else + { + $errormsg = $p->t('gesamtnote/passwortFalsch'); + } +} + echo ' @@ -926,148 +1072,6 @@ if (defined('CIS_ANWESENHEITSLISTE_NOTENLISTE_ANZEIGEN') && CIS_ANWESENHEITSLIST echo "
" . $p->t('benotungstool/notenlisteImport') . ""; } -// eingetragene lv-gesamtnoten freigeben -if (isset($_REQUEST["freigabe"]) && ($_REQUEST["freigabe"] == 1)) -{ - // Passwort pruefen - if (checkldapuser($user, $_REQUEST['passwort'])) - { - $jetzt = date("Y-m-d H:i:s"); - $neuenoten = 0; - - $studlist = " - "; - - // entweder personenbezogene Daten einbinden - if (defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE) - { - $studlist .= " - - - - - "; - - if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) - { - $studlist .= "\n"; - } - $studlist .= "\n"; - - $studlist .= "\n"; - } - // oder anonymisiert nur die UIDs einbinden - else - { - $studlist .= " - \n - "; - } - - // studentenquery - $qry_stud = "SELECT - DISTINCT uid, vorname, nachname, matrikelnr, kurzbzlang - FROM - campus.vw_student_lehrveranstaltung - JOIN campus.vw_student USING(uid) - JOIN public.tbl_studiengang ON campus.vw_student.studiengang_kz = public.tbl_studiengang.studiengang_kz - WHERE - studiensemester_kurzbz = " . $db->db_add_param($stsem) . " - AND lehrveranstaltung_id = " . $db->db_add_param($lvid, FHC_INTEGER) . " - ORDER BY nachname, vorname "; - if ($result_stud = $db->db_query($qry_stud)) - { - $i = 1; - while ($row_stud = $db->db_fetch_object($result_stud)) - { - $lvgesamtnote = new lvgesamtnote(); - if ($lvgesamtnote->load($lvid, $row_stud->uid, $stsem)) - { - if ($lvgesamtnote->benotungsdatum > $lvgesamtnote->freigabedatum) - { - $lvgesamtnote->freigabedatum = $jetzt; - $lvgesamtnote->freigabevon_uid = $user; - $lvgesamtnote->save(); - - if (defined('CIS_GESAMTNOTE_FREIGABEMAIL_NOTE') && CIS_GESAMTNOTE_FREIGABEMAIL_NOTE) - { - $studlist .= ""; - $studlist .= ""; - $studlist .= ""; - $studlist .= ""; - - if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) - { - $studlist .= "\n"; - } - $studlist .= ""; - - $studlist .= "\n"; - } - else - { - $studlist .= "\n"; - } - - $neuenoten ++; - } - } - } - } - - $studlist .= "
" . $p->t('global/personenkz') . "" . $p->t('global/studiengang') . "" . $p->t('global/nachname') . "" . $p->t('global/vorname') . "" . $p->t('benotungstool/punkte') . "" . $p->t('benotungstool/note') . "" . $p->t('benotungstool/bearbeitetvon') . "
" . $p->t('global/uid') . "
" . trim($row_stud->matrikelnr) . "" . trim($row_stud->kurzbzlang) . "" . trim($row_stud->nachname) . "" . trim($row_stud->vorname) . ""; - if ($lvgesamtnote->punkte != '') - $studlist .= trim(number_format($lvgesamtnote->punkte, 2)); - $studlist .= "" . $noten_array[trim($lvgesamtnote->note)]['bezeichnung_mehrsprachig'][$sprache] . "" . $lvgesamtnote->mitarbeiter_uid; - if ($lvgesamtnote->updatevon != '') - $studlist .= " (" . $lvgesamtnote->updatevon . ")"; - $studlist .= "
" . trim($row_stud->uid) . "
"; - - // mail an assistentin und den user selber verschicken - if ($neuenoten > 0) - { - $lv = new lehrveranstaltung($lvid); - $sg = new studiengang($lv->studiengang_kz); - $lektor_adresse = $user . "@" . DOMAIN; - $adressen = $sg->email . ", " . $user . "@" . DOMAIN; - - $studienplan = new studienplan(); - $studienplan->getStudienplanLehrveranstaltung($lvid, $stsem); - $studienplan_bezeichnung = ''; - foreach ($studienplan->result as $row) - $studienplan_bezeichnung .= $row->bezeichnung . ' '; - - $mit = new mitarbeiter(); - $mit->load($user); - $name = $mit->anrede.' '.$mit->vorname.' '.$mit->nachname.' ('.$mit->kurzbz.')'; - - $betreff = 'Notenfreigabe ' . $lv->bezeichnung . ' ' . $lv->orgform_kurzbz . ' - ' . $studienplan_bezeichnung; - $mail = new mail($adressen, 'vilesci@' . DOMAIN, $betreff, ''); - $htmlcontent = " - - $name hat neue Noten für die Lehrveranstaltung\n\n
- " . $sg->kuerzel . ' ' . $lv->semester . '.Semester - ' . $lv->bezeichnung . " " . $lv->orgform_kurzbz . " - " . $stsem . " -
eingetragen.\n

- Die Noten können jetzt ins Zeugnis übernommen werden.\n"; - - $htmlcontent .= $studlist; - - $htmlcontent.= " -
Anzahl der Noten:" . $neuenoten . " -

" . $p->t('abgabetool/mailVerschicktAn') . ": " . $adressen . " - "; - $mail->setHTMLContent($htmlcontent); - $mail->setReplyTo($lektor_adresse); - $mail->send(); - } - } - else - { - $errormsg = $p->t('gesamtnote/passwortFalsch'); - } -} - if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) { $onclickpath = "notenschluessel.php?lehrveranstaltung_id=$lvid&stsem=$stsem"; From f993780ec355cfec7b1612d4ab3878191c275daa Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 23 May 2023 13:17:27 +0200 Subject: [PATCH 025/175] - texte und anzeige angepasst --- include/reihungstest.class.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 2da424af5..633ddf1da 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -688,14 +688,14 @@ class reihungstest extends basis_db tbl_reihungstest.aufnahmegruppe_kurzbz, tbl_studiengang.typ, UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel, - tbl_studiengang.bezeichnung, - tbl_studiengang.english + so.studiengangbezeichnung as bezeichnung, + so.studiengangbezeichnung_englisch as english FROM public.tbl_rt_person - JOIN - public.tbl_reihungstest ON (rt_id=reihungstest_id) - LEFT JOIN - public.tbl_studiengang ON tbl_reihungstest.studiengang_kz = tbl_studiengang.studiengang_kz + JOIN public.tbl_reihungstest ON (rt_id=reihungstest_id) + JOIN public.tbl_studiengang ON tbl_reihungstest.studiengang_kz = tbl_studiengang.studiengang_kz + JOIN lehre.tbl_studienplan sp USING(studienplan_id) + JOIN lehre.tbl_studienordnung so USING(studienordnung_id) WHERE tbl_rt_person.person_id=".$this->db_add_param($person_id); From 09bc98543138f75d16a9e4b7a968a58b19f7f071 Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Tue, 23 May 2023 16:08:50 +0200 Subject: [PATCH 026/175] Notenumrechnung beim Punkteimport, Fehlermeldung wenn Note oder Punkte fehlen. --- .../benotungstool/lvgesamtnoteverwalten.php | 149 ++++++++++++------ .../benotungstool/nachpruefungeintragen.php | 15 ++ cis/private/lehre/notenliste.xls.php | 20 ++- 3 files changed, 132 insertions(+), 52 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index c32fa43e6..6dce2b6ae 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -341,6 +341,9 @@ foreach ($noten_obj->result as $row) } ?> + + const CIS_GESAMTNOTE_PUNKTE = ; + function getOffset(pos) { var x,y; @@ -799,33 +802,48 @@ foreach ($noten_obj->result as $row) } ?> + var linenumber = 0; for(row in rows) { - zeile = rows[row].split(" "); - - - - if (zeile[0]!='' && zeile[1]!='') + linenumber++; + if( rows[row] == '' ) { - gradedata['matrikelnr_'+i]=zeile[0]; - - - i++; + //skip empty lines + continue; } + zeile = rows[row].split(" "); + + if( zeile.length < 2 ) + { + alertMsg = alertMsg + "Zeile " + linenumber + ': ' + + 'Zu wenig Paramter - 2 erforderlich. ' + + 'Die Zeile wurde uebersprungen.' + "\n\n"; + continue; + } + + if (CIS_GESAMTNOTE_PUNKTE == false) + { + // check for valid grades + if (validGrades.indexOf(zeile[1]) === -1) + { + alertMsg = alertMsg + "Zeile " + linenumber + ': ' + + "Die Note "+zeile[1]+" ist nicht zulaessig. " + + "Die Zeile wurde uebersprungen. \n\n"; + continue; + } + } + + gradedata['matrikelnr_'+i]=zeile[0]; + if (CIS_GESAMTNOTE_PUNKTE) + { + gradedata['punkte_'+i]= zeile[1]; + } + else + { + gradedata['note_'+i]= zeile[1]; + } + + i++; } if (alertMsg != "") @@ -895,35 +913,70 @@ foreach ($noten_obj->result as $row) } ?> - + var linenumber = 0; for(row in rows) { - zeile = rows[row].split(" "); - - - - if (zeile[0]!='' && zeile[1]!='' && zeile[2]!='') + linenumber++; + if( rows[row] == '' ) { - gradedata['student_uid_'+i]=zeile[0]; - gradedata['datumNachp_'+i]=zeile[1]; - - - i++; + //skip empty lines + continue; } + zeile = rows[row].split(" "); + + if( zeile.length < 3 ) + { + alertMsg = alertMsg + "Zeile " + linenumber + ': ' + + 'Zu wenig Paramter - 3 erforderlich. ' + + 'Die Zeile wurde uebersprungen.' + "\n\n"; + continue; + } + + if( zeile[1] == '' && zeile[2] == '' ) + { + // ignore lines just copied from excel + continue; + } + + if( zeile[2] == '' ) + { + alertMsg = alertMsg + "Zeile " + linenumber + ': ' + + "Die Note oder Punkte fehlen. " + + "Die Zeile wurde uebersprungen. \n\n"; + continue; + } + + if (CIS_GESAMTNOTE_PUNKTE == false) + { + // check for valid grades + if (validGrades.indexOf(zeile[2]) === -1) + { + alertMsg = alertMsg + "Zeile " + linenumber + ': ' + + "Die Note "+zeile[2]+" ist nicht zulaessig. " + + "Die Zeile wurde uebersprungen. \n\n"; + continue; + } + } + + if( !zeile[1].match(/[0-9]{2}\.[0-9]{2}\.[0-9]{4}/) ) + { + alertMsg = alertMsg + "Zeile " + linenumber + ': ' + + "Das Datum "+zeile[1]+" fehlt oder ist nicht zulaessig. " + + "Die Zeile wurde uebersprungen. \n\n"; + continue; + } + + gradedata['student_uid_'+i]=zeile[0]; + gradedata['datumNachp_'+i]=zeile[1]; + if (CIS_GESAMTNOTE_PUNKTE) + { + gradedata['punkte_'+i]= zeile[2]; + } + else + { + gradedata['note_'+i]= zeile[2]; + } + i++; } diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 804ab34fb..873c0f173 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -130,6 +130,17 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) continue; } $punkte=str_replace(',', '.', $punkte); + if($punkte!='') + { + // Bei Punkteeingabe wird die Note nochmals geprueft und ggf korrigiert + $notenschluessel = new notenschluessel(); + $note_pruef = $notenschluessel->getNote($punkte, $lvid, $stsem); + if($note_pruef!=$note) + { + $note = $note_pruef; + $note_dirty=true; + } + } $datum = $_POST['datumNachp_'.$id]; //check Datumsformat @@ -172,6 +183,10 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $note = $noten_anmerkung[$note]; } $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); + if($response!='neu' && $response!='update' && $response!='update_f') + { + echo $response; + } } else { diff --git a/cis/private/lehre/notenliste.xls.php b/cis/private/lehre/notenliste.xls.php index 2e0403139..63cf45d29 100644 --- a/cis/private/lehre/notenliste.xls.php +++ b/cis/private/lehre/notenliste.xls.php @@ -226,7 +226,7 @@ else if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) { - $worksheet->write($lines,8,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,8,$p->t('global/personenkennzeichen'),$format_border_bottom); $worksheet->write($lines,9,$p->t('global/datum'),$format_border_bottom); if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) $worksheet->write($lines,10,$p->t('benotungstool/punkte'),$format_border_bottom); @@ -236,7 +236,7 @@ else if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { - $worksheet->write($lines,12,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,12,$p->t('global/personenkennzeichen'),$format_border_bottom); $worksheet->write($lines,13,$p->t('global/datum'),$format_border_bottom); if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) $worksheet->write($lines,14,$p->t('benotungstool/punkte'),$format_border_bottom); @@ -328,7 +328,7 @@ else // Nachprüfung if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) { - $worksheet->write($lines,8, $elem->uid, $format_highlightright); + $worksheet->write($lines,8, '="'.trim($elem->matrikelnr).'"', $format_highlight); $pr = new Pruefung(); $pr->getPruefungen($elem->uid, "Termin2", $lvid, $sem); $output2 = $pr->result; @@ -349,7 +349,7 @@ else // Nachprüfung if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { - $worksheet->write($lines,12, $elem->uid, $format_highlightright); + $worksheet->write($lines,12, '="'.trim($elem->matrikelnr).'"', $format_highlight); $pr = new Pruefung(); $pr->getPruefungen($elem->uid, "Termin3", $lvid, $sem); $output3 = $pr->result; @@ -420,5 +420,17 @@ else $worksheet->setColumn(0, 3, 25); $worksheet->setColumn(0, 4, 7); $worksheet->setColumn(0, 5, 21); + + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->setColumn(8, 8, 15); + $worksheet->setColumn(9, 9, 10); + } + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) + { + $worksheet->setColumn(12, 12, 15); + $worksheet->setColumn(13, 13, 10); + } + $workbook->close(); ?> From 9e883a48a05eb8ae56414a574461ad4db20a61db Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 2 Jun 2023 09:02:47 +0200 Subject: [PATCH 027/175] Adaptierungen Icalfiles Coole --- cis/public/coodle.php | 93 ++--- include/coodle.class.php | 722 ++++++++++++++++++++------------------- 2 files changed, 420 insertions(+), 395 deletions(-) diff --git a/cis/public/coodle.php b/cis/public/coodle.php index 721f2d3c0..2b8421db0 100644 --- a/cis/public/coodle.php +++ b/cis/public/coodle.php @@ -571,7 +571,7 @@ if (isset($_GET['resend'])) echo "
- + "; // Für Colspan bei Datum @@ -675,7 +675,6 @@ if (isset($_GET['resend'])) } else { - // Ort-Ressourcen ueberspringen if ($ressource->ort_kurzbz != '') { @@ -761,8 +760,8 @@ if (isset($_GET['resend'])) echo ' + @@ -98,33 +98,38 @@ export default { - - - - - - + + +
+ + + + + ` +} diff --git a/public/js/components/Bootstrap/Prompt.js b/public/js/components/Bootstrap/Prompt.js new file mode 100644 index 000000000..74e5c8b3f --- /dev/null +++ b/public/js/components/Bootstrap/Prompt.js @@ -0,0 +1,37 @@ + +import BsAlert from './Alert'; + +export default { + mixins: [ + BsAlert + ], + props: { + placeholder: String, + default: String + }, + data: () => ({ + value: '', + result: false + }), + created() { + if (this.default) + this.value = this.default; + }, + popup(msg, options) { + if (typeof options === 'string') + options = { default: options }; + return BsAlert.popup.bind(this)(msg, options); + }, + template: ` + + + ` +} diff --git a/public/js/components/Fetch.js b/public/js/components/Fetch.js index 32d5616d0..9a34e1a3f 100644 --- a/public/js/components/Fetch.js +++ b/public/js/components/Fetch.js @@ -53,7 +53,9 @@ export const CoreFetchCmpt = { * */ fetchData: function() { - this.loading = true; // loader started + this.loading = true; // loader started + this.error = false; + this.errorMessage = null; // Checks if the apifunction is a callable function if (typeof this.apiFunction == "function") @@ -91,13 +93,16 @@ export const CoreFetchCmpt = { * */ successHandler: function(response) { - this.$emit('dataFetched', response.data); // trigger the event dataFetched + this.$emit('dataFetched', response ? response.data : undefined); // trigger the event dataFetched }, /** * */ errorHandler: function(error) { - this.setError(error.message); + if (error.response.data.retval) + this.setError(error.response.data.retval); + else + this.setError(error.message); }, /** * @@ -107,12 +112,12 @@ export const CoreFetchCmpt = { } }, template: ` - +
Loading...
- +
{{ errorMessage }}
+ ` }; - diff --git a/public/js/components/Loader.js b/public/js/components/Loader.js new file mode 100644 index 000000000..ce4dee638 --- /dev/null +++ b/public/js/components/Loader.js @@ -0,0 +1,62 @@ +import BsModal from './Bootstrap/Modal.js'; + +export default { + components: { + BsModal + }, + props: { + timeout: { + type: Number, + default: 300 + } + }, + data() { + return { + t: null, + state: 0 + } + }, + methods: { + show() { + switch (this.state) { + case 0: + if (this.timeout) { + this.state = 1; + this.t = window.setTimeout(() => this.$refs.modal.show(), this.timeout); + return; + } else + return this.$refs.modal.show(); + case 4: + return window.setTimeout(() => this.show(), 1); + } + }, + hide() { + switch (this.state) { + case 1: + return window.clearTimeout(this.t); + case 2: + return window.setTimeout(() => this.hide(), 1); + case 3: + this.$refs.modal.hide(); + } + } + }, + mounted() { + this.$refs.modal.$refs.modal.addEventListener('show.bs.modal', () => { + this.state = 2; + }); + this.$refs.modal.$refs.modal.addEventListener('shown.bs.modal', () => { + this.state = 3; + }); + this.$refs.modal.$refs.modal.addEventListener('hide.bs.modal', () => { + this.state = 4; + }); + this.$refs.modal.$refs.modal.addEventListener('hidden.bs.modal', () => { + this.state = 0; + }); + }, + template: ` + + Loading... + ` +} \ No newline at end of file diff --git a/public/js/components/Studierendenantrag/Antrag.js b/public/js/components/Studierendenantrag/Antrag.js new file mode 100644 index 000000000..6619b74e7 --- /dev/null +++ b/public/js/components/Studierendenantrag/Antrag.js @@ -0,0 +1,60 @@ +import StudierendenantragAbmeldung from './Form/Abmeldung.js'; +import StudierendenantragUnterbrechung from './Form/Unterbrechung.js'; +import StudierendenantragWiederholung from './Form/Wiederholung.js'; +import Phrasen from '../../mixins/Phrasen.js'; + +export default { + components: { + StudierendenantragAbmeldung, + StudierendenantragUnterbrechung, + StudierendenantragWiederholung + }, + mixins: [ + Phrasen + ], + emits: [ + 'update:infoArray', + 'update:statusMsg', + 'update:statusSeverity' + ], + props: { + antragType: String, + prestudentId: Number, + studierendenantragId: Number, + infoArray: Array, + statusMsg: String, + statusSeverity: String + }, + data() { + return { + status: '' + }; + }, + computed: { + typeComponent() { + return 'Studierendenantrag' + this.antragType; + }, + infoText() { + return this.p.t('studierendenantrag/info_' + this.antragType + '_' + this.status); + } + }, + template: ` +
+
+ {{p.t('studierendenantrag', 'title_' + antragType)}} +
+ + + +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Form/Abmeldung.js b/public/js/components/Studierendenantrag/Form/Abmeldung.js new file mode 100644 index 000000000..0de6e3d16 --- /dev/null +++ b/public/js/components/Studierendenantrag/Form/Abmeldung.js @@ -0,0 +1,285 @@ +import {CoreFetchCmpt} from '../../Fetch.js'; +import Phrasen from '../../../mixins/Phrasen.js'; + +var _uuid = 0; + +export default { + components: { + CoreFetchCmpt + }, + mixins: [ + Phrasen + ], + emits: [ + 'setInfos', + 'setStatus' + ], + props: { + prestudentId: Number + }, + data() { + return { + data: null, + saving: false, + errors: { + grund: [], + default: [] + } + } + }, + computed: { + statusSeverity() { + switch (this.data.status) + { + case 'Erstellt': return 'info'; + case 'Genehmigt': return 'success'; + default: return 'info'; + } + } + }, + methods: { + load() { + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/getDetailsForNewAntrag/' + + this.prestudentId + ).then( + result => { + this.data = result.data.retval; + if (this.data.status) { + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + return result; + } + ); + }, + createAntrag() { + bootstrap.Modal.getOrCreateInstance(this.$refs.modal).hide(); + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}), + severity: 'warning' + }); + this.saving = true; + for(var k in this.errors) + this.errors[k] = []; + axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/createAntrag/', { + studiensemester: this.data.studiensemester_kurzbz, + prestudent_id: this.data.prestudent_id, + grund: this.$refs.grund.value + } + ).then( + result => { + if (result.data.error) + { + for (var k in result.data.retval) + { + if (this.errors[k] !== undefined) + this.errors[k].push(result.data.retval[k]); + else + this.errors.default.push(result.data.retval[k]); + } + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}), + severity: 'danger' + }); + } + else + { + if (result.data.retval === true) + document.location += ""; + this.data = result.data.retval; + if (this.data.status) { + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + else + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_open')}), + severity:'success' + }); + } + this.saving = false; + } + ); + }, + cancelAntrag() { + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelling')}), + severity: 'warning' + }); + this.saving = true; + for(var k in this.errors) + this.errors[k] = []; + axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/cancelAntrag/', { + antrag_id: this.data.studierendenantrag_id + } + ).then( + result => { + if (result.data.error) + { + for (var k in result.data.retval) + { + if (this.errors[k] !== undefined) + this.errors[k].push(result.data.retval[k]); + else + this.errors.default.push(result.data.retval[k]); + } + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}), + severity:'danger' + }); + } + else + { + if (Number.isInteger(result.data.retval)) { + document.location = document.location.replace(/abmeldung\/([0-9]*)\/[0-9]*[\/]?$/, 'abmeldung/$1') + "/" + result.data.retval; + } + this.data = result.data.retval; + if (this.data.status) { + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + else + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelled')}), + severity: 'danger' + }); + } + this.saving = false; + } + ); + } + }, + created() { + this.uuid = _uuid++; + }, + template: ` +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
{{p.t('lehre', 'studiengang')}}{{data.bezeichnung}}
{{p.t('lehre', 'organisationsform')}}{{data.orgform_bezeichnung}}
{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}{{data.name}}
{{p.t('person', 'personenkennzeichen')}}{{data.matrikelnr}}
{{p.t('lehre', 'studienjahr')}}{{data.studienjahr_kurzbz}}
{{p.t('lehre', 'semester')}}{{data.semester}}
+
+
+
{{p.t('studierendenantrag', 'antrag_grund')}}:
+
{{data.grund}}
+
+
+ + +
+ {{errors.grund.join(".")}} +
+
+
+ + + + +
+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Form/Unterbrechung.js b/public/js/components/Studierendenantrag/Form/Unterbrechung.js new file mode 100644 index 000000000..2034361bc --- /dev/null +++ b/public/js/components/Studierendenantrag/Form/Unterbrechung.js @@ -0,0 +1,359 @@ +import {CoreFetchCmpt} from '../../Fetch.js'; +import VueDatepicker from '../../vueDatepicker.js.php'; +import Phrasen from '../../../mixins/Phrasen.js'; + +var _uuid = 0; + +export default { + components: { + CoreFetchCmpt, + VueDatepicker + }, + mixins: [ + Phrasen + ], + emits: [ + 'setInfos', + 'setStatus' + ], + props: { + prestudentId: Number, + studierendenantragId: Number + }, + data() { + return { + data: null, + saving: false, + errors: { + grund: [], + studiensemester: [], + datum_wiedereinstieg: [], + default: [] + }, + stsem: null, + siteUrl: FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + } + }, + computed: { + statusSeverity() { + switch (this.data.status) + { + case 'Erstellt': return 'info'; + case 'Genehmigt': return 'success'; + case 'Zurückgezogen': return 'danger'; + default: return 'info'; + } + }, + loadUrl() { + if (this.studierendenantragId) + return '/components/Antrag/Unterbrechung/getDetailsForAntrag/'+ + this.studierendenantragId; + return '/components/Antrag/Unterbrechung/getDetailsForNewAntrag/' + + this.prestudentId; + }, + datumWsFormatted() { + if(!this.data.datum_wiedereinstieg) + return ''; + let datum = new Date(this.data.datum_wiedereinstieg); + return datum.toLocaleDateString(); + } + }, + methods: { + load() { + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + this.loadUrl + ).then( + result => { + this.data = result.data.retval; + if (this.data.status) { + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + return result; + } + ); + }, + createAntrag() { + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}), + severity: 'warning' + }); + this.saving = true; + for(var k in this.errors) + this.errors[k] = []; + + var formData = new FormData(); + var attachment = this.$refs.attachment; + formData.append("attachment", attachment.files[0]); + formData.append("studiensemester", this.stsem !== null && this.data.studiensemester[this.stsem].studiensemester_kurzbz); + formData.append("prestudent_id", this.data.prestudent_id); + formData.append("grund", this.$refs.grund.value); + formData.append("datum_wiedereinstieg", this.$refs.datum_wiedereinstieg && this.$refs.datum_wiedereinstieg.value); + + axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Unterbrechung/createAntrag/', + formData, + { + headers: { + 'Content-Type': 'multipart/form-data' + } + } + ).then( + result => { + if (result.data.error) + { + for (var k in result.data.retval) + { + if (this.errors[k] !== undefined) + this.errors[k].push(result.data.retval[k]); + else + this.errors.default.push(result.data.retval[k]); + } + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}), + severity: 'danger' + }); + } + else + { + if (Number.isInteger(result.data.retval)) + document.location += "/" + result.data.retval; + this.data = result.data.retval; + if (this.data.status) { + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + else + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_created')}), + severity: 'info' + }); + } + this.saving = false; + } + ); + }, + cancelAntrag() { + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelling')}), + severity: 'warning' + }); + this.saving = true; + for(var k in this.errors) + this.errors[k] = []; + axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Unterbrechung/cancelAntrag/', { + antrag_id: this.data.studierendenantrag_id + } + ).then( + result => { + if (result.data.error) + { + for (var k in result.data.retval) + { + if (this.errors[k] !== undefined) + this.errors[k].push(result.data.retval[k]); + else + this.errors.default.push(result.data.retval[k]); + } + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}), + severity: 'danger' + }); + } + else + { + if (Number.isInteger(result.data.retval)) { + document.location = document.location.replace(/unterbrechung\/([0-9]*)\/[0-9]*[\/]?$/, 'unterbrechung/$1') + "/" + result.data.retval; + } + this.data = result.data.retval; + if (this.data.status) { + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + else + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelled')}), + severity: 'danger' + }); + } + this.saving = false; + } + ); + } + }, + created() { + this.uuid = _uuid++; + }, + template: ` +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{p.t('lehre', 'studiengang')}}{{data.bezeichnung}}
{{p.t('lehre', 'organisationsform')}}{{data.orgform_bezeichnung}}
{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}{{data.name}}
{{p.t('person', 'personenkennzeichen')}}{{data.matrikelnr}}
{{p.t('lehre', 'studienjahr')}}{{data.studienjahr_kurzbz}}{{stsem === null ? '' : data.studiensemester[stsem].studienjahr_kurzbz}}
{{p.t('lehre', 'semester')}}{{data.semester}}{{stsem === null ? '' : data.studiensemester[stsem].semester}}
+
+ +
+ +
+ {{data.studiensemester_kurzbz}} +
+
+ +
+ {{errors.studiensemester.join(".")}} +
+
+
+
+ + +
+ {{datumWsFormatted}} +
+
+ + +
+ +
+ {{errors.datum_wiedereinstieg.join(".")}} +
+
+
+
{{p.t('studierendenantrag', 'antrag_grund')}}:
+
{{data.grund}}
+
+
+ + +
+ {{errors.grund.join(".")}} +
+
+
+ +
+ {{p.t('studierendenantrag', 'antrag_dateianhaenge')}} + {{p.t('studierendenantrag', 'no_attachments')}} +
+
+ + +
+
+
+ + +
+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Form/Wiederholung.js b/public/js/components/Studierendenantrag/Form/Wiederholung.js new file mode 100644 index 000000000..4cbc32d88 --- /dev/null +++ b/public/js/components/Studierendenantrag/Form/Wiederholung.js @@ -0,0 +1,212 @@ +import {CoreFetchCmpt} from '../../Fetch.js'; +import VueDatepicker from '../../vueDatepicker.js.php'; +import Phrasen from '../../../mixins/Phrasen.js'; + +var _uuid = 0; + +export default { + components: { + CoreFetchCmpt, + VueDatepicker + }, + mixins: [ + Phrasen + ], + emits: [ + 'setInfos', + 'setStatus', + 'update:status' + ], + props: { + status: String, + prestudentId: Number, + studierendenantragId: Number + }, + data() { + return { + data: null, + saving: false, + errors: { + grund: [], + default: [] + }, + siteUrl: FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router, + infos: [] + } + }, + computed: { + statusSeverity() { + switch (this.data.status) + { + case 'Erstellt': return 'info'; + case 'Genehmigt': return 'success'; + case 'Verzichtet': return 'danger'; + default: return 'info'; + } + }, + loadUrl() { + return '/components/Antrag/Wiederholung/getDetailsForNewAntrag/' + + this.prestudentId; + }, + datumPruefungFormatted() { + if(!this.data.pruefungsdatum) + return ''; + let datum = new Date(this.data.pruefungsdatum); + return datum.toLocaleDateString(); + } + }, + methods: { + load() { + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + this.loadUrl + ).then( + result => { + this.data = result.data.retval; + if (!this.data.status || this.data.status == 'ErsteAufforderungVersandt' || this.data.status == 'ZweiteAufforderungVersandt') + this.data.status = 'Offen'; + this.$emit('update:status', this.data.status); + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + return result; + } + ); + }, + createAntrag() { + this.createAntragWithStatus(true); + }, + cancelAntrag() { + this.createAntragWithStatus(false); + }, + createAntragWithStatus(repeat) { + let func = repeat ? 'createAntrag' : 'cancelAntrag'; + let nextState = repeat ? 'Erstellt' : 'Verzichtet'; + + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t_ref('studierendenantrag', 'status_saving')}), + severity: 'warning' + }); + this.saving = true; + for(var k in this.errors) + this.errors[k] = []; + + axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Wiederholung/' + func + '/', + { + prestudent_id: this.data.prestudent_id, + studiensemester: this.data.studiensemester_kurzbz + } + ).then( + result => { + if (result.data.error) + { + for (var k in result.data.retval) + { + if (this.errors[k] !== undefined) + this.errors[k].push(result.data.retval[k]); + else + this.errors.default.push(result.data.retval[k]); + } + this.$emit('setStatus', { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t_ref('studierendenantrag', 'status_error')}), + severity: 'danger' + }); + } + else + { + if (result.data.retval === true) + document.location += ""; + this.data = result.data.retval; + if (!this.data.status) + this.data.status = nextState; + this.$emit('update:status', this.data.status); + this.$emit("setStatus", { + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); + } + this.saving = false; + } + ); + } + }, + created() { + this.uuid = _uuid++; + }, + mounted() { + this.infos = [...Array(5).keys()].map(n => ({ + body: this.p.t_ref('studierendenantrag', 'infotext_Wiederholung_' + n) + })); + this.$emit('setInfos', this.infos); + }, + template: ` +
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
{{p.t('lehre', 'studiengang')}}{{data.bezeichnung}}
{{p.t('lehre', 'organisationsform')}}{{data.orgform_bezeichnung}}
{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}{{data.name}}
{{p.t('person', 'personenkennzeichen')}}{{data.matrikelnr}}
{{p.t('studierendenantrag', 'antrag_Wiederholung_pruefung')}}{{data.lvbezeichnung}}
{{p.t('studierendenantrag', 'antrag_Wiederholung_pruefung_date')}}{{datumPruefungFormatted}}
+
+ +
+ + +
+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Infoblock.js b/public/js/components/Studierendenantrag/Infoblock.js new file mode 100644 index 000000000..59e3cce96 --- /dev/null +++ b/public/js/components/Studierendenantrag/Infoblock.js @@ -0,0 +1,19 @@ +export default { + props: { + infos: Array, + }, + template: ` +
+ +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung.js b/public/js/components/Studierendenantrag/Leitung.js new file mode 100644 index 000000000..f08da3879 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung.js @@ -0,0 +1,312 @@ +import LeitungHeader from './Leitung/Header.js'; +import LeitungActions from './Leitung/Actions.js'; +import LeitungTable from './Leitung/Table.js'; +import GrundPopup from './Leitung/GrundPopup.js'; +import LvPopup from './Leitung/LvPopup.js'; +import BsAlert from '../Bootstrap/Alert.js'; +import FhcLoader from '../Loader.js'; +import Phrasen from '../../mixins/Phrasen.js'; + +export default { + components: { + LeitungHeader, + LeitungTable, + LeitungActions, + FhcLoader + }, + mixins: [Phrasen], + props: { + stgL: Array, + stgA: Array + }, + data() { + return { + filter: undefined, + selectedData: [], + columns: [] + } + }, + computed: { + stgs(){ + if(!this.stgL || !this.stgA) + return[]; + let undesiredOutput = [...this.stgL, ...this.stgA]; + let desiredOutput = undesiredOutput.reduce( + (accumulator, currentValue)=> + { + accumulator[currentValue.studiengang_kz] = currentValue; + return accumulator; + }, + {} + ); + return Object.values(desiredOutput); + + }, + stgkzL() + { + if (!this.stgL) + return []; + return this.stgL.map(stg => stg.studiengang_kz); + }, + stgkzA() + { + if (!this.stgA) + return []; + return this.stgA.map(stg => stg.studiengang_kz); + } + }, + methods: { + changeFilter(evt) { + this.filter = evt.target.value || undefined; + this.reload(); + }, + reload() { + this.$refs.table.reload(this.filter); + }, + download() { + this.$refs.table.download(); + }, + actionApprove(evt, oks) { + var antraege = evt || [...this.selectedData]; + + if (!oks) { + oks = []; + } + var currentAntrag = antraege.shift(); + if (currentAntrag) { + if (currentAntrag.typ != 'Wiederholung') + { + oks.push(currentAntrag); + this.actionApprove(antraege, oks); + } + else + { + let countAntrage = 0; + LvPopup + .popup(this.p.t('studierendenantrag','title_show_lvs', currentAntrag), { + antragId: currentAntrag.studierendenantrag_id, + footer: true, + dialogClass: 'modal-lg', + countRemaining : antraege.filter(antrag => antrag.typ == 'Wiederholung').length + }) + .then(result => { + if (result[0]) { + oks.push(currentAntrag); + if (result[1]) + while (antraege.length) + oks.push(antraege.pop()); + } else if (result[1]) { + while (antraege.length) { + currentAntrag = antraege.pop(); + if (currentAntrag.typ != 'Wiederholung') + oks.push(currentAntrag); + } + } + this.actionApprove(antraege, oks); + }) + .catch(() => {}); + } + } else { + this.$refs.loader.show(); + axios + .all( + oks.map( + antrag => axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/approve' + antrag.typ, + { + studierendenantrag_id: antrag.studierendenantrag_id + } + ) + ) + ) + .then(this.showValidation) + .catch(this.showError); + } + }, + actionReject(evt, gruende) { + var antraege = evt || this.selectedData; + if(!gruende) + { + gruende = []; + } + var currentAntrag = antraege.pop(); + if(currentAntrag) + GrundPopup.popup(this.p.t('studierendenantrag', 'title_grund', {id: currentAntrag.studierendenantrag_id})).then(result => + { + currentAntrag.grund = result[0]; + gruende.push(currentAntrag); + if(result[1]) + { + while (antraege.length) + { + currentAntrag = antraege.pop(); + currentAntrag.grund = result[0]; + gruende.push(currentAntrag); + } + } + this.actionReject(antraege, gruende); + }) + .catch(() => {}); + else + { + this.$refs.loader.show(); + axios + .all( + gruende.map( + antrag => axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/reject' + antrag.typ, + { + studierendenantrag_id: antrag.studierendenantrag_id, + grund: antrag.grund + } + ) + ) + ) + .then(this.showValidation) + .catch(this.showError); + } + }, + actionReopen(evt) { + var antraege = evt || this.selectedData; + this.$refs.loader.show(); + axios + .all( + antraege.map( + antrag => axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/reopenAntrag/', + { + studierendenantrag_id: antrag.studierendenantrag_id + } + ) + ) + ) + .then(this.showValidation) + .catch(this.showError); + }, + actionObject(evt) { + var antraege = evt || this.selectedData; + this.$refs.loader.show(); + axios + .all( + antraege.map( + antrag => axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/objectAntrag/', + { + studierendenantrag_id: antrag.studierendenantrag_id + } + ) + ) + ) + .then(this.showValidation) + .catch(this.showError); + }, + actionoObjectionDeny(evt, gruende) { + var antraege = evt || this.selectedData; + this.$refs.loader.show(); + axios + .all( + antraege.map( + antrag => axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/objectionDeny/', + { + studierendenantrag_id: antrag.studierendenantrag_id + } + ) + ) + ) + .then(this.showValidation) + .catch(this.showError); + }, + actionObjectionApprove(evt, gruende) { + var antraege = evt || this.selectedData; + this.$refs.loader.show(); + axios + .all( + antraege.map( + antrag => axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/objectionApprove/', + { + studierendenantrag_id: antrag.studierendenantrag_id + } + ) + ) + ) + .then(this.showValidation) + .catch(this.showError); + }, + showValidation(results) { + var errors = results.filter(res => res.data.error); + this.$refs.loader.hide(); + if (errors.length) { + let errorMsg = errors.map( + error => + 'Antrag ' + + JSON.parse(error.config.data).studierendenantrag_id + + '\n' + + Object.values(error.data.retval).join('\n') + ).join('\n'); + + BsAlert.popup(errorMsg, {dialogClass: 'alert alert-danger'}); + } + this.reload(); + }, + showError(error) { + this.$refs.loader.hide(); + let msg = error.response.data; + if (msg.replace(/^\s+/, '').substr(0, 9) == ' + + + + + + + + + + + + ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Actions.js b/public/js/components/Studierendenantrag/Leitung/Actions.js new file mode 100644 index 000000000..71ada5c20 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Actions.js @@ -0,0 +1,87 @@ +import ActionsNew from './Actions/New.js'; +import ActionsColumns from './Actions/Columns.js'; +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + components: { + ActionsNew, + ActionsColumns + }, + mixins: [Phrasen], + props: { + selectedData: Array, + columns: Array, + stgL: Array, + stgA: Array + }, + emits: [ + 'reload', + 'download', + 'action:approve', + 'action:reject', + 'action:reopen' + ], + data() { + return { + currentStudent: '' + } + }, + computed: { + selectedCanBeApproved() { + if (!this.selectedData.length) + return false; + if (!this.selectedData.every(val => this.stgL.includes(val.studiengang_kz))) + return false; + return this.selectedData.filter(row => { + return (row.typ == 'Wiederholung' && row.status == 'Lvszugewiesen') || (row.typ != 'Wiederholung' && (row.status == 'Erstellt' || row.status == 'ErstelltStgl')); + }).length == this.selectedData.length; + }, + selectedCanBeRejected() { + if (!this.selectedData.length) + return false; + if (!this.selectedData.every(val => this.stgL.includes(val.studiengang_kz))) + return false; + return this.selectedData.filter(row => { + return (row.typ == 'Unterbrechung' && row.status == 'Erstellt'); + }).length == this.selectedData.length; + }, + selectedCanBeReopened() { + if (!this.selectedData.length) + return false; + if (!this.selectedData.every(val => this.stgA.includes(val.studiengang_kz))) + return false; + return this.selectedData.filter(row => { + return (row.typ == 'Wiederholung' && row.status == 'Verzichtet'); + }).length == this.selectedData.length; + }, + newUrl() { + return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + this.currentStudent; + } + }, + methods: { + hideModal() { + bootstrap.Modal.getInstance(this.$refs.modal).hide(); + } + }, + template: ` +
+
+ + + {{p.t('table', 'with_selected', {count: selectedData.length})}} + + + +
+
+ + +
+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/Columns.js b/public/js/components/Studierendenantrag/Leitung/Actions/Columns.js new file mode 100644 index 000000000..df2b2a0de --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Actions/Columns.js @@ -0,0 +1,25 @@ +export default { + props: { + columns: Array + }, + methods: { + toggleColumn(col) { + col.visible = !col.visible; + col.original.toggle() + }, + show() { + + } + }, + template: ` + + ` +} \ No newline at end of file diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/New.js b/public/js/components/Studierendenantrag/Leitung/Actions/New.js new file mode 100644 index 000000000..8a98a6aa5 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Actions/New.js @@ -0,0 +1,118 @@ +import BsAlert from '../../../Bootstrap/Alert.js'; +import BsModal from '../../../Bootstrap/Modal.js'; +import Phrasen from '../../../../mixins/Phrasen.js'; + +export default { + components: { + BsModal + }, + mixins: [ + Phrasen + ], + emits: [ + 'reload' + ], + data() { + return { + data: [], + student: '', + stg: '' + } + }, + computed: { + newUrl() { + return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/lehre/Studierendenantrag/abmeldung/' + this.student; + }, + students() { + if (!this.stg) + return []; + if (!this.data[this.stg]) + return []; + return this.data[this.stg].studenten.sort( + (a, b) => a.nachname == b.nachname ? + a.vorname > b.vorname : + a.nachname > b.nachname + ); + }, + hasNoData() { + return !Object.values(this.data).length; + } + }, + methods: { + openForm() { + bootstrap.Modal.getInstance(this.$refs.modal).hide(); + BsModal.popup(Vue.h('iframe', { + src: this.newUrl, + class: 'position-absolute top-0 start-0 w-100 h-100' + }), { + dialogClass: 'modal-fullscreen' + }, this.p.t('studierendenantrag', 'antrag_header')).then(() => { + this.loadSelects(); + this.$emit('reload'); + }); + }, + loadSelects() { + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/' + ).then( + result => { + if (result.data.error) { + BsAlert.popup(result.data.retval, {dialogClass: 'alert alert-danger'}); + } else { + this.data = result.data.retval; + } + return result; + } + ); + } + }, + created() { + return this.loadSelects(); + }, + template: ` +
+ + +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/GrundPopup.js b/public/js/components/Studierendenantrag/Leitung/GrundPopup.js new file mode 100644 index 000000000..d560dfb00 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/GrundPopup.js @@ -0,0 +1,62 @@ + +import BsAlert from '../../Bootstrap/Alert.js'; +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + mixins: [ + BsAlert, + Phrasen + ], + props: { + placeholder: String, + default: String + }, + data: () => ({ + value: '', + result: false, + check: false, + isInvalid: false + }), + methods: { + submit(){ + if(!this.value) { + this.isInvalid = true; + } + else { + this.result = [this.value, this.check]; + this.hide(); + } + return + } + }, + created() { + if (this.default) + this.value = this.default; + }, + popup(msg, options) { + if (typeof options === 'string') + options = { default: options }; + return BsAlert.popup.bind(this)(msg, options); + }, + template: ` + + + + ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Header.js b/public/js/components/Studierendenantrag/Leitung/Header.js new file mode 100644 index 000000000..388a93b7d --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Header.js @@ -0,0 +1,24 @@ +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + mixins: [Phrasen], + props: { + stgs: Array + }, + emits: [ + 'input' + ], + template: ` +
+

{{p.t('studierendenantrag', 'studierendenantraege')}}

+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/LvPopup.js b/public/js/components/Studierendenantrag/Leitung/LvPopup.js new file mode 100644 index 000000000..045e98729 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/LvPopup.js @@ -0,0 +1,142 @@ +import BsAlert from '../../Bootstrap/Alert.js'; +import {CoreFetchCmpt} from "../../Fetch.js"; +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + components: { + CoreFetchCmpt + }, + mixins: [ + BsAlert, + Phrasen + ], + props: { + footer: Boolean, + antragId: Number, + countRemaining: Number + }, + data: () => ({ + lvs: null, + refresh: true, + result: false, + check: false + }), + computed: { + lvzugelassen() { + let zwischen = {}; + for (let k in this.lvs){ + zwischen[k] = this.lvs[k].filter(lv=>lv.antrag_zugelassen); + } + return zwischen; + }, + lvzugelassenLength() { + return Object.values(this.lvzugelassen).reduce((result, current) => result + current.length, 0); + } + }, + methods: { + setlvs(param) { + if(param.error) + { + this.$refs.fetchCompt.error = true; + this.$refs.fetchCompt.errorMessage = param.retval; + } + else + this.lvs = param.retval; + }, + loadlvs() { + if (!this.antragId) + return new Promise(() => {}); + return axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Antrag/Wiederholung/getLvs/' + this.antragId); + }, + submit(result) { + this.result = [result, this.check]; + this.hide(); + } + }, + watch: { + antragId() { + Vue.nextTick(() => { + this.refresh = !this.refresh; + }); + } + }, + popup(msg, options) { + if (typeof options === 'string') + options = { default: options }; + return BsAlert.popup.bind(this)(msg, options); + }, + template: ` + + + + ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Table.js b/public/js/components/Studierendenantrag/Leitung/Table.js new file mode 100644 index 000000000..309678ae1 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Table.js @@ -0,0 +1,388 @@ +import BsModal from '../../Bootstrap/Modal.js'; +import {CoreFetchCmpt} from '../../Fetch.js'; +import LvPopup from './LvPopup.js'; +import Phrasen from '../../../mixins/Phrasen.js'; +import { dateFilter } from '../../../tabulator/filters/Dates.js'; + +export default { + components: { + BsModal, + CoreFetchCmpt, + LvPopup + }, + mixins: [Phrasen], + props: { + selectedData: Array, + columnData: Array, + stgL: Array, + stgA: Array + }, + emits: [ + 'update:columnData', + 'update:selectedData', + 'action:approve', + 'action:reject', + 'action:reopen', + 'action:object', + 'action:objectionDeny', + 'action:objectionApprove' + ], + data() { + return { + ajaxUrl: FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/getAntraege/', + table: null, + lastHistoryClickedId: null, + historyData: [], + lvsData: null + } + }, + methods: { + reload(stg) { + this.table.replaceData(this.ajaxUrl + (stg || '')); + }, + download() { + this.table.download("csv", "data.csv"); + }, + getHistory() { + if (this.lastHistoryClickedId === null) + return null; + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/getHistory/' + + this.lastHistoryClickedId + ).then(res => { + this.historyData = res.data.retval.sort((a, b) => a.insertamum > b.insertamum); + }); + }, + showHistoryGrund(grund) { + this.$refs.modalGrund.$el.addEventListener( + 'hidden.bs.modal', + this.$refs.history.show, + { + once: true + } + ); + this.$refs.modalGrundPre.innerHTML = grund; + }, + showLVs(data) { + this.lvsData = data; + this.$refs.lvList.show(); + } + }, + mounted() { + function dateFormatter (cell) { + let val = cell.getValue(); + if (!val) + return ''; + let date = new Date(val); + return date.toLocaleDateString(); + } + + this.table = new Tabulator(this.$refs.table, { + placeholder:"Keine zu bearbeitenden Datensätze", + movableColumns: true, + maxHeight: '50vh', + layout: "fitDataStretch", // TODO(chris): wont work when changed + ajaxURL: this.ajaxUrl, + persistence: { // NOTE(chris): do not store column titles + sort: true, //persist column sorting + filter: true, //persist filters + headerFilter: true, //persist header filters + group: true, //persist row grouping + page: true, //persist page + columns: ["width", "visible"], //persist columns + }, + persistenceID: 'studierendenantrag_leitung', + columns: [ + { + formatter: 'rowSelection', + titleFormatter: 'rowSelection', + titleFormatterParams: { + rowRange: 'active' + }, + hozAlign: 'center', + headerSort: false + }, + { + field: 'studierendenantrag_id', + title: '#' + }, + { + field: 'bezeichnung', + title: this.p.t('lehre', 'studiengang'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + } + }, + { + field: 'orgform', + title: this.p.t('lehre', 'organisationsform'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + } + }, + { + field: 'typ', + title: this.p.t('studierendenantrag', 'antrag_typ'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + }, + formatter: (cell, formatterParams, onRendered) => { + return this.p.t('studierendenantrag','antrag_typ_' + cell.getValue()); + } + }, + { + field: 'statustyp', + title: this.p.t('studierendenantrag', 'antrag_status'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + } + }, + { + field: 'matrikelnr', + title: this.p.t('person', 'personenkennzeichen'), + headerFilter: 'input' + }, + { + field: 'prestudent_id', + title: this.p.t('lehre', 'prestudent'), + headerFilter: 'input' + }, + { + field: 'name', + title: this.p.t('global', 'name'), + mutator: (value, data) => (data.vorname + ' ' + data.nachname).replace(/^\s*(.*)\s*$/, '$1'), + headerFilter: 'input' + }, + { + field: 'datum', + title: this.p.t('global', 'datum'), + formatter: dateFormatter, + headerFilterFunc: 'dates', + headerFilter: dateFilter + }, + { + field: 'datum_wiedereinstieg', + title: this.p.t('studierendenantrag', 'antrag_datum_wiedereinstieg'), + formatter: dateFormatter, + headerFilterFunc: 'dates', + headerFilter: dateFilter + }, + { + field: 'grund', + title: this.p.t('studierendenantrag', 'antrag_grund'), + formatter: (cell, formatterParams, onRendered) => { + let link = document.createElement('a'), + val = cell.getValue(); + link.href = "#modal-grund"; + link.setAttribute('data-bs-toggle', 'modal'); + link.innerHTML = this.p.t('studierendenantrag', 'antrag_grund'); + link.addEventListener('click', () => { + this.$refs.modalGrundPre.innerHTML = val; + }); + + return val ? link : ''; + } + }, + { + field: 'dms_id', + title: this.p.t('studierendenantrag', 'antrag_dateianhaenge'), + formatter: (cell, formatterParams, onRendered) => { + let val = cell.getValue(); + if (!val) + return ''; + return ' ' + this.p.t('studierendenantrag', 'antrag_anhang') + ''; + } + }, + { + field: 'actions', + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'), + data = cell.getData(); + + container.className = "d-flex gap-2"; + + if((data.typ == 'Abmeldung' || data.typ == 'Unterbrechung') && (data.status == 'Genehmigt')) + { + // NOTE(chris): Download PDF + let button = document.createElement('a'); + button.innerHTML = ''; + button.className = "btn btn-outline-secondary"; + button.target = "_blank"; + button.href = FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'content/pdfExport.php?xml=Antrag' + data.typ + '.xml.php&xsl=Antrag' + data.typ + '&id='+ data.studierendenantrag_id +'&output=pdf'; + container.append(button); + } + if(data.typ == 'Abmeldung' && data.status == 'GenehmigtStgl') + { + // NOTE(chris): Object + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_object'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:object', [cell.getData()])); + container.append(button); + } + + if(data.typ == 'Abmeldung' && data.status == 'Beeinsprucht') + { + // NOTE(chris): Deny Objection + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_objection_deny'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:objectionDeny', [cell.getData()])); + container.append(button); + + // NOTE(chris): Approve Objection + button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_objection_approve'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:objectionApprove', [cell.getData()])); + container.append(button); + } + + if (this.stgA.includes(data.studiengang_kz)) + { + // NOTE(chris): Reopen + if (data.typ == 'Wiederholung' && data.status == 'Verzichtet') { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_reopen'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:reopen', [cell.getData()])); + container.append(button); + } + // NOTE(chris): Lv Zuweisen + if (data.typ == 'Wiederholung' && (data.status == 'Erstellt' || data.status == 'Lvszugewiesen')) { + let button = document.createElement('a'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_lvzuweisen'); + button.className = "btn btn-outline-secondary"; + button.href = FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/lehre/Antrag/Wiederholung/assistenz/' + + cell.getData().studierendenantrag_id + '/frame'; + button.onclick = e => { + e.preventDefault(); + BsModal.popup(Vue.h('iframe', { + src: button.href, + class: 'position-absolute top-0 start-0 w-100 h-100' + }), { + dialogClass: 'modal-fullscreen' + }, this.p.t('studierendenantrag', 'title_lvzuweisen', cell.getData())).then(() => { + this.$emit('reload'); + }); + }; + container.append(button); + } + } + + if (this.stgL.includes(data.studiengang_kz)) + { + // NOTE(chris): Approve + if ((data.typ == 'Wiederholung' && data.status == 'Lvszugewiesen') || (data.typ != 'Wiederholung' && (data.status == 'Erstellt' || data.status == 'ErstelltStgl'))) { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_approve'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click', () => this.$emit('action:approve', [cell.getData()])); + container.append(button); + } + // NOTE(chris): Reject (Unterbrechung braucht grund) + if (data.status == 'Erstellt' && data.typ == 'Unterbrechung') { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_reject'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click', () => this.$emit('action:reject', [cell.getData()])); + container.append(button); + } + } + + // NOTE(chris): Show LVs + if (data.typ == 'Wiederholung' && (data.status == 'Lvszugewiesen' || data.status == 'Genehmigt')) { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_show_lvs'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click', () => this.showLVs(cell.getData())); + container.append(button); + } + + // TODO(chris): not yet perfect + onRendered(() => { + cell.getColumn().setWidth(true); + }); + + return container; + } + } + ] + }); + this.table.on("tableBuilt", () => { + let columns = this.table.getColumns(); + let columnData = []; + for (let col of columns) { + let def = col.getDefinition(); + if (def.title) { + columnData.push({ + title: def.title, + visible: col.isVisible(), + original: col + }); + } + } + this.$emit('update:columnData', columnData); + }); + this.table.on("rowSelectionChanged", data => { + this.$emit('update:selectedData', data); + }); + this.table.on("cellClick", (e, cell) => { + if (cell.getColumn().getField() == 'statustyp') { + this.lastHistoryClickedId = cell.getData().studierendenantrag_id; + this.$refs.historyLoader.fetchData(); + this.$refs.history.show(); + } + }); + }, + template: ` +
+
+ + +

+		
+ + + + + + + + + + +
{{(new Date(status.insertamum)).toLocaleString()}}{{status.insertvon}}{{status.typ}} + + {{p.t('studierendenantrag', 'antrag_grund')}} + +
+
+
+ + {{p.t('studierendenantrag', 'title_show_lvs', lvsData ? lvsData : {name: ''}) }} + +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Lvzuweisung.js b/public/js/components/Studierendenantrag/Lvzuweisung.js new file mode 100644 index 000000000..cbc97b79e --- /dev/null +++ b/public/js/components/Studierendenantrag/Lvzuweisung.js @@ -0,0 +1,242 @@ +import StudierendenantragStatus from './Status.js'; +import Phrasen from '../../mixins/Phrasen.js'; + +export default { + components: { + StudierendenantragStatus + }, + mixins: [Phrasen], + props: { + antragId: Number, + initialStatusCode: String, + initialStatusMsg: String, + disabled: Boolean + }, + data() { + return { + lvs: [], + isloading: false, + statusCode: '', + statusMsg: '' + } + }, + computed: { + lvs1() { + return this.lvs[Object.keys(this.lvs).filter(key => key.substr(0, 1) == 1)] || []; + }, + lvs2() { + return this.lvs[Object.keys(this.lvs).filter(key => key.substr(0, 1) == 2)] || []; + }, + lvs1sem(){ + return (Object.keys(this.lvs).filter(key => key.substr(0, 1) == 1).pop() || "1").substr(1); + }, + lvs2sem(){ + return (Object.keys(this.lvs).filter(key => key.substr(0, 1) == 2).pop() || "2").substr(1); + }, + statusSeverity() { + switch (this.statusCode) { + case 0: return 'danger'; + default: return 'info'; + } + } + }, + methods: { + save() { + this.isloading = true; + const forbiddenLvs = this.lvs1.filter(lv => lv.antrag_zugelassen && !lv._children).map(lv => ({ + studierendenantrag_id: this.antragId, + lehrveranstaltung_id: lv.lehrveranstaltung_id, + zugelassen: 0, + anmerkung: lv.antrag_anmerkung || "", + studiensemester_kurzbz: this.lvs1sem + })); + const mandatoryLvs = this.lvs2.filter(lv => !lv._children).map(lv => ({ + studierendenantrag_id: this.antragId, + lehrveranstaltung_id: lv.lehrveranstaltung_id, + zugelassen:lv.antrag_zugelassen ? 1 : 2, + anmerkung: lv.antrag_anmerkung || "", + studiensemester_kurzbz: this.lvs2sem + })); + axios.post(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Antrag/Wiederholung/saveLvs/', {forbiddenLvs, mandatoryLvs}) + .then(response => { + if(!response.data.error) { + this.addAlert('Speichern erfolgreich', 'alert-success'); + this.statusCode = response.data.retval[0].studierendenantrag_statustyp_kurzbz; + this.statusMsg = response.data.retval[0].typ; + } else { + this.addAlert(response.data.retval, 'alert-danger'); + this.statusCode = 0; + this.statusMsg = 'Error'; + } + this.isloading = false; + }).catch(error => { + this.addAlert(error.message, 'alert-danger'); + this.statusCode = 0; + this.statusMsg = 'Error'; + this.isloading = false; + }).finally(() => { + window.scrollTo(0, 0); + }); + }, + addAlert(text, type) { + const para = document.createElement("p"); + para.innerText = text; + para.className = "alert " + type + " alert-dismissible fade show"; + const btn = document.createElement("button"); + btn.className = "btn-close"; + btn.type = "button"; + btn.setAttribute("aria-label", "Close"); + btn.setAttribute("data-bs-dismiss", "alert"); + para.appendChild(btn); + + this.$refs.alertbox.appendChild(para); + } + }, + created() { + this.statusCode = this.initialStatusCode; + this.statusMsg = this.initialStatusMsg; + }, + mounted() { + axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Antrag/Wiederholung/getLvs/' + this.antragId).then( + result => { + if(result.data.error) + { + this.addAlert(result.data.retval, 'alert-danger'); + this.isloading = true; + } + else + { + let res = {}; + for (var k in result.data.retval) { + let lvs = result.data.retval[k].reduce((obj,lv) => { + obj[lv.studienplan_lehrveranstaltung_id] = lv; + return obj; + }, {}); + for (var lv of Object.values(lvs)) { + if (!lv.studienplan_lehrveranstaltung_id_parent) + continue; + if (!lvs[lv.studienplan_lehrveranstaltung_id_parent]) + console.error('parent not available'); + else { + if (!lvs[lv.studienplan_lehrveranstaltung_id_parent]._children) + lvs[lv.studienplan_lehrveranstaltung_id_parent]._children = []; + lvs[lv.studienplan_lehrveranstaltung_id_parent]._children.push(lv); + } + } + res[k] = Object.values(lvs).filter(lv => !lv.studienplan_lehrveranstaltung_id_parent); + let current = res[k]; + let index = k.substr(0,1); + var table = new Tabulator(this.$refs["lvtable" + k.substr(0,1)], { + data: current, + dataTree: true, + dataTreeStartExpanded:true, //start with an expanded tree + dataTreeChildIndent:15, + columns: [ + {title: this.p.t('ui','bezeichnung'), field: "bezeichnung"}, + {title: this.p.t('lehre','lehrform'), field: "lehrform_kurzbz"}, + {title: "ECTS", field: "ects"}, + {title: this.p.t('lehre','note'), field: "note", formatter:(cell, formatterParams, onRendered)=>cell.getValue() || "---"}, + {title: (index==1) ? this.p.t('studierendenantrag','lv_nicht_zulassen') : this.p.t('studierendenantrag','lv_wiederholen'), field: "antrag_zugelassen", formatter: (cell, formatterParams, onRendered) => { + let data = cell.getData(); + if(data._children || !data.zeugnis) + return ""; + let input = document.createElement('input'); + input.className = "form-check-input"; + input.type = "checkbox"; + input.role = "switch"; + input.checked = cell.getValue(); + input.addEventListener('input', () => { + lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.checked; + cell.getRow().reformat(); + }); + if (this.disabled) { + input.disabled = true; + } + + let div = document.createElement('div'); + div.className = 'form-check form-switch'; + div.append(input); + + return div; + }}, + { + title: this.p.t('global','anmerkung'), + field: "antrag_anmerkung", + headerSort:false, + titleFormatter:(cell, formatterParams, onRendered)=>{ + let link = document.createElement('a'); + link.addEventListener('click', (e) => { + e.preventDefault(); + }); + + link.href ="#"; + link.title = this.p.t('studierendenantrag','anmerkung_tooltip'); + new bootstrap.Tooltip(link); + let tooltip = document.createElement('span'); + tooltip.innerHTML = this.p.t('global','anmerkung') + " "; + tooltip.append(link); + + let icon = document.createElement('i'); + link.append(icon); + icon.className = "fa fa-info-circle"; + icon.setAttribute("aria-hidden", "true"); + icon.style.minWidth = '1em'; + + return tooltip; + + }, + formatter: (cell, formatterParams, onRendered) => { + if (this.disabled) { + return cell.getValue() || ""; + } + var data = cell.getData(); + if (lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen) + { + let input = document.createElement('input'); + input.className = "form-control"; + input.type = "text"; + input.value = cell.getValue() || ""; + input.addEventListener('input', () => { + lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.value; + }); + return input; + } + else + { + return ""; + } + } + } + ] + }); + } + this.lvs = result.data.retval; + } + } + ); + }, + template: ` +
+
+ + + {{p.t('studierendenantrag', 'title_lv_nicht_zugelassen')}} + {{lvs1sem}} + +
+
+ + + {{p.t('studierendenantrag', 'title_lv_wiederholen')}} + {{lvs2sem}} + +
+
+ + +
+
+ +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Status.js b/public/js/components/Studierendenantrag/Status.js new file mode 100644 index 000000000..7449fd376 --- /dev/null +++ b/public/js/components/Studierendenantrag/Status.js @@ -0,0 +1,15 @@ +export default { + props: { + msg: String, + severity: String + }, + computed: { + severityClass() { + return 'alert-' + this.severity; + } + }, + template: ` + + ` +} diff --git a/public/js/components/vueDatepicker.js.php b/public/js/components/vueDatepicker.js.php new file mode 100644 index 000000000..e0814ac53 --- /dev/null +++ b/public/js/components/vueDatepicker.js.php @@ -0,0 +1,12 @@ + e.category == category).reduce((res, elem) => { + if (!res[elem.phrase]) + res[elem.phrase] = elem.text; + return res; + }, {}); +} +function reloadRefs(category) { + while (loadingModules[category].length) { + var v = loadingModules[category].pop(); + v[0].value = getValueForLoadedPhrase(category, v[1], v[2]); + Vue.triggerRef(v[0]); + /*Vue.unref(v);*/ + } +} +function loadLazy(category, val, phrase, params) { + // NOTE(chris): load module if it's not loaded yet + if (loadingModules[category]) { + loadingModules[category].push([val, phrase, params]); + if (categories[category]) // NOTE(chris): this is for safety in case the loading finished the moment before the val was pushed into the array + reloadRefs(category); + return; + } + loadingModules[category] = [[val, phrase, params]]; + + axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Phrasen/loadModule/' + category).then(res => { + if (res.data.retval) + categories[category] = extractCategory(res.data.retval, category); + else + categories[category] = {}; + + reloadRefs(category); + }).catch(err => console.error(err)); +} +function getValueForLoadedPhrase(category, phrase, params) { + let result = categories[category][phrase]; + if (!result) + return '<< PHRASE ' + phrase + '>>'; + if (params) + result = result.replace(/\{([^}]*)\}/g, (match, p1) => params[p1] === undefined ? match : params[p1]); + return result; +} + +const phrasen = { + t_ref(category, phrase, params) { + if (params === undefined && ( + (Array.isArray(category) && category.length == 2) || + (category.split && category.split('/').length == 2)) + ) { + params = phrase; + [category, phrase] = category.split ? category.split('/') : category; + } + if (phrase === undefined) { + console.error('invalid input'); + return ''; + } + if (!categories[category]) { + if (window.FHC_JS_PHRASES_STORAGE_OBJECT !== undefined) + categories[category] = extractCategory(FHC_JS_PHRASES_STORAGE_OBJECT, category); + + if (!categories[category] || Object.keys(categories[category]).length === 0) { + categories[category] = undefined; + let val = Vue.ref(''); + loadLazy(category, val, phrase, params); + return val; + } + } + var result = getValueForLoadedPhrase(category, phrase, params); + return Vue.ref(result); + }, + t(category, phrase, params) { + return Vue.unref(this.t_ref(category, phrase, params)); + } +}; + +export default { + data: () => { + return { + p: phrasen + } + } +} diff --git a/public/js/tabulator/filters/Dates.js b/public/js/tabulator/filters/Dates.js new file mode 100644 index 000000000..7c9f268f0 --- /dev/null +++ b/public/js/tabulator/filters/Dates.js @@ -0,0 +1,43 @@ +if (!primevue) { + console.error('PrimeVue not loaded!'); +} + +// NOTE(chris): Click on clear button gives an error. This is a bug in primevue => fixed in current version +Tabulator.extendModule('filter', 'filters', { + "dates": (headerValue, rowValue) => { + if (!headerValue) + return true; + let v = new Date(rowValue); + if (Array.isArray(headerValue)) { + if (headerValue[1]) { + return v >= headerValue[0] && v <= headerValue[1].setHours(23, 59, 59, 999); + } + return v.toDateString() == headerValue[0].toDateString(); + } + return v.toDateString() == headerValue.toDateString(); + } +}); +function dateFilter(cell, onRendered, success) { + let div = document.createElement('div'); + + Vue.createApp({ + components: { + PrimevueCalendar: primevue.calendar + }, + data() { + return { + val: null + } + }, + watch: { + val(n) { + success(n); + } + }, + template: `` + }).use(primevue.config.default).mount(div); + + return div; +} + +export { dateFilter as 'dateFilter' }; diff --git a/rdf/AntragAbmeldung.xml.php b/rdf/AntragAbmeldung.xml.php new file mode 100644 index 000000000..b89fa51df --- /dev/null +++ b/rdf/AntragAbmeldung.xml.php @@ -0,0 +1,68 @@ +db_add_param($id) . " + AND campus.tbl_studierendenantrag.typ = 'Abmeldung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found'. $id; + } elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) { + $uid = $_GET['uid']; + $uid = explode(';', $uid); + $uid = (array_filter($uid, 'strlen')); + + $prestudent_id = $_GET['prestudent_id']; + $prestudent_id = explode(';', $prestudent_id); + $prestudent_id = (array_filter($prestudent_id, 'strlen')); + + $where = " WHERE campus.tbl_studierendenantrag.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ") + AND campus.tbl_studierendenantrag.typ = 'Abmeldung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid); + } else + die('wrong parameters'); +} +else + die('Format not supported'); + + +// TODO(chris): mehrsprachig +$query = " + SELECT tbl_studiengang.bezeichnung, bezeichnung_mehrsprachig[1], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, vorname, nachname, studiengang_kz, semester, tbl_studierendenantrag.grund + FROM + campus.tbl_studierendenantrag + JOIN public.tbl_student USING (prestudent_id) + JOIN public.tbl_benutzer ON tbl_student.student_uid=uid + JOIN public.tbl_person USING (person_id) + JOIN public.tbl_studiengang USING (studiengang_kz) + JOIN public.tbl_studiensemester USING (studiensemester_kurzbz) + JOIN bis.tbl_orgform ON (tbl_orgform.orgform_kurzbz = tbl_studiengang.orgform_kurzbz)" . $where; + + +if (!$db->db_query($query) || !$db->db_num_rows()) + die('' . $not_found_error . ''); + +?> + + + db_fetch_object()) { ?> + + bezeichnung;?> + bezeichnung_mehrsprachig;?> + vorname. " " . $row->nachname);?> + matrikelnr;?> + studienjahr_kurzbz;?> + semester;?> + grund;?> + + + diff --git a/rdf/AntragUnterbrechung.xml.php b/rdf/AntragUnterbrechung.xml.php new file mode 100644 index 000000000..50c9f4c6a --- /dev/null +++ b/rdf/AntragUnterbrechung.xml.php @@ -0,0 +1,71 @@ +db_add_param($id) . " + AND campus.tbl_studierendenantrag.typ = 'Unterbrechung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found'. $id; + } elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) { + $uid = $_GET['uid']; + $uid = explode(';', $uid); + $uid = (array_filter($uid, 'strlen')); + + $prestudent_id = $_GET['prestudent_id']; + $prestudent_id = explode(';', $prestudent_id); + $prestudent_id = (array_filter($prestudent_id, 'strlen')); + + $where = " WHERE campus.tbl_studierendenantrag.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ") + AND campus.tbl_studierendenantrag.typ = 'Unterbrechung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid); + } else + die('wrong parameters'); +} +else + die('Format not supported'); + + +// TODO(chris): mehrsprachig +$query = " + SELECT tbl_studiengang.bezeichnung, bezeichnung_mehrsprachig[1], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, vorname, nachname, studiengang_kz, semester, tbl_studierendenantrag.grund, datum_wiedereinstieg, datum + FROM + campus.tbl_studierendenantrag + JOIN public.tbl_student USING (prestudent_id) + JOIN public.tbl_benutzer ON tbl_student.student_uid=uid + JOIN public.tbl_person USING (person_id) + JOIN public.tbl_studiengang USING (studiengang_kz) + JOIN public.tbl_studiensemester USING (studiensemester_kurzbz) + JOIN bis.tbl_orgform ON (tbl_orgform.orgform_kurzbz = tbl_studiengang.orgform_kurzbz)" . $where; + + +if (!$db->db_query($query) || !$db->db_num_rows()) + die('' . $not_found_error . ''); + +?> + + + db_fetch_object()) { ?> + + bezeichnung;?> + bezeichnung_mehrsprachig;?> + vorname. " " . $row->nachname);?> + matrikelnr;?> + studienjahr_kurzbz;?> + semester;?> + grund;?> + datum_wiedereinstieg))->format('d.m.Y');?> + datum))->format('d.m.Y');?> + + + diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 9fda09bba..013972154 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -39,6 +39,7 @@ require_once('dbupdate_3.4/27107_vilesci_erfassung_abwesenheiten_reinigung.php') require_once('dbupdate_3.4/24913_tabelle_raumtyp_neues_attribut_aktiv.php'); require_once('dbupdate_3.4/28089_plausichecks_in_extension_hinzufuegen.php'); require_once('dbupdate_3.4/29133_einzelne_studiengaenge_aus_issuechecks_ausnehmen.php'); +require_once('dbupdate_3.4/27351_digitalisierung_formulare.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/27351_digitalisierung_formulare.php b/system/dbupdate_3.4/27351_digitalisierung_formulare.php new file mode 100644 index 000000000..a40b457e2 --- /dev/null +++ b/system/dbupdate_3.4/27351_digitalisierung_formulare.php @@ -0,0 +1,289 @@ +db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag_statustyp ( + studierendenantrag_statustyp_kurzbz VARCHAR(32) NOT NULL, + bezeichnung VARCHAR(128)[] NOT NULL, + CONSTRAINT tbl_studierendenantrag_statustyp_pk PRIMARY KEY(studierendenantrag_statustyp_kurzbz) + ); + + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_statustyp TO vilesci; + GRANT SELECT ON campus.tbl_studierendenantrag_statustyp TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_statustyp: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_statustyp: table created'; +} + +if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp WHERE studierendenantrag_statustyp_kurzbz = 'Erstellt' ")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO campus.tbl_studierendenantrag_statustyp + (studierendenantrag_statustyp_kurzbz, bezeichnung) + VALUES + ('Erstellt', '{\"Erstellt\",\"Created\"}'), + ('ErstelltStgl', '{\"Erstellt\",\"Created\"}'), + ('Genehmigt', '{\"Genehmigt\",\"Approved\"}'), + ('GenehmigtStgl', '{\"Vorläufig Genehmigt\",\"Provisionally Approved\"}'), + ('Beeinsprucht', '{\"Beeinsprucht\",\"Objected\"}'), + ('Abgelehnt', '{\"Abgelehnt\",\"Rejected\"}'), + ('Verzichtet', '{\"Verzichtet\",\"Pass\"}'), + ('Offen', '{\"Offen\",\"Reopened\"}'), + ('Zurückgezogen', '{\"Zurückgezogen\",\"Cancelled\"}'), + ('EmailVersandt', '{\"Email Versandt\",\"Reminder Sent\"}'), + ('ErsteAufforderungVersandt', '{\"1.Aufforderung Versandt\",\"1st Request Sent\"}'), + ('ZweiteAufforderungVersandt', '{\"2.Aufforderung Versandt\",\"2nd Request Sent\"}'), + ('Lvszugewiesen', '{\"Lvszugewiesen\",\"Lvsassigned\"}'); + "; + if (!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_statustyp (insert): '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_statustyp: table prefilled'; + } +} + +if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag ( + studierendenantrag_id INTEGER NOT NULL, + prestudent_id INTEGER NOT NULL, + studiensemester_kurzbz VARCHAR(32) NOT NULL, + datum TIMESTAMP NULL, + typ VARCHAR(32) NOT NULL, + insertamum TIMESTAMP DEFAULT NOW(), + insertvon VARCHAR(32) NOT NULL, + datum_wiedereinstieg TIMESTAMP NULL, + grund TEXT NULL, + dms_id INTEGER NULL, + CONSTRAINT tbl_studierendenantrag_pk PRIMARY KEY(studierendenantrag_id) + ); + CREATE SEQUENCE campus.tbl_studierendenantrag_studierendenantrag_id_seq + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + ALTER TABLE campus.tbl_studierendenantrag ALTER COLUMN studierendenantrag_id SET DEFAULT nextval('campus.tbl_studierendenantrag_studierendenantrag_id_seq'); + + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO vilesci; + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO web; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_studierendenantrag_id_seq TO vilesci; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_studierendenantrag_id_seq TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag: table created'; +} + +if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag_status ( + studierendenantrag_status_id INTEGER NOT NULL, + studierendenantrag_id INTEGER NOT NULL, + studierendenantrag_statustyp_kurzbz VARCHAR(32) NOT NULL, + insertamum TIMESTAMP DEFAULT NOW(), + insertvon VARCHAR(32) NOT NULL, + grund TEXT NULL, + CONSTRAINT tbl_studierendenantrag_status_pk PRIMARY KEY(studierendenantrag_status_id), + CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT tbl_studierendenantrag_statustyp_fk FOREIGN KEY (studierendenantrag_statustyp_kurzbz) REFERENCES campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT + ); + CREATE SEQUENCE campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + ALTER TABLE campus.tbl_studierendenantrag_status ALTER COLUMN studierendenantrag_status_id SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq'); + + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO vilesci; + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO web; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO vilesci; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_status: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_status: table created'; +} + +if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_lehrveranstaltung LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag_lehrveranstaltung ( + studierendenantrag_lehrveranstaltung_id INTEGER NOT NULL, + studierendenantrag_id INTEGER NOT NULL, + lehrveranstaltung_id INTEGER NOT NULL, + studiensemester_kurzbz VARCHAR(16) NOT NULL, + note SMALLINT NOT NULL, + anmerkung TEXT NULL, + insertamum TIMESTAMP DEFAULT NOW(), + insertvon VARCHAR(32) NOT NULL, + CONSTRAINT tbl_studierendenantrag_lehrveranstaltung_pk PRIMARY KEY(studierendenantrag_lehrveranstaltung_id), + CONSTRAINT tbl_studiensemester_fk FOREIGN KEY (studiensemester_kurzbz) REFERENCES public.tbl_studiensemester(studiensemester_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT tbl_note_fk FOREIGN KEY (note) REFERENCES lehre.tbl_note(note) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT + ); + CREATE SEQUENCE campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + ALTER TABLE campus.tbl_studierendenantrag_lehrveranstaltung ALTER COLUMN studierendenantrag_lehrveranstaltung_id SET DEFAULT nextval('campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq'); + + GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_lehrveranstaltung TO vilesci; + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_lehrveranstaltung TO web; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq TO vilesci; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_lehrveranstaltung: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_lehrveranstaltung: table created'; +} + +if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'student/studierendenantrag';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/studierendenantrag', 'Berechtigung für Bearbeiten Studierendenanträge');"; + + if(!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo ' system.tbl_berechtigung: Added permission for student/studierendenantrag
'; + } +} + +if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'student/antragfreigabe';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/antragfreigabe', 'Berechtigung für Freigabe der Studierendenanträge');"; + + if(!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo ' system.tbl_berechtigung: Added permission for student/antragfreigabe
'; + } +} + +if (!$result = @$db->db_query("SELECT campus.get_status_studierendenantrag(0)")) { + $qry = 'CREATE FUNCTION campus.get_status_studierendenantrag(integer) RETURNS character varying + LANGUAGE plpgsql + AS $_$ + DECLARE i_studierendenantrag_id ALIAS FOR $1; + DECLARE rec RECORD; + BEGIN + SELECT INTO rec studierendenantrag_statustyp_kurzbz + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_id=i_studierendenantrag_id + ORDER BY insertamum desc + LIMIT 1; + + RETURN rec.studierendenantrag_statustyp_kurzbz; + END; + $_$; + + ALTER FUNCTION campus.get_status_studierendenantrag(integer) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'campus.get_status_studierendenantrag(integer): '.$db->db_last_error().'
'; + else + echo '
campus.get_status_studierendenantrag(integer): function created'; +} + +if (!$result = @$db->db_query("SELECT campus.get_status_id_studierendenantrag(0)")) { + $qry = 'CREATE FUNCTION campus.get_status_id_studierendenantrag(integer) RETURNS integer + LANGUAGE plpgsql + AS $_$ + DECLARE i_studierendenantrag_id ALIAS FOR $1; + DECLARE rec RECORD; + BEGIN + SELECT INTO rec studierendenantrag_status_id + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_id=i_studierendenantrag_id + ORDER BY insertamum desc + LIMIT 1; + + RETURN rec.studierendenantrag_status_id; + END; + $_$; + + ALTER FUNCTION campus.get_status_id_studierendenantrag(integer) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'campus.get_status_id_studierendenantrag(integer): '.$db->db_last_error().'
'; + else + echo '
campus.get_status_id_studierendenantrag(integer): function created'; +} + +if (!$result = @$db->db_query("SELECT public.get_absem_prestudent(0, null)")) { + $qry = 'CREATE FUNCTION public.get_absem_prestudent(integer, character varying) RETURNS integer + LANGUAGE plpgsql + AS $_$ + DECLARE i_prestudent_id ALIAS FOR $1; + DECLARE cv_studiensemester_kurzbz ALIAS FOR $2; + DECLARE rec RECORD; + BEGIN + IF (cv_studiensemester_kurzbz IS NULL) THEN + SELECT INTO rec ausbildungssemester + FROM public.tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + ELSE + SELECT INTO rec ausbildungssemester + FROM tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id AND studiensemester_kurzbz=cv_studiensemester_kurzbz + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + END IF; + + RETURN rec.ausbildungssemester; + END; + $_$; + + ALTER FUNCTION public.get_absem_prestudent(integer, character varying) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'public.get_absem_prestudent(integer, character varying): '.$db->db_last_error().'
'; + else + echo '
public.get_absem_prestudent(integer, character varying): function created'; +} +if (!$result = @$db->db_query("SELECT public.get_stdsem_prestudent(0, null)")) { + $qry = 'CREATE FUNCTION public.get_stdsem_prestudent(integer, character varying) RETURNS character varying + LANGUAGE plpgsql + AS $_$ + DECLARE i_prestudent_id ALIAS FOR $1; + DECLARE cv_studiensemester_kurzbz ALIAS FOR $2; + DECLARE rec RECORD; + BEGIN + IF (cv_studiensemester_kurzbz IS NULL) THEN + SELECT INTO rec studiensemester_kurzbz + FROM public.tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + ELSE + SELECT INTO rec studiensemester_kurzbz + FROM tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id AND studiensemester_kurzbz=cv_studiensemester_kurzbz + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + END IF; + + RETURN rec.studiensemester_kurzbz; + END; + $_$; + + ALTER FUNCTION public.get_stdsem_prestudent(integer, character varying) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'public.get_stdsem_prestudent(integer, character varying): '.$db->db_last_error().'
'; + else + echo '
public.get_stdsem_prestudent(integer, character varying): function created'; +} diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 0bc748c80..f6df3afad 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -5774,6 +5774,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'error_invalid_date', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Das Datumsformat ist ungültig oder liegt außerhalb des gültigen Bereichs.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The date format is invalid or out of range.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'ui', @@ -14446,6 +14466,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'schliessen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Schließen", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Close", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'global', @@ -18123,6 +18163,1750 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_0', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gemäß § 16 Abs. 1 FHG steht Studierenden einmalig das Recht auf Wiederholung eines Studienjahres in Folge einer negativ beurteilten kommissionellen Prüfung zu.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'According to § 16 paragraph 1 FHG, students have the right to repeat an academic year as a result of a negative examination before a committee.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_1', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Die Wiederholung ist bei der Studiengangsleitung binnen eines Monats ab Mitteilung des negativen Prüfungsergebnisses bekannt zu geben.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The head of the degree program must be notified of the repetition within one month of notification of the negative examination result.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_2', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Infolge der Weiterentwicklung der Qualität des Studienganges kann es zu Änderungen der Studienbedingungen im Zuge der Wiederholung eines Studienjahres kommen (z.B. Studienplan, Prüfungsordnung etc.).', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'As a result of the further development of the quality of the course, there may be changes to the study conditions in the course of repeating an academic year (e.g. study plan, examination regulations, etc.).', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_3', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Die Studiengangsleitung legt Prüfungen und Lehrveranstaltungen für die Wiederholung des Studienjahres fest.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The head of the degree program determines examinations and courses for the repetition of the academic year.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_4', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nicht bestandene Prüfungen und Lehrveranstaltungen sind jedenfalls, bestandene Prüfungen und Lehrveranstaltungen nur, sofern es der Zweck des Studiums erforderlich macht, zu wiederholen oder erneut zu besuchen. Wird eine Lehrveranstaltung nach der letzten Wiederholungsmöglichkeit negativ beurteilt, darf dieder Studierende an keiner kommissionellen Wiederholungsprüfung im Semester der negativ beurteilen Lehrveranstaltung und im Folgesemester mehr teilnehmen (nicht-kommissionelle Wiederholungsprüfungen können wahrgenommen werden)', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'In any case, failed examinations and courses are to be repeated or attended again only if the purpose of the course makes it necessary. If a course is assessed negatively after the last opportunity to repeat it, the student may no longer take part in a board re-examination in the semester in which the course was assessed as negative and in the following semester (non-board re-examinations can be taken).', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'info_Wiederholung_Erstellt', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Info für Wiederholung Erstellt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Info for Wiederholung Erstellt', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_pruefung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Negativ beurteilte kommissionelle Prüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Negative assessment by a committee', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_pruefung_date', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Datum der Beurteilung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'date of assessment', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_button_yes', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ich gebe hiermit die Wiederholung des Studienjahres bekannt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'I hereby announce the repetition of the academic year', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_button_no', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ich werde das Studienjahr nicht wiederholen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'I will not repeat the academic year', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antraege_header', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anträge auf Änderung des Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Requests for changing the Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_header', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag auf Änderung des Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Request for changing the Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_new', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Neu Anlegen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Create new', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'cancel', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abbrechen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancel', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'ok', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ok', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Ok', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_create', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anlegen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Create', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_create_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vom Studium abmelden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Deregister from your studies', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_create_Unterbrechung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Das Studium unterbrechen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Interrupt your studies', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_cancel', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag zurückziehen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancel Application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'warning_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ihr CIS-Account ist noch 21 Tage aktiv. Wir bitten Sie, alle benötigten Dateien (Zeugnisse, Studienerfolgsbestätigungen, Studienbestätigungen, etc.) innerhalb dieses Zeitraums herunterzuladen. Für die Ausstellung von Duplikaten fallen nach Inaktivsetzung des CIS-Accounts Kosten an.' . "
\n" . + 'Bitte retournieren Sie baldmöglichst entlehnte Bücher an die Bibliothek.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Your CIS account is still active for 21 days. We ask you to download all required files (certificates, confirmations of academic success, confirmation of studies, etc.) within this period. There is a charge for issuing duplicates after the CIS account has been deactivated.' . "
\n" . + 'Please return borrowed books to the library as soon as possible.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abmeldung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'De-registration', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_Unterbrechung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Unterbrechung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Interruption', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_Wiederholung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wiederholung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Repetition', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_new_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Neue Abmeldung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'New de-registration', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Typ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Type', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_status', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Status', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_studiensemester', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studiensemester', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Semester', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_erstelldatum', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Erstelldatum', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Createdate', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'studierendenantraege', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studierendenanträge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Applications', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_datum_wiedereinstieg', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Datum Wiedereinstieg', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Date of return', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_grund', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Grund', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reason', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_dateianhaenge', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Dateianhänge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Attachments', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_anhang', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anhang', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Attachment', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abmeldung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Deregistration', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ_Unterbrechung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Unterbrechung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Break', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ_Wiederholung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wiederholung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Repetition', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_show_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LVs anzeigen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Show LVs', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_edit', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Bearbeiten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Edit', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_reopen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Erneut Freischalten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reopen', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_object', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Beeinspruchen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Object', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_objection_deny', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Einspruch abgelehnt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Objection rejected', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_objection_approve', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Einspruch stattgegeben', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Objection granted', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_lvzuweisen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LVs zuweisen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assign Lvs', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_approve', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Genehmigen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Approve', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_reject', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ablehnen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reject', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'skip', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Überspringen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Skip', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'select_studiensemester', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studiensemester auswählen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Select a semester', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_save_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zuweisungen speichern', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Save assignments', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_download_antrag', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'PDF herunterladen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Download PDF', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'table', + 'phrase' => 'download', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Download', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Download', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'table', + 'phrase' => 'reload', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Tabelle neu laden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reload table', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_student', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Sie sind derzeit in keinem Studium', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'You are currently not enrolled', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_student_no_failed_exam', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Sie sind derzeit in keinem Studium oder haben keine negativ beurteilte kommissionelle Prüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'You are not currently studying or have not passed a board examination with negative reasons', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'no_attachments', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Dateianhänge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No Attachments', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'prestudent', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prestudent', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Prestudent', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'studienjahr', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studienjahr', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Academic year', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_lvzuweisen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrveranstaltungen zuweisen für {name}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assign Courses for {name}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_lv_nicht_zugelassen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Angabe aller Lehrveranstaltungen, zu denen die Person nicht zugelassen ist', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Details of all courses to which the person is not admitted', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_lv_wiederholen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Angabe aller zu wiederholenden bzw. erneut zu besuchenden Lehrveranstaltungen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Specification of all courses to be repeated or attended again', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_show_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrveranstaltungen für {name}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Courses for {name}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'my_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Meine Lehrveranstaltungen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'My Courses', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'table', + 'phrase' => 'with_selected', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Mit {count} ausgewählten: ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'With {count} selected: ', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'lv_nicht_zulassen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nicht zulassen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Don\'t allow ', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'lv_wiederholen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wiederholen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Repeat', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_history', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Statusverlauf für Antrag #{id} ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'History for Application #{id}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'anmerkung_tooltip', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Die Spalte Anmerkung kann verwendet werden, um Besonderheiten z.B. bei einem Studienplanwechsel zu dokumentieren (Änderung von LV-Titel, ECTS…) ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The Comment column can be used to document special features, e.g. when changing the curriculum (change of course title, ECTS...)', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'fuer_alle_uebernehmen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'für alle übernehmen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'apply for all', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'fuer_x_uebernehmen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Auswahl für {count} weitere(n) Wiederholungsanträge übernehmen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Adopt selection for {count} further repeat applications', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_grund', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Grund für Ablehnung von Antrag #{id}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reason for rejection of Application #{id}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Lehrveranstaltungen zugewiesen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No courses assigned', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_x', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Status: {status}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Status: {status}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_saving', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Daten werden gespeichert...', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Saving...', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_error', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Fehler', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Error', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_open', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Offen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Open', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_created', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Erstellt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Created', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_cancelling', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zurückziehen...', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancelling...', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_cancelled', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zurückgezogen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancelled', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_stg_blacklist', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Für diesen Studiengang sind keine Anträge möglich', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No applications are accepted for this course', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_antrag_exists', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Es gibt bereits einen bestehenden Antrag', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'There is already an existing application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_antrag_pending', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Es gibt bereits einen bestehenden Antrag vom Typ {typ}' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'There is already an existing application of type {typ}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_antrag_found', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kein Antrag mit AntragsId {id} gefunden' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No application found with ApplicationId {id}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_antrag_locked', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Dieser Antrag ist gesperrt' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'This request is locked', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_lv', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Lehrveranstaltung ausgewählt' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No course selected', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_lv_in_application', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Lehrveranstaltung im Antrag gefunden' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No course found in application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_right', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Berechtigung, den Antrag zu bearbeiten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No authorization to edit the application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_objection', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Berechtigung, den Antrag zu beeinspruchen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No authorization to object the application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_not_objected', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag ist nicht beeinsprucht', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Application is not objected', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + ); diff --git a/system/vorlage_zip/AntragAbmeldung.odt b/system/vorlage_zip/AntragAbmeldung.odt new file mode 100644 index 0000000000000000000000000000000000000000..2e11ca60ae49eb67a843672bf6e2c87e5d31517c GIT binary patch literal 37277 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 literal 0 HcmV?d00001 diff --git a/system/vorlage_zip/AntragUnterbrechung.odt b/system/vorlage_zip/AntragUnterbrechung.odt new file mode 100644 index 0000000000000000000000000000000000000000..aeaa82105e7a130979d9a86f82ee5d622b610b7c GIT binary patch literal 34155 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

VY%NO_G+4oZkl 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Studiengang: + + + + + + Organisationsform: + + + + + + + + Abmeldung vom Studium durch Studierende + + + + + + + Name der*des Studierenden + + + + + + + + + + + Personenkennzeichen + + + + + + + + + + Studienjahr + + + + + + + + + + Semester + + + + + + + + + + Grund der Abmeldung: + + + + + + + + + + + + + + + Wir weisen Sie darauf hin, dass Ihr FHTW Account noch 21 Tage aktiv ist. Wir bitten Sie, alle benötigte Dateien (Zeugnisse, Studienerfolgsbestätigungen, Studienbestätigungen, etc.) innerhalb dieses Zeitraums herunterzuladen. Für die Ausstellung von Duplikaten fallen nach Inaktivsetzung des CIS-Accounts Kosten an. + + + Sie sind gem. Ausbildungsvertrag verpflichtet, unverzüglich alle zur Verfügung gestellten Gerätschaften, Bücher, Schlüssel und sonstige Materialien zurückzugeben. + + Bei Abmeldung vor dem 01.09. bzw. 15.02. und bereits eingezahltem Studienbeitrag für das kommende Semester: Wir informieren Sie darüber, dass der Studienbeitrag für das kommende Semester von Ihnen zurückgefordert werden kann. Bitte geben Sie uns dafür innerhalb von 14 Tagen Ihre Bankdaten an folgende E-Mail-Adresse bekannt: billing@technikum-wien.at. + + + + + + + + \ No newline at end of file diff --git a/system/xsl/AntragUnterbrechung.xsl b/system/xsl/AntragUnterbrechung.xsl new file mode 100644 index 000000000..f1ab10d91 --- /dev/null +++ b/system/xsl/AntragUnterbrechung.xsl @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Studiengang: + + + + + + + + Organisationsform: + + + + + + + + + Antrag auf Unterbrechung des Studiums + + + + + + + + Name der*des Studierenden + + + + + + + + + + + + + + Personenkennzeichen + + + + + + + + + + + + + + Studienjahr + + + + + + + + + + + + + + Aktuelles Semester + + + + + + + + + + + + Grund der Unterbrechung: + + + + + + + + + + + + + Wiedereinstieg am + + + + + + + + + + + + + + + + + + + + Datum: + + + + + + + + + + + + + + + + Infolge der Weiterentwicklung der Qualität des Studienganges kann es zu Änderungen der Studienbedingungen beim Wiedereinstieg kommen (z. B. Studienplan, Prüfungsordnung etc.) + + + Falls Sie das Studium im Wintersemester vor dem 15.10. bzw. im Sommersemester vor dem 15.3. beenden, wird Ihnen der Studienbeitrag für das aktuelle Semester rückerstattet. Bitte geben Sie uns innerhalb von 14 Tagen Ihre Bankdaten an folgende E-Mail-Adresse bekannt: + + + billing@technikum-wien.at + + + . + + + + + + \ No newline at end of file From b39fa7667e4f36d4db15a95007631bc0bc9c46c5 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 11:09:55 +0200 Subject: [PATCH 037/175] Remove TODO --- application/controllers/components/Antrag/Wiederholung.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/controllers/components/Antrag/Wiederholung.php b/application/controllers/components/Antrag/Wiederholung.php index 7b5d8f887..941d6e51a 100644 --- a/application/controllers/components/Antrag/Wiederholung.php +++ b/application/controllers/components/Antrag/Wiederholung.php @@ -66,7 +66,6 @@ class Wiederholung extends FHC_Controller } $result = $result->retval; if (!$result) { - // TODO(chris): ERROR Message $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); return $this->outputJsonError($this->p->t('studierendenantrag','error_no_student_no_failed_exam')); } From ff93cb26fe07985fcc0b29263c419c7b75b5d759 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 11:10:26 +0200 Subject: [PATCH 038/175] Bug: status --- .../Studierendenantrag/Form/Wiederholung.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/public/js/components/Studierendenantrag/Form/Wiederholung.js b/public/js/components/Studierendenantrag/Form/Wiederholung.js index 4cbc32d88..ff37540bb 100644 --- a/public/js/components/Studierendenantrag/Form/Wiederholung.js +++ b/public/js/components/Studierendenantrag/Form/Wiederholung.js @@ -65,13 +65,15 @@ export default { ).then( result => { this.data = result.data.retval; - if (!this.data.status || this.data.status == 'ErsteAufforderungVersandt' || this.data.status == 'ZweiteAufforderungVersandt') + if (!this.data.status || this.data.status == 'ErsteAufforderungVersandt' || this.data.status == 'ZweiteAufforderungVersandt') { this.data.status = 'Offen'; + this.data.statustyp = this.p.t('studierendenantrag', 'status_open'); + } this.$emit('update:status', this.data.status); this.$emit("setStatus", { - msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), - severity: this.statusSeverity - }); + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); return result; } ); @@ -87,7 +89,7 @@ export default { let nextState = repeat ? 'Erstellt' : 'Verzichtet'; this.$emit('setStatus', { - msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t_ref('studierendenantrag', 'status_saving')}), + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}), severity: 'warning' }); this.saving = true; @@ -114,7 +116,7 @@ export default { this.errors.default.push(result.data.retval[k]); } this.$emit('setStatus', { - msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t_ref('studierendenantrag', 'status_error')}), + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}), severity: 'danger' }); } From 7eed07a68295d8b83db19e915983140282123ddb Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 13:37:54 +0200 Subject: [PATCH 039/175] LV zuweisung & anzeige: handle semester above max_semester & anmerkung bug --- application/libraries/AntragLib.php | 30 ++++++--- .../Studierendenantrag/Leitung/LvPopup.js | 63 ++++++++++--------- .../Studierendenantrag/Lvzuweisung.js | 15 ++++- system/phrasesupdate.php | 20 ++++++ 4 files changed, 87 insertions(+), 41 deletions(-) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index 38504772c..f1a757bc2 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -765,14 +765,16 @@ class AntragLib ); if (isError($result)) return $result; - $lvsA = getData($result) ?: []; - foreach($lvsA as $lv) - { - if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && - ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == $this->_ci->config->item('wiederholung_note_nicht_zugelassen'))) + $lvsA = $result->retval; // NOTE(chris): don't use getData() because we want to differenciate [] and null + if ($lvsA) { + foreach($lvsA as $lv) { - $lv->antrag_zugelassen = true; - $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && + ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == $this->_ci->config->item('wiederholung_note_nicht_zugelassen'))) + { + $lv->antrag_zugelassen = true; + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + } } } @@ -798,7 +800,7 @@ class AntragLib } return success([ - '1' . $semA => $lvsA ?: [], + '1' . $semA => $lvsA, '2' . $semB => $lvsB ?: [] ]); } @@ -822,13 +824,23 @@ class AntragLib if (isError($result)) return $result; $result = getData($result); - if (!$result) + if (!$result) { + $result = $this->_ci->StudiengangModel->load($studiengang_kz); + if (isError($result)) + return $result; + if (!hasData($result)) + return error('No Studiengang found with studiengang_kz: ' . $studiengang_kz); + $stg = current(getData($result)); + + if ($ausbildungssemester > $stg->max_semester) + return success(); return error('No studienplan found for stg: ' . $studiengang_kz . ', studiensemester: ' . $studiensemester_kurzbz . ', ausbildungssemester: ' . ($ausbildungssemester)); + } if (count($result) > 1) return error('Multiple studienplaene found for stg: ' . $studiengang_kz . diff --git a/public/js/components/Studierendenantrag/Leitung/LvPopup.js b/public/js/components/Studierendenantrag/Leitung/LvPopup.js index 045e98729..c3f2aa118 100644 --- a/public/js/components/Studierendenantrag/Leitung/LvPopup.js +++ b/public/js/components/Studierendenantrag/Leitung/LvPopup.js @@ -25,12 +25,12 @@ export default { lvzugelassen() { let zwischen = {}; for (let k in this.lvs){ - zwischen[k] = this.lvs[k].filter(lv=>lv.antrag_zugelassen); + zwischen[k] = this.lvs[k] ? this.lvs[k].filter(lv=>lv.antrag_zugelassen) : null; } return zwischen; }, lvzugelassenLength() { - return Object.values(this.lvzugelassen).reduce((result, current) => result + current.length, 0); + return Object.values(this.lvzugelassen).reduce((result, current) => result + (current ? current.length : 0), 0); } }, methods: { @@ -86,7 +86,7 @@ export default { {{sem.substr(1)}} -

{{p.t('ui','bezeichnung')}} {{p.t('lehre','lehrform')}}
- - -
- {{lv.lehrform_kurzbz}} -
-
-
- {{lv.ects}} -
-
-
- {{lv.note || '---'}} -
-
-
- {{lv.antrag_anmerkung}} -
-
{{p.t('studierendenantrag/error_stg_last_semester')}}
diff --git a/public/js/components/Studierendenantrag/Lvzuweisung.js b/public/js/components/Studierendenantrag/Lvzuweisung.js index cbc97b79e..d987f55be 100644 --- a/public/js/components/Studierendenantrag/Lvzuweisung.js +++ b/public/js/components/Studierendenantrag/Lvzuweisung.js @@ -108,6 +108,14 @@ export default { { let res = {}; for (var k in result.data.retval) { + if (result.data.retval[k] === null) { + const alert = document.createElement('div'); + alert.innerHTML = this.p.t('studierendenantrag', 'error_stg_last_semester'); + alert.className = 'alert alert-warning'; + alert.role = 'alert'; + this.$refs["lvtable" + k.substr(0,1)].append(alert); + continue; + } let lvs = result.data.retval[k].reduce((obj,lv) => { obj[lv.studienplan_lehrveranstaltung_id] = lv; return obj; @@ -129,8 +137,9 @@ export default { var table = new Tabulator(this.$refs["lvtable" + k.substr(0,1)], { data: current, dataTree: true, - dataTreeStartExpanded:true, //start with an expanded tree - dataTreeChildIndent:15, + dataTreeStartExpanded: true, //start with an expanded tree + dataTreeChildIndent: 15, + layout: "fitDataStretch", columns: [ {title: this.p.t('ui','bezeichnung'), field: "bezeichnung"}, {title: this.p.t('lehre','lehrform'), field: "lehrform_kurzbz"}, @@ -197,7 +206,7 @@ export default { input.type = "text"; input.value = cell.getValue() || ""; input.addEventListener('input', () => { - lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.value; + lvs[data.studienplan_lehrveranstaltung_id].antrag_anmerkung = input.value; }); return input; } diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index f6df3afad..562e4e5c2 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -19906,6 +19906,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_stg_last_semester', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Der Studiengang hat nicht genügend Semester', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The course does not have enough semesters', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); From 3ca80904eafa3080bb9615426514db987dd1ced4 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 15:59:43 +0200 Subject: [PATCH 040/175] =?UTF-8?q?Verbesserungen=20Unterbrecher=20best?= =?UTF-8?q?=C3=A4tigen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/libraries/AntragLib.php | 6 ++++++ application/libraries/PrestudentLib.php | 19 +++++++++++++++++-- .../27351_digitalisierung_formulare.php | 4 ++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index f1a757bc2..e3119d65b 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -288,6 +288,7 @@ class AntragLib } else { + $studierendenantrag_status_id = getData($result); $resultAntrag = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); if (isError($resultAntrag)) return $resultAntrag; @@ -299,6 +300,11 @@ class AntragLib // Prestudentstatus und Unterbrechungsfolgeaktionen setzen $result = $this->_ci->prestudentlib->setUnterbrecher($resultAntrag->prestudent_id, $resultAntrag->studiensemester_kurzbz, $studierendenantrag_id); + if (isError($result)) { + $this->_ci->StudierendenantragstatusModel->delete($studierendenantrag_status_id); + return $result; + } + //Mail $subject = 'Unterbrechung freigegeben'; $mail = []; diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php index 6dff4e812..2597b40d0 100644 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -203,8 +203,23 @@ class PrestudentLib if (isError($result)) return $result; $result = getData($result); - if (!$result) - return error('Kein Prestudent in diesem Studiensemester gefunden'); + if (!$result) { + /** TODO(chris): Zukünftige Unterbrecher so nicht möglich + * - Verband und Gruppe dürfen noch nicht gesetzt werden + * - Keine Garantie das Ausbildungssemester gleich bleibt (weiter Unterbrechungen oder eine Wiederholung in der Zwischenzeit) + * - LVs eventuell nicht zugewießen + * Mögliche Lösung: JOB! + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) { + return error('Kein Prestudent status gefunden'); + } + $result->studiensemester_kurzbz*/ + return error('Kein Prestudent status gefunden'); + } $prestudent_status = current($result); diff --git a/system/dbupdate_3.4/27351_digitalisierung_formulare.php b/system/dbupdate_3.4/27351_digitalisierung_formulare.php index a40b457e2..e94bd2b61 100644 --- a/system/dbupdate_3.4/27351_digitalisierung_formulare.php +++ b/system/dbupdate_3.4/27351_digitalisierung_formulare.php @@ -100,8 +100,8 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status CACHE 1; ALTER TABLE campus.tbl_studierendenantrag_status ALTER COLUMN studierendenantrag_status_id SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq'); - GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO vilesci; - GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO web; + GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO vilesci; + GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO web; GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO vilesci; GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO web;"; From 61856473eaf40242128fd170c23d156bc0b3c0ba Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Wed, 5 Jul 2023 08:30:33 +0200 Subject: [PATCH 041/175] Leitungsansicht Autocomplete 1st draft --- .../components/Antrag/Abmeldung.php | 7 +- application/libraries/AntragLib.php | 10 ++- .../models/organisation/Studiengang_model.php | 17 +++- application/views/templates/FHC-Footer.php | 1 + public/js/apps/lehre/Antrag/Leitung.js | 2 +- .../Studierendenantrag/Leitung/Actions/New.js | 84 ++++++++++++------- 6 files changed, 86 insertions(+), 35 deletions(-) diff --git a/application/controllers/components/Antrag/Abmeldung.php b/application/controllers/components/Antrag/Abmeldung.php index 9130c1d7d..44d1b5c4a 100644 --- a/application/controllers/components/Antrag/Abmeldung.php +++ b/application/controllers/components/Antrag/Abmeldung.php @@ -167,9 +167,12 @@ class Abmeldung extends FHC_Controller { $this->load->library('PermissionLib'); + $_POST = json_decode($this->input->raw_input_stream, true); + $query = $this->input->post('query'); + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); - $result = $this->antraglib->getAbmeldeBerechtigtForStg($studiengaenge); + $result = $this->antraglib->getAktivePrestudentenInStgs($studiengaenge, $query); if (isError($result)) { return $this->outputJsonError(getError($result)); } @@ -178,6 +181,8 @@ class Abmeldung extends FHC_Controller return $this->outputJsonSuccess([]); } + return $this->outputJsonSuccess($result); + $sortedStudents = []; foreach ($result as $item) { if (!isset($sortedStudents[$item->studiengang_kz])) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index e3119d65b..e06c57544 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -1188,13 +1188,15 @@ class AntragLib return $stsems; } - public function getAbmeldeBerechtigtForStg($studiengaenge) + public function getAktivePrestudentenInStgs($studiengaenge, $query) { $blacklist = $this->_ci->config->item('stgkz_blacklist_abmeldung'); $studiengaenge = array_diff($studiengaenge, $blacklist); - return $this->_ci->StudiengangModel->getAktivePrestudenten($studiengaenge, [ - Studierendenantrag_model::TYP_ABMELDUNG - ]); + return $this->_ci->StudiengangModel->getAktivePrestudenten( + $studiengaenge, + [ Studierendenantrag_model::TYP_ABMELDUNG ], + $query + ); } public function getFailedExamForPrestudent($prestudent_id) diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index ea9e5857e..1e5c16cc5 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -532,7 +532,7 @@ class Studiengang_model extends DB_Model * * @return stdClass */ - public function getAktivePrestudenten($studiengang_kzs, $not_antrag_typ = null) + public function getAktivePrestudenten($studiengang_kzs, $not_antrag_typ = null, $query = null) { $this->load->config('studierendenantrag'); @@ -571,6 +571,21 @@ class Studiengang_model extends DB_Model $this->db->group_end(); } + if ($query) { + $query = explode(' ', $query); + $this->db->group_start(); + foreach ($query as $q) { + $this->db->group_start(); + $this->db->where('pers.vorname ILIKE', "%" . $q . "%"); + $this->db->or_where('pers.nachname ILIKE', "%" . $q . "%"); + $this->db->or_where($this->dbTable . '.bezeichnung ILIKE', "%" . $q . "%"); + if (is_numeric($q)) + $this->db->or_where('p.prestudent_id', $q); + $this->db->group_end(); + } + $this->db->group_end(); + } + return $this->load(); } } diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index c461dd8b0..f4d66a9b9 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -122,6 +122,7 @@ generateJSsInclude('vendor/npm-asset/primevue/column/column.min.js'); generateJSsInclude('vendor/npm-asset/primevue/calendar/calendar.min.js'); generateJSsInclude('vendor/npm-asset/primevue/skeleton/skeleton.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/autocomplete/autocomplete.min.js'); } // -------------------------------------------------------------------------------------------------------- diff --git a/public/js/apps/lehre/Antrag/Leitung.js b/public/js/apps/lehre/Antrag/Leitung.js index 0e68cccba..e243aad93 100644 --- a/public/js/apps/lehre/Antrag/Leitung.js +++ b/public/js/apps/lehre/Antrag/Leitung.js @@ -5,4 +5,4 @@ const app = Vue.createApp({ StudierendenantragLeitung } }); -app.mount('#wrapper'); +app.use(primevue.config.default).mount('#wrapper'); diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/New.js b/public/js/components/Studierendenantrag/Leitung/Actions/New.js index 8a98a6aa5..b9c21b05f 100644 --- a/public/js/components/Studierendenantrag/Leitung/Actions/New.js +++ b/public/js/components/Studierendenantrag/Leitung/Actions/New.js @@ -4,7 +4,8 @@ import Phrasen from '../../../../mixins/Phrasen.js'; export default { components: { - BsModal + BsModal, + AutoComplete: primevue.autocomplete }, mixins: [ Phrasen @@ -15,8 +16,7 @@ export default { data() { return { data: [], - student: '', - stg: '' + student: '' } }, computed: { @@ -24,13 +24,13 @@ export default { return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/lehre/Studierendenantrag/abmeldung/' + this.student; }, students() { - if (!this.stg) - return []; - if (!this.data[this.stg]) - return []; - return this.data[this.stg].studenten.sort( + return this.data.sort( (a, b) => a.nachname == b.nachname ? - a.vorname > b.vorname : + ( + a.vorname == b.vorname ? + a.bezeichnung > b.bezeichnung : + a.vorname > b.vorname + ) : a.nachname > b.nachname ); }, @@ -47,15 +47,17 @@ export default { }), { dialogClass: 'modal-fullscreen' }, this.p.t('studierendenantrag', 'antrag_header')).then(() => { + this.data = []; this.loadSelects(); this.$emit('reload'); }); }, - loadSelects() { - return axios.get( + loadData(evt) { + axios.post( FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + - '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/' + '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/', + evt ).then( result => { if (result.data.error) { @@ -66,14 +68,30 @@ export default { return result; } ); + }, + loadSelects() { + if (this.hasNoData) { + return axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/', + {query: 'felix'} + ).then( + result => { + if (result.data.error) { + BsAlert.popup(result.data.retval, {dialogClass: 'alert alert-danger'}); + } else { + this.data = result.data.retval; + } + return result; + } + ); + } } }, - created() { - return this.loadSelects(); - }, template: `
- @@ -85,22 +103,32 @@ export default {
From 573a8d8e333a056136b7f80640143a432b00ae35 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Mon, 10 Jul 2023 09:09:46 +0200 Subject: [PATCH 043/175] composer lock --- composer.lock | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/composer.lock b/composer.lock index 30d011aae..c88612d1b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "03cfe5f5e33ab66a5009b6ffcb2c5fa0", + "content-hash": "1105a07a83f98040eedbe34b23e11ee3", "packages": [ { "name": "afarkas/html5shiv", @@ -1628,15 +1628,6 @@ ], "time": "2023-06-13T08:41:47+00:00" }, - { - "name": "popperjs/core", - "version": "2.10.2", - "dist": { - "type": "file", - "url": "https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" - }, - "type": "library" - }, { "name": "rmariuzzo/jquery-checkboxes", "version": "1.0.7", From 761af30a7525515e8ca66018d77d15279e042d5e Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Mon, 10 Jul 2023 09:21:12 +0200 Subject: [PATCH 044/175] speed up student selection --- .../models/organisation/Studiengang_model.php | 3 +++ .../Studierendenantrag/Leitung/Actions/New.js | 12 +----------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 89941aeb1..e06965bea 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -547,6 +547,7 @@ class Studiengang_model extends DB_Model $this->addSelect('p.prestudent_id'); $this->addSelect('pers.vorname'); $this->addSelect('pers.nachname'); + $this->addSelect("CONCAT(UPPER(pers.nachname), ' ', pers.vorname, ' (', " . $this->dbTable . ".bezeichnung, ')') AS name"); $this->addJoin('public.tbl_prestudent p', 'studiengang_kz'); $this->addJoin( @@ -585,6 +586,8 @@ class Studiengang_model extends DB_Model $this->db->group_end(); } + $this->addOrder('name'); + return $this->load(); } } diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/New.js b/public/js/components/Studierendenantrag/Leitung/Actions/New.js index 490e62548..6169fef72 100644 --- a/public/js/components/Studierendenantrag/Leitung/Actions/New.js +++ b/public/js/components/Studierendenantrag/Leitung/Actions/New.js @@ -22,15 +22,6 @@ export default { computed: { newUrl() { return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/lehre/Studierendenantrag/abmeldung/' + this.student.prestudent_id; - }, - students() { - return this.data.map((current)=> - { - current.name = current.nachname.toUpperCase() + " " + current.vorname + " (" + current.bezeichnung + ")"; - return current; - }).sort( - (a, b) => a.name > b.name ? 1 : -1 - ); } }, methods: { @@ -79,12 +70,11 @@ export default {