cis4 myLv employee functionality implemented; wrote new query fetching studiensemester an employee in which he had assigned lehraufträge; afterwards fetch all lva by employee uid and sem_kurzbz so they fit in the existing component structure; MyLv/Lvs/SS2026 etc now also returns a 'student' | 'employee' string based on path taken inside the controller to aid vue components in rendering useful information and avoiding senseless fetch requests -> e.g. employees cant have grades on lva they are teaching; added component names for sanity when using vuedevtools;

This commit is contained in:
Johann Hoffmann
2026-04-07 16:07:10 +02:00
parent 2c057aad58
commit ac44b36b59
9 changed files with 118 additions and 18 deletions
@@ -44,13 +44,28 @@ class Mylv extends Auth_Controller
public function Studiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID());
$isMitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter(getAuthUID())) ?? false;
$isStudent = getData($this->StudentModel->isStudent(getAuthUID())) ?? false;
if($isMitarbeiter) {
$result = $this->StudiensemesterModel->getWhereMitarbeiterHasLvs(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
$this->outputJsonSuccess(getData($result));
} else if($isStudent) { // $isStudent
$result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
} else {
$this->outputJsonError('neither student or mitarbeiter');
}
}
/**
@@ -58,13 +73,27 @@ class Mylv extends Auth_Controller
public function Lvs($studiensemester_kurzbz)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
$isMitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter(getAuthUID())) ?? false;
if($isMitarbeiter) {
$result = $this->LehrveranstaltungModel->getLvsByMitarbeiterInSemester(getAuthUID(), $studiensemester_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
$this->outputJsonSuccess([getData($result), 'employee']);
} else if(getData($this->StudentModel->isStudent(getAuthUID())) ?? false) { // $isStudent
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess([getData($result), 'student']);
} else {
$this->outputJsonError('neither student or mitarbeiter');
}
}
/**
@@ -1343,4 +1343,35 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, $params);
}
// used for cis4 mylv mitarbeiter
public function getLvsByMitarbeiterInSemester($mitarbeiter_uid, $sem_kurzbz) {
$qry = "SELECT
public.tbl_studiengang.studiengang_kz,
lehre.tbl_lehrveranstaltung.semester,
public.tbl_studiengang.bezeichnung as sg_bezeichnung,
public.tbl_studiengang.english as sg_bezeichnung_eng,
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as studiengang_kuerzel,
lehre.tbl_lehrveranstaltung.lehrveranstaltung_id,
lehre.tbl_lehrveranstaltung.bezeichnung,
lehre.tbl_lehrveranstaltung.bezeichnung_english as bezeichnung_eng,
lehre.tbl_lehrveranstaltung.farbe,
lehre.tbl_lehrveranstaltung.lvinfo,
lehre.tbl_lehrveranstaltung.benotung,
lehre.tbl_lehrveranstaltung.orgform_kurzbz,
lehre.tbl_lehrveranstaltung.sprache,
lehre.tbl_lehrveranstaltung.ects,
lehre.tbl_lehrveranstaltung.incoming
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 studiengang_kuerzel, lehre.tbl_lehrveranstaltung.semester, lehre.tbl_lehrveranstaltung.bezeichnung";
return $this->execReadOnlyQuery($qry, [$sem_kurzbz, $mitarbeiter_uid]);
}
}
@@ -242,6 +242,30 @@ class Studiensemester_model extends DB_Model
return $this->loadWhere(['uid' => $student_uid, 'v.lehre' => true]);
}
public function getWhereMitarbeiterHasLvs($uid) {
// first order by year with last 2 letter from right,
// then order by WS/SS inside the years
// query it asc so the ordering magic in cis4 turns it around again
$qry = "WITH unique_semesters AS (
SELECT DISTINCT ON (studiensemester_kurzbz)
studiensemester_kurzbz,
start,
ende,
bezeichnung,
studienjahr_kurzbz
FROM lehre.tbl_lehreinheit
JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id)
JOIN public.tbl_studiensemester USING(studiensemester_kurzbz)
WHERE mitarbeiter_uid = ?
)
SELECT * FROM unique_semesters
ORDER BY
RIGHT(studiensemester_kurzbz, 2) ASC,
LEFT(studiensemester_kurzbz, 2) ASC;";
return $this->execReadOnlyQuery($qry, [$uid]);
}
public function getAktAndFutureSemester()
{
$query = 'SELECT studiensemester_kurzbz
+1
View File
@@ -1,5 +1,6 @@
export default {
name: 'LvMenu',
props:{
menu:{
type:Array,
@@ -4,7 +4,7 @@ import LvMenu from "./LvMenu.js";
import ApiAddons from '../../../api/factory/addons.js';
export default {
name: 'LvUebersicht',
props:{
event:{
type:Object,
@@ -1,6 +1,7 @@
import MylvSemesterStudiengang from "./Semester/Studiengang.js";
export default {
name: 'Semester',
components: {
MylvSemesterStudiengang
},
@@ -2,6 +2,7 @@ import MylvSemesterStudiengangLv from "./Studiengang/Lv.js";
import Phrasen from "../../../../mixins/Phrasen.js";
export default {
name: 'Studiengang',
components: {
MylvSemesterStudiengangLv
},
@@ -9,13 +9,14 @@ import ApiAddons from '../../../../../api/factory/addons.js';
// TODO(chris): L10n
export default {
name: 'Lv',
components:{
LvUebersicht,
},
mixins: [
Phrasen
],
inject: ['studien_semester'],
inject: ['studien_semester', 'type'],
props: {
lehrveranstaltung_id: Number,
bezeichnung: String,
@@ -152,12 +153,16 @@ export default {
}
},
created() {
this.$api
.call(ApiLehre.getStudentPruefungen(this.lehrveranstaltung_id))
.then(res => res.data)
.then(pruefungen => {
this.pruefungenData = pruefungen;
});
// TODO: check if this isnt a race condition in disguise
if(this.type == 'student') {
this.$api
.call(ApiLehre.getStudentPruefungen(this.lehrveranstaltung_id))
.then(res => res.data)
.then(pruefungen => {
this.pruefungenData = pruefungen;
});
}
},
mounted() {
this.fetchMenu(this.lehrveranstaltung_id, this.studien_semester);
@@ -204,7 +209,7 @@ export default {
</div>
</template>
</div>
<div v-if="!emptyMenu" class="card-footer">
<div v-if="!emptyMenu && type == 'student'" class="card-footer">
<div class="row">
<!-- template for the LV if there are multiple pruefungen -->
<template v-if="LvHasPruefungenInformation">
+9 -1
View File
@@ -5,6 +5,7 @@ import Phrasen from "../../../mixins/Phrasen.js";
// TODO(chris): phrase: next & prev +aria-label
export default {
name: 'Student',
components: {
MylvSemester
},
@@ -16,9 +17,15 @@ export default {
firstLoad: true,
studiensemester: null,
lvs: {},
type: null,
currentSemester: null
};
},
provide() {
return {
type: Vue.computed(() => this.type)
}
},
computed: {
ready() {
return this.studiensemester !== null && (!this.firstLoad || this.current.lvs !== null);
@@ -32,7 +39,8 @@ export default {
lvs: null
};
axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Cis/Mylv/Lvs/' + this.currentSemester).then(res => {
this.lvs[this.currentSemester].lvs = res.data.retval || [];
this.lvs[this.currentSemester].lvs = res.data.retval[0] || [];
this.type = res.data.retval[1] // student or employee
this.firstLoad = false;
});
}