Merge branch 'master' into feature-78292/dv_gehaltsbestandteil_ersteinstufung

This commit is contained in:
Harald Bamberger
2026-08-12 11:39:49 +02:00
17 changed files with 335 additions and 75 deletions
+1
View File
@@ -1,5 +1,6 @@
documents/
vendor/
public/vendor
/nbproject/
.vscode
+2
View File
@@ -91,11 +91,13 @@ $route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/incoming/1'] = 'a
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/outgoing/1'] = 'api/frontend/v1/stv/students/getOutgoing/$1';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/shared_studies/1'] = 'api/frontend/v1/stv/students/getGemeinsamestudien/$1';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)/:any/1/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)/:any/1/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3';
@@ -197,3 +197,11 @@ $config['unterbrechung_enabled'] = true;
*/
$config['wiederholung_enabled'] = true;
/**
* Modal with Infotext of TLC
* if true, there will be shown an info modal in the studentsView after the first button ABMELDUNG
*
* @var boolean
*/
$config['showInfoModalAbmeldung'] = true;
@@ -14,11 +14,11 @@ class Mylv extends Auth_Controller
public function __construct()
{
parent::__construct([
'Student' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Studiensemester' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Lvs' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Info' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Pruefungen' => ['student/anrechnung_beantragen:r','user:r'] // TODO(chris): permissions?
'Student' => self::PERM_LOGGED,
'Studiensemester' => self::PERM_LOGGED,
'Lvs' => self::PERM_LOGGED,
'Info' => self::PERM_LOGGED,
'Pruefungen' => self::PERM_LOGGED
]);
}
+1 -1
View File
@@ -125,7 +125,7 @@ class AntragJob extends JOB_Controller
$stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz;
}
$result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id);
$result = $this->StudierendenantragModel->getStgAndDetails($antrag->studierendenantrag_id);
if (isError($result))
{
$this->logError(getError($result));
@@ -25,7 +25,8 @@ class Studierendenantrag extends FHC_Controller
// Load language phrases
$this->loadPhrases([
'studierendenantrag'
'studierendenantrag',
'ui'
]);
$this->load->config('studierendenantrag');
+8 -11
View File
@@ -320,16 +320,9 @@ class StudentListLib
* @param string studiensemester_kurzbz
*
*/
protected function addSelectAndJoinForTagsIfConfigured($studiensemester_kurzbz)
{
protected function addSelectAndJoinForTagsIfConfigured($studiensemester_kurzbz)
{
if (defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED) {
$this->_ci->load->model('system/Sprache_model', 'SpracheModel');
$this->_ci->SpracheModel->addSelect('index');
$result = $this->_ci->SpracheModel->loadWhere(array('sprache' => getUserLanguage()));
$language = hasData($result) ? getData($result)[0]->index : 1;
$index_bezeichnung_mehrsprachig = $language - 1;
$this->_ci->load->config('stv');
$tags = $this->_ci->config->item('stv_prestudent_tags');
@@ -351,7 +344,11 @@ class StudentListLib
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
array_to_json(nt.bezeichnung_mehrsprachig)->>". $index_bezeichnung_mehrsprachig . " AS beschreibung,
nt.bezeichnung_mehrsprachig[(
SELECT index
FROM tbl_sprache
WHERE sprache=" . $this->_ci->PrestudentModel->escape(getUserLanguage()) . "
)] AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
@@ -387,7 +384,7 @@ class StudentListLib
$this->addSelect('tag_data_agg.tags');
$this->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
}
}
}
/**
* Get alias of a table or select statement
@@ -188,6 +188,7 @@ class Studierendenantrag_model extends DB_Model
* Get the studiengang and ausbildungssemester the student was in
* for the studiensemester the antrag was committed for
*
*
* @param integer $antrag_id
*
* @return stdClass
@@ -242,6 +243,28 @@ class Studierendenantrag_model extends DB_Model
);
}
/**
* Get the studiengang and the studienplan the student is in
*
* @param integer $antrag_id
*
* @return stdClass
*/
public function getStgAndDetails($antrag_id)
{
$this->addSelect('p.studiengang_kz');
$this->addSelect('stg.orgform_kurzbz');
$this->addSelect('stg.bezeichnung');
$this->addJoin('public.tbl_prestudent p', 'prestudent_id');
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz');
$this->addLimit(1);
return $this->load(
$antrag_id
);
}
public function getStgEmail($antrag_id)
{
$this->addJoin('public.tbl_prestudent p', 'prestudent_id');
+74 -10
View File
@@ -30,6 +30,12 @@ if(defined('CIS4')){
}
?>
<?php
$config = $this->load->config('studierendenantrag');
$showInfoModalAbmeldung = $this->config->item('showInfoModalAbmeldung');
?>
<div id="wrapper">
<div class="fhc-header">
@@ -43,17 +49,75 @@ if(defined('CIS4')){
<h4><?= $array['bezeichnungStg']; ?> (<?= $array['bezeichnungOrgform']; ?>)</h4>
<?php foreach ($array['allowedNewTypes'] as $type) { ?>
<div class="alert alert-secondary">
<p><?= $this->p->t('studierendenantrag', 'calltoaction_' . $type); ?></p>
<hr>
<a
href="<?= site_url('lehre/Studierendenantrag/' . strtolower($type) . '/' . $prestudent_id); ?>"
class="btn btn-outline-secondary"
>
<i class="fa fa-plus"></i> <?= $this->p->t('studierendenantrag', 'antrag_typ_' . $type); ?>
</a>
<p><?= $this->p->t('studierendenantrag', 'calltoaction_' . $type); ?></p>
<hr>
<?php
if($type == 'Abmeldung' && $showInfoModalAbmeldung){
$href = "#modalinfo" . $prestudent_id;
}
else
$href = site_url('lehre/Studierendenantrag/' . strtolower($type) . '/' . $prestudent_id);
?>
<a
href="<?= $href ?>"
class="btn btn-outline-secondary"
<?php if($type == 'Abmeldung' && $showInfoModalAbmeldung): ?>
data-bs-toggle="modal"
<?php endif; ?>
>
<i class="fa fa-plus"></i> <?= $this->p->t('studierendenantrag', 'antrag_typ_' . $type); ?>
</a>
<!-- Modal -->
<div
class="modal fade"
id="modalinfo<?= $prestudent_id; ?>"
tabindex="-1"
aria-labelledby="modalinfoLabel<?= $prestudent_id; ?>"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5
class="modal-title"
id="modalinfoLabel<?= $prestudent_id; ?>"
> <?= $this->p->t('studierendenantrag', 'info_consultation'); ?>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<?php
$hrefUnterbrechung = site_url('lehre/Studierendenantrag/unterbrechung/' . $prestudent_id);
?>
<div class="modal-body">
<div
class="form-control"
style="width: 100%; height: 250px;overflow:auto; white-space: normal;"
><?= $this->p->t('studierendenantrag', 'modalHinweistext_Abmeldung', ['linkUnterbrechung' => $hrefUnterbrechung] ); ?>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-primary" data-bs-dismiss="modal"><?= $this->p->t('ui', 'cancel'); ?></button>
<a
href="<?= site_url('lehre/Studierendenantrag/abmeldung/' . $prestudent_id); ?>"
class="btn btn-outline-primary"
> <?= $this->p->t('studierendenantrag', 'link_Abmeldung'); ?>
</a>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
<?php } ?>
<table class="table">
<thead>
@@ -205,7 +269,7 @@ if(defined('CIS4')){
</a>
<lv-popup
id="modallv<?= $antrag->studierendenantrag_id; ?>"
antrag-id = "<?= $antrag->studierendenantrag_id; ?>"
:antrag-id = "<?= $antrag->studierendenantrag_id; ?>"
>
<?= $this->p->t('studierendenantrag', 'my_lvs'); ?>
</lv-popup>
@@ -82,6 +82,9 @@ export default {
hasTileGammaSlot() {
return !!this.$slots.titleGammaTile
},
hasTileDeltaSlot() {
return !!this.$slots.titleDeltaTile
},
hasTileUIDSlot() {
return !!this.$slots.uid
},
@@ -492,6 +495,13 @@ export default {
<div class="px-2" style="min-width: 100px;">
<slot name="issues"></slot>
</div>
<div v-if="hasTileDeltaSlot" class="px-2" style="border-left: 1px solid #EEE">
<h4 class="mb-1 text-center"><slot name="titleDeltaTile"></slot></h4>
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
<slot v-else name="valueDeltaTile"></slot>
</h6>
</div>
<div v-if="hasTileGammaSlot" class="px-2" style="border-left: 1px solid #EEE">
<h4 class="mb-1 text-center"><slot name="titleGammaTile"></slot></h4>
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
@@ -612,6 +622,13 @@ export default {
<div class="px-2" style="min-width: 100px;">
<slot name="issues"></slot>
</div>
<div v-if="hasTileDeltaSlot" class="px-2" style="border-left: 1px solid #EEE">
<h4 class="mb-1 text-center"><slot name="titleDeltaTile"></slot></h4>
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
<pv-skeleton v-if="isLoading" width="4rem"></pv-skeleton>
<slot v-else name="valueDeltaTile"></slot>
</h6>
</div>
<div v-if="hasTileGammaSlot" class="px-2" style="border-left: 1px solid #EEE">
<h4 class="mb-1 text-center"><slot name="titleGammaTile"></slot></h4>
<h6 class="text-muted d-flex align-items-center justify-content-center flex-wrap gap-1">
@@ -63,6 +63,14 @@ export default {
let tile = this.students[0].matrikelnr != null ? this.students[0].matrikelnr : '-';
return tile;
},
tile_PrestdId(){
let tile = this.students[0].prestudent_id != null ? this.students[0].prestudent_id : '-';
return tile;
},
tile_UID(){
let tile = this.students[0].uid != null ? this.students[0].uid : '-';
return tile;
},
},
watch: {
'$p.user_language.value'(n, o) {
@@ -143,13 +151,15 @@ export default {
fotoEditable
:isLoading="isLoading"
>
<template #uid>{{students[0].uid}}</template>
<template #titleAlphaTile>PersID</template>
<template #valueAlphaTile>{{tile_PersId}}</template>
<template #titleBetaTile>MatrNr</template>
<template #valueBetaTile>{{tile_MatrNr}}</template>
<template #titleGammaTile>PersKz</template>
<template #valueGammaTile>{{tile_PersKz}}</template>
<template #uid>{{tile_UID}}</template>
<template #titleAlphaTile>PrestdID</template>
<template #valueAlphaTile>{{tile_PrestdId}}</template>
<template #titleBetaTile>PersID</template>
<template #valueBetaTile>{{tile_PersId}}</template>
<template #titleGammaTile>MatrNr</template>
<template #valueGammaTile>{{tile_MatrNr}}</template>
<template #titleDeltaTile>PersKz</template>
<template #valueDeltaTile>{{tile_PersKz}}</template>
</fhc-header>
<fhc-tabs
v-if="students.length == 1"
@@ -402,7 +402,7 @@ export default {
name="foto"
@actionbutton-clicked="sendInfomail"
>
<img alt="No Image" :src="noImageSrc" class="w-100">
<img alt="No Image" :src="noImageSrc" />
</form-input>
<form-input
v-if="!config.hiddenFields.includes('anmerkung')"
@@ -31,6 +31,11 @@ export default {
teacherLoaded: false,
};
},
computed: {
gradeListLink() {
return this.$api.getUri('/person/gradelist/index/' + this.modelValue.uid);
}
},
methods: {
reload() {
this.$refs.zeugnis.$refs.table.reloadTable();
@@ -69,13 +74,21 @@ export default {
const savedPath = window.localStorage.getItem(LOCAL_STORAGE_ID);
this.stdsem = savedPath || '';
},
template: `
template: /* html */`
<div class="stv-details-noten d-flex flex-column overflow-hidden">
<div class="mb-3">
<select class="form-select" v-model="stdsem" @input="saveStdsem">
<option value="">{{ $p.t('ui/current_semester') }}</option>
<option value="true">{{ $p.t('ui/all_semester') }}</option>
</select>
<div class="d-flex justify-content-between my-2">
<div>
<select class="form-select" v-model="stdsem" @input="saveStdsem">
<option value="">{{ $p.t('ui/current_semester') }}</option>
<option value="true">{{ $p.t('ui/all_semester') }}</option>
</select>
</div>
<div>
<a :href="gradeListLink" target="_blank">
{{ $p.t('stv/grades_gradelist') }}
<i class="fa-solid fa-arrow-up-right-from-square"></i>
</a>
</div>
</div>
<div class="row">
<div class="col-8">
+23 -19
View File
@@ -107,7 +107,6 @@ export const CoreFilterCmpt = {
default: [],
},
},
inject: ["language"],
data: function () {
return {
uuid: 0,
@@ -215,23 +214,9 @@ export const CoreFilterCmpt = {
fieldIdsForVisibilty() {
if (!this.tableBuilt) return [];
const localizedColumnTitles = this.tabulator.getLang().columns;
const isTabulatorLocalized = !!this.$props.tabulatorOptions.locale;
return this.tabulator
.getColumns()
.filter((col) => {
let def = col.getDefinition();
let title =
isTabulatorLocalized && localizedColumnTitles[def.field]
? localizedColumnTitles[def.field]
: def.title;
return (
!def.frozen &&
title &&
def.formatter != "responsiveCollapse"
);
})
.map((col) => col.getField());
return this.$props.tabulatorOptions?.columns
?.filter((column) => column.formatter !== "responsiveCollapse")
.map((column) => column.field) ?? [];
},
idExtra() {
if (!this.uuid) return "";
@@ -261,6 +246,9 @@ export const CoreFilterCmpt = {
...{ title: filterTitles[el.name] },
}));
},
language() {
return this.$p.user_language;
},
},
watch: {
"language.value": {
@@ -931,7 +919,23 @@ export const CoreFilterCmpt = {
if (!this.tableBuilt) {
return {};
} else if (this.tabulator.options.locale) {
return this.tabulator.getLang().columns;
let result = this.tabulator.getLang().columns;
const columnFieldTitlePairs = this.tabulator
.getColumns()
.map((column) => {
const definition = column.getDefinition();
return [definition.field, definition.title];
});
columnFieldTitlePairs.forEach((fieldTitlePair) => {
if (
fieldTitlePair[0]?.length &&
fieldTitlePair[1]?.length &&
!(fieldTitlePair[0] in result)
) {
result[fieldTitlePair[0]] = fieldTitlePair[1];
}
});
return result;
}
return this.tabulator.getColumns().reduce((res, col) => {
res[col.getField()] = col.getDefinition().title;
@@ -34,6 +34,7 @@ export default {
presetInfo: null,
newPreset: null,
newPresetName: "",
presetIndexBeingApplied: null,
};
},
computed: {
@@ -161,6 +162,9 @@ export default {
},
},
methods: {
getPresetIndex() {
return this.presetIndexBeingApplied;
},
async showPresetInfo(preset) {
let shouldUpdatePresetInfo;
if (!this.presetInfo) {
@@ -393,14 +397,22 @@ export default {
this.fetchCustomUserTabulatorPresets();
}
},
async applyPreset(preset) {
preset = this.syncPresetWithConfig(preset);
window.localStorage["tabulatorPreset-" + this.$props.presetsId] =
preset.id ? "custom:" + preset.id : "general:" + preset.name;
async applyPreset(preset, index) {
this.presetIndexBeingApplied = index;
this.$props.tabulator.modules.tablePresets.applyPreset(preset);
this.$emit("tablePresetApplied", { preset });
// workaround for updating DOM and displaying preset-loading spinner
// conventional use of $nextTick ineffective
setTimeout(() => {
preset = this.syncPresetWithConfig(preset);
window.localStorage["tabulatorPreset-" + this.$props.presetsId] =
preset.id ? "custom:" + preset.id : "general:" + preset.name;
this.$props.tabulator.modules.tablePresets.applyPreset(preset);
this.$emit("tablePresetApplied", { preset });
this.presetIndexBeingApplied = null;
}, 50);
},
async fetchCustomUserTabulatorPresets() {
let tabulatorPresetsResponse = await this.$api.call(
@@ -453,7 +465,7 @@ export default {
if (!preset) return;
this.applyPreset(preset);
this.applyPreset(preset, null);
},
},
async created() {
@@ -467,8 +479,19 @@ export default {
<div class="card-header">{{ $p.t("tabulator_presets/table_presets") }}</div>
<div class="card-body d-flex flex-column">
<div class="d-flex flex-row gap-1 justify-content-start flex-wrap">
<div v-for="preset in allPresets" class="d-flex flex-column gap-1 mb-2">
<div @click="applyPreset(preset)" class="btn btn-dark py-1 px-2">{{ preset.name }}</div>
<div v-for="(preset, index) in allPresets" class="d-flex flex-column gap-1 mb-2">
<div @click="applyPreset(preset, index)" class="position-relative btn btn-dark py-1 px-2">
<span :class="{'opacity-0': getPresetIndex() === index}">{{ preset.name }}</span>
<div
v-if="getPresetIndex() === index"
class="position-absolute d-flex flex-row align-items-center justify-content-center"
style="inset:0;"
>
<div class="spinner-border spinner-border-sm" role="status" style>
<span class="visually-hidden">Loading...</span>
</div>
</div>
</div>
<div class="d-flex flex-row justify-content-center">
<div class="d-flex flex-row gap-2 px-3">
<span @click="showPresetInfo(preset)" type="button" class="fa-solid fa-circle-info"></span>
@@ -34,10 +34,21 @@ export default class TablePresetsModule extends Module {
if (preset.headerFilters) {
Object.entries(preset.headerFilters).forEach(
([columnField, filterValue]) => {
this.table.setHeaderFilterValue(
columnField,
filterValue,
);
this.table.setHeaderFilterValue(columnField, filterValue);
// double checking if filter inputs are filled in due to issues with custom header filters
const headerFilterInputElement =
this.table.columnManager.columns
.find((column) => column.field === columnField)
?.element.querySelector(
".tabulator-header-filter input",
);
if (
headerFilterInputElement &&
headerFilterInputElement.value !== filterValue
) {
headerFilterInputElement.value = filterValue;
}
},
);
}
+86
View File
@@ -41556,6 +41556,26 @@ array(
)
),
// grades
array(
'app' => 'core',
'category' => 'stv',
'phrase' => 'grades_gradelist',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Studienverlauf',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Grade list',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'stv',
@@ -62265,6 +62285,72 @@ I have been informed that I am under no obligation to consent to the transmissio
)
),
// StudVw legacy Bis Links ende
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'link_Abmeldung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Weiter zur Abmeldung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Continue to De-registration',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'modalHinweistext_Abmeldung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => "Bevor du deine Abmeldung abschließt, möchten wir dir gerne ein Gespräch anbieten. Vielleicht gibt es Fragen, Unsicherheiten oder Herausforderungen, bei denen wir dich unterstützen können.<br>
<br>Du kannst dich jederzeit unverbindlich an deine Studiengangsassistenz, Studiengangsleitung oder das <a href='https://cis.technikum-wien.at/cis.php/CisVue/Cms/content/9248' target='_blank'>Student Support Team</a> wenden. Ein Gespräch ist natürlich freiwillig – manchmal hilft es aber, gemeinsam Optionen zu besprechen, zum Beispiel auch eine vorübergehende
<a href={linkUnterbrechung} target='_blank'>Studienunterbrechung</a>.
<br><br>Wenn du deine Abmeldung fortsetzen möchtest, kannst du das selbstverständlich tun.",
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => "Before you finalize your deregistration, we would like to offer you a consultation. Perhaps you have questions, uncertainties, or challenges that we can help you with. <br>
<br>You can contact your program assistant, program director, or the <a href='https://cis.technikum-wien.at/cis.php/CisVue/Cms/content/9248' target='_blank'>Student Support Team</a> at any time without obligation. A consultation is, of course, voluntary; however, sometimes it helps to discuss options together, such as a
<a href={linkUnterbrechung} target='_blank'>temporary break</a> from your studies.
<br><br>If you wish to proceed with your deregistration, you can, of course, do so.",
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'info_consultation',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Hinweis Beratungsgespräch',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Note Consultation',
'description' => '',
'insertvon' => 'system'
)
)
),
);