From a0dce925d43f687db814a611561edc5ae562a2b8 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 14 Jan 2025 10:56:28 +0100 Subject: [PATCH 001/357] =?UTF-8?q?-=20rt=20holt=20sich=20zus=C3=A4tzlich?= =?UTF-8?q?=20alle=20gebiete=20aus=20den=20semestern=20davor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cis/testtool/login.php | 1 + cis/testtool/menu.php | 48 ++++++--- include/gebiet_pruefling.class.php | 97 +++++++++++++++++++ system/dbupdate_3.4.php | 2 + ...eihungstest_ablauf_fuer_quereinsteiger.php | 39 ++++++++ 5 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 include/gebiet_pruefling.class.php create mode 100644 system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php diff --git a/cis/testtool/login.php b/cis/testtool/login.php index d1944fe7a..2bd4601db 100644 --- a/cis/testtool/login.php +++ b/cis/testtool/login.php @@ -604,6 +604,7 @@ elseif (isset($prestudent_id)) $ps_obj->lastStatus = $ps_tmp->status_kurzbz; // letzten Status dem result array hinzufügen $ps_obj->status_mehrsprachig = $ps_tmp->status_mehrsprachig; + $ps_obj->ausbildungssemester = $ps_tmp->ausbildungssemester; } // Falls Status 'Abgewiesene' vorhanden, nach hinten reihen diff --git a/cis/testtool/menu.php b/cis/testtool/menu.php index 7c8b12b9d..42ab8f8d3 100644 --- a/cis/testtool/menu.php +++ b/cis/testtool/menu.php @@ -29,6 +29,7 @@ require_once('../../include/sprache.class.php'); require_once '../../include/phrasen.class.php'; require_once '../../include/studiengang.class.php'; require_once('../../include/gebiet.class.php'); +require_once('../../include/gebiet_pruefling.class.php'); if (!$db = new basis_db()) die('Fehler beim Oeffnen der Datenbankverbindung'); @@ -193,8 +194,8 @@ if (isset($_SESSION['pruefling_id'])) ) - SELECT DISTINCT ON - (gebiet_id, semester, reihung) + SELECT * FROM (SELECT DISTINCT ON + (gebiet_id) semester, gebiet_id, STRING_AGG(studiengang_kz::TEXT, ', ' ORDER BY studiengang_kz) AS studiengang_kz_list, @@ -221,13 +222,7 @@ if (isset($_SESSION['pruefling_id'])) JOIN testtool.tbl_gebiet USING (gebiet_id) WHERE - ( - (prestudent_data.semester= 1 AND tbl_ablauf.semester = 1) - OR - (prestudent_data.semester= 2 AND tbl_ablauf.semester = 2) - OR - (prestudent_data.semester= 3 AND tbl_ablauf.semester IN (1,3)) - ) + tbl_ablauf.semester <= prestudent_data.semester AND ( prestudent_data.studienplan_id = tbl_ablauf.studienplan_id OR @@ -254,9 +249,7 @@ if (isset($_SESSION['pruefling_id'])) JOIN testtool.tbl_gebiet USING (gebiet_id) WHERE - (prestudent_data.semester= 1 AND tbl_ablauf.semester = 1) - OR - (prestudent_data.semester= 3 AND tbl_ablauf.semester IN (1,3)) + tbl_ablauf.semester <= prestudent_data.semester ) ) temp ) temp2 @@ -265,7 +258,7 @@ if (isset($_SESSION['pruefling_id'])) semester, gebiet_id, bezeichnung, - ". $bezeichnung_mehrsprachig_sel ." + ". $bezeichnung_mehrsprachig_sel ." ) temp3 ORDER BY semester, @@ -278,6 +271,8 @@ if (isset($_SESSION['pruefling_id'])) $lastsemester = ''; $quereinsteiger_stg = ''; $_SESSION['alleGebiete']= []; + $gebiet_pruefling = new gebiet_pruefling(); + $quereinsteiger_menu = false; while($row = $db->db_fetch_object($result)) { //Jedes Semester in einer eigenen Tabelle anzeigen @@ -289,8 +284,25 @@ if (isset($_SESSION['pruefling_id'])) } $lastsemester = $row->semester; - echo ''; - echo ''; + if ($row->semester == '1') + { + // Basisgebiete anzeigen + echo '
'. ($row->semester == '1' ? $p->t('testtool/basisgebiete') : $p->t('testtool/quereinstiegsgebiete')).'
'; + echo ''; + } + else + { + if (!$quereinsteiger_menu) + { + echo '
' . $p->t('testtool/basisgebiete') . '
'; + echo ''; + $quereinsteiger_menu = true; + } + else + { + echo '
' . $p->t('testtool/quereinstiegsgebiete') . '
'; + } + } } // Bei Quereinstiegsgebieten nach STG clustern und die STG anzeigen @@ -386,6 +398,12 @@ if (isset($_SESSION['pruefling_id'])) '; + if (!$gebiet_pruefling->checkIfExists($_SESSION['pruefling_id'], $row->gebiet_id)) + { + $gebiet_pruefling->pruefling_id = $_SESSION['pruefling_id']; + $gebiet_pruefling->gebiet_id = $row->gebiet_id; + $gebiet_pruefling->saveGebietForPruefling(); + } $_SESSION['alleGebiete'][] = $row->gebiet_id; } else diff --git a/include/gebiet_pruefling.class.php b/include/gebiet_pruefling.class.php new file mode 100644 index 000000000..9578bb546 --- /dev/null +++ b/include/gebiet_pruefling.class.php @@ -0,0 +1,97 @@ +db_add_param($pruefling_id, FHC_INTEGER); + + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $this->prueflinggebiet_id = $row->prueflinggebiet_id; + $this->pruefling_id = $row->pruefling_id; + $this->gebiet_id = $row->gebiet_id; + return true; + } + else + { + $this->errormsg = "Pruefling nicht gefunden"; + return false; + } + } + else + { + $this->errormsg = "Fehler beim Laden der Gebiete für den Pruefling"; + return false; + } + } + + public function checkIfExists($pruefling_id, $gebiet_id) + { + $qry = "SELECT 1 + FROM testtool.tbl_pruefling_gebiet + WHERE pruefling_id =".$this->db_add_param($pruefling_id, FHC_INTEGER) ." AND gebiet_id =".$this->db_add_param($gebiet_id, FHC_INTEGER); + + if ($result = $this->db_query($qry)) + { + if ($this->db_num_rows($result) > 0) + return true; + else + return false; + } + } + + public function saveGebietForPruefling() + { + $qry = "INSERT INTO testtool.tbl_pruefling_gebiet + (pruefling_id, gebiet_id) + VALUES(". + $this->db_add_param($this->pruefling_id, FHC_INTEGER).','. + $this->db_add_param($this->gebiet_id, FHC_INTEGER).');'; + + if ($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = 'Fehler beim Speichern der Daten'; + return true; + } + } + +} +?> diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 0af314c46..75bb58898 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -67,6 +67,7 @@ require_once('dbupdate_3.4/25999_C4_permission.php'); require_once('dbupdate_3.4/33683_digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp.php'); require_once('dbupdate_3.4/40717_lv_faktor.php'); require_once('dbupdate_3.4/48526_pep_tagging.php'); +require_once('dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen @@ -377,6 +378,7 @@ $tabellen=array( "testtool.tbl_pruefling_frage" => array("prueflingfrage_id","pruefling_id","frage_id","nummer","begintime","endtime"), "testtool.tbl_frage_sprache" => array("frage_id","sprache","text","bild","audio","insertamum","insertvon","updateamum","updatevon"), "testtool.tbl_vorschlag_sprache" => array("vorschlag_id","sprache","text","bild","audio","insertamum","insertvon","updateamum","updatevon"), + "testtool.tbl_pruefling_gebiet" => array("prueflinggebiet_id","pruefling_id","gebiet_id","insertamum"), "system.tbl_app" => array("app"), "system.tbl_appdaten" => array("appdaten_id","uid","app","appversion","version","bezeichnung","daten","freigabe","insertamum","insertvon","updateamum","updatevon"), "system.tbl_cronjob" => array("cronjob_id","server_kurzbz","titel","beschreibung","file","last_execute","aktiv","running","jahr","monat","tag","wochentag","stunde","minute","standalone","reihenfolge","updateamum", "updatevon","insertamum","insertvon","variablen"), diff --git a/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php b/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php new file mode 100644 index 000000000..8898afdf3 --- /dev/null +++ b/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php @@ -0,0 +1,39 @@ +db_query('SELECT 1 FROM testtool.tbl_pruefling_gebiet LIMIT 1')) +{ + $qry = 'CREATE TABLE testtool.tbl_pruefling_gebiet + ( + prueflinggebiet_id integer NOT NULL, + pruefling_id integer NOT NULL, + gebiet_id integer NOT NULL, + insertamum timestamp DEFAULT now() + ); + + ALTER TABLE testtool.tbl_pruefling_gebiet OWNER TO fhcomplete; + ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT pk_tbl_pruefling_gebiet PRIMARY KEY (prueflinggebiet_id); + + CREATE SEQUENCE testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + + ALTER TABLE testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq OWNER TO fhcomplete; + ALTER TABLE testtool.tbl_pruefling_gebiet ALTER COLUMN prueflinggebiet_id SET DEFAULT nextval(\'testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq\'); + + GRANT SELECT, UPDATE, INSERT, DELETE ON testtool.tbl_pruefling_gebiet TO web; + GRANT SELECT, UPDATE, INSERT, DELETE ON testtool.tbl_pruefling_gebiet TO vilesci; + GRANT SELECT, UPDATE ON testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq TO vilesci; + GRANT SELECT, UPDATE ON testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq TO web; + '; + + if (!$db->db_query($qry)) + echo 'public.tbl_pruefling_gebiet: '.$db->db_last_error().'
'; + else + echo '
public.tbl_pruefling_gebiet table created'; +} + From d3210f0d3d19eff642888f1803ee08d140266f19 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 18 Feb 2025 13:51:20 +0100 Subject: [PATCH 002/357] - foreign keys hinzugefuegt - beim zuruecksetzen der gebiete, wird auch tbl_pruefling_gebiet zurueckgesetzt --- ...eihungstest_ablauf_fuer_quereinsteiger.php | 2 + vilesci/stammdaten/auswertung_fhtw.php | 57 ++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php b/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php index 8898afdf3..41532cfe0 100644 --- a/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php +++ b/system/dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php @@ -14,6 +14,8 @@ if (!$result = @$db->db_query('SELECT 1 FROM testtool.tbl_pruefling_gebiet LIMIT ALTER TABLE testtool.tbl_pruefling_gebiet OWNER TO fhcomplete; ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT pk_tbl_pruefling_gebiet PRIMARY KEY (prueflinggebiet_id); + ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT fk_tbl_pruefling_gebiet_pruefling_id FOREIGN KEY (pruefling_id) REFERENCES testtool.tbl_pruefling(pruefling_id) ON UPDATE CASCADE ON DELETE RESTRICT; + ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT fk_tbl_pruefling_gebiet_gebiet_id FOREIGN KEY (gebiet_id) REFERENCES testtool.tbl_gebiet(gebiet_id) ON UPDATE CASCADE ON DELETE RESTRICT; CREATE SEQUENCE testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq START WITH 1 diff --git a/vilesci/stammdaten/auswertung_fhtw.php b/vilesci/stammdaten/auswertung_fhtw.php index 8d928dacf..d4ece9c72 100644 --- a/vilesci/stammdaten/auswertung_fhtw.php +++ b/vilesci/stammdaten/auswertung_fhtw.php @@ -251,6 +251,31 @@ if ($deleteSingleResult) exit(); } + $qry = "SELECT * FROM testtool.tbl_pruefling_gebiet + WHERE pruefling_id=" . $db->db_add_param($pruefling->pruefling_id) . " AND gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . ""; + + if ($db->db_query($qry)) + { + while ($row = $db->db_fetch_object()) + { + $undo .= " INSERT INTO testtool.tbl_pruefling_gebiet(prueflinggebiet_id,pruefling_id,gebiet_id, insertamum) VALUES (" . + $db->db_add_param($row->prueflinggebiet_id, FHC_INTEGER) . ', ' . + $db->db_add_param($row->pruefling_id, FHC_INTEGER) . ', ' . + $db->db_add_param($row->gebiet_id, FHC_INTEGER) . ', ' . + $db->db_add_param($row->insertamum) . ');'; + } + } + else + { + $db->db_query('ROLLBACK'); + echo json_encode(array( + 'status' => 'fehler', + 'msg' => 'Fehler beim Erstellen des UNDO Befehls fuer testtool.tbl_pruefling_gebiet' + )); + exit(); + } + + //Antworten loeschen $qry = "DELETE FROM testtool.tbl_pruefling_frage where pruefling_id=" . $db->db_add_param($pruefling->pruefling_id, FHC_INTEGER) . " AND frage_id IN (SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . "); @@ -258,7 +283,9 @@ if ($deleteSingleResult) DELETE FROM testtool.tbl_antwort WHERE pruefling_id=" . $db->db_add_param($pruefling->pruefling_id) . " AND vorschlag_id IN (SELECT vorschlag_id FROM testtool.tbl_vorschlag WHERE frage_id IN - (SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . "));"; + (SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . ")); + + DELETE FROM testtool.tbl_pruefling_gebiet where pruefling_id=" . $db->db_add_param($pruefling->pruefling_id, FHC_INTEGER) . " AND gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . ";"; if ($result = $db->db_query($qry)) { @@ -388,9 +415,35 @@ if ($deleteAllResults) exit(); } + $qry = "SELECT * FROM testtool.tbl_pruefling_gebiet WHERE pruefling_id=" . $db->db_add_param($pruefling->pruefling_id, FHC_INTEGER) . "; + "; + + if ($db->db_query($qry)) + { + while ($row = $db->db_fetch_object()) + { + $undo .= " INSERT INTO testtool.tbl_pruefling_gebiet(prueflinggebiet_id,pruefling_id,gebiet_id,insertamum) VALUES (" . + $db->db_add_param($row->prueflinggebiet_id, FHC_INTEGER) . ', ' . + $db->db_add_param($row->pruefling_id, FHC_INTEGER) . ', ' . + $db->db_add_param($row->gebiet_id, FHC_INTEGER) . ', ' . + $db->db_add_param($row->insertamum) . ');'; + } + } + else + { + $db->db_query('ROLLBACK'); + echo json_encode(array( + 'status' => 'fehler', + 'msg' => 'Fehler beim Erstellen des UNDO Befehls fuer testtool.tbl_pruefling_gebiet' + )); + exit(); + } + + //Antworten loeschen $qry = " DELETE FROM testtool.tbl_pruefling_frage where pruefling_id=".$db->db_add_param($pruefling->pruefling_id)."; - DELETE FROM testtool.tbl_antwort WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";"; + DELETE FROM testtool.tbl_antwort where pruefling_id=".$db->db_add_param($pruefling->pruefling_id)."; + DELETE FROM testtool.tbl_pruefling_gebiet WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";"; if ($result = $db->db_query($qry)) { From 6495f741b928498fa3e5580cef01a39f73ed0b06 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 9 Jul 2025 14:02:41 +0200 Subject: [PATCH 003/357] added missing phrase --- system/phrasesupdate.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 0203b3c2f..bc067f3f0 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -19663,6 +19663,26 @@ array( ) ) ), + array( + 'app' => 'international', + 'category' => 'international', + 'phrase' => 'personenMassnahmen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'alle Maßnahmen der Personen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => ' all measures of the people', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'international', 'category' => 'international', From cf59bcff12b4e4ad1a14ccbcd34ffbef7478dcf7 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 19 Aug 2025 09:16:26 +0200 Subject: [PATCH 004/357] add Functionality sendInfomail - expand InputComponent for dynamic adding of actionButton to Form Upload Image - add Phrases for Infomail --- public/js/components/Form/Input.js | 4 +- public/js/components/Form/Upload/Image.js | 13 +++++- .../Studentenverwaltung/Details/Details.js | 12 ++++++ system/phrasesupdate.php | 42 ++++++++++++++++++- 4 files changed, 66 insertions(+), 5 deletions(-) diff --git a/public/js/components/Form/Input.js b/public/js/components/Form/Input.js index c85272aab..4044b32fb 100644 --- a/public/js/components/Form/Input.js +++ b/public/js/components/Form/Input.js @@ -28,7 +28,8 @@ export default { label: String, // NOTE(chris): remove these from $attrs array to prevent doubled event listeners onInput: [Array, Function], - 'onUpdate:modelValue': [Array, Function] + 'onUpdate:modelValue': [Array, Function], + titleActionButton: String }, data() { return { @@ -314,6 +315,7 @@ export default { :id="idCmp" :name="name" :class="validationClass" + :titleActionButton="titleActionButton" @update:model-value="clearValidationForThisName" > diff --git a/public/js/components/Form/Upload/Image.js b/public/js/components/Form/Upload/Image.js index b0b8d5b78..4b96d4c85 100644 --- a/public/js/components/Form/Upload/Image.js +++ b/public/js/components/Form/Upload/Image.js @@ -1,9 +1,14 @@ export default { emits: [ - 'update:modelValue' + 'update:modelValue', + 'actionbutton-clicked' ], props: { - modelValue: String + modelValue: String, + titleActionButton: { + type: String, + default: "" + } }, computed: { valueAsBase64DataString() { @@ -28,6 +33,9 @@ export default { }, deleteImage() { this.$emit('update:modelValue', ''); + }, + emitAction(){ + this.$emit('actionbutton-clicked', this.modelValue); } }, template: ` @@ -42,6 +50,7 @@ export default { + diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Details.js b/public/js/components/Stv/Studentenverwaltung/Details/Details.js index 45ee3bdd5..61eea7605 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Details.js @@ -158,6 +158,16 @@ export default { }, reload(){ this.updateStudent(this.modelValue); + }, + sendInfomail(){ + const subject = this.$p.t('person', 'betreffProfilfoto'); + const subjectEncoded = encodeURIComponent(subject); + + const body = this.$p.t('person', 'mailText_profilfoto'); + const bodyWithNewLines = body.replace(/\\n/g, '\n'); + const bodyEncoded = encodeURIComponent(bodyWithNewLines); + + window.location.href = "mailto:" + this.modelValue.mail_intern + "?subject=" + subjectEncoded + "&body=" + bodyEncoded; } }, created() { @@ -400,8 +410,10 @@ export default { container-class="col-4 stv-details-details-foto" :label="$p.t('person', 'foto')" type="UploadImage" + titleActionButton="Infomail" v-model="data.foto" name="foto" + @actionbutton-clicked="sendInfomail" > No Image diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 4a3cfd7ec..3b0e607c9 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -30281,8 +30281,6 @@ array( ) ) ), - - //ProfilUpdate Phrasen ende array( 'app' => 'core', @@ -46677,6 +46675,46 @@ and represent the current state of research on the topic. The prescribed citatio ) ) ), + array( + 'app' => 'core', + 'category' => 'person', + 'phrase' => 'mailText_profilfoto', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Hallo,\n\nIhr Profilbild wurde entfernt, da es nicht den aktuellen Bildrichtlinen entspricht. Bitte laden Sie unter CIS->Profil ein neues Profilbild hoch!\n\nDanke!", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Hello,\n\nYour profile picture has been removed because it does not comply with the current image guidelines. Please upload a new profile picture under CIS->Profile!\n\nThank you!", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'person', + 'phrase' => 'betreffProfilfoto', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Profilbild', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Profile picture', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), // FHC-4 Finetuning END //**************************** CORE/search From 9183c4f04c37aecc9141aaddfaea077d4795ccfc Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 1 Oct 2025 12:03:18 +0200 Subject: [PATCH 005/357] massnahme einmalig flag hinzugefuegt --- system/phrasesupdate.php | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index ceb265b14..5078fb12d 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -19963,6 +19963,46 @@ array( ) ) ), + array( + 'app' => 'international', + 'category' => 'international', + 'phrase' => 'einmalig', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nur einmal planbar', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'One-time only', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'international', + 'category' => 'international', + 'phrase' => 'erroreinmalig', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Diese Maßnahme kann nur einmal geplant werden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'This measure can only be planned once.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'gruppenmanagement', From efc67d14a5bc1432ad8af522dff062e3c164c08c Mon Sep 17 00:00:00 2001 From: ma0048 Date: Thu, 6 Nov 2025 12:38:13 +0100 Subject: [PATCH 006/357] qulikurs spalte hinzugekommen bei infocenter freigegebendata --- application/config/infocenter.php | 1 + .../infocenter/infocenterFreigegebenData.php | 33 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/application/config/infocenter.php b/application/config/infocenter.php index 555c30996..15889ef78 100644 --- a/application/config/infocenter.php +++ b/application/config/infocenter.php @@ -3,3 +3,4 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); $config['infocenter_studiengang_kz'] = '10021, 10027, 10002'; +$config['infocenter_qualifikationskurs_kz'] = '10002'; diff --git a/application/views/system/infocenter/infocenterFreigegebenData.php b/application/views/system/infocenter/infocenterFreigegebenData.php index 38285b6ae..55d8f403e 100644 --- a/application/views/system/infocenter/infocenterFreigegebenData.php +++ b/application/views/system/infocenter/infocenterFreigegebenData.php @@ -8,6 +8,7 @@ $LOGDATA_NAME = '\'Login with code\', \'Login with user\', \'Attempt to register with existing mailadress\', \'Access code sent\', \'Personal data saved\''; $REJECTED_STATUS = '\'Abgewiesener\''; $ADDITIONAL_STG = $this->config->item('infocenter_studiengang_kz'); + $QUALIFIKATIONSKURS = $this->config->item('infocenter_qualifikationskurs_kz'); $STATUS_KURZBZ = '\'Wartender\', \'Bewerber\', \'Aufgenommener\', \'Student\''; $STUDIENSEMESTER = '\''.$this->variablelib->getVar('infocenter_studiensemester').'\''; $ORG_NAME = '\'InfoCenter\''; @@ -277,7 +278,26 @@ $query = ' WHERE konto.person_id = p.person_id AND konto.studiensemester_kurzbz = '. $STUDIENSEMESTER .' AND konto.buchungstyp_kurzbz = '. $KAUTION_DRITT_STAAT .' - ) AS "Kaution" + ) AS "Kaution", + ( + SELECT 1 + FROM public.tbl_prestudentstatus pss + JOIN public.tbl_prestudent ps USING(prestudent_id) + JOIN public.tbl_studiengang sg USING(studiengang_kz) + JOIN lehre.tbl_studienplan sp USING(studienplan_id) + JOIN lehre.tbl_studienordnung so USING(studienordnung_id) + WHERE pss.status_kurzbz = '.$INTERESSENT_STATUS.' + AND pss.bewerbung_abgeschicktamum IS NOT NULL + AND ps.person_id = p.person_id + AND sg.studiengang_kz in('.$QUALIFIKATIONSKURS.') + AND NOT EXISTS ( + SELECT 1 + FROM tbl_prestudentstatus spss + WHERE spss.prestudent_id = ps.prestudent_id + AND spss.status_kurzbz = '.$REJECTED_STATUS.' + ) + LIMIT 1 + ) AS "Qualikurs" FROM public.tbl_person p LEFT JOIN ( SELECT tpl.person_id, @@ -351,7 +371,8 @@ $query = ' 'ZGV Nation MA', 'InfoCenter Mitarbeiter', 'Identitätsnachweis', - ucfirst($this->p->t('infocenter', 'kaution')) + ucfirst($this->p->t('infocenter', 'kaution')), + 'Qualikurs' ), 'formatRow' => function($datasetRaw) { @@ -480,6 +501,14 @@ $query = ' $datasetRaw->{'Kaution'} = 'Offen'; } + if ($datasetRaw->{'Qualikurs'} === null) + { + $datasetRaw->{'Qualikurs'} = 'Nein'; + } + else + { + $datasetRaw->{'Qualikurs'} = 'Ja'; + } return $datasetRaw; }, 'markRow' => function($datasetRaw) { From 4c6d645cc62bea6ae5cdbb8a2451940994a019e0 Mon Sep 17 00:00:00 2001 From: chfhtw Date: Tue, 18 Nov 2025 15:02:55 +0100 Subject: [PATCH 007/357] Studienverlauf verlinken im neuen FAS --- .../Stv/Studentenverwaltung/Details/Noten.js | 13 +++++++++++- system/phrasesupdate.php | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Noten.js b/public/js/components/Stv/Studentenverwaltung/Details/Noten.js index 71b8096ec..817465879 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Noten.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Noten.js @@ -25,6 +25,11 @@ export default { stdsem: '' }; }, + computed: { + gradeListLink() { + return this.$api.getUri('/person/gradelist/index/' + this.modelValue.uid); + } + }, methods: { reload() { this.$refs.zeugnis.$refs.table.reloadTable(); @@ -39,8 +44,14 @@ export default { const savedPath = window.localStorage.getItem(LOCAL_STORAGE_ID); this.stdsem = savedPath || ''; }, - template: ` + template: /* html */`
+
+ + + +
+
+
+ +
+
+ +
+
+
` +}; \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Noten.js b/public/js/components/Stv/Studentenverwaltung/Details/Noten.js index 71b8096ec..3217f192c 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Noten.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Noten.js @@ -2,6 +2,9 @@ import NotenZeugnis from './Noten/Zeugnis.js'; import NotenTeacher from './Noten/Teacher.js'; import NotenRepeater from './Noten/Repeater.js'; +import ApiStvGrades from '../../../../api/factory/stv/grades.js'; +import { highlightGesamtnote } from "../../../../helpers/DocumentHelper"; + const LOCAL_STORAGE_ID = 'stv_details_noten_2024-11-25_stdsem_all'; export default { @@ -22,7 +25,10 @@ export default { }, data() { return { - stdsem: '' + stdsem: '', + endpoint: ApiStvGrades, + zeugnisLoaded: false, + teacherLoaded: false, }; }, methods: { @@ -33,6 +39,30 @@ export default { }, saveStdsem(event) { window.localStorage.setItem(LOCAL_STORAGE_ID, event.target.value); + }, + onZeugnisLoaded() { + this.zeugnisLoaded = true; + this.checkHighlight(); + }, + onTeacherLoaded() { + this.teacherLoaded = true; + this.checkHighlight(); + }, + checkHighlight() + { + if (!this.zeugnisLoaded || !this.teacherLoaded) + return; + + if (!this.$refs.zeugnis || !this.$refs.teacher) + return; + + let zeugnisTable = this.$refs.zeugnis.$refs.table.tabulator; + let teacherTable = this.$refs.teacher.$refs.table.tabulator; + + if (!zeugnisTable || !teacherTable) + return; + + highlightGesamtnote(zeugnisTable, teacherTable); } }, created() { @@ -49,10 +79,10 @@ export default {
- +
- +
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Noten/Teacher.js b/public/js/components/Stv/Studentenverwaltung/Details/Noten/Teacher.js index e566d3a09..f25d291cf 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Noten/Teacher.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Noten/Teacher.js @@ -1,13 +1,12 @@ import {CoreFilterCmpt} from "../../../../filter/Filter.js"; -import ApiStvGrades from '../../../../../api/factory/stv/grades.js'; - export default { components: { CoreFilterCmpt }, emits: [ - "copied" + "copied", + "loaded" ], inject: { currentSemester: { @@ -16,47 +15,127 @@ export default { } }, props: { - student: Object, - allSemester: Boolean + endpoint: { + type: Object, + required: true + }, + id: { + type: [Number, String], + required: true + }, + allSemester: Boolean, + optionalTabulatorOptions: Object, }, data() { return { - tabulatorEvents: [] + tabulatorEvents: [ + { + event: "dataProcessed", + handler: () => this.$emit("loaded"), + }, + ] }; }, computed: { tabulatorOptions() { return { ajaxURL: 'dummy', - ajaxRequestFunc: () => this.$api.call(ApiStvGrades.getTeacherProposal( - this.student.prestudent_id, + ajaxRequestFunc: () => this.$api.call(this.endpoint.getTeacherProposal( + this.id, (!this.allSemester ? this.currentSemester : null) )), ajaxResponse: (url, params, response) => { return response.data || []; }, columns: [ - { field: 'lehrveranstaltung_bezeichnung', title: this.$p.t('lehre/lehrveranstaltung') }, - { field: 'note_bezeichnung', title: this.$p.t('lehre/note') }, - { field: 'mitarbeiter_uid', title: this.$p.t('profil/mitarbeiterIn'), visible: false }, - { field: 'benotungsdatum', title: this.$p.t('stv/grades_gradingdate'), visible: false }, - { field: 'freigabedatum', title: this.$p.t('stv/grades_approvaldate'), visible: false }, - { field: 'studiensemester_kurzbz', title: this.$p.t('lehre/studiensemester'), visible: false }, - { field: 'note', title: this.$p.t('stv/grades_numericgrade'), visible: false }, - { field: 'student_uid', title: this.$p.t('profil/studentIn'), visible: false }, - { field: 'lehrveranstaltung_id', title: this.$p.t('lehre/lehrveranstaltung_id'), visible: false }, - { field: 'punkte', title: this.$p.t('stv/grades_points'), visible: false } + { + field: 'lehrveranstaltung_bezeichnung', + title: this.$p.t('lehre/lehrveranstaltung'), + visible: this.optionalTabulatorOptions?.visibleColumns?.lehrveranstaltung_bezeichnung ?? true, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.lehrveranstaltung_bezeichnung || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'note_bezeichnung', + title: this.$p.t('lehre/note'), + visible: this.optionalTabulatorOptions?.visibleColumns?.note_bezeichnung ?? true, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.note_bezeichnung || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'mitarbeiter_uid', + title: this.$p.t('profil/mitarbeiterIn'), + visible: this.optionalTabulatorOptions?.visibleColumns?.mitarbeiter_uid ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.mitarbeiter_uid || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'benotungsdatum', + title: this.$p.t('stv/grades_gradingdate'), + visible: this.optionalTabulatorOptions?.visibleColumns?.benotungsdatum ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.benotungsdatum || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'freigabedatum', + title: this.$p.t('stv/grades_approvaldate'), + visible: this.optionalTabulatorOptions?.visibleColumns?.freigabedatum ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.freigabedatum || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'studiensemester_kurzbz', + title: this.$p.t('lehre/studiensemester'), + visible: this.optionalTabulatorOptions?.visibleColumns?.studiensemester_kurzbz ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.studiensemester_kurzbz || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'note', + title: this.$p.t('stv/grades_numericgrade'), + visible: this.optionalTabulatorOptions?.visibleColumns?.note ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.note || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'student_uid', + title: this.$p.t('profil/studentIn'), + visible: this.optionalTabulatorOptions?.visibleColumns?.student_uid ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.student_uid || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'lehrveranstaltung_id', + title: this.$p.t('lehre/lehrveranstaltung_id'), + visible: this.optionalTabulatorOptions?.visibleColumns?.lehrveranstaltung_id ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.lehrveranstaltung_id || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'punkte', + title: this.$p.t('stv/grades_points'), + visible: this.optionalTabulatorOptions?.visibleColumns?.punkte ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.punkte || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'vorname', + title: this.$p.t('person/vorname'), + visible: this.optionalTabulatorOptions?.visibleColumns?.vorname ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.vorname || this.optionalTabulatorOptions?.headerFilter || false + }, + { + field: 'nachname', + title: this.$p.t('person/nachname'), + visible: this.optionalTabulatorOptions?.visibleColumns?.nachname ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.nachname || this.optionalTabulatorOptions?.headerFilter || false + } ], + columnDefaults: { + headerFilter: this.optionalTabulatorOptions?.headerFilter ?? false, + }, layout: 'fitDataStretch', height: '100%', selectable: true, + selectableRows: true, // needed for Tabulator v6 + selectableRowsRangeMode: 'click', // needed for Tabulator v6 selectableRangeMode: 'click', - persistenceID: 'stv-details-noten-teacher' + persistenceID: this.optionalTabulatorOptions?.persistenceTeacherID ?? 'stv-details-noten-teacher-2025120401', }; } }, watch: { - student(n) { + id() { this.$refs.table.reloadTable(); }, allSemester(n) { @@ -67,7 +146,7 @@ export default { copyGrades(selected) { const promises = selected.map( grade => this.$api - .call(ApiStvGrades.copyTeacherProposalToCertificate(grade), { + .call(this.endpoint.copyTeacherProposalToCertificate(grade), { errorHeader: grade.lehrveranstaltung_bezeichnung }) .then(() => { diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Noten/Zeugnis.js b/public/js/components/Stv/Studentenverwaltung/Details/Noten/Zeugnis.js index 4d0996b6b..8e921c668 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Noten/Zeugnis.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Noten/Zeugnis.js @@ -2,8 +2,6 @@ import {CoreFilterCmpt} from "../../../../filter/Filter.js"; import ZeugnisActions from './Zeugnis/Actions.js'; import ZeugnisDocuments from './Zeugnis/Documents.js'; -import ApiStvGrades from '../../../../../api/factory/stv/grades.js'; - export default { name: 'Zeugnis', components: { @@ -11,6 +9,7 @@ export default { ZeugnisActions, ZeugnisDocuments }, + emits: ['loaded'], inject: { config: { from: 'config', @@ -22,7 +21,15 @@ export default { } }, props: { - student: Object, + endpoint: { + type: Object, + required: true + }, + id: { + type: [Number, String], + required: true + }, + optionalTabulatorOptions: Object, allSemester: Boolean }, data() { @@ -35,6 +42,10 @@ export default { return item; }) }, + { + event: "dataProcessed", + handler: () => this.$emit("loaded") + }, { event: "rowSelected", handler: row => row.getElement().style.zIndex = 12 @@ -53,7 +64,7 @@ export default { computed: { tabulatorOptions() { const listPromise = this.$api - .call(ApiStvGrades.list()) + .call(this.endpoint.list()) .then(res => res.data.map(({bezeichnung: label, note: value}) => ({label, value}))); let gradeField = { @@ -86,7 +97,7 @@ export default { note_bezeichnung })) // send to backend - .then(data => this.$api.call(ApiStvGrades.updateCertificate(data))) + .then(data => this.$api.call(this.endpoint.updateCertificate(data))) // get bezeichnung again .then(() => listPromise) .then(list => list.find(el => el.value == note)) @@ -109,7 +120,7 @@ export default { if (filterTerm) { return this.$api .call( - ApiStvGrades.getGradeFromPoints( + this.endpoint.getGradeFromPoints( filterTerm, cell.getData().lehrveranstaltung_id, this.currentSemester @@ -142,27 +153,146 @@ export default { .then(() => node.innerText = this.$p.t('ui/loading')) .catch(this.$fhcAlert.handleSystemError); gradeField.editorParams.placeholderLoading = node; + gradeField.visible = this.optionalTabulatorOptions?.visibleColumns?.note ?? true + gradeField.headerFiler = this.optionalTabulatorOptions?.headerFilter?.note || this.optionalTabulatorOptions?.note || false } const columns = [ - { field: 'zeugnis', title: this.$p.t('stv/grades_zeugnis'), formatter: 'tickCross' }, - { field: 'lehrveranstaltung_bezeichnung', title: this.$p.t('lehre/lehrveranstaltung') }, - gradeField, - { field: 'uebernahmedatum', title: this.$p.t('stv/grades_takeoverdate'), visible: false }, - { field: 'benotungsdatum', title: this.$p.t('stv/grades_gradingdate'), visible: false }, - { field: 'studiensemester_kurzbz', title: this.$p.t('lehre/studiensemester'), visible: false }, - { field: 'note_number', title: this.$p.t('stv/grades_numericgrade'), visible: false, formatter: cell => cell.getData().note, tooltip: (evt, cell) => cell.getData().note }, - { field: 'lehrveranstaltung_id', title: this.$p.t('lehre/lehrveranstaltung_id'), visible: false }, - { field: 'studiengang', title: this.$p.t('lehre/studiengang'), visible: false }, - { field: 'studiengang_kz', title: this.$p.t('lehre/studiengangskennzahlLehre'), visible: false }, - { field: 'studiengang_lv', title: this.$p.t('stv/grades_studiengang_lv'), visible: false }, - { field: 'studiengang_kz_lv', title: this.$p.t('stv/grades_studiengang_kz_lv'), visible: false }, - { field: 'semester_lv', title: this.$p.t('stv/grades_semester_lv'), visible: false }, - { field: 'ects_lv', title: this.$p.t('lehre/ects'), visible: false }, - { field: 'lehrform', title: this.$p.t('lehre/lehrform'), visible: false }, - { field: 'kurzbz', title: this.$p.t('lehre/kurzbz'), visible: false }, - { field: 'punkte', title: this.$p.t('stv/grades_points'), visible: false }, - { field: 'lehrveranstaltung_bezeichnung_english', title: this.$p.t('stv/grades_lehrveranstaltung_bezeichnung_english'), visible: false } + { + field: 'zeugnis', + title: this.$p.t('stv/grades_zeugnis'), + formatter: 'tickCross', + visible: this.optionalTabulatorOptions?.visibleColumns?.zeugnis ?? true, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.zeugnis || this.optionalTabulatorOptions?.zeugnis || false + }, + { + field: 'lehrveranstaltung_bezeichnung', + title: this.$p.t('lehre/lehrveranstaltung'), + visible: this.optionalTabulatorOptions?.visibleColumns?.lehrveranstaltung_bezeichnung ?? true, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.lehrveranstaltung_bezeichnung || this.optionalTabulatorOptions?.lehrveranstaltung_bezeichnung || false + + }, + gradeField, + { + field: 'uebernahmedatum', + title: this.$p.t('stv/grades_takeoverdate'), + visible: this.optionalTabulatorOptions?.visibleColumns?.uebernahmedatum ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.uebernahmedatum || this.optionalTabulatorOptions?.uebernahmedatum || false + + }, + { + field: 'benotungsdatum', + title: this.$p.t('stv/grades_gradingdate'), + visible: this.optionalTabulatorOptions?.visibleColumns?.benotungsdatum ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.benotungsdatum || this.optionalTabulatorOptions?.benotungsdatum || false + + }, + { + field: 'studiensemester_kurzbz', + title: this.$p.t('lehre/studiensemester'), + visible: this.optionalTabulatorOptions?.visibleColumns?.studiensemester_kurzbz ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.studiensemester_kurzbz || this.optionalTabulatorOptions?.studiensemester_kurzbz || false + + }, + { + field: 'note_number', + title: this.$p.t('stv/grades_numericgrade'), + visible: this.optionalTabulatorOptions?.visibleColumns?.note_number ?? false, + formatter: cell => cell.getData().note, tooltip: (evt, cell) => cell.getData().note, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.note_number || this.optionalTabulatorOptions?.note_number || false + + }, + { + field: 'lehrveranstaltung_id', + title: this.$p.t('lehre/lehrveranstaltung_id'), + visible: this.optionalTabulatorOptions?.visibleColumns?.lehrveranstaltung_id ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.lehrveranstaltung_id || this.optionalTabulatorOptions?.lehrveranstaltung_id || false + + }, + { + field: 'studiengang', + title: this.$p.t('lehre/studiengang'), + visible: this.optionalTabulatorOptions?.visibleColumns?.studiengang ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.studiengang || this.optionalTabulatorOptions?.studiengang || false + + }, + { + field: 'studiengang_kz', + title: this.$p.t('lehre/studiengangskennzahlLehre'), + visible: this.optionalTabulatorOptions?.visibleColumns?.studiengang_kz ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.studiengang_kz || this.optionalTabulatorOptions?.studiengang_kz || false + + }, + { + field: 'studiengang_lv', + title: this.$p.t('stv/grades_studiengang_lv'), + visible: this.optionalTabulatorOptions?.visibleColumns?.studiengang_lv ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.studiengang_lv || this.optionalTabulatorOptions?.studiengang_lv || false + + }, + { + field: 'studiengang_kz_lv', + title: this.$p.t('stv/grades_studiengang_kz_lv'), + visible: this.optionalTabulatorOptions?.visibleColumns?.studiengang_kz_lv ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.studiengang_kz_lv || this.optionalTabulatorOptions?.studiengang_kz_lv || false + + }, + { + field: 'semester_lv', + title: this.$p.t('stv/grades_semester_lv'), + visible: this.optionalTabulatorOptions?.visibleColumns?.semester_lv ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.semester_lv || this.optionalTabulatorOptions?.semester_lv || false + + }, + { + field: 'ects_lv', + title: this.$p.t('lehre/ects'), + visible: this.optionalTabulatorOptions?.visibleColumns?.ects_lv ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.ects_lv || this.optionalTabulatorOptions?.ects_lv || false + + }, + { + field: 'lehrform', + title: this.$p.t('lehre/lehrform'), + visible: this.optionalTabulatorOptions?.visibleColumns?.lehrform ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.lehrform || this.optionalTabulatorOptions?.lehrform || false + + }, + { + field: 'kurzbz', + title: this.$p.t('lehre/kurzbz'), + visible: this.optionalTabulatorOptions?.visibleColumns?.kurzbz ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.kurzbz || this.optionalTabulatorOptions?.kurzbz || false + + }, + { + field: 'punkte', + title: this.$p.t('stv/grades_points'), + visible: this.optionalTabulatorOptions?.visibleColumns?.punkte ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.punkte || this.optionalTabulatorOptions?.punkte || false + + }, + { + field: 'vorname', + title: this.$p.t('person/vorname'), + visible: this.optionalTabulatorOptions?.visibleColumns?.vorname ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.vorname || this.optionalTabulatorOptions?.vorname || false + + }, + { + field: 'nachname', + title: this.$p.t('person/nachname'), + visible: this.optionalTabulatorOptions?.visibleColumns?.nachname ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.nachname || this.optionalTabulatorOptions?.nachname || false + + }, + { + field: 'lehrveranstaltung_bezeichnung_english', + title: this.$p.t('stv/grades_lehrveranstaltung_bezeichnung_english'), + visible: this.optionalTabulatorOptions?.visibleColumns?.lehrveranstaltung_bezeichnung_english ?? false, + headerFilter: this.optionalTabulatorOptions?.headerFilter?.lehrveranstaltung_bezeichnung_english || this.optionalTabulatorOptions?.lehrveranstaltung_bezeichnung_english || false + + } ]; const hasDocuments = ['both', 'inline'].includes(this.config.documents); @@ -208,8 +338,8 @@ export default { return { ajaxURL: 'dummy', - ajaxRequestFunc: () => this.$api.call(ApiStvGrades.getCertificate( - this.student.prestudent_id, + ajaxRequestFunc: () => this.$api.call(this.endpoint.getCertificate( + this.id, (!this.allSemester ? this.currentSemester : null) )), ajaxResponse: (url, params, response) => { @@ -218,9 +348,11 @@ export default { columns, height: '100%', layout: 'fitDataStretchFrozen', - selectable: 1, + selectable: true, selectableRangeMode: 'click', - persistenceID: 'stv-details-noten-zeugnis-2025112401', + selectableRowsRangeMode: 'click', //needed for Tabulator v6 + selectableRows: true, //needed for Tabulator v6 + persistenceID: this.optionalTabulatorOptions?.persistenceZeugnisID ?? 'stv-details-noten-zeugnis-2025120302', persistence:{ columns: ["width", "visible", "frozen"] } @@ -228,7 +360,8 @@ export default { } }, watch: { - student(n) { + id() + { this.$refs.table.reloadTable(); }, allSemester(n) { @@ -239,7 +372,7 @@ export default { setGrade(data) { this.$api .call( - ApiStvGrades.updateCertificate(data), + this.endpoint.updateCertificate(data), { errorHeader: data.lehrveranstaltung_bezeichnung } ) .then(this.$refs.table.reloadTable) @@ -252,7 +385,7 @@ export default { .confirmDelete() .then(result => result ? data : Promise.reject({handled:true})) .then(data => this.$api.call( - ApiStvGrades.deleteCertificate(data), + this.endpoint.deleteCertificate(data), { errorHeader: data.lehrveranstaltung_bezeichnung } )) .then(this.$refs.table.reloadTable) @@ -261,7 +394,7 @@ export default { } }, created() { - this.$p.loadCategory(['global', 'stv', 'lehre']) + this.$p.loadCategory(['global', 'stv', 'lehre', 'person']) .then(() => { if (this.$refs.table.tableBuilt) this.$refs.table.tabulator.columnManager.setColumns(this.tabulatorOptions.columns); diff --git a/public/js/helpers/DocumentHelper.js b/public/js/helpers/DocumentHelper.js new file mode 100644 index 000000000..c37c632d5 --- /dev/null +++ b/public/js/helpers/DocumentHelper.js @@ -0,0 +1,44 @@ +export function highlightGesamtnote(zeugnisTable, teacherTable) +{ + let zeugnisData = zeugnisTable.getData(); + + let studentsWithNote = new Set(); + + zeugnisData.forEach(row => { + let student = row.uid; + let lv = row.lehrveranstaltung_id; + let note = row.note; + + if (!student || !lv) + return; + + if (note == null || note === "") + return; + + let key = `${student}_${lv}`; + studentsWithNote.add(key); + }); + + teacherTable.deselectRow(); + + teacherTable.getRows().forEach(row => { + let data = row.getData(); + + let student = data.student_uid; + let lv = data.lehrveranstaltung_id; + let note = data.note; + + if (!student || !lv) + return; + + if (note == null || note === "") + return; + + let key = `${student}_${lv}`; + + if (!studentsWithNote.has(key)) + { + row.select(); + } + }); +} \ No newline at end of file From 60f128b314a73bb2edd6046620ccd48e4d8a8c4d Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 9 Dec 2025 13:00:40 +0100 Subject: [PATCH 016/357] tabs gleichgezogen --- public/js/components/LVVerwaltung/Setup/Tabs.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/js/components/LVVerwaltung/Setup/Tabs.js b/public/js/components/LVVerwaltung/Setup/Tabs.js index fbb18bedf..5425b5169 100644 --- a/public/js/components/LVVerwaltung/Setup/Tabs.js +++ b/public/js/components/LVVerwaltung/Setup/Tabs.js @@ -53,17 +53,21 @@ export default { From c664c14afc07a4f98e0c43fa4b27894c5c18927a Mon Sep 17 00:00:00 2001 From: ma0048 Date: Thu, 18 Dec 2025 11:10:08 +0100 Subject: [PATCH 017/357] phrase hinzugefuegt --- system/phrasesupdate.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 5078fb12d..98dff6edb 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -19103,6 +19103,26 @@ array( ) ) ), + array( + 'app' => 'international', + 'category' => 'international', + 'phrase' => 'massnahmeneinmalig', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Diese Maßnahme ist nur einmalig planbar.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'This measure may only be planned once.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'international', 'category' => 'international', From ab63bf9d74def7764a66c7942e9410a241892692 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Mon, 12 Jan 2026 09:27:27 +0100 Subject: [PATCH 018/357] gruppen in baum anzeigen und drag and drop von gruppen --- .../controllers/api/frontend/v1/lv/Gruppe.php | 68 +++++++- .../api/frontend/v1/lv/StgTree.php | 146 +++++++++++++++++- .../education/Lehreinheitgruppe_model.php | 47 +++--- public/css/Lvverwaltung.css | 6 + public/js/api/lehrveranstaltung/gruppe.js | 8 + .../LVVerwaltung/Details/Gruppen.js | 66 +++++--- .../components/LVVerwaltung/LVVerwaltung.js | 2 +- .../Stv/Studentenverwaltung/Verband.js | 26 +++- public/js/helpers/DragAndDrop.js | 4 + 9 files changed, 325 insertions(+), 48 deletions(-) diff --git a/application/controllers/api/frontend/v1/lv/Gruppe.php b/application/controllers/api/frontend/v1/lv/Gruppe.php index daebe8a61..f60d3a99a 100644 --- a/application/controllers/api/frontend/v1/lv/Gruppe.php +++ b/application/controllers/api/frontend/v1/lv/Gruppe.php @@ -15,6 +15,7 @@ class Gruppe extends FHCAPI_Controller 'getBenutzerSearch' => ['admin:r', 'assistenz:r'], 'getAllSearch' => ['admin:r', 'assistenz:r'], 'getByLehreinheit' => ['admin:r', 'assistenz:r'], + 'getGruppe' => ['admin:r', 'assistenz:r'], ]); $this->_ci = &get_instance(); @@ -67,7 +68,7 @@ class Gruppe extends FHCAPI_Controller $this->checkPermission($lehreinheit_id); - $result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, !($lehrverband === 'false')); + $result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, $lehrverband === true || $lehrverband === 'true'); if (isError($result)) $this->terminateWithError(getError($result)); @@ -75,6 +76,71 @@ class Gruppe extends FHCAPI_Controller $this->terminateWithSuccess($result); } + public function getGruppe() + { + $lehrverband = $this->input->post('lehrverband'); + + $gruppen_result = array(); + + if ($lehrverband === false) + { + $gruppen_result = $this->_ci->GruppeModel->loadWhere(array( + 'studiengang_kz' => $this->input->post('stg_kz'), + 'gruppe_kurzbz' => $this->input->post('gruppe_kurzbz'), + 'aktiv' => true + )); + } + else if ($lehrverband === true) + { + + if (!isEmptyString($this->input->post('verband'))) + { + $this->LehrverbandModel->db->where('verband', $this->input->post('verband')); + } + else + { + $this->LehrverbandModel->db->group_start(); + $this->LehrverbandModel->db->where("trim(verband) = ''"); + $this->LehrverbandModel->db->or_where("verband IS NULL"); + $this->LehrverbandModel->db->group_end(); + } + + if (!isEmptyString($this->input->post('gruppe'))) + { + $this->LehrverbandModel->db->where('gruppe', $this->input->post('gruppe')); + } + else + { + $this->LehrverbandModel->db->group_start(); + $this->LehrverbandModel->db->where("trim(gruppe) = ''"); + $this->LehrverbandModel->db->or_where("gruppe IS NULL"); + $this->LehrverbandModel->db->group_end(); + } + + if (!isEmptyString((string)$this->input->post('semester'))) + { + $this->LehrverbandModel->db->where('semester', $this->input->post('semester')); + } + else + { + + $this->LehrverbandModel->db->group_start(); + $this->LehrverbandModel->db->where("semester = ''"); + $this->LehrverbandModel->db->or_where("semester IS NULL"); + $this->LehrverbandModel->db->group_end(); + } + + $gruppen_result = $this->LehrverbandModel->loadWhere(array('studiengang_kz' => $this->input->post('stg_kz'), 'aktiv' => true)); + } + + if (!hasData($gruppen_result)) + return $this->terminateWithError('No group found'); + + $gruppen_array = getData($gruppen_result)[0]; + + $this->terminateWithSuccess($gruppen_array->gid); + } + public function getByLehreinheit($lehreinheit_id = null) { if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id)) diff --git a/application/controllers/api/frontend/v1/lv/StgTree.php b/application/controllers/api/frontend/v1/lv/StgTree.php index 8272da978..f36d4030f 100644 --- a/application/controllers/api/frontend/v1/lv/StgTree.php +++ b/application/controllers/api/frontend/v1/lv/StgTree.php @@ -25,7 +25,25 @@ class StgTree extends FHCAPI_Controller return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]); } - return $this->getStudiengang($method); + $count = count($params); + if (!$count) + return $this->getStudiengang($method); + + if ($count == 1) { + if (is_numeric($params[0])) + return $this->getSemester($method, $params[0]); + else + return $this->getStudiengang($method, $params[0]); + } + if ($count == 2) { + if (is_numeric($params[0])) + return $this->getVerband($method, $params[0], $params[1]); + else + return $this->getSemester($method, $params[1], $params[0]); + } + + + show_404(); } @@ -64,16 +82,27 @@ class StgTree extends FHCAPI_Controller $this->terminateWithSuccess($list); } - protected function getStudiengang($studiengang_kz) + protected function getStudiengang($studiengang_kz, $org_form = null) { $link = $studiengang_kz . '/'; + if ($org_form !== null) + $link .= $org_form . '/'; $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); $this->StudiengangModel->addDistinct(); $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false); - $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester ORDER BY verband, gruppe LIMIT 1)) AS name", false); - $this->StudiengangModel->addSelect("TRUE AS leaf", false); + $this->StudiengangModel->addSelect("CONCAT( + UPPER(CONCAT(typ, kurzbz)), + '-', + semester, + ( + SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END + FROM public.tbl_lehrverband + WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester + ORDER BY verband, gruppe LIMIT 1 + ) + ) AS name", false); $this->StudiengangModel->addSelect('semester'); $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); @@ -111,6 +140,115 @@ class StgTree extends FHCAPI_Controller $list = array_merge($list, $result); } } + $this->terminateWithSuccess($list); + } + + protected function getSemester($studiengang_kz, $semester, $org_form = null) + { + $link = $studiengang_kz . '/'; + if ($org_form !== null) + $link .= $org_form . '/'; + $link .= $semester . '/'; + + + $this->load->model('organisation/Gruppe_model', 'GruppeModel'); + + $this->GruppeModel->addDistinct(); + $this->GruppeModel->addSelect("CONCAT(" . $this->GruppeModel->escape($link . 'grp/') . ", gruppe_kurzbz) AS link", false); + $this->GruppeModel->addSelect("CONCAT(gruppe_kurzbz, ' (', bezeichnung, ')') AS name", false); + $this->GruppeModel->addSelect("TRUE AS leaf", false); + + $this->GruppeModel->addSelect('sort'); + $this->GruppeModel->addSelect('gruppe_kurzbz'); + $this->GruppeModel->addSelect($this->GruppeModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->GruppeModel->addOrder('sort'); + $this->GruppeModel->addOrder('gruppe_kurzbz'); + + $where = [ + 'studiengang_kz' => $studiengang_kz, + 'semester' => $semester, + 'lehre' => true, + 'sichtbar' => true, + 'aktiv' => true, + 'direktinskription' => false + ]; + + if ($org_form !== null) + $where['orgform_kurzbz'] = $org_form; + + $result = $this->GruppeModel->loadWhere($where); + + $list = $this->getDataOrTerminateWithError($result); + + $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); + + $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", verband) AS link", false); + $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband ORDER BY gruppe LIMIT 1)) AS name", false); + $this->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf"); + + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($semester) . ' AS semester'); + $this->StudiengangModel->addSelect('verband'); + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->StudiengangModel->addOrder('verband'); + + $this->StudiengangModel->addGroupBy('link, name, verband'); + + $where = [ + 'v.studiengang_kz' => $studiengang_kz, + 'v.semester' => $semester, + 'v.verband !=' => '', + 'v.aktiv' => true + ]; + + if ($org_form !== null && $semester) // NOTE(chris): on semester 0 show all? + $where['v.orgform_kurzbz'] = $org_form; + + $result = $this->StudiengangModel->loadWhere($where); + $result = $this->getDataOrTerminateWithError($result); + + $list = array_merge($list, $result); + + $this->terminateWithSuccess($list); + } + + protected function getVerband($studiengang_kz, $semester, $verband, $org_form = null) + { + $link = $studiengang_kz . '/'; + if ($org_form !== null) + $link .= $org_form . '/'; + $link .= $semester . '/'. $verband . '/'; + + + $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); + + $this->StudiengangModel->addDistinct(); + $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", gruppe) AS link", false); + $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, gruppe, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband AND gruppe=v.gruppe ORDER BY gruppe LIMIT 1)) AS name", false); + $this->StudiengangModel->addSelect("TRUE AS leaf", false); + + $this->StudiengangModel->addSelect('v.semester'); + $this->StudiengangModel->addSelect('v.verband'); + $this->StudiengangModel->addSelect('gruppe'); + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->StudiengangModel->addOrder('gruppe'); + + $where = [ + 'v.studiengang_kz' => $studiengang_kz, + 'v.semester' => $semester, + 'v.verband' => $verband, + 'v.gruppe !=' => '', + 'v.aktiv' => true + ]; + + if ($org_form !== null && $semester) + $where['v.orgform_kurzbz'] = $org_form; + + $result = $this->StudiengangModel->loadWhere($where); + + $list = $this->getDataOrTerminateWithError($result); $this->terminateWithSuccess($list); } diff --git a/application/models/education/Lehreinheitgruppe_model.php b/application/models/education/Lehreinheitgruppe_model.php index dee8bbfe1..139d639cb 100644 --- a/application/models/education/Lehreinheitgruppe_model.php +++ b/application/models/education/Lehreinheitgruppe_model.php @@ -341,7 +341,7 @@ class Lehreinheitgruppe_model extends DB_Model $this->db->where('lehreinheit_id', $lehreinheit_id); $this->db->where('studiengang_kz', $gruppen_array->studiengang_kz); - if (!isEmptyString($gruppen_array->semester)) + if (!isEmptyString((string)$gruppen_array->semester)) { $this->db->where('semester', $gruppen_array->semester); } @@ -444,30 +444,37 @@ class Lehreinheitgruppe_model extends DB_Model ) ELSE tbl_gruppe.beschreibung END AS beschreibung"); - $this->addSelect("CASE - WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN - ( - SELECT EXISTS ( - SELECT 1 - FROM lehre.tbl_stundenplandev - WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id - AND studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz - AND semester = tbl_lehreinheitgruppe.semester - AND TRIM(COALESCE(verband, '')) = TRIM(tbl_lehreinheitgruppe.verband) - AND TRIM(COALESCE(gruppe, '')) = TRIM(tbl_lehreinheitgruppe.gruppe) - AND (gruppe_kurzbz IS NULL OR gruppe_kurzbz = '') - ) - ) - ELSE + $this->addSelect(" + CASE + WHEN trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, '')) = '' THEN ( SELECT EXISTS ( SELECT 1 - FROM lehre.tbl_stundenplandev - WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id - AND gruppe_kurzbz = tbl_lehreinheitgruppe.gruppe_kurzbz + FROM lehre.tbl_stundenplandev sp + WHERE sp.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id + AND sp.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz + AND sp.semester = tbl_lehreinheitgruppe.semester + AND trim(COALESCE(sp.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, '')) + AND trim(COALESCE(sp.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, '')) + AND trim(COALESCE(sp.gruppe_kurzbz, '')) = '' ) ) - END AS verplant"); + ELSE + ( + SELECT EXISTS ( + SELECT 1 + FROM lehre.tbl_stundenplandev sp + WHERE sp.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id + AND sp.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz + AND sp.semester = tbl_lehreinheitgruppe.semester + AND trim(COALESCE(sp.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, '')) + AND trim(COALESCE(sp.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, '')) + AND trim(COALESCE(sp.gruppe_kurzbz, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, '')) + ) + ) + END AS verplant + "); + $this->addJoin('tbl_studiengang', 'studiengang_kz', 'LEFT'); $this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz', 'LEFT'); diff --git a/public/css/Lvverwaltung.css b/public/css/Lvverwaltung.css index 6e0f4c760..b8152d39a 100644 --- a/public/css/Lvverwaltung.css +++ b/public/css/Lvverwaltung.css @@ -38,3 +38,9 @@ textarea[name="anmerkung"] { { border-color: black; } + +.node-verband { + user-select: none; + -webkit-user-select: none; + -moz-user-select: none; +} diff --git a/public/js/api/lehrveranstaltung/gruppe.js b/public/js/api/lehrveranstaltung/gruppe.js index 44340bec7..23db4c069 100644 --- a/public/js/api/lehrveranstaltung/gruppe.js +++ b/public/js/api/lehrveranstaltung/gruppe.js @@ -18,6 +18,14 @@ export default { params: newData }; }, + getGruppe(gruppe) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/gruppe/getGruppe/', + params: gruppe + }; + }, getByLehreinheit(lehreinheit_id) { return { diff --git a/public/js/components/LVVerwaltung/Details/Gruppen.js b/public/js/components/LVVerwaltung/Details/Gruppen.js index 024bf6468..5244136cc 100644 --- a/public/js/components/LVVerwaltung/Details/Gruppen.js +++ b/public/js/components/LVVerwaltung/Details/Gruppen.js @@ -2,6 +2,7 @@ import {CoreFilterCmpt} from "../../filter/Filter.js"; import FormForm from '../../Form/Form.js'; import FormInput from '../../Form/Input.js'; import ApiGruppe from "../../../api/lehrveranstaltung/gruppe.js"; +import drop from '../../../directives/drop.js'; export default{ name: "LVGruppen", components: { @@ -9,6 +10,9 @@ export default{ FormForm, FormInput }, + directives: { + drop + }, props: { lehreinheit_id: Number }, @@ -187,28 +191,48 @@ export default{ this.reload(); }) }, + onDropVerband(node, gruppe) { + this.$api.call(ApiGruppe.getGruppe(gruppe)) + .then(result => result.data) + .then(result => { + + let newData = { + 'gid': result, + 'lehreinheit_id': this.lehreinheit_id, + 'lehrverband': gruppe.lehrverband, + } + this.$api.call(ApiGruppe.add(newData)) + .then(result => { + this.reload() + }) + }); + + }, + }, template: ` - - - - +
+ + + + +
` }; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/LVVerwaltung.js b/public/js/components/LVVerwaltung/LVVerwaltung.js index 42c50bdfa..9a68c3781 100644 --- a/public/js/components/LVVerwaltung/LVVerwaltung.js +++ b/public/js/components/LVVerwaltung/LVVerwaltung.js @@ -285,7 +285,7 @@ export default {
- + diff --git a/public/js/components/Stv/Studentenverwaltung/Verband.js b/public/js/components/Stv/Studentenverwaltung/Verband.js index 1ff9d2ed9..4490901e9 100644 --- a/public/js/components/Stv/Studentenverwaltung/Verband.js +++ b/public/js/components/Stv/Studentenverwaltung/Verband.js @@ -1,5 +1,6 @@ import drop from '../../../directives/drop.js'; import dragClick from '../../../directives/dragClick.js'; +import draggable from '../../../directives/draggable.js'; import ApiStvGroups from '../../../api/factory/stv/group.js'; import ApiStvDetails from '../../../api/factory/stv/details.js'; @@ -11,7 +12,8 @@ export default { }, directives: { drop, - dragClick + dragClick, + draggable }, inject: { $reloadList: { @@ -40,6 +42,10 @@ export default { preselectedKey: { type: String, default: null + }, + dragEnabled: { + type: Boolean, + default: false } }, data() { @@ -79,6 +85,22 @@ export default { } }, methods: { + dragVerband(node) { + const gruppe = node?.data || {}; + + const id = gruppe.gruppe_kurzbz ?? gruppe.link ?? node?.key ?? null; + + return [{ + type: 'verband', + id: id, + gruppe_kurzbz: gruppe.gruppe_kurzbz ?? null, + semester: gruppe.semester ?? null, + verband: gruppe.verband ?? null, + gruppe: gruppe.gruppe ?? null, + lehrverband: gruppe.gruppe_kurzbz == null, + stg_kz: gruppe.stg_kz ?? null, + }]; + }, findNodeByKey(key, arr) { if (!arr) arr = this.nodes; @@ -359,7 +381,9 @@ export default { :data-tree-item-key="node.key" :title="node.data.studiengang_kz" v-drag-click="() => toggleTreeNode(node)" + class="node-verband" v-drop:link-strict.student-collection="(evt, students) => dropStudents(node, students)" + v-draggable:link-strict="dragEnabled && dragVerband(node)" > {{ node.data.name }} diff --git a/public/js/helpers/DragAndDrop.js b/public/js/helpers/DragAndDrop.js index f98697eb2..3eeff0ee2 100644 --- a/public/js/helpers/DragAndDrop.js +++ b/public/js/helpers/DragAndDrop.js @@ -30,6 +30,10 @@ const TYPE_DEFINITION = { prestudent: { id: "prestudent_id", dragIcon: "fa-solid fa-user-graduate text-muted" + }, + verband: { + id: "gruppe_id", + dragIcon: "fa-solid fa-user-group text-muted" } // TODO: IMPLEMENT OTHER TYPES }; From e26387a75a6075ee1c9ab2bc87bb96af52338907 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Mon, 19 Jan 2026 15:08:59 +0100 Subject: [PATCH 019/357] lektoren tausch auch bei verplanten lektoren hinzugefuegt --- .../controllers/api/frontend/v1/lv/Config.php | 86 +++++++ .../controllers/api/frontend/v1/lv/Lektor.php | 3 + application/libraries/LektorLib.php | 240 ++++++++++++------ .../models/ressource/Reservierung_model.php | 11 + .../models/ressource/Stundenplandev_model.php | 11 + .../models/ressource/Zeitsperre_model.php | 36 +++ application/views/LVVerwaltung.php | 2 + public/js/api/lehrveranstaltung/config.js | 15 ++ .../components/LVVerwaltung/LVVerwaltung.js | 57 ++++- .../components/LVVerwaltung/Lektor/Daten.js | 5 +- 10 files changed, 382 insertions(+), 84 deletions(-) create mode 100644 application/controllers/api/frontend/v1/lv/Config.php create mode 100644 public/js/api/lehrveranstaltung/config.js diff --git a/application/controllers/api/frontend/v1/lv/Config.php b/application/controllers/api/frontend/v1/lv/Config.php new file mode 100644 index 000000000..4f39c6b8b --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Config.php @@ -0,0 +1,86 @@ + ['admin:r', 'assistenz:r'], + 'set' => ['admin:r', 'assistenz:r'], + ]); + + $this->_ci = &get_instance(); + $this->_setAuthUID(); + + $this->loadPhrases([ + 'lehre' + ]); + + $this->_ci->load->library('VariableLib', ['uid' => $this->_uid]); + $this->_ci->load->library('PermissionLib'); + + } + + + public function get() + { + if (!($this->permissionlib->isBerechtigt('basis/tempus')) && !($this->permissionlib->isBerechtigt('lv-plan'))) + $this->terminateWithSuccess([]); + + $ignore_kollision = $this->_ci->variablelib->getVar('ignore_kollision'); + $ignore_zeitsperre = $this->_ci->variablelib->getVar('ignore_zeitsperre'); + $ignore_reservierung = $this->_ci->variablelib->getVar('ignore_reservierung'); + + $config['ignore_kollision'] = [ + "type" => "checkbox", + "label" => 'ignore_kollision', + "value" => $ignore_kollision, + ]; + + $config['ignore_zeitsperre'] = [ + "type" => "checkbox", + "label" => 'ignore_zeitsperre', + "value" => $ignore_zeitsperre, + ]; + + $config['ignore_reservierung'] = [ + "type" => "checkbox", + "label" => 'ignore_reservierung', + "value" => $ignore_reservierung, + ]; + + $this->terminateWithSuccess($config); + } + public function set() + { + if (!($this->permissionlib->isBerechtigt('basis/tempus')) && !($this->permissionlib->isBerechtigt('lv-plan'))) + $this->terminateWithSuccess([]); + + $this->load->model('system/Variable_model', 'VariableModel'); + + foreach (['ignore_kollision','ignore_zeitsperre','ignore_reservierung'] as $variable) + { + if ($this->_ci->input->post($variable) !== null) + { + $this->VariableModel->update(array('uid' => $this->_uid, 'name' => $variable), array('wert' => $this->input->post($variable))); + + } + } + + $this->terminateWithSuccess(); + } + + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } +} diff --git a/application/controllers/api/frontend/v1/lv/Lektor.php b/application/controllers/api/frontend/v1/lv/Lektor.php index cce7f6e8b..7db23e75f 100644 --- a/application/controllers/api/frontend/v1/lv/Lektor.php +++ b/application/controllers/api/frontend/v1/lv/Lektor.php @@ -144,6 +144,9 @@ class Lektor extends FHCAPI_Controller if (!$lehreinheit_permission) $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + if (!is_null($this->getLektorVertrag($lehreinheit_id, $mitarbeiter_uid)) && (array_key_exists('mitarbeiter_uid', $formData) && $mitarbeiter_uid !== $formData['mitarbeiter_uid'])) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + $result = $this->_ci->lektorlib->updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $formData); if (isError($result)) $this->terminateWithError(getError($result)); diff --git a/application/libraries/LektorLib.php b/application/libraries/LektorLib.php index bbe630eaf..0e96a1070 100644 --- a/application/libraries/LektorLib.php +++ b/application/libraries/LektorLib.php @@ -17,7 +17,12 @@ class LektorLib $this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); $this->_ci->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->_ci->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel'); + $this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel'); + $this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); + $this->_ci->load->library('PhrasesLib', array('lehre')); + $this->_ci->load->library('VariableLib', ['uid' => getAuthUID()]); } public function addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid) @@ -78,10 +83,13 @@ class LektorLib public function updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $new_data) { + $old_uid = $mitarbeiter_uid; + $new_uid = isset($new_data['mitarbeiter_uid']) ? $new_data['mitarbeiter_uid'] : $mitarbeiter_uid; + $this->_ci->LehreinheitmitarbeiterModel->addSelect('lehre.tbl_lehreinheitmitarbeiter.*, lehre.tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.studiengang_kz'); $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); - $lehreinheit_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + $lehreinheit_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $old_uid)); if (isError($lehreinheit_result)) return $lehreinheit_result; @@ -89,27 +97,47 @@ class LektorLib $lehreinheit = getData($lehreinheit_result)[0]; + $semesterstunden_alt = $lehreinheit->semesterstunden; + $semesterstunden_neu = isset($new_data['semesterstunden']) ? $new_data['semesterstunden'] : $semesterstunden_alt; + $bismelden_neu = isset($new_data['bismelden']) ? $new_data['bismelden'] : $lehreinheit->bismelden; + $neue_stunden_eingerechnet = (bool)$bismelden_neu; + $alte_stunden_eingerechnet = (bool)$lehreinheit->bismelden; + $stundenplan_update = false; - //TODO kollision check, wird vorerst nicht implementiert -> nur über das FAS möglich - if (isset($new_data['mitarbeiter_uid']) && $new_data['mitarbeiter_uid'] !== $mitarbeiter_uid) + if ($old_uid !== $new_uid) { - $this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); - $this->_ci->StundenplandevModel->addGroupBy('stundenplandev_id'); - $this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid'); - $this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid'); - $verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); - - if (hasData($verplant)) - return error($this->_ci->phraseslib->t("lehre", "lektorbereitsverplant")); - - $lehreinheit_data = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $new_data['mitarbeiter_uid'], 'lehreinheit_id' => $lehreinheit_id)); + $lehreinheit_data = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $new_uid, 'lehreinheit_id' => $lehreinheit_id)); if (hasData($lehreinheit_data)) return error($this->_ci->phraseslib->t("lehre", "bereitzugeteilt")); + $this->_ci->StundenplandevModel->addGroupBy('stundenplandev_id'); + $this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid'); + $verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $old_uid)); + + if (hasData($verplant)) + { + $kollision = $this->hasKollision(getData($verplant), $new_uid); + + $ignore_kollision = $this->_ci->variablelib->getVar('ignore_kollision'); + + if ($kollision === false || $ignore_kollision == 'true') + { + $stundenplan_update = true; + } + else if (is_array($kollision)) + { + return error( "Änderung fehlgeschlagen! Die Änderung des Lektors führt zu ".count($kollision)." Kollision(en) im LV-Plan. Deaktivieren Sie die Kollisionspruefung oder wenden Sie sich an die LV-Planung!\n zB. $kollision[0]"); + } + else + { + return error($kollision); + } + } } + $warning = ''; - if (isset($new_data['semesterstunden'])) + if (($semesterstunden_neu !== '' && $semesterstunden_alt !== '') && (($semesterstunden_neu > $semesterstunden_alt) || $neue_stunden_eingerechnet)) { $studiengang_result = $this->_ci->StudiengangModel->loadWhere(array('studiengang_kz' => $lehreinheit->studiengang_kz)); if (isError($studiengang_result)) return $studiengang_result; @@ -120,7 +148,7 @@ class LektorLib if (isError($studiensemester_result)) return $studiensemester_result; $studiensemester = getData($studiensemester_result)[0]; - $echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'echterdv'); + $echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($new_uid, $studiensemester->start, $studiensemester->ende, 'echterdv'); $echter_dv = false; @@ -129,83 +157,78 @@ class LektorLib $echter_dv = true; } - $neue_stunden_eingerechnet = isset($new_data['bismelden']) ? $new_data['bismelden'] : $lehreinheit->bismelden; - $alte_stunden_eingerechnet = $lehreinheit->bismelden; + $stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv); + if (isError($stundengrenze_result)) return $stundengrenze_result; - if (($new_data['semesterstunden'] > $lehreinheit->semesterstunden) || $neue_stunden_eingerechnet) + $stundengrenze = getData($stundengrenze_result)[0]; + + $oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz); + $oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(); + + if ($alte_stunden_eingerechnet && $neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($semesterstunden_alt) + {$this->_ci->LehreinheitmitarbeiterModel->db->escape($semesterstunden_neu)}) as summe"); + else if ($alte_stunden_eingerechnet && !$neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($semesterstunden_alt)) as summe"); + else if (!$alte_stunden_eingerechnet && $neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) + ({$this->_ci->LehreinheitmitarbeiterModel->db->escape($semesterstunden_neu)})) as summe"); + else if (!$alte_stunden_eingerechnet && !$neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden)) as summe"); + + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); + + $this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', $new_uid); + $this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $lehreinheit->studiensemester_kurzbz); + $this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true); + $this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%'); + + if (count($oe_array) > 0) { - $stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv); - if (isError($stundengrenze_result)) return $stundengrenze_result; - - $stundengrenze = getData($stundengrenze_result)[0]; - - $oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz); - $oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(''); - - if ($alte_stunden_eingerechnet && $neue_stunden_eingerechnet) - $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden) + {$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])}) as summe"); - else if ($alte_stunden_eingerechnet && !$neue_stunden_eingerechnet) - $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden)) as summe"); - else if (!$alte_stunden_eingerechnet && $neue_stunden_eingerechnet) - $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) + ({$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])})) as summe"); - else if (!$alte_stunden_eingerechnet && !$neue_stunden_eingerechnet) - $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden)) as summe"); - - $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); - $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); - $this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); - - $this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', (isset($new_data['mitarbeiter_uid']) ? $new_data['mitarbeiter_uid'] : $mitarbeiter_uid)); - $this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $lehreinheit->studiensemester_kurzbz); - $this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true); - $this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%'); - $this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array); + } + if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE') + && is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) + && count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0) + { + $this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE); + } - if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE') - && is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) - && count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0) + $summe_result = $this->_ci->LehreinheitmitarbeiterModel->load(); + + if (isError($summe_result)) return $summe_result; + + if (!hasData($summe_result)) return error('Fehler beim Ermitteln der Gesamtstunden'); + + $summe = getData($summe_result)[0]->summe; + + if ($summe > $stundengrenze->stunden) + { + if (!$echter_dv && (!$this->_ci->permissionlib->isBerechtigt('admin'))) { - $this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE); + if (!$this->LehrauftragAufFirma($new_uid)) + return error("ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden NICHT gespeichert!\n\n"); + } + else + { + $warning .= "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden gespeichert!\n\n"; } - $summe_result = $this->_ci->LehreinheitmitarbeiterModel->load(); + $stunden_limit_result = $this->getStundenInstitut($new_uid, $lehreinheit->studiensemester_kurzbz, $oe_array); - if (isError($summe_result)) return $summe_result; - - if (!hasData($summe_result)) return error('Fehler beim Ermitteln der Gesamtstunden'); - - $summe = getData($summe_result)[0]->summe; - - if ($summe > $stundengrenze->stunden) + if (hasData($stunden_limit_result)) { - - if (!$echter_dv && (!$this->_ci->permissionlib->isBerechtigt('admin'))) + $stunden_limit_array = getData($stunden_limit_result); + foreach ($stunden_limit_array as $stunden_limit) { - if (!$this->LehrauftragAufFirma(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid)) - return error("ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden NICHT gespeichert!\n\n"); - } - else - { - $warning .= "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden gespeichert!\n\n"; - } - - $stunden_limit_result = $this->getStundenInstitut($mitarbeiter_uid, $lehreinheit->studiensemester_kurzbz, $oe_array); - - if (hasData($stunden_limit_result)) - { - $stunden_limit_array = getData($stunden_limit_result); - foreach ($stunden_limit_array as $stunden_limit) - { - $warning .= $stunden_limit->summe . ' Stunden ' . $stunden_limit->bezeichnung . "\n"; - } + $warning .= $stunden_limit->summe . ' Stunden ' . $stunden_limit->bezeichnung . "\n"; } } } } - $benutzer_result = $this->_ci->BenutzerModel->load(array(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid)); + $benutzer_result = $this->_ci->BenutzerModel->load(array($new_uid)); if (isError($benutzer_result)) return $benutzer_result; @@ -240,10 +263,24 @@ class LektorLib $updateData['updatevon'] = getAuthUID(); $updateData['updateamum'] = date('Y-m-d H:i:s'); - $result = $this->_ci->LehreinheitmitarbeiterModel->update(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid), $updateData); + $result = $this->_ci->LehreinheitmitarbeiterModel->update(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $old_uid), $updateData); if (isError($result)) return $result; + if ($stundenplan_update) + { + $update_result = $this->_ci->StundenplandevModel->update([ + 'lehreinheit_id' => $lehreinheit_id, + 'mitarbeiter_uid' => $old_uid, + ], [ + 'mitarbeiter_uid' => $new_uid, + 'updateamum' => date('Y-m-d H:i:s'), + 'updatevon' => getAuthUID() + ]); + + if (isError($update_result)) return $update_result; + } + if ($warning !== '') return success(['warning' => $warning]); return success('Erfolgreich geupdated'); @@ -347,4 +384,53 @@ class LektorLib $this->_ci->LehreinheitmitarbeiterModel->addGroupBy('tbl_studiengang.bezeichnung'); return $this->_ci->LehreinheitmitarbeiterModel->load(); } +//if($rechte->isBerechtigt('lv-plan')) + + private function hasKollision($stunden, $mitarbeiter) + { + $kollision = array(); + + $ignore_zeitsperre = $this->_ci->variablelib->getVar('ignore_zeitsperre'); + $ignore_reservierung = $this->_ci->variablelib->getVar('ignore_reservierung'); + + foreach ($stunden as $stunde) + { + $stundenplan_result = $this->_ci->StundenplandevModel->lektorHasStundenplandevEintrag($mitarbeiter, $stunde->datum, $stunde->stunde); + + if (isError($stundenplan_result)) + return $stundenplan_result; + + if (hasData($stundenplan_result)) + { + $stundenplan_result = getData($stundenplan_result)[0]; + $kollision[] = "Kollision stundenplandev: $stundenplan_result->stundenplandev_id|$stundenplan_result->lektor|$stundenplan_result->ort_kurzbz|$stundenplan_result->stg_kurzbz-$stundenplan_result->semester$stundenplan_result->verband$stundenplan_result->gruppe$stundenplan_result->gruppe_kurzbz - $stundenplan_result->datum/$stundenplan_result->stunde"; + } + else + { + if ($ignore_zeitsperre == 'false' && (!defined('KOLLISIONSFREIE_USER') || !in_array($mitarbeiter, unserialize(KOLLISIONSFREIE_USER)))) + { + $zeitsperre_result = $this->_ci->ZeitsperreModel->checkIfZeitsperreExists($mitarbeiter, $stunde->datum, $stunde->stunde); + + if (hasData($zeitsperre_result)) + { + $zeitsperre_result = getData($zeitsperre_result)[0]; + $kollision[] = "Kollision (Zeitsperre): $zeitsperre_result->zeitsperre_id|$zeitsperre_result->mitarbeiter_uid|$zeitsperre_result->zeitsperretyp_kurzbz - $zeitsperre_result->vondatum/$zeitsperre_result->vonstunde|$zeitsperre_result->bisdatum/$zeitsperre_result->bisstunde"; + } + } + + if ($ignore_reservierung == 'false' && (!defined('KOLLISIONSFREIE_USER') || !in_array($mitarbeiter, unserialize(KOLLISIONSFREIE_USER)))) + { + $reservierung_result = $this->_ci->ReservierungModel->lektorHasReservierung($mitarbeiter, $stunde->datum, $stunde->stunde); + + if (hasData($reservierung_result)) + { + $reservierung_result = getData($reservierung_result)[0]; + $kollision[] = "Kollision (Reservierung): $reservierung_result->reservierung_id|$reservierung_result->uid|$reservierung_result->ort_kurzbz|$reservierung_result->stg_kurzbz-$reservierung_result->semester$reservierung_result->verband$reservierung_result->gruppe$reservierung_result->gruppe_kurzbz - $reservierung_result->datum/$reservierung_result->stunde"; + } + } + } + } + + return isEmptyArray($kollision) ? false : $kollision; + } } diff --git a/application/models/ressource/Reservierung_model.php b/application/models/ressource/Reservierung_model.php index 0c391ea20..8049838eb 100644 --- a/application/models/ressource/Reservierung_model.php +++ b/application/models/ressource/Reservierung_model.php @@ -135,4 +135,15 @@ class Reservierung_model extends DB_Model return $this->execQuery($query, [$uid, $uid]); } + public function lektorHasReservierung($uid, $datum, $stunde) + { + $qry = "SELECT reservierung_id, uid, stg_kurzbz, ort_kurzbz, semester, verband, gruppe, gruppe_kurzbz, datum, stunde + FROM lehre.vw_reservierung + WHERE uid = ? + AND datum = ? + AND stunde = ?"; + + return $this->execReadOnlyQuery($qry, [$uid, $datum, $stunde]); + } + } diff --git a/application/models/ressource/Stundenplandev_model.php b/application/models/ressource/Stundenplandev_model.php index e718ba073..355283b90 100644 --- a/application/models/ressource/Stundenplandev_model.php +++ b/application/models/ressource/Stundenplandev_model.php @@ -241,4 +241,15 @@ class Stundenplandev_model extends DB_Model return $this->delete(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); } + + public function lektorHasStundenplandevEintrag($uid, $datum, $stunde) + { + $qry = "SELECT stundenplandev_id, lektor, stg_kurzbz, ort_kurzbz, semester, verband, gruppe, gruppe_kurzbz, datum, stunde + FROM lehre.vw_stundenplandev + WHERE uid = ? + AND datum = ? + AND stunde = ?"; + + return $this->execReadOnlyQuery($qry, [$uid, $datum, $stunde]); + } } diff --git a/application/models/ressource/Zeitsperre_model.php b/application/models/ressource/Zeitsperre_model.php index 078d29d8b..50ba4cb1d 100644 --- a/application/models/ressource/Zeitsperre_model.php +++ b/application/models/ressource/Zeitsperre_model.php @@ -61,4 +61,40 @@ class Zeitsperre_model extends DB_Model return $this->execQuery($qry); } + + public function checkIfZeitsperreExists($uid, $datum, $stunde) + { + $this->db->select("*"); + + $this->db->where('mitarbeiter_uid', $uid); + $this->db->where('zeitsperretyp_kurzbz !=', 'ZVerfueg'); + + $this->db->group_start(); + + $this->db->where('vondatum <', $datum); + $this->db->or_group_start(); + $this->db->where('vondatum', $datum); + $this->db->group_start(); + $this->db->where('vonstunde <=', $stunde); + $this->db->or_where('vonstunde IS NULL', null, false); + $this->db->group_end(); + $this->db->group_end(); + $this->db->group_end(); + + + $this->db->group_start(); + $this->db->where('bisdatum >', $datum); + $this->db->or_group_start(); + $this->db->where('bisdatum', $datum); + $this->db->group_start(); + $this->db->where('bisstunde >=', $stunde); + $this->db->or_where('bisstunde IS NULL', null, false); + $this->db->group_end(); + + $this->db->group_end(); + $this->db->group_end(); + + return $this->load(); + + } } diff --git a/application/views/LVVerwaltung.php b/application/views/LVVerwaltung.php index 4cebae839..42d4631f1 100644 --- a/application/views/LVVerwaltung.php +++ b/application/views/LVVerwaltung.php @@ -31,6 +31,8 @@ lv-root="" :permissions="" :config="" + avatar-url="" + logout-url="" > diff --git a/public/js/api/lehrveranstaltung/config.js b/public/js/api/lehrveranstaltung/config.js new file mode 100644 index 000000000..40d275145 --- /dev/null +++ b/public/js/api/lehrveranstaltung/config.js @@ -0,0 +1,15 @@ +export default { + get() { + return { + method: 'get', + url: '/api/frontend/v1/lv/config/get' + }; + }, + set(params) { + return { + method: 'post', + url: 'api/frontend/v1/lv/config/set', + params + }; + } +}; diff --git a/public/js/components/LVVerwaltung/LVVerwaltung.js b/public/js/components/LVVerwaltung/LVVerwaltung.js index 42c50bdfa..4854854b9 100644 --- a/public/js/components/LVVerwaltung/LVVerwaltung.js +++ b/public/js/components/LVVerwaltung/LVVerwaltung.js @@ -8,9 +8,10 @@ import LvTabs from "./Setup/Tabs.js"; import ApiDetails from "../../api/lehrveranstaltung/details.js"; import ApiLektor from "../../api/lehrveranstaltung/lektor.js"; -import ApiGruppe from "../../api/lehrveranstaltung/gruppe.js"; import ApiStudiengangTree from "../../api/lehrveranstaltung/studiengangtree.js"; import ApiSearchbar from "../../api/factory/searchbar.js"; +import AppConfig from "../AppConfig.js"; +import ApiLvConfig from "../../api/lehrveranstaltung/config.js"; export default { @@ -23,6 +24,7 @@ export default { StvStudiensemester, LvTable, LvTabs, + AppConfig }, props: { defaultSemester: String, @@ -32,7 +34,9 @@ export default { stg: { type: String, required: false }, semester: { type: [Number, String], required: false, default: null }, studiensemester_kurzbz: { type: String, required: false, default: null }, - emp: { type: String, required: false, default: null } + emp: { type: String, required: false, default: null }, + avatarUrl: String, + logoutUrl: String, }, provide() { @@ -44,7 +48,6 @@ export default { lehreinheitAnmerkungDefault: (this.config.lehreinheitAnmerkungDefault || '').replace(/\\n/g, '\n'), lehreinheitRaumtypDefault: this.config.lehreinheitRaumtypDefault, lehreinheitRaumtypAlternativeDefault: this.config.lehreinheitRaumtypAlternativeDefault, - permissionLehrveranstaltung: this.permissions['lehre/lehrveranstaltung'], permissionGruppenEntfernen: this.permissions['lv-plan/gruppenentfernen'], permissionLektorEntfernen: this.permissions['lv-plan/lektorentfernen'], @@ -72,6 +75,8 @@ export default { }, data() { return { + appconfig:{}, + configEndpoints: ApiLvConfig, selected: [], studiengang: "", filter: {}, @@ -269,6 +274,51 @@ export default { +
@@ -327,5 +377,6 @@ export default {
+ ` }; diff --git a/public/js/components/LVVerwaltung/Lektor/Daten.js b/public/js/components/LVVerwaltung/Lektor/Daten.js index 21e5dc196..0263b236f 100644 --- a/public/js/components/LVVerwaltung/Lektor/Daten.js +++ b/public/js/components/LVVerwaltung/Lektor/Daten.js @@ -140,7 +140,7 @@ export default{ { this.$emit('changedLektor', this.changed.mitarbeiter_uid); } - if (this.changed.semesterstunden || this.changed.stundensatz) + else if (this.changed.semesterstunden || this.changed.stundensatz) { this.$emit('changedCosts'); } @@ -183,9 +183,6 @@ export default{ }, }, - created() { - this.getLektorData() - }, template: `
From bb236796835f4a325b54056621f31990d7b81f3a Mon Sep 17 00:00:00 2001 From: ma0048 Date: Thu, 12 Feb 2026 10:45:32 +0100 Subject: [PATCH 020/357] auskommentierten code entfernt --- application/libraries/LektorLib.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/libraries/LektorLib.php b/application/libraries/LektorLib.php index 0e96a1070..a89ccdf6b 100644 --- a/application/libraries/LektorLib.php +++ b/application/libraries/LektorLib.php @@ -384,7 +384,6 @@ class LektorLib $this->_ci->LehreinheitmitarbeiterModel->addGroupBy('tbl_studiengang.bezeichnung'); return $this->_ci->LehreinheitmitarbeiterModel->load(); } -//if($rechte->isBerechtigt('lv-plan')) private function hasKollision($stunden, $mitarbeiter) { From fc01fa045e75d3438d6a7ee68df1e7303ac40517 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 23 Feb 2026 13:44:33 +0100 Subject: [PATCH 021/357] add and use variable semester_berechnet for using ausbildungssemester in status interessent --- application/controllers/api/frontend/v1/stv/Students.php | 7 +++++++ public/js/components/Stv/Studentenverwaltung/List.js | 6 +++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index acacca052..816ed5b87 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -905,6 +905,13 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('pls.status_kurzbz AS status'); $this->PrestudentModel->addSelect('pls.datum AS status_datum'); $this->PrestudentModel->addSelect('pls.bestaetigtam AS status_bestaetigung'); + $this->PrestudentModel->addSelect(" + CASE + WHEN pls.status_kurzbz = 'Interessent' + THEN pls.ausbildungssemester + ELSE s.semester + END AS semester_berechnet + "); $this->PrestudentModel->addSelect( "(SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat", false diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 045326ae6..3a6de21c7 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -81,7 +81,7 @@ export default { } }, {title:"Geschlecht", field:"geschlecht", headerFilter: "list", headerFilterParams: {values:{'m':'männlich','w':'weiblich','x':'divers','u':'unbekannt'}, listOnEmpty:true, autocomplete:true}}, - {title:"Sem.", field:"semester", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}}, + {title:"Sem.", field:"semester_berechnet", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}}, {title:"Verb.", field:"verband", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}}, {title:"Grp.", field:"gruppe", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}}, {title:"Studiengang", field:"studiengang", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}}, @@ -157,7 +157,7 @@ export default { selectable: true, selectableRangeMode: 'click', index: 'prestudent_id', - persistenceID: 'stv-list' + persistenceID: 'stv-list-20260223_01' }, tabulatorEvents: [ { @@ -263,7 +263,7 @@ export default { ersatzkennzeichen: capitalize(this.$p.t('person/ersatzkennzeichen')), gebdatum: capitalize(this.$p.t('person/geburtsdatum')), geschlecht: capitalize(this.$p.t('person/geschlecht')), - semester: capitalize(this.$p.t('lehre/sem')), + semester_berechnet: capitalize(this.$p.t('lehre/sem')), verband: capitalize(this.$p.t('lehre/verb')), gruppe: capitalize(this.$p.t('lehre/grp')), studiengang: capitalize(this.$p.t('lehre/studiengang')), From c127c0900ec62842c095b046582c83dfcba461d7 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 25 Feb 2026 14:28:41 +0100 Subject: [PATCH 022/357] refactor dropdown for pruefer, add localStorage for formVariables, add multiactions for adding new finalexam --- .../api/frontend/v1/stv/Abschlusspruefung.php | 16 -- .../js/api/factory/stv/abschlusspruefung.js | 7 - public/js/api/stv/abschlusspruefung.js | 3 - .../Abschlusspruefung/Abschlusspruefung.js | 185 +++++++++++++----- 4 files changed, 139 insertions(+), 72 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php b/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php index def4f6502..f77de7021 100644 --- a/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php +++ b/application/controllers/api/frontend/v1/stv/Abschlusspruefung.php @@ -20,7 +20,6 @@ class Abschlusspruefung extends FHCAPI_Controller 'getBeurteilungen' => ['admin:rw', 'assistenz:rw'], 'getAkadGrade' => ['admin:rw', 'assistenz:rw'], 'getMitarbeiter' => ['admin:rw', 'assistenz:rw'], - 'getPruefer' => ['admin:rw', 'assistenz:rw'], 'getTypStudiengang' => ['admin:rw', 'assistenz:rw'], 'checkForExistingExams' => ['admin:rw', 'assistenz:rw'], ]); @@ -242,21 +241,6 @@ class Abschlusspruefung extends FHCAPI_Controller $this->terminateWithSuccess($result ?: []); } - public function getPruefer() - { - $searchString = $this->input->get('searchString') ?? ''; - - $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); - - $result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid'); - - if (isError($result)) { - $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - } - - $this->terminateWithSuccess($result ?: []); - } - public function getNoten() { $this->load->model('education/Note_model', 'NoteModel'); diff --git a/public/js/api/factory/stv/abschlusspruefung.js b/public/js/api/factory/stv/abschlusspruefung.js index dcba61887..7a1a088ea 100644 --- a/public/js/api/factory/stv/abschlusspruefung.js +++ b/public/js/api/factory/stv/abschlusspruefung.js @@ -90,13 +90,6 @@ export default { params: { searchString } }; }, - getPruefer(searchString) { - return { - method: 'get', - url: 'api/frontend/v1/stv/abschlusspruefung/getPruefer', - params: { searchString } - }; - }, getNoten() { return { method: 'get', diff --git a/public/js/api/stv/abschlusspruefung.js b/public/js/api/stv/abschlusspruefung.js index dccc10085..26d9c17ab 100644 --- a/public/js/api/stv/abschlusspruefung.js +++ b/public/js/api/stv/abschlusspruefung.js @@ -35,9 +35,6 @@ export default { getMitarbeiter(searchString){ return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getMitarbeiter/' + searchString); }, - getPruefer(searchString){ - return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getPruefer/' + searchString); - }, getNoten(){ return this.$fhcApi.get('api/frontend/v1/stv/abschlusspruefung/getNoten/'); }, diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js b/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js index d46e1f299..444bf1097 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung/Abschlusspruefung.js @@ -42,6 +42,16 @@ export default { } return this.student.map(e => e.uid); }, + studentNames() { + if (this.student.uid) + { + return [this.student.vorname + ' ' + this.student.nachname]; + } + + const array = this.student.map(e => ' ' + e.vorname + ' ' + e.nachname + '(' + e.uid +')'); + + return array.toString(); + }, studentKzs(){ if (this.student.uid) { @@ -60,7 +70,7 @@ export default { } let retval = this.isBerechtigtDocAndOdt.includes(this.stgInfo.oe_kurzbz); return retval; - } + }, }, props: { student: Object @@ -260,7 +270,6 @@ export default { arrNoten: [], selectedVorsitz: null, filteredMitarbeiter: [], - filteredPersons: [], selectedPruefer1: null, selectedPruefer2: null, selectedPruefer3: null, @@ -300,10 +309,50 @@ export default { .catch(this.$fhcAlert.handleSystemError); }, actionNewAbschlusspruefung() { - this.resetForm(); - this.statusNew = true; - this.$refs.finalexamModal.show(); this.setDefaultFormData(); + this.statusNew = true; + + //prepare local Storage + let STORAGE_KEY = 'finalExamDefaultData'; + const id = '20260224_01'; + const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)) || {}; + + if (stored[id]) { + const data = stored[id]; + + this.formData.pruefungstyp_kurzbz = data.pruefungstyp_kurzbz; + this.formData.datum = data.datum; + this.formData.sponsion = data.sponsion; + this.formData.akadgrad_id = data.akadgrad_id; + + if (data.vorsitz_uid) { + this.selectedVorsitz = { + mitarbeiter_uid: data.vorsitz_uid, + person_id: data.vorsitz_person_id, + label: data.vorsitz_label + }; + } + + if (data.pruefer1_person_id) { + this.selectedPruefer1 = { + person_id: data.pruefer1_person_id, + label: data.pruefer1_label + }; + } + if (data.pruefer2_person_id) { + this.selectedPruefer2 = { + person_id: data.pruefer2_person_id, + label: data.pruefer2_label + }; + } + if (data.pruefer3_person_id) { + this.selectedPruefer3 = { + person_id: data.pruefer3_person_id, + label: data.pruefer3_label + }; + } + } + this.$refs.finalexamModal.show(); }, actionEditAbschlusspruefung(abschlusspruefung_id) { this.resetForm(); @@ -350,6 +399,29 @@ export default { .then(this.deleteAbschlusspruefung) .catch(this.$fhcAlert.handleSystemError); }, + saveOrUpdateLocalStorage(){ + let STORAGE_KEY = 'finalExamDefaultData'; + + const id = '20260224_01'; + const stored = JSON.parse(localStorage.getItem(STORAGE_KEY)) || {}; + + stored[id] = { + pruefungstyp_kurzbz: this.formData.pruefungstyp_kurzbz, + vorsitz_uid: this.selectedVorsitz?.mitarbeiter_uid || null, + vorsitz_person_id: this.selectedVorsitz?.person_id || null, + vorsitz_label: this.selectedVorsitz?.label || null, + pruefer1_person_id: this.selectedPruefer1?.person_id || null, + pruefer1_label: this.selectedPruefer1?.label || null, + pruefer2_person_id: this.selectedPruefer2?.person_id || null, + pruefer2_label: this.selectedPruefer2?.label || null, + pruefer3_person_id: this.selectedPruefer3?.person_id || null, + pruefer3_label: this.selectedPruefer3?.label || null, + akadgrad_id: this.formData.akadgrad_id, + datum: this.formData.datum, + sponsion: this.formData.sponsion + }; + localStorage.setItem(STORAGE_KEY, JSON.stringify(stored)); + }, addNewAbschlusspruefung() { const dataToSend = { uid: this.student.uid, @@ -360,6 +432,8 @@ export default { .call(ApiStvAbschlusspruefung.addNewAbschlusspruefung(dataToSend)) .then(response => { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave')); + //save formData fields in LocalStorage + this.saveOrUpdateLocalStorage(); this.hideModal('finalexamModal'); this.resetForm(); }) @@ -368,6 +442,26 @@ export default { this.reload(); }); }, + async addNewAbschlusspruefungMulti(){ + try { + for (const student of this.studentUids) { + + await this.$refs.formFinalExam.call( + ApiStvAbschlusspruefung.addNewAbschlusspruefung({ + uid: student, + formData: this.formData + }) + ); + } + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave')); + //save formData fields in LocalStorage + this.saveOrUpdateLocalStorage(); + this.hideModal('finalexamModal'); + this.resetForm(); + } catch (error) { + this.$fhcAlert.handleSystemError(error); + } + }, hideModal(modalRef){ this.$refs[modalRef].hide(); }, @@ -389,6 +483,9 @@ export default { id: abschlusspruefung_id, formData: this.formData }; + //uncomment if also save data in local storage for update + //this.saveOrUpdateLocalStorage(); + return this.$refs.formFinalExam .call(ApiStvAbschlusspruefung.updateAbschlusspruefung(dataToSend)) .then(response => { @@ -430,7 +527,6 @@ export default { this.selectedPruefer1 = null; this.selectedPruefer2 = null; this.selectedPruefer3 = null; - }, setDefaultFormData() { @@ -481,33 +577,6 @@ export default { } }); }, - searchPerson(event) { - if (this.abortController.persons) { - this.abortController.persons.abort(); - } - - this.abortController.persons = new AbortController(); - - return this.$api - .call(ApiStvAbschlusspruefung.getPruefer(event.query)) - .then(result => { - this.filteredPersons = []; - for (let person of result.data.retval) { - this.filteredPersons.push( - { - label: this.getPersonLabel( - person.titelpre, - person.nachname, - person.vorname, - person.titelpost, - person.person_uid - ), - person_id: person.person_id - } - ); - } - }); - }, }, created() { this.$api @@ -539,7 +608,7 @@ export default { .catch(this.$fhcAlert.handleSystemError); this.$api - .call(ApiStvAbschlusspruefung.getAkadGrade(this.student.studiengang_kz)) + .call(ApiStvAbschlusspruefung.getAkadGrade(this.stg_kz)) .then(result => { this.arrAkadGrad = result.data; }) @@ -560,7 +629,8 @@ export default {

{{this.$p.t('stv','tab_finalexam')}}

-
+
+

{{$p.t('abschlusspruefung', 'abschluessPruefungAnlegen')}}

{{$p.t('abschlusspruefung', 'abschluessPruefungBearbeiten')}}

+ {{studentNames}} - + {{this.$p.t('global','details')}}

[{{$p.t('ui', 'neu')}}]

+
- +
+ + @@ -735,6 +825,7 @@ export default { @@ -792,6 +883,7 @@ export default { >
-
+

{{$p.t('abschlusspruefung', 'zurBeurteilung')}}

@@ -820,8 +912,9 @@ export default { From 233a6e8b8915173eb59add4a3d2a3741161c1305 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 25 Feb 2026 15:25:36 +0100 Subject: [PATCH 023/357] =?UTF-8?q?lvverwaltung:=20-=20event=20hinzugefueg?= =?UTF-8?q?t=20damit=20tabs=20erweitert=20werden=20k=C3=B6nnen=20-=20beric?= =?UTF-8?q?hte=20hinzugefuegt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/api/frontend/v1/lv/Setup.php | 7 ++ .../statistik/lehrauftragsliste_gst.xls.php | 6 ++ content/statistik/lvplanung.php | 6 ++ .../components/LVVerwaltung/LVVerwaltung.js | 98 ++++++++++++++++- system/phrasesupdate.php | 100 ++++++++++++++++++ 5 files changed, 215 insertions(+), 2 deletions(-) diff --git a/application/controllers/api/frontend/v1/lv/Setup.php b/application/controllers/api/frontend/v1/lv/Setup.php index eea4befa5..2c1c1d842 100644 --- a/application/controllers/api/frontend/v1/lv/Setup.php +++ b/application/controllers/api/frontend/v1/lv/Setup.php @@ -19,6 +19,8 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); +use CI3_Events as Events; + class Setup extends FHCAPI_Controller { private $_ci; @@ -65,6 +67,11 @@ class Setup extends FHCAPI_Controller 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Notiz.js'), 'config' => [] ); + + Events::trigger('lvv_conf_tabs', function & () use (&$tabs) { + return $tabs; + }); + $this->terminateWithSuccess($tabs); } diff --git a/content/statistik/lehrauftragsliste_gst.xls.php b/content/statistik/lehrauftragsliste_gst.xls.php index 990216c09..d44c91e63 100644 --- a/content/statistik/lehrauftragsliste_gst.xls.php +++ b/content/statistik/lehrauftragsliste_gst.xls.php @@ -41,6 +41,12 @@ else $user = get_uid(); loadVariables($user); +if (isset($_GET['studiensemester_kurzbz'])) +{ + if (check_stsem($_GET['studiensemester_kurzbz'])) + $semester_aktuell = $_GET['studiensemester_kurzbz']; +} + //Studiengang laden $studiengang = new studiengang($studiengang_kz); diff --git a/content/statistik/lvplanung.php b/content/statistik/lvplanung.php index b0169dade..fe69e4160 100644 --- a/content/statistik/lvplanung.php +++ b/content/statistik/lvplanung.php @@ -50,6 +50,12 @@ else $user = get_uid(); loadVariables($user); +if (isset($_GET['studiensemester_kurzbz'])) +{ + if (check_stsem($_GET['studiensemester_kurzbz'])) + $semester_aktuell = $_GET['studiensemester_kurzbz']; +} + $rechte = new benutzerberechtigung(); $rechte->getBerechtigungen($user); diff --git a/public/js/components/LVVerwaltung/LVVerwaltung.js b/public/js/components/LVVerwaltung/LVVerwaltung.js index 42c50bdfa..8b688cdb3 100644 --- a/public/js/components/LVVerwaltung/LVVerwaltung.js +++ b/public/js/components/LVVerwaltung/LVVerwaltung.js @@ -8,7 +8,6 @@ import LvTabs from "./Setup/Tabs.js"; import ApiDetails from "../../api/lehrveranstaltung/details.js"; import ApiLektor from "../../api/lehrveranstaltung/lektor.js"; -import ApiGruppe from "../../api/lehrveranstaltung/gruppe.js"; import ApiStudiengangTree from "../../api/lehrveranstaltung/studiengangtree.js"; import ApiSearchbar from "../../api/factory/searchbar.js"; @@ -205,6 +204,21 @@ export default { this.$router.push({ name: routeName, params: newParams }); this.selected = []; }, + isDisabled(item) + { + if (!item?.requires?.length) + return false; + + const values = { + stg: this.stg, + emp: this.emp, + studiensemester: this.selectedStudiensemester, + semester: this.semester + }; + + return item.requires.some(req => !values[req]); + + } }, created() { this.$p.loadCategory(['lehre', 'person', 'global']) @@ -239,6 +253,62 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); }, + computed: + { + appMenuExtraItems() + { + let extraItems = []; + + const studiengang_kz = this.stg || ''; + const studiensemester = this.selectedStudiensemester; + const semester = this.semester || ''; + const uid = this.emp || ''; + + extraItems.push({ + link: FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'content/statistik/lvplanung.xls.php' + + '?studiengang_kz=' + studiengang_kz + + '&studiensemester_kurzbz=' + studiensemester + + '&semester=' + semester, + description: 'lehre/lvplanung', + requires: ['stg'] + }); + + extraItems.push({ + link: FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'content/statistik/lehrauftragsliste_gst.xls.php' + + '?studiengang_kz=' + studiengang_kz + + '&studiensemester_kurzbz=' + studiensemester + + '&semester=' + semester, + description: 'lehre/lehrauftragsliste', + requires: ['stg'] + }); + + extraItems.push({ + link: FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'content/pdfExport.php?xml=lehrauftrag.xml.php' + + '&xsl=Lehrauftrag' + + '&stg_kz=' + studiengang_kz + + '&ss=' + studiensemester, + description: 'lehre/lehrauftraege', + requires: ['stg'] + }); + + extraItems.push({ + link: FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'content/pdfExport.php?xml=lehrauftrag.xml.php' + + '&xsl=Lehrauftrag' + + '&stg_kz=' + studiengang_kz + + '&ss=' + studiensemester + + '&uid=' + uid, + description: 'lehre/lehrauftragslisteemp', + requires: ['emp'] + }); + + return extraItems; + + } + }, template: /* html */`
@@ -278,7 +348,31 @@ export default {
diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index b09a24a6f..f24efcebc 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -48901,7 +48901,7 @@ array( 'description' => '', 'insertvon' => 'system' ), - array(w + array( 'sprache' => 'English', 'text' => 'Teaching Assignments', 'description' => '', @@ -48949,6 +48949,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'extrakvverwaltung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrveranstaltung Verwaltung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Course Management', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), // feature-55614 end array( 'app' => 'softwarebereitstellung', From d1af44bcdc8bf7df2afbe87c6b3098b2ea439184 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Thu, 5 Mar 2026 17:33:18 +0100 Subject: [PATCH 025/357] dbupdate entry; WIP table altering statements for lehre.tbl_projektarbeit --- system/dbupdate_3.4.php | 1 + .../75469_le_optional_4_projektarbeit.php | 48 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 4ddb38203..eafd73604 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -92,6 +92,7 @@ require_once('dbupdate_3.4/68744_StV_settings.php'); require_once('dbupdate_3.4/62889_reihungstest_ueberwachung_mit_constructor.php'); require_once('dbupdate_3.4/71399_dashboard_update_widget_paths.php'); require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php'); +require_once('dbupdate_3.4/75469_le_optional_4_projektarbeit.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php b/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php new file mode 100644 index 000000000..6ad783e2f --- /dev/null +++ b/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php @@ -0,0 +1,48 @@ +db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = 'lehrveranstaltung_id'")) +{ + if($db->db_num_rows($result) === 0) + { + + $qry = "ALTER TABLE lehre.tbl_projektarbeit + ADD COLUMN IF NOT EXISTS lehrveranstaltung_id INTEGER;"; + + if(!$db->db_query($qry)) + echo 'lehre.tbl_projektarbeit: '.$db->db_last_error().'
'; + else + echo '
tbl_projektarbeit column lehrveranstaltung_id hinzugefuegt'; + } +} + +// TODO: check for and add fk constraint lehrveranstaltung_id +//if($result = $db->db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = 'lehrveranstaltung_id'")) +//{ +// if($db->db_num_rows($result) === 0) +// { +// +// $qry = "ALTER TABLE lehre.tbl_projektarbeit +// ADD COLUMN IF NOT EXISTS lehrveranstaltung_id INTEGER;"; +// +// if(!$db->db_query($qry)) +// echo 'lehre.tbl_projektarbeit: '.$db->db_last_error().'
'; +// else +// echo '
tbl_projektarbeit column lehrveranstaltung_id hinzugefuegt'; +// } +//} + +if($result = $db->db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = 'studiensemester_kurzbz'")) +{ + if($db->db_num_rows($result) === 0) + { + + $qry = "ALTER TABLE lehre.tbl_projektarbeit + ADD COLUMN IF NOT EXISTS lehrveranstaltung_id INTEGER;"; + + if(!$db->db_query($qry)) + echo 'lehre.tbl_projektarbeit: '.$db->db_last_error().'
'; + else + echo '
tbl_projektarbeit column lehrveranstaltung_id hinzugefuegt'; + } +} \ No newline at end of file From daf332a10283e00282a41f8fb3c29cf72af4626f Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Fri, 6 Mar 2026 10:39:37 +0100 Subject: [PATCH 026/357] add query_studiensemester_kurzbz to result of fetchStudents, fetchPrestudents and search --- application/controllers/api/frontend/v1/stv/Students.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index acacca052..53137a472 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -468,6 +468,8 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect("'' AS verband"); $this->PrestudentModel->addSelect("'' AS gruppe"); $this->addSelectPrioRel(); + $query_studiensemester_kurzbz = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : '\'NULL\''; + $this->PrestudentModel->addSelect($query_studiensemester_kurzbz . ' as query_studiensemester_kurzbz'); $this->addFilter($studiensemester_kurzbz); @@ -588,6 +590,7 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); $this->PrestudentModel->addSelect("'' AS priorisierung_relativ"); + $this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz'); $where = []; @@ -798,6 +801,7 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false); $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); + $this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz'); //add status per semester $this->PrestudentModel->addSelect( From 9b4fa132dc1fde8fe57fc7b9971f5a4e0f1abb53 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 6 Mar 2026 10:58:54 +0100 Subject: [PATCH 027/357] add status --- public/js/components/Stv/Studentenverwaltung.js | 3 ++- .../js/components/Stv/Studentenverwaltung/List.js | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index cfd229fb0..a7d97d4fc 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -208,6 +208,7 @@ export default { 'url_studiengang': function (newVal, oldVal) { if (newVal !== oldVal) { this.checkUrlStudiengang(); + this.$refs.stvList.clearSelection(); } }, 'url_mode': function () { @@ -420,7 +421,7 @@ export default { this.$refs.searchbar.$refs.input.blur(); this.$refs.searchbar.abort(); this.$refs.searchbar.hideresult(); - } + }, }, created() { if (!this.url_studiensemester_kurzbz) { diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 045326ae6..af893f7de 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -324,10 +324,13 @@ export default { actionNewPrestudent() { this.$refs.new.open(); }, - rowSelectionChanged(data, rows) { + rowSelectionChanged(data, rows, selected, deselected) { this.selectedcount = data.length; - this.lastSelected = this.selected; - this.$emit('update:selected', data); + + if(selected.length > 0 || deselected.length > 0){ + this.lastSelected = this.selected; + this.$emit('update:selected', data); + } // set selected elements draggable const tableEl = this.$refs.table?.$refs?.table; @@ -471,6 +474,10 @@ export default { if (el != this.focusObj) this.changeFocus(this.focusObj, el); } + }, + clearSelection(){ + this.lastSelected = []; + this.$emit('update:selected',[]); } }, // TODO(chris): focusin, focusout, keydown and tabindex should be in the filter component From 8ccb9cd892e62eb9f90b4adb1aa27330712bebee Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Fri, 6 Mar 2026 11:47:09 +0100 Subject: [PATCH 028/357] db migrate skript from le_id -> lva_id & stsem_kurzbz via existing references --- .../75469_le_optional_4_projektarbeit.php | 100 ++++++++++++------ 1 file changed, 66 insertions(+), 34 deletions(-) diff --git a/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php b/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php index 6ad783e2f..939b1ea7e 100644 --- a/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php +++ b/system/dbupdate_3.4/75469_le_optional_4_projektarbeit.php @@ -1,48 +1,80 @@ db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = 'lehrveranstaltung_id'")) -{ - if($db->db_num_rows($result) === 0) - { +$cols_to_add = [ + 'lehrveranstaltung_id' => "INTEGER", + 'studiensemester_kurzbz' => "INTEGER" +]; - $qry = "ALTER TABLE lehre.tbl_projektarbeit - ADD COLUMN IF NOT EXISTS lehrveranstaltung_id INTEGER;"; +foreach ($cols_to_add as $col => $type) { + $check = "SELECT 1 FROM information_schema.columns + WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = '$col'"; - if(!$db->db_query($qry)) - echo 'lehre.tbl_projektarbeit: '.$db->db_last_error().'
'; - else - echo '
tbl_projektarbeit column lehrveranstaltung_id hinzugefuegt'; + if ($result = $db->db_query($check)) { + if ($db->db_num_rows($result) === 0) { + $qry = "ALTER TABLE lehre.tbl_projektarbeit ADD COLUMN IF NOT EXISTS $col $type;"; + if ($db->db_query($qry)) { + echo "
Column $col hinzugefuegt."; + } else { + echo "Error adding $col: ".$db->db_last_error()."
"; + } + } } } -// TODO: check for and add fk constraint lehrveranstaltung_id -//if($result = $db->db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = 'lehrveranstaltung_id'")) -//{ -// if($db->db_num_rows($result) === 0) -// { -// -// $qry = "ALTER TABLE lehre.tbl_projektarbeit -// ADD COLUMN IF NOT EXISTS lehrveranstaltung_id INTEGER;"; -// -// if(!$db->db_query($qry)) -// echo 'lehre.tbl_projektarbeit: '.$db->db_last_error().'
'; -// else -// echo '
tbl_projektarbeit column lehrveranstaltung_id hinzugefuegt'; -// } -//} +// retrieve lehrveranstaltung_id & studiensemester_kurzbz from tbl_lehreinheit +// into new columns based on the existing reference +$migration_qry = "UPDATE lehre.tbl_projektarbeit p + SET lehrveranstaltung_id = l.lehrveranstaltung_id, + studiensemester_kurzbz = l.studiensemester_kurzbz + FROM lehre.tbl_lehreinheit l + WHERE p.lehreinheit_id = l.lehreinheit_id + AND (p.lehrveranstaltung_id IS NULL OR p.studiensemester_kurzbz IS NULL);"; -if($result = $db->db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_projektarbeit' AND column_name = 'studiensemester_kurzbz'")) -{ - if($db->db_num_rows($result) === 0) - { +if ($db->db_query($migration_qry)) { + echo "
Datenmigration von lehreinheit_id zu lehrveranstaltung_id & studiensemester_kurzbz abgeschlossen."; +} else { + echo "Migration Error: ".$db->db_last_error()."
"; +} +// set NOT NULL and make lehreinheit_id NULLable +$constraint_qry = "ALTER TABLE lehre.tbl_projektarbeit + ALTER COLUMN lehrveranstaltung_id SET NOT NULL, + ALTER COLUMN studiensemester_kurzbz SET NOT NULL, + ALTER COLUMN lehreinheit_id DROP NOT NULL;"; + +if ($db->db_query($constraint_qry)) { + echo "
Constraints updated lehrveranstaltung_id SET NOT NULL, studiensemester_kurzbz SET NOT NULL, lehreinheit_id DROP NOT NULL."; +} else { + echo "Alter Constraints Error: ".$db->db_last_error()."
"; +} + +// add fkey for lehrveranstaltung_id +$fk_check_lv = "SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'fk_projektarbeit_lehrveranstaltung_id' AND table_schema = 'lehre'"; + +if ($result = $db->db_query($fk_check_lv)) { + if ($db->db_num_rows($result) === 0) { $qry = "ALTER TABLE lehre.tbl_projektarbeit - ADD COLUMN IF NOT EXISTS lehrveranstaltung_id INTEGER;"; + ADD CONSTRAINT fk_projektarbeit_lehrveranstaltung_id + FOREIGN KEY (lehrveranstaltung_id) + REFERENCES lehre.tbl_lehrveranstaltung (lehrveranstaltung_id) + ON DELETE RESTRICT;"; + if ($db->db_query($qry)) echo '
fk_projektarbeit_lehrveranstaltung_id hinzugefuegt'; + } +} - if(!$db->db_query($qry)) - echo 'lehre.tbl_projektarbeit: '.$db->db_last_error().'
'; - else - echo '
tbl_projektarbeit column lehrveranstaltung_id hinzugefuegt'; +// add fkey for studiensemester_kurzbz +$fk_check_sem = "SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'fk_projektarbeit_studiensemester_kurzbz' AND table_schema = 'lehre'"; + +if ($result = $db->db_query($fk_check_sem)) { + if ($db->db_num_rows($result) === 0) { + $qry = "ALTER TABLE lehre.tbl_projektarbeit + ADD CONSTRAINT fk_projektarbeit_studiensemester_kurzbz + FOREIGN KEY (studiensemester_kurzbz) + REFERENCES public.tbl_studiensemester (studiensemester_kurzbz) + ON DELETE RESTRICT;"; + if ($db->db_query($qry)) echo '
fk_projektarbeit_studiensemester_kurzbz hinzugefuegt'; } } \ No newline at end of file From fce5ee7a16e6ada02a93cec579e3c9c7addc5ea2 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Mon, 9 Mar 2026 11:24:17 +0100 Subject: [PATCH 029/357] adjust abgabetool queries lehreinheit -> lehrveranstaltung table; always redraw with scrollX/Y preserve in abgabetool --- .../models/education/Paabgabe_model.php | 15 +++---- .../models/education/Projektarbeit_model.php | 32 +++++++------- .../Cis/Abgabetool/AbgabetoolAssistenz.js | 42 +++++++++---------- .../Cis/Abgabetool/AbgabetoolMitarbeiter.js | 31 +++++++++----- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index be42b7660..63fbb3304 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -50,8 +50,7 @@ class Paabgabe_model extends DB_Model JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id) JOIN public.tbl_benutzer bn_student ON(tbl_projektarbeit.student_uid=bn_student.uid) JOIN public.tbl_person person_student ON(bn_student.person_id=person_student.person_id) - JOIN lehre.tbl_lehreinheit ON(tbl_projektarbeit.lehreinheit_id=tbl_lehreinheit.lehreinheit_id) - JOIN lehre.tbl_lehrveranstaltung ON(tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id) + JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) JOIN public.tbl_studiengang ON(tbl_lehrveranstaltung.studiengang_kz=tbl_studiengang.studiengang_kz) JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz) WHERE @@ -68,14 +67,13 @@ class Paabgabe_model extends DB_Model campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum, campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel, UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz, - public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz, + public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_projektarbeit.studiensemester_kurzbz, public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost FROM campus.tbl_paabgabe JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz) JOIN lehre.tbl_projektarbeit USING (projektarbeit_id) - JOIN lehre.tbl_lehreinheit using(lehreinheit_id) - JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) - JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz) + JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN public.tbl_studiengang ON(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz) JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid) JOIN public.tbl_person USING (person_id) @@ -93,7 +91,7 @@ class Paabgabe_model extends DB_Model campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum, campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel, UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz, - public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz, + public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_projektarbeit.studiensemester_kurzbz, lehre.tbl_projektbetreuer.betreuerart_kurzbz, lehre.tbl_projektbetreuer.person_id, public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost @@ -101,8 +99,7 @@ class Paabgabe_model extends DB_Model JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz) JOIN lehre.tbl_projektarbeit USING (projektarbeit_id) JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) - JOIN lehre.tbl_lehreinheit using(lehreinheit_id) - JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) + JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz) JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid) JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index 3b1ea55e5..1c46ca0c6 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -25,7 +25,7 @@ class Projektarbeit_model extends DB_Model { $qry = "SELECT pa.*, tbl_projekttyp.bezeichnung, - tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id, + tbl_projektarbeit.studiensemester_kurzbz, tbl_projektarbeit.lehrveranstaltung_id, tbl_firma.name AS firma_name, ( SELECT @@ -41,7 +41,6 @@ class Projektarbeit_model extends DB_Model FROM lehre.tbl_projektarbeit pa JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) - JOIN lehre.tbl_lehreinheit USING (lehreinheit_id) JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) LEFT JOIN public.tbl_firma USING (firma_id) WHERE @@ -57,7 +56,7 @@ class Projektarbeit_model extends DB_Model if (isset($studiensemester_kurzbz)) { - $qry .= ' AND tbl_lehreinheit.studiensemester_kurzbz=?'; + $qry .= ' AND tbl_projektarbeit.studiensemester_kurzbz=?'; $params[] = $studiensemester_kurzbz; } @@ -134,7 +133,7 @@ class Projektarbeit_model extends DB_Model projektarbeit_id, lehre.tbl_projekttyp.bezeichnung as projekttypbezeichnung, lehre.tbl_projekttyp.projekttyp_kurzbz as projekttypkurzbz, - lehre.tbl_lehreinheit.studiensemester_kurzbz, + lehre.tbl_projektarbeit.studiensemester_kurzbz, lehre.tbl_lehrveranstaltung.studiengang_kz, public.tbl_studiengang.kurzbzlang, lehre.tbl_projektarbeit.note as note, @@ -157,7 +156,6 @@ class Projektarbeit_model extends DB_Model LEFT JOIN public.tbl_benutzer USING(person_id) LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) LEFT JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz) - LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) LEFT JOIN public.tbl_mitarbeiter ON(public.tbl_mitarbeiter.mitarbeiter_uid = public.tbl_benutzer.uid) LEFT JOIN public.tbl_studiengang USING(studiengang_kz) @@ -294,23 +292,22 @@ class Projektarbeit_model extends DB_Model * Get a List of Projektarbeiten of a mitarbeiter with zuordnung * used by the mitarbeiter cis4 abgabetool. */ - public function getMitarbeiterProjektarbeiten($uid, $showAll){ + public function getMitarbeiterProjektarbeiten($uid, $showAll) { $qry = "SELECT * FROM (SELECT tbl_person.vorname, tbl_person.nachname, tbl_studiengang.typ, tbl_studiengang.kurzbz, tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note, tbl_projektbetreuer.person_id as betreuer_person_id, tbl_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung, - tbl_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid + tbl_benutzer.uid, tbl_student.matrikelnr, tbl_projektarbeit.studiensemester_kurzbz, public.tbl_student.student_uid FROM lehre.tbl_projektarbeit - LEFT JOIN lehre.tbl_projektbetreuer using(projektarbeit_id) - LEFT JOIN lehre.tbl_betreuerart using(betreuerart_kurzbz) - LEFT JOIN public.tbl_benutzer on(uid=student_uid) - LEFT JOIN public.tbl_student on(public.tbl_benutzer.uid=public.tbl_student.student_uid) - LEFT JOIN public.tbl_person on(tbl_benutzer.person_id=tbl_person.person_id) - LEFT JOIN lehre.tbl_lehreinheit using(lehreinheit_id) - LEFT JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) - LEFT JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz=public.tbl_studiengang.studiengang_kz) + LEFT JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id) + LEFT JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz) + LEFT JOIN public.tbl_benutzer ON(uid=student_uid) + LEFT JOIN public.tbl_student ON(public.tbl_benutzer.uid=public.tbl_student.student_uid) + LEFT JOIN public.tbl_person ON(tbl_benutzer.person_id=tbl_person.person_id) + LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + LEFT JOIN public.tbl_studiengang ON(lehre.tbl_lehrveranstaltung.studiengang_kz=public.tbl_studiengang.studiengang_kz) LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) WHERE (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom') AND tbl_projektbetreuer.person_id IN (SELECT person_id FROM public.tbl_benutzer @@ -352,7 +349,7 @@ class Projektarbeit_model extends DB_Model student_benutzer.uid as student_uid, student_person.vorname as student_vorname, student_person.nachname as student_nachname, - tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, + tbl_student.matrikelnr, tbl_projektarbeit.studiensemester_kurzbz, betreuer_benutzer.uid as betreuer_benutzer_uid, betreuer_person.titelpre as betreuer_titelpre, betreuer_person.vorname as betreuer_vorname, @@ -483,8 +480,7 @@ class Projektarbeit_model extends DB_Model LEFT JOIN public.tbl_benutzer student_benutzer ON (student_benutzer.uid = lehre.tbl_projektarbeit.student_uid) LEFT JOIN public.tbl_person student_person ON (student_benutzer.person_id = student_person.person_id) LEFT JOIN public.tbl_student on(student_benutzer.uid = public.tbl_student.student_uid) - LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id) - LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) + LEFT JOIN lehre.tbl_lehrveranstaltung ON (lehrveranstaltung_id) LEFT JOIN public.tbl_studiengang ON (public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz) LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) LEFT JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index d5caf97a6..66e932d28 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -247,9 +247,23 @@ export const AbgabetoolAssistenz = { ]}; }, methods: { + redrawTableScrollSave() { + const table = this.$refs.abgabeTable.tabulator; + const scrollX = table.rowManager.scrollLeft; + const scrollY = table.rowManager.scrollTop; + this.$refs.abgabeTable.tabulator.redraw(true) + + Vue.nextTick(()=> { + const tableholder = this.$refs.abgabeTable?.tabulator.element.querySelector('.tabulator-tableholder') + if(tableholder) { + tableholder.scrollLeft = scrollX; + tableholder.scrollTop = scrollY; + } + }) + }, handlePaUpdated(projektarbeit) { this.checkAbgabetermineProjektarbeit(projektarbeit) - this.$refs.abgabeTable.tabulator.redraw(true) + this.redrawTableScrollSave() }, getQGateStatusList() { return [ @@ -736,24 +750,9 @@ export const AbgabetoolAssistenz = { pa.abgabetermine.sort((a, b) => new Date(a.datum) - new Date(b.datum)) }) - // reset selection to empty - // this.$refs.abgabeTable.tabulator.deselectRow() - const table = this.$refs.abgabeTable.tabulator; - const scrollX = table.rowManager.scrollLeft; - const scrollY = table.rowManager.scrollTop; - - const mappedData = this.mapProjekteToTableData(this.projektarbeiten) + this.projektarbeiten = this.mapProjekteToTableData(this.projektarbeiten) - table.setData(mappedData) - table.redraw(true) - - Vue.nextTick(()=> { - const table = this.$refs.abgabeTable?.tabulator.element.querySelector('.tabulator-tableholder') - if(table) { - table.scrollLeft = scrollX; - table.scrollTop = scrollY; - } - }) + this.redrawTableScrollSave() }).finally(()=>{ this.saving = false @@ -977,14 +976,13 @@ export const AbgabetoolAssistenz = { return projekt.zweitbetreuer_full_name ?? '' }, async setupData(data){ - this.projektarbeiten = data[0] this.domain = data[1] - - this.tableData = this.mapProjekteToTableData(this.projektarbeiten) + + this.projektarbeiten = this.mapProjekteToTableData(data[0]) await this.tableBuiltPromise - this.$refs.abgabeTable.tabulator.setData(this.tableData); + this.$refs.abgabeTable.tabulator.setData(this.projektarbeiten); }, loadProjektarbeiten(all = false, callback) { this.loading = true diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js index ee1d18942..e84ff90e3 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js @@ -43,7 +43,6 @@ export const AbgabetoolMitarbeiter = { }, data() { return { - tableData: null, abgabetypenBetreuer: null, detailIsFullscreen: false, phrasenPromise: null, @@ -205,9 +204,23 @@ export const AbgabetoolMitarbeiter = { ]}; }, methods: { + redrawTableScrollSave() { + const table = this.$refs.abgabeTable.tabulator; + const scrollX = table.rowManager.scrollLeft; + const scrollY = table.rowManager.scrollTop; + this.$refs.abgabeTable.tabulator.redraw(true) + + Vue.nextTick(()=> { + const tableholder = this.$refs.abgabeTable?.tabulator.element.querySelector('.tabulator-tableholder') + if(tableholder) { + tableholder.scrollLeft = scrollX; + tableholder.scrollTop = scrollY; + } + }) + }, handlePaUpdated(projektarbeit) { this.checkAbgabetermineProjektarbeit(projektarbeit) - this.$refs.abgabeTable.tabulator.redraw(true) + this.redrawTableScrollSave() }, sammelMailStudent(param) { @@ -601,8 +614,7 @@ export const AbgabetoolMitarbeiter = { this.showAll = showall this.loading = true this.loadProjektarbeiten(showall, () => { - this.$refs.abgabeTable?.tabulator.redraw(true) - this.$refs.abgabeTable?.tabulator.setSort([]); + this.redrawTableScrollSave() this.loading = false }) }, @@ -627,8 +639,7 @@ export const AbgabetoolMitarbeiter = { const oldScrollTop = this.$refs.abgabeTable?.tabulator.rowManager.scrollTop this.loading = true this.loadProjektarbeiten(this.showAll, () => { - this.$refs.abgabeTable?.tabulator.redraw(true) - this.$refs.abgabeTable?.tabulator.setSort([]); + this.redrawTableScrollSave() this.loading = false Vue.nextTick(()=> { @@ -762,11 +773,9 @@ export const AbgabetoolMitarbeiter = { }, setupData(data){ - - this.projektarbeiten = data[0] this.domain = data[1] - - this.tableData = data[0]?.retval?.map(projekt => { + + this.projektarbeiten = data[0]?.retval?.map(projekt => { this.checkAbgabetermineProjektarbeit(projekt) projekt.selectable = projekt.betreuerart_kurzbz !== 'Zweitbegutachter' @@ -787,7 +796,7 @@ export const AbgabetoolMitarbeiter = { }) this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns) - this.$refs.abgabeTable.tabulator.setData(this.tableData); + this.$refs.abgabeTable.tabulator.setData(this.projektarbeiten); }, loadProjektarbeiten(all = false, callback) { this.$api.call(ApiAbgabe.getMitarbeiterProjektarbeiten(all)) From 2237e9f1b72f16e63f0d65da13e910272eb280be Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 9 Mar 2026 11:42:24 +0100 Subject: [PATCH 030/357] refactor detail Header, relaod array if semester changed, show no status if no status, phrase --- .../frontend/v1/detailheader/DetailHeader.php | 30 +++++++++++++ public/js/api/factory/detailHeader.js | 6 +++ .../components/DetailHeader/DetailHeader.js | 44 ++++++++++++++++--- .../js/components/Stv/Studentenverwaltung.js | 8 +++- .../Stv/Studentenverwaltung/Details.js | 29 +++++++++++- system/phrasesupdate.php | 20 +++++++++ 6 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 application/controllers/api/frontend/v1/detailheader/DetailHeader.php diff --git a/application/controllers/api/frontend/v1/detailheader/DetailHeader.php b/application/controllers/api/frontend/v1/detailheader/DetailHeader.php new file mode 100644 index 000000000..be9fad27a --- /dev/null +++ b/application/controllers/api/frontend/v1/detailheader/DetailHeader.php @@ -0,0 +1,30 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getSemesterStati($prestudent_id) + { + $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + + $result = $this->PrestudentstatusModel->getAllPrestudentstatiWithStudiensemester($prestudent_id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + +} diff --git a/public/js/api/factory/detailHeader.js b/public/js/api/factory/detailHeader.js index 74563bd4b..9e50e8ebb 100644 --- a/public/js/api/factory/detailHeader.js +++ b/public/js/api/factory/detailHeader.js @@ -34,4 +34,10 @@ export default { url: 'api/frontend/v1/vertraege/vertraege/getLeitungOrg/' + oekurzbz, }; }, + getSemesterStati(prestudent_id){ + return { + method: 'get', + url: 'api/frontend/v1/detailheader/DetailHeader/getSemesterStati/' + prestudent_id, + }; + }, } \ No newline at end of file diff --git a/public/js/components/DetailHeader/DetailHeader.js b/public/js/components/DetailHeader/DetailHeader.js index 04c6d1835..f0db9fe5d 100644 --- a/public/js/components/DetailHeader/DetailHeader.js +++ b/public/js/components/DetailHeader/DetailHeader.js @@ -7,6 +7,9 @@ export default { from: 'configDomain', default: 'technikum-wien.at' }, + currentSemester: { + from: 'currentSemester', + }, }, props: { headerData: { @@ -51,6 +54,10 @@ export default { console.error("Error loading department data:", error); }); } + + if(this.headerData){ + this.getSemesterStati(this.headerData[0].prestudent_id); + } }, watch: { person_id: { @@ -65,12 +72,27 @@ export default { }, deep: true, }, + currentSemester: { + handler(newVal) { + if (newVal) { + if(!this.semesterStati.some(item => item.studiensemester_kurzbz === this.currentSemester)) { + this.noCurrentStatus = true; + } + else + { + this.noCurrentStatus = false; + } + } + }, + deep: true, + }, }, data(){ return{ headerDataMa: {}, departmentData: {}, leitungData: {}, + noCurrentStatus: false }; }, methods: { @@ -109,6 +131,14 @@ export default { } else { return 'data:image/jpeg;base64,' + foto; } + }, + getSemesterStati(prestudent_id){ + return this.$api + .call(ApiDetailHeader.getSemesterStati(prestudent_id)) + .then(result => { + this.semesterStati = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); } }, template: ` @@ -149,11 +179,11 @@ export default { {{headerData[0].person_id}} | {{$p.t('lehre', 'studiengang')}} {{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}}) - | {{$p.t('lehre', 'semester')}} + | {{$p.t('lehre', 'semester')}} {{headerData[0].semester}} | {{$p.t('lehre', 'verband')}} {{headerData[0].verband}} - | {{$p.t('lehre', 'gruppe')}} + | {{$p.t('lehre', 'gruppe')}} {{headerData[0].gruppe}} @@ -162,12 +192,16 @@ export default { {{headerData[0].mail_intern}} - | Status - {{headerData[0].statusofsemester}} + | Status + + {{$p.t('lehre', 'textNoStatus')}} + + + {{headerData[0].statusofsemester}} + | {{$p.t('person', 'matrikelnummer')}} {{headerData[0].matr_nr}} -
diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index a7d97d4fc..fae85b653 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -422,6 +422,12 @@ export default { this.$refs.searchbar.abort(); this.$refs.searchbar.hideresult(); }, + handleReloadStudent(students){ + this.$refs.stvList.updateUrl( + ApiStv.students.uid(students[0].uid,'CURRENT_SEMESTER'), + true + ); + } }, created() { if (!this.url_studiensemester_kurzbz) { @@ -629,7 +635,7 @@ export default { diff --git a/public/js/components/Stv/Studentenverwaltung/Details.js b/public/js/components/Stv/Studentenverwaltung/Details.js index dca08c07f..4d49aba0d 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details.js @@ -8,6 +8,11 @@ import ApiStvApp from '../../../api/factory/stv/app.js'; export default { name: "DetailsPrestudent", + inject: { + currentSemester: { + from: 'currentSemester', + }, + }, components: { FhcTabs, FhcHeader @@ -21,6 +26,9 @@ export default { props: { students: Array }, + emits: [ + 'reloadStudent:students' + ], computed: { appRoot() { return FHC_JS_DATA_STORAGE_OBJECT.app_root; @@ -39,13 +47,30 @@ export default { return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid)); } return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid)); - } + }, +/* studiensemester(){ + if(this.students) + return this.students.query_studiensemester_kurzbz; + else + return null; + //return this.students?[0].query_studiensemester_kurzbz || null; + },*/ }, watch: { '$p.user_language.value'(n, o) { if (n !== o && o !== undefined) this.loadConfig(); + }, + currentSemester(newVal) { + if ( + this.students && + this.students.length > 0 && + newVal !== this.students[0].query_studiensemester_kurzbz + ) { + this.$emit('reloadStudent:students', this.students); + } } + }, methods: { loadConfig() { @@ -65,7 +90,7 @@ export default { reload() { if (this.$refs.tabs?.$refs?.current?.reload) this.$refs.tabs.$refs.current.reload(); - } + }, }, created() { this.loadConfig(); diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 580f15bc2..b1f4b004a 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -56144,6 +56144,26 @@ I have been informed that I am under no obligation to consent to the transmissio ) ), // ### Refactor Messages END + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'textNoStatus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kein Status', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); From 2fde630971b56a0072b7c0eae79dcba67140f08a Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Mon, 9 Mar 2026 15:25:44 +0100 Subject: [PATCH 031/357] adjust abgabetool queries Studentenverwaltung Projektarbeit Tab: lehreinheit required -> lehreinheit optional, lehrveranstaltung & studiensemester_kurbz required; changed occurences of the typo "Studiensemster" rigorously; --- .../api/frontend/v1/stv/Projektarbeit.php | 23 ++++++++++++++----- .../controllers/jobs/ReihungstestJob.php | 2 +- .../models/crm/Prestudentstatus_model.php | 2 +- .../models/education/Projektarbeit_model.php | 2 +- .../organisation/Studiensemester_model.php | 2 +- include/bisarchiv.class.php | 4 ++-- include/lehrveranstaltung.class.php | 2 +- .../Details/Projektarbeit/Details.js | 6 ++--- .../Details/Projektarbeit/Projektarbeit.js | 2 +- system/checkStudenten.php | 4 ++-- system/prestudentstatus_studienplan_id.php | 2 +- vilesci/bis/archiv.php | 12 +++++----- vilesci/bis/personalmeldung.php | 2 +- 13 files changed, 38 insertions(+), 27 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Projektarbeit.php b/application/controllers/api/frontend/v1/stv/Projektarbeit.php index 8740ef3d6..d31354856 100644 --- a/application/controllers/api/frontend/v1/stv/Projektarbeit.php +++ b/application/controllers/api/frontend/v1/stv/Projektarbeit.php @@ -91,11 +91,13 @@ class Projektarbeit extends FHCAPI_Controller if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) return $this->terminateWithError('Projektarbeit Id missing', self::ERROR_TYPE_GENERAL); $this->ProjektarbeitModel->addSelect( - 'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id, + 'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, + lehre.tbl_projektarbeit.lehrveranstaltung_id, lehre.tbl_projektarbeit.studiensemester_kurzbz, lehre.tbl_projektarbeit.lehreinheit_id, firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name' ); - $this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); + $this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + $this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id', 'LEFT'); $this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT'); $result = $this->ProjektarbeitModel->loadWhere( array('projektarbeit_id' => $projektarbeit_id) @@ -229,7 +231,7 @@ class Projektarbeit extends FHCAPI_Controller } /** - * Get Lehrveranstaltungen by params, incling lehreinheiten for a specific Studiensemester.. + * Get Lehrveranstaltungen by params, including lehreinheiten for a specific Studiensemester.. */ public function getLehrveranstaltungen() { @@ -239,7 +241,7 @@ class Projektarbeit extends FHCAPI_Controller $additional_lehrveranstaltung_id = $this->input->get('additional_lehrveranstaltung_id'); if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL); - if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL); + if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemester missing', self::ERROR_TYPE_GENERAL); // get Lvs $lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id); @@ -316,11 +318,18 @@ class Projektarbeit extends FHCAPI_Controller 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Projekttyp']) ]); - $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'required|is_natural', [ - 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']), + $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'is_natural', [ 'is_natural' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit']) ]); + $this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung']) + ]); + + $this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester']) + ]); + $this->form_validation->set_rules('beginn', 'Beginn', 'is_valid_date', [ 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Beginn']) ]); @@ -350,6 +359,8 @@ class Projektarbeit extends FHCAPI_Controller 'projekttyp_kurzbz' => $formData['projekttyp_kurzbz'], 'firma_id' => $formData['firma_id'] ?? null, 'lehreinheit_id' => $formData['lehreinheit_id'], + 'lehrveranstaltung_id' => $formData['lehrveranstaltung_id'], + 'studiensemester_kurzbz' => $formData['studiensemester_kurzbz'], 'beginn' => isset($formData['beginn']) && !isEmptyString($formData['beginn']) ? $formData['beginn'] : null, 'ende' => isset($formData['ende']) && !isEmptyString($formData['ende']) ? $formData['ende'] : null, 'note' => $formData['note'] ?? null, diff --git a/application/controllers/jobs/ReihungstestJob.php b/application/controllers/jobs/ReihungstestJob.php index 6dd214fbb..83ab9b526 100644 --- a/application/controllers/jobs/ReihungstestJob.php +++ b/application/controllers/jobs/ReihungstestJob.php @@ -803,7 +803,7 @@ class ReihungstestJob extends JOB_Controller { if (!isset($studiensemester) || isEmptyString($studiensemester)) { - $this->logError("Studiensemster not passed as parameter"); + $this->logError("Studiensemester not passed as parameter"); return; } diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index c0ed8595e..618d4be51 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -177,7 +177,7 @@ class Prestudentstatus_model extends DB_Model * @param prestudent_id ID of the Prestudent. * @param $status_kurzbz kurzbz of the status. * @param $ausbildungssemester ausbildungssemester of the status. - * @param $studiensemester_kurzbz studiensemster of the status. + * @param $studiensemester_kurzbz studiensemester of the status. * * @return result object with all the status entries */ diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index 1c46ca0c6..726bb70a7 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -25,7 +25,7 @@ class Projektarbeit_model extends DB_Model { $qry = "SELECT pa.*, tbl_projekttyp.bezeichnung, - tbl_projektarbeit.studiensemester_kurzbz, tbl_projektarbeit.lehrveranstaltung_id, + pa.studiensemester_kurzbz, pa.lehrveranstaltung_id, tbl_firma.name AS firma_name, ( SELECT diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php index 5fa6ffb14..48c0aff78 100644 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -177,7 +177,7 @@ class Studiensemester_model extends DB_Model */ public function getByDate($date) { - // gets the studiensemster of a date or the next closest previous studiensemester if a date is not within a studiensemester + // gets the studiensemester of a date or the next closest previous studiensemester if a date is not within a studiensemester $query = " SELECT studiensemester_kurzbz, start, ende FROM public.tbl_studiensemester diff --git a/include/bisarchiv.class.php b/include/bisarchiv.class.php index edec01ae3..7c51ae46c 100644 --- a/include/bisarchiv.class.php +++ b/include/bisarchiv.class.php @@ -48,7 +48,7 @@ class bisarchiv extends basis_db */ protected function validate() { - if($this->studiensemster_kurzbz == null || mb_strlen($this->studiensemster_kurzbz) > 6) + if($this->studiensemester_kurzbz == null || mb_strlen($this->studiensemester_kurzbz) > 6) { $this->errormsg = "Studiensemester ist ungueltig"; return false; @@ -107,7 +107,7 @@ class bisarchiv extends basis_db return false; $qry = "INSERT INTO bis.tbl_archiv (studiensemester_kurzbz, meldung, html, studiengang_kz, insertamum, insertvon, typ) VALUES (" - . $this->db_add_param($this->studiensemster_kurzbz) . "," + . $this->db_add_param($this->studiensemester_kurzbz) . "," . $this->db_add_param($this->meldung) . "," . $this->db_add_param($this->html) . "," . $this->db_add_param($this->studiengang_kz) . "," diff --git a/include/lehrveranstaltung.class.php b/include/lehrveranstaltung.class.php index cc89556c7..234ded019 100644 --- a/include/lehrveranstaltung.class.php +++ b/include/lehrveranstaltung.class.php @@ -2088,7 +2088,7 @@ class lehrveranstaltung extends basis_db /** * lädt die Lehrveranstaltungen zum zugehörigen Mitarbeiter * @param String $uid User ID des Mitarbeiters - * @param String $studiensemster_kurzbz Kurzbezeichnung des Studiensemesters + * @param String $studiensemester_kurzbz Kurzbezeichnung des Studiensemesters */ public function getLVByMitarbeiter($uid, $studiensemester_kurzbz = null) { diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js index 34dd99c8f..bee7fef9e 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js @@ -5,6 +5,7 @@ import PvAutoComplete from "../../../../../../../index.ci.php/public/js/componen import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js'; export default { + name: 'ProjektarbeitDetails', components: { FormForm, FormInput, @@ -219,7 +220,8 @@ export default { if (preparedFormData.projektarbeit_id == null) delete(preparedFormData.projektarbeit_id); delete(preparedFormData.firma); delete(preparedFormData.firma_name); - delete(preparedFormData.lehrveranstaltung_id); + + preparedFormData.studiensemester_kurzbz = this.studiensemester return preparedFormData; } @@ -312,7 +314,6 @@ export default { name="lehrveranstaltung_id" @change="lvChanged($event)" > -