Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into feature-63192/FHC4-Studierendenverwaltung_Semsterauswahl_fuer_mehrere_Tabs_anpassen

This commit is contained in:
Harald Bamberger
2025-07-31 17:03:31 +02:00
30 changed files with 139 additions and 26 deletions
@@ -31,6 +31,11 @@ class Address extends FHCAPI_Controller
'getNations' => self::PERM_LOGGED,
'getPlaces' => self::PERM_LOGGED
]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getNations()
@@ -53,7 +58,11 @@ class Address extends FHCAPI_Controller
$this->form_validation->set_data(['address.plz' => $plz]);
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]');
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']),
'less_than' => $this->p->t('ui', 'error_fieldLessThan10000', ['field' => 'PLZ'])
]);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
@@ -136,14 +136,19 @@ class Prestudent extends FHCAPI_Controller
$update_prestudent = array();
foreach ($array_allowed_props_prestudent as $prop)
{
$val = $this->input->post($prop);
if ($val !== null || $prop == 'foerderrelevant') {
$val = $this->input->post($prop, true);
if ($val !== null || $prop === 'foerderrelevant') {
$update_prestudent[$prop] = $val;
}
if (($prop == 'zgvdatum' && $val == '')
|| ($prop == 'zgvmadatum' && $val == '')
|| ($prop == 'zgvdoktordatum' && $val == '')
) {
// allowed to be null, but has to be in postparameter
if (
in_array($prop, ['zgvdatum', 'zgvmadatum', 'zgvdoktordatum', 'zgv_code', 'zgvmas_code', 'zgvdoktor_code'])
&& !isset($update_prestudent[$prop])
&& array_key_exists($prop, $_POST)
)
{
$update_prestudent[$prop] = null;
}
}
@@ -97,6 +97,15 @@ class Student extends FHCAPI_Controller
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
$this->PrestudentModel->addSelect('b.alias');
$this->PrestudentModel->addSelect('p.geburtsnation');
$this->PrestudentModel->addSelect('p.sprache');
$this->PrestudentModel->addSelect('p.gebort');
$this->PrestudentModel->addSelect('p.homepage');
$this->PrestudentModel->addSelect('p.anmerkung');
$this->PrestudentModel->addSelect('p.familienstand');
$this->PrestudentModel->addSelect('p.staatsbuergerschaft');
$this->PrestudentModel->addSelect('p.matr_nr');
$this->PrestudentModel->addSelect('p.anrede');
if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) {
$this->PrestudentModel->addSelect(
@@ -172,6 +181,7 @@ class Student extends FHCAPI_Controller
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->library('form_validation');
@@ -186,7 +196,15 @@ class Student extends FHCAPI_Controller
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date');
$this->form_validation->set_rules('semester', 'Semester', 'integer');
$this->form_validation->set_rules('semester', 'Semester', 'integer', [
'integer' => $this->p->t('ui', 'error_fieldNotInteger')
]
);
$this->form_validation->set_rules('alias', 'Alias', 'regex_match[/^[-a-z0-9\_\.]*[a-z0-9]{1,}\.[-a-z0-9\_]{1,}$/]',
[
'regex_match' => $this->p->t('ui', 'error_fieldInvalidAlias')
]);
$this->load->library('UDFLib');
@@ -298,11 +316,37 @@ class Student extends FHCAPI_Controller
// Do Updates
if (count($update_lehrverband)) {
$curstudlvb = $this->StudentlehrverbandModel->load([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid
]);
$data = $this->getDataOrTerminateWithError($curstudlvb);
$data = current($data);
$verbandCurrent = $data->verband;
$studiengang_kz = $data->studiengang_kz;
$semesterCurrent = $data->semester;
$gruppeCurrent = $data->gruppe;
$verband = isset($update_lehrverband['verband']) ? $update_lehrverband['verband'] : $verbandCurrent;
$gruppe = isset($update_lehrverband['gruppe']) ? $update_lehrverband['gruppe'] : $gruppeCurrent;
$semester = isset($update_lehrverband['semester']) ? $update_lehrverband['semester'] : $semesterCurrent;
//check if existing Lehrverband of new data to avoid Error
$result = $this->LehrverbandModel->loadWhere([
'verband' => $verband,
'gruppe' => $gruppe,
'semester' => $semester,
'studiengang_kz' => $studiengang_kz,
]);
if(!hasData($result))
{
$this->terminateWithError($this->p->t('lehre', 'error_noLehrverband'), self::ERROR_TYPE_GENERAL);
}
if(hasData($curstudlvb) && count(getData($curstudlvb)) > 0 )
{
$update_lehrverband['updatevon'] = $authuid;
@@ -137,8 +137,6 @@ export default {
layout: 'fitColumns',
layoutColumnsOnNewData: false,
height: '550',
selectableRangeMode: 'click',
selectable: true,
persistenceID: 'core-betriebsmittel'
},
tabulatorEvents: [
@@ -317,6 +315,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('ui', 'betriebsmittel')"
@click:new="actionNewBetriebsmittel"
@@ -132,8 +132,7 @@ export default {
<h2 class="h4">
{{headerData[0].titelpre}}
{{headerData[0].vorname}}
{{headerData[0].nachname}}
<span v-if="headerData[0].titelpost">, </span>
{{headerData[0].nachname}}<span v-if="headerData[0].titelpost">, </span>
{{headerData[0].titelpost}}
</h2>
@@ -444,6 +444,7 @@ export default {
table-only
:side-menu="false"
:reload= "!this.stylePv21"
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-class="this.newBtnStyle"
:new-btn-label="this.$p.t('person', 'funktion')"
@@ -401,6 +401,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('global', 'nachricht')"
@click:new="actionNewMessage"
+3 -4
View File
@@ -82,7 +82,7 @@ export default {
field: "text_stripped",
width: 250,
formatter: "html",
clipContents: true,
//clipContents: true,
tooltip:function(e, cell, onRendered){
var el = document.createElement("div");
el.style.backgroundColor = "white";
@@ -178,8 +178,6 @@ export default {
layoutColumnsOnNewData: false,
//responsiveLayout: "collapse",
maxHeight: '200px',
//selectableRangeMode: 'click',
//selectable: true,
index: 'notiz_id',
persistenceID: 'core-notiz'
},
@@ -254,7 +252,7 @@ export default {
title: this.$p.t('global', 'text'),
width: 250,
tooltip: true,
clipContents: true,
//clipContents: true,
});
// Force layout recalculation for handling overflow text
@@ -1268,6 +1266,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('global', 'notiz')"
@click:new="actionNewNotiz"
@@ -168,7 +168,6 @@ export default {
layoutColumnsOnNewData: false,
height: 'auto',
minHeight: '200',
selectable: true,
index: 'abschlusspruefung_id',
persistenceID: 'stv-details-finalexam'
},
@@ -542,6 +541,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('stv', 'tab_finalexam')"
@click:new="actionNewAbschlusspruefung"
@@ -357,6 +357,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
</core-filter-cmpt>
</template>
@@ -130,6 +130,7 @@ export default {
let editButton = document.createElement('button');
editButton.className = 'btn btn-outline-secondary';
editButton.innerHTML = '<i class="fa fa-edit"></i>';
editButton.title = this.$p.t('ui', 'bearbeiten');
editButton.addEventListener('click', () =>
this.$refs.edit.open(cell.getData())
);
@@ -139,6 +140,7 @@ export default {
let deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-outline-secondary';
deleteButton.innerHTML = '<i class="fa fa-trash"></i>';
deleteButton.title = this.$p.t('ui', 'loeschen');
deleteButton.addEventListener('click', evt => {
evt.stopPropagation();
this.$fhcAlert
@@ -262,6 +264,7 @@ export default {
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
<template #actions>
<div class="input-group w-auto">
@@ -358,6 +358,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('lehre', 'reihungstest')"
@click:new="actionNewPlacementTest"
@@ -336,6 +336,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
<template #actions="{selected}">
<button
@@ -347,6 +347,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('global', 'dokument')"
@click:new="actionUploadFile"
@@ -78,7 +78,6 @@ export default {
],
layout: 'fitDataFill',
height: 'auto',
selectable: true,
index: 'group_id',
persistenceID: 'stv-details-gruppe'
},
@@ -180,6 +179,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
</core-filter-cmpt>
</div>
@@ -329,6 +329,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('jointstudies', 'gemeinsamesStudium')"
@click:new="actionNewJointStudy"
@@ -123,7 +123,6 @@ export default{
},
],
height: 'auto',
selectable: true,
index: 'adresse_id',
persistenceID: 'stv-details-kontakt-address'
},
@@ -610,6 +609,7 @@ export default{
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('person', 'adresse')"
@click:new="actionNewAdress"
@@ -87,7 +87,6 @@ export default{
},
],
height: 'auto',
selectable: true,
index: 'bankverbindung_id',
persistenceID: 'stv-details-kontakt-bankaccount'
},
@@ -348,6 +347,7 @@ export default{
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('person', 'bankverbindung')"
@click:new="actionNewBankverbindung"
@@ -95,7 +95,6 @@ export default{
},
],
height: 'auto',
selectable: true,
index: 'kontakt_id',
persistenceID: 'stv-details-kontakt-contact'
},
@@ -449,6 +448,7 @@ export default{
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('global', 'kontakt')"
@click:new="actionNewContact"
@@ -248,6 +248,7 @@ export default {
:side-menu="false"
:tabulator-options="tabulatorOptions"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="$p.t('konto/buchung')"
:new-btn-disabled="stg_kz === ''"
@@ -175,6 +175,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
<template #actions>
<button
@@ -113,7 +113,6 @@ export default {
layoutColumnsOnNewData: false,
height: 'auto',
minHeight: 200,
selectable: true,
index: 'bisio_id',
persistenceID: 'stv-details-table_mobiliy'
},
@@ -436,6 +435,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('stv', 'tab_mobility')"
@click:new="actionNewMobility"
@@ -101,6 +101,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
<template #actions="{selected}">
<button class="btn btn-primary" :disabled="!selected.length" @click="copyGrades(selected)">
@@ -273,6 +273,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
<template v-if="['both', 'header'].includes(config.edit) || ['both', 'header'].includes(config.delete)" #actions="{selected}">
<zeugnis-actions :selected="selected" @set-grade="setGrade" @delete-grade="deleteGrade"></zeugnis-actions>
@@ -574,7 +574,7 @@ export default {
v-model="data.gsstudientyp_kurzbz"
name="gsstudientyp_kurzbz"
>
<option v-for="typ in listStgTyp" :key="typ.typ" :value="typ.typ">{{typ.bezeichnung}}</option>
<option v-for="typ in listStgTyp" :key="typ.gsstudientyp_kurzbz" :value="typ.gsstudientyp_kurzbz">{{typ.bezeichnung}}</option>
</form-input>
</div>
@@ -428,6 +428,7 @@ export default{
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('global', 'status')"
@click:new="actionNewStatus"
@@ -89,7 +89,7 @@ export default{
},
frozen: true
}],
layout: 'fitDataFill',
layout: 'fitDataStretchFrozen',
layoutColumnsOnNewData: false,
height: 'auto',
index: 'pruefung_id',
@@ -420,6 +420,7 @@ export default{
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('lehre', 'pruefung')"
@click:new="actionNewPruefung"
+2 -2
View File
@@ -66,6 +66,7 @@ export const CoreFilterCmpt = {
tableOnly: Boolean,
noColumnFilter:Boolean,
reload: Boolean,
reloadBtnInfotext: String,
download: {
type: [Boolean, String, Function, Array, Object],
default: false
@@ -648,7 +649,6 @@ export const CoreFilterCmpt = {
</h3>
</div>
</div>
<div :id="'filterCollapsables' + idExtra">
<div class="d-flex flex-row justify-content-between flex-wrap">
@@ -658,7 +658,7 @@ export const CoreFilterCmpt = {
{{ newBtnLabel }}
</button>
<button v-if="reload" class="btn btn-outline-secondary" aria-label="Reload" @click="reloadTable">
<span class="fa-solid fa-rotate-right" aria-hidden="true"></span>
<span class="fa-solid fa-rotate-right" aria-hidden="true" :title="reloadBtnInfotext ? reloadBtnInfotext : 'Reload'" ></span>
</button>
<span v-if="$slots.actions && tabulatorHasSelector">
<span v-if="countOnly">{{ selectedData.length }} ausgewählt</span>
+40
View File
@@ -44577,6 +44577,46 @@ and represent the current state of research on the topic. The prescribed citatio
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'error_fieldInvalidAlias',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alias ist ungültig',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Alias is invalid',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'error_fieldLessThan10000',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Das Eingabefeld {field} darf maximal 4-stellig sein.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The Field {Field} must contain a number less then 10000.',
'description' => '',
'insertvon' => 'system'
)
)
),
// FHC-4 Finetuning END
);
+2
View File
@@ -550,6 +550,8 @@ if($orgform_kurzbz != -1)
if($lehrveranstaltung_id != '')
$sql_query.= " AND tbl_lehrveranstaltung.lehrveranstaltung_id=".$db->db_add_param($lehrveranstaltung_id, FHC_INTEGER);
elseif(isset($_GET['delete_lvid']))
$sql_query.= " AND tbl_lehrveranstaltung.lehrveranstaltung_id=".$db->db_add_param(intval($_GET['delete_lvid']), FHC_INTEGER);
if($lehrveranstaltung_name != '')
{