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/noteneingabeSpeichern') }}
+
+
+
+
+
+
+
+
+
+
+
{{$p.t('benotungstool/benotungstoolTitle')}}
+ {{ lv?.bezeichnung }}
+
+
+
+
+
+ {{ option.fullString }}
+
+
+
+
+
+
+
+
+ {{ option.studiensemester_kurzbz }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `,
+};
+
+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 ------------------------------------------------------------------------------------
+
+
);