diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php
index 455b1e8fc..dd2eaed02 100644
--- a/application/controllers/api/frontend/v1/stv/Config.php
+++ b/application/controllers/api/frontend/v1/stv/Config.php
@@ -123,6 +123,11 @@ class Config extends FHCAPI_Controller
'config' => $config['finalexam']
];
+ $result['projektarbeit'] = [
+ 'title' => $this->p->t('stv', 'tab_projektarbeit'),
+ 'component' => './Stv/Studentenverwaltung/Details/Projektarbeit.js'
+ ];
+
$result['mobility'] = [
'title' => $this->p->t('stv', 'tab_mobility'),
'component' => './Stv/Studentenverwaltung/Details/Mobility.js'
diff --git a/application/controllers/api/frontend/v1/stv/Projektarbeit.php b/application/controllers/api/frontend/v1/stv/Projektarbeit.php
new file mode 100644
index 000000000..3be2b26a3
--- /dev/null
+++ b/application/controllers/api/frontend/v1/stv/Projektarbeit.php
@@ -0,0 +1,334 @@
+ ['admin:r', 'assistenz:r'],
+ 'loadProjektarbeit' => ['admin:r', 'assistenz:r'],
+ 'insertProjektarbeit' => ['admin:rw', 'assistenz:rw'],
+ 'updateProjektarbeit' => ['admin:rw', 'assistenz:rw'],
+ 'deleteProjektarbeit' => ['admin:rw', 'assistenz:rw'],
+ 'getTypenProjektarbeit' => ['admin:r', 'assistenz:r'],
+ 'getFirmen' => ['admin:r', 'assistenz:r'],
+ 'getLehrveranstaltungen' => ['admin:r', 'assistenz:r'],
+ 'getNoten' => ['admin:rw', 'assistenz:rw']
+ ]);
+
+ // Load Libraries
+ $this->load->library('form_validation');
+
+ // Load language phrases
+ $this->loadPhrases([
+ 'ui',
+ 'person',
+ 'projektarbeit'
+ ]);
+
+ // Load models
+ $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
+ $this->load->model('education/Projekttyp_model', 'ProjekttypModel');
+ $this->load->model('education/Paabgabe_model', 'PaabgabeModel');
+ $this->load->model('ressource/Firma_model', 'FirmaModel');
+ $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
+ $this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
+ $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
+ $this->load->model('education/Note_model', 'NoteModel');
+ $this->load->model('education/Projektbetreuer_model', 'BetreuerModel');
+
+ // load libraries
+ $this->load->library('PermissionLib');
+ }
+
+ public function getProjektarbeit()
+ {
+ $student_uid = $this->input->get('uid');
+
+ if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
+
+ $result = $this->ProjektarbeitModel->getProjektarbeit($student_uid);
+
+ if (isError($result))
+ {
+ $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
+ }
+
+ if (!hasData($result)) $this->terminateWithSuccess([]);
+
+ $projektarbeiten = getData($result);
+
+ foreach ($projektarbeiten as $projektarbeit)
+ {
+ $projektarbeit_id = $projektarbeit->projektarbeit_id;
+ $abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id);
+
+ if (isError($abgabeRes)) $this->terminateWithError(getError($abgabeRes), self::ERROR_TYPE_GENERAL);
+
+ if (hasData($abgabeRes))
+ {
+ $paabgabe = getData($abgabeRes)[0];
+ $projektarbeit->abgabedatum = $paabgabe->abgabedatum;
+ }
+ }
+
+ $this->terminateWithSuccess($projektarbeiten);
+ }
+
+ public function loadProjektarbeit()
+ {
+ $projektarbeit_id = $this->input->get('projektarbeit_id');
+
+ if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) return $this->terminateWithError('Projektarbeit Id missing', self::ERROR_TYPE_GENERAL);
+
+ $this->ProjektarbeitModel->addSelect(
+ 'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, firma_id,
+ lehrveranstaltung_id, lehreinheit_id, beginn, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
+ );
+ $this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
+ $this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
+ $this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id');
+ $result = $this->ProjektarbeitModel->loadWhere(
+ array('projektarbeit_id' => $projektarbeit_id)
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess(current($data));
+ }
+
+ public function insertProjektarbeit()
+ {
+ $student_uid = $this->input->post('uid');
+
+ if (!$student_uid) return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
+
+ if (!$this->_hasBerechtigungForStudent($student_uid))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
+
+ $formData = $this->input->post('formData');
+
+ $this->addMeta('form', $formData);
+
+ if ($this->_validate($formData) == false)
+ {
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+ }
+
+ $result = $this->ProjektarbeitModel->insert(
+ array_merge($formData, ['insertamum' => date('c'), 'insertvon' => getAuthUID(), 'student_uid' => $student_uid])
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function updateProjektarbeit()
+ {
+ $projektarbeit_id = $this->input->post('projektarbeit_id');
+
+ if (!$projektarbeit_id || !is_numeric($projektarbeit_id))
+ return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
+
+ if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
+
+ $formData = $this->input->post('formData');
+
+ if ($this->_validate($formData) == false)
+ {
+ $this->terminateWithValidationErrors($this->form_validation->error_array());
+ }
+
+ $result = $this->ProjektarbeitModel->update(
+ $projektarbeit_id,
+ array_merge($formData, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
+ );
+
+ $data = $this->getDataOrTerminateWithError($result);
+
+ $this->terminateWithSuccess($data);
+ }
+
+ public function deleteProjektarbeit()
+ {
+ $projektarbeit_id = $this->input->post('projektarbeit_id');
+
+ if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
+ return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID'], self::ERROR_TYPE_GENERAL));
+
+ if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
+ return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
+
+ $validate = $this->_validateDelete($projektarbeit_id);
+
+ if (isError($validate)) return $this->terminateWithError(getError($validate), self::ERROR_TYPE_GENERAL);
+
+ $result = $this->ProjektarbeitModel->delete(
+ array('projektarbeit_id' => $projektarbeit_id)
+ );
+
+ if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
+
+ if (!hasData($result))
+ {
+ $this->outputJson($result);
+ }
+
+ return $this->terminateWithSuccess(current(getData($result)) ? : null);
+ }
+
+ public function getTypenProjektarbeit()
+ {
+ $result = $this->ProjekttypModel->loadWhere(['aktiv' => true]);
+
+ if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
+
+ return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
+ }
+
+ public function getFirmen()
+ {
+ $searchString = $this->input->get('searchString');
+
+ if (!isset($searchString)) $this->terminateWithError($this->p->t('projektarbeit', 'error_searchStringMissing', self::ERROR_TYPE_GENERAL));
+
+ $result = $this->FirmaModel->searchFirmen($searchString, $aktiv = true);
+
+ if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
+
+ return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
+ }
+
+ public function getLehrveranstaltungen()
+ {
+ $student_uid = $this->input->get('student_uid');
+ $studiengang_kz = $this->input->get('studiengang_kz');
+ $studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
+ $additional_lehrveranstaltung_id = $this->input->get('additional_lehrveranstaltung_id');
+
+ if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
+ if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL);
+
+ $lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id);
+
+ if (isError($lvsResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
+
+ $lvs = hasData($lvsResult) ? getData($lvsResult) : [];
+
+ foreach ($lvs as $lv)
+ {
+ $lehreinheiten = $this->LehreinheitModel->getLesForLv(
+ $lv->lehrveranstaltung_id, $studiensemester_kurzbz
+ );
+
+ foreach ($lehreinheiten as $lehreinheit)
+ {
+ if (!isEmptyArray($lehreinheit->lektoren))
+ {
+ $this->MitarbeiterModel->addSelect('kurzbz');
+ $this->MitarbeiterModel->db->where_in('tbl_mitarbeiter.mitarbeiter_uid', $lehreinheit->lektoren);
+ $maResult = $this->MitarbeiterModel->load();
+
+ if (isError($maResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
+
+ $lehreinheit->lektoren = array_column(getData($maResult), 'kurzbz');
+ }
+ }
+
+ $lv->lehreinheiten = $lehreinheiten;
+ }
+
+ return $this->terminateWithSuccess($lvs);
+ }
+
+ public function getNoten()
+ {
+ $result = $this->NoteModel->load();
+
+ if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
+
+ return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
+ }
+
+ /**
+ *
+ * @param
+ * @return object success or error
+ */
+ private function _validate($formData)
+ {
+ $this->form_validation->set_data($formData);
+
+ $this->form_validation->set_rules('titel', 'Titel', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Titel'])
+ ]);
+
+ $this->form_validation->set_rules('projekttyp_kurzbz', 'Projekttyp', 'required', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Projekttyp'])
+ ]);
+
+ $this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'required|numeric', [
+ 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']),
+ //'matches' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']),
+ 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
+ ]);
+
+ $this->form_validation->set_rules('beginn', 'Beginn', 'is_valid_date', [
+ 'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Beginn'])
+ ]);
+
+ return $this->form_validation->run();
+ }
+
+ /**
+ *
+ * @param
+ * @return object success or error
+ */
+ private function _validateDelete($projektarbeit_id)
+ {
+ $this->BetreuerModel->addSelect('1');
+ $result = $this->BetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
+
+ if (isError($result)) return $result;
+
+ if (hasData($result)) return error($this->p->t('projektarbeit', 'error_betreuerNichtGeloescht'));
+
+ $this->PaabgabeModel->addSelect('1');
+ $result = $this->PaabgabeModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
+
+ if (isError($result)) return $result;
+
+ if (hasData($result)) return error($this->p->t('projektarbeit', 'error_paabgabeNichtGeloescht'));
+
+ return success();
+ }
+
+ private function _hasBerechtigungForStudent($student_uid)
+ {
+ if (!$student_uid)
+ return false;
+
+ $this->load->model('crm/Student_model', 'StudentModel');
+
+ $this->StudentModel->addSelect('studiengang_kz');
+ $result = $this->StudentModel->load([$student_uid]);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $studiengang_kz = getData($result)[0]->studiengang_kz;
+
+ if ($this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz))
+ return true;
+ if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
+ return true;
+
+ return false;
+ }
+}
diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php
index 056fb45d7..446e6e9cf 100644
--- a/application/models/education/Lehrveranstaltung_model.php
+++ b/application/models/education/Lehrveranstaltung_model.php
@@ -988,4 +988,61 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, $params);
}
+
+ /**
+ * Gets Lehrveranstaltungen for a student, as needed for a Projektarbeit.
+ * @param student_uid
+ * @param studiengang_kz optional, all Lvs of this Studiengang will be included
+ * @param additional_lehrveranstaltung_id optional, this lv will be added to result
+ * @return object success or error
+ */
+ public function getLvsForProjektarbeit($student_uid, $studiengang_kz = null, $additional_lehrveranstaltung_id = null)
+ {
+ $params = array($student_uid, $student_uid);
+
+ $qry = "
+ SELECT *
+ FROM
+ lehre.tbl_lehrveranstaltung
+ WHERE
+ (
+ lehrveranstaltung_id IN (
+
+ SELECT
+ lehrveranstaltung_id
+ FROM
+ campus.vw_student_lehrveranstaltung
+ WHERE
+ uid=?
+
+ UNION
+
+ SELECT
+ lehrveranstaltung_id
+ FROM
+ lehre.tbl_zeugnisnote
+ WHERE
+ student_uid=?
+ )";
+
+ if (isset($studiengang_kz))
+ {
+ $params[] = $studiengang_kz;
+ $qry .= " OR (studiengang_kz = ? AND semester IS NOT NULL)";
+ }
+
+ if (isset($additional_lehrveranstaltung_id))
+ {
+ $params[] = $additional_lehrveranstaltung_id;
+ $qry .= " OR lehrveranstaltung_id = ?";
+ }
+
+ $qry .= "
+ )
+ AND projektarbeit = TRUE
+ ORDER BY
+ semester, bezeichnung";
+
+ return $this->execQuery($qry, $params);
+ }
}
diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php
index 109e23373..2be79f8e9 100644
--- a/application/models/education/Projektarbeit_model.php
+++ b/application/models/education/Projektarbeit_model.php
@@ -24,15 +24,17 @@ class Projektarbeit_model extends DB_Model
public function getProjektarbeit($student_uid, $studiengang_kz = null, $studiensemester_kurzbz = null, $projekttyp = null, $final = null)
{
$qry = "SELECT
- tbl_projektarbeit.* , tbl_projekttyp.bezeichnung
+ tbl_projektarbeit.*, tbl_projekttyp.bezeichnung,
+ tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id,
+ tbl_firma.name AS firma_name
FROM
lehre.tbl_projektarbeit
JOIN
- lehre.tbl_projekttyp USING (projekttyp_kurzbz), lehre.tbl_lehreinheit, lehre.tbl_lehrveranstaltung
-
+ lehre.tbl_projekttyp USING (projekttyp_kurzbz), lehre.tbl_lehreinheit, lehre.tbl_lehrveranstaltung, public.tbl_firma
WHERE
tbl_projektarbeit.lehreinheit_id=tbl_lehreinheit.lehreinheit_id AND
tbl_lehreinheit.lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id AND
+ tbl_projektarbeit.firma_id = tbl_firma.firma_id AND
tbl_projektarbeit.student_uid = ?";
$params = array($student_uid);
@@ -69,4 +71,30 @@ class Projektarbeit_model extends DB_Model
return $this->execQuery($qry, $params);
}
+
+ /**
+ *
+ * @param
+ * @return object success or error
+ */
+ public function hasBerechtigungForProjektarbeit($projektarbeit_id)
+ {
+ if (!$projektarbeit_id || !is_numeric($projektarbeit_id))
+ return false;
+
+ $this->ProjektarbeitModel->addSelect('studiengang_kz');
+ $this->ProjektarbeitModel->addJoin('public.tbl_student', 'student_uid');
+ $result = $this->ProjektarbeitModel->load($projektarbeit_id);
+ if (isError($result) || !hasData($result))
+ return false;
+
+ $studiengang_kz = getData($result)[0]->studiengang_kz;
+
+ if ($this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz))
+ return true;
+ if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
+ return true;
+
+ return false;
+ }
}
diff --git a/application/models/ressource/Firma_model.php b/application/models/ressource/Firma_model.php
index 431f0815f..5ae53eeaf 100644
--- a/application/models/ressource/Firma_model.php
+++ b/application/models/ressource/Firma_model.php
@@ -12,17 +12,24 @@ class Firma_model extends DB_Model
$this->pk = 'firma_id';
}
- public function searchFirmen($filter)
+ public function searchFirmen($filter, $aktiv = null)
{
+ $params = [];
$filter = strtoLower($filter);
$qry = "
- SELECT
+ SELECT
f.name, f.firma_id
- FROM
- public.tbl_firma f
- WHERE
- lower (f.name) LIKE '%". $this->db->escape_like_str($filter)."%'";
+ FROM
+ public.tbl_firma f
+ WHERE
+ lower (f.name) LIKE '%". $this->db->escape_like_str($filter)."%'";
- return $this->execQuery($qry);
+ if (isset($aktiv) && is_bool($aktiv))
+ {
+ $params[] = $aktiv;
+ $qry .= " AND aktiv = ?";
+ }
+
+ return $this->execQuery($qry, $params);
}
}
diff --git a/public/js/api/factory/stv/projektarbeit.js b/public/js/api/factory/stv/projektarbeit.js
new file mode 100644
index 000000000..243383de0
--- /dev/null
+++ b/public/js/api/factory/stv/projektarbeit.js
@@ -0,0 +1,80 @@
+/**
+ * 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 {
+ getProjektarbeit(uid) {
+ return {
+ method: 'get',
+ url: 'api/frontend/v1/stv/projektarbeit/getProjektarbeit',
+ params: { uid }
+ };
+ },
+ getTypenProjektarbeit() {
+ return {
+ method: 'get',
+ url: 'api/frontend/v1/stv/projektarbeit/getTypenProjektarbeit'
+ };
+ },
+ getFirmen(searchString) {
+ return {
+ method: 'get',
+ url: 'api/frontend/v1/stv/projektarbeit/getFirmen',
+ params: {searchString}
+ };
+ },
+ getLehrveranstaltungen(student_uid, studiengang_kz, studiensemester_kurzbz, additional_lehrveranstaltung_id) {
+ return {
+ method: 'get',
+ url: 'api/frontend/v1/stv/projektarbeit/getLehrveranstaltungen',
+ params: { student_uid, studiengang_kz, studiensemester_kurzbz, additional_lehrveranstaltung_id }
+ };
+ },
+ getNoten() {
+ return {
+ method: 'get',
+ url: 'api/frontend/v1/stv/projektarbeit/getNoten'
+ };
+ },
+ loadProjektarbeit(projektarbeit_id) {
+ return {
+ method: 'get',
+ url: 'api/frontend/v1/stv/projektarbeit/loadProjektarbeit',
+ params: { projektarbeit_id }
+ };
+ },
+ addNewProjektarbeit(params) {
+ return {
+ method: 'post',
+ url: 'api/frontend/v1/stv/projektarbeit/insertProjektarbeit',
+ params
+ };
+ },
+ updateProjektarbeit(params) {
+ return {
+ method: 'post',
+ url: 'api/frontend/v1/stv/projektarbeit/updateProjektarbeit',
+ params
+ };
+ },
+ deleteProjektarbeit(projektarbeit_id) {
+ return {
+ method: 'post',
+ url: 'api/frontend/v1/stv/projektarbeit/deleteProjektarbeit',
+ params: { projektarbeit_id }
+ };
+ }
+};
\ No newline at end of file
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit.js
new file mode 100644
index 000000000..3615e8f5d
--- /dev/null
+++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit.js
@@ -0,0 +1,24 @@
+import Projektarbeit from './Projektarbeit/Projektarbeit.js';
+
+export default {
+ name: "TabProjektarbeit",
+ components: {
+ Projektarbeit
+ },
+ provide() {
+ return {
+ config: this.config
+ };
+ },
+ props: {
+ modelValue: Object,
+ config: Object
+ },
+ data(){
+ return {}
+ },
+ template: `
+
`
+};
\ No newline at end of file
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Betreuung.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Betreuung.js
new file mode 100644
index 000000000..5d223d694
--- /dev/null
+++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Betreuung.js
@@ -0,0 +1,847 @@
+import {CoreFilterCmpt} from "../../../../filter/Filter.js";
+import FormForm from '../../../../Form/Form.js';
+import FormInput from '../../../../Form/Input.js';
+import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
+
+import ApiStvAbschlusspruefung from '../../../../../api/factory/stv/abschlusspruefung.js';
+
+export default {
+ components: {
+ CoreFilterCmpt,
+ BsModal,
+ FormForm,
+ FormInput,
+ PvAutoComplete,
+ AbschlusspruefungDropdown,
+ PruefungList
+ },
+ inject: {
+ cisRoot: {
+ from: 'cisRoot'
+ },
+ config: {
+ from: 'config',
+ required: true
+ },
+ $reloadList: {
+ from: '$reloadList',
+ required: true
+ },
+ isBerechtigtDocAndOdt: {
+ from: 'hasPermissionOutputformat',
+ default: false
+ }
+ },
+ computed: {
+ studentUids() {
+ if (this.student.uid)
+ {
+ return [this.student.uid];
+ }
+ return this.student.map(e => e.uid);
+ },
+ studentKzs(){
+ if (this.student.uid)
+ {
+ return [this.student.studiengang_kz];
+ }
+ return this.student.map(e => e.studiengang_kz);
+ },
+ stg_kz(){
+ return this.studentKzs[0];
+ },
+ },
+ props: {
+ student: Object
+ },
+ data() {
+ return {
+ tabulatorOptions: {
+ ajaxURL: 'dummy',
+ ajaxRequestFunc: () => this.$api.call(ApiStvAbschlusspruefung.getAbschlusspruefung(this.student.uid)),
+ ajaxResponse: (url, params, response) => response.data,
+ columns: [
+ {title: "vorsitz", field: "vorsitz_nachname"},
+ {title: "abschlussbeurteilung", field: "beurteilung_bezeichnung"},
+ {title: "prueferIn1", field: "p1_nachname", visible: false},
+ {title: "prueferIn2", field: "p2_nachname", visible: false},
+ {title: "prueferIn3", field: "p3_nachname", visible: false},
+ {
+ title: "datum",
+ field: "datum",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ }
+ },
+ {title: "uhrzeit", field: "uhrzeit"},
+ {
+ title: "freigabe",
+ field: "freigabedatum",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ }
+ },
+ {title: "pruefungsantritt", field: "antritt_bezeichnung"},
+ {
+ title: "sponsion",
+ field: "sponsion",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ }
+ },
+ {title: "anmerkung", field: "anmerkung"},
+ {title: "abschlusspruefung_id", field: "abschlusspruefung_id", visible: false},
+ {title: "typ", field: "pruefungstyp_kurzbz", visible: false},
+
+ {
+ title: 'Aktionen', field: 'actions',
+ minWidth: 150, // Ensures Action-buttons will be always fully displayed
+ formatter: (cell, formatterParams, onRendered) => {
+ let container = document.createElement('div');
+ container.className = "d-flex gap-2";
+
+ let button = document.createElement('button');
+ button.className = 'btn btn-outline-secondary btn-action';
+ button.innerHTML = '';
+ button.title = this.$p.t('ui', 'bearbeiten');
+ button.addEventListener('click', (event) =>
+ this.actionEditAbschlusspruefung(cell.getData().abschlusspruefung_id)
+ );
+ container.append(button);
+
+ button = document.createElement('button');
+ button.className = 'btn btn-outline-secondary btn-action';
+ button.innerHTML = '';
+ button.title = this.$p.t('ui', 'loeschen');
+ button.addEventListener('click', () =>
+ this.actionDeleteAbschlusspruefung(cell.getData().abschlusspruefung_id)
+ );
+ container.append(button);
+
+ container.append(cell.getData().actionDiv);
+
+ return container;
+ },
+ frozen: true
+ },
+ ],
+ layout: 'fitDataFill',
+ layoutColumnsOnNewData: false,
+ height: 'auto',
+ minHeight: '200',
+ selectable: true,
+ index: 'abschlusspruefung_id',
+ persistenceID: 'stv-details-finalexam'
+ },
+ tabulatorEvents: [
+ {
+ event: 'dataLoaded',
+ handler: data => this.tabulatorData = data.map(item => {
+ item.actionDiv = document.createElement('div');
+ return item;
+ }),
+ },
+ {
+ event: 'tableBuilt',
+ handler: async() => {
+ await this.$p.loadCategory(['global', 'person', 'stv', 'abschlusspruefung', 'ui']);
+
+
+ let cm = this.$refs.table.tabulator.columnManager;
+
+ cm.getColumnByField('vorsitz_nachname').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'vorsitz_header')
+ });
+ cm.getColumnByField('beurteilung_bezeichnung').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'abschlussbeurteilung')
+ });
+ cm.getColumnByField('p1_nachname').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'pruefer1')
+ });
+ cm.getColumnByField('p2_nachname').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'pruefer2')
+ });
+ cm.getColumnByField('p3_nachname').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'pruefer3')
+ });
+ cm.getColumnByField('datum').component.updateDefinition({
+ title: this.$p.t('global', 'datum')
+ });
+ cm.getColumnByField('uhrzeit').component.updateDefinition({
+ title: this.$p.t('global', 'uhrzeit')
+ });
+ cm.getColumnByField('freigabedatum').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'freigabe')
+ });
+ cm.getColumnByField('antritt_bezeichnung').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'pruefungsantritt')
+ });
+ cm.getColumnByField('sponsion').component.updateDefinition({
+ title: this.$p.t('abschlusspruefung', 'sponsion')
+ });
+ cm.getColumnByField('anmerkung').component.updateDefinition({
+ title: this.$p.t('global', 'anmerkung')
+ });
+ cm.getColumnByField('pruefungstyp_kurzbz').component.updateDefinition({
+ title: this.$p.t('global', 'typ')
+ });
+ cm.getColumnByField('abschlusspruefung_id').component.updateDefinition({
+ title: this.$p.t('ui', 'abschlusspruefung_id')
+ });
+ /*
+ cm.getColumnByField('actions').component.updateDefinition({
+ title: this.$p.t('global', 'aktionen')
+ });
+ */
+ }
+ }
+ ],
+ tabulatorData: [],
+ lastSelected: null,
+ formData: {
+ typStg: null,
+ pruefungstyp_kurzbz: null,
+ akadgrad_id: null,
+ vorsitz: null,
+ pruefungsantritt_kurzbz: null,
+ abschlussbeurteilung_kurzbz: null,
+ datum: null,
+ sponsion: null,
+ pruefer1: null,
+ pruefer2: null,
+ pruefer3: null,
+ anmerkung: null,
+ protokoll: null,
+ note: null,
+ link: null
+ },
+ statusNew: true,
+ arrTypen: [],
+ arrAntritte: [],
+ arrBeurteilungen: [],
+ arrAkadGrad: [],
+ arrNoten: [],
+ filteredMitarbeiter: [],
+ filteredPruefer: [],
+ abortController: {
+ mitarbeiter: null,
+ pruefer: null
+ },
+ stgInfo: { typ: '', oe_kurzbz: '' }
+ }
+ },
+ watch: {
+ student(){
+ if (this.$refs.table) {
+ this.$refs.table.reloadTable();
+ }
+ this.getStudiengangByKz();
+ }
+ },
+ methods: {
+ getStudiengangByKz(){
+ this.stgInfo = { typ: '', oe_kurzbz: '' };
+ this.$api
+ .call(ApiStudiengang.getStudiengangByKz(this.stg_kz))
+ .then(result => this.stgInfo = result.data)
+ .catch(this.$fhcAlert.handleSystemError);
+ },
+ actionNewAbschlusspruefung() {
+ this.resetForm();
+ this.statusNew = true;
+ this.$refs.finalexamModal.show();
+ this.setDefaultFormData();
+ },
+ actionEditAbschlusspruefung(abschlusspruefung_id) {
+ this.resetForm();
+ this.statusNew = false;
+ this.$refs.finalexamModal.show();
+ this.loadAbschlusspruefung(abschlusspruefung_id);
+ },
+ actionDeleteAbschlusspruefung(abschlusspruefung_id) {
+ this.$fhcAlert
+ .confirmDelete()
+ .then(result => result
+ ? abschlusspruefung_id
+ : Promise.reject({handled: true}))
+ .then(this.deleteAbschlusspruefung)
+ .catch(this.$fhcAlert.handleSystemError);
+ },
+ addNewAbschlusspruefung() {
+ const dataToSend = {
+ uid: this.student.uid,
+ formData: this.formData
+ };
+
+ return this.$refs.formFinalExam
+ .call(ApiStvAbschlusspruefung.addNewAbschlusspruefung(dataToSend))
+ .then(response => {
+ this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
+ this.hideModal('finalexamModal');
+ this.resetForm();
+ })
+ .catch(this.$fhcAlert.handleSystemError)
+ .finally(() => {
+ this.reload();
+ });
+ },
+ hideModal(modalRef){
+ this.$refs[modalRef].hide();
+ },
+ reload() {
+ this.$refs.table.reloadTable();
+ },
+ loadAbschlusspruefung(abschlusspruefung_id) {
+ return this.$api
+ .call(ApiStvAbschlusspruefung.loadAbschlusspruefung(abschlusspruefung_id))
+ .then(result => {
+ this.formData = result.data;
+ //TODO(Manu) check if cisRoot is okay
+ this.formData.link = this.cisRoot + 'index.ci.php/lehre/Pruefungsprotokoll/showProtokoll?abschlusspruefung_id=' + this.formData.abschlusspruefung_id + '&fhc_controller_id=67481e5ed5490';
+ return result;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+ },
+ updateAbschlusspruefung(abschlusspruefung_id) {
+ const dataToSend = {
+ id: abschlusspruefung_id,
+ formData: this.formData
+ };
+ return this.$refs.formFinalExam
+ .call(ApiStvAbschlusspruefung.updateAbschlusspruefung(dataToSend))
+ .then(response => {
+ this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
+ this.hideModal('finalexamModal');
+ this.resetForm();
+ })
+ .catch(this.$fhcAlert.handleSystemError)
+ .finally(() => {
+ this.reload();
+ });
+ },
+ deleteAbschlusspruefung(abschlusspruefung_id) {
+ return this.$api
+ .call(ApiStvAbschlusspruefung.deleteAbschlusspruefung(abschlusspruefung_id))
+ .then(response => {
+ this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
+ })
+ .catch(this.$fhcAlert.handleSystemError)
+ .finally(() => {
+ this.reload();
+ });
+ },
+ resetForm() {
+ this.formData.pruefungstyp_kurzbz = null;
+ this.formData.akadgrad_id = null;
+ this.formData.vorsitz = null;
+ this.formData.pruefungsantritt_kurzbz = null;
+ this.formData.abschlussbeurteilung_kurzbz = null;
+ this.formData.datum = null; //oder new Date();
+ this.formData.sponsion = null;
+ this.formData.pruefer1 = null;
+ this.formData.pruefer2 = null;
+ this.formData.pruefer3 = null;
+ this.formData.anmerkung = null;
+ this.formData.protokoll = null;
+ this.formData.note = null;
+ this.formData.p1 = null;
+ this.formData.p2 = null;
+ this.formData.p3 = null;
+ this.formData.pv = null;
+ },
+ search(event) {
+ if (this.abortController.mitarbeiter) {
+ this.abortController.mitarbeiter.abort();
+ }
+ this.abortController.mitarbeiter = new AbortController();
+
+ return this.$api
+ .call(ApiStvAbschlusspruefung.getMitarbeiter(event.query))
+ .then(result => {
+ this.filteredMitarbeiter = result.data.retval;
+ });
+ },
+ searchNotAkad(event) {
+ if (this.abortController.pruefer) {
+ this.abortController.pruefer.abort();
+ }
+ this.abortController.pruefer = new AbortController();
+
+ return this.$api
+ .call(ApiStvAbschlusspruefung.getPruefer(event.query))
+ .then(result => {
+ this.filteredPruefer = result.data.retval;
+ });
+ },
+ setDefaultFormData() {
+
+ this.resetForm();
+
+ if (this.stgInfo.typ === 'b') {
+ this.formData.pruefungstyp_kurzbz = 'Bachelor';
+ this.formData.protokoll = this.$p.t('abschlusspruefung', 'pruefungsnotizenMaster');
+ }
+ if (this.stgInfo.typ === 'd' || this.stgInfo === 'm') {
+ this.formData.pruefungstyp_kurzbz = 'Diplom';
+ this.formData.protokoll = this.$p.t('abschlusspruefung', 'pruefungsnotizenMaster');
+ }
+ if (this.stgInfo.typ === 'lg') {
+ this.formData.pruefungstyp_kurzbz = 'lgabschluss';
+ }
+
+ if (!this.formData.akadgrad_id && this.arrAkadGrad.length > 0) {
+ this.formData.akadgrad_id = this.arrAkadGrad[0].akadgrad_id;
+ }
+ },
+ printDocument(link) {
+ window.open(link, '_blank');
+ },
+ },
+ created() {
+ this.$api
+ .call(ApiStvAbschlusspruefung.getTypenAbschlusspruefung())
+ .then(result => {
+ this.arrTypen = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+
+ this.$api
+ .call(ApiStvAbschlusspruefung.getTypenAntritte())
+ .then(result => {
+ this.arrAntritte = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+
+ this.$api
+ .call(ApiStvAbschlusspruefung.getBeurteilungen())
+ .then(result => {
+ this.arrBeurteilungen = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+
+ this.$api
+ .call(ApiStvAbschlusspruefung.getNoten())
+ .then(result => {
+ this.arrNoten = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+
+ this.$api
+ .call(ApiStvAbschlusspruefung.getAkadGrade(this.student.studiengang_kz))
+ .then(result => {
+ this.arrAkadGrad = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+ if (!this.student.length) {
+ this.$api
+ .call(ApiStudiengang.getStudiengangByKz(this.student.studiengang_kz))
+ .then(result => {
+ this.stgInfo = result.data;
+ this.setDefaultFormData();
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+ } else
+ this.getStudiengangByKz();
+ },
+ template: `
+
+
{{this.$p.t('stv','tab_finalexam')}}
+
+
+
+
+
+
+
+
+
+ {{$p.t('abschlusspruefung', 'abschluessPruefungAnlegen')}}
+ {{$p.t('abschlusspruefung', 'abschluessPruefungBearbeiten')}}
+
+
+
+
+
+
+
+ [{{$p.t('ui', 'neu')}}]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{$p.t('abschlusspruefung', 'zurBeurteilung')}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`
+}
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js
new file mode 100644
index 000000000..a6256ceb1
--- /dev/null
+++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js
@@ -0,0 +1,461 @@
+import {CoreFilterCmpt} from "../../../../filter/Filter.js";
+import FormForm from '../../../../Form/Form.js';
+import FormInput from '../../../../Form/Input.js';
+import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
+
+import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js';
+
+export default {
+ components: {
+ CoreFilterCmpt,
+ FormForm,
+ FormInput,
+ PvAutoComplete
+ },
+ emits: ['details-saved'],
+ inject: {
+ defaultSemester: {
+ from: 'defaultSemester'
+ }
+ //~ cisRoot: {
+ //~ from: 'cisRoot'
+ //~ },
+ //~ config: {
+ //~ from: 'config',
+ //~ required: true
+ //~ }
+ },
+ computed: {
+ arrLes() {
+ let lehreinheiten = [];
+ if (this.formData.lehrveranstaltung_id) {
+ let lv = this.arrLvs.find(lv => {return lv.lehrveranstaltung_id == this.formData.lehrveranstaltung_id});
+ if (lv) lehreinheiten = lv.lehreinheiten
+ }
+
+ for (let le of lehreinheiten)
+ {
+ let bezeichnung = le.lehrfach_kurzbz + '-' + le.lehrform_kurzbz + ' ' + le.lehrfach_bezeichnung + ' ';
+
+ for (let grp of le.lehreinheitgruppen)
+ {
+ bezeichnung += grp.gruppe_kurzbz ? grp.gruppe_kurzbz : '' + grp.semester ?? '' + grp.verband ?? '' + grp.gruppe ?? '';
+ }
+
+ bezeichnung += ' (' + le.lektoren.join(' ') + ') ID: ' + le.lehreinheit_id;
+
+ le.bezeichnung = bezeichnung;
+ }
+
+ return lehreinheiten;
+ },
+ //~ preparedFormData() {
+ //~ console.log("FOR DATA CALLEd");
+ //~ if (this.formData.projektarbeit_id == null) delete(this.formData.projektarbeit_id);
+ //~ if (this.formData.firma) this.formData.firma_id = this.formData.firma.firma_id;
+ //~ delete(this.formData.firma);
+ //~ delete(this.formData.firma_name);
+ //~ delete(this.formData.lehrveranstaltung_id);
+ //~ // convert null value fields from string to null
+ //~ return this.formData;
+ //~ }
+ },
+ props: {
+ statusNew: Boolean,
+ student: Object,
+ projektarbeit: Object,
+ stg_kz: Number
+ },
+ data() {
+ return {
+ formData: {
+ projektarbeit_id: null,
+ titel: null,
+ titel_english: null,
+ themenbereich: null,
+ projekttyp_kurzbz: null,
+ firma: null,
+ lehrveranstaltung_id: null,
+ lehreinheit_id: null,
+ beginn: null,
+ ende: null,
+ freigegeben: true,
+ gesperrtbis: null,
+ note: null,
+ final: true,
+ anmerkung: null
+ },
+ arrTypen: [],
+ arrFirmen: [],
+ arrLvs: [],
+ arrNoten: [],
+ filteredFirmen: [],
+ abortController: {
+ firma: null
+ }
+ }
+ },
+ methods: {
+ resetForm() {
+ this.formData.projektarbeit_id = null;
+ this.formData.titel = null;
+ this.formData.titel_english = null;
+ this.formData.themenbereich = null;
+ this.formData.projekttyp_kurzbz = null;
+ this.formData.firma = null;
+ this.formData.lehrveranstaltung_id = null;
+ this.formData.lehreinheit_id = null;
+ this.formData.beginn = null;
+ this.formData.ende = null;
+ this.formData.freigegeben = true;
+ this.formData.gesperrtbis = null;
+ this.formData.note = null;
+ this.formData.final = true;
+ this.formData.anmerkung = null;
+ },
+ getFormData(statusNew, studiensemester_kurzbz, additional_lehrveranstaltung_id/*, successCallback*/) {
+
+ //~ let callArray = [
+ //~ this.$api.call(ApiStvProjektarbeit.getTypenProjektarbeit()),
+ //~ this.$api.call(ApiStvProjektarbeit.getLehrveranstaltungen(
+ //~ this.student.uid,
+ //~ projektarbeit_id ? null : this.student.studiengang_kz,
+ //~ studiensemester_kurzbz ?? this.defaultSemester,
+ //~ additional_lehrveranstaltung_id ?? null
+ //~ )),
+ //~ this.$api.call(ApiStvProjektarbeit.getNoten())
+ //~ ];
+
+ //~ if (projektarbeit_id) callArray.push(this.$api.call(ApiStvProjektarbeit.loadProjektarbeit(projektarbeit_id)));
+
+ //~ // Run when All promises are settled
+ //~ Promise.allSettled(callArray).then((results) => {
+ //~ let hasError = false;
+ //~ let allFormData = [];
+ //~ results.forEach((promise_result) => {
+
+ //~ if (promise_result.status === 'fulfilled' && promise_result.value.meta.status === "success") {
+ //~ allFormData.push(promise_result.value.data);
+ //~ } else {
+ //~ hasError = true;
+ //~ //this.$fhcAlert.handleSystemError(promise_result);
+ //~ }
+ //~ //let data = promise_result.value.data;
+ //~ console.log(promise_result.status);
+ //~ });
+
+ //~ if (!hasError) {
+ //~ this.setFormData(allFormData[0], allFormData[1], allFormData[2], allFormData[3], allFormData[4] ?? null);
+ //~ if (successCallback) successCallback();
+ //~ }
+ //~ });
+
+ this.$api
+ .call(ApiStvProjektarbeit.getTypenProjektarbeit())
+ .then(result => {
+ this.arrTypen = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+
+ this.$api
+ .call(ApiStvProjektarbeit.getLehrveranstaltungen(
+ this.student.uid,
+ statusNew ? this.student.studiengang_kz : null,
+ studiensemester_kurzbz ?? this.defaultSemester,
+ additional_lehrveranstaltung_id
+ ))
+ .then(result => {
+ this.arrLvs = result.data
+ }
+ )
+ .catch(this.$fhcAlert.handleSystemError);
+
+ this.$api
+ .call(ApiStvProjektarbeit.getNoten())
+ .then(result => {
+ this.arrNoten = result.data;
+ })
+ .catch(this.$fhcAlert.handleSystemError);
+ },
+ setFormData(arrTypen, arrLvs, arrNoten, projektarbeitData) {
+ this.arrTypen = arrTypen;
+ this.arrLvs = arrLvs;
+ this.arrNoten = arrNoten;
+ if (projektarbeitData) {
+ projektarbeitData.firma = {firma_id: projektarbeitData.firma_id, name: projektarbeitData.firma_name};
+ this.formData = projektarbeitData;
+ }
+ },
+ loadProjektarbeit(projektarbeit_id) {
+
+ return this.$api
+ .call(ApiStvProjektarbeit.loadProjektarbeit(projektarbeit_id))
+ .then(result => {
+ this.formData = result.data;
+ return result;
+ })
+ .catch(this.$fhcAlert.handleSystemError)
+ },
+ addNewProjektarbeit() {
+
+ let dataToSend = {
+ uid: this.student.uid,
+ formData: this.getPreparedFormData()
+ };
+
+ return this.$refs.formDetails
+ .call(ApiStvProjektarbeit.addNewProjektarbeit(dataToSend));
+ },
+ updateProjektarbeit() {
+
+ let dataToSend = {
+ projektarbeit_id: this.formData.projektarbeit_id,
+ formData: this.getPreparedFormData()
+ };
+ return this.$refs.formDetails
+ .call(ApiStvProjektarbeit.updateProjektarbeit(dataToSend));
+ },
+ searchFirma(event) {
+ if (this.abortController.firma) {
+ this.abortController.firma.abort();
+ }
+ this.abortController.firma = new AbortController();
+
+ return this.$api
+ .call(ApiStvProjektarbeit.getFirmen(event.query))
+ .then(result => {
+ this.filteredFirmen = result.data;
+ });
+ },
+ lvChanged(event) {
+ this.formData.lehreinheit_id = null;
+ },
+ getPreparedFormData() {
+ let preparedFormData = JSON.parse(JSON.stringify(this.formData)); // deep copy
+
+ // delete "helper" fields
+ if (preparedFormData.projektarbeit_id == null) delete(preparedFormData.projektarbeit_id);
+ if (preparedFormData.firma) preparedFormData.firma_id = preparedFormData.firma.firma_id;
+ delete(preparedFormData.firma);
+ delete(preparedFormData.firma_name);
+ delete(preparedFormData.lehrveranstaltung_id);
+
+ return preparedFormData;
+ }
+ //~ setDefaultFormData() {
+ //~ this.resetForm();
+ //~ },
+ },
+ template: `
+
+
+
+ [{{$p.t('ui', 'neu')}}]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+}
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js
new file mode 100644
index 000000000..034b3fd6c
--- /dev/null
+++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js
@@ -0,0 +1,377 @@
+import {CoreFilterCmpt} from "../../../../filter/Filter.js";
+import BsModal from "../../../../Bootstrap/Modal.js";
+import FormForm from '../../../../Form/Form.js';
+import FormInput from '../../../../Form/Input.js';
+import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
+
+
+import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js';
+import ProjektarbeitDetails from "./Details.js";
+
+export default {
+ components: {
+ CoreFilterCmpt,
+ BsModal,
+ FormForm,
+ FormInput,
+ PvAutoComplete,
+ ProjektarbeitDetails
+ },
+ inject: {
+ cisRoot: {
+ from: 'cisRoot'
+ },
+ config: {
+ from: 'config',
+ required: true
+ },
+ $reloadList: {
+ from: '$reloadList',
+ required: true
+ },
+ isBerechtigtDocAndOdt: {
+ from: 'hasPermissionOutputformat',
+ default: false
+ }
+ },
+ computed: {
+ //~ studentUids() {
+ //~ if (this.student.uid)
+ //~ {
+ //~ return [this.student.uid];
+ //~ }
+ //~ return this.student.map(e => e.uid);
+ //~ },
+ studentKzs(){
+ if (this.student.uid)
+ {
+ return [this.student.studiengang_kz];
+ }
+ return this.student.map(e => e.studiengang_kz);
+ },
+ stg_kz(){
+ return this.studentKzs.length > 0 ? this.studentKzs.length[0] : null;
+ }
+ },
+ props: {
+ student: Object
+ },
+ data() {
+ return {
+ tabulatorOptions: {
+ ajaxURL: 'dummy',
+ ajaxRequestFunc: () => this.$api.call(ApiStvProjektarbeit.getProjektarbeit(this.student.uid)),
+ ajaxResponse: (url, params, response) => response.data,
+ columns: [
+ {title: "Projektarbeit ID", field: "projektarbeit_id", visible: false},
+ {title: "Typ", field: "projekttyp_kurzbz"},
+ {title: "Studiensemester", field: "studiensemester_kurzbz"},
+ {title: "Titel", field: "titel"},
+ {
+ title: "Abgabe Enduplad",
+ field: "abgabedatum",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ }
+ },
+ {
+ title: "Beginn",
+ field: "beginn",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ },
+ visible: false
+ },
+ {
+ title: "Ende",
+ field: "ende",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ },
+ visible: false
+ },
+ {
+ title:"Freigegeben",
+ field:"freigegeben",
+ formatter:"tickCross",
+ hozAlign:"center",
+ formatterParams: {
+ tickElement: '',
+ crossElement: ''
+ },
+ visible: false
+ },
+ {
+ title: "Gesperrt bis",
+ field: "gesperrtbis",
+ formatter: function (cell) {
+ const dateStr = cell.getValue();
+ if (!dateStr) return "";
+
+ const date = new Date(dateStr);
+ return date.toLocaleString("de-DE", {
+ day: "2-digit",
+ month: "2-digit",
+ year: "numeric",
+ hour12: false
+ });
+ },
+ visible: false
+ },
+ {title: "Themenbereich", field: "themenbereich", visible: false},
+ {title: "Anmerkung", field: "anmerkung", visible: false},
+ {title: "Lehreinheit ID", field: "lehreinheit_id", visible: false},
+ {title: "Student UID", field: "student_uid", visible: false},
+ {
+ title:"Final",
+ field:"final",
+ formatter:"tickCross",
+ hozAlign:"center",
+ formatterParams: {
+ tickElement: '',
+ crossElement: ''
+ },
+ visible: false
+ },
+ {title: "Firma ID", field: "firma_id", visible: false},
+ {
+ title: 'Aktionen', field: 'actions',
+ minWidth: 150, // Ensures Action-buttons will be always fully displayed
+ formatter: (cell, formatterParams, onRendered) => {
+ let container = document.createElement('div');
+ container.className = "d-flex gap-2";
+
+ let button = document.createElement('button');
+ button.className = 'btn btn-outline-secondary btn-action';
+ button.innerHTML = '';
+ button.title = this.$p.t('ui', 'bearbeiten');
+ button.addEventListener('click', (event) => {
+ let data = cell.getData();
+ this.actionEditProjektarbeit(data.projektarbeit_id, data.studiensemester_kurzbz, data.lehrveranstaltung_id);
+ });
+ container.append(button);
+
+ button = document.createElement('button');
+ button.className = 'btn btn-outline-secondary btn-action';
+ button.innerHTML = '';
+ button.title = this.$p.t('ui', 'loeschen');
+ button.addEventListener('click', () =>
+ this.actionDeleteProjektarbeit(cell.getData().projektarbeit_id)
+ );
+ container.append(button);
+
+ container.append(cell.getData().actionDiv);
+
+ return container;
+ },
+ frozen: true
+ },
+ ],
+ layout: 'fitDataFill',
+ layoutColumnsOnNewData: false,
+ height: 'auto',
+ minHeight: '200',
+ selectable: 1,
+ index: 'projektarbeit_id',
+ persistenceID: 'stv-details-projektarbeit'
+ },
+ tabulatorEvents: [
+ {
+ event: 'rowSelectionChanged',
+ handler: this.rowSelectionChanged
+ },
+ {
+ event: 'dataLoaded',
+ handler: data => this.tabulatorData = data.map(item => {
+ item.actionDiv = document.createElement('div');
+ return item;
+ }),
+ },
+ {
+ event: 'tableBuilt',
+ handler: async() => {
+ await this.$p.loadCategory(['global', 'person', 'stv', 'ui']);
+
+
+ let cm = this.$refs.table.tabulator.columnManager;
+
+ //~ cm.getColumnByField('vorsitz_nachname').component.updateDefinition({
+ //~ title: this.$p.t('abschlusspruefung', 'vorsitz_header')
+ //~ });
+ /*
+ cm.getColumnByField('actions').component.updateDefinition({
+ title: this.$p.t('global', 'aktionen')
+ });
+ */
+ }
+ },
+ ],
+ tabulatorData: [],
+ lastSelected: null,
+ statusNew: true,
+ studiensemester_kurzbz: null,
+ lehrveranstaltung_id: null
+ }
+ },
+ //~ watch: {
+ //~ student(){
+ //~ if (this.$refs.table) {
+ //~ this.$refs.table.reloadTable();
+ //~ }
+ //~ this.getStudiengangByKz();
+ //~ }
+ //~ },
+ methods: {
+ actionNewProjektarbeit() {
+ this.statusNew = true;
+ this.$refs.projektarbeitDetails.resetForm();
+ this.$refs.projektarbeitDetails.getFormData();
+ this.$refs.projektarbeitModal.show();
+ },
+ actionEditProjektarbeit(projektarbeit_id, studiensemester_kurzbz, lehrveranstaltung_id) {
+ this.statusNew = false;
+ this.$refs.projektarbeitDetails.getFormData(this.statusNew, studiensemester_kurzbz, lehrveranstaltung_id);
+ this.$refs.projektarbeitDetails.loadProjektarbeit(projektarbeit_id);
+ this.$refs.projektarbeitModal.show();
+ },
+ actionDeleteProjektarbeit(projektarbeit_id) {
+ this.$fhcAlert
+ .confirmDelete()
+ .then(result => result
+ ? projektarbeit_id
+ : Promise.reject({handled: true}))
+ .then(this.deleteProjektarbeit)
+ .catch(this.$fhcAlert.handleSystemError);
+ },
+ addNewProjektarbeit() {
+ Promise.allSettled([
+ this.$refs.projektarbeitDetails.addNewProjektarbeit()
+ ]).then((results) => {
+ let hasError = false;
+ results.forEach((promise_result) => {
+
+ if (!(promise_result.status === 'fulfilled' && promise_result.value.meta.status === "success")) {
+
+ hasError = true;
+ }
+ });
+
+ if (!hasError) {
+ this.projektarbeitSaved();
+ }
+ });
+ },
+ updateProjektarbeit() {
+ Promise.allSettled(
+ [
+ this.$refs.projektarbeitDetails.updateProjektarbeit()
+ ]).then((results) => {
+ let hasError = false;
+ results.forEach((promise_result) => {
+
+ if (!(promise_result.status === 'fulfilled' && promise_result.value.meta.status === "success")) {
+
+ hasError = true;
+ }
+ });
+
+ if (!hasError) {
+ this.projektarbeitSaved();
+ }
+ });
+ },
+ deleteProjektarbeit(projektarbeit_id) {
+ return this.$api
+ .call(ApiStvProjektarbeit.deleteProjektarbeit(projektarbeit_id))
+ .then(response => {
+ this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
+ })
+ .catch(this.$fhcAlert.handleSystemError)
+ .finally(() => {
+ this.reload();
+ });
+ },
+ projektarbeitSaved() {
+ this.reload();
+ this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
+ this.hideModal('projektarbeitModal');
+ this.$refs.projektarbeitDetails.resetForm();
+ },
+ rowSelectionChanged(data) {
+ console.log("selection changed");
+ this.lastSelected = data.length > 0 ? data[0] : null;
+ },
+ hideModal(modalRef){
+ this.$refs[modalRef].hide();
+ },
+ reload() {
+ this.$refs.table.reloadTable();
+ }
+ },
+ created() {
+ },
+ template: `
+
+
{{this.$p.t('stv','tab_projektarbeit')}}
+
+
+
+
+
+
+
+ {{$p.t('projektarbeit', 'projektarbeitAnlegen')}}
+ {{$p.t('projektarbeit', 'projektarbeitBearbeiten')}}
+
+
+
+
+
+
+
+
+
+
+
+
+`
+}
+