From 5bbf05ac8abf4346802a5109f389af5b3442ac59 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Mon, 12 May 2025 12:50:56 +0200 Subject: [PATCH] WIP Gesamtnoteneingabe Notenberechnung endpoint --- application/config/routes.php | 1 + application/controllers/Cis/Benotungstool.php | 36 ++ .../controllers/api/frontend/v1/Lehre.php | 37 +- .../controllers/api/frontend/v1/Noten.php | 94 ++++ .../api/frontend/v1/Studiensemester.php | 67 +++ .../education/Lehrveranstaltung_model.php | 20 + application/models/education/Note_model.php | 9 + .../models/education/Pruefung_model.php | 15 + .../views/CisRouterView/CisRouterView.php | 3 +- public/js/api/factory/lehre.js | 20 + public/js/api/factory/noten.js | 39 ++ public/js/api/factory/studiensemester.js | 25 + public/js/apps/Dashboard/Fhc.js | 7 + .../Cis/Benotungstool/Benotungstool.js | 337 ++++++++++++++ system/phrasesupdate.php | 427 +++++++++++++++++- 15 files changed, 1134 insertions(+), 3 deletions(-) create mode 100644 application/controllers/Cis/Benotungstool.php create mode 100644 application/controllers/api/frontend/v1/Noten.php create mode 100644 application/controllers/api/frontend/v1/Studiensemester.php create mode 100644 public/js/api/factory/noten.js create mode 100644 public/js/api/factory/studiensemester.js create mode 100644 public/js/components/Cis/Benotungstool/Benotungstool.js diff --git a/application/config/routes.php b/application/config/routes.php index eb4c267ce..e031305ee 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -62,6 +62,7 @@ $route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/b $route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1'; $route['Cis/Stundenplan/.*'] = 'Cis/Stundenplan/index/$1'; +$route['Cis/Benotungstool/.*'] = 'Cis/Benotungstool/index/$1'; // load routes from extensions $subdir = 'application/config/extensions'; diff --git a/application/controllers/Cis/Benotungstool.php b/application/controllers/Cis/Benotungstool.php new file mode 100644 index 000000000..30d4ed0c1 --- /dev/null +++ b/application/controllers/Cis/Benotungstool.php @@ -0,0 +1,36 @@ + self::PERM_LOGGED + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $viewData = array( + 'uid'=>getAuthUID(), + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Benotungstool']); + } + +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/Lehre.php b/application/controllers/api/frontend/v1/Lehre.php index f079a5b37..237f97090 100644 --- a/application/controllers/api/frontend/v1/Lehre.php +++ b/application/controllers/api/frontend/v1/Lehre.php @@ -31,10 +31,15 @@ class Lehre extends FHCAPI_Controller 'lvStudentenMail' => self::PERM_LOGGED, 'LV' => self::PERM_LOGGED, 'Pruefungen' => self::PERM_LOGGED, + 'getLvViewData' => self::PERM_LOGGED, + 'getZugewieseneLv' => self::PERM_LOGGED ]); + // Loads phrases system + $this->loadPhrases([ + 'global' + ]); - } //------------------------------------------------------------------------------------------------------------------ @@ -94,6 +99,36 @@ class Lehre extends FHCAPI_Controller $this->terminateWithSuccess($result); } + + /** + * fetches all assigned lehrveranstaltungen of a mitarbeiter for a given semester + * @param mixed $uid + * @param mixed $sem_kurzbz + * @return void + */ + public function getZugewieseneLv() { + $uid = $this->input->get("uid",TRUE); + $sem_kurzbz = $this->input->get("sem_kurzbz",TRUE); + + if(!isset($sem_kurzbz) || isEmptyString($sem_kurzbz)) + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + + if (!isset($uid) || isEmptyString($uid)) + $uid = getAuthUID(); + + // querying other ma_uids data requires admin permission + if($uid !== getAuthUID()) { + $this->load->library('PermissionLib'); + $isAdmin = $this->permissionlib->isBerechtigt('admin'); + if(!$isAdmin) $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); + } + + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $result = $this->LehrveranstaltungModel->getLvForLektorInSemester($sem_kurzbz, $uid); + $data = $this->getDataOrTerminateWithError($result); + $this->terminateWithSuccess($data); + } + diff --git a/application/controllers/api/frontend/v1/Noten.php b/application/controllers/api/frontend/v1/Noten.php new file mode 100644 index 000000000..50447786c --- /dev/null +++ b/application/controllers/api/frontend/v1/Noten.php @@ -0,0 +1,94 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +require_once(__DIR__.'/../../../../../include/lehreinheit.class.php'); +require_once(__DIR__.'/../../../../../include/legesamtnote.class.php'); +class Noten extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getStudentenNoten' => self::PERM_LOGGED, // todo: berechtigung + 'getNoten' => self::PERM_LOGGED, + 'saveStudentenNoten' => self::PERM_LOGGED // todo: berechtigungen! + ]); + + $this->load->library('AuthLib', null, 'AuthLib'); + + // Loads phrases system + $this->loadPhrases([ + 'global' + ]); + + } + + public function getStudentenNoten() { + $lv_id = $this->input->get("lv_id",TRUE); + $sem_kurzbz = $this->input->get("sem_kurzbz",TRUE); + $active = true; // todo: check this param + + if (!isset($lv_id) || isEmptyString($lv_id) + || !isset($sem_kurzbz) || isEmptyString($sem_kurzbz)) + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + + // todo: check various other berechtigungen if its mitarbeiter/lektor/zugeteilterLektor? + + $this->load->model('education/Pruefung_model', 'PruefungModel'); + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + // get studenten for lva & sem with zeugnisnote if available + $studenten = $this->LehrveranstaltungModel->getStudentsByLv($sem_kurzbz, $lv_id, $active); + $studentenData = $this->getDataOrTerminateWithError($studenten); + + + + // get all prüfungen with noten held in that semester in that lva + $pruefungen = $this->PruefungModel->getPruefungenByLvStudiensemester($lv_id, $sem_kurzbz); + $pruefungenData = $this->getDataOrTerminateWithError($pruefungen); + + $this->terminateWithSuccess(array($studentenData, $pruefungenData, DOMAIN)); + } + + public function getNoten() { + $this->load->model('education/Note_model', 'NoteModel'); + + $result = $this->NoteModel->getAll(); + $noten = $this->getDataOrTerminateWithError($result); + $this->terminateWithSuccess($noten); + } + + public function saveStudentenNoten() { + $result = $this->getPostJSON(); + + if(!property_exists($result, 'password')) { + $this->terminateWithError($this->p->t('global', 'missingParameters'), 'general'); + } + + // TODO: send & save noten + + $this.$this->terminateWithSuccess($this->AuthLib->checkUserAuthByUsernamePassword(getAuthUID(), $result->password)); + } + +} + diff --git a/application/controllers/api/frontend/v1/Studiensemester.php b/application/controllers/api/frontend/v1/Studiensemester.php new file mode 100644 index 000000000..44f236a3c --- /dev/null +++ b/application/controllers/api/frontend/v1/Studiensemester.php @@ -0,0 +1,67 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); +class Studiensemester extends FHCAPI_Controller +{ + + private $_ci; + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getStudiensemester'=> self::PERM_LOGGED, + + ]); + + $this->_ci =& get_instance(); + + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * GET METHOD + * returns List of all studiensemester as well as current one + */ + public function getStudiensemester() + { + $this->_ci->StudiensemesterModel->addOrder("start", "DESC"); + $result = $this->_ci->StudiensemesterModel->load(); + + $studiensemester = getData($result); + $result = $this->_ci->StudiensemesterModel->getAkt(); + $aktuell = getData($result); + + $this->terminateWithSuccess(array($studiensemester, $aktuell)); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + + +} + diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 056fb45d7..883c6d9ca 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -988,4 +988,24 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($qry, $params); } + + public function getLvForLektorInSemester($sem_kurzbz, $uid) { + $qry = "SELECT DISTINCT (tbl_lehrveranstaltung.lehrveranstaltung_id), + UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as stg_kurzbz, + tbl_lehrveranstaltung.semester as lv_semester, + tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, + (SELECT kurzbz FROM public.tbl_mitarbeiter + WHERE mitarbeiter_uid=tbl_lehreinheitmitarbeiter.mitarbeiter_uid) as lektor + FROM + lehre.tbl_lehreinheit JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN public.tbl_studiengang USING(studiengang_kz) + JOIN lehre.tbl_lehrveranstaltung as lehrfach ON(tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id) + WHERE + tbl_lehreinheit.studiensemester_kurzbz = ? + AND mitarbeiter_uid = ? + ORDER BY stg_kurzbz,lv_semester,lv_bezeichnung"; + + return $this->execReadOnlyQuery($qry, array($sem_kurzbz, $uid)); + } } diff --git a/application/models/education/Note_model.php b/application/models/education/Note_model.php index 80b454398..fe601b1f9 100644 --- a/application/models/education/Note_model.php +++ b/application/models/education/Note_model.php @@ -11,4 +11,13 @@ class Note_model extends DB_Model $this->dbTable = 'lehre.tbl_note'; $this->pk = 'note'; } + + public function getAll() { + $qry ="SELECT * + FROM lehre.tbl_note"; + + return $this->execReadOnlyQuery($qry); + } + + } \ No newline at end of file diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index 927d83c82..d3cc72d69 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -306,4 +306,19 @@ class Pruefung_model extends DB_Model return $this->loadWhereCommitteeExamsFailed(); } + + public function getPruefungenByLvStudiensemester($lv_id, $sem_kurzbz) { + $qry = "SELECT tbl_pruefung.*, tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung, tbl_lehrveranstaltung.lehrveranstaltung_id, + tbl_note.bezeichnung as note_bezeichnung, tbl_pruefungstyp.beschreibung as typ_beschreibung, tbl_lehreinheit.studiensemester_kurzbz as studiensemester_kurzbz + FROM lehre.tbl_pruefung, lehre.tbl_lehreinheit, lehre.tbl_lehrveranstaltung, lehre.tbl_note, lehre.tbl_pruefungstyp + WHERE tbl_pruefung.lehreinheit_id=tbl_lehreinheit.lehreinheit_id + AND tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id + AND tbl_pruefung.note = tbl_note.note + AND tbl_pruefung.pruefungstyp_kurzbz=tbl_pruefungstyp.pruefungstyp_kurzbz + AND tbl_lehrveranstaltung.lehrveranstaltung_id = ? + AND tbl_lehreinheit.studiensemester_kurzbz = ? + ORDER BY datum DESC;"; + + return $this->execReadOnlyQuery($qry, array($lv_id, $sem_kurzbz)); + } } diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index 4590b210e..9d24d9a68 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -23,7 +23,8 @@ $includesArray = array( ), 'customJSs' => array( 'vendor/npm-asset/primevue/accordion/accordion.js', - 'vendor/npm-asset/primevue/accordiontab/accordiontab.js' + 'vendor/npm-asset/primevue/accordiontab/accordiontab.js', + 'vendor/npm-asset/primevue/password/password.js' ), 'customJSModules' => array( 'public/js/apps/Dashboard/Fhc.js' diff --git a/public/js/api/factory/lehre.js b/public/js/api/factory/lehre.js index 84c8e8662..f9306839e 100644 --- a/public/js/api/factory/lehre.js +++ b/public/js/api/factory/lehre.js @@ -35,5 +35,25 @@ export default { method: 'get', url: `/api/frontend/v1/Lehre/Pruefungen/${lehrveranstaltung_id}` }; + }, + getStudentenNoten(lv_id, sem_kurzbz) { + return { + method: 'get', + url: '/api/frontend/v1/Noten/getStudentenNoten', + params: { lv_id, sem_kurzbz } + }; + }, + getNoten(){ + return { + method: 'get', + url: '/api/frontend/v1/Noten/getNoten' + }; + }, + getZugewieseneLv(uid, sem_kurzbz){ + return { + method: 'get', + url: '/api/frontend/v1/Lehre/getZugewieseneLv', + params: { uid, sem_kurzbz} + }; } }; \ No newline at end of file diff --git a/public/js/api/factory/noten.js b/public/js/api/factory/noten.js new file mode 100644 index 000000000..e0343cb4b --- /dev/null +++ b/public/js/api/factory/noten.js @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2025 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 { + getStudentenNoten(lv_id, sem_kurzbz) { + return { + method: 'get', + url: '/api/frontend/v1/Noten/getStudentenNoten', + params: { lv_id, sem_kurzbz } + }; + }, + getNoten(){ + return { + method: 'get', + url: '/api/frontend/v1/Noten/getNoten' + }; + }, + saveStudentenNoten(password) { + return { + method: 'post', + url: '/api/frontend/v1/Noten/saveStudentenNoten', + params: { password } + }; + } +}; \ No newline at end of file diff --git a/public/js/api/factory/studiensemester.js b/public/js/api/factory/studiensemester.js new file mode 100644 index 000000000..ac4819e98 --- /dev/null +++ b/public/js/api/factory/studiensemester.js @@ -0,0 +1,25 @@ +/** + * Copyright (C) 2025 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 { + getStudiensemester() { + return { + method: 'get', + url: '/api/frontend/v1/Studiensemester/getStudiensemester' + }; + }, +}; \ No newline at end of file diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 3b6bb5683..707961078 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -9,6 +9,7 @@ import CmsNews from "../../components/Cis/Cms/News.js"; import CmsContent from "../../components/Cis/Cms/Content.js"; import Info from "../../components/Cis/Mylv/Semester/Studiengang/Lv/Info.js"; import RoomInformation, {DEFAULT_MODE_RAUMINFO} from "../../components/Cis/Mylv/RoomInformation.js"; +import Benotungstool from "../../components/Cis/Benotungstool/Benotungstool.js"; const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; @@ -27,6 +28,12 @@ const router = VueRouter.createRouter({ component: Profil, props: true }, + { + path: `/Cis/Benotungstool/:lv_id/:sem_kurzbz`, + name: 'Benotungstool', + component: Benotungstool, + props: true + }, // Redirect old links to new format { diff --git a/public/js/components/Cis/Benotungstool/Benotungstool.js b/public/js/components/Cis/Benotungstool/Benotungstool.js new file mode 100644 index 000000000..6dd968316 --- /dev/null +++ b/public/js/components/Cis/Benotungstool/Benotungstool.js @@ -0,0 +1,337 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import ApiLehre from "../../../api/factory/lehre.js"; +import ApiNoten from "../../../api/factory/noten.js"; +import ApiStudiensemester from "../../../api/factory/studiensemester.js"; +import BsModal from '../../Bootstrap/Modal.js'; + +export const Benotungstool = { + name: "Benotungstool", + components: { + BsModal, + CoreFilterCmpt, + Dropdown: primevue.dropdown, + Password: primevue.password + }, + props: { + lv_id: { + default: null, + required: true + }, + sem_kurzbz: { + default: null, + required: true + }, + viewData: { + type: Object, + required: true, + default: () => ({name: '', uid: ''}), + validator(value) { + return value && value.name && value.uid + } + } + }, + data() { + return { + password: '', + tabulatorUuid: Vue.ref(0), + domain: '', + lv: null, + studenten: null, + pruefungen: null, + studiensemester: null, + selectedSemester: null, + lehrveranstaltungen: null, + selectedLehrveranstaltung: null, + tableBuiltResolve: null, + notenOptions: null, + tableBuiltPromise: null, + notenTableOptions: { + height: 700, + index: 'student_uid', + layout: 'fitColumns', + placeholder: this.$p.t('global/noDataAvailable'), + columns: [ + {title: Vue.computed(() => this.$p.t('benotungstool/c4mail')), field: 'email', formatter: this.mailFormatter, tooltip: false, widthGrow: 1}, + {title: 'UID', field: 'uid', tooltip: false, widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4vorname')), field: 'vorname', tooltip: false, widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4nachname')), field: 'nachname', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4teilnoten')), field: 'teilnoten', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4note')), field: 'note_vorschlag', + editor: 'list', + editorParams: { + values: Vue.computed(()=>this.notenOptions.map(opt => { + return { + label: opt.bezeichnung, + value: opt.note + } + })) + }, + formatter: (cell) => { + const value = cell.getValue() + const match = this.notenOptions.find(opt => opt.note === value) + return match ? match.bezeichnung : value + }, + widthGrow: 1}, + {title: '', width: 50, hozAlign: 'center', formatter: this.arrowFormatter, cellClick: this.saveNote}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4lvnote')), field: 'lv_note', + formatter: (cell) => { + const value = cell.getValue() + const match = this.notenOptions.find(opt => opt.note === value) + return match ? match.bezeichnung : value + }, + widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4freigabe')), field: 'freigegeben', widthGrow: 1}, + {title: Vue.computed(() => this.$p.t('benotungstool/c4zeugnisnote')), field: 'note', widthGrow: 1} + // {title: Vue.computed(() => this.$p.t('benotungstool/c4termin1')), field: 'termin1', widthGrow: 1}, + // {title: Vue.computed(() => this.$p.t('benotungstool/c4termin2')), field: 'termin2', widthGrow: 1}, + // {title: Vue.computed(() => this.$p.t('benotungstool/c4termin3')), field: 'termin3', widthGrow: 1} + ], + persistence: false, + }, + notenTableEventHandlers: [{ + event: "tableBuilt", + handler: async () => { + this.tableBuiltResolve() + } + }, + { + event: "cellClick", + handler: async (e, cell) => { + + + + } + } + ]}; + }, + methods: { + handlePasswordChanged(pw) { + console.log('pw:', pw) + }, + saveNote(e, cell) { + const row = cell.getRow() + const data = row.getData() + + row.update({ note: data.note_vorschlag }) + }, + arrowFormatter(cell) { + return '
' + + '
' + }, + mailFormatter(cell) { + const val = cell.getValue() + return '
' + + '
' + }, + buildMailToLink(student){ + return 'mailto:' + student.uid +'@'+ this.domain + }, + tableResolve(resolve) { + this.tableBuiltResolve = resolve + }, + setupData(data){ + this.studenten = data[0] + this.pruefungen = data[1] + this.domain = data[2] + + this.pruefungen.forEach(p => { + const student = this.studenten.find(s => s.uid === p.student_uid) + + if(!student) return + // TODO: fetch typen and remove hardcoded strings + // TODO: dynamic amount of termin columns! + // if(p.pruefungstyp_kurzbz == "Termin1") { + // student.termin1 = p + // } else if (p.pruefungstyp_kurzbz == "Termin2") { + // student.termin2 = p + // } else if (p.pruefungstyp_kurzbz == "Termin3") { + // student.termin3 = p + // } + + // TODO: LE TEILNOTEN IN BACKEND LADEN, BERECHNEN UND VORSCHLAG PASTEN + // if(p.negativ) + student.teilnoten = '' + }) + + this.studenten.forEach(s => { + s.email = this.buildMailToLink(s) + }) + + this.$refs.notenTable.tabulator.clearSort() + this.$refs.notenTable.tabulator.setColumns(this.notenTableOptions.columns) + this.$refs.notenTable.tabulator.setData(this.studenten); + }, + loadNoten(lv_id, sem_kurzbz) { + this.$api.call(ApiNoten.getStudentenNoten(lv_id, sem_kurzbz)) + .then(res => { + if(res?.data) this.setupData(res.data) + }) + }, + handleUuidDefined(uuid) { + this.tabulatorUuid = uuid + }, + calcMaxTableHeight() { + const tableID = this.tabulatorUuid ? ('-' + this.tabulatorUuid) : '' + const tableDataSet = document.getElementById('filterTableDataset' + tableID); + if(!tableDataSet) return + const rect = tableDataSet.getBoundingClientRect(); + + this.notenTableOptions.height = window.visualViewport.height - rect.top + this.$refs.notenTable.tabulator.setHeight(this.notenTableOptions.height) + }, + async setupCreated() { + // fetch lva dropdown + this.$api.call(ApiLehre.getZugewieseneLv(this.viewData?.uid, this.sem_kurzbz)).then(res => { + console.log(res) + this.lehrveranstaltungen = res.data + + // build dropdown option string + this.lehrveranstaltungen.forEach(lva => { + lva.fullString = `${lva.stg_kurzbz} - ${lva.lv_semester}: ${lva.lv_bezeichnung}` + }) + + this.selectedLehrveranstaltung = this.lehrveranstaltungen.find(lva => lva.lehrveranstaltung_id == this.lv_id) + }) + + //fetch sem_kurzbz dropdown + this.$api.call(ApiStudiensemester.getStudiensemester()).then(res => { + this.studiensemester = res.data[0] + this.selectedSemester = this.studiensemester.find(sem => sem.studiensemester_kurzbz === this.sem_kurzbz) + }) + + // fetch noten dropdown + await this.$api.call(ApiNoten.getNoten()).then(res => { + this.notenOptions = res.data + }) + + }, + async setupMounted() { + this.tableBuiltPromise = new Promise(this.tableResolve) + await this.tableBuiltPromise + + this.loadNoten(this.lv_id, this.sem_kurzbz) + + this.calcMaxTableHeight() + + }, + lvChanged(e) { + this.$router.push({ + name: "Benotungstool", + params: { + sem_kurzbz: this.sem_kurzbz, + lv_id: e.value.lehrveranstaltung_id + } + }) + + // reload data + this.loadNoten(e.value.lehrveranstaltung_id, this.sem_kurzbz) + }, + ssChanged(e) { + // change url params & write history + this.$router.push({ + name: "Benotungstool", + params: { + sem_kurzbz: e.value.studiensemester_kurzbz, + lv_id: this.lv_id + } + }) + + // reload data + this.loadNoten(this.lv_id, e.value.studiensemester_kurzbz) + + }, + getOptionLabel(option) { + return option.studiensemester_kurzbz + }, + getOptionLabelLv(option) { + return option.fullString + }, + saveNoteneingabe() { + + this.$api.call(ApiNoten.saveStudentenNoten(this.password)) + + this.$refs.modalContainerNotenSpeichern.hide() + }, + openSaveModal() { + this.$refs.modalContainerNotenSpeichern.show() + } + }, + watch: { + + }, + computed: { + getSaveBtnClass() { + return "btn btn-primary ml-2" + // return !this.changedData.length ? "btn btn-secondary ml-2" : "btn btn-primary ml-2" + } + }, + created() { + this.setupCreated() + }, + mounted() { + this.setupMounted() + }, + template: ` + + + + + + +
+
+

