Studierendenverwaltung Projektarbeit: added concatenated Betreuer, sorted autocomplete suggestions, added Gesamtnote, freigegeben check removed when lock date set, added phrases

This commit is contained in:
Alexei Karpenko
2025-12-05 22:01:35 +01:00
parent c79ff24c89
commit 112e30ab39
7 changed files with 238 additions and 30 deletions
@@ -55,10 +55,7 @@ class Projektarbeit extends FHCAPI_Controller
$result = $this->ProjektarbeitModel->getProjektarbeit($student_uid);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result)) $this->terminateWithSuccess([]);
@@ -50,21 +50,30 @@ class Projektbetreuer extends FHCAPI_Controller
if (!isset($projektarbeit_id))
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
$this->ProjektbetreuerModel->addSelect(
'projektarbeit_id, person_id, nachname, vorname, note, punkte, round(stunden, 1) AS stunden,
stundensatz, betreuerart_kurzbz, vertrag_id, titelpre, titelpost'
);
$this->ProjektbetreuerModel->addSelect("CASE
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=pers.person_id)
THEN 'Mitarbeiter'
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=pers.person_id)
THEN 'Student'
ELSE 'Person'
END AS status");
$this->ProjektbetreuerModel->addJoin('public.tbl_person pers', 'person_id');
$result = $this->ProjektbetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
$qry = "
SELECT * FROM (
SELECT
projektarbeit_id, person_id, nachname, vorname, note, punkte, round(stunden, 1) AS stunden,
stundensatz, betreuerart_kurzbz, vertrag_id, titelpre, titelpost,
CASE
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=pers.person_id)
THEN 'Mitarbeiter'
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=pers.person_id)
THEN 'Student'
ELSE 'Person'
END AS status
FROM
lehre.tbl_projektbetreuer
JOIN public.tbl_person pers USING (person_id)
WHERE
projektarbeit_id = ?
) betreuer
ORDER BY
CASE WHEN status = 'Mitarbeiter' THEN 0 WHEN status = 'Person' THEN 1 ELSE 2 END";
$result = $this->ProjektbetreuerModel->execReadOnlyQuery($qry, [$projektarbeit_id]);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
@@ -245,7 +254,18 @@ class Projektbetreuer extends FHCAPI_Controller
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? $this->_addFullNameToBetreuer(getData($result)) : []);
// sort persons
if (!hasData($result)) $this->terminateWithSuccess([]);
$persons = $this->_addFullNameToBetreuer(getData($result));
usort($persons, function($a, $b)
{
$statusRanks = ['Mitarbeiter' => 0, 'Person' => 1, 'Student' => 2];
return (isset($statusRanks[$a->status]) ? $statusRanks[$a->status] : count($statusRanks) + 1)
- (isset($statusRanks[$b->status]) ? $statusRanks[$b->status] : count($statusRanks) + 1);
});
return $this->terminateWithSuccess($persons);
}
public function getPerson()
@@ -24,17 +24,28 @@ 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,
pa.*, tbl_projekttyp.bezeichnung,
tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_firma.name AS firma_name
tbl_firma.name AS firma_name,
(
SELECT
STRING_AGG(trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')), ', ')
FROM
lehre.tbl_projektbetreuer
JOIN public.tbl_person USING (person_id)
WHERE
projektarbeit_id = pa.projektarbeit_id
AND student_uid = pa.student_uid
GROUP BY projektarbeit_id
) AS projektbetreuer
FROM
lehre.tbl_projektarbeit
lehre.tbl_projektarbeit pa
JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_firma USING (firma_id)
WHERE
tbl_projektarbeit.student_uid = ?";
pa.student_uid = ?";
$params = array($student_uid);
@@ -195,12 +195,15 @@ export default {
)
.catch(this.$fhcAlert.handleSystemError);
},
lvChanged(event) {
this.formData.lehreinheit_id = null;
},
studiensemesterChanged() {
this.formData.lehreinheit_id = null;
this.getLehrveranstaltungen();
},
lvChanged(event) {
this.formData.lehreinheit_id = null;
gesperrtBisChanged(newSperrdatum) {
this.formData.freigegeben = newSperrdatum == null || newSperrdatum == '';
},
// enrich and modify data before sending
getPreparedFormData() {
@@ -400,6 +403,7 @@ export default {
format="dd.MM.yyyy"
model-type="yyyy-MM-dd"
name="gesperrtbis"
@update:model-value="gesperrtBisChanged"
>
</form-input>
<div class="col-4">
@@ -47,16 +47,25 @@ export default {
{
event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global', 'person', 'stv', 'ui', 'projektarbeit']);
await this.$p.loadCategory(['global', 'person', 'lehre', 'stv', 'ui', 'projektarbeit']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('projekttyp_kurzbz').component.updateDefinition({
title: this.$p.t('projektarbeit', 'typKurzbezeichnung')
});
cm.getColumnByField('bezeichnung').component.updateDefinition({
title: this.$p.t('projektarbeit', 'typ')
});
cm.getColumnByField('studiensemester_kurzbz').component.updateDefinition({
title: this.$p.t('lehre', 'studiensemester')
});
cm.getColumnByField('titel').component.updateDefinition({
title: this.$p.t('projektarbeit', 'titel')
});
cm.getColumnByField('note').component.updateDefinition({
title: this.$p.t('projektarbeit', 'gesamtnote')
});
cm.getColumnByField('beginn').component.updateDefinition({
title: this.$p.t('projektarbeit', 'beginn')
});
@@ -78,6 +87,12 @@ export default {
cm.getColumnByField('firma_id').component.updateDefinition({
title: this.$p.t('projektarbeit', 'firmaId')
});
cm.getColumnByField('abgabedatum').component.updateDefinition({
title: this.$p.t('projektarbeit', 'abgabeEndupload')
});
cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'aktionen')
});
}
},
],
@@ -101,6 +116,7 @@ export default {
{title: "Typ Kurzbz", field: "projekttyp_kurzbz", visible: false},
{title: "Studiensemester", field: "studiensemester_kurzbz"},
{title: "Titel", field: "titel"},
{title: "Gesamtnote", field: "note"},
{
title: "Abgabe Enduplad",
field: "abgabedatum",
@@ -183,6 +199,7 @@ export default {
{title: "Anmerkung", field: "anmerkung", visible: false},
{title: "Lehreinheit ID", field: "lehreinheit_id", visible: false},
{title: "Student UID", field: "student_uid", visible: false},
{title: "Projektbetreuer", field: "projektbetreuer", visible: false},
{
title:"Final",
field:"final",
@@ -388,7 +405,7 @@ export default {
<div class="tab-pane fade show" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer" role="tabpanel" aria-labelledby="betreuer-tab">
<div class="row">
<div class="col-12">
<projektbetreuer ref="projektbetreuer" :config="config"></projektbetreuer>
<projektbetreuer ref="projektbetreuer" :config="config" @betreuer-saved="reload"></projektbetreuer>
</div>
</div>
</div>
@@ -20,6 +20,7 @@ export default {
Contact,
Vertrag
},
emits: ['betreuerSaved'],
provide() {
return {
configShowVertragsdetails: this.config.showVertragsdetails
@@ -131,7 +132,43 @@ export default {
{
event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global', 'person', 'stv', 'projektarbeit', 'ui']);
await this.$p.loadCategory(['global', 'person', 'lehre', 'stv', 'projektarbeit', 'ui']);
let cm = this.$refs.projektbetreuerTable.tabulator.columnManager;
cm.getColumnByField('nachname').component.updateDefinition({
title: this.$p.t('person', 'nachname')
});
cm.getColumnByField('vorname').component.updateDefinition({
title: this.$p.t('person', 'vorname')
});
cm.getColumnByField('note').component.updateDefinition({
title: this.$p.t('projektarbeit', 'note')
});
cm.getColumnByField('punkte').component.updateDefinition({
title: this.$p.t('projektarbeit', 'titel')
});
cm.getColumnByField('stunden').component.updateDefinition({
title: this.$p.t('projektarbeit', 'stunden')
});
cm.getColumnByField('stundensatz').component.updateDefinition({
title: this.$p.t('projektarbeit', 'stundensatz')
});
cm.getColumnByField('betreuerart_kurzbz').component.updateDefinition({
title: this.$p.t('projektarbeit', 'betreuerart_kurzbz')
});
cm.getColumnByField('person_id').component.updateDefinition({
title: this.$p.t('system', 'person_id')
});
cm.getColumnByField('vertrag_id').component.updateDefinition({
title: this.$p.t('projektarbeit', 'vertrag_id')
});
cm.getColumnByField('projektarbeit_id').component.updateDefinition({
title: this.$p.t('projektarbeit', 'projektarbeit_id')
});
cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'actions')
});
// Force layout recalculation for handling overflow text
this.$refs.projektbetreuerTable.tabulator.redraw(true);
@@ -173,6 +210,7 @@ export default {
methods: {
actionNewProjektbetreuer() {
this.resetForm();
this.defaultStundensatz = this.config.defaultProjektbetreuerStundensatz;
this.newMode = !this.newMode;
this.editMode = false;
this.captureFormData();
@@ -279,6 +317,7 @@ export default {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.getProjektbetreuer(this.projektarbeit_id, this.studiensemester_kurzbz);
this.resetModes();
this.$emit('betreuerSaved');
})
.catch(this.$fhcAlert.handleSystemError);
},
@@ -300,7 +339,6 @@ export default {
resetForm() {
const defaultFormData = this.getDefaultFormData();
this.formData = defaultFormData;
this.defaultStundensatz = defaultFormData.stundensatz;
if (this.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = '';
this.autocompleteSelectedBetreuer = null;
this.initialFormData = null;
@@ -404,6 +442,7 @@ export default {
.then(response => {
// set the new person in Betreuer autocomplete field
this.autocompleteSelectedBetreuer = response.data;
this.getDefaultStundensaetze(this.autocompleteSelectedBetreuer.person_id);
})
.catch(this.$fhcAlert.handleSystemError)
},
+120
View File
@@ -51665,6 +51665,126 @@ I have been informed that I am under no obligation to consent to the transmissio
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'punkte',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Punkte',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'points',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'gesamtnote',
'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' => 'projektarbeit',
'phrase' => 'abgabeEndupload',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Abgabe Endupload',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'final submission upload',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'vertrag_id',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Vertrag ID',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'contract ID',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'projektarbeit_id',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Projektarbeit ID',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'project work ID',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'betreuerart_kurzbz',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Betreuerart Kurzbezeichnung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'project assessor short name',
'description' => '',
'insertvon' => 'system'
)
)
),
// FHC-4 Projektarbeiten & Vertraege ENDE
// ### DOKUMENTE ERSTELLEN PHRASEN START ###
array(