From 8b68e60ae8d230e651d27bcaba767cb41c9e757c Mon Sep 17 00:00:00 2001 From: Harald Bamberger Date: Fri, 9 Oct 2026 15:14:51 +0200 Subject: [PATCH] work in progress --- .../api/frontend/v1/stv/LvTermine.php | 70 +++++- application/libraries/StundenplanLib.php | 17 +- .../models/ressource/Stundenplan_model.php | 224 ++++++++++-------- 3 files changed, 200 insertions(+), 111 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/LvTermine.php b/application/controllers/api/frontend/v1/stv/LvTermine.php index bd4f5085d..8e2662f53 100644 --- a/application/controllers/api/frontend/v1/stv/LvTermine.php +++ b/application/controllers/api/frontend/v1/stv/LvTermine.php @@ -32,9 +32,14 @@ class LvTermine extends FHCAPI_Controller $this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); } + public function getStundenplan($uid, $start_date = null, $end_date = null, $dbStundenplanTable = "stundenplan", $groupConsecutiveHours = false) + { + $this->getStundenplanbh($uid, '2026-02-04', '2027-02-03', $dbStundenplanTable, $groupConsecutiveHours); + } + //TODO Build own lib or combine with Controller Stundenplan.php //here use of logic of Stundenplan.php, extended with parameters uid, grouping, and used dbTable - public function getStundenplan($uid, $start_date = null, $end_date = null, $dbStundenplanTable = "stundenplan", $groupConsecutiveHours = false) + public function getStundenplanbh($uid, $start_date = null, $end_date = null, $dbStundenplanTable = "stundenplan", $groupConsecutiveHours = false) { $ci = get_instance(); $student_uid = $uid; @@ -59,8 +64,24 @@ class LvTermine extends FHCAPI_Controller $ci->addMeta('spezialgruppen', $benutzer_gruppen); // getting the student_lehrverbaende of the student in the different studiensemester - $ende_semProlonged = $semester_range[$first_semester][$first_semester]->ende; - $ci->addMeta(' E N D E _semProlonged', $ende_semProlonged); + $ci->addMeta('bhsemtest', print_r($semester_range, true)); + + $semester_range = array( + 'SS2026' => array( + 'WS2025' => (object) array( + 'start' => '2026-02-04', + 'ende' => '2026-05-19' + ), + 'SS2026' => (object) array( + 'start' => '2026-02-04', + 'ende' => '2026-11-15' + ), + 'WS2026' => (object) array( + 'start' => '2026-09-01', + 'ende' => '2027-02-03' + ) + ) + ); $student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($student_uid, $semester_range); @@ -68,6 +89,40 @@ class LvTermine extends FHCAPI_Controller if (isError($student_lehrverband)) return $student_lehrverband; $student_lehrverband = getData($student_lehrverband); + + $student_lehrverband = array ( + 'SS2026' => + array ( + 0 => + (object) array( + 'verbandsgruppe' => 'BEE1A', + 'studiengang_kz' => 476, + 'semester' => 1, + 'verband' => 'A', + 'gruppe' => ' ', + 'studiensemester_kurzbz' => 'WS2025', + ), + 1 => + (object) array( + 'verbandsgruppe' => 'BEE2A', + 'studiengang_kz' => 476, + 'semester' => 2, + 'verband' => 'A', + 'gruppe' => ' ', + 'studiensemester_kurzbz' => 'SS2026', + ), + 2 => + (object) array( + 'verbandsgruppe' => 'BEE3A', + 'studiengang_kz' => 476, + 'semester' => 3, + 'verband' => 'A', + 'gruppe' => ' ', + 'studiensemester_kurzbz' => 'SS2026', + ), + ), + ); + $ci->addMeta('studentlehrverbaende', $student_lehrverband); $this->load->model('crm/Student_model', 'StudentModel'); @@ -95,10 +150,12 @@ class LvTermine extends FHCAPI_Controller $student_lehrverband, $dbStundenplanTable, $groupConsecutiveHours, - $ende_semProlonged, - $semesterStud + null, + null ); + $ci->addMeta('bhstdplanquery', $stundenplan_query); + if(!$stundenplan_query) { $this->terminateWithSuccess([]); @@ -258,7 +315,7 @@ class LvTermine extends FHCAPI_Controller { // for each active semester query the student_lehrverband associated to the semester $lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]); + SELECT vbd.*, UPPER(s.typ || s.kurzbz) as stg FROM tbl_studentlehrverband vbd join tbl_studiengang s USING(studiengang_kz) where vbd.student_uid = ? AND vbd.studiensemester_kurzbz = ?", [$student_uid, $semester]); if(isError($lehrverband_query)){ return error(getData($lehrverband_query)); } @@ -268,6 +325,7 @@ class LvTermine extends FHCAPI_Controller function ($item) { $result = new stdClass(); + $result->verbandsgruppe = $item->stg . $item->semester . trim($item->verband) . trim($item->gruppe); $result->studiengang_kz = $item->studiengang_kz; $result->semester = $item->semester; $result->verband = $item->verband; diff --git a/application/libraries/StundenplanLib.php b/application/libraries/StundenplanLib.php index 2c13a29d9..00eeb7dfa 100644 --- a/application/libraries/StundenplanLib.php +++ b/application/libraries/StundenplanLib.php @@ -88,7 +88,22 @@ class StundenplanLib $this->_ci->addMeta('nach_apply_semester_range', $semester_range); if ($function_error) return $function_error; - + + $this->_ci->addMeta('bhsemtest', print_r($semester_range, true)); + + $semester_range = array( + 'SS2026' => array( + 'WS2025' => (object) array( + 'start' => '2026-02-04', + 'ende' => '2026-05-19' + ), + 'SS2026' => (object) array( + 'start' => '2026-02-04', + 'ende' => '2026-11-15' + ), + ) + ); + // getting the gruppen_kurzbz of the student in the different studiensemester $benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($student_uid, $semester_range); if (isError($benutzer_gruppen)) diff --git a/application/models/ressource/Stundenplan_model.php b/application/models/ressource/Stundenplan_model.php index 6f0633d0f..2df31756a 100644 --- a/application/models/ressource/Stundenplan_model.php +++ b/application/models/ressource/Stundenplan_model.php @@ -193,7 +193,8 @@ class Stundenplan_model extends DB_Model */ public function stundenplanGruppierungConsecutive($stundenplanViewQuery) { - $query_result = $this->execReadOnlyQuery(" + $query_result = $this->execReadOnlyQuery( + $stundenplanViewQuery . " SELECT distinct lehrveranstaltung_id, datum, @@ -247,7 +248,7 @@ class Stundenplan_model extends DB_Model anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz, CONCAT(p.nachname, ' ', p.vorname) as lektorname - FROM (".$stundenplanViewQuery.") sp + FROM stundenplaneintraege sp JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde LEFT JOIN public.tbl_benutzer bn ON bn.uid = sp.uid LEFT JOIN public.tbl_person p ON p.person_id = bn.person_id @@ -529,6 +530,95 @@ class Stundenplan_model extends DB_Model return $this->execReadOnlyQuery($qry, $qry_params); } + protected function genLehrverbandClauses($semester, $studentlehrverbaende) + { + $lvbdclauses = array(); + $studiengang_kz = null; + foreach($semester as $sem=>$semester_date_range) + { + foreach($semester_date_range as $sem_date => $sem_date_range) + { + if(!array_key_exists($sem,$studentlehrverbaende) || count($studentlehrverbaende[$sem]) == 0) + { + continue; + } + + $studlvbds = array_filter( + $studentlehrverbaende[$sem], + function($value) use ($sem_date) { + return $value->studiensemester_kurzbz === $sem_date; + } + ); + + foreach($studlvbds as $key=>$lehrverband) + { + $studiengang_kz = $lehrverband->studiengang_kz; + $lvbdclauses[] = <<escape($lehrverband->verbandsgruppe)} like sp.verbandsgruppe || '%' + and sp.datum between {$this->escape($sem_date_range->start)} and {$this->escape($sem_date_range->ende)} + and (sp.studiensemester_kurzbz is null or sp.studiensemester_kurzbz = {$this->escape($lehrverband->studiensemester_kurzbz)}) + ) +EOCLAUSE; + + } + } + } + $sql = implode(PHP_EOL . " OR" . PHP_EOL, $lvbdclauses); + if($sql) + { + $sql = <<escape($studiengang_kz)} + and + sp.gruppe_kurzbz is null + and + ( +{$sql} + ) + ) +EOSQL; + + } + return $sql; + } + + protected function genSpezialgruppenClauses($semester, $gruppen) + { + $spezgrpclauses = array(); + foreach($semester as $sem => $semester_date_range) + { + + foreach($semester_date_range as $sem_date => $sem_date_range) + { + // if there are not groups for the semester skip the iteration step + if(!array_key_exists($sem_date,$gruppen) || count($gruppen[$sem_date]) == 0) + { + continue; + } + // converts the array of gruppen strings into a sql IN (_,_,_) chain + $groups = implode(', ', $gruppen[$sem_date]); + $spezgrpclauses[] = <<escape($sem_date_range->start)} AND {$this->escape($sem_date_range->ende)} + ) +EOSPEZGRP; + + } + } + $sql = implode(PHP_EOL . " OR" . PHP_EOL, $spezgrpclauses); + if($sql) + { + $sql = <<= ".$this->escape($start_date)." - AND sp.datum <= ".$this->escape($end_date); + $lvbdclauses = $this->genLehrverbandClauses($semester, $studentlehrverbaende); + $spezgrpclauses = $this->genSpezialgruppenClauses($semester, $gruppen); + $chainingand = ($lvbdclauses && $spezgrpclauses) ? 'AND' : ''; - //necessary for new prolonged interval - if($semesterFilter && $endDateNextSemHalf) - { - $query .= " AND sp.semester = " . $semesterFilter; - } + $query = <<= {$this->escape($start_date)} + and sp.datum <= {$this->escape($end_date)} + ), + stundenplaneintraege as ( + select + sp.* + from + preprocessedsp sp + where + {$lvbdclauses} + {$chainingand} + {$spezgrpclauses} + ) - // adds the AND sql chain only if both $gruppen and $studentlehrverbaende are not empty - if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende)) - { - $query .= " AND ( "; - } - - foreach($semester as $sem => $semester_date_range) - { - - foreach($semester_date_range as $sem_date => $sem_date_range) - { - // if there are not groups for the semester skip the iteration step - if(!array_key_exists($sem_date,$gruppen) || count($gruppen[$sem_date]) == 0) - { - continue; - } - // converts the array of gruppen strings into a sql IN (_,_,_) chain - $query .="(sp.gruppe_kurzbz IN (" .implode(',',$gruppen[$sem_date]).") AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende)." )"; - - $query .="OR"; - } - } - - // if there are no studentlehrverbaende and the gruppen are not empty, we can remove the last OR added after the groups - if($emptyCheck($studentlehrverbaende) && !$emptyCheck($gruppen)) - { - $query = substr($query, 0, -2); - } - - foreach($semester as $sem=>$semester_date_range) - { - foreach($semester_date_range as $sem_date => $sem_date_range) - { - if(!array_key_exists($sem,$studentlehrverbaende) || count($studentlehrverbaende[$sem]) == 0) - { - continue; - } - - $studlvbds = array_filter( - $studentlehrverbaende[$sem], - function($value) use ($sem_date) { - return $value->studiensemester_kurzbz === $sem_date; - } - ); - - foreach($studlvbds as $key=>$lehrverband) - { - $query .= "(((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; - // Eintraege fuer den ganzen Verband - $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; - // Eintraege fuer das ganze Semester - $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start) - ." AND ".$this->escape($sem_date_range->ende).")) AND gruppe_kurzbz is null)"; - - // Eintraege vom Stundenplan //not in master - if($showLvsStundenplan) - { - $query .= " - OR EXISTS ( - SELECT 1 - FROM lehre.tbl_stundenplan tsp - WHERE tsp.lehreinheit_id = sp.lehreinheit_id - AND tsp.studiengang_kz = " . $this->escape($lehrverband->studiengang_kz) . " - AND (tsp.semester = " . $this->escape($lehrverband->semester) . " OR tsp.semester IS NULL) - AND (tsp.verband = " . $this->escape($lehrverband->verband) . " OR tsp.verband IS NULL OR tsp.verband = '0' OR tsp.verband = '') - AND (tsp.gruppe = " . $this->escape($lehrverband->gruppe) . " OR tsp.gruppe IS NULL OR tsp.gruppe = '0' OR tsp.gruppe = '') - AND tsp.gruppe_kurzbz IS NULL)"; - } - - $query .= "OR"; - } - } - } - - // if the studentlehrverbaende is not empty we can remove the last OR that was added to the query - if(!$emptyCheck($studentlehrverbaende)) - { - $query = substr($query, 0, -2); - } - - // closes the AND sql chain only if it was opened previously - if(!$emptyCheck($gruppen) || !$emptyCheck($studentlehrverbaende)) - { - $query .= ")"; - } +EOSQL; return $query; }