From f2e337b17903f771b0a4a1889d13f9387c4151fc Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Wed, 11 May 2022 04:36:23 +0200 Subject: [PATCH 1/4] FAS prestudent status: added checks when adding or modifiying status, including status and status date checks --- content/student/studentDBDML.php | 191 +++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) diff --git a/content/student/studentDBDML.php b/content/student/studentDBDML.php index 4a4b64201..f811ee780 100644 --- a/content/student/studentDBDML.php +++ b/content/student/studentDBDML.php @@ -372,6 +372,153 @@ function isBuchungAllowedToChange($buchung_obj) return true; } +/** + * + * Prüft für einen Prestudenten, ob eine bestimmte Statusänderung valide ist. + * @param $prestudent_id + * @param $status_kurzbz des neuen/bearbeiteten Status + * @param $new_status_studiensemester Studiensemester des neuen/zu ändernen Status + * @param $new_status_datum Datum des neuen/zu ändernen Status + * @param $new_status_ausbildungssemester Ausbildungssemester des neuen/zu ändernen Status + * @param $old_status_studiensemester Studiensemester des alten Status, leer wenn neuer Status + * @param $old_status_ausbildungssemester Ausbildungssemester des alten Status, leer wenn neuer Status + * @return array + */ +function checkStatusaenderung( + $prestudent_id, $status_kurzbz, $new_status_studiensemester, $new_status_datum, $new_status_ausbildungssemester, + $old_status_studiensemester = '', $old_status_ausbildungssemester = '' +) +{ + global $db; + $endstatus = array('Absolvent', 'Abbrecher'); + // Datum des neuen Status setzen + $new_status_datum = new DateTime($new_status_datum); + + // Wenn neuer Status + if ($old_status_studiensemester == '') + { + // Datum des neuen Status darf nicht in Vergangenheit liegen, sonst Probleme wenn neues Datum < Bismeldedatum + $current_date = new DateTime('today'); + if ($new_status_datum < $current_date) + { + return array( + 'error' => true, + 'errormsg' => 'Datum eines neuen Statuseintrags darf nicht in der Vergangenheit liegen' + ); + } + } + + // start des Studiensemesters holen + $studiensemester = new studiensemester(); + $studiensemester->load($new_status_studiensemester); + $new_status_semesterstart = new DateTime($studiensemester->start); + + // Alle bisherigen prestudentstatus nach Datum sortiert + $qry = "SELECT status_kurzbz, studiensemester_kurzbz, ausbildungssemester, datum, sem.start AS studiensemester_start + FROM public.tbl_prestudentstatus pss + JOIN public.tbl_studiensemester sem USING (studiensemester_kurzbz) + WHERE prestudent_id=".$db->db_add_param($prestudent_id, FHC_INTEGER); + + // gerade bearbeiteten Status rausfiltern + if ($old_status_studiensemester != '' && $old_status_ausbildungssemester != '') + { + $qry .= " AND NOT ( + status_kurzbz=".$db->db_add_param($status_kurzbz) + ." AND studiensemester_kurzbz=".$db->db_add_param($old_status_studiensemester) + ." AND ausbildungssemester=".$db->db_add_param($old_status_ausbildungssemester, FHC_INTEGER)." + )"; + } + + $qry .= " ORDER BY datum DESC, pss.insertamum DESC, pss.ext_id DESC"; + + if($result = $db->db_query($qry)) + { + while($row = $db->db_fetch_object($result)) + { + $studiensemester_start = new DateTime($row->studiensemester_start); + $status_datum = new DateTime($row->datum); + + // Neuer/editierter Statuseintrag nach anderem Statuseintrag + if ($new_status_datum >= $status_datum && $new_status_semesterstart >= $studiensemester_start) + { + // Status vor bearbeiteten für spätere Checks speichern + if (!isset($prev_status)) + $prev_status = $row; + } + // Neuer/editierter Statuseintrag vor anderem Statuseintrag + elseif ($new_status_datum < $status_datum && $new_status_semesterstart <= $studiensemester_start) + { + if (!isset($next_status)) + $next_status = $row; + } + // Datums- oder Semesterabfolge passt nicht - Fehler + else + { + return array( + 'error' => true, + 'errormsg' => 'Datum des Statuseintrags muss nach dem Statusdatum,' + .' Studiensemester Startdatum nach Startdatum des vorherigen Statuseintrags sein' + ); + } + } + + // Abbrecher- oder Absolventenstatus muss Endstatus sein + if ( + (isset($prev_status) && in_array($prev_status->status_kurzbz, $endstatus)) + || (isset($next_status) && in_array($status_kurzbz, $endstatus)) + ) + { + return array( + 'error' => true, + 'errormsg' => 'Nach Abbrecher- und Absolventenstatus darf kein anderer Status mehr eingetragen werden' + ); + } + + // wenn Unterbrecher auf Unterbrecher folgt, muss Ausbildungssemester gleich sein + if ( + $status_kurzbz == 'Unterbrecher' && + ((isset($prev_status) && $prev_status->status_kurzbz == 'Unterbrecher' + && $new_status_ausbildungssemester != $prev_status->ausbildungssemester) + || (isset($next_status) && $next_status->status_kurzbz == 'Unterbrecher' + && $new_status_ausbildungssemester != $next_status->ausbildungssemester)) + ) + { + return array( + 'error' => true, + 'errormsg' => 'Aufeinanderfolgende Unterbrecher müssen gleiches Ausbildungssemester haben' + ); + } + + // wenn Abbrecher auf Unterbrecher folgt, muss Ausbildungssemester gleich sein + if ( + (isset($prev_status) && $status_kurzbz == 'Abbrecher' + && $prev_status->status_kurzbz == 'Unterbrecher' && $new_status_ausbildungssemester != $prev_status->ausbildungssemester) + || (isset($next_status) && $status_kurzbz == 'Unterbrecher' + && $next_status->status_kurzbz == 'Abbrecher' && $new_status_ausbildungssemester != $next_status->ausbildungssemester) + ) + { + return array( + 'error' => true, + 'errormsg' => 'Unterbrecher und folgender Abbrecher müssen gleiches Ausbildungssemester haben' + ); + } + + // keine Studenten nach Diplomand Status + if ( + (isset($prev_status) && $status_kurzbz == 'Student' && $prev_status->status_kurzbz == 'Diplomand') + || (isset($next_status) && $status_kurzbz == 'Diplomand' && $next_status->status_kurzbz == 'Student') + ) + { + return array( + 'error' => true, + 'errormsg' => 'Nach Diplomantenstatus darf kein Studentenstatus mehr eingetragen werden' + ); + } + } + + return array('error' => false, 'errormsg' => ''); +} + if(!$error) { @@ -808,6 +955,28 @@ if(!$error) } } + // wenn keine spezielle Berechtiung zur Umgebung, Statusänderung Checks durchführen + if (!$rechte->isBerechtigt('admin')) + { + $new_status_datum = isset($_POST['datum']) ? $_POST['datum'] : date('Y-m-d'); + + $check_statusaenderung_result = checkStatusaenderung( + $prestudent_id, + $_POST['status_kurzbz'], + $studiensemester, + $new_status_datum, + $sem + ); + + if (isset($check_statusaenderung_result['error']) && $check_statusaenderung_result['error'] === true) + { + $return = false; + $error = true; + $errormsg .= isset($check_statusaenderung_result['errormsg']) ? $check_statusaenderung_result['errormsg'] : ''; + $anzahl_fehler++; + } + } + if(!$error) { $prestd_neu = new prestudent(); @@ -1307,6 +1476,28 @@ if(!$error) $rolle->new = false; } + // Statuschecks durchführen wenn keine spezielle Berechtigung zur Umgehung + if (!$rechte->isBerechtigt('admin')) + { + // allgemeine Prüfung bei Änderung oder Hinzufügen eines Status, inkludiert alle Status + $check_statusaenderung_result = checkStatusaenderung( + $_POST['prestudent_id'], + $_POST['status_kurzbz'], + $_POST['studiensemester_kurzbz'], + $_POST['datum'], + $_POST['ausbildungssemester'], + $_POST['studiensemester_old'], + $_POST['ausbildungssemester_old'] + ); + + if (isset($check_statusaenderung_result['error']) && $check_statusaenderung_result['error'] === true) + { + $return = false; + $error = true; + $errormsg = isset($check_statusaenderung_result['errormsg']) ? $check_statusaenderung_result['errormsg'] : ''; + } + } + if(!$error) { // Bei Studenten wird der Studentlehrverband Eintrag angelegt/korrigiert From d7708e2f6c4046bc6c15974002542b2a2a1d777c Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Mon, 23 May 2022 18:53:16 +0200 Subject: [PATCH 2/4] =?UTF-8?q?Status=C3=A4nderungen=20check=20studentDBDM?= =?UTF-8?q?L.php:=20improved=20way=20of=20checking=20status=20by=20saving?= =?UTF-8?q?=20status=20in=20array=20first?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/student/studentDBDML.php | 148 ++++++++++++++++++------------- 1 file changed, 85 insertions(+), 63 deletions(-) diff --git a/content/student/studentDBDML.php b/content/student/studentDBDML.php index f811ee780..623772c8a 100644 --- a/content/student/studentDBDML.php +++ b/content/student/studentDBDML.php @@ -390,12 +390,15 @@ function checkStatusaenderung( ) { global $db; - $endstatus = array('Absolvent', 'Abbrecher'); + // Es ist ein neuer Status wenn es kein altes Semester gibt + $isNewStatus = $old_status_studiensemester == '' && $old_status_ausbildungssemester == ''; + // status_kurzbz für Endstatus + $endstatusArr = array('Absolvent', 'Abbrecher'); // Datum des neuen Status setzen $new_status_datum = new DateTime($new_status_datum); // Wenn neuer Status - if ($old_status_studiensemester == '') + if ($isNewStatus) { // Datum des neuen Status darf nicht in Vergangenheit liegen, sonst Probleme wenn neues Datum < Bismeldedatum $current_date = new DateTime('today'); @@ -419,8 +422,8 @@ function checkStatusaenderung( JOIN public.tbl_studiensemester sem USING (studiensemester_kurzbz) WHERE prestudent_id=".$db->db_add_param($prestudent_id, FHC_INTEGER); - // gerade bearbeiteten Status rausfiltern - if ($old_status_studiensemester != '' && $old_status_ausbildungssemester != '') + // zu ändernden Status rausfiltern wenn Status bearbeitet wird + if (!$isNewStatus) { $qry .= " AND NOT ( status_kurzbz=".$db->db_add_param($status_kurzbz) @@ -431,90 +434,109 @@ function checkStatusaenderung( $qry .= " ORDER BY datum DESC, pss.insertamum DESC, pss.ext_id DESC"; - if($result = $db->db_query($qry)) + $statusArr = array(); + if ($result = $db->db_query($qry)) { - while($row = $db->db_fetch_object($result)) + $newStatusInserted = false; + + // für jeden Status + while ($row = $db->db_fetch_object($result)) { $studiensemester_start = new DateTime($row->studiensemester_start); $status_datum = new DateTime($row->datum); - // Neuer/editierter Statuseintrag nach anderem Statuseintrag + // Neuer/editierter Statuseintrag nach bestehendem Statuseintrag if ($new_status_datum >= $status_datum && $new_status_semesterstart >= $studiensemester_start) { - // Status vor bearbeiteten für spätere Checks speichern - if (!isset($prev_status)) - $prev_status = $row; + if (!$newStatusInserted) + { + // neuer Status erstmals größer als Datum eines bestehenden Status -> neuen Status einfügen + $new_status = new stdClass(); + $new_status->status_kurzbz = $status_kurzbz; + $new_status->studiensemester_kurzbz = $new_status_studiensemester; + $new_status->datum = $new_status_datum; + $new_status->ausbildungssemester = $new_status_ausbildungssemester; + $statusArr[] = $new_status; + $newStatusInserted = true; + } + + // Gültige Zeitabfolge, bestehenden Status hinzufügen + $statusArr[] = $row; } - // Neuer/editierter Statuseintrag vor anderem Statuseintrag - elseif ($new_status_datum < $status_datum && $new_status_semesterstart <= $studiensemester_start) + // oder Neuer/editierter Statuseintrag nach bestehendem Statuseintrag + elseif ($new_status_datum <= $status_datum && $new_status_semesterstart <= $studiensemester_start) { - if (!isset($next_status)) - $next_status = $row; + // Gültige Zeitabfolge, bestehenden Status hinzufügen + $statusArr[] = $row; } - // Datums- oder Semesterabfolge passt nicht - Fehler else { + // Zeitabfolge ungültig, Fehler return array( 'error' => true, 'errormsg' => 'Datum des Statuseintrags muss nach dem Statusdatum,' - .' Studiensemester Startdatum nach Startdatum des vorherigen Statuseintrags sein' + .' Semesterstartdatum nach Semesterstartdatum des vorherigen Statuseintrags sein' ); } } - // Abbrecher- oder Absolventenstatus muss Endstatus sein - if ( - (isset($prev_status) && in_array($prev_status->status_kurzbz, $endstatus)) - || (isset($next_status) && in_array($status_kurzbz, $endstatus)) - ) + // Prüfungen den Prestudentstatus betreffend + // Über alle gespeicherten Status gehen und Statusabfolge prüfen + for ($i = 0; $i < count($statusArr); $i++) { - return array( - 'error' => true, - 'errormsg' => 'Nach Abbrecher- und Absolventenstatus darf kein anderer Status mehr eingetragen werden' - ); - } + $curr_status = $statusArr[$i]; + $curr_status_kurzbz = $curr_status->status_kurzbz; + $curr_status_ausbildungssemester = $curr_status->ausbildungssemester; + $next_idx = $i - 1; //absteigend sortiert, nächster Status ist vorheriger Eintrag + $next_status = isset($statusArr[$next_idx]) ? $statusArr[$next_idx] : null; - // wenn Unterbrecher auf Unterbrecher folgt, muss Ausbildungssemester gleich sein - if ( - $status_kurzbz == 'Unterbrecher' && - ((isset($prev_status) && $prev_status->status_kurzbz == 'Unterbrecher' - && $new_status_ausbildungssemester != $prev_status->ausbildungssemester) - || (isset($next_status) && $next_status->status_kurzbz == 'Unterbrecher' - && $new_status_ausbildungssemester != $next_status->ausbildungssemester)) - ) - { - return array( - 'error' => true, - 'errormsg' => 'Aufeinanderfolgende Unterbrecher müssen gleiches Ausbildungssemester haben' - ); - } + // Abbrecher- oder Absolventenstatus muss Endstatus sein + if (isset($next_status) && in_array($curr_status_kurzbz, $endstatusArr)) + { + return array( + 'error' => true, + 'errormsg' => 'Nach Abbrecher- und Absolventenstatus darf kein anderer Status mehr eingetragen werden' + ); + } - // wenn Abbrecher auf Unterbrecher folgt, muss Ausbildungssemester gleich sein - if ( - (isset($prev_status) && $status_kurzbz == 'Abbrecher' - && $prev_status->status_kurzbz == 'Unterbrecher' && $new_status_ausbildungssemester != $prev_status->ausbildungssemester) - || (isset($next_status) && $status_kurzbz == 'Unterbrecher' - && $next_status->status_kurzbz == 'Abbrecher' && $new_status_ausbildungssemester != $next_status->ausbildungssemester) - ) - { - return array( - 'error' => true, - 'errormsg' => 'Unterbrecher und folgender Abbrecher müssen gleiches Ausbildungssemester haben' - ); - } + // wenn Unterbrecher auf Unterbrecher folgt, muss Ausbildungssemester gleich sein + if ( + $curr_status_kurzbz == 'Unterbrecher' && isset($next_status) && $next_status->status_kurzbz == 'Unterbrecher' + && $curr_status_ausbildungssemester != $next_status->ausbildungssemester + ) + { + return array( + 'error' => true, + 'errormsg' => 'Aufeinanderfolgende Unterbrecher müssen gleiches Ausbildungssemester haben' + ); + } - // keine Studenten nach Diplomand Status - if ( - (isset($prev_status) && $status_kurzbz == 'Student' && $prev_status->status_kurzbz == 'Diplomand') - || (isset($next_status) && $status_kurzbz == 'Diplomand' && $next_status->status_kurzbz == 'Student') - ) - { - return array( - 'error' => true, - 'errormsg' => 'Nach Diplomantenstatus darf kein Studentenstatus mehr eingetragen werden' - ); + // wenn Abbrecher auf Unterbrecher folgt, muss Ausbildungssemester gleich sein + if ( + isset($next_status) && $curr_status_kurzbz == 'Unterbrecher' + && $next_status->status_kurzbz == 'Abbrecher' && $curr_status_ausbildungssemester != $next_status->ausbildungssemester + ) + { + return array( + 'error' => true, + 'errormsg' => 'Unterbrecher und folgender Abbrecher müssen gleiches Ausbildungssemester haben' + ); + } + + // keine Studenten nach Diplomand Status + if ( + isset($next_status) && $curr_status_kurzbz == 'Diplomand' && $next_status->status_kurzbz == 'Student' + ) + { + return array( + 'error' => true, + 'errormsg' => 'Nach Diplomantenstatus darf kein Studentenstatus mehr eingetragen werden' + ); + } } } + else + return array('error' => true, 'errormsg' => 'Fehler bei Statusänderungcheck'); return array('error' => false, 'errormsg' => ''); } From dc47a2ffc98494949a0d208b0d30b32f549b544b Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Tue, 24 May 2022 18:38:44 +0200 Subject: [PATCH 3/4] added permission student/keine_studstatuspruefung to enable non-admins to bypass studstatus checks --- content/student/studentDBDML.php | 5 +++-- system/dbupdate_3.3.php | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/content/student/studentDBDML.php b/content/student/studentDBDML.php index 623772c8a..e58ed391b 100644 --- a/content/student/studentDBDML.php +++ b/content/student/studentDBDML.php @@ -95,6 +95,7 @@ if(!$rechte->isBerechtigt('admin') && !$rechte->isBerechtigt('assistenz') && !$r $data = ''; $error = true; } +$check_statusaenderung_berechtigung = 'student/keine_studstatuspruefung'; // *** FUNKTIONEN *** @@ -978,7 +979,7 @@ if(!$error) } // wenn keine spezielle Berechtiung zur Umgebung, Statusänderung Checks durchführen - if (!$rechte->isBerechtigt('admin')) + if (!$rechte->isBerechtigt($check_statusaenderung_berechtigung)) { $new_status_datum = isset($_POST['datum']) ? $_POST['datum'] : date('Y-m-d'); @@ -1499,7 +1500,7 @@ if(!$error) } // Statuschecks durchführen wenn keine spezielle Berechtigung zur Umgehung - if (!$rechte->isBerechtigt('admin')) + if (!$rechte->isBerechtigt($check_statusaenderung_berechtigung)) { // allgemeine Prüfung bei Änderung oder Hinzufügen eines Status, inkludiert alle Status $check_statusaenderung_result = checkStatusaenderung( diff --git a/system/dbupdate_3.3.php b/system/dbupdate_3.3.php index 9e73828d0..e1d2b0a4c 100644 --- a/system/dbupdate_3.3.php +++ b/system/dbupdate_3.3.php @@ -6141,6 +6141,20 @@ if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berecht } } +// Add permission for avoiding checks when saving prestudentstatus +if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'student/keine_studstatuspruefung';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/keine_studstatuspruefung', 'Ermöglicht Umgehen der Checks beim Speichern der Presstudentstatus');"; + + if(!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo 'system.tbl_berechtigung: Added permission for student/keine_studstatuspruefung
'; + } +} + // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; From 2faa649cf3e0a164219955c420d550e5ea55eb9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Thu, 9 Jun 2022 14:55:15 +0200 Subject: [PATCH 4/4] =?UTF-8?q?L=C3=B6schen=20von=20Statuseintr=C3=A4gen?= =?UTF-8?q?=20auch=20mit=20Berechtigung=20student/keine=5Fstudstatuspruefu?= =?UTF-8?q?ng=20erm=C3=B6glicht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- content/student/studentDBDML.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/content/student/studentDBDML.php b/content/student/studentDBDML.php index e58ed391b..e9c657635 100644 --- a/content/student/studentDBDML.php +++ b/content/student/studentDBDML.php @@ -573,7 +573,7 @@ if(!$error) $return = false; $errormsg = 'Geburtsdatum ist nicht korrekt.'; $error = true; - } + } if(!$error) { @@ -818,12 +818,12 @@ if(!$error) $prestudent->zgvort = $_POST['zgvort']; $prestudent->zgvdatum = $_POST['zgvdatum']; $prestudent->zgvnation = $_POST['zgvnation']; - $prestudent->zgv_erfuellt = $_POST['zgv_erfuellt']; + $prestudent->zgv_erfuellt = $_POST['zgv_erfuellt']; $prestudent->zgvmas_code = $_POST['zgvmas_code']; $prestudent->zgvmaort = $_POST['zgvmaort']; $prestudent->zgvmadatum = $_POST['zgvmadatum']; $prestudent->zgvmanation = $_POST['zgvmanation']; - $prestudent->zgvmas_erfuellt = $_POST['zgvmas_erfuellt']; + $prestudent->zgvmas_erfuellt = $_POST['zgvmas_erfuellt']; $prestudent->zgvdoktor_code = $_POST['zgvdoktor_code']; $prestudent->zgvdoktorort = $_POST['zgvdoktorort']; $prestudent->zgvdoktordatum = $_POST['zgvdoktordatum']; @@ -1195,7 +1195,7 @@ if(!$error) isset($_POST['prestudent_id']) && is_numeric($_POST['prestudent_id']) && isset($_POST['ausbildungssemester']) && is_numeric($_POST['ausbildungssemester'])) { - if($_POST['status_kurzbz']=='Student' && !$rechte->isBerechtigt('admin', null, 'suid')) + if($_POST['status_kurzbz']=='Student' && !$rechte->isBerechtigt('admin', null, 'suid') && !$rechte->isBerechtigt('student/keine_studstatuspruefung', null, 'suid')) { $return = false; $errormsg = 'Studentenrolle kann nur durch den Administrator geloescht werden'; @@ -1211,7 +1211,7 @@ if(!$error) if($row->anzahl<=1) { $deletePrestudent = true; - if (!$rechte->isBerechtigt('admin', null, 'suid')) + if (!$rechte->isBerechtigt('admin', null, 'suid') && !$rechte->isBerechtigt('student/keine_studstatuspruefung', null, 'suid')) { $return = false; $errormsg = 'Die letzte Rolle kann nur durch den Administrator geloescht werden'; @@ -2575,7 +2575,7 @@ if(!$error) { if ($dokument_kurzbz === 'Sonst' && $sonst !== 0) continue; - + if($dokument_kurzbz!='') { $dok = new dokument(); @@ -2588,7 +2588,7 @@ if(!$error) $dok->new = true; if ($dokument_kurzbz === 'Sonst') $sonst++; - + if(!$dok->save()) {