diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index 9de0c29b1..b9f869ac3 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -430,7 +430,7 @@ class Students extends FHCAPI_Controller * * @return void */ - protected function fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null) + protected function fetchStudentsWithoutTagsPrestudent($studiensemester_kurzbz, $studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null) { $this->load->model('crm/Prestudent_model', 'PrestudentModel'); $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); @@ -496,7 +496,7 @@ class Students extends FHCAPI_Controller if (!$verband && !$gruppe && $orgform_kurzbz !== null) { $this->PrestudentModel->db->where( "( - SELECT orgform_kurzbz + SELECT orgform_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=tbl_prestudent.prestudent_id AND studiensemester_kurzbz=" . $this->PrestudentModel->escape($studiensemester_kurzbz) . " @@ -518,6 +518,23 @@ class Students extends FHCAPI_Controller $this->terminateWithSuccess($data); } + protected function fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null){ + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } + $allowedStg = $this->allowedStgs; + $result = $this->PrestudentModel->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $allowedStg, $semester, $verband, $gruppe, $gruppe_kurzbz, $orgform_kurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } + + /** * @param string $prestudent_id * diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index ff56c3268..bd552d0c3 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -782,4 +782,170 @@ class Prestudent_model extends DB_Model return $this->execQuery($query, array($person_id)); } + + /** + * Version in raw sql to fetch Students for loading StudentList + * @param integer $studiengang_kz + * @param string $studiensemester_kurzbz + * @param Array $allowedStg + * @param integer $semester (optional) + * @param string $verband (optional) + * @param integer $gruppe (optional) + * @param string $gruppe_kurzbz (optional) + * @param string $orgform_kurzbz (optional) + * + * @return object + */ + public function fetchStudents($studiensemester_kurzbz, $studiengang_kz, $allowedStg, $semester, $verband, $gruppe, $gruppe_kurzbz, $orgform_kurzbz) + { + + $stdsemEsc = $studiensemester_kurzbz ? $this->db->escape($studiensemester_kurzbz) : 'NULL'; + $orgform_kurzbzEsc = $orgform_kurzbz ? $this->db->escape($orgform_kurzbz) : 'NULL'; + + $qry = "WITH prestudenten AS ( + SELECT * + FROM public.tbl_prestudent + ), + ". $this->getTagsCTE() . " + SELECT b.uid, + COALESCE(tag_data_agg.tags, '[]'::json) AS tags, + titelpre, nachname, vorname, wahlname, vornamen, titelpost, ersatzkennzeichen, gebdatum, geschlecht, foto, foto_sperre, + UPPER(stg.typ || stg.kurzbz) AS studiengang, tbl_prestudent.studiengang_kz, stg.bezeichnung AS stg_bezeichnung, s.matrikelnr, + p.person_id, pls.status_kurzbz AS status, pls.datum AS status_datum, pls.bestaetigtam AS status_bestaetigung, + (SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat, + CASE + WHEN b.uid IS NOT NULL AND b.uid<>'' + THEN CONCAT(b.uid, '@', " . $this->db->escape(DOMAIN) .") + ELSE '' + END AS mail_intern, p.anmerkung AS anmerkungen, tbl_prestudent.anmerkung, pls.orgform_kurzbz, aufmerksamdurch_kurzbz, + (SELECT rt_gesamtpunkte AS punkte FROM public.tbl_prestudent WHERE prestudent_id=ps.prestudent_id) AS punkte, + tbl_prestudent.aufnahmegruppe_kurzbz, tbl_prestudent.dual, p.matr_nr, sp.bezeichnung AS studienplan_bezeichnung, + tbl_prestudent.prestudent_id, mentor, b.aktiv AS bnaktiv, v.semester, v.verband, v.gruppe, '' AS priorisierung_relativ, + ( + SELECT status_kurzbz + FROM public.tbl_prestudentstatus pss + WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id + AND pss.studiensemester_kurzbz = ? + ORDER BY GREATEST(pss.datum, '0001-01-01') DESC + LIMIT 1 + ) AS statusofsemester + FROM public.tbl_prestudent + LEFT JOIN public.tbl_studiengang stg USING (studiengang_kz) + JOIN public.tbl_person p USING (person_id) + JOIN public.tbl_student s USING (prestudent_id) + LEFT JOIN public.tbl_prestudentstatus pls ON pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) + AND pls.prestudent_id = tbl_prestudent.prestudent_id + AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL) + AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL) + LEFT JOIN lehre.tbl_studienplan sp USING (studienplan_id) + LEFT JOIN public.tbl_benutzer b ON s.student_uid=b.uid + JOIN public.tbl_studentlehrverband v ON v.student_uid=s.student_uid "; + + $qry .= $studiensemester_kurzbz ? ' AND v.studiensemester_kurzbz = ' . $this->db->escape($studiensemester_kurzbz) : ' AND v.studiensemester_kurzbz = IS NULL'; + + if($gruppe_kurzbz !== null) + { + $qry .= " JOIN public.tbl_benutzergruppe g USING (uid)"; + } + + $qry .= " + LEFT JOIN public.tbl_prestudentstatus ps ON ps.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, ?) + AND ps.prestudent_id = tbl_prestudent.prestudent_id + AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ?) + AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ?) + LEFT JOIN tag_data_agg ON tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id + WHERE tbl_prestudent.studiengang_kz IN ?"; + + $params = array($stdsemEsc, $stdsemEsc, $stdsemEsc, $stdsemEsc, $allowedStg); + + if (!$verband && !$gruppe && $orgform_kurzbz !== null) + { + $qry .= " + AND ( + SELECT orgform_kurzbz + FROM public.tbl_prestudentstatus + WHERE prestudent_id=tbl_prestudent.prestudent_id + AND studiensemester_kurzbz=" . $stdsemEsc . " + ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1 + ) = " . $orgform_kurzbzEsc ; + } + + if($semester !== null) + { + $qry .= " AND v.semester = ?"; + $params[] = $semester; + } + if($verband !== null) + { + $qry .= " AND v.verband = ?"; + $params[] = $verband; + } + + if($gruppe !== null) + { + $qry .= " AND v.gruppe = ?"; + $params[] = $gruppe; + } + + if($gruppe_kurzbz !== null) + { + $qry .= " AND g.gruppe_kurzbz = ?"; + $qry .= " AND g.studiensemester_kurzbz = ?"; + $params[] = $gruppe_kurzbz; + $params[] = $stdsemEsc; + } + else + { + $qry .= " AND v.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + $qry .= " + ORDER BY nachname ASC, vorname ASC + "; + return $this->execReadOnlyQuery($qry, $params); + } + + public function getTagsCTE() + { + $this->load->config('stv'); + $tags = $this->config->item('tags'); + + $whereTags = ''; + if (is_array($tags) && !isEmptyArray($tags)) + { + $tags = array_keys($tags); + + foreach ($tags as $key => $tag) + { + $tags[$key] = $this->db->escape($tag); + } + + $whereTags = " AND tbl_notiz_typ.typ_kurzbz IN (" . implode(",", $tags) . ")"; + } + + return "tag_data_agg AS + ( + SELECT + prestudent_id, + COALESCE(json_agg(tag ORDER BY done), '[]'::json) AS tags + FROM ( + SELECT DISTINCT ON (public.tbl_notiz.notiz_id) + tbl_notiz.notiz_id AS id, + typ_kurzbz, + array_to_json(tbl_notiz_typ.bezeichnung_mehrsprachig)->>0 AS beschreibung, + text AS notiz, + style, + erledigt AS done, + prestudent_id + FROM public.tbl_notizzuordnung + JOIN public.tbl_notiz ON tbl_notizzuordnung.notiz_id = tbl_notiz.notiz_id + JOIN public.tbl_notiz_typ ON tbl_notiz.typ = tbl_notiz_typ.typ_kurzbz + WHERE prestudent_id IN (SELECT prestudent_id FROM prestudenten)" + . $whereTags. + ") AS tag + GROUP BY prestudent_id + )"; + } + } diff --git a/public/js/components/Stv/Studentenverwaltung/List.js b/public/js/components/Stv/Studentenverwaltung/List.js index 3d46dc32f..7de862a96 100644 --- a/public/js/components/Stv/Studentenverwaltung/List.js +++ b/public/js/components/Stv/Studentenverwaltung/List.js @@ -200,6 +200,9 @@ export default { return Promise.resolve({ data: []}); } return this.$api.call({url, params}); + //version with Tags + return this.$api.call({url, params}); + }, ajaxResponse: (url, params, response) => { return response?.data; @@ -238,7 +241,7 @@ export default { event: 'rowClick', handler: this.handleRowClick // TODO(chris): this should be in the filter component }, - { +/* { event: 'dataTreeRowExpanded', handler: (data) => { this.getExpandedRows() @@ -249,7 +252,7 @@ export default { handler: (data) => { this.getExpandedRows() } - } + }*/ ], focusObj: null, // TODO(chris): this should be in the filter component lastSelected: null, @@ -278,7 +281,7 @@ export default { //for tags this.selectedRows = this.$refs.table.tabulator.getSelectedRows(); - this.selectedColumnValues = this.selectedRows.filter(row => row.getData().uid !== undefined && row.getData().uid).map(row => row.getData().uid); + this.selectedColumnValues = this.selectedRows.filter(row => row.getData().prestudent_id !== undefined && row.getData().prestudent_id).map(row => row.getData().prestudent_id); this.$emit('update:selected', data); }, @@ -403,7 +406,6 @@ export default { //methods tags addedTag(addedTag) { - console.log("addedTag"); const table = this.$refs.table.tabulator; this.selectedRows.forEach(row => @@ -411,7 +413,7 @@ export default { if (Array.isArray(addedTag.response)) { addedTag.response.forEach(tag => { - const targetRow = this.allRows.find(row => row.getData().uid === tag.uid); + const targetRow = this.allRows.find(row => row.getData().prestudent_id === tag.prestudent_id); if (targetRow) { const rowData = targetRow.getData(); @@ -434,7 +436,6 @@ export default { }); }, deletedTag(deletedTag) { - console.log("deletedTag"); const targetRow = this.allRows.find(row => { const rowData = row.getData(); @@ -467,7 +468,6 @@ export default { } }, updatedTag(updatedTag) { - console.log("updatedTag"); const targetRow = this.allRows.find(row => { const rowData = row.getData(); let tags = []; @@ -504,45 +504,6 @@ export default { } } }, - resetTree() { - console.log("reset tree"); - this.allRows.forEach(row => { - row._row.modules.dataTree.open = false; - }); - - let rootRows = this.$refs.table.tabulator.getRows(true); - var lastRow = rootRows[rootRows.length - 1]; - lastRow?.treeCollapse(true) - - this.currentTreeLevel = 0; - }, - expandTree() - { - console.log("expandTree"); - this.currentTreeLevel = (this.currentTreeLevel || 0) + 1; - - let lastMatchingRow = null; - - this.allRows.forEach(row => { - const level = row._row.modules.dataTree?.index ?? 0; - - if (level === this.currentTreeLevel - 1 ) - { - row._row.modules.dataTree.open = true; - - if (row._row.data._children?.length > 0) - { - lastMatchingRow = row; - } - } - }); - - if (lastMatchingRow) - { - lastMatchingRow.treeExpand(); - } - this.$refs.table.tabulator.redraw(); - }, getAllRows(rows) { let result = []; @@ -557,16 +518,6 @@ export default { }); return result; }, - async getExpandedRows() { - this.expanded = []; - - this.allRows.forEach(row => { - if (row.getTreeChildren().length > 0 && row.isTreeExpanded()) - { - this.expanded.push(row.getData().uniqueindex); - } - }); - }, reexpandRows() { this.allRows = this.getAllRows(this.$refs.table.tabulator.getRows()); @@ -605,7 +556,6 @@ export default { // TODO(chris): filter component column chooser has no accessibilty features template: `