From fe8cf9bc832a98383858ba74d3ca4bf275954feb Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 11 Jun 2026 15:34:45 +0200 Subject: [PATCH] new widget CIS4 MA Widget - db-update for new widget studstatus - different view for stgL and stgA - update phrases --- .../api/frontend/v1/StudstatusAntraege.php | 145 ++++++++++++++++++ .../education/Studierendenantrag_model.php | 71 +++++++++ .../models/person/Benutzerfunktion_model.php | 34 ++++ public/js/api/factory/widget/studstatus.js | 25 +++ .../components/DashboardWidget/StudStatus.js | 75 +++++++++ .../components/Studierendenantrag/Antrag.js | 2 +- system/dbupdate_3.4.php | 1 + ...048_cis4_mitarbeiter_studstatus_widget.php | 44 ++++++ system/phrasesupdate.php | 102 ++++++++++++ 9 files changed, 498 insertions(+), 1 deletion(-) create mode 100644 application/controllers/api/frontend/v1/StudstatusAntraege.php create mode 100644 public/js/api/factory/widget/studstatus.js create mode 100644 public/js/components/DashboardWidget/StudStatus.js create mode 100644 system/dbupdate_3.4/77048_cis4_mitarbeiter_studstatus_widget.php diff --git a/application/controllers/api/frontend/v1/StudstatusAntraege.php b/application/controllers/api/frontend/v1/StudstatusAntraege.php new file mode 100644 index 000000000..44dc4134d --- /dev/null +++ b/application/controllers/api/frontend/v1/StudstatusAntraege.php @@ -0,0 +1,145 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +class StudstatusAntraege extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getTodos' => self::PERM_LOGGED + ]); + + //load models + $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * gets all todos of antraegen of the user with stg leitungsfunction + * or list of open antraege for user with assistance function + * @access public + * @return array || [] + */ + public function getTodos() + { + $uid = getAuthUID(); + + //at first get studiengang with leitungsfunktion + $result = $this->BenutzerfunktionModel->getSTGLByUID($uid); + + if(hasData($result)) + { + $funktionen = getData($result); + + $studiengaenge = []; + + foreach ($funktionen as $funktion) { + $studiengaenge[] = $funktion->studiengang_kz; + } + + $dataAntrage = []; + + $result = $this->StudierendenantragModel->getOpenAntraegeForStgl($studiengaenge); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + $dataAntrage[] = getData($result) ?: []; + $statusRole = 1; + + $this->terminateWithSuccess([count($dataAntrage) > 0 ? $dataAntrage[0] : $dataAntrage, $statusRole]); + + } + + //TODO delete after check if needed or not + //get studiengaenge of assistance (regarding benutzerfunktion) + //$result = $this->BenutzerfunktionModel->getSTGAssByUID($uid); + /* if(hasData($result)) { + $statusRole = 2; + $funktionen = getData($result); + + $studiengaenge = []; + + foreach ($funktionen as $funktion) { + $studiengaenge[] = $funktion->studiengang_kz; + } + + $ci->addMeta('stgAss', $studiengaenge); + $dataAntrage = []; + + foreach ($studiengaenge as $studiengang) + { + $result = $this->StudierendenantragModel->getOpenAntraegeForAss($studiengang); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + if(hasData($result)) { + $dataAntrage[] = getData($result); + $statusRole = 2; + } + } + } + else + { + $statusRole = 0; + $dataAntrage = []; + //$this->terminateWithSuccess([[], $statusRole]); + }*/ + + //get studiengaenge of assistance (regarding rights) + $stgAss = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + if(!is_array($stgAss)) + { + $statusRole = 0; + $this->terminateWithSuccess([[], $statusRole]); + } + else { + $statusRole = 2; + $studiengaenge = []; + + foreach ($stgAss as $stg) { + $studiengaenge[] = (int) $stg; + } + + $dataAntrage = []; + $result = $this->StudierendenantragModel->getOpenAntraegeForAss($studiengaenge); + + if (isError($result)) { + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + if(hasData($result)) { + $dataAntrage[] = getData($result); + $statusRole = 2; + } + + $this->terminateWithSuccess([count($dataAntrage) > 0 ? $dataAntrage[0] : $dataAntrage, $statusRole]); + + } + } +} \ No newline at end of file diff --git a/application/models/education/Studierendenantrag_model.php b/application/models/education/Studierendenantrag_model.php index 677d01f04..f7519b6a3 100644 --- a/application/models/education/Studierendenantrag_model.php +++ b/application/models/education/Studierendenantrag_model.php @@ -490,4 +490,75 @@ class Studierendenantrag_model extends DB_Model return hasData($this->load()); } + + /** + * Loads all todos for a certain studiengangsleiter + * + * @param integer $stg_kz + * + * @return stdClass + */ + public function getOpenAntraegeForStgl($stg_kz) + { + $qry = " + SELECT + studierendenantrag_id, + prestudent_id, + typ, + person.nachname, + person.vorname, + ps.studiengang_kz + FROM campus.tbl_studierendenantrag a + JOIN public.tbl_prestudent ps USING (prestudent_id) + JOIN public.tbl_person person USING (person_id) + WHERE studiengang_kz in ? + AND ( + (typ IN ('Abmeldung', 'AbmeldungStgl', 'Unterbrechung') + AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Erstellt') + OR + (typ = 'Wiederholung' + AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Lvszugewiesen') + ) + ORDER BY typ; + "; + + $params = array($stg_kz); + return $this->execQuery($qry, $params); + } + + /** + * Lists all open antraege for a certain stg + * + * @param Array $stg_kz + * + * @return stdClass + */ + public function getOpenAntraegeForAss($stg_kz) + { + $qry = " + SELECT + UPPER(stg.typ) || UPPER(stg.kurzbz) || ' ' || stg.bezeichnung AS studiengang, + COUNT(*) AS anzahl + FROM campus.tbl_studierendenantrag + JOIN public.tbl_prestudent p USING (prestudent_id) + JOIN public.tbl_studiengang stg ON p.studiengang_kz=stg.studiengang_kz + JOIN campus.tbl_studierendenantrag_status as s ON campus.get_status_id_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = studierendenantrag_status_id + JOIN campus.tbl_studierendenantrag_statustyp as st USING (studierendenantrag_statustyp_kurzbz) + WHERE ( + s.studierendenantrag_statustyp_kurzbz NOT IN('Zurueckgezogen', 'Genehmigt', 'Abgelehnt', 'EinspruchAbgelehnt', 'Abgemeldet', 'Pause', 'EmailVersandt') + OR ( + s.studierendenantrag_statustyp_kurzbz = 'Genehmigt' + AND tbl_studierendenantrag.typ = 'AbmeldungStgl' + ) + ) + AND p.studiengang_kz IN ? + GROUP BY studiengang + ORDER BY studiengang + " + ; + + $params = array($stg_kz); + return $this->execQuery($qry, $params); + } + } diff --git a/application/models/person/Benutzerfunktion_model.php b/application/models/person/Benutzerfunktion_model.php index dff422b7d..8c5986462 100644 --- a/application/models/person/Benutzerfunktion_model.php +++ b/application/models/person/Benutzerfunktion_model.php @@ -321,6 +321,40 @@ class Benutzerfunktion_model extends DB_Model return $record; } + /** + * Get active Assistenz(en) of the user by UID. + * @param $uid + */ + public function getSTGAssByUID($uid) + { + $query = ' + SELECT + uid, + oe_kurzbz, + studiengang_kz, + typ, + tbl_studiengang.bezeichnung + FROM + public.tbl_benutzerfunktion + JOIN public.tbl_studiengang USING (oe_kurzbz) + WHERE + funktion_kurzbz = \'ass\' + AND (datum_von IS NULL OR datum_von <= now()) + AND (datum_bis IS NULL OR datum_bis >= now()) + AND uid = ? + ORDER BY + oe_kurzbz + '; + + $parameters_array = array(); + if (is_string($uid)) + { + $parameters_array[] = $uid; + } + + return $this->execQuery($query, $parameters_array); + } + function updateBenutzerfunktion($funktionJson) { $funktionJson['updatevon'] = getAuthUID(); diff --git a/public/js/api/factory/widget/studstatus.js b/public/js/api/factory/widget/studstatus.js new file mode 100644 index 000000000..96f55652a --- /dev/null +++ b/public/js/api/factory/widget/studstatus.js @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2026 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + getTodos() { + return { + method: 'get', + url: '/api/frontend/v1/StudstatusAntraege/getTodos' + }; + }, +}; diff --git a/public/js/components/DashboardWidget/StudStatus.js b/public/js/components/DashboardWidget/StudStatus.js new file mode 100644 index 000000000..8b5b52fa0 --- /dev/null +++ b/public/js/components/DashboardWidget/StudStatus.js @@ -0,0 +1,75 @@ +import AbstractWidget from './Abstract.js'; + +import ApiStudstatus from '../../api/factory/widget/studstatus.js'; + +export default { + name: "WidgetStudstatus", + mixins: [AbstractWidget], + data(){ + return { + statusData: [], + role: 0 + }; + }, + mounted(){ + this.getTodos(); + }, + computed: { + countTodosLeitung(){ + return this.statusData.length; + }, + countTodosAss(){ + return this.statusData.reduce( + (sum, item) => sum + item.anzahl, + 0 + ); + }, + linkStudstatus(){ + return ( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + "/lehre/Studierendenantrag/leitung/" + ); + }, + }, + methods: { + getTodos(){ + this.$api + .call(ApiStudstatus.getTodos()) + .then(result => { + this.statusData = result.data[0]; + this.role = result.data[1]; + }) + .catch(this.$fhcAlert.handleSystemError); + } + }, + template:/*html*/` +
+
+ {{$p.t('dashboard','noPermissionStudstatus')}} +
+
+

{{countTodosLeitung}} {{$p.t('dashboard','antraegeToEdit')}}:

+ +
+ {{status.typ}} {{status.vorname}} {{status.nachname}} ({{status.prestudent_id}}) +
+
+
+ {{countTodosAss}} {{$p.t('dashboard','antraegeOpen')}}: +

+ +
+ {{status.studiengang}} ({{status.anzahl}}) +
+
+
+ {{$p.t('dashboard','antraegeNoOpen')}} +
+ + +
+ ` +}; \ No newline at end of file diff --git a/public/js/components/Studierendenantrag/Antrag.js b/public/js/components/Studierendenantrag/Antrag.js index b04801075..d0543fae2 100644 --- a/public/js/components/Studierendenantrag/Antrag.js +++ b/public/js/components/Studierendenantrag/Antrag.js @@ -21,7 +21,7 @@ export default { studierendenantragId: Number, infoArray: Array, statusMsg: String, - statusSeverity: String + statusSeverity: String, }, data() { return { diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index d43f1f3d3..88beecc41 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -95,6 +95,7 @@ require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php'); require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php'); require_once('dbupdate_3.4/70376_lohnguide.php'); require_once('dbupdate_3.4/75888_reihungstest_mehrfachdurchfuehrung.php'); +require_once('dbupdate_3.4/77048_cis4_mitarbeiter_studstatus_widget.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/77048_cis4_mitarbeiter_studstatus_widget.php b/system/dbupdate_3.4/77048_cis4_mitarbeiter_studstatus_widget.php new file mode 100644 index 000000000..f132a98ca --- /dev/null +++ b/system/dbupdate_3.4/77048_cis4_mitarbeiter_studstatus_widget.php @@ -0,0 +1,44 @@ +db_query("SELECT 1 FROM dashboard.tbl_widget WHERE widget_kurzbz= 'studstatus';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = " + INSERT INTO dashboard.tbl_widget ( + widget_id, + widget_kurzbz, + beschreibung, + arguments, + setup + ) + VALUES ( + 9, + 'studstatus', + 'Widget Todos Studierendenstatus', + '{ + \"css\": \"d-flex justify-content-center align-items-center h-100\", + \"title\": \"Tasks Studstatus\" + }'::jsonb, + '{ + \"file\": \"public/js/components/DashboardWidget/StudStatus.js\", + \"icon\": \"/skin/images/fh_technikum_wien_illustration_klein.png\", + \"name\": \"Studierendenstatus\", + \"width\": { + \"max\": 2, + \"min\": 1 + }, + \"height\": { + \"max\": 2, + \"min\": 1 + }, + \"hideFooter\": true + }'::jsonb + );"; + + if(!$db->db_query($qry)) + echo 'dashboard.tbl_widget: '.$db->db_last_error().'
'; + else + echo '
dashboard.tbl_widget: Widget studstatus hinzugefuegt!
'; + } +} diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 5f6269365..c5e2bca35 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -58177,6 +58177,108 @@ I have been informed that I am under no obligation to consent to the transmissio ) ), // ### Phrases Dashboard Admin END + // ### Phrases Dashboard Studstatus Widget START + array( + 'app' => 'core', + 'category' => 'dashboard', + 'phrase' => 'antraegeToEdit', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'zu bearbeitende Studierendenanträge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Student applications to be processed', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'dashboard', + 'phrase' => 'antraegeOpen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'offene Studierendenanträge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'open student applications', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'dashboard', + 'phrase' => 'antraegeNoOpen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine offenen Studierendenanträge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No open student applications', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'dashboard', + 'phrase' => 'linkVerwaltungStudstatus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zur Verwaltung des Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Link to the administration of the student status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'dashboard', + 'phrase' => 'noPermissionStudstatus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Berechtigung für Bearbeitung von Studierendenanträgen.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No permission to process student applications.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + // ### Phrases Dashboard Studstatus Widget END );