Teacher Proposal

This commit is contained in:
cgfhtw
2024-11-20 11:06:28 +01:00
parent 5369c95e77
commit fe7ca2bf69
7 changed files with 539 additions and 3 deletions
@@ -30,7 +30,9 @@ class Grades extends FHCAPI_Controller
parent::__construct([
'list' => 'student/noten:r',
'getCertificate' => 'student/noten:r',
'getTeacherProposal' => 'student/noten:r',
'updateCertificate' => ['admin:w', 'assistenz:w'],
'copyTeacherProposalToCertificate' => 'student/noten:w',
'getGradeFromPoints' => 'student/noten:r'
]);
@@ -77,6 +79,32 @@ class Grades extends FHCAPI_Controller
$this->terminateWithSuccess($grades);
}
public function getTeacherProposal($prestudent_id, $all = null)
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
$result = $this->StudentModel->loadWhere([
'prestudent_id' => $prestudent_id
]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
$this->terminateWithSuccess([]);
$student_uid = current($student)->student_uid;
$studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null;
$result = $this->LvgesamtnoteModel->getLvGesamtNoten(null, $student_uid, $studiensemester_kurzbz);
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
public function updateCertificate()
{
$this->load->model('crm/Student_model', 'StudentModel');
@@ -136,6 +164,95 @@ class Grades extends FHCAPI_Controller
$this->terminateWithSuccess(true);
}
public function copyTeacherProposalToCertificate()
{
$this->load->library('form_validation');
$this->form_validation->set_rules("lehrveranstaltung_id", "Lehrverantaltung ID", "required|integer"); // TODO(chris): phrase
$this->form_validation->set_rules("student_uid", "Student UID", "required"); // TODO(chris): phrase
$this->form_validation->set_rules("studiensemester_kurzbz", "Studiensemester", "required"); // TODO(chris): phrase
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
$student_uid = $this->input->post('student_uid');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$authUID = getAuthUID();
// NOTE(chris): Stg Permissions
if (!$this->hasPermissionCopy($lehrveranstaltung_id, $student_uid))
return $this->_outputAuthError([$this->router->method => 'student/noten']);
$this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
$result = $this->LvgesamtnoteModel->load([
$student_uid,
$studiensemester_kurzbz,
$lehrveranstaltung_id
]);
$teacherGrade = $this->getDataOrTerminateWithError($result);
if (!$teacherGrade)
show_404();
$teacherGrade = current($teacherGrade);
$data = [
'note' => $teacherGrade->note,
'punkte' => $teacherGrade->punkte,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $teacherGrade->benotungsdatum,
'bemerkung' => $teacherGrade->bemerkung
];
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->ZeugnisnoteModel->addJoin('lehre.tbl_note n', 'note');
$result = $this->ZeugnisnoteModel->load([
$studiensemester_kurzbz,
$student_uid,
$lehrveranstaltung_id
]);
$certificateGrade = $this->getDataOrTerminateWithError($result);
if ($certificateGrade) {
$certificateGrade = current($certificateGrade);
if (!$certificateGrade->lkt_ueberschreibbar)
$this->terminateWithError("Nicht überschreibbar"); // TODO(chris): phrase
// NOTE(chris): update
$data['updateamum'] = $data['uebernahmedatum'];
$data['updatevon'] = $authUID;
$this->ZeugnisnoteModel->update([
$studiensemester_kurzbz,
$student_uid,
$lehrveranstaltung_id
], $data);
} else {
// NOTE(chris): insert
$data['insertamum'] = $data['uebernahmedatum'];
$data['insertvon'] = $authUID;
$data['lehrveranstaltung_id'] = $lehrveranstaltung_id;
$data['student_uid'] = $student_uid;
$data['studiensemester_kurzbz'] = $studiensemester_kurzbz;
$this->ZeugnisnoteModel->insert($data);
// TODO(chris): FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN
if (defined('FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN')
&& FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN) {
$result = $this->addTestsForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $teacherGrade->note, $teacherGrade->punkte);
$this->getDataOrTerminateWithError($result);// TODO(chris): terminate?
}
}
$this->terminateWithSuccess();
}
public function getGradeFromPoints()
{
$this->load->library('form_validation');
@@ -161,6 +278,68 @@ class Grades extends FHCAPI_Controller
$this->terminateWithSuccess($note);
}
protected function addTestsForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $note, $punkte)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
// Get Lehreinheit
$result = $this->LehrveranstaltungModel->getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id);
if (isError($result))
return $result;
if (!hasData($result))
return error('Fehler beim Ermitteln der Lehreinheit ID'); // TODO(chris): phrase
$le = current(getData($result));
// Prepare
$this->load->model('education/LePruefung_model', 'LePruefungModel');
$data = [
"student_uid" => $student_uid,
"lehreinheit_id" => $le->lehreinheit_id,
"datum" => date('Y-m-d'),
"pruefungstyp_kurzbz" => "Termin1", // TODO(chris): const?
"note" => $note
];
if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE)
$data["punkte"] = $punkte;
// Get Anwesenheit
$this->load->model('education/Anwesenheit_model', 'AnwesenheitModel');
$result = $this->AnwesenheitModel->loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id);
if (isError($result))
return $result;
$anwesenheit = getData($result);
if ($anwesenheit && (float)current($anwesenheit)->prozent < FAS_ANWESENHEIT_ROT) {
// Get Anwesenheitsbefreiung
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerFunktionByUidInStdsem($student_uid, $studiensemester_kurzbz, 'awbefreit');
if (isError($result))
return $result;
$anwesenheitsbefreit = hasData($result);
// Wenn nicht Anwesenheitsbefreit und Anwesenheit unter einem bestimmten Prozentsatz fällt dann wird ein Pruefungsantritt abgezogen
if (!$anwesenheitsbefreit) {
$data2 = $data;
$data2["note"] = 7; // TODO(chris): const?
if (isset($data2["punkte"]))
unset($data2["punkte"]);
$result = $this->LePruefungModel->insert($data2);
if (isError($result))
return $result;
$data["pruefungstyp_kurzbz"] = "Termin2"; // TODO(chris): const?
}
}
return $this->LePruefungModel->insert($data);
}
protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
{
// TODO(chris): error phrases!
@@ -197,4 +376,34 @@ class Grades extends FHCAPI_Controller
return error('Forbidden');
}
protected function hasPermissionCopy($lehrveranstaltung_id, $student_uid)
{
if ($lehrveranstaltung_id === null || $student_uid === null)
return true;
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
if (isError($result) || !hasData($result))
return false;
$student = current(getData($result));
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $student->studiengang_kz))
return true;
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
if (isError($result) || !hasData($result))
return false;
$oe = current(getData($result));
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->oe_kurzbz))
return true;
return false;
}
}
@@ -11,4 +11,193 @@ class Anwesenheit_model extends DB_Model
$this->dbTable = 'campus.tbl_anwesenheit';
$this->pk = 'anwesenheit_id';
}
/**
* Laedt die Anwesenheiten in Prozent von Studierenden bei Lehrveranstaltungen
* Wenn die StudentUID uebergeben wird, werden alle Lehrveranstaltungen zu denen der Studierenden zugeteilt ist inkl Prozent der Anwesenheit
* Wenn die LehrveranstaltungID uebergeben wird, werden alle Studierenden geholt die zugeteilt sind inkl Prozent der Anwesenheit
* Es werden pro Student die Anwesenheiten berechnet aufgrund der Lehreinheit zu der sie zugeordnet sind
*
* @param string $studiensemester_kurzbz
* @param string|null (optional) $student_uid
* @param integer|null (optional) $lehrveranstaltung_id
*
* @return stdClass
*/
public function loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid = null, $lehrveranstaltung_id = null)
{
$this->addSelect("vorname");
$this->addSelect("nachname");
$this->addSelect("wahlname");
$this->addSelect("lehrveranstaltung_id");
$this->addSelect("bezeichnung");
$this->addSelect("gruppe");
$this->addSelect("student_uid AS uid");
$this->addSelect("COUNT(stundenplan_id) AS gesamtstunden");
$this->addSelect("COALESCE(anwesend.summe, 0) AS anwesend");
$this->addSelect("COALESCE(nichtanwesend.summe, 0) AS nichtanwesend");
$this->addSelect("COALESCE(anwesend.summe, 0) + COALESCE(nichtanwesend.summe, 0) AS erfassteanwesenheit");
$this->addSelect("CASE
WHEN COUNT(stundenplan_id) = 0 OR COALESCE(anwesend.summe, 0) + COALESCE(nichtanwesend.summe, 0) = 0
THEN 100
ELSE TRUNC(100-(100/COUNT(stundenplan_id)*COALESCE(nichtanwesend.summe, 0)), 2)
END AS prozent");
$this->db->join("(
SELECT
semester::text AS gruppe,
public.tbl_studentlehrverband.studiensemester_kurzbz,
student_uid,
studiengang_kz
FROM public.tbl_studentlehrverband
WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
UNION
SELECT
semester || verband AS gruppe,
public.tbl_studentlehrverband.studiensemester_kurzbz,
student_uid,
studiengang_kz
FROM public.tbl_studentlehrverband
WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
UNION
SELECT
semester || verband || gruppe AS gruppe,
public.tbl_studentlehrverband.studiensemester_kurzbz,
student_uid,
studiengang_kz
FROM public.tbl_studentlehrverband
WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
UNION
SELECT
gruppe_kurzbz AS gruppe,
public.tbl_benutzergruppe.studiensemester_kurzbz,
uid AS student_uid,
studiengang_kz
FROM public.tbl_benutzergruppe
JOIN public.tbl_gruppe USING (gruppe_kurzbz)
WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
) a", "gruppe,studiensemester_kurzbz,studiengang_kz", "", false);
$this->addJoin("public.tbl_benutzer b", "b.uid = student_uid");
$this->addJoin("public.tbl_person p", "person_id");
$this->db->join("(
SELECT
lehrveranstaltung_id,
studiensemester_kurzbz, uid AS student_uid,
SUM(einheiten) AS summe
FROM campus.tbl_anwesenheit a
JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
WHERE anwesend = TRUE
AND studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
GROUP BY
lehrveranstaltung_id,
bezeichnung,
uid,
studiensemester_kurzbz
) anwesend", "lehrveranstaltung_id,student_uid,studiensemester_kurzbz", "LEFT", false);
$this->db->join("(
SELECT
lehrveranstaltung_id,
studiensemester_kurzbz,
uid AS student_uid,
SUM(einheiten) AS summe
FROM campus.tbl_anwesenheit a
JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
WHERE anwesend = FALSE
AND studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
GROUP BY
lehrveranstaltung_id, bezeichnung, uid, studiensemester_kurzbz
) nichtanwesend", "lehrveranstaltung_id,student_uid,studiensemester_kurzbz", "LEFT", false); // TODO(chris): use USING
$this->addGroupBy("vorname");
$this->addGroupBy("nachname");
$this->addGroupBy("wahlname");
$this->addGroupBy("lehrveranstaltung_id");
$this->addGroupBy("bezeichnung");
$this->addGroupBy("gruppe");
$this->addGroupBy("student_uid");
$this->addGroupBy("anwesend.summe");
$this->addGroupBy("nichtanwesend.summe");
$where = [
"lehrveranstaltung_id >" => 0
];
if ($student_uid)
$where["student_uid"] = $student_uid;
if ($lehrveranstaltung_id)
$where["lehrveranstaltung_id"] = $lehrveranstaltung_id;
if ($lehrveranstaltung_id) {
$this->addOrder("nachname");
$this->addOrder("vorname");
} elseif ($student_uid) {
$this->addOrder("bezeichnung");
}
$tmp = $this->dbTable;
$this->dbTable = "(
SELECT
SUM(stundenplan_id) AS stundenplan_id,
datum,
stunde,
lehrveranstaltung_id,
bezeichnung,
studiensemester_kurzbz,
studiengang_kz,
TRIM(
CASE
WHEN stp.gruppe_kurzbz IS NOT NULL
THEN stp.gruppe_kurzbz
ELSE stp.semester || (
CASE
WHEN verband IS NULL
THEN ''
ELSE stp.verband
END
) || (
CASE
WHEN stp.gruppe IS NULL
THEN ''
ELSE stp.gruppe
END
)
END
) AS gruppe
FROM lehre.tbl_lehrveranstaltung lv
JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id)
JOIN lehre.tbl_stundenplan stp USING (lehreinheit_id,studiengang_kz)
WHERE studiensemester_kurzbz = " . $this->escape($studiensemester_kurzbz) . "
AND (titel NOT LIKE '%Nebenprüfung%' OR titel IS NULL)
GROUP BY
datum,
stunde,
lehrveranstaltung_id,
bezeichnung,
studiensemester_kurzbz,
studiengang_kz,
stp.gruppe_kurzbz,
stp.semester,
stp.verband,
stp.gruppe
) x";
$result = $this->loadWhere($where);
$this->dbTable = $tmp;
return $result;
}
}
@@ -623,6 +623,37 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($query, array($uid, $studiensemester_kurzbz, $lehrveranstaltung_id));
}
/**
* Get Lehreinheit.
*
* @param $student_uid
* @param $studiensemester_kurzbz
* @param $lehrveranstaltung_id
*
* @return stdClass
*/
public function getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id)
{
$this->addSelect("lehreinheit_id");
$this->addOrder("lehreinheit_id", "ASC");
$this->addLimit(1);
$tmp = $this->dbTable;
$this->dbTable = "campus.vw_student_lehrveranstaltung";
$result = $this->loadWhere([
"uid" => $student_uid,
"lehrveranstaltung_id" => $lehrveranstaltung_id,
"studiensemester_kurzbz" => $studiensemester_kurzbz
]);
$this->dbTable = $tmp;
return $result;
}
/**
* Sucht nach LV Templates und gibt Id und Label ("bezeichnung [kurzbz]") aus
* Diese funktion ist für autocomplete gedacht
@@ -12,4 +12,38 @@ class Lvgesamtnote_model extends DB_Model
$this->pk = array('student_uid', 'studiensemester_kurzbz', 'lehrveranstaltung_id');
$this->hasSequence = false;
}
/**
* Laedt die Noten
*
* @param $lehrveranstaltung_id
* @param $student_uid
* @param $studiensemester_kurzbz
*
* @return stdClass
*/
public function getLvGesamtNoten($lehrveranstaltung_id, $student_uid, $studiensemester_kurzbz)
{
$this->addSelect($this->dbTable . ".*");
$this->addSelect("n.bezeichnung AS note_bezeichnung");
$this->addSelect("lv.bezeichnung AS lehrveranstaltung_bezeichnung");
$this->addSelect("lv.studiengang_kz");
$this->addSelect("UPPER(stg.typ || stg.kurzbz) AS studiengang");
$this->addJoin("lehre.tbl_note n", "note");
$this->addJoin("lehre.tbl_lehrveranstaltung lv", "lehrveranstaltung_id");
$this->addJoin("public.tbl_studiengang stg", "studiengang_kz");
$this->db->where($this->dbTable . ".freigabedatum <", "NOW()", false);
$where = [];
if ($studiensemester_kurzbz)
$where[$this->dbTable . ".studiensemester_kurzbz"] = $studiensemester_kurzbz;
if ($lehrveranstaltung_id)
$where[$this->dbTable . ".lehrveranstaltung_id"] = $lehrveranstaltung_id;
if ($student_uid)
$where[$this->dbTable . ".student_uid"] = $student_uid;
return $this->loadWhere($where);
}
}
@@ -50,6 +50,53 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($qry, $params);
}
/**
* Lädt alle Benutzerfunktionen zu einer UID im Zeitraum eines Studiensemesters
*
* @param string $uid
* @param string $stdsem
* @param string (optional) $funktion_kurzbz
*
* @return stdClass
*/
public function getBenutzerFunktionByUidInStdsem($uid, $stdsem, $funktion_kurzbz = null)
{
$stdsemEscaped = $this->escape($stdsem);
$this->addSelect($this->dbTable . ".*");
$this->addSelect("oe.bezeichnung AS organisationseinheit_bezeichnung");
$this->addSelect("oe.organisationseinheittyp_kurzbz");
$this->addJoin("public.tbl_organisationseinheit oe", "oe_kurzbz");
$this->db->where("uid", $uid);
if ($funktion_kurzbz !== null)
$this->db->where("funktion_kurzbz", $funktion_kurzbz);
$this->db->group_start();
$this->db->where("datum_bis IS NULL");
$this->db->or_where("datum_bis >=", "(
SELECT start
FROM public.tbl_studiensemester
WHERE studiensemester_kurzbz = " . $stdsemEscaped . "
)", false);
$this->db->group_end();
$this->db->group_start();
$this->db->where("datum_von IS NULL");
$this->db->or_where("datum_von <=", "(
SELECT ende
FROM public.tbl_studiensemester
WHERE studiensemester_kurzbz = " . $stdsemEscaped . "
)", false);
$this->db->group_end();
$this->addOrder("datum_bis", "NULLS LAST");
$this->addOrder("datum_von", "NULLS LAST");
return $this->load();
}
/**
* Get the Benutzerfunktion using the person_id
*/
+17
View File
@@ -6,9 +6,26 @@ export default {
all = all ? '/all' : '';
return this.$fhcApi.get('api/frontend/v1/stv/grades/getCertificate/' + prestudent_id + all);
},
getTeacherProposal(prestudent_id, all) {
all = all ? '/all' : '';
return this.$fhcApi.get('api/frontend/v1/stv/grades/getTeacherProposal/' + prestudent_id + all);
},
updateCertificate(data) {
return this.$fhcApi.post('api/frontend/v1/stv/grades/updateCertificate', data);
},
copyTeacherProposalToCertificate({lehrveranstaltung_id, student_uid, studiensemester_kurzbz, lehrveranstaltung_bezeichnung}) {
return this.$fhcApi.post(
'api/frontend/v1/stv/grades/copyTeacherProposalToCertificate',
{
lehrveranstaltung_id,
student_uid,
studiensemester_kurzbz
},
{
errorHeader: lehrveranstaltung_bezeichnung
}
);
},
getGradeFromPoints(points) {
return this.$fhcApi.post('api/frontend/v1/stv/grades/getGradeFromPoints', data);
}
@@ -1,8 +1,10 @@
import NotenZeugnis from './Noten/Zeugnis.js';
import NotenTeacher from './Noten/Teacher.js';
export default {
components: {
NotenZeugnis
NotenZeugnis,
NotenTeacher
},
props: {
modelValue: Object
@@ -13,7 +15,14 @@ export default {
}
},
template: `
<div class="stv-details-noten h-100 d-flex flex-column">
<noten-zeugnis ref="zeugnis" :student="modelValue"></noten-zeugnis>
<div class="stv-details-noten h-100 d-flex flex-column overflow-hidden">
<div class="row">
<div class="col-8">
<noten-zeugnis ref="zeugnis" :student="modelValue"></noten-zeugnis>
</div>
<div class="col-4">
<noten-teacher ref="teacher" :student="modelValue" @copied="reload"></noten-teacher>
</div>
</div>
</div>`
};