{{$p.t('benotungstool/benotungstoolTitle')}}

+

{{ lv?.bezeichnung }}

+
+
+
+ + + +
+
+
+
+ + + +
+
+
+
+ + + + + + + `, +}; + +export default Benotungstool; \ No newline at end of file diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 1afe4a196..d15a9f266 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -41453,8 +41453,433 @@ and represent the current state of research on the topic. The prescribed citatio 'insertvon' => 'system' ) ) - ) + ), // PROJEKTARBEITSBEURTEILUNG SS2025 ENDE --------------------------------------------------------------------------- + // CIS4 GESAMTNOTENEINGABE START ----------------------------------------------------------------------------------- + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'benotungstoolTitle', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gesamtnote', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Final Grade', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4mail', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kontakt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Email', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4vorname', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vorname', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'First Name', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4nachname', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nachname', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Last Name', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4teilnoten', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Teilnoten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Partial Grades', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4note', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Punkte/Note', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Points/Grade', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4lvnote', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LV-Note', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Subject grade', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4freigabe', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Freigabe', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Approval', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4password', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Passwort', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Password', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4zeugnisnote', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zeugnisnote', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Transcript Grade', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4date', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Datum', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Date', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4grade', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Note', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Grade', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4termin1', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nachprüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Re-examination', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4termin2', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => '2. Nebenprüfungstermin', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => '2nd subsidiary examination date', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4termin3', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kommissionelle Prüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Oral Examination', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4anlegen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anlegen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Create', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4change', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ändern', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Change', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4import', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Importieren', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Import', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4changedGradesAvailable', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Es sind geänderte Noten vorhanden. Geben Sie diese frei, um die Assistenz zu informieren', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'There are changed grades. Please send the changes to the assistant by clicking "Approval"', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'c4gradeListExcel', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Notenliste für den LV-Noten-Import (Excel)', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Grade list for the subject grade import (Excel)', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'benotungstool', + 'phrase' => 'passwort', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Passwort', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Password', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ) + + // CIS4 GESAMTNOTENEINGABE ENDE ------------------------------------------------------------------------------------ + + );