Studierendenverwaltung Projektarbeit: separate saving of Projektarbeit and Betreuer, added action for editing Betreuer

This commit is contained in:
Alexei Karpenko
2025-09-02 15:04:45 +02:00
parent ce9a4e2e09
commit fc845ebf4e
9 changed files with 248 additions and 221 deletions
@@ -310,13 +310,13 @@ class Projektarbeit extends FHCAPI_Controller
'projekttyp_kurzbz' => $formData['projekttyp_kurzbz'],
'firma_id' => $formData['firma_id'] ?? null,
'lehreinheit_id' => $formData['lehreinheit_id'],
'beginn' => $formData['beginn'] ?? null,
'ende' => $formData['ende'] ?? null,
'beginn' => isset($formData['beginn']) && !isEmptyString($formData['beginn']) ? $formData['beginn'] : null,
'ende' => isset($formData['ende']) && !isEmptyString($formData['ende']) ? $formData['ende'] : null,
'note' => $formData['note'] ?? null,
'final' => $formData['final'] ?? null,
'freigegeben' => $formData['freigegeben'] ?? null,
'anmerkung' => $formData['anmerkung'] ?? null,
'gesperrtbis' => $formData['gesperrtbis'] ?? null
'gesperrtbis' => isset($formData['gesperrtbis']) && !isEmptyString($formData['gesperrtbis']) ? $formData['gesperrtbis'] : null
];
}
@@ -114,49 +114,40 @@ class Projektbetreuer extends FHCAPI_Controller
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
$projektbetreuer = $this->input->post('projektbetreuerListe');
$projektbetreuer = $this->input->post('projektbetreuer');
if (!is_array($projektbetreuer))
return $this->terminateWithError($this->p->t('projektarbeit', 'error_invalidProjektbetreuer'), self::ERROR_TYPE_GENERAL);
foreach ($projektbetreuer as $pb)
{
if ($this->_validate($pb) == false) $this->terminateWithValidationErrors($this->form_validation->error_array());
}
if ($this->_validate($projektbetreuer) == false) $this->terminateWithValidationErrors($this->form_validation->error_array());
$result = null;
foreach ($projektbetreuer as $pb)
$betreuer = [
'projektarbeit_id' => $projektarbeit_id,
'person_id' => $projektbetreuer['person_id'],
'note' => $projektbetreuer['note'],
'stunden' => $projektbetreuer['stunden'],
'stundensatz' => $projektbetreuer['stundensatz'],
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz']
];
if (isset($projektbetreuer['person_id_old']) && isset($projektbetreuer['betreuerart_kurzbz_old']))
{
$betreuer = [
'projektarbeit_id' => $projektarbeit_id,
'person_id' => $pb['person_id'],
'note' => $pb['note'],
'stunden' => $pb['stunden'],
'stundensatz' => $pb['stundensatz'],
'betreuerart_kurzbz' => $pb['betreuerart_kurzbz']
];
if (isset($pb['person_id_old']) && isset($pb['betreuerart_kurzbz_old']))
{
$result = $this->ProjektbetreuerModel->update(
[
'projektarbeit_id' => $projektarbeit_id,
'person_id' => $pb['person_id_old'],
'betreuerart_kurzbz' => $pb['betreuerart_kurzbz_old']
],
array_merge($betreuer, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
);
}
else
{
$result = $this->ProjektbetreuerModel->insert(
array_merge($betreuer, ['insertamum' => date('c'), 'insertvon' => getAuthUID()])
);
}
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$result = $this->ProjektbetreuerModel->update(
[
'projektarbeit_id' => $projektarbeit_id,
'person_id' => $projektbetreuer['person_id_old'],
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz_old']
],
array_merge($betreuer, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
);
}
else
{
$result = $this->ProjektbetreuerModel->insert(
array_merge($betreuer, ['insertamum' => date('c'), 'insertvon' => getAuthUID()])
);
}
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
@@ -1255,4 +1255,61 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execReadOnlyQuery($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);
}
}
+1 -1
View File
@@ -77,4 +77,4 @@ export default {
params: { projektarbeit_id }
};
}
};
};
+2 -2
View File
@@ -42,11 +42,11 @@ export default {
url: 'api/frontend/v1/stv/projektbetreuer/getNoten'
};
},
saveProjektbetreuer(projektarbeit_id, projektbetreuerListe) {
saveProjektbetreuer(projektarbeit_id, projektbetreuer) {
return {
method: 'post',
url: 'api/frontend/v1/stv/projektbetreuer/saveProjektbetreuer',
params: { projektarbeit_id, projektbetreuerListe }
params: { projektarbeit_id, projektbetreuer }
};
},
deleteProjektbetreuer(projektarbeit_id, person_id, betreuerart_kurzbz) {
@@ -15,10 +15,6 @@ export default {
defaultSemester: {
from: 'defaultSemester'
}
//~ config: {
//~ from: 'config',
//~ required: true
//~ }
},
computed: {
// prepared Lehreinheiten (with compound Bezeichnung)
@@ -169,6 +165,7 @@ export default {
},
loadProjektarbeit(projektarbeit_id) {
this.resetForm();
return this.$api
.call(ApiStvProjektarbeit.loadProjektarbeit(projektarbeit_id))
.then(result => {
@@ -36,7 +36,63 @@ export default {
},
data() {
return {
tabulatorOptions: {
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', 'ui', 'projektarbeit']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('projekttyp_kurzbz').component.updateDefinition({
title: this.$p.t('projektarbeit', 'typ')
});
cm.getColumnByField('titel').component.updateDefinition({
title: this.$p.t('projektarbeit', 'titel')
});
cm.getColumnByField('beginn').component.updateDefinition({
title: this.$p.t('projektarbeit', 'beginn')
});
cm.getColumnByField('ende').component.updateDefinition({
title: this.$p.t('projektarbeit', 'ende')
});
cm.getColumnByField('freigegeben').component.updateDefinition({
title: this.$p.t('projektarbeit', 'freigegeben')
});
cm.getColumnByField('gesperrtbis').component.updateDefinition({
title: this.$p.t('projektarbeit', 'gesperrtBis')
});
cm.getColumnByField('themenbereich').component.updateDefinition({
title: this.$p.t('projektarbeit', 'themenbereich')
});
cm.getColumnByField('anmerkung').component.updateDefinition({
title: this.$p.t('projektarbeit', 'anmerkung')
});
cm.getColumnByField('firma_id').component.updateDefinition({
title: this.$p.t('projektarbeit', 'firmaId')
});
}
},
],
tabulatorData: [],
//lastSelected: null,
editedProjektarbeit: null,
statusNew: true,
studiensemester_kurzbz: null,
lehrveranstaltung_id: null,
activeTab: 'details'
}
},
computed: {
tabulatorOptions() {
const options = {
ajaxURL: 'dummy',
ajaxRequestFunc: () => this.$api.call(ApiStvProjektarbeit.getProjektarbeit(this.student.uid)),
ajaxResponse: (url, params, response) => response.data,
@@ -153,9 +209,19 @@ export default {
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, data.projekttyp_kurzbz
);
this.editedProjektarbeit = data;
this.actionEditProjektarbeit();
});
container.append(button);
button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-users"></i>';
button.title = this.$p.t('projektarbeit', 'betreuerBearbeiten');
button.addEventListener('click', (event) => {
let data = cell.getData();
this.editedProjektarbeit = data;
this.actionEditBetreuer();
});
container.append(button);
@@ -184,76 +250,27 @@ export default {
columns: true, //persist column layout
},
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', 'projektarbeit']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('projekttyp_kurzbz').component.updateDefinition({
title: this.$p.t('projektarbeit', 'typ')
});
cm.getColumnByField('titel').component.updateDefinition({
title: this.$p.t('projektarbeit', 'titel')
});
cm.getColumnByField('beginn').component.updateDefinition({
title: this.$p.t('projektarbeit', 'beginn')
});
cm.getColumnByField('ende').component.updateDefinition({
title: this.$p.t('projektarbeit', 'ende')
});
cm.getColumnByField('freigegeben').component.updateDefinition({
title: this.$p.t('projektarbeit', 'freigegeben')
});
cm.getColumnByField('gesperrtbis').component.updateDefinition({
title: this.$p.t('projektarbeit', 'gesperrtBis')
});
cm.getColumnByField('themenbereich').component.updateDefinition({
title: this.$p.t('projektarbeit', 'themenbereich')
});
cm.getColumnByField('anmerkung').component.updateDefinition({
title: this.$p.t('projektarbeit', 'anmerkung')
});
cm.getColumnByField('firma_id').component.updateDefinition({
title: this.$p.t('projektarbeit', 'firmaId')
});
}
},
],
tabulatorData: [],
lastSelected: null,
statusNew: true,
studiensemester_kurzbz: null,
lehrveranstaltung_id: null
}
return options;
}
},
methods: {
actionNewProjektarbeit() {
this.statusNew = true;
this.$refs.projektarbeitDetails.resetForm();
this.$refs.projektarbeitDetails.getFormData(this.statusNew);
this.$refs.projektbetreuer.getData();
this.$refs.projektarbeitModal.show();
},
actionEditProjektarbeit(projektarbeit_id, studiensemester_kurzbz, lehrveranstaltung_id, projekttyp_kurzbz) {
actionEditProjektarbeit() {
this.statusNew = false;
this.$refs.projektarbeitDetails.getFormData(this.statusNew, studiensemester_kurzbz, lehrveranstaltung_id);
this.$refs.projektarbeitDetails.loadProjektarbeit(projektarbeit_id);
this.$refs.projektbetreuer.getData(projektarbeit_id, studiensemester_kurzbz, projekttyp_kurzbz);
this.toggleMenu('details');
this.$refs.projektarbeitDetails.getFormData(this.statusNew, this.editedProjektarbeit.studiensemester_kurzbz, this.editedProjektarbeit.lehrveranstaltung_id);
this.$refs.projektarbeitDetails.loadProjektarbeit(this.editedProjektarbeit.projektarbeit_id);
this.$refs.projektarbeitModal.show();
},
actionEditBetreuer() {
this.statusNew = false;
this.toggleMenu('betreuer');
this.$refs.projektbetreuer.getData(this.editedProjektarbeit.projektarbeit_id, this.editedProjektarbeit.studiensemester_kurzbz, this.editedProjektarbeit.projekttyp_kurzbz);
this.$refs.projektarbeitModal.show();
},
actionDeleteProjektarbeit(projektarbeit_id) {
@@ -266,34 +283,14 @@ export default {
.catch(this.$fhcAlert.handleSystemError);
},
addNewProjektarbeit() {
this.$refs.projektbetreuer.validateProjektbetreuer()
.then(() => {
return this.$refs.projektarbeitDetails.addNewProjektarbeit();
})
.then((result) => {
const projektarbeit_id = result.data;
if (!isNaN(projektarbeit_id)) {
return this.$refs.projektbetreuer.saveProjektbetreuer(projektarbeit_id);
}
})
this.$refs.projektarbeitDetails.addNewProjektarbeit()
.then((result) => {
this.projektarbeitSaved();
})
.catch(this.$fhcAlert.handleSystemError);
},
updateProjektarbeit() {
this.$refs.projektbetreuer.validateProjektbetreuer()
.then(() => {
return this.$refs.projektarbeitDetails.updateProjektarbeit();
})
.then((result) => {
const projektarbeit_id = result.data;
if (!isNaN(projektarbeit_id)) {
return this.$refs.projektbetreuer.saveProjektbetreuer(projektarbeit_id);
}
})
this.$refs.projektarbeitDetails.updateProjektarbeit()
.then((result) => {
this.projektarbeitSaved();
})
@@ -314,10 +311,6 @@ export default {
this.reload();
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.hideModal('projektarbeitModal');
this.$refs.projektarbeitDetails.resetForm();
},
rowSelectionChanged(data) {
this.lastSelected = data.length > 0 ? data[0] : null;
},
setDefaultStunden(projekttyp_kurzbz) {
this.$refs.projektbetreuer.setDefaultStunden(projekttyp_kurzbz);
@@ -327,6 +320,9 @@ export default {
},
reload() {
this.$refs.table.reloadTable();
},
toggleMenu(tabId) {
this.activeTab = tabId;
}
},
template: `
@@ -357,16 +353,16 @@ export default {
<template #modal-header-content>
<ul class="nav nav-tabs w-100 mt-3 msg_preview" id="pa_tabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab" aria-controls="details" aria-selected="true">Details</button>
<button class="nav-link" :class="activeTab == 'details' ? 'active' : ''" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab" aria-controls="details" aria-selected="true" @click="actionEditProjektarbeit">Details</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="betreuer-tab" data-bs-toggle="tab" data-bs-target="#betreuer" type="button" role="tab" aria-controls="betreuer" aria-selected="false">{{$p.t('projektarbeit', 'betreuerGross')}}</button>
<button class="nav-link" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer-tab" data-bs-toggle="tab" data-bs-target="#betreuer" type="button" role="tab" aria-controls="betreuer" aria-selected="false" @click="actionEditBetreuer">{{$p.t('projektarbeit', 'betreuerGross')}}</button>
</li>
</ul>
</template>
<div class="tab-content" id="pa_content">
<div class="tab-pane fade show active" id="details" role="tabpanel" aria-labelledby="details-tab">
<div class="tab-pane fade show" :class="activeTab == 'details' ? 'active' : ''" id="details" role="tabpanel" aria-labelledby="details-tab">
<div class="row">
<div class="col-12">
<projektarbeit-details ref="projektarbeitDetails" :student="student" @projekttyp-changed="setDefaultStunden">
@@ -375,7 +371,7 @@ export default {
</div>
</div>
<div class="tab-pane fade show" id="betreuer" role="tabpanel" aria-labelledby="betreuer-tab">
<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>
@@ -387,7 +383,7 @@ export default {
<template #footer>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
<button v-if="statusNew" class="btn btn-primary" @click="addNewProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
<button v-else class="btn btn-primary" @click="updateProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
<button v-if="!statusNew && activeTab == 'details'" class="btn btn-primary" @click="updateProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
</template>
</bs-modal>
@@ -132,6 +132,10 @@ export default {
event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global', 'person', 'stv', 'projektarbeit', 'ui']);
// Force layout recalculation for handling overflow text
this.$refs.projektbetreuerTable.tabulator.redraw(true);
}
},
{
@@ -193,7 +197,7 @@ export default {
if (idx >= 0) { // if betreuer found
betreuer = projektbetreuerListe[idx];
// set currently edited betreuera
// set currently edited betreuer
this.formData = betreuer;
// set download link
@@ -259,46 +263,31 @@ export default {
if (projektarbeit_id) {
this.projektarbeit_id = projektarbeit_id;
this.$api
.call(ApiStvProjektbetreuer.getProjektbetreuer(projektarbeit_id))
.then(result => {
this.$refs.projektbetreuerTable.tabulator.setData(this.addIds(result.data));
this.resetForm();
})
.catch(this.$fhcAlert.handleSystemError);
this.getProjektbetreuer();
} else {
this.$refs.projektbetreuerTable.tabulator.setData([]);
this.resetForm();
}
},
// confirming Betreuer means adding/updating him in list (but not yet saving in db)
confirmProjektbetreuer() {
if (!this.betreuerFormOpened) return;
if (typeof this.formData.betreuer_id == 'undefined') {
this.formData.betreuer_id = this.getNewBetreuerId();
this.$refs.projektbetreuerTable.tabulator.addData(this.addAutoCompleteBetreuerToFormData(this.formData));
} else {
this.$refs.projektbetreuerTable.tabulator.updateData([this.formData]);
}
this.resetModes();
},
confirmProjektbetreuerAfterValidation() {
//if (!this.formDataModified()) return;
this.validateProjektbetreuer()
getProjektbetreuer() {
this.$api
.call(ApiStvProjektbetreuer.getProjektbetreuer(this.projektarbeit_id))
.then(result => {
this.confirmProjektbetreuer();
this.$refs.projektbetreuerTable.tabulator.replaceData(this.addIds(result.data));
this.resetForm();
})
.catch(this.$fhcAlert.handleSystemError);
},
saveProjektbetreuer(projektarbeit_id) {
this.confirmProjektbetreuer();
return this.$refs.formProjektbetreuer.call(
ApiStvProjektbetreuer.saveProjektbetreuer(projektarbeit_id, this.$refs.projektbetreuerTable.tabulator.getData())
);
saveProjektbetreuer() {
this.$refs.formProjektbetreuer.call(
ApiStvProjektbetreuer.saveProjektbetreuer(this.projektarbeit_id, this.getFormDataWithBetreuer())
)
.then(result => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.getProjektbetreuer();
this.resetModes();
})
.catch(this.$fhcAlert.handleSystemError);
},
searchBetreuer(event) {
if (this.abortController.betreuer) {
@@ -312,16 +301,6 @@ export default {
this.filteredBetreuer = result.data;
});
},
// validate betreuer for data
validateProjektbetreuer() {
let alleBetreuer = this.$refs.projektbetreuerTable.tabulator.getData();
if (this.betreuerFormOpened) {
alleBetreuer.push(this.addAutoCompleteBetreuerToFormData(this.formData));
}
return this.$refs.formProjektbetreuer.call(ApiStvProjektbetreuer.validateProjektbetreuer(alleBetreuer));
},
resetForm() {
this.formData = this.getDefaultFormData();
if (this.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = '';
@@ -360,7 +339,7 @@ export default {
return betreuerListe;
},
// add the betreuer selected in automomplete to betreuer liste
addAutoCompleteBetreuerToFormData() {
getFormDataWithBetreuer() {
let preparedFormData = this.formData;
preparedFormData.projektarbeit_id = this.projektarbeit_id;
@@ -385,16 +364,6 @@ export default {
// if form data has not already been modified by user, set the default stunden
if (!this.formDataModified()) this.formData.stunden = this.getDefaultStunden(projekttyp_kurzbz);
},
// get a new betreuer id (max + 1)
getNewBetreuerId() {
let max = 0;
for (const betreuer of this.$refs.projektbetreuerTable.tabulator.getData()) {
if (betreuer.betreuer_id > max) max = betreuer.betreuer_id;
}
return max + 1;
},
// check if form data has been modified since initial data has been captured
formDataModified() {
if (this.autocompleteSelectedBetreuer != null) return true;
@@ -406,9 +375,6 @@ export default {
return false;
},
reload() {
this.$refs.projektbetreuerTable.reloadTable();
},
actionNewPerson() {
this.$refs.newPersonModal.reset();
this.$refs.newPersonModal.open();
@@ -422,7 +388,7 @@ export default {
this.$api
.call(ApiStvProjektbetreuer.getPerson(result.person_id))
.then(response => {
// set the new person in autocomplete field
// set the new person in Betreuer autocomplete field
this.autocompleteSelectedBetreuer = response.data;
})
.catch(this.$fhcAlert.handleSystemError)
@@ -541,8 +507,8 @@ export default {
</form-form>
<button class="btn btn-primary" v-show="betreuerFormOpened" @click="confirmProjektbetreuerAfterValidation">
{{ $p.t('projektarbeit', 'betreuerBestaetigen') }}
<button class="btn btn-primary" v-show="betreuerFormOpened" @click="saveProjektbetreuer">
{{ $p.t('projektarbeit', 'betreuerSpeichern') }}
</button>
<!-- <div class = "mt-5" v-if="beurteilungDownloadLink !== null">
<div class="mb-1">
+40 -20
View File
@@ -48606,26 +48606,6 @@ and represent the current state of research on the topic. The prescribed citatio
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'betreuerBestaetigen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'BetreuerIn bestätigen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Confirm assessor',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
@@ -49245,6 +49225,46 @@ and represent the current state of research on the topic. The prescribed citatio
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'betreuerBearbeiten',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Betreuer bearbeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Edit assessor',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'projektarbeit',
'phrase' => 'betreuerSpeichern',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Betreuer speichern',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Save assessor',
'description' => '',
'insertvon' => 'system'
)
)
)
// FHC-4 Projektarbeiten & Vertraege ENDE
);