Merge branch 'master' into feature-62462/FHC4_Studierendenverwaltung_Delete_Photo

This commit is contained in:
Harald Bamberger
2025-09-26 14:29:32 +02:00
76 changed files with 8124 additions and 203 deletions
+11
View File
@@ -0,0 +1,11 @@
<?php
/*It defines which tags are available in LVVerwaltung and whether they are editable
$config['lvverwaltung_tags'] = [
'tag_1' => ['readonly' => false],
'tag_1' => ['readonly' => true]
];
*/
$config['lvverwaltung_tags'] = [];
+11 -1
View File
@@ -64,7 +64,7 @@ $config['navigation_header'] = array(
'lehrveranstaltungen' => array(
'link' => site_url('lehre/lvplanung/LvTemplateUebersicht'),
'icon' => '',
'description' => 'Lehrveranstaltungen',
'description' => 'Lehrveranstaltungen Templates',
'sort' => 15
),
'reihungstest' => array(
@@ -81,6 +81,16 @@ $config['navigation_header'] = array(
'sort' => 30,
'requiredPermissions' => 'infocenter:r'
),
'lvverwaltung' => array(
'link' => site_url('LVVerwaltung'),
'icon' => '',
'description' => 'LV Verwaltung',
'requiredPermissions' => array(
'admin:r',
'assistenz:r'
),
'sort' => 35
),
'lehrauftrag' => array(
'link' => site_url('lehre/lehrauftrag/Lehrauftrag/Dashboard'),
'description' => 'Lehrauftrag',
+42
View File
@@ -0,0 +1,42 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class LVVerwaltung extends Auth_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* @return void
*/
public function _remap()
{
$this->load->view('LVVerwaltung', [
'permissions' => [
'lehre/lehrveranstaltung' => $this->permissionlib->isBerechtigt('lehre/lehrveranstaltung'),
'lv-plan/gruppenentfernen' => $this->permissionlib->isBerechtigt('lv-plan/gruppenentfernen'),
'lv-plan/lektorentfernen' => $this->permissionlib->isBerechtigt('lv-plan/lektorentfernen'),
],
'variables' => [
'semester_aktuell' => $this->variablelib->getVar('semester_aktuell')
],
'configs' => [
'showVertragsdetails' => defined('FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN') && FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN,
'showGewichtung' => defined('CIS_GESAMTNOTE_GEWICHTUNG') && CIS_GESAMTNOTE_GEWICHTUNG,
'lehreinheitAnmerkungDefault' => defined('LEHREINHEIT_ANMERKUNG_DEFAULT') ? LEHREINHEIT_ANMERKUNG_DEFAULT : '',
'lehreinheitRaumtypDefault' => defined('DEFAULT_LEHREINHEIT_RAUMTYP') ? DEFAULT_LEHREINHEIT_RAUMTYP : '',
'lehreinheitRaumtypAlternativeDefault' => defined('DEFAULT_LEHREINHEIT_RAUMTYP_ALTERNATIV') ? DEFAULT_LEHREINHEIT_RAUMTYP_ALTERNATIV : ''
]
]);
}
}
@@ -0,0 +1,265 @@
<?php
/**
* 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 <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Lehrveranstaltung extends FHCAPI_Controller
{
private $_ci;
private $_uid;
public function __construct()
{
parent::__construct([
'getByEmp' => ['admin:r', 'assistenz:r'],
'getByStg' => ['admin:r', 'assistenz:r'],
'loadByLV' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->loadPhrases(
array(
'ui'
)
);
}
public function getByEmp($studiensemester_kurzbz = null, $mitarbeiter_uid = null, $stg_kz = null)
{
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$lehrveranstaltungen = $this->_ci->LehreinheitModel->getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
$tree = [];
foreach ($lehrveranstaltungen_data as $lehrveranstaltung)
{
$lehreinheiten = $this->_ci->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
if (!isset($lehrveranstaltung->_children))
{
$lehrveranstaltung->_children = $lehreinheiten_data;
}
$tree[] = $lehrveranstaltung;
}
$this->terminateWithSuccess($tree);
}
public function getByStg($studiensemester_kurzbz = null, $studiengang_kz = null, $semester = null)
{
if (is_null($studiengang_kz) || !preg_match("/^-?[1-9][0-9]*$/", (string)$studiengang_kz))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$verband = null;
if (!is_null($semester) && !is_numeric($semester))
{
$verband = $semester;
$semester = null;
}
$this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel');
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$studienplan_ids = array();
$only_ids = array();
$placeholders = array();
if (hasData($studienplan_data))
{
foreach (getData($studienplan_data) as $studienplan) {
$placeholders[] = "(?, ?)";
$studienplan_ids[] = $studienplan->studienplan_id;
$studienplan_ids[] = $studienplan->semester;
$only_ids[] = $studienplan->studienplan_id;
}
}
$lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$lehrveranstaltungen_data = hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array();
$tree = [];
foreach ($lehrveranstaltungen_data as $row)
{
$rowData = $row;
$lehreinheiten_data = $this->_ci->LehreinheitModel->getByLvidStudiensemester($row->lehrveranstaltung_id, $studiensemester_kurzbz);
if (hasData($lehreinheiten_data))
{
$lehreinheiten = getData($lehreinheiten_data);
$rowData->_children = $lehreinheiten;
}
if (!isEmptyString($row->studienplan_lehrveranstaltung_id_parent))
{
$child = $this->_ci->StudienplanModel->loadStudienplanLehrveranstaltung($row->studienplan_lehrveranstaltung_id_parent);
if (hasData($child))
{
$child = getData($child)[0];
$searchId = $child->lehrveranstaltung_id;
foreach ($lehrveranstaltungen_data as &$searchParent)
{
if ($searchParent->lehrveranstaltung_id === $searchId)
{
if (!isset($searchParent->_children))
{
$searchParent->_children = [];
}
if (is_array($searchParent->_children))
{
$searchParent->_children[] = $row;
}
else
{
$searchParent->_children = [$searchParent->_children, $row];
}
break;
}
}
}
}
else
{
$tree[] = $rowData;
}
}
$counter = 0;
$this->assignUniqueIndex($tree, $counter);
$this->terminateWithSuccess($tree);
}
public function loadByLV($lehrveranstaltung_id = null)
{
if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->_ci->LehrveranstaltungModel->addSelect('lehrveranstaltung_id, lehrform_kurzbz, lehre, bezeichnung as lvbezeichnung, sprache');
$lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id));
$lehrveranstaltung_result = $this->getDataOrTerminateWithError($lehrveranstaltung_result);
$lehrveranstaltung = $lehrveranstaltung_result[0];
$this->_ci->LehreinheitModel->addSelect('lehrveranstaltung_id_kompatibel');
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung_kompatibel', 'lehrveranstaltung_id');
$lehrfaecher = $this->_ci->LehreinheitModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung->lehrveranstaltung_id));
$lehrfaecher_array = [];
if (hasData($lehrfaecher))
$lehrfaecher_array = array_merge($lehrfaecher_array, array_column(getData($lehrfaecher), 'lehrveranstaltung_id_kompatibel'));
$lehrfaecher_array[] = $lehrveranstaltung->lehrveranstaltung_id;
$this->_ci->LehrveranstaltungModel->addDistinct('lehrfach_id');
$this->_ci->LehrveranstaltungModel->addSelect("tbl_lehrveranstaltung.lehrveranstaltung_id, CONCAT(tbl_lehrveranstaltung.bezeichnung || '(' || tbl_lehrveranstaltung.oe_kurzbz || ')') as lehrfach");
$this->_ci->LehrveranstaltungModel->db->where_in('tbl_lehrveranstaltung.lehrveranstaltung_id', $lehrfaecher_array);
$lehrfaecher_result = $this->_ci->LehrveranstaltungModel->load();
$lehrfaecher_array = hasData($lehrfaecher_result) ? getData($lehrfaecher_result) : array();
$lehrveranstaltung->lehrfaecher = $lehrfaecher_array;
$this->terminateWithSuccess($lehrveranstaltung);
}
/*
* (david) ggf. im naechsten release
* public function loadByOrganization($oe_kurzbz)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$lehrveranstaltungen = $this->LehrveranstaltungModel->getLvsByOrganization($oe_kurzbz);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
$tree = [];
foreach ($lehrveranstaltungen_data as $lehrveranstaltung)
{
$lehreinheiten = $this->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
if (!isset($lehrveranstaltung->_children))
{
$lehrveranstaltung->_children = $lehreinheiten_data;
}
$tree[] = $lehrveranstaltung;
}
$this->terminateWithSuccess($tree);
}*/
/*public function loadByFachbereich($fachbereich, $mitarbeiter_uid = null)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->LehreinheitModel->getLvsByFachbereich($fachbereich, $studiensemester_kurzbz, $mitarbeiter_uid);
}*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
private function assignUniqueIndex(&$nodes, &$counter)
{
foreach ($nodes as &$node)
{
$node->uniqueindex = $counter++;
if (!empty($node->_children) && is_array($node->_children))
{
$this->assignUniqueIndex($node->_children, $counter);
}
}
}
private function getStudiensemesterKurzbz($studiensemester_kurzbz = null)
{
if (!is_null($studiensemester_kurzbz))
{
$studiensemester_result = $this->_ci->StudiensemesterModel->load($studiensemester_kurzbz);
if (isError($studiensemester_result) || !hasData($studiensemester_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return getData($studiensemester_result)[0]->studiensemester_kurzbz;
}
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
}
}
@@ -0,0 +1,110 @@
<?php
/**
* 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 <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class DirektGruppe extends FHCAPI_Controller
{
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'delete' => ['admin:rw', 'assistenz:rw'],
'getByLehreinheit' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->loadPhrases([
'ui'
]);
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
}
public function add()
{
$uid = $this->input->post('uid');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$this->checkPermission($lehreinheit_id, $uid);
$result = $this->_ci->LehreinheitgruppeModel->direktUserAdd($uid, $lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function delete()
{
$uid = $this->input->post('uid');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$this->checkPermission($lehreinheit_id, $uid);
$result = $this->_ci->LehreinheitgruppeModel->direktUserDelete($uid, $lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function getByLehreinheit($lehreinheit_id = null)
{
$this->checkPermission($lehreinheit_id);
$gruppen = $this->_ci->LehreinheitgruppeModel->getDirectGroup($lehreinheit_id);
$this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : array());
}
private function checkPermission($lehreinheit_id, $uid = false)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if ($uid)
{
$benuzuer_result = $this->_ci->BenutzerModel->load(array($uid));
if (!hasData($benuzuer_result) || isError($benuzuer_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
}
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
}
}
@@ -0,0 +1,47 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Favorites extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'index' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
]);
// Load models
$this->load->model('system/Variable_model', 'VariableModel');
}
public function index()
{
$result = $this->VariableModel->getVariables(getAuthUID(), ['lv_favorites']);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
$this->terminateWithSuccess(null);
else
$this->terminateWithSuccess(isset($data['lv_favorites']) ? $data['lv_favorites'] : null);
}
public function set()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('favorites', 'Favorites', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$favorites = $this->input->post('favorites');
$result = $this->VariableModel->setVariable(getAuthUID(), 'lv_favorites', $favorites);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
}
@@ -0,0 +1,195 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Gruppe extends FHCAPI_Controller
{
private $_uid;
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'delete' => ['admin:rw', 'assistenz:rw'],
'deleteFromLVPlan' => ['admin:rw', 'assistenz:rw'],
'getBenutzer' => ['admin:r', 'assistenz:r'],
'getAll' => ['admin:r', 'assistenz:r'],
'getByLehreinheit' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->library('PhrasesLib');
$this->loadPhrases(
array(
'ui'
)
);
$this->_ci->load->model('organisation/Gruppe_model', 'GruppeModel');
$this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('person/Person_model', 'PersonModel');
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
}
public function delete()
{
$lehreinheitgruppe_id = $this->input->post('lehreinheitgruppe_id');
$lehreinheit_id = $this->input->post('lehreinheit_id');
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($lehreinheitgruppe_id) || !ctype_digit((string)$lehreinheitgruppe_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheitgruppe_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheitgruppe_id' => $lehreinheitgruppe_id));
if (!hasData($lehreinheitgruppe_result) || isError($lehreinheitgruppe_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->LehreinheitgruppeModel->deleteGroup($lehreinheit_id, $lehreinheitgruppe_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function add()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$gid = $this->input->post('gid');
$lehrverband = $this->input->post('lehrverband');
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($gid) || !ctype_digit((string)$gid) || is_null($lehrverband))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, !($lehrverband === 'false'));
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function getByLehreinheit($lehreinheit_id = null)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$gruppen = $this->_ci->LehreinheitgruppeModel->getByLehreinheit($lehreinheit_id);
$this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : array());
}
public function deleteFromLVPlan()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$lehreinheitgruppe_id = $this->input->post('lehreinheitgruppe_id');
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($lehreinheitgruppe_id) || !ctype_digit((string)$lehreinheitgruppe_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheitgruppe_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheitgruppe_id' => $lehreinheitgruppe_id));
if (!hasData($lehreinheitgruppe_result) || isError($lehreinheitgruppe_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->StundenplandevModel->deleteGroupPlanning($lehreinheit_id, $lehreinheitgruppe_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function getAll()
{
$this->_ci->GruppeModel->addSelect('gruppe_kurzbz,
studiengang_kz,
semester,
bezeichnung,
gid,
\'false\' as lehrverband');
$gruppen_result = $this->_ci->GruppeModel->loadWhere(array('sichtbar' => true, 'aktiv' => true, 'lehre' => true, 'direktinskription' => false, 'semester IS NOT NULL' => null));
$gruppen_array = array();
if (isError($gruppen_result))
$this->terminateWithError(getError($gruppen_result), self::ERROR_TYPE_GENERAL);
if (hasData($gruppen_result))
$gruppen_array = getData($gruppen_result);
$this->_ci->LehrverbandModel->addSelect('CONCAT(UPPER(CONCAT(typ, kurzbz)), \'\', semester, verband, COALESCE(gruppe,\'\')) as gruppe_kurzbz,
studiengang_kz,
semester,
tbl_lehrverband.bezeichnung,
gid,
\'true\' as lehrverband');
$this->_ci->LehrverbandModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehrverbandModel->addOrder('verband');
$this->_ci->LehrverbandModel->addOrder('gruppe');
$lehrverband_result = $this->_ci->LehrverbandModel->loadWhere(array('tbl_lehrverband.aktiv' => true));
$lehrverband_array = array();
if (isError($lehrverband_result))
$this->terminateWithError(getError($lehrverband_result), self::ERROR_TYPE_GENERAL);
if (hasData($lehrverband_result))
$lehrverband_array = getData($lehrverband_result);
$all_gruppen = array_merge($gruppen_array, $lehrverband_array);
$this->terminateWithSuccess($all_gruppen);
}
public function getBenutzer()
{
$this->_ci->PersonModel->addSelect('vorname, nachname, uid, semester, UPPER(CONCAT(tbl_studiengang.typ, tbl_studiengang.kurzbz)) as studiengang');
$this->_ci->PersonModel->addJoin('public.tbl_benutzer', 'person_id');
$this->_ci->PersonModel->addJoin('public.tbl_mitarbeiter', 'uid = mitarbeiter_uid', 'LEFT');
$this->_ci->PersonModel->addJoin('public.tbl_student', 'uid = student_uid', 'LEFT');
$this->_ci->PersonModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
$personen = $this->_ci->PersonModel->loadWhere(array('tbl_benutzer.aktiv' => true));
$this->terminateWithSuccess(hasData($personen) ? getData($personen) : array());
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
private function checkPermission($lehreinheit_id)
{
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
}
}
@@ -0,0 +1,446 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Lehreinheit extends FHCAPI_Controller
{
private $_uid;
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'copy' => ['admin:rw', 'assistenz:rw'],
'delete' => ['admin:rw', 'assistenz:rw'],
'update' => ['admin:rw', 'assistenz:rw'],
'get' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getLehrfach' => ['admin:r', 'assistenz:r'],
'getSprache' => ['admin:r', 'assistenz:r'],
'getRaumtyp' => ['admin:r', 'assistenz:r'],
'getLehrform' => ['admin:r', 'assistenz:r']
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->_ci->load->library('PhrasesLib');
$this->loadPhrases(
array(
'global',
'ui'
)
);
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
}
public function get($lehreinheit_id)
{
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
$lehreinheit->lehrfaecher = $this->getLehrfaecher($lehreinheit);
$this->terminateWithSuccess($lehreinheit);
}
private function getLehrfaecher($lehreinheit)
{
$lehrfacher_array = array($lehreinheit->lehrfach_id);
$this->_ci->LehreinheitModel->addSelect('lehrveranstaltung_id_kompatibel');
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung_kompatibel', 'lehrveranstaltung_id');
$lehrfaecher = $this->_ci->LehreinheitModel->loadWhere(array('lehrveranstaltung_id' => $lehreinheit->lehrveranstaltung_id));
if (hasData($lehrfaecher))
$lehrfaecher_array = array_merge($lehrfacher_array, array_column(getData($lehrfaecher), 'lehrveranstaltung_id_kompatibel'));
$lehrfaecher_array[] = $lehreinheit->lehrveranstaltung_id;
$this->_ci->LehrveranstaltungModel->addDistinct('lehrfach_id');
$this->_ci->LehrveranstaltungModel->addSelect("tbl_lehrveranstaltung.lehrveranstaltung_id, CONCAT(tbl_lehrveranstaltung.bezeichnung || '(' || tbl_lehrveranstaltung.oe_kurzbz || ')') as lehrfach");
$this->_ci->LehrveranstaltungModel->db->where_in('tbl_lehrveranstaltung.lehrveranstaltung_id', $lehrfaecher_array);
$lehrfaecher_result = $this->_ci->LehrveranstaltungModel->load();
return hasData($lehrfaecher_result) ? getData($lehrfaecher_result) : array();
}
public function add()
{
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id));
if (!hasData($lehrveranstaltung_result) || isError($lehrveranstaltung_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehrveranstaltung = getData($lehrveranstaltung_result)[0];
$oe_result = $this->_ci->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id);
$oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array();
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
$this->_ci->load->library('form_validation');
$updatableFields = array(
'lehrveranstaltung_id',
'studiensemester_kurzbz',
'lehrfach_id',
'lehrform_kurzbz',
'stundenblockung',
'wochenrythmus',
'gewicht',
'start_kw',
'raumtyp',
'raumtypalternativ',
'sprache',
'lehre',
'anmerkung',
'lvnr',
'unr',
);
foreach ($updatableFields as $field)
{
switch ($field) {
case 'lehrveranstaltung_id':
$this->form_validation->set_rules($field, 'Lehrveranstaltung ID', 'required|integer');
break;
case 'studiensemester_kurzbz':
$this->form_validation->set_rules($field, 'Studiensemester', 'required|max_length[16]');
break;
case 'lehrfach_id':
$this->form_validation->set_rules($field, 'Lehrfach ID', 'required|integer');
break;
case 'lehrform_kurzbz':
$this->form_validation->set_rules($field, 'Lehrform', 'required|max_length[8]');
break;
case 'stundenblockung':
$this->form_validation->set_rules($field, 'Stundenblockung', 'required|integer|greater_than_equal_to[0]');
break;
case 'wochenrythmus':
$this->form_validation->set_rules($field, 'Wochenrhytmus', 'required|integer|greater_than_equal_to[0]');
break;
case 'start_kw':
$this->form_validation->set_rules($field, 'Start KW', 'integer|greater_than[0]|less_than_equal_to[53]');
break;
case 'gewicht':
$this->form_validation->set_rules($field, 'Gewicht', 'numeric');
break;
case 'raumtyp':
$this->form_validation->set_rules($field, 'Raumtyp', 'required|max_length[16]');
break;
case 'raumtypalternativ':
$this->form_validation->set_rules($field, 'Raumtyp Alternativ', 'required|max_length[16]');
break;
case 'sprache':
$this->form_validation->set_rules($field, 'Sprache', 'required|max_length[16]');
break;
case 'lvnr':
$this->form_validation->set_rules($field, 'LVNR', 'integer');
break;
case 'unr':
$this->form_validation->set_rules($field, 'UNR', 'integer');
break;
case 'lehre':
$this->form_validation->set_rules($field, 'Lehre', 'trim');
break;
case 'anmerkung':
$this->form_validation->set_rules($field, 'Anmerkung', 'trim');
break;
}
}
if ($this->form_validation->run() === false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$updateData = array();
foreach ($updatableFields as $field)
{
$value = $this->input->post($field);
if ($value !== null)
{
$updateData[$field] = $value;
}
}
$updateData['insertvon'] = $this->_uid;
$updateData['insertamum'] = date('Y-m-d H:i:s');
$result = $this->_ci->LehreinheitModel->insert(
$updateData
);
if (!isset($updateData['unr']))
{
$unr = getData($result);
$this->_ci->LehreinheitModel->update($unr, array('unr' => $unr));
}
$this->terminateWithSuccess($result);
}
public function copy()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$art = $this->input->post('art');
$lehreinheit_old = $this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_old->lehreinheit_id);
$lehreinheit_new = $lehreinheit_old;
$lehreinheit_new->unr = null;
unset($lehreinheit_new->lehreinheit_id);
$lehreinheit_new->updateamum = date('Y-m-d H:i:s');
$lehreinheit_new->updatevon = $this->_uid;
$lehreinheit_new->insertamum = date('Y-m-d H:i:s');
$lehreinheit_new->insertvon = $this->_uid;
$insert_result = $this->_ci->LehreinheitModel->insert($lehreinheit_new);
if (isError($insert_result))
$this->terminateWithError(getError($insert_result), self::ERROR_TYPE_GENERAL);
$lehreinheit_id_new = getData($insert_result);
$this->_ci->LehreinheitModel->update(array('lehreinheit_id' => $lehreinheit_id_new), array('unr' => $lehreinheit_id_new));
if (in_array($art, array('gruppen', 'alle')))
{
$gruppen_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($gruppen_result))
$this->terminateWithError(getError($gruppen_result), self::ERROR_TYPE_GENERAL);
if (hasData($gruppen_result))
{
$gruppen = getData($gruppen_result);
foreach ($gruppen as $gruppe)
{
$gruppe_new = $gruppe;
unset($gruppe_new->lehreinheitgruppe_id);
$gruppe_new->lehreinheit_id = $lehreinheit_id_new;
$gruppe_new->insertamum = date('Y-m-d H:i:s');
$gruppe_new->insertvon = $this->_uid;
$gruppe_new->updateamum = date('Y-m-d H:i:s');
$gruppe_new->updatevon = $this->_uid;
$gruppe_new_result = $this->_ci->LehreinheitgruppeModel->insert($gruppe_new);
if (isError($gruppe_new_result))
$this->terminateWithError(getError($gruppe_new_result), self::ERROR_TYPE_GENERAL);
}
}
}
if (in_array($art, array('lektoren', 'alle')))
{
$lektoren_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($lektoren_result))
$this->terminateWithError(getError($lektoren_result), self::ERROR_TYPE_GENERAL);
if (hasData($lektoren_result))
{
$lektoren = getData($lektoren_result);
foreach ($lektoren as $lektor)
{
$lektor_new = $lektor;
$lektor_new->lehreinheit_id = $lehreinheit_id_new;
$lektor_new->insertamum = date('Y-m-d H:i:s');
$lektor_new->insertvon = $this->_uid;
$lektor_new->updateamum = date('Y-m-d H:i:s');
$lektor_new->updatevon = $this->_uid;
unset($lektor_new->vertrag_id);
$lektor_new_result = $this->_ci->LehreinheitmitarbeiterModel->insert((array)$lektor_new);
if (isError($lektor_new_result))
$this->terminateWithError(getError($lektor_new_result), self::ERROR_TYPE_GENERAL);
}
}
}
$this->terminateWithSuccess("Erfolgeich gespeichert");
}
public function delete()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit->lehreinheit_id);
$result = $this->_ci->LehreinheitModel->deleteLehreinheit($lehreinheit->lehreinheit_id);
if (isError($result))
$this->terminateWithValidationErrors(getError($result));
$this->terminateWithSuccess('Erfolgreich geloescht');
}
public function update()
{
$lehreinheit = $this->checkLehreinheit($this->input->post('lehreinheit_id'));
$this->checkPermission($lehreinheit->lehreinheit_id);
$this->_ci->load->library('form_validation');
$formData = $this->input->post('formData');
$updatableFields = array(
'lehrveranstaltung_id',
'studiensemester_kurzbz',
'lehrfach_id',
'lehrform_kurzbz',
'stundenblockung',
'wochenrythmus',
'gewicht',
'start_kw',
'raumtyp',
'raumtypalternativ',
'sprache',
'lehre',
'anmerkung',
'lvnr',
'unr',
);
$this->form_validation->set_data($formData);
foreach ($updatableFields as $field)
{
if (array_key_exists($field, $formData))
{
switch ($field)
{
case 'lehrveranstaltung_id':
$this->form_validation->set_rules($field, 'Lehrveranstaltung ID', 'required|integer');
break;
case 'studiensemester_kurzbz':
$this->form_validation->set_rules($field, 'Studiensemester', 'required|max_length[16]');
break;
case 'lehrfach_id':
$this->form_validation->set_rules($field, 'Lehrfach ID', 'required|integer');
break;
case 'lehrform_kurzbz':
$this->form_validation->set_rules($field, 'Lehrform', 'required|max_length[8]');
break;
case 'stundenblockung':
$this->form_validation->set_rules($field, 'Stundenblockung', 'required|integer|greater_than_equal_to[0]');
break;
case 'wochenrythmus':
$this->form_validation->set_rules($field, 'Wochenrhytmus', 'required|integer|greater_than_equal_to[0]');
break;
case 'start_kw':
$this->form_validation->set_rules($field, 'Start KW', 'integer|greater_than[0]|less_than_equal_to[53]');
break;
case 'gewicht':
$this->form_validation->set_rules($field, 'Gewicht', 'numeric|greater_than_equal_to[0]');
break;
case 'raumtyp':
$this->form_validation->set_rules($field, 'Raumtyp', 'required|max_length[16]');
break;
case 'raumtypalternativ':
$this->form_validation->set_rules($field, 'Raumtyp Alternativ', 'required|max_length[16]');
break;
case 'sprache':
$this->form_validation->set_rules($field, 'Sprache', 'required|max_length[16]');
break;
case 'lvnr':
$this->form_validation->set_rules($field, 'LVNR', 'integer');
break;
case 'unr':
$this->form_validation->set_rules($field, 'UNR', 'integer|greater_than_equal_to[0]');
break;
case 'lehre':
$this->form_validation->set_rules($field, 'Lehre', 'trim');
break;
case 'anmerkung':
$this->form_validation->set_rules($field, 'Anmerkung', 'trim');
break;
}
}
}
if ($this->form_validation->run() === false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$updateData = [];
foreach ($updatableFields as $field)
{
if (array_key_exists($field, $formData))
{
$updateData[$field] = $formData[$field];
}
}
$updateData['updatevon'] = $this->_uid;
$updateData['updateamum'] = date('Y-m-d H:i:s');
$result = $this->_ci->LehreinheitModel->update(
[
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
],
$updateData
);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess($this->p->t('global', 'gespeichert'));
}
private function checkPermission($lehreinheit_id)
{
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
}
private function checkLehreinheit($lehreinheit_id)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return getData($lehreinheit_result)[0];
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -0,0 +1,409 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Lektor extends FHCAPI_Controller
{
private $_uid;
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'update' => ['admin:rw', 'assistenz:rw'],
'cancelVertrag' => ['admin:rw', 'assistenz:rw'],
'deleteLVPlan' => ['admin:rw', 'assistenz:rw'],
'deletePerson' => ['admin:rw', 'assistenz:rw'],
'getLehrfunktionen' => ['admin:r', 'assistenz:r'],
'getLektoren' => ['admin:r', 'assistenz:r'],
'getLektorenByLE' => ['admin:r', 'assistenz:r'],
'getLektorDaten' => ['admin:r', 'assistenz:r'],
'getLektorVertrag' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->_ci->load->library('PermissionLib');
$this->_ci->load->library('LektorLib');
$this->_ci->load->library('form_validation');
$this->loadPhrases([
'ui'
]);
$this->_ci->load->model('accounting/Vertrag_model', 'VertragModel');
$this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->_ci->load->model('ressource/Stundensatz_model', 'StundensatzModel');
}
private function checkMitarbeiter($mitarbeiter_uid)
{
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
}
public function add()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkMitarbeiter($mitarbeiter_uid);
$lehrfach_permission = $this->checkLehrfachPermission($lehreinheit_id, array('assistenz', 'admin'));
$lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
if (!$lehrfach_permission && !$lehreinheit_permission)
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
$result = $this->_ci->lektorlib->addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid);
if (isError($result)) $this->terminateWithError(getError($result));
$this->terminateWithSuccess("Erfolgreich gespeichert");
}
public function update()
{
$formData = $this->input->post('formData');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkMitarbeiter($mitarbeiter_uid);
$updatableFields = array(
'lehrfunktion_kurzbz',
'planstunden',
'stundensatz',
'faktor',
'anmerkung',
'bismelden',
'semesterstunden',
'mitarbeiter_uid'
);
$this->form_validation->set_data($formData);
foreach ($updatableFields as $field)
{
if (array_key_exists($field, $formData))
{
switch ($field)
{
case 'lehrfunktion_kurzbz':
$this->form_validation->set_rules($field, 'Lehrfunktion', 'required|max_length[16]');
break;
case 'planstunden':
$this->form_validation->set_rules($field, 'Planstunden', 'integer|greater_than_equal_to[0]');
break;
case 'stundensatz':
$formData['stundensatz'] = str_replace(',', '.', $formData['stundensatz']);
$this->form_validation->set_rules($field, 'Stundensatz', 'callback__check_stundensatz');
break;
case 'faktor':
$this->form_validation->set_rules($field, 'Faktor', 'numeric|greater_than_equal_to[0]');
break;
case 'anmerkung':
$this->form_validation->set_rules($field, 'Anmerkung', 'max_length[256]');
break;
case 'bismelden':
$this->form_validation->set_rules($field, 'Bis Melden', 'trim');
break;
case 'semesterstunden':
$formData['semesterstunden'] = str_replace(',', '.', $formData['semesterstunden']);
$this->form_validation->set_rules($field, 'Semesterstunden', 'callback__check_semesterstunden');
break;
case 'mitarbeiter_uid':
$this->form_validation->set_rules($field, 'Semesterstunden', 'required|max_length[32]');
break;
}
}
}
if (!$this->form_validation->run())
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if (isset($formData['semesterstunden']) && (!is_numeric($formData['semesterstunden']) || $formData['semesterstunden'] === ''))
{
$formData['semesterstunden'] = null;
}
$lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
if (!$lehreinheit_permission)
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
$result = $this->_ci->lektorlib->updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $formData);
if (isError($result)) $this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function _check_stundensatz($value)
{
$value = str_replace(',', '.', $value);
if (!is_numeric($value))
{
$this->form_validation->set_message('_check_decimal', 'Das Feld {field} muss eine Zahl sein.');
return false;
}
if ($value < 0 || $value >= 10000) {
$this->form_validation->set_message('_check_decimal', 'Das Feld {field} muss zwischen 0 und 10000 liegen.');
return false;
}
return true;
}
public function _check_semesterstunden($value)
{
if ($value === null || $value === '') {
return true;
}
if (!is_numeric($value))
{
$this->form_validation->set_message(
'_check_semesterstunden',
'Das Feld {field} muss eine Zahl sein.'
);
return false;
}
if ($value < 0)
{
$this->form_validation->set_message(
'_check_semesterstunden',
'Das Feld {field} muss eine Zahl größer oder gleich 0 sein.'
);
return false;
}
if ($value > 999.99)
{
$this->form_validation->set_message(
'_check_semesterstunden',
'Das Feld {field} darf maximal 999,99 betragen.'
);
return false;
}
return true;
}
public function getLehrfunktionen()
{
$this->_ci->load->model('education/Lehrfunktion_model', 'LehrfunktionModel');
$this->_ci->LehrfunktionModel->addOrder('lehrfunktion_kurzbz');
$this->terminateWithSuccess(getData($this->_ci->LehrfunktionModel->load()));
}
public function getLektoren()
{
$this->_ci->MitarbeiterModel->addSelect('uid, person_id, vorname, nachname');
$this->_ci->MitarbeiterModel->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid');
$this->_ci->MitarbeiterModel->addJoin('public.tbl_person', 'person_id');
$this->terminateWithSuccess(getData($this->_ci->MitarbeiterModel->loadWhere(array('public.tbl_benutzer.aktiv' => true))));
}
private function checkLehreinheit($lehreinheit_id)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return getData($lehreinheit_result)[0];
}
public function getLektorenByLE($lehreinheit_id = null)
{
$this->checkLehreinheit($lehreinheit_id);
$le_mitarbeiter_data = $this->_ci->LehreinheitmitarbeiterModel->getLektorenByLe($lehreinheit_id);
$this->terminateWithSuccess(hasData($le_mitarbeiter_data) ? getData($le_mitarbeiter_data) : array());
}
public function getLektorDaten($lehreinheit_id = null, $mitarbeiter_uid = null)
{
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
if (is_null($mitarbeiter_uid))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz));
$studiensemester = getData($studiensemester_result)[0];
$defaultStundensatz = $this->_ci->StundensatzModel->getDefaultStundensatz($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre');
$le_mitarbeiter_result = $this->_ci->LehreinheitmitarbeiterModel->getByLeLektor($lehreinheit_id, $mitarbeiter_uid);
$le_mitarbeiter_data = array();
if (hasData($le_mitarbeiter_result))
{
$le_mitarbeiter_data = getData($le_mitarbeiter_result)[0];
$le_mitarbeiter_data->default_stundensatz = $defaultStundensatz;
}
$vertrag = $this->getLektorVertrag($lehreinheit_id, $mitarbeiter_uid);
$le_mitarbeiter_data->vertrag = $vertrag;
$this->terminateWithSuccess($le_mitarbeiter_data);
}
private function getLektorVertrag($lehreinheit_id = null, $mitarbeiter_uid = null)
{
$this->_ci->load->model('accounting/Vertrag_model', 'VertragModel');
$vertrag = $this->_ci->VertragModel->getVertrag($mitarbeiter_uid, $lehreinheit_id);
return hasData($vertrag) ? getData($vertrag)[0] : null;
}
private function checkLehrfachPermission($lehreinheit_id, $permissions)
{
$lehrfach_oe_kurzbz = $this->_ci->LehreinheitModel->getLehrfachOe($lehreinheit_id);
if (isError($lehrfach_oe_kurzbz))
$this->terminateWithError(getError($lehrfach_oe_kurzbz), self::ERROR_TYPE_GENERAL);
$lehrfach_oe_kurzbz = array('');
if (hasData($lehrfach_oe_kurzbz))
$lehrfach_oe_kurzbz = array_column(getData($lehrfach_oe_kurzbz), 'oe_kurzbz');
return $this->checkPermissionGenerel($permissions, $lehrfach_oe_kurzbz);
}
private function checkPermissionGenerel($permissions, $oe_array)
{
$hasPermission = false;
foreach ($permissions as $permission)
{
if ($this->_ci->permissionlib->isBerechtigtMultipleOe($permission, $oe_array, 'suid'))
{
$hasPermission = true;
break;
}
}
return $hasPermission;
}
private function checkPermission($lehreinheit_id, $permissions)
{
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
return $this->checkPermissionGenerel($permissions, $oe_array);
}
public function cancelVertrag()
{
$vertrag_id = $this->input->post('vertrag_id');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_id, array('admin', 'lehre/lehrauftrag_bestellen'));
if (is_null($vertrag_id) || !ctype_digit((string)$vertrag_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$vertrag_result = $this->_ci->VertragModel->load($vertrag_id);
if (!hasData($vertrag_result) || isError($vertrag_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if (is_null($mitarbeiter_uid))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$result = $this->_ci->VertragModel->cancelVertrag($vertrag_id, $mitarbeiter_uid);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function deletePerson()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$delete_result =$this->_ci->LehreinheitmitarbeiterModel->deleteLektorFromLe($lehreinheit_id, $mitarbeiter_uid);
if (isError($delete_result))
$this->terminateWithError(getError($delete_result));
$this->terminateWithSuccess($delete_result);
}
public function deleteLVPlan()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_id, array('lv-plan/lektorentfernen'));
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$delete_result = $this->_ci->StundenplandevModel->deleteLektorPlanning($lehreinheit_id, $mitarbeiter_uid);
if (isError($delete_result))
$this->terminateWithError(getError($delete_result));
$this->terminateWithSuccess($delete_result);
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -0,0 +1,121 @@
<?php
/**
* 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 <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Setup extends FHCAPI_Controller
{
private $_ci;
private $_uid;
public function __construct()
{
parent::__construct([
'getTabs' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getSprache' => ['admin:r', 'assistenz:r'],
'getRaumtyp' => ['admin:r', 'assistenz:r'],
'getLehrform' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
}
public function getTabs()
{
$tabs['details'] = array (
'title' => 'Details',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Details.js',
'config' => []
);
$tabs['gruppen'] = array (
'title' => 'Gruppen',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Gruppen.js',
'config' => []
);
$tabs['lektor'] = array (
'title' => 'LektorInnenzuteilung',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Lektor.js',
'config' => []
);
$tabs['notiz'] = array (
'title' => 'Notizen',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Notiz.js',
'config' => []
);
$this->terminateWithSuccess($tabs);
}
public function getStudiensemester()
{
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->_ci->StudiensemesterModel->addOrder('start', 'DESC');
$this->terminateWithSuccess(getData($this->_ci->StudiensemesterModel->load()));
}
public function getSprache()
{
$this->_ci->load->model('system/Sprache_model', 'SpracheModel');
$this->terminateWithSuccess(getData($this->_ci->SpracheModel->load()));
}
public function getRaumtyp()
{
$this->_ci->load->model('ressource/Raumtyp_model', 'RaumtypModel');
$this->_ci->RaumtypModel->addOrder('raumtyp_kurzbz');
$this->terminateWithSuccess(getData($this->_ci->RaumtypModel->loadWhere(array('aktiv' => true))));
}
public function getLehrform()
{
$language = $this->_getLanguageIndex();
$this->_ci->load->model('codex/lehrform_model', 'LehrformModel');
$this->_ci->LehrformModel->addSelect(
'*,
bezeichnung_kurz[('.$language.')] as bez_kurz,
bezeichnung_lang[('.$language.')] as bez
'
);
$this->terminateWithSuccess(getData($this->_ci->LehrformModel->load()));
}
private function _getLanguageIndex()
{
$this->_ci->load->model('system/Sprache_model', 'SpracheModel');
$this->_ci->SpracheModel->addSelect('index');
$result = $this->_ci->SpracheModel->loadWhere(array('sprache' => getUserLanguage()));
return hasData($result) ? getData($result)[0]->index : 1;
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -0,0 +1,117 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class StgTree extends FHCAPI_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
public function _remap($method, $params = [])
{
if ($method == '' || $method == 'index')
return $this->getBase();
if (!$this->permissionlib->isBerechtigt('assistenz', 's', $method)
&& !$this->permissionlib->isBerechtigt('admin', 's', $method)
) {
return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]);
}
return $this->getStudiengang($method);
show_404();
}
protected function getBase()
{
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("v.studiengang_kz AS link");
$this->StudiengangModel->addSelect(
"CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name",
false
);
$this->StudiengangModel->addSelect('erhalter_kz');
$this->StudiengangModel->addSelect('typ');
$this->StudiengangModel->addSelect('kurzbz');
$this->StudiengangModel->addSelect('studiengang_kz');
$this->StudiengangModel->addSelect('studiengang_kz AS stg_kz');
$this->StudiengangModel->addOrder('erhalter_kz');
$this->StudiengangModel->addOrder('typ');
$this->StudiengangModel->addOrder('kurzbz');
$stgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$stgs = array_merge($stgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
if (!$stgs)
$this->terminateWithSuccess([]);
$this->StudiengangModel->db->where_in('studiengang_kz', $stgs);
$result = $this->StudiengangModel->loadWhere(['v.aktiv' => true]);
$list = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($list);
}
protected function getStudiengang($studiengang_kz)
{
$link = $studiengang_kz . '/';
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester ORDER BY verband, gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("TRUE AS leaf", false);
$this->StudiengangModel->addSelect('semester');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('semester');
$result = $this->StudiengangModel->loadWhere([
'v.studiengang_kz' => $studiengang_kz,
'v.aktiv' => true
]);
$list = $this->getDataOrTerminateWithError($result);
$result = $this->StudiengangModel->load($studiengang_kz);
$result = $this->getDataOrTerminateWithError($result);
if ($result)
{
if (current($result)->mischform)
{
$this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
$this->StudienordnungModel->addDistinct();
$this->StudienordnungModel->addSelect("CONCAT(studiengang_kz, '/', p.orgform_kurzbz) AS link");
$this->StudienordnungModel->addSelect("p.orgform_kurzbz AS name");
$this->StudienordnungModel->addSelect("TRUE as leaf", false);
$this->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id');
$result = $this->StudienordnungModel->loadWhere([
'aktiv' => true,
'studiengang_kz' => $studiengang_kz,
'p.orgform_kurzbz !=' => 'DDP'
]);
$result = $this->getDataOrTerminateWithError($result);
$list = array_merge($list, $result);
}
}
$this->terminateWithSuccess($list);
}
}
@@ -0,0 +1,50 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Tags extends Tag_Controller
{
const BERECHTIGUNG_KURZBZ = ['admin:rw', 'assistenz:rw'];
public function __construct()
{
parent::__construct([
'getTag' => self::BERECHTIGUNG_KURZBZ,
'getTags' => self::BERECHTIGUNG_KURZBZ,
'addTag' => self::BERECHTIGUNG_KURZBZ,
'updateTag' => self::BERECHTIGUNG_KURZBZ,
'doneTag' => self::BERECHTIGUNG_KURZBZ,
'deleteTag' => self::BERECHTIGUNG_KURZBZ,
'updateLehre' => self::BERECHTIGUNG_KURZBZ,
'doneLehre' => self::BERECHTIGUNG_KURZBZ,
'deleteLehre' => self::BERECHTIGUNG_KURZBZ,
]);
$this->config->load('lvverwaltung');
}
public function getTag($readonly_tags = null)
{
parent::getTag($this->config->item('lvverwaltung_tags'));
}
public function getTags($tags = null)
{
parent::getTags($this->config->item('lvverwaltung_tags'));
}
public function addTag($withZuordnung = true, $updatable_tags = null)
{
parent::addTag(true, $this->config->item('lvverwaltung_tags'));
}
public function updateTag($updatable_tags = null)
{
parent::updateTag($this->config->item('lvverwaltung_tags'));
}
public function deleteTag($withZuordnung = true, $updatable_tags = null)
{
parent::deleteTag(true, $this->config->item('lvverwaltung_tags'));
}
public function doneTag($updatable_tags = null)
{
parent::doneTag($this->config->item('lvverwaltung_tags'));
}
}
@@ -0,0 +1,21 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class NotizLehreinheit extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'getUid' => ['admin:r', 'assistenz:r'],
'getNotizen' => ['admin:r', 'assistenz:r'],
'loadNotiz' => ['admin:r', 'assistenz:r'],
'addNewNotiz' => ['admin:rw', 'assistenz:rw'],
'updateNotiz' => ['admin:rw', 'assistenz:rw'],
'deleteNotiz' => ['admin:rw', 'assistenz:rw'],
'loadDokumente' => ['admin:r', 'assistenz:r'],
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
}
@@ -362,6 +362,8 @@ class InfoCenter extends Auth_Controller
$data[self::ORIGIN_PAGE] = $origin_page;
$data[self::PREV_FILTER_ID] = $this->input->get(self::PREV_FILTER_ID);
$data['studiensemester'] = $this->variablelib->getVar('infocenter_studiensemester');
$this->load->view('system/infocenter/infocenterDetails.php', $data);
}
+2 -2
View File
@@ -393,10 +393,10 @@ abstract class Notiz_Controller extends FHCAPI_Controller
foreach ($result as $doc) {
$res = $this->dmslib->removeAll($doc->dms_id);
if (isError($result))
if (isError($res))
{
$this->db->trans_rollback();
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($res), self::ERROR_TYPE_GENERAL);
}
}
+126 -24
View File
@@ -29,13 +29,36 @@ class Tag_Controller extends FHCAPI_Controller
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('system/Notiztyp_model', 'NotiztypModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
$this->loadPhrases([
'ui'
]);
}
public function getTag()
public function getTag($readonly_tags = null)
{
$language = $this->_getLanguageIndex();
$id = $this->input->get('id');
if (is_array($readonly_tags) && !isEmptyArray($readonly_tags))
{
$readonly_tags = $this->_filterTag($readonly_tags, true);
foreach ($readonly_tags as $key => $tag)
{
$readonly_tags[$key] = $this->NotizModel->db->escape($tag);
}
$tags = '(' . implode(',', $readonly_tags) . ')';
$this->NotizModel->addSelect("
CASE
WHEN tbl_notiz_typ.typ_kurzbz IN $tags
THEN TRUE
ELSE FALSE
END as readonly
");
}
$this->NotizModel->addSelect(
"tbl_notiz.titel,
tbl_notiz.text,
@@ -54,7 +77,7 @@ class Tag_Controller extends FHCAPI_Controller
$this->NotizModel->addJoin('public.tbl_benutzer verfasserbenutzer', 'tbl_notiz.verfasser_uid = verfasserbenutzer.uid', 'LEFT');
$this->NotizModel->addJoin('public.tbl_person verfasserperson', 'verfasserbenutzer.person_id = verfasserperson.person_id', 'LEFT');
$this->NotizModel->addJoin('public.tbl_benutzer bearbeiterbenutzer', 'tbl_notiz.verfasser_uid = bearbeiterbenutzer.uid', 'LEFT');
$this->NotizModel->addJoin('public.tbl_benutzer bearbeiterbenutzer', 'tbl_notiz.bearbeiter_uid = bearbeiterbenutzer.uid', 'LEFT');
$this->NotizModel->addJoin('public.tbl_person bearbeiterperson', 'bearbeiterbenutzer.person_id = bearbeiterperson.person_id', 'LEFT');
$notiz = $this->NotizModel->loadWhere(array('notiz_id' => $id));
@@ -62,7 +85,7 @@ class Tag_Controller extends FHCAPI_Controller
$this->terminateWithSuccess(hasData($notiz) ? getData($notiz)[0] : array());
}
public function getTags()
public function getTags($tags = null)
{
$this->NotiztypModel->addSelect(
'typ_kurzbz as tag_typ_kurzbz,
@@ -73,19 +96,36 @@ class Tag_Controller extends FHCAPI_Controller
'
);
$this->NotiztypModel->addOrder('prioritaet');
if (is_array($tags) && !isEmptyArray($tags))
{
$tags = $this->_filterTag($tags, false);
$this->NotiztypModel->db->where_in('typ_kurzbz', $tags);
}
$notiztypen = $this->NotiztypModel->loadWhere(array('aktiv' => true));
$this->terminateWithSuccess(hasData($notiztypen) ? getData($notiztypen) : array());
}
public function addTag($withZuordnung = true)
public function addTag($withZuordnung = true, $updatable_tags = null)
{
$postData = $this->getPostJson();
$checkTyp = $this->NotiztypModel->loadWhere(array('typ_kurzbz' => $postData->tag_typ_kurzbz));
if (!hasData($checkTyp))
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
if (isError($checkTyp))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (!hasData($checkTyp))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (is_array($updatable_tags) && !isEmptyArray($updatable_tags))
{
$tags = $this->_filterTag($updatable_tags, false);
if (!in_array($postData->tag_typ_kurzbz, $tags))
$this->terminateWithError($this->p->t('ui', 'keineBerechtigung'));
}
if ($withZuordnung)
{
@@ -125,48 +165,88 @@ class Tag_Controller extends FHCAPI_Controller
}
}
private function addNotiz($postData)
{
return $this->NotizModel->insert(array(
'titel' => 'TAG', //TODO klären
'text' => $postData->notiz,
'verfasser_uid' => $this->_uid,
'erledigt' => false,
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => $this->_uid,
'typ' => $postData->tag_typ_kurzbz
));
}
public function updateTag()
public function updateTag($updatable_tags = null)
{
$postData = $this->getPostJson();
$post_tag = $this->NotizModel->loadWhere(array('notiz_id' => $postData->id));
if (isError($post_tag))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (!hasData($post_tag))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (is_array($updatable_tags) && !isEmptyArray($updatable_tags))
{
$tags = $this->_filterTag($updatable_tags, false);
$post_tag_typ = getData($post_tag)[0]->typ;
if (!in_array($post_tag_typ, $tags))
$this->terminateWithError($this->p->t('ui', 'keineBerechtigung'));
}
$updateData = $this->NotizModel->update(array('notiz_id' => $postData->id),
array('text' => $postData->notiz,
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => $this->_uid,
'bearbeiter_uid' => $this->_uid,
)
)
);
$this->terminateWithSuccess($updateData);
}
public function doneTag()
public function doneTag($updatable_tags = null)
{
$postData = $this->getPostJson();
$post_tag = $this->NotizModel->loadWhere(array('notiz_id' => $postData->id));
if (isError($post_tag))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (!hasData($post_tag))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (is_array($updatable_tags) && !isEmptyArray($updatable_tags))
{
$tags = $this->_filterTag($updatable_tags, false);
$post_tag_typ = getData($post_tag)[0]->typ;
if (!in_array($post_tag_typ, $tags))
$this->terminateWithError($this->p->t('ui', 'keineBerechtigung'));
}
$updateData = $this->NotizModel->update(array('notiz_id' => $postData->id),
array('erledigt' => !$postData->done,
'text' => $postData->notiz,
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => $this->_uid,
'bearbeiter_uid' => $this->_uid,
)
);
$this->terminateWithSuccess($updateData);
}
public function deleteTag($withZuordnung = true)
public function deleteTag($withZuordnung = true, $updatable_tags = null)
{
$postData = $this->getPostJson();
$post_tag = $this->NotizModel->loadWhere(array('notiz_id' => $postData->id));
if (isError($post_tag))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (!hasData($post_tag))
$this->terminateWithError($this->p->t('ui', 'fehlerBeimLesen'));
if (is_array($updatable_tags) && !isEmptyArray($updatable_tags))
{
$tags = $this->_filterTag($updatable_tags, false);
$post_tag_typ = getData($post_tag)[0]->typ;
if (!in_array($post_tag_typ, $tags))
$this->terminateWithError($this->p->t('ui', 'keineBerechtigung'));
}
$deleteNotiz = "";
if ($withZuordnung)
@@ -208,5 +288,27 @@ class Tag_Controller extends FHCAPI_Controller
return hasData($result) ? getData($result)[0]->index : 1;
}
private function _filterTag($tags, $readonly = true)
{
$filtered_tags = array_filter($tags, function ($tag) use ($readonly)
{
return isset($tag['readonly']) && $tag['readonly'] === $readonly;
});
return array_keys($filtered_tags);
}
private function addNotiz($postData)
{
return $this->NotizModel->insert(array(
'titel' => 'TAG', //TODO klären
'text' => $postData->notiz,
'verfasser_uid' => $this->_uid,
'erledigt' => false,
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => $this->_uid,
'typ' => $postData->tag_typ_kurzbz
));
}
}
+342
View File
@@ -0,0 +1,342 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class LektorLib
{
private $_ci; // Code igniter instance
public function __construct()
{
$this->_ci =& get_instance();
$this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$this->_ci->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$this->_ci->load->model('ressource/Stundensatz_model', 'StundensatzModel');
$this->_ci->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel');
$this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->_ci->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
}
public function addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid)
{
$this->_ci->LehreinheitModel->addSelect('tbl_lehreinheit.*, tbl_lehrveranstaltung.studiengang_kz, semesterstunden');
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$lehreinheit_result = $this->_ci->LehreinheitModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($lehreinheit_result)) return $lehreinheit_result;
if (!hasData($lehreinheit_result)) return error("Lehreinheit not found");
$lehreinheit = getData($lehreinheit_result)[0];
$already_assigned = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit->lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (isError($already_assigned)) return $already_assigned;
if (hasData($already_assigned)) return error('Lektor already assigned');
$studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz));
if (isError($studiensemester_result)) return $studiensemester_result;
$studiensemester = getData($studiensemester_result)[0];
$stundensatz = $this->_ci->StundensatzModel->getDefaultStundensatz($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre');
$echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'echterdv');
$echter_dv = false;
if (hasData($echter_dv_result))
{
$echter_dv = true;
}
$maxstunden = $this->getMaxStunden($mitarbeiter_uid, $studiensemester->studiensemester_kurzbz, $lehreinheit->studiengang_kz, $echter_dv);
$newData['semesterstunden'] = 0;
$newData['planstunden'] = 0;
if (!is_null($lehreinheit->semesterstunden))
{
$newData['semesterstunden'] = min($lehreinheit->semesterstunden, $maxstunden);
$newData['planstunden'] = min($lehreinheit->semesterstunden, $maxstunden);
}
$newData['lehreinheit_id'] = $lehreinheit->lehreinheit_id;
$newData['mitarbeiter_uid'] = $mitarbeiter_uid;
$newData['lehrfunktion_kurzbz'] = 'Lektor';
$newData['bismelden'] = true;
$newData['insertvon'] = getAuthUID();
$newData['insertamum'] = date('Y-m-d H:i:s');
$newData['stundensatz'] = $stundensatz;
$result = $this->_ci->LehreinheitmitarbeiterModel->insert($newData);
if (isError($result)) return $result;
return success("Lektor added successfully");
}
public function updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $new_data)
{
$this->_ci->LehreinheitmitarbeiterModel->addSelect('lehre.tbl_lehreinheitmitarbeiter.*, lehre.tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$lehreinheit_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (isError($lehreinheit_result)) return $lehreinheit_result;
if (!hasData($lehreinheit_result)) return error("Lehreinheit not found");
$lehreinheit = getData($lehreinheit_result)[0];
//TODO kollision check, wird vorerst nicht implementiert -> nur über das FAS möglich
if (isset($new_data['mitarbeiter_uid']) && $new_data['mitarbeiter_uid'] !== $mitarbeiter_uid)
{
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->_ci->StundenplandevModel->addGroupBy('stundenplandev_id');
$this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid');
$this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid');
$verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (hasData($verplant))
return error('Wechsel vom Mitarbeiter nicht möglich da er bereits verplant ist!');
}
$warning = '';
if (isset($new_data['semesterstunden']))
{
$studiengang_result = $this->_ci->StudiengangModel->loadWhere(array('studiengang_kz' => $lehreinheit->studiengang_kz));
if (isError($studiengang_result)) return $studiengang_result;
if (!hasData($studiengang_result)) return error('Studiengang not found');
$studiengang = getData($studiengang_result)[0];
$studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz));
if (isError($studiensemester_result)) return $studiensemester_result;
$studiensemester = getData($studiensemester_result)[0];
$echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'echterdv');
$echter_dv = false;
if (hasData($echter_dv_result))
{
$echter_dv = true;
}
$neue_stunden_eingerechnet = isset($new_data['bismelden']) ? $new_data['bismelden'] : $lehreinheit->bismelden;
$alte_stunden_eingerechnet = $lehreinheit->bismelden;
if (($new_data['semesterstunden'] > $lehreinheit->semesterstunden) || $neue_stunden_eingerechnet)
{
$stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv);
if (isError($stundengrenze_result)) return $stundengrenze_result;
$stundengrenze = getData($stundengrenze_result)[0];
$oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz);
$oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array('');
if ($alte_stunden_eingerechnet && $neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden) + {$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])}) as summe");
else if ($alte_stunden_eingerechnet && !$neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden)) as summe");
else if (!$alte_stunden_eingerechnet && $neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) + ({$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])})) as summe");
else if (!$alte_stunden_eingerechnet && !$neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden)) as summe");
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', (isset($new_data['mitarbeiter_uid']) ? $new_data['mitarbeiter_uid'] : $mitarbeiter_uid));
$this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $lehreinheit->studiensemester_kurzbz);
$this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true);
$this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%');
$this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array);
if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE')
&& is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE)
&& count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0)
{
$this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE);
}
$summe_result = $this->_ci->LehreinheitmitarbeiterModel->load();
if (isError($summe_result)) return $summe_result;
if (!hasData($summe_result)) return error('Fehler beim Ermitteln der Gesamtstunden');
$summe = getData($summe_result)[0]->summe;
if ($summe > $stundengrenze->stunden)
{
if (!$echter_dv && (!$this->_ci->permissionlib->isBerechtigt('admin')))
{
if (!$this->LehrauftragAufFirma(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid))
return error("ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden NICHT gespeichert!\n\n");
}
else
{
$warning .= "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden gespeichert!\n\n";
}
$stunden_limit_result = $this->getStundenInstitut($mitarbeiter_uid, $lehreinheit->studiensemester_kurzbz, $oe_array);
if (hasData($stunden_limit_result))
{
$stunden_limit_array = getData($stunden_limit_result);
foreach ($stunden_limit_array as $stunden_limit)
{
$warning .= $stunden_limit->summe . ' Stunden ' . $stunden_limit->bezeichnung . "\n";
}
}
}
}
}
$benutzer_result = $this->_ci->BenutzerModel->load(array(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid));
if (isError($benutzer_result)) return $benutzer_result;
if (!hasData($benutzer_result)) return error('Benutzer not found');
$benutzer_aktiv = getData($benutzer_result)[0]->aktiv;
if (!$benutzer_aktiv)
$warning .= "Achtung: Der/Die Benutzer*in ist inaktiv!\nBitte informieren Sie die Personalbteilung.\nDaten wurden gespeichert.\n\n";
$updatableFields = array(
'semesterstunden',
'planstunden',
'stundensatz',
'faktor',
'anmerkung',
'lehrfunktion_kurzbz',
'mitarbeiter_uid',
'bismelden'
);
$updateData = array();
foreach ($updatableFields as $field)
{
$value = isset($new_data[$field]) ? $new_data[$field] : null;
if ($value !== null)
{
$updateData[$field] = $value;
}
}
$updateData['updatevon'] = getAuthUID();
$updateData['updateamum'] = date('Y-m-d H:i:s');
$result = $this->_ci->LehreinheitmitarbeiterModel->update(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid), $updateData);
if (isError($result)) return $result;
if ($warning !== '') return success(['warning' => $warning]);
return success('Erfolgreich geupdated');
}
private function getMaxStunden($mitarbeiter_uid, $studiensemester_kurzbz, $studiengang_kz, $echter_dv)
{
$maxstunden = 9999;
$studiengang_result = $this->_ci->StudiengangModel->loadWhere(array('studiengang_kz' => $studiengang_kz));
if (isError($studiengang_result)) return $studiengang_result;
$studiengang = getData($studiengang_result)[0];
$stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv);
if (isError($stundengrenze_result)) return $stundengrenze_result;
$stundengrenze = getData($stundengrenze_result)[0];
$maxstunden = $stundengrenze->stunden;
$lehrauftrag_firma = $this->LehrauftragAufFirma($mitarbeiter_uid);
if (!$echter_dv && !$lehrauftrag_firma)
{
$oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz);
$oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array('');
$stunden_summe_result = $this->getSumSemesterstunden($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array);
$stunden_summe = hasData($stunden_summe_result) ? getData($stunden_summe_result)[0]->summe : 0;
if ($stunden_summe >= $maxstunden && (!$this->_ci->permissionlib->isBerechtigt('admin')))
{
$stunden_limit_result = $this->getStundenInstitut($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array);
$error = "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $maxstunden Stunden ($stundengrenze->oe_kurzbz) wurde ueberschritten!\n
Daten wurden NICHT gespeichert!\n\n";
if (hasData($stunden_limit_result))
{
$stunden_limit_array = getData($stunden_limit_result);
foreach ($stunden_limit_array as $stunden_limit)
{
$error .= $stunden_limit->summe . ' Stunden ' . $stunden_limit->bezeichnung . "\n";
}
}
return error($error);
}
else
$maxstunden =- $stunden_summe;
}
return $maxstunden;
}
private function LehrauftragAufFirma($mitarbeiter_uid)
{
$this->_ci->MitarbeiterModel->addJoin('tbl_benutzer', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid');
$this->_ci->MitarbeiterModel->addJoin('tbl_person', 'person_id');
$this->_ci->MitarbeiterModel->addJoin('tbl_adresse', 'person_id', 'LEFT');
$this->_ci->MitarbeiterModel->addOrder('zustelladresse', 'DESC');
$this->_ci->MitarbeiterModel->addOrder('firma_id');
$this->_ci->MitarbeiterModel->addLimit(1);
$firma_result = $this->_ci->MitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid));
$firma = getData($firma_result)[0]->firma_id;
return !is_null($firma);
}
private function getSumSemesterstunden($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array = array())
{
$this->_ci->LehreinheitmitarbeiterModel->addSelect('SUM(tbl_lehreinheitmitarbeiter.semesterstunden) as summe');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', $mitarbeiter_uid);
$this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $studiensemester_kurzbz);
$this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true);
$this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%');
$this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array);
return $this->_ci->LehreinheitmitarbeiterModel->load();
}
private function getStundenInstitut($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array = array())
{
$this->_ci->LehreinheitmitarbeiterModel->addSelect('SUM(tbl_lehreinheitmitarbeiter.semesterstunden) as summe, tbl_studiengang.bezeichnung');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', $mitarbeiter_uid);
$this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $studiensemester_kurzbz);
$this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true);
$this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array);
if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE')
&& is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE)
&& count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0)
{
$this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE);
}
$this->_ci->LehreinheitmitarbeiterModel->addGroupBy('tbl_studiengang.bezeichnung');
return $this->_ci->LehreinheitmitarbeiterModel->load();
}
}
+22 -4
View File
@@ -214,7 +214,7 @@ class ProfilLib{
* @param integer $uid the userID used to get the kontakt information
* @return array all the kontakt information corresponding to a userID
*/
private function getKontaktInfo($pid)
private function getKontaktInfo($pid, $includehidden=false)
{
$this->ci->load->model("person/Kontakt_model","KontaktModel");
$this->ci->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']);
@@ -222,7 +222,13 @@ class ProfilLib{
$this->ci->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT');
$this->ci->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum');
$kontakte_res = $this->ci->KontaktModel->loadWhere(['person_id' => $pid]);
$params = array('person_id' => $pid);
if(!$includehidden)
{
$params['kontakttyp <>'] = 'hidden';
}
$kontakte_res = $this->ci->KontaktModel->loadWhere($params);
if(isError($kontakte_res)){
return error(getData($kontakte_res));
}
@@ -303,10 +309,22 @@ class ProfilLib{
private function getBenutzerFunktion($uid)
{
$this->ci->load->model("person/Benutzerfunktion_model","BenutzerfunktionModel");
$this->ci->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]);
$this->ci->BenutzerfunktionModel->addSelect([
"CASE WHEN (tbl_benutzerfunktion.bezeichnung IS NOT NULL AND tbl_benutzerfunktion.bezeichnung <> '' AND tbl_benutzerfunktion.bezeichnung <> tbl_funktion.beschreibung) THEN tbl_funktion.beschreibung || ' - ' || tbl_benutzerfunktion.bezeichnung ELSE tbl_funktion.beschreibung END as \"Bezeichnung\"",
"tbl_organisationseinheit.bezeichnung as Organisationseinheit",
"datum_von as Gültig_von",
"datum_bis as Gültig_bis",
"COALESCE(wochenstunden, '0'::numeric(5,2)) AS \"Wochenstunden\""
]);
$this->ci->BenutzerfunktionModel->addJoin("tbl_funktion", "funktion_kurzbz");
$this->ci->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz");
$benutzer_funktion_res = $this->ci->BenutzerfunktionModel->loadWhere(array('uid' => $uid));
$benutzer_funktion_res = $this->ci->BenutzerfunktionModel->loadWhere(
array(
'uid' => $uid,
'NOW()::date BETWEEN COALESCE(datum_von, \'1970-01-01\'::date) AND COALESCE(datum_bis, \'2170-12-01\'::date)' => null
)
);
if(isError($benutzer_funktion_res)){
return error(getData($benutzer_funktion_res));
}
@@ -384,6 +384,60 @@ class Vertrag_model extends DB_Model
}
}
public function getVertrag($mitarbeiter_uid, $lehreinheit_id)
{
$this->addSelect('tbl_lehreinheitmitarbeiter.*, tbl_vertrag.*, status.bezeichnung as vertragsstatus, status.vertragsstatus_kurzbz');
$this->addJoin('lehre.tbl_lehreinheitmitarbeiter', 'vertrag_id');
$this->addJoin('lehre.tbl_vertragstyp', 'vertragstyp_kurzbz', 'LEFT');
$this->addJoin('
(
SELECT DISTINCT ON(vertrag_id) vertrag_id,
bezeichnung,
tbl_vertragsstatus.vertragsstatus_kurzbz
FROM lehre.tbl_vertrag_vertragsstatus
JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz)
ORDER BY vertrag_id, datum DESC
) as status', 'status.vertrag_id = lehre.tbl_vertrag.vertrag_id', 'LEFT');
return $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid, 'lehreinheit_id' => $lehreinheit_id));
}
public function cancelVertrag($vertrag_id, $mitarbeiter_uid)
{
$vertrag = $this->load($vertrag_id);
if (!hasData($vertrag))
return error("Contract not found");
$vertrag = getData($vertrag)[0];
$this->_updateVertragRelevant($vertrag->vertrag_id);
return $this->VertragvertragsstatusModel->insert(array(
'vertrag_id' => $vertrag->vertrag_id,
'vertragsstatus_kurzbz' => 'storno',
'uid' => $mitarbeiter_uid,
'datum' => 'NOW()',
'insertamum' => 'NOW()',
'insertvon' => getAuthUID()
));
}
public function deleteVertrag($vertrag_id)
{
$vertrag = $this->load($vertrag_id);
if (!hasData($vertrag))
return error("Contract not found");
$vertrag = getData($vertrag)[0];
$this->_updateVertragRelevant($vertrag->vertrag_id);
$this->VertragvertragsstatusModel->delete(array('vertrag_id' => $vertrag->vertrag_id));
return $this->delete(array('vertrag_id' => $vertrag->vertrag_id));
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
@@ -415,4 +469,20 @@ class Vertrag_model extends DB_Model
return $bezeichnung;
}
private function _updateVertragRelevant($vertrag_id)
{
$this->LehreinheitmitarbeiterModel->update(
array("vertrag_id" => $vertrag_id),
array(
'vertrag_id' => null
)
);
$this->ProjektbetreuerModel->update(
array("vertrag_id" => $vertrag_id),
array(
'vertrag_id' => null
)
);
}
}
@@ -1,4 +1,6 @@
<?php
use \CI3_Events as Events;
class Lehreinheit_model extends DB_Model
{
@@ -15,6 +17,9 @@ class Lehreinheit_model extends DB_Model
$this->load->model('education/lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->load->model('education/lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$this->load->model('organisation/studiengang_model', 'StudiengangModel');
$this->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->load->model('ressource/stundenplan_model', 'StundenplanModel');
$this->load->model('system/Log_model', 'LogModel');
}
/**
@@ -308,4 +313,424 @@ EOSQL;
return $this->execQuery($query, $params);
}
public function getOes($lehreinheit_id)
{
$this->addSelect('tbl_lehrveranstaltung.studiengang_kz,
tbl_lehrveranstaltung.lehrveranstaltung_id');
$this->addJoin('lehre.tbl_lehrveranstaltung', 'tbl_lehrveranstaltung.lehrveranstaltung_id = tbl_lehreinheit.lehrveranstaltung_id');
$result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($result)) return $result;
if (hasData($result))
{
$lehrveranstaltung = getData($result)[0];
$oe_result = $this->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id);
return success(hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(''));
}
}
public function getLehrfachOe($lehreinheit_id)
{
$this->addSelect('lehrfach.oe_kurzbz');
$this->addJoin('lehre.tbl_lehrveranstaltung lehrfach', 'lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id', 'LEFT');
return $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
}
public function getByLvidStudiensemester($lv_id, $studiensemester_kurzbz, $mitarbeiter_uid = null, $fachbereich_kurzbz = null)
{
$qry = "WITH lehreinheiten AS (
SELECT *
FROM lehre.tbl_lehreinheit
WHERE lehrveranstaltung_id = ?
AND studiensemester_kurzbz = ?
),
". $this->_getGruppenCTE() . ",
". $this->_getLektorenCTE() . ",
". $this->_getFachbereichCTE() . ",
". $this->_getTagsCTE() . "
SELECT lehreinheiten.*,
lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
COALESCE(tag_data_agg.tags, '[]'::json) AS tags,
gruppen.gruppen,
mitarbeiter.lektoren,
mitarbeiter.le_planstunden,
mitarbeiter.vorname,
mitarbeiter.nachname,
mitarbeiter.semesterstunden,
fachbereich.bezeichnung as fachbereich,
UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang,
semester
FROM lehreinheiten
LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id
LEFT JOIN mitarbeiter ON lehreinheiten.lehreinheit_id = mitarbeiter.lehreinheit_id
LEFT JOIN fachbereich ON lehreinheiten.lehreinheit_id = fachbereich.lehreinheit_id
LEFT JOIN gruppen ON lehreinheiten.lehreinheit_id = gruppen.lehreinheit_id
WHERE true
";
$params = array($lv_id, $studiensemester_kurzbz);
if ($mitarbeiter_uid !== null)
{
$qry .= " AND lehreinheiten.lehreinheit_id IN ( SELECT lehreinheit_id FROM lehre.tbl_lehreinheitmitarbeiter WHERE mitarbeiter_uid = ?) ";
$params[] = $mitarbeiter_uid;
}
if($fachbereich_kurzbz !== null)
{
$qry .= " AND EXISTS ( SELECT 1 FROM lehre.tbl_lehrveranstaltung JOIN public.tbl_fachbereich USING(oe_kurzbz) WHERE fachbereich_kurzbz= ? AND lehrveranstaltung_id=lehreinheiten.lehrfach_id)";
$params[] = $fachbereich_kurzbz;
}
$qry .= " ORDER BY lehrveranstaltung_id;";
return $this->execReadOnlyQuery($qry, $params);
}
private function getLVTmp($stg_kz = null)
{
$qry = "SELECT DISTINCT ON(lehrveranstaltung_id) *,
'' as stundenblockung,
'' as lehreinheit_id,
'' as wochenrythmus,
'' as raumtyp,
'' as raumtypalternativ,
'' as gruppen,
'' as studienplan_id,
'' as studienplan_beeichnung,
UPPER(CONCAT(vw_lehreinheit.stg_typ, vw_lehreinheit.stg_kurzbz)) as studiengang
FROM campus.vw_lehreinheit
WHERE mitarbeiter_uid = ?
AND studiensemester_kurzbz = ?";
if (!is_null($stg_kz)) {
$qry .= " AND lv_studiengang_kz = ?";
}
return $qry;
}
public function getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz = null)
{
$qry = "WITH lvs AS (" . $this->getLVTmp($stg_kz) . ")
SELECT lvs.*
FROM lvs
";
$params = array($mitarbeiter_uid, $studiensemester_kurzbz);
if (!is_null($stg_kz))
{
$params[] = $stg_kz;
}
return $this->execReadOnlyQuery($qry, $params);
}
public function deleteLehreinheit($lehreinheit_id)
{
$lehreinheit = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($lehreinheit)) return $lehreinheit;
if (!hasData($lehreinheit))
return error("Lehreinheit not found!");
$errorReasons = [];
$addError = function ($reason = null) use (&$errorReasons)
{
if ($reason !== null)
{
$errorReasons[] = $reason;
}
};
$stundenplandev_result = $this->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
$stundenplan_result = $this->StundenplanModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (hasData($stundenplan_result) || hasData($stundenplandev_result))
$addError('Dieser LV-Teil ist bereits im LV-Plan verplant und kann daher nicht geloescht werden!');
Events::trigger(
'lehreinheit_delete_check',
$addError,
$lehreinheit_id
);
if (!empty($errorReasons)) return error($errorReasons);
$this->db->trans_begin();
Events::trigger(
'lehreinheit_delete',
$addError,
$lehreinheit_id
);
$undosql = '';
$lehreinheit_gruppe_result = $this->LehreinheitgruppeModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (hasData($lehreinheit_gruppe_result))
{
foreach (getData($lehreinheit_gruppe_result) as $row)
{
$values = [
$this->db->escape($row->lehreinheitgruppe_id),
$this->db->escape($row->lehreinheit_id),
$this->db->escape($row->studiengang_kz),
$this->db->escape($row->semester),
$this->db->escape($row->verband),
$this->db->escape($row->gruppe),
$this->db->escape($row->gruppe_kurzbz),
$this->db->escape($row->updateamum),
$this->db->escape($row->updatevon),
$this->db->escape($row->insertamum),
$this->db->escape($row->insertvon)
];
$undosql .= "INSERT INTO lehre.tbl_lehreinheitgruppe (
lehreinheitgruppe_id,
lehreinheit_id,
studiengang_kz,
semester,
verband,
gruppe,
gruppe_kurzbz,
updateamum,
updatevon,
insertamum,
insertvon
) VALUES (" . implode(', ', $values) . ");\n";
}
$lehreinheit_gruppe_delete_result = $this->LehreinheitgruppeModel->delete(array('lehreinheit_id' => $lehreinheit_id));
if (isError($lehreinheit_gruppe_delete_result))
$addError(getError($lehreinheit_gruppe_delete_result));
}
$lehreinheit_mitarbeiter_result = $this->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (hasData($lehreinheit_mitarbeiter_result))
{
foreach (getData($lehreinheit_mitarbeiter_result) as $row)
{
$values = [
$this->db->escape($row->lehreinheit_id),
$this->db->escape($row->mitarbeiter_uid),
$this->db->escape($row->lehrfunktion_kurzbz),
$this->db->escape($row->planstunden),
$this->db->escape($row->stundensatz),
$this->db->escape($row->faktor),
$this->db->escape($row->anmerkung),
$this->db->escape($row->bismelden),
$this->db->escape($row->updateamum),
$this->db->escape($row->updatevon),
$this->db->escape($row->insertamum),
$this->db->escape($row->insertvon),
$this->db->escape($row->semesterstunden)
];
$undosql .= "INSERT INTO lehre.tbl_lehreinheitmitarbeiter (
lehreinheit_id,
mitarbeiter_uid,
lehrfunktion_kurzbz,
planstunden,
stundensatz,
faktor,
anmerkung,
bismelden,
updateamum,
updatevon,
insertamum,
insertvon,
semesterstunden
) VALUES (" . implode(', ', $values) . ");\n";
}
$lehreinheit_mitarbeiter_delete_result = $this->LehreinheitmitarbeiterModel->delete(array('lehreinheit_id' => $lehreinheit_id));
if (isError($lehreinheit_mitarbeiter_delete_result))
$addError(getError($lehreinheit_mitarbeiter_delete_result));
}
foreach (getData($lehreinheit) as $row)
{
$values = [
$this->db->escape($row->lehreinheit_id),
$this->db->escape($row->lehrveranstaltung_id),
$this->db->escape($row->studiensemester_kurzbz),
$this->db->escape($row->lehrfach_id),
$this->db->escape($row->lehrform_kurzbz),
$this->db->escape($row->stundenblockung),
$this->db->escape($row->wochenrythmus),
$this->db->escape($row->start_kw),
$this->db->escape($row->raumtyp),
$this->db->escape($row->raumtypalternativ),
$this->db->escape($row->sprache),
$this->db->escape($row->lehre),
$this->db->escape($row->anmerkung),
$this->db->escape($row->unr),
$this->db->escape($row->lvnr),
$this->db->escape($row->updateamum),
$this->db->escape($row->updatevon),
$this->db->escape($row->insertamum),
$this->db->escape($row->insertvon),
];
$undosql .= "INSERT INTO lehre.tbl_lehreinheit (
lehreinheit_id,
lehrveranstaltung_id,
studiensemester_kurzbz,
lehrfach_id,
lehrform_kurzbz,
stundenblockung,
wochenrythmus,
start_kw,
raumtyp,
raumtypalternativ,
sprache,
lehre,
anmerkung,
unr,
lvnr,
updateamum,
updatevon,
insertamum,
insertvon
) VALUES (" . implode(', ', $values) . ");\n";
}
$lehreinheit_result = $this->delete($lehreinheit_id);
$deleteSql = "DELETE FROM lehre.tbl_lehreinheitmitarbeiter WHERE lehreinheit_id = " . $this->db->escape($lehreinheit_id) ."; \n
DELETE FROM lehre.tbl_lehreinheitgruppe WHERE lehreinheit_id = " . $this->db->escape($lehreinheit_id) ."; \n
DELETE FROM lehre.tbl_lehreinheit WHERE lehreinheit_id = " . $this->db->escape($lehreinheit_id) .";";
if (isError($lehreinheit_result))
$addError($lehreinheit_result);
$log_result = $this->LogModel->insert([
'sql' => $deleteSql,
'sqlundo' => $undosql,
'beschreibung' => 'Lehreinheit loeschen - ' . $lehreinheit_id,
'mitarbeiter_uid' => getAuthUID(),
]);
if (isError($log_result))
$addError($log_result);
if (!empty($errorReasons))
{
$this->db->trans_rollback();
return error($errorReasons);
}
$this->db->trans_commit();
return success('Contract successfully updated.');
}
private function _getGruppenCTE()
{
return "gruppen AS (
SELECT
lehreinheit_id,
STRING_AGG(
CASE
WHEN (tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL OR tbl_lehreinheitgruppe.gruppe_kurzbz = '')
THEN
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) ||
COALESCE(TRIM(tbl_lehreinheitgruppe.semester::text), '') ||
COALESCE(TRIM(tbl_lehreinheitgruppe.verband), '') ||
COALESCE(TRIM(tbl_lehreinheitgruppe.gruppe), '')
ELSE
CASE
WHEN NOT tbl_gruppe.direktinskription THEN tbl_lehreinheitgruppe.gruppe_kurzbz
ELSE NULL
END
END,
' '
) AS gruppen
FROM lehre.tbl_lehreinheitgruppe
LEFT JOIN public.tbl_studiengang USING (studiengang_kz)
LEFT JOIN public.tbl_gruppe USING (gruppe_kurzbz)
JOIN lehreinheiten USING(lehreinheit_id)
GROUP BY lehreinheit_id
)";
}
private function _getLektorenCTE()
{
return "mitarbeiter AS (
SELECT
tbl_lehreinheitmitarbeiter.lehreinheit_id,
STRING_AGG(m.kurzbz, ' ') AS lektoren,
STRING_AGG(tbl_person.vorname, ' ') AS vorname,
STRING_AGG(tbl_person.nachname, ' ') AS nachname,
STRING_AGG(tbl_lehreinheitmitarbeiter.semesterstunden::text, ' ') AS semesterstunden,
STRING_AGG(tbl_lehreinheitmitarbeiter.planstunden::text, ' ') AS le_planstunden
FROM lehre.tbl_lehreinheitmitarbeiter
JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid)
JOIN lehreinheiten USING(lehreinheit_id)
JOIN public.tbl_benutzer ON mitarbeiter_uid = uid
JOIN public.tbl_person ON tbl_benutzer.person_id = tbl_person.person_id
GROUP BY tbl_lehreinheitmitarbeiter.lehreinheit_id
)";
}
private function _getFachbereichCTE()
{
return "fachbereich AS (
SELECT
CONCAT(tbl_organisationseinheit.bezeichnung, ' (', tbl_organisationseinheit.organisationseinheittyp_kurzbz, ')') as bezeichnung,
lehreinheiten.lehreinheit_id
FROM public.tbl_organisationseinheit
JOIN lehre.tbl_lehrveranstaltung AS lehrfach ON tbl_organisationseinheit.oe_kurzbz = lehrfach.oe_kurzbz
JOIN lehre.tbl_lehreinheit ON lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id
JOIN lehreinheiten ON tbl_lehreinheit.lehreinheit_id = lehreinheiten.lehreinheit_id
)";
}
private function _getTagsCTE()
{
$this->load->config('lvverwaltung');
$tags = $this->config->item('tags');
$whereTags = '';
if (is_array($tags) && !isEmptyArray($tags))
{
$tags = array_keys($tags);
foreach ($tags as $key => $tag)
{
$tags[$key] = $this->db->escape($tag);
}
$whereTags = " AND tbl_notiz_typ.typ_kurzbz IN (" . implode(",", $tags) . ")";
}
return "tag_data_agg AS (
SELECT
lehreinheit_id,
COALESCE(json_agg(tag ORDER BY done), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (public.tbl_notiz.notiz_id)
tbl_notiz.notiz_id AS id,
typ_kurzbz,
array_to_json(tbl_notiz_typ.bezeichnung_mehrsprachig)->>0 AS beschreibung,
text AS notiz,
style,
erledigt AS done,
lehreinheit_id
FROM public.tbl_notizzuordnung
JOIN public.tbl_notiz ON tbl_notizzuordnung.notiz_id = tbl_notiz.notiz_id
JOIN public.tbl_notiz_typ ON tbl_notiz.typ = tbl_notiz_typ.typ_kurzbz
WHERE lehreinheit_id IN (SELECT lehreinheit_id FROM lehreinheiten)"
. $whereTags.
") AS tag
GROUP BY lehreinheit_id
)";
}
}
@@ -14,6 +14,7 @@ class Lehreinheitgruppe_model extends DB_Model
$this->load->model('organisation/studiengang_model', 'StudiengangModel');
$this->load->model('organisation/gruppe_model', 'GruppeModel');
$this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
}
/**
@@ -23,7 +24,15 @@ class Lehreinheitgruppe_model extends DB_Model
*/
public function getDirectGroup($lehreinheit_id)
{
$this->addSelect('tbl_lehreinheitgruppe.*');
$this->addSelect('tbl_gruppe.*');
$this->addSelect('uid');
$this->addSelect('vorname');
$this->addSelect('nachname');
$this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz');
$this->addJoin('public.tbl_benutzergruppe', 'gruppe_kurzbz', 'LEFT');
$this->addJoin('public.tbl_benutzer', 'uid', 'LEFT');
$this->addJoin('public.tbl_person', 'person_id', 'LEFT');
return $this->loadWhere(
array(
'tbl_gruppe.direktinskription' => true,
@@ -264,4 +273,209 @@ class Lehreinheitgruppe_model extends DB_Model
}
return $result;
}
public function addGroup($lehreinheit_id, $gid, $verband)
{
$lehreinheit = $this->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit))
return error ('No Lehreinheit found!');
if ($verband === false)
{
$gruppen_result = $this->GruppeModel->loadWhere(array('gid' => $gid));
if (!hasData($gruppen_result))
return error('No group found for gid ' . $gid);
$gruppen_array = getData($gruppen_result)[0];
if (!isEmptyString($gruppen_array->gruppe_kurzbz))
{
$this->db->where('trim(gruppe_kurzbz)', $gruppen_array->gruppe_kurzbz);
}
else
{
$this->db->group_start();
$this->db->where("trim(gruppe_kurzbz) = ''");
$this->db->or_where("gruppe_kurzbz IS NULL");
$this->db->group_end();
}
}
else if ($verband === true)
{
$gruppen_result = $this->LehrverbandModel->loadWhere(array('gid' => $gid));
if (!hasData($gruppen_result))
return error('No group found for gid ' . $gid);
$gruppen_array = getData($gruppen_result)[0];
if (!isEmptyString($gruppen_array->verband))
{
$this->db->where('verband', $gruppen_array->verband);
}
else
{
$this->db->group_start();
$this->db->where("trim(verband) = ''");
$this->db->or_where("verband IS NULL");
$this->db->group_end();
}
if (!isEmptyString($gruppen_array->gruppe))
{
$this->db->where('gruppe', $gruppen_array->gruppe);
}
else
{
$this->db->group_start();
$this->db->where("trim(gruppe) = ''");
$this->db->or_where("gruppe IS NULL");
$this->db->group_end();
}
}
else
return error('Wrong type of verband');
$this->db->where('lehreinheit_id', $lehreinheit_id);
$this->db->where('studiengang_kz', $gruppen_array->studiengang_kz);
if (!isEmptyString($gruppen_array->semester))
{
$this->db->where('semester', $gruppen_array->semester);
}
else
{
$this->db->group_start();
$this->db->where("semester = ''");
$this->db->or_where("semester IS NULL");
$this->db->group_end();
}
$exist_result = $this->load();
if (!hasData($exist_result))
{
$new_group_result = $this->insert(array(
'lehreinheit_id' => $lehreinheit_id,
'studiengang_kz' => $gruppen_array->studiengang_kz,
'gruppe_kurzbz' => isset($gruppen_array->gruppe_kurzbz) ? $gruppen_array->gruppe_kurzbz : null,
'semester' => $gruppen_array->semester,
'verband' => isset($gruppen_array->verband) && !isEmptyString($gruppen_array->verband) ? $gruppen_array->verband : null,
'gruppe' => isset($gruppen_array->gruppe) && !isEmptyString($gruppen_array->gruppe) ? $gruppen_array->gruppe : null,
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => getAuthUID()
));
if (isError($new_group_result))
return error('Error when adding Group');
return success('Group assigned successfully to Lehreinheit');
}
else
return error('Group already assigned');
}
public function deleteGroup($lehreinheit_id, $lehreinheitgruppe_id)
{
$lehreinheit = $this->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit))
return error ('No Lehreinheit found!');
$lehreinheitgruppe = $this->load($lehreinheitgruppe_id);
if (!hasData($lehreinheitgruppe))
return error ('No Lehreinheitgruppe found!');
$this->addSelect('stundenplandev_id');
$this->addJoin('lehre.tbl_stundenplandev',
"tbl_stundenplandev.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND tbl_stundenplandev.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND tbl_stundenplandev.semester = tbl_lehreinheitgruppe.semester
AND trim(COALESCE(tbl_stundenplandev.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, ''))
AND trim(COALESCE(tbl_stundenplandev.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, ''))
AND trim(COALESCE(tbl_stundenplandev.gruppe_kurzbz, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, ''))"
);
$stundenplan_result = $this->loadWhere(array('tbl_lehreinheitgruppe.lehreinheitgruppe_id' => $lehreinheitgruppe_id));
if (hasData($stundenplan_result))
return error('Gruppe already verplant');
$delete_result = $this->delete($lehreinheitgruppe_id);
if (isError($delete_result))
return error('Error deleting Group');
return success('Group deleted');
}
public function getByLehreinheit($lehreinheit_id)
{
$lehreinheit = $this->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit))
return error ('No Lehreinheit found!');
$this->addSelect('tbl_lehreinheitgruppe.*');
$this->addSelect('tbl_gruppe.direktinskription');
$this->addSelect('tbl_gruppe.gruppe_kurzbz');
$this->addSelect("CASE
WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN
COALESCE (
UPPER(tbl_studiengang.typ || tbl_studiengang.kurzbz) ||
COALESCE(tbl_lehreinheitgruppe.semester::varchar, '') ||
COALESCE(tbl_lehreinheitgruppe.verband::varchar, '') ||
COALESCE(tbl_lehreinheitgruppe.gruppe, ''),
'')
ELSE tbl_lehreinheitgruppe.gruppe_kurzbz
END AS bezeichnung");
$this->addSelect("CASE
WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN
(
SELECT bezeichnung
FROM public.tbl_lehrverband
WHERE studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND semester = tbl_lehreinheitgruppe.semester
AND verband = tbl_lehreinheitgruppe.verband
AND gruppe = tbl_lehreinheitgruppe.gruppe
LIMIT 1
)
ELSE tbl_gruppe.beschreibung
END AS beschreibung");
$this->addSelect("CASE
WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN
(
SELECT EXISTS (
SELECT 1
FROM lehre.tbl_stundenplandev
WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND semester = tbl_lehreinheitgruppe.semester
AND TRIM(COALESCE(verband, '')) = TRIM(tbl_lehreinheitgruppe.verband)
AND TRIM(COALESCE(gruppe, '')) = TRIM(tbl_lehreinheitgruppe.gruppe)
AND (gruppe_kurzbz IS NULL OR gruppe_kurzbz = '')
)
)
ELSE
(
SELECT EXISTS (
SELECT 1
FROM lehre.tbl_stundenplandev
WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND gruppe_kurzbz = tbl_lehreinheitgruppe.gruppe_kurzbz
)
)
END AS verplant");
$this->addJoin('tbl_studiengang', 'studiengang_kz', 'LEFT');
$this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz', 'LEFT');
$this->db->where('lehreinheit_id', $lehreinheit_id);
$this->db->group_start()
->where('tbl_gruppe.direktinskription !=', true)
->or_where('tbl_gruppe.direktinskription IS NULL')
->group_end();
return $this->load();
}
}
@@ -10,6 +10,14 @@ class Lehreinheitmitarbeiter_model extends DB_Model
parent::__construct();
$this->dbTable = 'lehre.tbl_lehreinheitmitarbeiter';
$this->pk = array('mitarbeiter_uid', 'lehreinheit_id');
$this->hasSequence = false;
$this->load->model('accounting/Vertrag_model', 'VertragModel');
$this->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->load->model('ressource/stundenplan_model', 'StundenplanModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
}
/**
@@ -75,4 +83,67 @@ class Lehreinheitmitarbeiter_model extends DB_Model
]);
}
public function getLektorenByLe($lehreinheit_id)
{
$this->addSelect('vorname, nachname, tbl_lehreinheitmitarbeiter.*, stundenplan.verplant');
$this->addJoin('tbl_benutzer', 'uid = mitarbeiter_uid');
$this->addJoin('tbl_person', 'person_id');
$this->addJoin('(
SELECT 1 as verplant, lehreinheit_id, mitarbeiter_uid
FROM lehre.tbl_stundenplandev
GROUP BY lehreinheit_id, mitarbeiter_uid
) stundenplan', 'stundenplan.mitarbeiter_uid = tbl_lehreinheitmitarbeiter.mitarbeiter_uid AND stundenplan.lehreinheit_id = tbl_lehreinheitmitarbeiter.lehreinheit_id', 'LEFT');
return $this->loadWhere(array('tbl_lehreinheitmitarbeiter.lehreinheit_id' => $lehreinheit_id));
}
public function getByLeLektor($lehreinheit_id, $mitarbeiter_uid)
{
$this->addSelect('vorname, nachname, tbl_lehreinheitmitarbeiter.*');
$this->addJoin('tbl_benutzer', 'uid = mitarbeiter_uid');
$this->addJoin('tbl_person', 'person_id');
return $this->loadWhere(array('tbl_lehreinheitmitarbeiter.lehreinheit_id' => $lehreinheit_id, 'tbl_lehreinheitmitarbeiter.mitarbeiter_uid' => $mitarbeiter_uid));
}
public function deleteLektorFromLe($lehreinheit_id, $mitarbeiter_uid)
{
if (defined('FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN') && FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN)
{
$vertrag_result = $this->VertragModel->getVertrag($mitarbeiter_uid, $lehreinheit_id);
if (hasData($vertrag_result))
return error("Loeschen nur nach Stornierung des Vertrags möglich");
}
$stundenplandev_result = $this->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
$stundenplan_result = $this->StundenplanModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (hasData($stundenplandev_result) || hasData($stundenplan_result))
return error("Diese/r LektorIn kann nicht gelöscht werden da er schon verplant ist");
$result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (hasData($result))
{
$le_mitarbeiter_array = getData($result)[0];
if ($le_mitarbeiter_array->vertrag_id !== null)
{
$vertrag_result = $this->VertragModel->deleteVertrag($le_mitarbeiter_array->vertrag_id);
if (isError($vertrag_result))
return $vertrag_result;
}
$delete_result = $this->delete(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (isError($delete_result))
return $delete_result;
return success($delete_result);
}
}
}
@@ -1019,4 +1019,240 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, $params);
}
public function getLvsByOrganization($oe_kurzbz)
{
$qry="
SELECT
distinct on (lehrveranstaltung_id)
tbl_lehrveranstaltung.studiengang_kz as lv_studiengang_kz, tbl_lehrveranstaltung.semester as lv_semester,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, tbl_lehrveranstaltung.ects as lv_ects,
tbl_lehrveranstaltung.lehreverzeichnis as lv_lehreverzeichnis, tbl_lehrveranstaltung.planfaktor as lv_planfaktor,
tbl_lehrveranstaltung.planlektoren as lv_planlektoren, tbl_lehrveranstaltung.planpersonalkosten as lv_planpersonalkosten,
tbl_lehrveranstaltung.plankostenprolektor as lv_plankostenprolektor, tbl_lehrveranstaltung.orgform_kurzbz as lv_orgform_kurzbz,
tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_lehrveranstaltung.lehrform_kurzbz as lehrform_kurzbz,
tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english,
tbl_lehrveranstaltung.studiengang_kz, tbl_lehrveranstaltung.semester, tbl_lehrveranstaltung.anmerkung, tbl_lehrveranstaltung.sprache, tbl_lehrveranstaltung.semesterstunden,
tbl_lehrveranstaltung.lehre, tbl_lehrveranstaltung.aktiv,
'' as studienplan_id, '' as studienplan_bezeichnung, tbl_lehrveranstaltung.lehrtyp_kurzbz
FROM
lehre.tbl_lehrveranstaltung
WHERE
tbl_lehrveranstaltung.oe_kurzbz= ?
AND tbl_lehrveranstaltung.aktiv
";
return $this->execReadOnlyQuery($qry, array($oe_kurzbz));
}
public function getLvsByFachbereich($fachbereich, $studiensemester_kurbz, $mitarbeiter_uid = null)
{
$qry = "";
if (!is_null($mitarbeiter_uid))
{
$qry = $this->getLvsFromStudienplanByEmp();
$params = array($fachbereich, $studiensemester_kurbz);
}
$qry .= "SELECT
distinct on(lehrveranstaltung_id)
lv_studiengang_kz, lv_semester, lv_kurzbz, lv_bezeichnung, lv_ects,
lv_lehreverzeichnis, lv_planfaktor, lv_planlektoren, lv_planpersonalkosten,
lv_plankostenprolektor, lv_orgform_kurzbz, lehrveranstaltung_id,
lehrform_kurzbz, lv_lehrform_kurzbz, lv_bezeichnung_english, studiengang_kz, semester, anmerkung, sprache, semesterstunden,
lehre, aktiv,
'' as studienplan_id, '' as studienplan_bezeichnung,
(SELECT lehrtyp_kurzbz FROM lehre.tbl_lehrveranstaltung WHERE lehrveranstaltung_id=vw_lehreinheit.lehrveranstaltung_id) as lehrtyp_kurzbz
FROM
campus.vw_lehreinheit
WHERE studiensemester_kurzbz = ?
AND fachbereich_kurzbz = ?";
$params[] = array($studiensemester_kurbz, $fachbereich);
if (!is_null($mitarbeiter_uid))
{
$qry .= " AND mitarbeiter_uid = ?";
$params[] = $mitarbeiter_uid;
}
else
{
$qry.=" AND lehrveranstaltung_id NOT IN (SELECT lehrveranstaltung_id
FROM
lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN lehre.tbl_studienplan USING(studienplan_id)
JOIN lehre.tbl_studienordnung USING(studienordnung_id)
JOIN lehre.tbl_studienplan_semester USING(studienplan_id)
WHERE
tbl_lehrveranstaltung.oe_kurzbz=(Select oe_kurzbz from public.tbl_fachbereich where fachbereich_kurzbz= ?)
AND tbl_studienplan_semester.studiensemester_kurzbz= ?";
$params[] = array($fachbereich, $studiensemester_kurbz);
}
return $this->execReadOnlyQuery($qry, $params);
}
private function getLvsFromStudienplanByEmp()
{
return "
SELECT
distinct on (lehrveranstaltung_id)
tbl_lehrveranstaltung.studiengang_kz as lv_studiengang_kz,
tbl_lehrveranstaltung.semester as lv_semester,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
tbl_lehrveranstaltung.ects as lv_ects,
tbl_lehrveranstaltung.lehreverzeichnis as lv_lehreverzeichnis,
tbl_lehrveranstaltung.planfaktor as lv_planfaktor,
tbl_lehrveranstaltung.planlektoren as lv_planlektoren,
tbl_lehrveranstaltung.planpersonalkosten as lv_planpersonalkosten,
tbl_lehrveranstaltung.plankostenprolektor as lv_plankostenprolektor,
tbl_lehrveranstaltung.orgform_kurzbz as lv_orgform_kurzbz,
tbl_lehrveranstaltung.lehrveranstaltung_id,
tbl_lehrveranstaltung.lehrform_kurzbz as lehrform_kurzbz,
tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english,
tbl_lehrveranstaltung.studiengang_kz,
tbl_studienplan_lehrveranstaltung.semester,
tbl_lehrveranstaltung.anmerkung,
tbl_lehrveranstaltung.sprache,
tbl_lehrveranstaltung.semesterstunden,
tbl_lehrveranstaltung.lehre,
tbl_lehrveranstaltung.aktiv,
tbl_studienplan.studienplan_id::text,
tbl_studienplan.bezeichnung as studienplan_bezeichnung,
tbl_lehrveranstaltung.lehrtyp_kurzbz
FROM
lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN lehre.tbl_studienplan USING(studienplan_id)
JOIN lehre.tbl_studienordnung USING(studienordnung_id)
JOIN lehre.tbl_studienplan_semester USING(studienplan_id)
WHERE
tbl_lehrveranstaltung.oe_kurzbz=(Select oe_kurzbz from public.tbl_fachbereich where fachbereich_kurzbz= ?)
AND tbl_studienplan_semester.studiensemester_kurzbz = ?
AND tbl_lehrveranstaltung.aktiv
UNION
";
}
public function getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester = null, $verband = null)
{
$qry = "";
$params = array();
if (!empty($studienplan_ids))
{
$qry = $this->getLvsFromStudienplanByStudienplanID($placeholders);
$params = $studienplan_ids;
}
$qry .= "
SELECT DISTINCT on(lehrveranstaltung_id) lehrveranstaltung_id,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english,
studiengang_kz,
semester,
tbl_lehrveranstaltung.sprache,
ects as lv_ects,
semesterstunden,
tbl_lehrveranstaltung.anmerkung,
tbl_lehrveranstaltung.lehre,
lehreverzeichnis as lv_lehreverzeichnis,
tbl_lehrveranstaltung.aktiv,
planfaktor as lv_planfaktor,
planlektoren as lv_planlektoren,
planpersonalkosten as lv_planpersonalkosten,
plankostenprolektor as lv_plankostenprolektor,
tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.orgform_kurzbz,
''::text as studienplan_id,
'' as studienplan_bezeichnung,
'' as studienplan_lehrveranstaltung_id_parent,
tbl_lehrveranstaltung.lehrtyp_kurzbz,
UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang
FROM lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_lehreinheit USING (lehrveranstaltung_id)
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE studiengang_kz = ?
AND studiensemester_kurzbz = ?
";
$params[] = $studiengang_kz;
$params[] = $studiensemester_kurzbz;
if (!is_null($semester))
{
$qry .= ' AND semester = ?';
$params[] = $semester;
}
if (!is_null($verband))
{
$qry .= ' AND (tbl_lehrveranstaltung.orgform_kurzbz = ? OR tbl_lehrveranstaltung.orgform_kurzbz IS NULL)';
$params[] = $verband;
}
if (!empty($only_ids))
{
$qry .= ' AND NOT EXISTS (SELECT 1 FROM lehre.tbl_studienplan_lehrveranstaltung where studienplan_id IN ?
AND lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id AND tbl_lehrveranstaltung.aktiv)';
$params[] = $only_ids;
}
return $this->execReadOnlyQuery($qry, $params);
}
private function getLvsFromStudienplanByStudienplanID($placeholders)
{
return "
SELECT
lehrveranstaltung_id, tbl_lehrveranstaltung.kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, bezeichnung_english as lv_bezeichnung_english, studiengang_kz,
tbl_studienplan_lehrveranstaltung.semester, tbl_lehrveranstaltung.sprache,
ects as lv_ects, semesterstunden, anmerkung, lehre, lehreverzeichnis as lv_lehreverzeichnis, tbl_lehrveranstaltung.aktiv,
planfaktor as lv_planfaktor, planlektoren as lv_planlektoren, planpersonalkosten as lv_planpersonalkosten,
plankostenprolektor as lv_plankostenprolektor, lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.orgform_kurzbz,
tbl_studienplan_lehrveranstaltung.studienplan_id::text as studienplan_id, tbl_studienplan.bezeichnung as studienplan_bezeichnung, tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent::text,
tbl_lehrveranstaltung.lehrtyp_kurzbz, UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang
FROM
lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN lehre.tbl_studienplan USING(studienplan_id)
JOIN tbl_studiengang USING(studiengang_kz)
WHERE
tbl_lehrveranstaltung.aktiv AND ((studienplan_id, tbl_studienplan_lehrveranstaltung.semester) IN ( " . implode(',', $placeholders) . "))
UNION
";
}
public function getAllOe($lv_id)
{
$qry = "SELECT DISTINCT oe_kurzbz
FROM lehre.tbl_studienplan_lehrveranstaltung
JOIN lehre.tbl_studienplan USING(studienplan_id)
JOIN lehre.tbl_studienordnung USING(studienordnung_id)
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE lehrveranstaltung_id = ?
UNION
(
SELECT oe_kurzbz
FROM public.tbl_studiengang
WHERE studiengang_kz = (
SELECT tbl_lehrveranstaltung.studiengang_kz
FROM lehre.tbl_lehrveranstaltung
WHERE lehrveranstaltung_id = ?
)
)
";
$params = array($lv_id, $lv_id);
return $this->execReadOnlyQuery($qry, $params);
}
}
@@ -213,4 +213,34 @@ class Organisationseinheit_model extends DB_Model
return $result;
}
/**
* Ermittelt die Stundenobergrenze fuer Lektoren
* Dabei wird im OE Baum nach oben nach Stundengrenzen gesucht und die niedrigste Stundengrenze ermittelt
* @param $oe_kurzbz Organisationseinheit
* @param $fixangestellt boolean legt fest ob die Grenze
* fuer Freie oder Fixangestellte Lektoren ermittelt werden soll
*/
public function getStundengrenze($oe_kurzbz, $fixangestellt = true)
{
$fixfrei = $fixangestellt ? 'fix' : 'frei';
$qry = "
WITH RECURSIVE oes(oe_kurzbz, oe_parent_kurzbz) as
(
SELECT oe_kurzbz, oe_parent_kurzbz FROM public.tbl_organisationseinheit
WHERE oe_kurzbz= ?
UNION ALL
SELECT o.oe_kurzbz, o.oe_parent_kurzbz FROM public.tbl_organisationseinheit o, oes
WHERE o.oe_kurzbz=oes.oe_parent_kurzbz
)
SELECT oe_kurzbz, warn_semesterstunden_{$fixfrei} AS stunden
FROM oes
JOIN public.tbl_organisationseinheit USING (oe_kurzbz)
ORDER BY warn_semesterstunden_{$fixfrei} ASC
LIMIT 1";
return $this->execReadOnlyQuery($qry, array($oe_kurzbz));
}
}
@@ -107,6 +107,8 @@ class Studienplan_model extends DB_Model
));
}
// Deprecated
// im Lehrveranstaltung_model vorhanden
public function getAllOesForLv($lehrveranstaltung_id)
{
$this->addDistinct('oe_kurzbz');
@@ -135,6 +137,27 @@ class Studienplan_model extends DB_Model
]);
}
public function loadStudienplanLehrveranstaltung($lv_id)
{
$qry = "SELECT studienplan_lehrveranstaltung_id,
semester,
pflicht,
studienplan_id,
koordinator,
studienplan_lehrveranstaltung_id_parent,
lehrveranstaltung_id,
insertamum,
insertvon,
updateamum,
updatevon,
sort,
curriculum,
export
FROM lehre.tbl_studienplan_lehrveranstaltung WHERE studienplan_lehrveranstaltung_id = ? ";
return $this->execReadOnlyQuery($qry, array($lv_id));
}
public function getStudienplaeneForPerson($person_id)
{
$this->addDistinct();
+7 -3
View File
@@ -151,7 +151,7 @@ class Notiz_model extends DB_Model
* bestellung_id, lehreinheit_id, anrechnung_id, uid)
* @param $id the corresponding id, part of public.tbl_notizzuordnung
*/
public function getNotizWithDocEntries($id, $type)
public function getNotizWithDocEntries($id, $type, $withoutTags = true)
{
$qry = "
SELECT
@@ -195,8 +195,12 @@ class Notiz_model extends DB_Model
LEFT JOIN
public.tbl_person person_bearbeiter ON (person_bearbeiter.person_id = p_bearbeiter.person_id)
WHERE
z.$type = ?
GROUP BY
z.$type = ?";
if ($withoutTags)
$qry .= " AND n.typ IS NULL ";
$qry .= "GROUP BY
notiz_id, z.notizzuordnung_id,
person_verfasser.vorname, person_verfasser.nachname,
person_bearbeiter.vorname, person_bearbeiter.nachname
+52 -64
View File
@@ -307,72 +307,60 @@ class Person_model extends DB_Model
public function checkDuplicate($person_id)
{
$qry = "SELECT person_id
FROM public.tbl_prestudent p
JOIN
(
SELECT DISTINCT ON(prestudent_id) *
FROM public.tbl_prestudentstatus
WHERE prestudent_id IN
(
SELECT prestudent_id
FROM public.tbl_prestudent
WHERE person_id IN
(
SELECT p2.person_id
FROM public.tbl_person p
JOIN public.tbl_person p2
ON lower(p.vorname) = lower(p2.vorname)
AND lower(p.nachname) = lower(p2.nachname)
AND p.gebdatum = p2.gebdatum
AND p.person_id = ?
)
)
ORDER BY prestudent_id, datum DESC, insertamum DESC
) ps USING(prestudent_id)
JOIN public.tbl_status USING(status_kurzbz)
$qry = "
WITH person AS (
SELECT *
FROM public.tbl_person
WHERE person_id = ?
),
allePersonen AS (
SELECT p.person_id
FROM public.tbl_person p
JOIN person
ON lower(p.vorname) = lower(person.vorname)
AND lower(p.nachname) = lower(person.nachname)
AND p.gebdatum = person.gebdatum
),
lastStatus AS (
SELECT DISTINCT ON (tbl_prestudentstatus.prestudent_id)
tbl_prestudentstatus.prestudent_id,
tbl_prestudentstatus.status_kurzbz,
tbl_prestudent.studiengang_kz,
tbl_prestudent.person_id
FROM public.tbl_prestudentstatus
JOIN public.tbl_prestudent USING (prestudent_id)
WHERE tbl_prestudent.person_id IN (SELECT person_id FROM allePersonen)
ORDER BY tbl_prestudentstatus.prestudent_id, tbl_prestudentstatus.datum DESC, tbl_prestudentstatus.insertamum DESC
),
interessenten AS (
SELECT *
FROM lastStatus
WHERE status_kurzbz = 'Interessent'
AND studiengang_kz IN
(
SELECT studiengang_kz
FROM public.tbl_prestudent p
JOIN
(
SELECT DISTINCT ON(prestudent_id) *
FROM public.tbl_prestudentstatus
WHERE prestudent_id IN
(
SELECT prestudent_id
FROM public.tbl_prestudent
WHERE person_id IN
(
SELECT p2.person_id
FROM public.tbl_person p
JOIN public.tbl_person p2
ON lower(p.vorname) = lower(p2.vorname)
AND lower(p.nachname) = lower(p2.nachname)
AND p.gebdatum = p2.gebdatum
AND p.person_id = ?
)
)
ORDER BY prestudent_id, datum DESC, insertamum DESC
) ps USING(prestudent_id)
JOIN public.tbl_status USING(status_kurzbz)
WHERE status_kurzbz = 'Abbrecher'
)
UNION
),
keineInteressenten AS (
SELECT *
FROM lastStatus
WHERE status_kurzbz != 'Interessent'
),
doppeltePerson AS (
SELECT p2.person_id
FROM tbl_person p1
JOIN tbl_prestudent ps ON p1.person_id = ps.person_id
INNER JOIN (
SELECT vorname, nachname, gebdatum, person.person_id
FROM tbl_person person
JOIN tbl_prestudent sps ON person.person_id = sps.person_id
) p2
ON (lower(p1.vorname) = lower(p2.vorname) AND lower(p1.nachname) = lower(p2.nachname) AND p1.gebdatum = p2.gebdatum)
WHERE p1.person_id != p2.person_id AND (p1.person_id = ?)";
FROM public.tbl_person p1
JOIN public.tbl_prestudent ps1 ON ps1.person_id = p1.person_id
JOIN public.tbl_person p2
ON lower(p1.vorname) = lower(p2.vorname)
AND lower(p1.nachname) = lower(p2.nachname)
AND p1.gebdatum = p2.gebdatum
WHERE p1.person_id = ?
AND p1.person_id <> p2.person_id
)
SELECT DISTINCT(interessenten.person_id)
FROM interessenten
JOIN keineInteressenten
ON interessenten.studiengang_kz = keineInteressenten.studiengang_kz
WHERE interessenten.person_id = ?
UNION
SELECT DISTINCT person_id
FROM doppeltePerson";
return $this->execQuery($qry, array($person_id, $person_id, $person_id));
}
@@ -430,4 +430,18 @@ class Mitarbeiter_model extends DB_Model
return $this->execQuery($qry, $parametersArray);
}
public function isLehrauftragFirma($mitarbeiter_uid)
{
$this->addSelect('firma_id');
$this->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid');
$this->addJoin('public.tbl_person', 'person_id');
$this->addJoin('public.tbl_adresse', 'person_id', 'LEFT');
$this->addOrder('zustelladresse', 'DESC');
$this->addOrder('firma_id');
$this->addLimit(1);
$firma_result = $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid));
$firma = getData($firma_result)[0]->firma_id;
return !is_null($firma);
}
}
@@ -10,6 +10,9 @@ class Stundenplandev_model extends DB_Model
parent::__construct();
$this->dbTable = 'lehre.tbl_stundenplandev';
$this->pk = 'stundenplandev_id';
$this->load->model('education/lehreinheit_model', 'LehreinheitModel');
$this->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
}
@@ -157,4 +160,85 @@ class Stundenplandev_model extends DB_Model
return $this->execQuery($qry, $params);
}
public function deleteGroupPlanning($lehreinheit_id, $lehreinheitgruppe_id)
{
$lehreinheit = $this->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit))
return error ('No Lehreinheit found!');
$lehreinheitgruppe = $this->LehreinheitgruppeModel->load($lehreinheitgruppe_id);
if (!hasData($lehreinheitgruppe))
return error ('No Lehreinheitgruppe found!');
$this->addJoin('lehre.tbl_stundenplan_betriebsmittel', 'stundenplandev_id');
$this->addJoin('lehre.tbl_lehreinheitgruppe', 'lehreinheit_id');
$this->db->where('tbl_lehreinheitgruppe.lehreinheitgruppe_id', $lehreinheitgruppe_id);
$this->db->group_start();
$this->db->group_start();
$this->db->where('tbl_lehreinheitgruppe.gruppe_kurzbz IS NOT NULL', null, false);
$this->db->where('tbl_lehreinheitgruppe.gruppe_kurzbz = tbl_stundenplandev.gruppe_kurzbz', null, false);
$this->db->group_end();
$this->db->or_group_start();
$this->db->where('tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL', null, false);
$this->db->where('tbl_lehreinheitgruppe.studiengang_kz = tbl_stundenplandev.studiengang_kz', null, false);
$this->db->where('tbl_lehreinheitgruppe.semester = tbl_stundenplandev.semester', null, false);
$this->db->where('tbl_lehreinheitgruppe.verband = tbl_stundenplandev.verband', null, false);
$this->db->where('tbl_lehreinheitgruppe.gruppe = tbl_stundenplandev.gruppe', null, false);
$this->db->group_end();
$this->db->group_end();
$betriebsmittel_result = $this->load();
$betriebsmittel_array = hasData($betriebsmittel_result) ? getData($betriebsmittel_result) : array();
if (sizeof($betriebsmittel_array) > 0)
{
return error ('Gruppe kann nicht entfernt werden da bereits Ressourcen zugeordnet wurden');
}
$this->addSelect('stundenplandev_id');
$this->addJoin('lehre.tbl_lehreinheitgruppe',
"tbl_stundenplandev.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND tbl_stundenplandev.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND tbl_stundenplandev.semester = tbl_lehreinheitgruppe.semester
AND trim(COALESCE(tbl_stundenplandev.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, ''))
AND trim(COALESCE(tbl_stundenplandev.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, ''))
AND trim(COALESCE(tbl_stundenplandev.gruppe_kurzbz, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, ''))"
);
$stundenplan_result = $this->loadWhere(array('tbl_lehreinheitgruppe.lehreinheitgruppe_id' => $lehreinheitgruppe_id));
if (hasData($stundenplan_result))
{
$stundenplan_ids = array_column(getData($stundenplan_result), 'stundenplandev_id');
$this->db->where_in('stundenplandev_id', $stundenplan_ids);
$delete_result = $this->db->delete('lehre.tbl_stundenplandev');
if ($delete_result)
return success('Group deleted successfully from Stundenplandev');
else
return error('Error deleting Group from Stundenplandev');
}
}
public function deleteLektorPlanning($lehreinheit_id, $mitarbeiter_uid)
{
//TODO (david) prüfen ob der check notwendig ist
/*$this->addDistinct('mitarbeiter_uid');
$this->addSelect('mitarbeiter_uid');
$stundenplan_result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
$stundenplan_array = hasData($stundenplan_result) ? (getData($stundenplan_result)) : array();
if (sizeof($stundenplan_array) <= 1)
return error('Diese/r LektorIn kann nicht aus dem LVPlan entfernt werden da dies der/die letzte verplante LektorIn ist');*/
$this->addJoin('lehre.tbl_stundenplan_betriebsmittel', 'stundenplandev_id');
$betriebsmittel_result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'tbl_stundenplandev.mitarbeiter_uid' => $mitarbeiter_uid));
$betriebsmittel_array = hasData($betriebsmittel_result) ? getData($betriebsmittel_result) : array();
if (sizeof($betriebsmittel_array) > 0)
return error('Gruppe kann nicht entfernt werden da bereits Ressourcen zugeordnet wurden');
return $this->delete(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
}
}
@@ -42,4 +42,20 @@ class Stundensatz_model extends DB_Model
return $this->execQuery($qry, $params);
}
public function getDefaultStundensatz($mitarbeiter_uid, $beginn, $ende = null, $typ = null)
{
$stundensatz_result = $this->getStundensatzByDatum($mitarbeiter_uid, $beginn, $ende, $typ);
$default_stundensatz = hasData($stundensatz_result) ? getData($stundensatz_result)[0]->stundensatz : null;
if (defined('FAS_LV_LEKTORINNENZUTEILUNG_FIXANGESTELLT_STUNDENSATZ') && !FAS_LV_LEKTORINNENZUTEILUNG_FIXANGESTELLT_STUNDENSATZ)
{
$this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel');
$echterdv_result = $this->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $beginn, $ende, 'echterdv');
if (hasData($echterdv_result))
{
$default_stundensatz = null;
}
}
return $default_stundensatz;
}
}
@@ -253,4 +253,25 @@ EOSQL;
}
return $dvs;
}
public function existsDienstverhaeltnis($mitarbeiter_uid, $start, $ende = null, $vertragsart_kurzbz = null)
{
$this->addOrder('von', 'DESC');
$this->db->where('mitarbeiter_uid', $mitarbeiter_uid);
if (!is_null($vertragsart_kurzbz))
$this->db->where('vertragsart_kurzbz', $this->escape($vertragsart_kurzbz));
$this->db->where('von <=', $ende);
if (!is_null($ende))
{
$this->db->group_start();
$this->db->where('bis >=', $start);
$this->db->or_where('bis IS NULL', null, false);
$this->db->group_end();
}
$this->addLimit(1);
return $this->load();
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
$includesArray = array(
'title' => 'LVVerwaltung',
'axios027' => true,
'bootstrap5' => true,
'fontawesome6' => true,
'vue3' => true,
'primevue3' => true,
'tabulator6' => true,
'tinymce5' => true,
'tags' => true,
'customCSSs' => [
'public/css/components/vue-datepicker.css',
'public/css/components/primevue.css',
'public/css/Studentenverwaltung.css',
'public/css/Lvverwaltung.css'
],
'customJSModules' => [
'public/js/apps/LVVerwaltung.js'
]
);
$this->load->view('templates/FHC-Header', $includesArray);
?>
<div id="main">
<router-view
default-semester="<?= $variables['semester_aktuell']; ?>"
lv-root="<?= site_url('LVVerwaltung'); ?>"
:permissions="<?= htmlspecialchars(json_encode($permissions));?>"
:config="<?= htmlspecialchars(json_encode($configs)); ?>"
>
</router-view>
</div>
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
@@ -18,6 +18,9 @@
<?php (!isset($notiz->kurzbzlang)) ?: print_r('(' . nl2br($notiz->kurzbzlang) . ') - ') ?>
<?php echo nl2br($notiz->text) ?>
</td>
<td>
<a href="mailto:<?php echo htmlspecialchars($notiz->email)?>?body=<?php echo rawurlencode($notiz->text);; ?>"><i class="fa fa-envelope"></i></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
@@ -57,7 +57,7 @@
<div class="row<?php if ($lockedbyother) echo ' alert-danger' ?>">
<div class="col-lg-8">
<h3 class="page-header">
Infocenter Details: <?php echo $stammdaten->vorname.' '.$stammdaten->nachname ?>
Infocenter Details: <a target="_blank" title="Studentenverwaltung" href="<?php echo site_url('/Studentenverwaltung/' . $studiensemester . '/person/' . $stammdaten->person_id) ?>"><?php echo $stammdaten->vorname.' '.$stammdaten->nachname ?> <i class="fa fa-external-link" style="font-size:small"></i></a>
</h3>
</div>
<div class="col-lg-4">
+40
View File
@@ -0,0 +1,40 @@
textarea[name="anmerkung"] {
position: absolute;
max-height: 300px;
}
.lv_table_icon::before
{
font-family: 'Font Awesome 6 Free';
font-weight: 900;
margin-left: 5px;
display: inline-block;
}
.lv_table_icon.icon-modul::before
{
content: '\f468';
color: #4e4ed2;
}
.lv_table_icon.icon-lv::before
{
content: '\f466';
color: black;
}
.lv_table_icon.icon-::before
{
content: '\f073';
color: #f3c541;
}
.modal-dialog.modal-xxl {
max-width: 95% !important;
}
.tabulator-menu .tabulator-menu-item.tabulator-menu-item-submenu:after
{
border-color: black;
}
+153 -1
View File
@@ -1 +1,153 @@
@import '../../vendor/olifolkerd/tabulator6/dist/css/tabulator_simple.min.css';
@import '../../vendor/olifolkerd/tabulator6/dist/css/tabulator_simple.min.css';
.tabulator-row {
border-bottom: none;
}
.tabulator-row .tabulator-frozen,
.tabulator-row .tabulator-cell {
border-bottom: 1px solid #dee2e6;
}
.tabulator-row.tabulator-row-even {
background-color: transparent;
}
.tabulator-headers .tabulator-frozen,
.tabulator-row.tabulator-row-odd .tabulator-frozen,
.tabulator-row.tabulator-row-odd .tabulator-cell {
background-color: #fff;
}
.tabulator-row.tabulator-row-even .tabulator-frozen,
.tabulator-row.tabulator-row-even .tabulator-cell {
background-color: #f2f2f2;
}
.tabulator-row.tabulator-selectable:hover .tabulator-frozen,
.tabulator-row.tabulator-selectable:hover .tabulator-cell {
background-color: #ececec;
}
.tabulator-row.tabulator-selected .tabulator-frozen,
.tabulator-row.tabulator-selected .tabulator-cell {
background-color: #9abcea;
}
.tabulator-row.tabulator-selected:hover .tabulator-frozen,
.tabulator-row.tabulator-selected:hover .tabulator-cell {
background-color: #769bcc;
}
.tabulator .tabulator-col-resize-handle:last-of-type {
z-index: 999999;
}
/* classes for rows that are not selectable in the tabulator, except for rows that are used for calculation */
.tabulator-row.tabulator-unselectable:not(.tabulator-calcs) {
color: #adb5bd !important;
pointer-events: none !important;
}
.tabulator-row.tabulator-unselectable a {
pointer-events: auto !important;
}
/* using bootstrap background classes to style the background color of tabulator rows */
/* bg-warning */
/* odd-rows */
.tabulator-headers .tabulator-frozen.bg-warning,
.tabulator-row.tabulator-row-odd .tabulator-frozen.bg-warning,
.tabulator-row.tabulator-row-odd .tabulator-cell.bg-warning {
background-color: #fcf8e3;
}
/* even-rows */
.tabulator-headers .tabulator-frozen.bg-warning,
.tabulator-row.tabulator-row-even .tabulator-frozen.bg-warning,
.tabulator-row.tabulator-row-even .tabulator-cell.bg-warning {
background-color: #fcf8e3;
}
/* bg-success */
/* odd-rows */
.tabulator-headers .tabulator-frozen.bg-success,
.tabulator-row.tabulator-row-odd .tabulator-frozen.bg-success,
.tabulator-row.tabulator-row-odd .tabulator-cell.bg-success {
background-color: #dff0d8;
}
/* even-rows */
.tabulator-headers .tabulator-frozen.bg-success,
.tabulator-row.tabulator-row-even .tabulator-frozen.bg-success,
.tabulator-row.tabulator-row-even .tabulator-cell.bg-success {
background-color: #dff0d8;
}
/* bg-info */
/* odd-rows */
.tabulator-headers .tabulator-frozen.bg-info,
.tabulator-row.tabulator-row-odd .tabulator-frozen.bg-info,
.tabulator-row.tabulator-row-odd .tabulator-cell.bg-info {
background-color: #d9edf7;
}
/* even-rows */
.tabulator-headers .tabulator-frozen.bg-info,
.tabulator-row.tabulator-row-even .tabulator-frozen.bg-info,
.tabulator-row.tabulator-row-even .tabulator-cell.bg-info {
background-color: #d9edf7;
}
/* special bootstrap5 styling for tableWidget and their accordion-item ::after content */
.accordion-button::after{
content:none !important;
}
.tabulator {
font-size: 1rem;
}
.tabulator-initialfontsize .tabulator {
font-size: 14px;
}
.tabulator-row.tabulator-unselectable .tabulator-cell {
pointer-events: all;
}
.tabulator-tooltip {
color: #fff;
background-color: #000;
}
.tabulator-row.tabulator-unselectable:not(.tabulator-calcs) {
color: #777 !important;
}
.tabulator-cell .btn {
padding: 0 .375rem;
font-size: calc(1rem - 2px / 1.5); /* substract border (2 x 1px) modified by the line-height (1.5) */
border-radius: .2rem;
vertical-align: baseline;
}
.tabulator-row.tabulator-selectable:focus {
box-shadow: 0 0 0 .24rem rgba(13,110,253,.25);
z-index: 1;
outline: 0;
}
.btn-select-col-selected
{
background-color: #e6e6e6;
}
.accordion-item-dark, .accordion-item-dark:focus{
background-color:#CED4DA !important;
border-color:#ADB5BD !important;
box-shadow: none !important;
}
/**
* Make keyboard-focused list items look like the mouse-hovered list items
*/
.tabulator-edit-list .tabulator-edit-list-item.focused {
color: #fff;
background: #1d68cd;
}
+4 -1
View File
@@ -16,7 +16,10 @@
*/
import person from "./notiz/person.js";
import lehreinheit from "./notiz/lehreinheit.js";
export default {
person
person,
lehreinheit
};
@@ -0,0 +1,29 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*/
import Person from './person.js';
export default {
...Person,
getNotizen(id, type) {
return {
method: 'get',
url: 'api/frontend/v1/notiz/notizLehreinheit/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type)
};
},
};
+36
View File
@@ -0,0 +1,36 @@
export default {
getByLV(lehrveranstaltung_id)
{
return {
method: 'get',
url: '/api/frontend/v1/Lehrveranstaltung/loadByLV/' + encodeURIComponent(lehrveranstaltung_id)
};
},
getByStg(studiensemester_kurzbz, studiengang_kz, semester = null)
{
let path = "/api/frontend/v1/Lehrveranstaltung/getByStg/" + encodeURIComponent(studiensemester_kurzbz) + "/" + encodeURIComponent(studiengang_kz);
if (semester)
path += "/" + encodeURIComponent(semester);
return path;
},
getByEmp(studiensemester_kurzbz, mitarbeiter_uid, stg = null)
{
let path = "/api/frontend/v1/Lehrveranstaltung/getByEmp/" + encodeURIComponent(studiensemester_kurzbz) + "/" + encodeURIComponent(mitarbeiter_uid);
if (stg)
path += "/" + encodeURIComponent(stg);
return path;
},
getTable(url)
{
return {
method: 'get',
url: url
};
},
}
@@ -0,0 +1,30 @@
export default {
getStudiensemester()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/setup/getStudiensemester/'
};
},
getSprache()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/setup/getSprache/'
};
},
getLehrform()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/setup/getLehrform/'
};
},
getRaumtyp()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/setup/getRaumtyp/'
};
},
}
@@ -0,0 +1,26 @@
export default {
add(newData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/DirektGruppe/add/',
params: newData
};
},
delete(deleteData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/DirektGruppe/delete/',
params: deleteData
};
},
getByLehreinheit(lehreinheit_id)
{
return {
method: 'get',
url: '/api/frontend/v1/lv/DirektGruppe/getByLehreinheit/' + encodeURIComponent(lehreinheit_id)
};
},
}
+56
View File
@@ -0,0 +1,56 @@
export default {
delete(deleteData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/gruppe/delete/',
params: deleteData
};
},
add(newData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/gruppe/add/',
params: newData
};
},
getByLehreinheit(lehreinheit_id)
{
return {
method: 'get',
url: '/api/frontend/v1/lv/gruppe/getByLehreinheit/' + encodeURIComponent(lehreinheit_id)
};
},
deleteFromLVPlan(deleteData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/gruppe/deleteFromLVPlan/',
params: deleteData
};
},
/*------------- details -------- */
getAll()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/gruppe/getAll/'
};
},
getBenutzer()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/gruppe/getBenutzer/'
};
}
}
@@ -0,0 +1,41 @@
export default {
copy(data)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lehreinheit/copy/',
params: data
};
},
delete(data)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lehreinheit/delete/',
params: data
};
},
add(newData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lehreinheit/add/',
params: newData
};
},
get(lehreinheit)
{
return {
method: 'get',
url: '/api/frontend/v1/lv/lehreinheit/get/' + encodeURIComponent(lehreinheit)
};
},
update(updatedData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lehreinheit/update/',
params: updatedData
};
},
}
+78
View File
@@ -0,0 +1,78 @@
export default {
getLehrfunktionen()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/lektor/getLehrfunktionen/'
};
},
getLektoren()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/lektor/getLektoren/'
};
},
getByLehreinheit(lehreinheit_id)
{
return {
method: 'get',
url: '/api/frontend/v1/lv/lektor/getLektorenByLE/' + encodeURIComponent(lehreinheit_id)
};
},
add(newData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lektor/add/',
params: newData
};
},
update(updatedData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lektor/update/',
params: updatedData
};
},
deletePerson(deleteData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lektor/deletePerson/',
params: deleteData
};
},
deleteFromLVPlan(deleteData)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lektor/deleteLVPlan/',
params: deleteData
};
},
getLektorDaten(lehreinheit_id, mitarbeiter_uid)
{
return {
method: 'get',
url: '/api/frontend/v1/lv/lektor/getLektorDaten/' + encodeURIComponent(lehreinheit_id) + '/' + encodeURIComponent(mitarbeiter_uid)
};
},
}
+9
View File
@@ -0,0 +1,9 @@
export default {
getTabs()
{
return {
method: 'get',
url: '/api/frontend/v1/lv/setup/getTabs/'
};
},
}
@@ -0,0 +1,43 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*/
export default {
get(path) {
let url = 'api/frontend/v1/lv/StgTree';
if (path)
url += '/' + path;
return {
method: 'get',
url
};
},
favorites: {
get() {
return {
method: 'get',
url: 'api/frontend/v1/lv/favorites'
};
},
set(favorites) {
return {
method: 'post',
url: 'api/frontend/v1/lv/favorites/set',
params: { favorites }
};
}
}
};
+54
View File
@@ -0,0 +1,54 @@
export default {
getTag(data)
{
return {
method: 'get',
url: 'api/frontend/v1/lv/Tags/getTag',
params: data
};
},
getTags(data)
{
return {
method: 'get',
url: 'api/frontend/v1/lv/Tags/getTags'
};
},
addTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/lv/Tags/addTag',
params: data
};
},
updateTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/lv/Tags/updateTag',
params: data
};
},
doneTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/lv/Tags/doneTag',
params: data
};
},
deleteTag(data)
{
return {
method: 'post',
url: 'api/frontend/v1/lv/Tags/deleteTag',
params: data
};
},
};
@@ -0,0 +1,22 @@
export default {
getByLeEmp(lehreinheit_id, mitarbeiter_uid)
{
return {
method: 'get',
url: '/api/frontend/v1/lv/lektor/getLektorDaten/' + encodeURIComponent(lehreinheit_id) + '/' + encodeURIComponent(mitarbeiter_uid),
};
},
cancelByLeEmp(needUpdate)
{
return {
method: 'post',
url: '/api/frontend/v1/lv/lektor/cancelVertrag/',
params: needUpdate
};
},
}
+102
View File
@@ -0,0 +1,102 @@
import LVVerwaltung from "../components/LVVerwaltung/LVVerwaltung.js";
import Phrasen from "../plugins/Phrasen.js";
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(`/${ciPath}/LVVerwaltung`),
routes: [
{
name: 'index',
path: `/`,
component: LVVerwaltung
},
{
name: `byEmp`,
path: `/emp/:studiensemester_kurzbz/:emp/:stg?/:semester?`,
component: LVVerwaltung,
props: route => {
let {emp, stg, semester, studiensemester_kurzbz} = route.params;
if (emp === '')
emp = undefined;
if (stg === '')
stg = undefined;
if (studiensemester_kurzbz === '')
studiensemester_kurzbz = undefined;
return {
studiensemester_kurzbz: studiensemester_kurzbz,
emp: emp,
stg: stg,
semester: semester
};
},
beforeEnter: (to, from, next) => {
const { studiensemester_kurzbz } = to.params;
const isSemester = /^(SS|WS)\d{4}$/.test(studiensemester_kurzbz);
if (!isSemester)
return next({ path: '/' });
else
next();
}
},
/*{
name: `byFachbereich`,
path: `/fachbereich/:fachbereich/:emp?`,
component: LVVerwaltung
},*/
{
name: `byStg`,
path: '/stg/:studiensemester_kurzbz/:stg?/:semester?/',
component: LVVerwaltung,
props: route => {
let { studiensemester_kurzbz, stg, semester } = route.params;
if (semester === '')
semester = undefined;
if (studiensemester_kurzbz === '')
studiensemester_kurzbz = undefined;
if (stg === '')
stg = undefined;
return {
studiensemester_kurzbz: studiensemester_kurzbz,
stg: stg,
semester: semester,
};
},
beforeEnter: (to, from, next) => {
const studiensemester_kurzbz = to.params?.studiensemester_kurzbz
const isSemester = /^(SS|WS)\d{4}$/.test(studiensemester_kurzbz);
if (!isSemester)
return next({ path: '/' });
else
next();
}
},
{
path: '/:pathMatch(.*)*',
redirect: '/'
},
]
});
const app = Vue.createApp();
app
.use(router)
.use(primevue.config.default, {
zIndex: {
overlay: 1100
}
})
.use(Phrasen)
.mount('#main');
+10 -27
View File
@@ -2,6 +2,8 @@ import raum_contentmittitel from './Content_types/Raum_contentmittitel.js'
import general from './Content_types/General.js'
import BsConfirm from "../../Bootstrap/Confirm.js";
import news_content from './Content_types/News_content.js';
import iframe_content from './Content_types/Iframe_content.js';
import ApiCms from '../../../api/factory/cms.js';
export default {
@@ -24,42 +26,23 @@ export default {
raum_contentmittitel,
news_content,
general,
iframe_content
},
data() {
return {
content_type: null,
content: null,
content_id_internal: this.content_id
};
},
methods: {
fetchContent(){
return this.$api
this.$api
.call(ApiCms.content(this.content_id_internal, this.version, this.sprache, this.sichtbar))
.then(res => {
this.content = res.data.content;
this.content_type = res.data.type;
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
el.addEventListener("click", (evt) => {
evt.preventDefault();
BsConfirm.popup(el.dataset.confirm)
.then(() => {
Axios.get(el.href)
.then((res) => {
// TODO(chris): check for success then show message and/or reload
location = location;
})
.catch((err) => console.error("ERROR:", err));
})
.catch(() => {
});
});
});
document.querySelectorAll("#cms [data-href]").forEach((el) => {
el.href = el.dataset.href.replace(
/^ROOT\//,
FHC_JS_DATA_STORAGE_OBJECT.app_root
);
this.$nextTick(function() {
this.content = res.data.content;
this.content_type = res.data.type;
});
});
}
@@ -83,6 +66,8 @@ export default {
return "raum_contentmittitel";
case "news":
return "news_content";
case "iframe":
return "iframe_content";
default:
return "general";
};
@@ -91,8 +76,6 @@ export default {
created() {
this.fetchContent();
},
mounted() {
},
template: /*html*/ `
<!-- div that contains the content -->
<div id="fhc-cms-content" v-if="content">
@@ -0,0 +1,31 @@
import { replaceRelativeLegacyLink } from "../../../../helpers/LegacyLinkReplaceHelper.js";
export default {
name: "iframe_content",
props: {
content: { type: String, required: true }
},
computed: {
srcUrl() {
const parser = new DOMParser()
const doc = parser.parseFromString(`<div>${this.content}</div>`, "text/html");
const iframe = doc.querySelector("iframe[src]");
if (!iframe)
return "";
let url = iframe.getAttribute("src") || "";
return replaceRelativeLegacyLink(url);
}
},
template: `
<div class="w-100">
<iframe
v-if="srcUrl"
:src="srcUrl"
style="width:100%; height:90vh; border:0; display:block;"
></iframe>
<div v-else class="alert alert-warning">Keine URL gefunden.</div>
</div>
`
};
@@ -11,6 +11,7 @@ import RoleInformation from "./ProfilComponents/RoleInformation.js";
import ProfilInformation from "./ProfilComponents/ProfilInformation.js";
import ApiProfilUpdate from '../../../api/factory/profilUpdate.js';
import { dateFilter } from '../../../tabulator/filters/Dates.js';
export default {
components: {
@@ -40,7 +41,7 @@ export default {
persistence: {
columns: false
},
height: 300,
minHeight: 300,
layout: "fitColumns",
responsiveLayout: "collapse",
responsiveLayoutCollapseUseFormatters: false,
@@ -74,18 +75,24 @@ export default {
{
title: Vue.computed(() => this.preloadedPhrasen.gueltigVonPhrase),
field: "Gültig_von",
headerFilter: true,
headerFilterFunc: 'dates',
headerFilter: dateFilter,
resizable: true,
minWidth: 200,
visible: true
visible: true,
formatter:"datetime",
formatterParams: this.datetimeFormatterParams()
},
{
title: Vue.computed(() => this.preloadedPhrasen.gueltigBisPhrase),
field: "Gültig_bis",
headerFilter: true,
headerFilterFunc: 'dates',
headerFilter: dateFilter,
resizable: true,
minWidth: 200,
visible: true
visible: true,
formatter:"datetime",
formatterParams: this.datetimeFormatterParams()
},
{
title: Vue.computed(() => this.preloadedPhrasen.wochenstundenPhrase),
@@ -102,7 +109,7 @@ export default {
persistence: {
columns: false
},
height: 300,
minHeight: 300,
layout: "fitColumns",
responsiveLayout: "collapse",
responsiveLayoutCollapseUseFormatters: false,
@@ -138,9 +145,12 @@ export default {
{
title: Vue.computed(() => this.preloadedPhrasen.ausgabedatumPhrase),
field: "Ausgegeben_am",
headerFilter: true,
headerFilterFunc: 'dates',
headerFilter: dateFilter,
minWidth: 200,
visible: true
visible: true,
formatter:"datetime",
formatterParams: this.datetimeFormatterParams()
},
],
}
@@ -211,6 +221,15 @@ export default {
setTableColumnTitles() { // reevaluates computed phrasen
if(this.$refs.betriebsmittelTable) this.$refs.betriebsmittelTable.tabulator.setColumns(this.betriebsmittel_table_options.columns)
if(this.$refs.funktionenTable) this.$refs.funktionenTable.tabulator.setColumns(this.funktionen_table_options.columns)
},
datetimeFormatterParams: function() {
const params = {
inputFormat:"yyyy-MM-dd",
outputFormat:"dd.MM.yyyy",
invalidPlaceholder:"(invalid date)",
timezone:FHC_JS_DATA_STORAGE_OBJECT.timezone
};
return params;
}
},
@@ -5,6 +5,8 @@ import RoleInformation from "./ProfilComponents/RoleInformation.js";
import ProfilEmails from "./ProfilComponents/ProfilEmails.js";
import ProfilInformation from "./ProfilComponents/ProfilInformation.js";
import { dateFilter } from '../../../tabulator/filters/Dates.js';
export default {
components: {
CoreFilterCmpt,
@@ -24,7 +26,7 @@ export default {
persistence: {
columns: false
},
height: 300,
minHeight: 300,
layout: "fitColumns",
responsiveLayout: "collapse",
responsiveLayoutCollapseUseFormatters: false,
@@ -60,18 +62,24 @@ export default {
{
title: Vue.computed(() => this.$p.t('global/gueltigVon')),
field: "Gültig_von",
headerFilter: true,
headerFilterFunc: 'dates',
headerFilter: dateFilter,
resizable: true,
minWidth: 200,
visible: true
visible: true,
formatter:"datetime",
formatterParams: this.datetimeFormatterParams()
},
{
title: Vue.computed(() => this.$p.t('global/gueltigBis')),
field: "Gültig_bis",
headerFilter: true,
headerFilterFunc: 'dates',
headerFilter: dateFilter,
resizable: true,
minWidth: 200,
visible: true
visible: true,
formatter:"datetime",
formatterParams: this.datetimeFormatterParams()
},
{
title: Vue.computed(() => this.$p.t('profil/wochenstunden')),
@@ -91,6 +99,15 @@ export default {
funktionenTableBuilt: function () {
this.$refs.funktionenTable.tabulator.setData(this.data.funktionen);
},
datetimeFormatterParams: function() {
const params = {
inputFormat:"yyyy-MM-dd",
outputFormat:"dd.MM.yyyy",
invalidPlaceholder:"(invalid date)",
timezone:FHC_JS_DATA_STORAGE_OBJECT.timezone
};
return params;
}
},
watch: {
'data.funktionen'(newVal) {
@@ -10,21 +10,34 @@ export default {
type: String,
}
},
inject: [
'studiengang_kz', // inject info that should not be displayed
],
inject: {
// inject info that should not be displayed
'studiengang_kz': {
from: 'studiengang_kz',
default: false
},
},
computed: {
getLinkGruppeListe() {
if(this.studiengang_kz === false) {
return '';
}
return this.data.gruppe?.value && this.data.verband?.value && this.data.semester?.value ? FHC_JS_DATA_STORAGE_OBJECT.app_root
+ 'cis/private/stud_in_grp.php?kz='+this.studiengang_kz+'&sem=' + this.data.semester.value
+ '&verband=' + this.data.verband.value + '&grp=' + this.data.gruppe.value : ''
},
getLinkVerbandListe() {
if(this.studiengang_kz === false) {
return '';
}
return this.data.verband?.value && this.data.semester?.value ? FHC_JS_DATA_STORAGE_OBJECT.app_root
+ 'cis/private/stud_in_grp.php?kz='+this.studiengang_kz+'&sem=' + this.data.semester.value
+ '&verband=' + this.data.verband.value : ''
},
getLinkSemesterListe() {
if(this.studiengang_kz === false) {
return '';
}
return this.data.semester?.value ? FHC_JS_DATA_STORAGE_OBJECT.app_root
+ 'cis/private/stud_in_grp.php?kz='+this.studiengang_kz+'&sem=' + this.data.semester.value : ''
}
@@ -16,7 +16,7 @@ export default {
mixins: [BsModal],
props: {
titel: {
type: Object,
type: String,
},
files: {
type: Array,
@@ -57,7 +57,7 @@ export default {
},
template: /*html*/`
<bs-modal v-show="!loading" ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" :backdrop="false">
<bs-modal ref="modalContainer" v-bind="$props" body-class="" dialog-class="modal-lg" class="bootstrap-alert" :backdrop="false">
<template #title>
<p style="opacity:0.8" class="ms-2" v-if="!updateID">{{$p.t('profilUpdate','profilBildUpdateMessage',[titel])}}</p>
</template>
@@ -11,6 +11,7 @@ import FetchProfilUpdates from "./ProfilComponents/FetchProfilUpdates.js";
import EditProfil from "./ProfilModal/EditProfil.js";
import ApiProfilUpdate from '../../../api/factory/profilUpdate.js';
import { dateFilter } from '../../../tabulator/filters/Dates.js';
export default {
components: {
@@ -39,7 +40,7 @@ export default {
persistence: {
columns: false
},
height: 200,
minHeight: 200,
layout: "fitColumns",
columns: [{
title: Vue.computed(() => this.preloadedPhrasen.zutrittsGruppenPhrase),
@@ -51,7 +52,7 @@ export default {
persistence: {
columns: false
},
height: 300,
minHeight: 300,
layout: "fitColumns",
responsiveLayout: "collapse",
responsiveLayoutCollapseUseFormatters: false,
@@ -85,9 +86,12 @@ export default {
{
title: Vue.computed(() =>this.preloadedPhrasen.ausgabedatum) ,
field: "Ausgegeben_am",
headerFilter: true,
headerFilterFunc: 'dates',
headerFilter: dateFilter,
minWidth: 200,
visible: true
visible: true,
formatter:"datetime",
formatterParams: this.datetimeFormatterParams()
},
],
},
@@ -160,6 +164,15 @@ export default {
this.$refs.editModal.show();
});
},
datetimeFormatterParams: function() {
const params = {
inputFormat:"yyyy-MM-dd",
outputFormat:"dd.MM.yyyy",
invalidPlaceholder:"(invalid date)",
timezone:FHC_JS_DATA_STORAGE_OBJECT.timezone
};
return params;
}
},
computed: {
@@ -0,0 +1,155 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import FormForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import ApiDirektGruppe from "../../../api/lehrveranstaltung/direktgruppe.js";
export default{
name: "LVDirektGruppen",
components: {
CoreFilterCmpt,
FormForm,
FormInput
},
props: {
lehreinheit_id: Number
},
inject: {
dropdowns: {
from: 'dropdowns'
},
},
computed: {
tabulatorOptions() {
return {
ajaxURL: 'dummy',
ajaxRequestFunc: () => this.$api.call(ApiDirektGruppe.getByLehreinheit(this.lehreinheit_id)),
ajaxResponse: (url, params, response) => { return response.data || [] },
columns:[
{title: this.$p.t('person', 'uid'), field:"uid"},
{title: this.$p.t('person', 'vorname'), field:"vorname"},
{title: this.$p.t('person', 'nachname'), field:"nachname"},
{title: this.$p.t('lehre', 'gruppe'), field:"gruppe_kurzbz"},
{
title: this.$p.t('global', 'actions'), field: 'actions',
minWidth: 150,
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
let button = document.createElement('button');
container.className = "d-flex gap-1";
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-xmark"></i>';
button.title = this.$p.t('ui', 'loeschen');
button.addEventListener('click', (event) => {
event.stopPropagation();
this.deleteDirektGroup(cell.getData().gruppe_kurzbz, cell.getData().uid)
});
container.append(button);
return container;
},
frozen: true
},
],
layout: 'fitDataFill',
selectable: true,
persistenceID: 'lvverwaltung_direkt_gruppen_2025_05_27_v1',
height: 'auto',
}
}
},
data() {
return{
lastSelected: null,
gruppen: [],
tabulatorEvents: [],
showAutocomplete: false,
selectedUser: null,
filteredUsers: [],
abortController: null,
searchTimeout: null,
}
},
watch: {
lehreinheit_id(n) {
this.$refs.table.reloadTable();
}
},
methods:{
reload() {
this.$refs.table.reloadTable();
},
deleteDirektGroup(gruppe_kurzbz, uid)
{
let deleteData = {
'gruppe_kurzbz': gruppe_kurzbz,
'uid': uid,
'lehreinheit_id': this.lehreinheit_id
}
this.$api.call(ApiDirektGruppe.delete(deleteData))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
this.reload();
})
},
searchUser(event)
{
const query = event.query.toLowerCase().trim();
this.filteredUsers = this.dropdowns.benutzer_array.filter(user => {
const fullName = `${user.vorname.toLowerCase()} ${user.nachname.toLowerCase()}`;
const reverseFullName = `${user.nachname.toLowerCase()} ${user.vorname.toLowerCase()}`;
return fullName.includes(query) || reverseFullName.includes(query) || user.uid.toLowerCase().includes(query) || user.studiengang.toLowerCase().includes(query);
}).map(user => ({
label: user.studiengang
? `${user.nachname} ${user.vorname} ${user.uid} ${user.studiengang} ${user.semester}`
: `${user.nachname} ${user.vorname} ${user.uid}`,
uid: user.uid
}));
},
addUser()
{
let newData = {
'uid': this.selectedUser.uid,
'lehreinheit_id': this.lehreinheit_id
}
return this.$api.call(ApiDirektGruppe.add(newData))
.then(result => {
this.reload()
this.selectedUser = ''
})
.catch(this.$fhcAlert.handleSystemError);
},
},
template: `
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
:reload=true
:new-btn-label="$p.t('lehre', 'assignPerson')"
new-btn-show
@click:new="showAutocomplete = !showAutocomplete"
>
<template #search> <!--TODO (david) Slot prüfen -->
<form-input
v-if="showAutocomplete"
type="autocomplete"
:suggestions="filteredUsers"
:placeholder="$p.t('lehre', 'assignPerson')"
v-model="selectedUser"
field="label"
:minLength="3"
@item-select="addUser"
@complete="searchUser"
></form-input>
</template>
</core-filter-cmpt>
`
};
@@ -0,0 +1,221 @@
import CoreForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
export default {
name: "LVDetailsForm",
components: {
FormInput,
CoreForm
},
props: {
data: {
type: Object,
required: true
}
},
inject: {
dropdowns: {
from: 'dropdowns'
},
showLVID: {
from: 'permissionLehrveranstaltung',
default: false
},
showGewichtung: {
from: 'configShowGewichtung',
default: true
}
},
computed: {
formattedAnmerkung: {
get() {
return (this.data.anmerkung || '').replace(/\\n/g, '\n');
},
set(value) {
this.data.anmerkung = (value || '').replace(/\n/g, '\\n');
}
}
},
template: `
<div>
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'lehrfach')"
type="select"
container-class="col-3"
v-model="data.lehrfach_id"
name="lehrfach_id"
>
<option
v-for="lehrfach in data.lehrfaecher"
:value="lehrfach.lehrveranstaltung_id"
:key="lehrfach.lehrfach"
>
{{ lehrfach.lehrfach }}
</option>
</form-input>
<form-input
:label="$p.t('lehre', 'lehrform')"
type="select"
container-class="col-3"
v-model="data.lehrform_kurzbz"
name="lehrform_kurzbz"
>
<option
v-for="lehrform in dropdowns.lehrform_array"
:value="lehrform.lehrform_kurzbz"
:key="lehrform.lehrform_kurzbz"
>
{{ lehrform.bez_kurz }} {{ lehrform.bez }}
</option>
</form-input>
<form-input
:label="$p.t('lehre', 'detailanmerkung')"
type="textarea"
container-class="col-3"
v-model="formattedAnmerkung"
name="anmerkung"
id="anmerkung"
rows="10"
/>
</div>
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'raumtyp')"
type="select"
container-class="col-3"
v-model="data.raumtyp"
name="raumtyp"
>
<option
v-for="raumtyp in dropdowns.raumtyp_array"
:value="raumtyp.raumtyp_kurzbz"
:key="raumtyp.raumtyp_kurzbz"
>
{{ raumtyp.raumtyp_kurzbz }} {{ raumtyp.beschreibung }}
</option>
</form-input>
<form-input
:label="$p.t('lehre', 'raumtypalternativ')"
type="select"
container-class="col-3"
v-model="data.raumtypalternativ"
name="raumtypalternativ"
>
<option
v-for="raumtyp in dropdowns.raumtyp_array"
:value="raumtyp.raumtyp_kurzbz"
:key="raumtyp.raumtyp_kurzbz + '-alt'"
>
{{ raumtyp.raumtyp_kurzbz }} {{ raumtyp.beschreibung }}
</option>
</form-input>
</div>
<div class="row mb-3">
<form-input
:label="$p.t('global', 'sprache')"
type="select"
container-class="col-3"
v-model="data.sprache"
name="sprache"
>
<option
v-for="sprache in dropdowns.sprachen_array"
:key="sprache.sprache"
:value="sprache.sprache"
>
{{ sprache.sprache }}
</option>
</form-input>
<form-input
:label="$p.t('lehre', 'studiensemester')"
type="select"
container-class="col-3"
v-model="data.studiensemester_kurzbz"
name="studiensemester_kurzbz"
>
<option
v-for="semester in dropdowns.studiensemester_array"
:key="semester.studiensemester_kurzbz"
:value="semester.studiensemester_kurzbz"
>
{{ semester.studiensemester_kurzbz }}
</option>
</form-input>
</div>
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'startkw')"
type="number"
min="0"
container-class="col-1"
v-model="data.start_kw"
name="start_kw"
/>
<form-input
:label="$p.t('lehre', 'stundenblockung')"
type="number"
min="0"
container-class="col-1"
v-model="data.stundenblockung"
name="stundenblockung"
/>
<form-input
:label="$p.t('lehre', 'wochenrhythmus')"
type="number"
min="0"
container-class="col-1"
v-model="data.wochenrythmus"
name="wochenrythmus"
/>
<div class="col-3 d-flex align-items-end">
<form-input
:label="$p.t('lehre', 'lehre')"
type="checkbox"
v-model="data.lehre"
name="lehre"
/>
</div>
</div>
<div class="row mb-3">
<form-input
v-if="showLVID"
:label="$p.t('lehre', 'lehrveranstaltung_id')"
type="text"
container-class="col-2"
v-model="data.lehrveranstaltung_id"
name="lehrveranstaltung_id"
/>
<form-input
:label="$p.t('lehre', 'unr')"
type="text"
container-class="col-1"
v-model="data.unr"
name="unr"
/>
<form-input
v-if="showGewichtung"
:label="$p.t('lehre', 'gewicht')"
type="text"
container-class="col-1"
v-model="data.gewicht"
name="gewicht"
/>
</div>
</div>
`
};
@@ -0,0 +1,195 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import FormForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import ApiGruppe from "../../../api/lehrveranstaltung/gruppe.js";
export default{
name: "LVGruppen",
components: {
CoreFilterCmpt,
FormForm,
FormInput
},
props: {
lehreinheit_id: Number
},
inject: {
dropdowns: {
from: 'dropdowns'
},
showLVPlanGruppenDel: {
from: 'permissionGruppenEntfernen',
default: false
},
},
computed: {
tabulatorOptions() {
return {
ajaxURL: 'dummy',
ajaxRequestFunc: () => this.$api.call(ApiGruppe.getByLehreinheit(this.lehreinheit_id)),
ajaxResponse: (url, params, response) => response.data,
columns:[
{title: this.$p.t('global', 'bezeichnung'), field:"bezeichnung"},
{title: this.$p.t('global', 'beschreibung'), field:"beschreibung"},
{title: this.$p.t('lehre', 'studiengang'), field:"studiengang"},
{title: "ID", field:"id", visible:false},
{
title: this.$p.t('lehre', 'verplant'),
field:"verplant",
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
}
},
{
title: this.$p.t('global', 'actions'), field: 'actions',
minWidth: 150,
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
let button = document.createElement('button');
container.className = "d-flex gap-1";
button.className = 'btn btn-outline-secondary';
button.innerHTML = '<i class="fa fa-xmark"></i>';
button.title = this.$p.t('ui', 'loeschen');
button.addEventListener('click', (event) => {
event.stopPropagation();
this.deleteGroup(cell.getData().lehreinheitgruppe_id)
});
container.append(button);
if (this.showLVPlanGruppenDel)
{
button = document.createElement('button');
container.className = "d-flex gap-2";
button.className = 'btn btn-outline-secondary';
button.innerHTML = '<i class="fa fa-calendar-xmark"></i>';
button.title = this.$p.t('lehre', 'auslvplanentfernen');
button.disabled = !cell.getData().verplant;
button.addEventListener('click', (event) => {
event.stopPropagation();
this.deleteLVPlan(cell.getData().lehreinheitgruppe_id)
});
container.append(button);
}
return container;
},
frozen: true
},
],
layout: 'fitDataFill',
selectable: true,
persistenceID: 'lvverwaltung_gruppen_2025_05_27_v1',
height: 'auto',
}
}
},
data() {
return{
tabulatorEvents: [],
showAutocomplete: false,
filteredGroups: [],
selectedGroup: null
}
},
watch: {
lehreinheit_id() {
this.$refs.table.reloadTable();
}
},
methods:{
searchGroup(event)
{
const query = event.query.toLowerCase().trim();
this.filteredGroups = this.dropdowns.gruppen_array.filter(gruppe => {
return gruppe.gruppe_kurzbz.toLowerCase().includes(query) || gruppe?.bezeichnung?.toLowerCase().includes(query);
}).map(gruppe => ({
label: gruppe.bezeichnung
? `${gruppe.gruppe_kurzbz.trim()} (${gruppe.bezeichnung})`
: gruppe.gruppe_kurzbz.trim(),
gid: gruppe.gid,
gruppe_kurzbz: gruppe.gruppe_kurzbz.trim(),
lehrverband: gruppe.lehrverband,
}));
},
reload() {
this.$refs.table.reloadTable();
},
addGroup()
{
let newData = {
'gid': this.selectedGroup.gid,
'lehreinheit_id': this.lehreinheit_id,
'lehrverband': this.selectedGroup.lehrverband,
'gruppe_kurzbz' : this.selectedGroup.gruppe_kurzbz
}
return this.$api.call(ApiGruppe.add(newData))
.then(result => {
this.reload()
this.selectedGroup = ''
})
.catch(this.$fhcAlert.handleSystemError);
},
deleteLVPlan(lehreinheitgruppe_id)
{
let deleteData = {
'lehreinheitgruppe_id': lehreinheitgruppe_id,
'lehreinheit_id': this.lehreinheit_id
}
this.$api.call(ApiGruppe.deleteFromLVPlan(deleteData))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
this.reload();
})
},
deleteGroup(lehreinheitgruppe_id)
{
let deleteData = {
'lehreinheitgruppe_id': lehreinheitgruppe_id,
'lehreinheit_id': this.lehreinheit_id
}
this.$api.call(ApiGruppe.delete(deleteData))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
this.reload();
})
},
},
template: `
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
:reload=true
:new-btn-label="$p.t('lehre', 'addGroup')"
new-btn-show
@click:new="showAutocomplete = !showAutocomplete"
>
<template #search> <!--TODO (david) Slot prüfen -->
<form-input
v-if="showAutocomplete"
type="autocomplete"
:suggestions="filteredGroups"
:placeholder="$p.t('lehre', 'addGroup')"
v-model="selectedGroup"
field="label"
@item-select="addGroup"
@complete="searchGroup"
></form-input>
</template>
</core-filter-cmpt>
`
};
@@ -0,0 +1,292 @@
import CoreSearchbar from "../searchbar/searchbar.js";
import VerticalSplit from "../verticalsplit/verticalsplit.js";
import StvVerband from "../Stv/Studentenverwaltung/Verband.js";
import StvStudiensemester from "../Stv/Studentenverwaltung/Studiensemester.js";
import LvTable from "./Setup/Table.js";
import LvTabs from "./Setup/Tabs.js";
import ApiDetails from "../../api/lehrveranstaltung/details.js";
import ApiLektor from "../../api/lehrveranstaltung/lektor.js";
import ApiGruppe from "../../api/lehrveranstaltung/gruppe.js";
import ApiStudiengangTree from "../../api/lehrveranstaltung/studiengangtree.js";
import ApiSearchbar from "../../api/factory/searchbar.js";
export default {
name: "LVVerwaltung",
components: {
CoreSearchbar,
VerticalSplit,
StvVerband,
StvStudiensemester,
LvTable,
LvTabs,
},
props: {
defaultSemester: String,
lvRoot: String,
permissions: Object,
config: Object,
stg: { type: String, required: false },
semester: { type: [Number, String], required: false, default: null },
studiensemester_kurzbz: { type: String, required: false, default: null },
emp: { type: String, required: false, default: null }
},
provide() {
return {
currentSemester: Vue.computed(() => this.selectedStudiensemester),
dropdowns: this.dropdowns,
configShowVertragsdetails: this.config.showVertragsdetails,
configShowGewichtung: this.config.showGewichtung,
lehreinheitAnmerkungDefault: this.config.lehreinheitAnmerkungDefault,
lehreinheitRaumtypDefault: this.config.lehreinheitRaumtypDefault,
lehreinheitRaumtypAlternativeDefault: this.config.lehreinheitRaumtypAlternativeDefault,
permissionLehrveranstaltung: this.permissions['lehre/lehrveranstaltung'],
permissionGruppenEntfernen: this.permissions['lv-plan/gruppenentfernen'],
permissionLektorEntfernen: this.permissions['lv-plan/lektorentfernen'],
}
},
mounted() {
this.updateFilter();
},
watch: {
stg() {
this.updateFilter();
},
semester() {
this.updateFilter();
},
selectedStudiensemester() {
this.updateFilter();
},
emp() {
this.updateFilter();
},
studiensemester_kurzbz(newVal) {
this.selectedStudiensemester = newVal ?? this.defaultSemester;
}
},
data() {
return {
selected: [],
studiengang: "",
filter: {},
selectedStudiensemester: this.studiensemester_kurzbz ?? this.defaultSemester,
endpoint: ApiStudiengangTree,
dropdowns: {
studiensemester_array: [],
sprachen_array: [],
lehrform_array: [],
raumtyp_array: [],
lektor_array: [],
gruppen_array: [],
benutzer_array: [],
},
selectedStudiengang: '',
searchbaroptions: {
origin: 'lvverwaltung',
cssclass: "position-relative",
calcheightonly: true,
types: [
"mitarbeiter",
"mitarbeiter_ohne_zuordnung"
],
actions: {
employee: {
defaultaction: {
type: "function",
action: (data) => {
this.onSelectEmployee(data.uid);
}
},
childactions: [
]
},
}
},
}
},
methods: {
updateFilter()
{
const filter = {
stg: this.stg,
emp: this.emp,
semester: this.semester,
studiensemester_kurzbz: this.selectedStudiensemester,
activeFilter: this.emp ? 'employee' : this.stg ? 'verband' : null
}
if (this.stg !== undefined)
{
this.selectedStudiengang = this.semester !== '' && this.semester
? `${this.stg}/${this.semester}`
: this.stg;
}
this.filter = filter;
},
handleRowClicked(data)
{
this.selected = data
},
onSelectEmployee(emp)
{
const { stg, semester } = this.filter;
let studiensemester_kurzbz = this.selectedStudiensemester;
const params = { emp };
if (stg)
params.stg = stg;
if (semester !== null)
params.semester = semester;
if (studiensemester_kurzbz)
params.studiensemester_kurzbz = studiensemester_kurzbz;
this.$router.push({ name: 'byEmp', params })
},
onSelectVerband({link})
{
let stg = null;
let semester = null;
let studiensemester_kurzbz = this.selectedStudiensemester;
if (typeof link === 'number')
stg = link;
else if (typeof link === 'string')
{
[stg, semester] = link.split('/');
}
const routeName = this.filter.emp ? 'byEmp' : 'byStg';
const params = { stg };
if (semester !== null)
params.semester = semester;
if (studiensemester_kurzbz)
params.studiensemester_kurzbz = studiensemester_kurzbz;
if (this.filter.emp)
params.emp = this.filter.emp;
this.$router.push({ name: routeName, params });
this.selected = [];
},
resetEmployeeFilter()
{
const newParams = { ...this.filter, activeFilter: 'verband' };
if (newParams.stg === '')
this.$router.replace({ name: 'index' });
else
{
delete newParams.emp;
this.$router.replace({ name: 'byStg', params: newParams });
}
},
searchfunction(params) {
return this.$api.call(ApiSearchbar.search(params));
},
studiensemesterChanged(newValue) {
const routeName = this.filter.activeFilter === 'employee' ? 'byEmp' : 'byStg';
const newParams = {...this.filter, studiensemester_kurzbz: newValue};
this.$router.push({ name: routeName, params: newParams });
this.selected = [];
},
},
created() {
this.$p.loadCategory(['lehre', 'person', 'global'])
this.$api.call(ApiDetails.getStudiensemester())
.then(result => {
this.dropdowns.studiensemester_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiDetails.getSprache())
.then(result => {
this.dropdowns.sprachen_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiDetails.getLehrform())
.then(result => {
this.dropdowns.lehrform_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiDetails.getRaumtyp())
.then(result => {
this.dropdowns.raumtyp_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiLektor.getLehrfunktionen())
.then(result => {
this.dropdowns.lehrfunktion_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiLektor.getLektoren())
.then(result => {
this.dropdowns.lektor_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiGruppe.getAll())
.then(result => {
this.dropdowns.gruppen_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api.call(ApiGruppe.getBenutzer())
.then(result => {
this.dropdowns.benutzer_array = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
template: `
<div class="stv">
<header class="navbar navbar-expand-lg navbar-dark bg-dark flex-md-nowrap p-0 shadow">
<a class="navbar-brand col-md-4 col-lg-3 col-xl-2 me-0 px-3">LV Verwaltung</a>
<core-searchbar :searchoptions="searchbaroptions" :searchfunction=searchfunction class="searchbar w-100"></core-searchbar>
</header>
<div class="container-fluid overflow-hidden">
<div class="row h-100">
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
<div class="offcanvas-header justify-content-end px-1 d-md-none">
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
</div>
<stv-verband :preselectedKey="selectedStudiengang" :endpoint="endpoint" @select-verband="onSelectVerband" class="col" style="height:0%"></stv-verband>
<stv-studiensemester v-model:studiensemester-kurzbz="selectedStudiensemester" @update:studiensemester-kurzbz="studiensemesterChanged"></stv-studiensemester>
</nav>
<main class="col-md-8 ms-sm-auto col-lg-9 col-xl-10">
<vertical-split>
<template #top>
<lv-table ref="lvTable"
v-model:selected="selected"
@row-clicked="handleRowClicked"
:filter="filter"
>
<template #filterzuruecksetzen v-if="filter.activeFilter === 'employee'">
<button type="button"
class="btn btn-outline-secondary btn-action"
title="Mitarbeiter Filter entfernen"
@click="resetEmployeeFilter">
<i class="fa fa-xmark"></i>
</button>
</template>
</lv-table>
</template>
<template #bottom>
<lv-tabs ref="details" :lv="selected"></lv-tabs>
</template>
</vertical-split>
</main>
</div>
</div>
</div>`
};
@@ -0,0 +1,278 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import CoreForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import ApiLektor from "../../../api/lehrveranstaltung/lektor.js";
export default{
name: "LVLektorDaten",
components: {
CoreFilterCmpt,
CoreForm,
FormInput
},
props: {
lehreinheit_id: Number,
mitarbeiter_uid: String
},
emits: [
'changedLektor',
'changedCosts',
],
inject: {
dropdowns: {
from: 'dropdowns'
}
},
data() {
return{
original: null,
data: null,
changed: {},
internal_mitarbeiter_uid: null,
filteredLektor: [],
}
},
computed: {
changedLength() {
return Object.keys(this.changed).length;
},
berechneteGesamtkosten() {
if (!this.data) return 0;
const stunden = Number(this.data.semesterstunden) || 0;
const stundensatz = Number(this.data.stundensatz) || 0;
return (stunden * stundensatz).toFixed(2);
}
},
watch: {
lehreinheit_id:
{
deep: true,
handler(newVal, oldVal) {
this.data = null;
this.original = null;
this.internal_mitarbeiter_uid = null;
}
},
mitarbeiter_uid:
{
deep: true,
handler(newVal, oldVal) {
this.internal_mitarbeiter_uid = newVal;
if (newVal === null)
this.data = null;
else if (newVal !== undefined && this.lehreinheit_id !== undefined)
this.getLektorData();
}
},
data: {
handler(newValue) {
if (newValue === null)
{
this.changed = {}
return
}
let changed = {};
let keys = Object.keys(this.original);
for (let key of keys)
{
if (this.original[key] !== newValue[key])
changed[key] = newValue[key];
}
this.changed = changed;
},
deep: true
},
},
methods: {
getLektorData()
{
if (!this.lehreinheit_id || !this.internal_mitarbeiter_uid)
return;
return this.$api.call(ApiLektor.getLektorDaten(this.lehreinheit_id, this.internal_mitarbeiter_uid))
.then(result => {
this.data = result.data;
this.original = { ...this.data };
})
.catch(this.$fhcAlert.handleSystemError);
},
updateDaten()
{
if (!this.changedLength)
return;
if (this.changed.mitarbeiter_uid && this.changed.mitarbeiter_uid.uid)
{
this.changed.mitarbeiter_uid = this.changed.mitarbeiter_uid.uid;
}
this.$refs.form.clearValidation();
let updatedData = {
lehreinheit_id: this.lehreinheit_id,
mitarbeiter_uid: this.mitarbeiter_uid,
formData: this.changed
}
this.$refs.form.call(ApiLektor.update(updatedData))
.then(result => {
let warning = result.data?.retval?.warning;
if (warning)
this.$fhcAlert.alertWarning(warning)
this.original = {...this.data};
if (this.changed.mitarbeiter_uid)
{
this.$emit('changedLektor', this.changed.mitarbeiter_uid);
}
if (this.changed.semesterstunden || this.changed.stundensatz)
{
this.$emit('changedCosts');
}
this.changed = {};
})
.catch(this.$fhcAlert.handleSystemError);
},
searchLektor(event)
{
const query = event.query.toLowerCase().trim();
this.filteredLektor = this.dropdowns.lektor_array.filter(lektor => {
const fullName = `${lektor.vorname.toLowerCase()} ${lektor.nachname.toLowerCase()}`;
const reverseFullName = `${lektor.nachname.toLowerCase()} ${lektor.vorname.toLowerCase()}`;
return fullName.includes(query) || reverseFullName.includes(query) || lektor.uid.toLowerCase().includes(query);
}).map(lektor => ({
label: `${lektor.nachname} ${lektor.vorname} (${lektor.uid})`,
uid: lektor.uid
}));
},
},
created() {
this.getLektorData()
},
template: `
<core-form ref="form" @submit.prevent="updateDaten">
<div class="position-sticky top-0 z-1">
<button type="submit" class="btn btn-primary position-absolute top-0 end-0" :disabled="!changedLength">{{$p.t('ui', 'speichern')}}</button>
</div>
<fieldset class="overflow-hidden">
<legend>{{$p.t('lehre', 'daten')}}</legend>
<template v-if="data">
<div class="row align-items-start mb-3">
<form-input
:label="$p.t('lehre', 'lehrfunktion')"
type="select"
container-class="col-3"
v-model="data.lehrfunktion_kurzbz"
name="lehrfunktion_kurzbz"
>
<option
v-for="lehrfunktion in dropdowns.lehrfunktion_array"
:value="lehrfunktion.lehrfunktion_kurzbz"
>
{{ lehrfunktion.lehrfunktion_kurzbz }}
</option>
</form-input>
<form-input
type="autocomplete"
:label="$p.t('lehre', 'lektor')"
:disabled="data.vertrag_id !== null"
:suggestions="filteredLektor"
placeholder="Mitarbeiter hinzufügen"
v-model="data.mitarbeiter_uid"
field="label"
container-class="col-3"
dropdown
@complete="searchLektor"
name="lektorautocomplete"
></form-input>
<form-input
:label="$p.t('lehre', 'anmerkung')"
type="text"
container-class="col-6"
v-model="data.anmerkung"
name="anmerkung"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'las')"
type="number"
min="0"
step="0.01"
container-class="col-3"
:disabled="data.vertrag?.vertragsstatus_kurzbz === 'akzeptiert'"
v-model="data.semesterstunden"
name="semesterstunden"
>
</form-input>
<form-input
:label="$p.t('lehre', 'planstunden')"
type="number"
min="0"
step="0.01"
container-class="col-3"
v-model="data.planstunden"
name="planstunden"
>
</form-input>
</div>
<div class="row mb-3 d-flex align-items-end">
<form-input
:label="data.default_stundensatz !== null
? $p.t('lehre', 'stundensatz') + ' (' + $p.t('lehre', 'default') + ': ' + data.default_stundensatz + ')'
: $p.t('lehre', 'stundensatz')"
type="number"
min="0"
step="0.01"
container-class="col-3"
v-model="data.stundensatz"
:disabled="data.vertrag?.vertragsstatus_kurzbz === 'akzeptiert'"
name="stundensatz"
>
</form-input>
<form-input
:label="$p.t('lehre', 'bismelden')"
type="checkbox"
container-class="col-3"
v-model="data.bismelden"
name="bismelden"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'gesamtkosten')"
type="number"
name="gesamtkosten"
container-class="col-3"
readonly
v-model="berechneteGesamtkosten"
:style="{ color: berechneteGesamtkosten <= 0 ? 'red' : 'black' }"
>
</form-input>
</div>
</template>
</fieldset>
</core-form>
`
};
@@ -0,0 +1,223 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import FormForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import ApiLektor from "../../../api/lehrveranstaltung/lektor.js";
export default{
name: "LVLektorTable",
components: {
CoreFilterCmpt,
FormForm,
FormInput
},
props: {
lehreinheit_id: Number,
selected: String
},
inject: {
dropdowns: {
from: 'dropdowns'
},
showLVPlanLektorDel: {
from: 'permissionLektorEntfernen',
default: false
},
},
emits: ['update:selected'],
data() {
return {
tabulatorEvents: [
{
event: 'rowSelectionChanged',
handler: this.lektorSelected
}
],
showAutocomplete: false,
filteredLektor: [],
selectedLektor: ''
}
},
computed: {
tabulatorOptions() {
return {
ajaxURL: 'dummy',
ajaxRequestFunc: () => this.$api.call(ApiLektor.getByLehreinheit(this.lehreinheit_id)),
ajaxResponse: (url, params, response) => { return response.data || [] },
columns:[
{title: this.$p.t('person', 'nachname'), field:"nachname"},
{title: this.$p.t('person', 'vorname'), field:"vorname"},
{title: this.$p.t('person', 'uid'), field:"mitarbeiter_uid"},
{title: this.$p.t('lehre', 'lehreinheit_id'), field:"lehreinheit_id"},
{
title: this.$p.t('lehre', 'verplant'),
field:"verplant",
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
}
},
{
title: this.$p.t('global', 'actions'), field: 'actions',
minWidth: 150,
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
let button = document.createElement('button');
container.className = "d-flex gap-2";
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-xmark"></i>';
button.title = this.$p.t('ui', 'loeschen');
button.addEventListener('click', (event) => {
event.stopPropagation();
this.deletePerson(cell.getData().mitarbeiter_uid, cell.getData().lehreinheit_id);
});
container.append(button);
if (this.showLVPlanLektorDel)
{
button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-calendar-xmark"></i>';
button.disabled = !cell.getData().verplant;
button.title = this.$p.t('lehre', 'auslvplanentfernen');
button.addEventListener('click', (event) => {
event.stopPropagation();
this.deleteLVPlan(cell.getData().mitarbeiter_uid, cell.getData().lehreinheit_id)
});
container.append(button);
}
return container;
},
frozen: true
},
],
layout: 'fitDataFill',
height: 'auto',
selectable: true,
selectableRangeMode: 'click',
selectableRows:1,
persistenceID: 'lehrveranstaltungen_lektor_table_2025_05_27_v1',
}},
},
mounted(){
},
watch: {
lehreinheit_id() {
this.$refs.table.tabulator.setData('api/frontend/v1/lv/lektor/getLektorenByLE/' + encodeURIComponent(this.lehreinheit_id));
},
},
methods:{
lektorSelected(data)
{
if (data.length > 0)
{
let mitarbeiter_uid = data[0].mitarbeiter_uid;
this.$emit('update:selected', mitarbeiter_uid);
}
else
{
this.$emit('update:selected', null);
}
},
reload() {
this.$refs.table.reloadTable();
},
deleteLVPlan(uid, lehreinheit_id)
{
let deleteData = {
'mitarbeiter_uid': uid,
'lehreinheit_id': lehreinheit_id,
}
this.$api.call(ApiLektor.deleteFromLVPlan(deleteData))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
this.reload();
})
},
deletePerson(uid, lehreinheit_id)
{
let deleteData = {
'mitarbeiter_uid': uid,
'lehreinheit_id': lehreinheit_id,
}
this.$api.call(ApiLektor.deletePerson(deleteData))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
this.reload();
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
})
},
searchLektor(event)
{
const query = event.query.toLowerCase().trim();
this.filteredLektor = this.dropdowns.lektor_array.filter(lektor => {
const fullName = `${lektor.vorname.toLowerCase()} ${lektor.nachname.toLowerCase()}`;
const reverseFullName = `${lektor.nachname.toLowerCase()} ${lektor.vorname.toLowerCase()}`;
return fullName.includes(query) || reverseFullName.includes(query) || lektor.uid.toLowerCase().includes(query);
}).map(lektor => ({
label: `${lektor.nachname} ${lektor.vorname} (${lektor.uid})`,
uid: lektor.uid
}));
},
addLektor()
{
let newData = {
'mitarbeiter_uid': this.selectedLektor.uid,
'lehreinheit_id': this.lehreinheit_id
}
this.$api.call(ApiLektor.add(newData))
.then(result => {
this.reload()
this.selectedLektor = ''
})
.catch(this.$fhcAlert.handleSystemError);
},
},
template: `
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
reload
:new-btn-label="$p.t('lehre', 'addLektor')"
new-btn-show
@click:new="showAutocomplete = !showAutocomplete"
>
<template #search> <!--TODO (david) Slot prüfen -->
<form-input
v-if="showAutocomplete"
type="autocomplete"
:suggestions="filteredLektor"
:placeholder="$p.t('lehre', 'addLektor')"
v-model="selectedLektor"
field="label"
@item-select="addLektor"
@complete="searchLektor"
></form-input>
</template>
</core-filter-cmpt>
`
};
@@ -0,0 +1,167 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import CoreForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import ApiVertrag from "../../../api/lehrveranstaltung/vertrag.js";
export default{
name: "LVLektorVertrag",
components: {
CoreFilterCmpt,
CoreForm,
FormInput
},
emits: [
'canceledVertrag'
],
props: {
lehreinheit_id: Number,
mitarbeiter_uid: String
},
inject: {
dropdowns: {
from: 'dropdowns'
},
showVertragsdetails: {
from: 'configShowVertragsdetails',
default: false
}
},
data() {
return{
data: null,
internal_mitarbeiter_uid: null,
}
},
watch: {
lehreinheit_id:
{
deep: true,
handler(newVal, oldVal) {
this.data = null;
this.internal_mitarbeiter_uid = null;
}
},
mitarbeiter_uid:
{
deep: true,
handler(newVal, oldVal) {
this.internal_mitarbeiter_uid = newVal;
if (newVal === null)
this.data = null;
else if (newVal !== undefined && this.lehreinheit_id !== undefined)
this.getLektorVertrag();
}
},
},
computed: {
vertragsstatus() {
if (!this.data || !this.data.vertrag) return;
const betragVertrag = Number(this.data.vertrag.betrag) || 0;
const stundenVertrag = Number(this.data.vertrag.vertragsstunden) || 0;
const semStunden = Number(this.data.semesterstunden) || 0;
const stundensatz = Number(this.data.stundensatz) || 0;
const kostenAktuell = semStunden * stundensatz;
return (stundenVertrag !== semStunden || betragVertrag !== kostenAktuell) ? 'Geändert' : (this.data.vertrag.vertragsstatus || '');
},
},
methods: {
getLektorVertrag ()
{
if (this.showVertragsdetails === false)
return;
if (!this.lehreinheit_id || !this.internal_mitarbeiter_uid)
return;
this.$api.call(ApiVertrag.getByLeEmp(this.lehreinheit_id, this.internal_mitarbeiter_uid))
.then(result => {
this.data = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
async cancelVertrag()
{
if (await this.$fhcAlert.confirm({
message: this.$p.t('lehre', 'vertragConfirm'),
acceptLabel: this.$p.t('ui', 'ja').charAt(0).toUpperCase() + this.$p.t('ui', 'ja').slice(1),
acceptClass: 'btn btn-danger'}) === false)
return;
let needUpdate = {
vertrag_id: this.data.vertrag.vertrag_id,
mitarbeiter_uid: this.mitarbeiter_uid,
lehreinheit_id: this.lehreinheit_id
}
this.$api.call(ApiVertrag.cancelByLeEmp(needUpdate))
.then(result => {
this.data.vertrag = null;
this.$emit('canceledVertrag');
})
.catch(this.$fhcAlert.handleSystemError);
},
},
template: `
<core-form ref="form">
<fieldset class="overflow-hidden" v-if="showVertragsdetails">
<legend> {{$p.t('lehre', 'vertragsdetails')}}
{{ data === null ? ' Noch kein Vertrag' : '' }}
</legend>
<template v-if="data?.vertrag">
<div class="row align-items-end mb-3">
<form-input
:label="$p.t('lehre', 'vertragsstatus')"
type="text"
readonly
container-class="col-3"
v-model="vertragsstatus"
:style="{fontWeight: vertragsstatus === 'Geändert' ? 'bold' : 'normal'}"
name="vertragsstatus"
/>
<div class="col-3 d-flex align-items-end">
<button
type="button"
class="btn btn-outline-secondary w-100"
@click="cancelVertrag"
:title="$p.t('lehre', 'cancelvertrag')"
>
<i class="fa-solid fa-ban"></i>
</button>
</div>
</div>
{{$p.t('lehre', 'vertragurfassung')}}
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'semesterstunden')"
type="text"
container-class="col-3"
readonly
v-model="data.vertrag.vertragsstunden"
name="vertragsstunden"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
:label="$p.t('lehre', 'studiensemester')"
type="text"
container-class="col-3"
readonly
v-model="data.vertrag.vertragsstunden_studiensemester_kurzbz"
name="vertragsstunden_studiensemester_kurzbz"
>
</form-input>
</div>
</template>
</fieldset>
</core-form>
`
};
@@ -0,0 +1,696 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import BsModal from "../../Bootstrap/Modal.js";
import DetailsForm from "../Details/Form.js";
import CoreTag from '../../Tag/Tag.js';
import { tagHeaderFilter } from '../../../../js/tabulator/filters/extendedHeaderFilter.js';
import { extendedHeaderFilter } from "../../../../js/tabulator/filters/extendedHeaderFilter.js";
import ApiLv from "../../../api/lehrveranstaltung.js";
import ApiTag from "../../../api/lehrveranstaltung/tag.js";
import ApiLehreinheit from "../../../api/lehrveranstaltung/lehreinheit.js";
export default {
name: "LVVerwaltungTable",
components: {
CoreFilterCmpt,
BsModal,
DetailsForm,
CoreTag
},
props: {
selected: Object,
filter: {
type: Object,
default: () => ({})
}
},
inject: {
currentSemester: {
from: 'currentSemester'
},
lehreinheitAnmerkungDefault: {
from: 'lehreinheitAnmerkungDefault',
default: ''
},
lehreinheitRaumtypDefault: {
from: 'lehreinheitRaumtypDefault',
default: ''
},
lehreinheitRaumtypAlternativeDefault: {
from: 'lehreinheitRaumtypAlternativeDefault',
default: ''
}
},
emits: [
'update:selected',
'row-clicked'
],
watch: {
filter: {
handler() {
if (this.$refs.table && this.$refs.table.tabulator)
{
this.expanded = [];
this.reload();
}
},
deep: true,
},
currentSemester: {
handler(newVal)
{
this.lv_info_default.studiensemester_kurzbz = newVal
this.lv_info = false;
}
}
},
data() {
return {
expanded: [],
selectedColumnValues: [],
tagEndpoint: ApiTag,
tabulatorEvents: [
{
event: 'rowSelectionChanged',
handler: this.rowSelectionChanged
},
{
event: 'dataProcessed',
handler: (data) => {
this.reexpandRows()
this.$emit('update:selected', {})
}
},
{
event: 'dataTreeRowExpanded',
handler: (data) => {
this.getExpandedRows()
}
},
{
event: 'dataTreeRowCollapsed',
handler: (data) => {
this.getExpandedRows()
}
}
],
formData: {},
lv_info: false,
lv_info_default: {
stundenblockung: 2,
wochenrythmus: 1,
studiensemester_kurzbz: this.currentSemester,
lehrform_kurzbz: 'UE',
anmerkung: this.lehreinheitAnmerkungDefault.replace("'","\'"),
raumtyp: this.lehreinheitRaumtypDefault,
raumtypalternativ: this.lehreinheitRaumtypAlternativeDefault,
lehrfach_id: ''
}
}
},
computed: {
tabulatorOptions() {
return {
index: 'uniqueindex',
ajaxURL: 'dummy',
ajaxRequestFunc: async (url, config, params) => {
let realUrl = this.buildApiUrl();
if (realUrl)
return this.$api.call(ApiLv.getTable(this.buildApiUrl()));
},
ajaxResponse: (url, params, response) => { return response?.data || [] },
dataTree: true,
initialSort:[
{column: 'lv_bezeichnung', dir: 'desc'},
],
dataTreeChildIndent: 20,
dataTreeElementColumn: "lv_kurzbz",
dataTreeStartExpanded: false,
dataTreeCollapseElement: '<i class="fa-solid fa-caret-down"></i>',
dataTreeExpandElement: '<i class="fa-solid fa-caret-right"></i>',
columnDefaults: {
tooltip: true,
headerFilter: "input",
headerFilterFunc: extendedHeaderFilter,
},
layout: 'fitDataStretch',
persistenceID: 'lehrveranstaltungen_2025_07_31_v1',
selectableRowsRangeMode: 'click',
selectableRows: true,
rowContextMenu: (component, e) => {
if (e.getData()?.lehreinheit_id === undefined)
return;
return [
{
label: "LV-Teil kopieren",
menu: [
{
label: "Alles",
action: (e, row) =>
{
this.copyLehreinheit(row, "alle");
},
},
{
label: "Nur LV-Teil",
action: (e, row) =>
{
this.copyLehreinheit(row, "lvteil");
},
},
{
label: "Nur mit Gruppen",
action: (e, row) =>
{
this.copyLehreinheit(row, "gruppen");
},
},
{
label: "Nur mit Lehrenden",
action: (e, row) =>
{
this.copyLehreinheit(row, "lektoren");
},
},
],
},
{
label: "Entfernen",
action: (e, row) => {
this.deleteLehreinheit(row)
},
},
];
},
columns: [
{
title: this.$p.t('lehre', 'kurzbz'),
field: "lv_kurzbz",
headerFilterFuncParams: {field: 'lv_kurzbz'},
headerFilter: true,
formatter: (cell, formatterParams) => {
const rowData = cell.getRow().getData();
const iconKey = (rowData.lehrtyp_kurzbz || '').toLowerCase();
const lvkurzbz = (cell.getValue()).toUpperCase();
const parentspan = document.createElement('span');
const span = document.createElement('span');
span.classList.add('lv_table_icon', `icon-${iconKey}`);
span.title = iconKey || 'LV-Teil';
parentspan.appendChild(span);
parentspan.appendChild(document.createTextNode(` ${lvkurzbz}`));
return parentspan
},
cellClick: (e, cell) => {
cell.getRow().treeToggle();
}
},
{
title: 'Tags',
field: 'tags',
tooltip: false,
headerFilter: "input",
headerFilterFunc: tagHeaderFilter,
headerFilterFuncParams: {field: 'tags'},
formatter: (cell) => {
let tags = cell.getValue();
if (!tags) return;
let container = document.createElement('div');
container.className = "d-flex gap-1";
let parsedTags = JSON.parse(tags);
let maxVisibleTags = 2;
const rowData = cell.getRow().getData();
if (rowData._tagExpanded === undefined) {
rowData._tagExpanded = false;
}
const renderTags = () => {
container.innerHTML = '';
parsedTags = parsedTags.filter(item => item !== null);
parsedTags.sort((a, b) => {
let adone = a.done ? 1 : 0;
let bbone = b.done ? 1 : 0;
if (adone !== bbone)
{
return adone - bbone;
}
return b.id - a.id;
});
const tagsToShow = rowData._tagExpanded ? parsedTags : parsedTags.slice(0, maxVisibleTags);
tagsToShow.forEach(tag => {
if (!tag) return;
let tagElement = document.createElement('span');
tagElement.innerText = tag.beschreibung;
tagElement.title = tag.notiz;
tagElement.className = "tag " + tag.style;
if (tag.done) tagElement.className += " tag_done";
tagElement.addEventListener('click', (event) => {
event.stopPropagation();
event.preventDefault();
this.$refs.tagComponent.editTag(tag.id);
});
container.appendChild(tagElement);
});
if (parsedTags.length > maxVisibleTags) {
let toggle = document.createElement('button');
toggle.innerText = (rowData._tagExpanded ? '- ' : '+ ') + (parsedTags.length - maxVisibleTags);
toggle.className = "display_all";
toggle.title = rowData._tagExpanded ? "Tags ausblenden" : "Tags einblenden";
toggle.addEventListener('click', () => {
rowData._tagExpanded = !rowData._tagExpanded;
renderTags();
});
container.appendChild(toggle);
}
};
renderTags();
return container;
},
width: 150,
},
{
title: this.$p.t('lehre', 'lehrveranstaltung_id'),
field: "lehrveranstaltung_id",
headerFilterFuncParams: {field: 'lehrveranstaltung_id'},
headerFilter: true,
visible: false
},
{title: this.$p.t('ui', 'bezeichnung'), field: "lv_bezeichnung", headerFilter: true, headerFilterFuncParams: {field: 'lv_bezeichnung'}},
{title: this.$p.t('lehre', 'bezeichnungeng'), field: "lv_bezeichnung_english", headerFilter: true, headerFilterFuncParams: {field: 'lv_bezeichnung_english'}, visible: false},
{
title: this.$p.t('lehre', 'studiengangskennzahlLehre'),
field: "lv_studiengang_kz",
headerFilter: true,
headerFilterFuncParams: {field: 'lv_studiengang_kz'},
visible: false
},
{title: this.$p.t('lehre', 'studiengang'), field: "studiengang", headerFilter: true, headerFilterFuncParams: {field: 'studiengang'}, visible: false},
{title: this.$p.t('lehre', 'semester'), field: "semester", headerFilter: true, headerFilterFuncParams: {field: 'semester'}},
{title: this.$p.t('global', 'sprache'), field: "sprache", headerFilter: true, headerFilterFuncParams: {field: 'sprache'}, visible: false},
{title: this.$p.t('lehre', 'ects'), field: "lv_ects", headerFilter: true, headerFilterFuncParams: {field: 'lv_ects'}, visible: false},
{title: this.$p.t('lehre', 'semesterstunden'), field: "semesterstunden", headerFilter: true, headerFilterFuncParams: {field: 'semesterstunden'}, visible: false},
{title: this.$p.t('global', 'anmerkung'), field: "anmerkung", headerFilter: true, headerFilterFuncParams: {field: 'anmerkung'}, visible: false},
{title: this.$p.t('lehre', 'lehre'), field: "lehre", headerFilter: true, headerFilterFuncParams: {field: 'lehre'}, formatter: (cell) => cell.getValue() ? this.toUpperCase(this.$p.t('ui', 'ja')) : this.toUpperCase(this.$p.t('ui', 'nein')), visible: false},
{title: this.$p.t('person', 'aktiv'), field: "aktiv", headerFilter: true, headerFilterFuncParams: {field: 'aktiv'}, formatter: (cell) => cell.getValue() ? this.toUpperCase(this.$p.t('ui', 'ja')) : this.toUpperCase(this.$p.t('ui', 'nein')), visible: false},
{title: this.$p.t('lehre', 'organisationsform'), field: "orgform_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'orgform_kurzbz'}},
{title: this.$p.t('ui', 'studienplan_id'), field: "studienplan_id", headerFilter: true, headerFilterFuncParams: {field: 'studienplan_id'}, visible: false},
{title: this.$p.t('lehre', 'studienplan'), field: "studienplan_bezeichnung", headerFilter: true, headerFilterFuncParams: {field: 'studienplan_bezeichnung'}, visible: false},
{title: this.$p.t('lehre', 'lehrtyp'), field: "lehrtyp_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'lehrtyp_kurzbz'}, visible: false},
{title: this.$p.t('lehre', 'lehrform'), field: "lehrform_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'lehrform_kurzbz'}},
{title: this.$p.t('lehre', 'leplanstunden'), field: "le_planstunden", headerFilter: true, headerFilterFuncParams: {field: 'le_planstunden'}, visible: false},
{title: this.$p.t('lehre', 'lehreinheit_id'), field: "lehreinheit_id", headerFilter: true, headerFilterFuncParams: {field: 'lehreinheit_id'}, visible: false},
{title: this.$p.t('lehre', 'studiensemester'), field: "studiensemester_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'studiensemester_kurzbz'}, visible: false},
{title: this.$p.t('lehre', 'unr'), field: "unr", headerFilter: true, headerFilterFuncParams: {field: 'unr'}, visible: false},
{title: this.$p.t('lehre', 'fachbereich'), field: "fachbereich", headerFilter: true, headerFilterFuncParams: {field: 'fachbereich'}, visible: false},
{title: this.$p.t('lehre', 'stundenblockung'), field: "stundenblockung", headerFilter: true, headerFilterFuncParams: {field: 'stundenblockung'}, visible: false},
{title: this.$p.t('lehre', 'wochenrhythmus'), field: "wochenrythmus", headerFilter: true, headerFilterFuncParams: {field: 'wochenrythmus'}, visible: false},
{title: this.$p.t('lehre', 'startkw'), field: "start_kw", headerFilter: true, headerFilterFuncParams: {field: 'startkw'}, visible: false},
{title: this.$p.t('lehre', 'raumtyp'), field: "raumtyp", headerFilter: true, headerFilterFuncParams: {field: 'raumtyp'}, visible: false},
{title: this.$p.t('lehre', 'raumtypalternativ'), field: "raumtypalternativ", headerFilter: true, headerFilterFuncParams: {field: 'raumtypalternativ'}, visible: false},
{title: this.$p.t('lehre', 'gruppen'), field: "gruppen", headerFilter: true, headerFilterFuncParams: {field: 'gruppen'}},
{title: this.$p.t('lehre', 'lehrende'), field: "lektoren", headerFilter: true, headerFilterFuncParams: {field: ['lektoren', 'vorname', 'nachname']}},
],
}
}
},
mounted() {
if (this.shouldAutoLoad())
{
this.reload();
}
},
methods: {
shouldAutoLoad() {
return this.filter && this.filter.activeFilter;
},
toUpperCase(str) {
if (!str)
return '';
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase()
},
async reload()
{
if (this.shouldAutoLoad)
{
this.$refs.table.reloadTable();
}
},
rowSelectionChanged(data) {
this.selectedRows = this.$refs.table.tabulator.getSelectedRows();
this.selectedColumnValues = this.selectedRows.filter(row => row.getData().lehreinheit_id !== undefined && row.getData().lehreinheit_id).map(row => row.getData().lehreinheit_id);
if (data[0]?.lehreinheit_id !== undefined && this.selectedColumnValues.length === 1)
{
this.$emit('update:selected', [data[0]]);
this.lv_info = false
}
else if (data[0]?.lehrveranstaltung_id)
{
this.$emit('update:selected', {});
this.getLVInfos(data[0]);
}
},
getLVInfos(data)
{
this.$api.call(ApiLv.getByLV(data.lehrveranstaltung_id))
.then(result => {
if (result.data?.lehrfach_id === undefined
&& Array.isArray(result.data?.lehrfaecher))
{
const match = result.data.lehrfaecher?.find(
lf => lf.lehrfach?.startsWith(result.data.lvbezeichnung)
);
if (match)
{
result.data.lehrfach_id = match.lehrveranstaltung_id;
}
}
this.lv_info = {...this.lv_info_default, ...result.data};
})
.catch(this.$fhcAlert.handleSystemError);
},
buildApiUrl()
{
if (this.filter.activeFilter === 'employee' && this.filter.emp)
{
const { emp, stg, studiensemester_kurzbz } = this.filter;
return this.$api.getUri(ApiLv.getByEmp(studiensemester_kurzbz, emp, stg));
}
if (this.filter.activeFilter === 'verband' && this.filter.stg)
{
const { stg, semester, studiensemester_kurzbz } = this.filter;
return this.$api.getUri(ApiLv.getByStg(studiensemester_kurzbz, stg, semester));
}
},
resetEmployeeFilter()
{
const newFilter = { ...this.filter };
delete newFilter.emp;
newFilter.activeFilter = 'verband';
},
showLehreinheitModal() {
this.resetModal();
this.$refs.lehreinheitModal.show();
},
addNewLehreinheit()
{
return this.$api.call(ApiLehreinheit.add(this.lv_info))
.then(result => {
this.$refs.lehreinheitModal.hide()
this.reload()
})
.catch(this.$fhcAlert.handleSystemError);
},
resetModal()
{
this.lv_info_default = {
stundenblockung: 2,
wochenrythmus: 1,
studiensemester_kurzbz: this.currentSemester,
lehrform_kurzbz: 'UE',
anmerkung: this.lehreinheitAnmerkungDefault.replace("'","\'"),
raumtyp: this.lehreinheitRaumtypDefault,
raumtypalternativ: this.lehreinheitRaumtypAlternativeDefault,
lehrfach_id: ''
}
},
addedTag(addedTag)
{
const table = this.$refs.table.tabulator;
this.selectedRows.forEach(row =>
{
if (Array.isArray(addedTag.response))
{
addedTag.response.forEach(tag => {
const targetRow = this.allRows.find(row => row.getData().lehreinheit_id === tag.lehreinheit_id);
if (targetRow)
{
const rowData = targetRow.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
const tagExists = tags.some((t) => t.id === tag.id);
if (!tagExists)
{
addedTag.id = tag.id;
tags.unshift({ ...addedTag });
targetRow.update({ tags: JSON.stringify(tags) });
targetRow.reformat();
}
}
});
}
});
},
deletedTag(deletedTag) {
const targetRow = this.allRows.find(row => {
const rowData = row.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
return tags.some(tag => tag.id === deletedTag);
});
if (targetRow) {
const rowData = targetRow.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
const filteredTags = tags.filter(t => t.id !== deletedTag);
const updatedTags = JSON.stringify(filteredTags);
if (updatedTags !== rowData.tags) {
targetRow.update({
tags: updatedTags
});
targetRow.reformat();
}
}
},
updatedTag(updatedTag) {
const targetRow = this.allRows.find(row => {
const rowData = row.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
return tags.some(t => t?.id === updatedTag.id);
});
if (targetRow)
{
const rowData = targetRow.getData();
let tags = [];
try {
tags = JSON.parse(rowData.tags || '[]');
} catch (e) {}
let changed = false;
const tagIndex = tags.findIndex(tag => tag?.id === updatedTag.id);
if (tagIndex !== -1) {
tags[tagIndex] = { ...updatedTag };
changed = true;
}
if (changed)
{
targetRow.update({
tags: JSON.stringify(tags),
});
targetRow.reformat();
}
}
},
async copyLehreinheit(row, art)
{
let data = {
lehreinheit_id: row.getData().lehreinheit_id,
art: art
}
return this.$api.call(ApiLehreinheit.copy(data))
.then(result => {
this.reload()
})
.catch(this.$fhcAlert.handleSystemError)
},
async getExpandedRows() {
this.expanded = [];
this.allRows.forEach(row => {
if (row.getTreeChildren().length > 0 && row.isTreeExpanded())
{
this.expanded.push(row.getData().uniqueindex);
}
});
},
reexpandRows() {
this.allRows = this.getAllRows(this.$refs.table.tabulator.getRows());
const matchingRows = this.allRows.filter(row =>
this.expanded.includes(row.getData().uniqueindex)
);
if (matchingRows.length === 0)
this.currentTreeLevel = 0;
matchingRows.forEach((row, index) => {
row._row.modules.dataTree.open = true;
if (index === matchingRows.length - 1)
{
row.treeExpand();
}
});
},
deleteLehreinheit(row)
{
let deleteData = {
lehreinheit_id: row.getData().lehreinheit_id,
}
return this.$api.call(ApiLehreinheit.delete(deleteData))
.then(result => {
this.reload()
})
.catch(this.$fhcAlert.handleSystemError);
},
getAllRows(rows)
{
let result = [];
rows.forEach(row =>
{
result.push(row);
let children = row.getTreeChildren();
if(children && children.length > 0)
{
result = result.concat(this.getAllRows(children));
}
});
return result;
},
resetTree() {
this.allRows.forEach(row => {
row._row.modules.dataTree.open = false;
});
let rootRows = this.$refs.table.tabulator.getRows(true);
var lastRow = rootRows[rootRows.length - 1];
lastRow?.treeCollapse(true)
this.currentTreeLevel = 0;
},
expandTree()
{
this.currentTreeLevel = (this.currentTreeLevel || 0) + 1;
let lastMatchingRow = null;
this.allRows.forEach(row => {
const level = row._row.modules.dataTree?.index ?? 0;
if (level === this.currentTreeLevel - 1 )
{
row._row.modules.dataTree.open = true;
if (row._row.data._children?.length > 0)
{
lastMatchingRow = row;
}
}
});
if (lastMatchingRow)
{
lastMatchingRow.treeExpand();
}
this.$refs.table.tabulator.redraw();
},
},
template: `
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
:reload=true
new-btn-label="LV-Teil hinzufügen"
new-btn-show
:new-btn-disabled="!lv_info"
@click:new="showLehreinheitModal">
<template #actions>
<core-tag ref="tagComponent"
:endpoint="tagEndpoint"
:values="selectedColumnValues"
@added="addedTag"
@deleted="deletedTag"
@updated="updatedTag"
zuordnung_typ="lehreinheit_id"
></core-tag>
<button @click="expandTree" class="btn btn-outline-secondary" type="button"><i class="fa-solid fa-maximize"></i></button>
<button @click="resetTree" class="btn btn-outline-secondary" type="button"><i id="togglegroup" class="fa-solid fa-minimize"></i></button>
</template>
<template #search>
<slot name="filterzuruecksetzen"></slot>
</template>
</core-filter-cmpt>
<bs-modal ref="lehreinheitModal" dialogClass="modal-xxl">
<template #title>
<p class="fw-bold mt-3">{{$p.t('lehre', 'newlehreinheit')}}</p>
</template>
<template v-if="lv_info">
<details-form :data="lv_info"/>
</template>
<template #footer>
<button type="button" class="btn btn-primary" @click="addNewLehreinheit">{{$p.t('ui', 'speichern')}}</button>
</template>
</bs-modal>
`
};
@@ -0,0 +1,61 @@
import FhcTabs from "../../Tabs.js";
import Setup from "../../../api/lehrveranstaltung/setup.js";
export default {
name: "LVVerwaltungTabs",
components: {
FhcTabs
},
data() {
return {
configLVTabs: {},
};
},
props: {
lv: Object
},
computed: {
config() {
if (!this.lv || !this.lv.length)
return {};
return this.configLVTabs;
}
},
methods: {
reload() {
if (this.$refs.tabs?.$refs?.current?.reload)
{
this.$refs.tabs.$refs.current.reload();
}
}
},
created() {
this.$api.call(Setup.getTabs())
.then(result => {
this.configLVTabs = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
template: `
<div class="stv-details h-100 pb-3 d-flex flex-column">
<div v-if="!lv?.length" class="justify-content-center d-flex h-100 align-items-center">
Bitte eine Lehreinheit auswählen!
</div>
<div v-else-if="configLVTabs" class="d-flex flex-column h-100 pb-3">
<fhc-tabs
v-if="lv.length === 1"
ref="tabs"
:modelValue="lv[0]"
:config="configLVTabs"
:default="$route.params.tab"
@changed="reload"
/>
</div>
<div v-else>
Loading...
</div>
</div>
`
};
@@ -0,0 +1,124 @@
import CoreForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import GruppenTable from '../Details/Gruppen.js';
import GruppenDirektTable from '../Details/Direktinskription.js';
import DetailsForm from '../Details/Form.js'
import ApiLehreinheit from "../../../api/lehrveranstaltung/lehreinheit.js";
export default {
name: "LVTabDetails",
components: {
CoreForm,
FormInput,
GruppenTable,
GruppenDirektTable,
DetailsForm
},
props: {
modelValue: Object,
config: {
type: Object,
default: {}
},
},
inject: {
dropdowns: {
from: 'dropdowns'
}
},
watch: {
modelValue(newValue)
{
this.updateLE(newValue)
},
data: {
handler(newValue) {
if (newValue === null)
{
this.changed = {}
return
}
let changed = {};
let keys = Object.keys(this.original);
for (let key of keys) {
if (this.original[key] !== newValue[key])
{
changed[key] = newValue[key];
}
}
this.changed = changed;
},
deep: true
}
},
data() {
return {
original: null,
data: null,
changed: {}
}
},
computed: {
changedLength() {
return Object.keys(this.changed).length;
}
},
methods: {
updateLE(le) {
if (le?.lehreinheit_id === undefined)
{
this.data = null;
return;
}
return this.$api.call(ApiLehreinheit.get(le.lehreinheit_id))
.then(result => {
this.data = result.data;
this.original = {...(this.original || {}), ...this.data};
})
.catch(this.$fhcAlert.handleSystemError);
},
save() {
if (!this.changedLength)
return;
this.$refs.form.clearValidation();
let updatedData = {
lehreinheit_id: this.modelValue.lehreinheit_id,
formData: this.changed
}
return this.$refs.form.call(ApiLehreinheit.update(updatedData))
.then(result => {
this.original = {...this.data};
this.changed = {};
this.$refs.form.setFeedback(true, result.data);
})
.catch(this.$fhcAlert.handleSystemError);
},
reload(){
this.updateLE(this.modelValue);
}
},
created() {
this.updateLE(this.modelValue);
},
template: `
<core-form ref="form" @submit.prevent="save">
<div class="position-sticky top-0 z-1">
<button type="submit" class="btn btn-primary position-absolute top-0 end-0" :disabled="!changedLength">{{$p.t('ui', 'speichern')}}</button>
</div>
<fieldset class="overflow-hidden">
<div class="core-header d-flex flex-column w-100 overflow-auto pb-3 gap-0">
<legend>{{ this.$p.t('lehre', 'lehreinheit') }}</legend>
<small v-if="data" v-html="data.lehreinheit_id" class="text-muted"></small>
</div>
<template v-if="data">
<details-form :data="data"/>
</template>
</fieldset>
</core-form>
`
};
@@ -0,0 +1,39 @@
import GruppenTable from '../Details/Gruppen.js';
import GruppenDirektTable from '../Details/Direktinskription.js';
export default {
name: "LVTabGruppen",
components: {
GruppenTable,
GruppenDirektTable,
},
props: {
modelValue: Object,
config: {
type: Object,
default: {}
},
},
inject: {
dropdowns: {
from: 'dropdowns'
}
},
template: `
<fieldset class="overflow-hidden">
<div class="row">
<div class="col-6">
<legend>{{this.$p.t('lehre', 'gruppen')}}</legend>
<gruppen-table ref="gruppen_table" :lehreinheit_id="modelValue.lehreinheit_id"></gruppen-table>
</div>
<div class="col-6">
<legend>{{this.$p.t('lehre', 'assignedPersons')}}</legend>
<gruppen-direkt-table ref="gruppen_direkt_table" :lehreinheit_id="modelValue.lehreinheit_id"></gruppen-direkt-table>
</div>
</div>
</fieldset>
`
};
@@ -0,0 +1,70 @@
import CoreForm from '../../Form/Form.js';
import FormInput from '../../Form/Input.js';
import LektorTable from '../Lektor/Table.js'
import LektorDaten from '../Lektor/Daten.js'
import LektorVertrag from '../Lektor/Vertrag.js'
export default {
name: "LVTabLektor",
components: {
CoreForm,
FormInput,
LektorTable,
LektorDaten,
LektorVertrag
},
props: {
modelValue: Object,
config: {
type: Object,
default: {}
},
},
data() {
return {
mitarbeiter_uid: null
}
},
methods: {
changedLektor(uid) {
const lektorTable = this.$refs.lektor_table;
const tabulator = lektorTable.$refs.table.tabulator;
const selectUID = () => {
let row = tabulator.getRows().find(r => r.getData().mitarbeiter_uid === uid);
if (row)
{
row.select();
}
tabulator.off('dataProcessed', selectUID);
};
tabulator.on('dataProcessed', selectUID);
lektorTable.reload();
},
changedCosts() {
this.$refs.lektor_vertrag?.getLektorVertrag();
},
canceledVertrag() {
this.$refs.lektor_daten?.getLektorData();
}
},
template: `
<fieldset class="overflow-hidden">
<div class="row">
<div class="col-5">
<legend>{{ $p.t('lehre', 'lektorInnen')}}</legend>
<lektor-table ref="lektor_table" :lehreinheit_id="modelValue.lehreinheit_id" v-model:selected="mitarbeiter_uid"></lektor-table>
</div>
<div class="col-5">
<lektor-daten ref="lektor_daten" :lehreinheit_id="modelValue.lehreinheit_id" :mitarbeiter_uid="mitarbeiter_uid" @changedLektor="changedLektor" @changedCosts="changedCosts"></lektor-daten>
</div>
</div>
<div class="row">
<div class="col-5">
</div>
<div class="col-5">
<lektor-vertrag ref="lektor_vertrag" :lehreinheit_id="modelValue.lehreinheit_id" :mitarbeiter_uid="mitarbeiter_uid" @canceledVertrag="canceledVertrag"></lektor-vertrag>
</div>
</div>
</fieldset>
`
};
@@ -0,0 +1,33 @@
import CoreNotiz from "../../Notiz/Notiz.js";
import ApiNotizLehreinheit from '../../../api/factory/notiz/lehreinheit.js';
export default {
name: "LVTabNotiz",
components: {
CoreNotiz
},
props: {
modelValue: Object
},
data() {
return {
endpoint: ApiNotizLehreinheit
};
},
template: `
<div class="stv-details-notizen h-100 pb-3">
<core-notiz
class="overflow-hidden"
:endpoint="endpoint"
ref="formc"
notiz-layout="popupModal"
type-id="lehreinheit_id"
:id="modelValue.lehreinheit_id"
show-document
show-tiny-mce
showErweitert
:visible-columns="['titel','text','verfasser','bearbeiter','dokumente']"
>
</core-notiz>
</div>
`
};
+13 -9
View File
@@ -57,7 +57,7 @@ export default {
init() {
if (!this.endpoint)
return;
this.endpoint.getTags()
this.$api.call(this.endpoint.getTags())
.then(response => response.data)
.then(response => {
this.tags = response
@@ -71,7 +71,7 @@ export default {
'id': tag_id
};
this.endpoint.getTag(getData)
this.$api.call(this.endpoint.getTag(getData))
.then(result => result.data)
.then(result => this.openModal(result))
},
@@ -86,6 +86,7 @@ export default {
this.tagData.updateamum = this.formatDateTime(item.updateamum)
this.tagData.bearbeiter = item.bearbeiter;
this.tagData.verfasser = item.verfasser;
this.tagData.readonly = item.readonly;
if (item && item.notiz_id)
{
@@ -118,7 +119,7 @@ export default {
{
postData.id = this.selectedTagId;
this.tagData.id = this.selectedTagId;
this.endpoint.updateTag(postData);
this.$api.call(this.endpoint.updateTag(postData));
this.$emit("updated", this.tagData);
this.$refs.tagModal.hide();
}
@@ -130,7 +131,7 @@ export default {
return;
}
this.endpoint.addTag(postData)
this.$api.call(this.endpoint.addTag(postData))
.then(response => response.data)
.then(response => {
if (typeof response === 'number') {
@@ -154,9 +155,10 @@ export default {
let postData = {
id: this.selectedTagId,
done: !this.tagData.done
done: !this.tagData.done,
notiz: this.tagData.notiz,
}
this.endpoint.doneTag(postData)
this.$api.call(this.endpoint.doneTag(postData))
this.$emit("updated", this.tagData);
this.$refs.tagModal.hide();
},
@@ -165,7 +167,7 @@ export default {
let postData = {
id: this.selectedTagId
}
this.endpoint.deleteTag(postData)
this.$api.call(this.endpoint.deleteTag(postData))
this.$emit("deleted", this.selectedTagId)
this.$refs.tagModal.hide();
},
@@ -182,7 +184,8 @@ export default {
verfasser: "",
updateamum: "",
bearbeiter: "",
response: ""
response: "",
readonly: false
};
this.selectedTagId = null;
this.mode = "create";
@@ -230,6 +233,7 @@ export default {
v-model="tagData.notiz"
type="textarea"
field="notiz"
:readonly="tagData.readonly"
placeholder="Notiz..."
></form-input>
<div class="modificationdate">
@@ -243,7 +247,7 @@ export default {
</div>
</div>
</template>
<template #footer>
<template #footer v-if="!tagData.readonly">
<div class="d-flex justify-content-between w-100">
<div>
<button
+1 -1
View File
@@ -706,7 +706,7 @@ export const CoreFilterCmpt = {
</button>
<span v-if="$slots.actions && tabulatorHasSelector && useSelectionSpan">
<span v-if="countOnly">{{ selectedData.length }} ausgewählt</span>
<span v-else> Mit {{ selectedData.length }} ausgewählten:</span>
<span v-else id="selected-info-text"> Mit {{ selectedData.length }} ausgewählten:</span>
</span>
<slot name="actions" v-bind="{selected: tabulatorHasSelector ? selectedData : []}"></slot>
<slot name="search"></slot>
@@ -39,8 +39,19 @@ function parseFilterExpression(expression)
return collections;
}
export function extendedHeaderFilter(headerValue, rowValue)
export function extendedHeaderFilter(headerValue, rowValue, rowData, filterParams)
{
const fields = Array.isArray(filterParams?.field)
? filterParams.field
: [filterParams?.field];
if (fields.length > 1 && rowData)
{
rowValue = fields
.map(f => rowData[f] ?? '')
.filter(Boolean)
.join(' ');
}
if (typeof headerValue === 'boolean')
{
return rowValue === headerValue;
@@ -48,52 +59,79 @@ export function extendedHeaderFilter(headerValue, rowValue)
const collections = parseFilterExpression(headerValue);
try {
function matchValue(value)
{
try {
return collections.some(collection => {
return collections.some(collection => {
let positives = collection.positives.length === 0 || collection.positives.every(condition => {
let positives = collection.positives.length === 0 || collection.positives.every(condition => {
if (condition.type === 'comparison')
{
let value = parseFloat(rowValue);
if (isNaN(value)) return false;
if (condition.type === 'comparison')
{
let value = parseFloat(rowValue);
if (isNaN(value)) return false;
switch (condition.operator) {
case '<':
return value < condition.number;
case '>':
return value > condition.number;
case '<=':
return value <= condition.number;
case '>=':
return value >= condition.number;
case '=':
return value === condition.number;
case '!=':
return value !== condition.number;
default:
return false;
switch (condition.operator) {
case '<':
return value < condition.number;
case '>':
return value > condition.number;
case '<=':
return value <= condition.number;
case '>=':
return value >= condition.number;
case '=':
return value === condition.number;
case '!=':
return value !== condition.number;
default:
return false;
}
}
}
else if (condition.type === 'regex')
{
return condition.regex.test(rowValue);
}
return false;
else if (condition.type === 'regex')
{
return condition.regex.test(rowValue);
}
return false;
});
let negatives = collection.negatives.every(condition => {
return !condition.regex.test(rowValue);
});
return positives && negatives;
});
} catch (e) {
let negatives = collection.negatives.every(condition => {
return !condition.regex.test(rowValue);
});
return positives && negatives;
});
} catch (e) {
}
}
if (matchValue(rowValue))
return true;
if (rowData && filterParams)
{
const childrenField = filterParams?.children || '_children';
const field = filterParams?.field;
const children = rowData[childrenField];
if (Array.isArray(children))
{
for (let child of children)
{
let childValue = child[field];
if (extendedHeaderFilter(headerValue, childValue, child, filterParams))
{
return true;
}
}
}
}
return false;
}
export function tagHeaderFilter(headerValue, rowValue) {
export function tagHeaderFilter(headerValue, rowValue, rowData, filterParams)
{
let data;
@@ -108,18 +146,18 @@ export function tagHeaderFilter(headerValue, rowValue) {
if (Array.isArray(data))
{
combinedText = data
.filter(item => item?.done === false)
.map(item => `${item?.beschreibung} ${item?.notiz}`)
.join(' ');
}
else if (typeof data === 'object' && data !== null)
{
combinedText = `${data?.beschreibung} ${data?.notiz}`;
combinedText = data?.erledigt === false ? `${data?.beschreibung} ${data?.notiz}` : '';
}
else
{
combinedText = String(data);
}
return extendedHeaderFilter(headerValue, combinedText)
}
return extendedHeaderFilter(headerValue, combinedText, rowData, filterParams)
}
+2
View File
@@ -77,6 +77,8 @@ require_once('dbupdate_3.4/55614_perm_verwaltetoe.php');
require_once('dbupdate_3.4/25999_C4_dashboard.php');
require_once('dbupdate_3.4/61730_Dashboard_Anpassungen.php');
require_once('dbupdate_3.4/40128_search.php');
require_once('dbupdate_3.4/63436_cis4_iframe_component.php');
require_once('dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php');
require_once('dbupdate_3.4/66982_berufsschule.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
@@ -0,0 +1,16 @@
<?php
if (!defined('DB_NAME')) exit('No direct script access allowed');
// Add new name type in public.tbl_variablenname
if ($result = @$db->db_query("SELECT 1 FROM public.tbl_variablenname WHERE name = 'lv_favorites';"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_variablenname(name, defaultwert) VALUES('lv_favorites', null);";
if (!$db->db_query($qry))
echo '<strong>public.tbl_variablenname '.$db->db_last_error().'</strong><br>';
else
echo 'public.tbl_variablenname: Added name "lv_favorites"<br>';
}
}
@@ -0,0 +1,81 @@
<?php
$xsd= <<<EOD
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element name="url" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
EOD;
$xslt_xhtml= <<<EOD
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="content">
<xsl:choose>
<xsl:when test="string(url)">
<iframe
src="{url}"
frameborder="0"
style="width:100%; height:90vh; border:0; display:block;"
>
</iframe>
</xsl:when>
<xsl:otherwise>
<div class="alert alert-warning">Keine URL im Inhalt gefunden.</div>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
EOD;
$xslt_xhtml_c4= <<<EOD
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="content">
<xsl:choose>
<xsl:when test="string(url)">
<iframe
src="{url}"
frameborder="0"
style="width:100%; height:90vh; border:0; display:block;"
>
</iframe>
</xsl:when>
<xsl:otherwise>
<div class="alert alert-warning">Keine URL im Inhalt gefunden.</div>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
EOD;
if ($result = @$db->db_query("SELECT * FROM campus.tbl_template WHERE template_kurzbz='iframe'"))
{
if ($db->db_num_rows($result) == 0)
{
$sql= <<<EOD
INSERT INTO campus.tbl_template
(template_kurzbz, bezeichnung, xsd, xslt_xhtml, xslfo_pdf, xslt_xhtml_c4)
VALUES
('iframe','iFrame Content ', '{$xsd}', '{$xslt_xhtml}' , NULL, '{$xslt_xhtml_c4}');
EOD;
if (!$db->db_query($sql))
{
echo '<strong>campus.tbl_template: ' . $db->db_last_error() . '</strong><br>';
}
else
{
echo ' campus.tbl_template: Template "iframe" hinzugefügt.<br>';
}
}
}
+883
View File
@@ -3004,6 +3004,46 @@ $phrases = array(
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'cancelvertrag',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Vertrag stornieren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Cancel Contract',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'vertragConfirm',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Möchten Sie den Vertrag wirklich stornieren?',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Do you really want to cancel the contract?',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
@@ -42551,6 +42591,48 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'fachbereich',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Institut',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Institute',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehrtyp',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrtyp',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching type',
'description' => '',
'insertvon' => 'system'
)
)
),
// ### STUDIENGANG_INFORMATIONEN PHRASEN START
array(
'app' => 'core',
@@ -43196,6 +43278,86 @@ array(
)
)
),
array(
'app' => 'pep',
'category' => 'ui',
'phrase' => 'lehrauftrag',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrauftrag',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching lectureship',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'pep',
'category' => 'ui',
'phrase' => 'kategorie',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kategorie',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Category',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'pep',
'category' => 'ui',
'phrase' => 'project',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kategorie',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Category',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'pep',
'category' => 'ui',
'phrase' => 'lventwicklung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Weiterentwicklung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course Development',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'pep',
'category' => 'ui',
@@ -45144,6 +45306,727 @@ and represent the current state of research on the topic. The prescribed citatio
)
),
// PROJEKTARBEITSBEURTEILUNG SS2025 ENDE ---------------------------------------------------------------------------
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'gewicht',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gewicht',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Weight',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'newlehreinheit',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Neuer LV-Teil',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'New teaching unit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'bezeichnungeng',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bezeichnung Englisch',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'title english',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'detailanmerkung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Info an LV-Planung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Info to LV Planning',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'unr',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'UNR',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'UNR',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'las',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrauftragsstunden (LAS)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching hours (LAS)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehre',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehre',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'raumtyp',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Raumtyp',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Room',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehrende',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrende',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'lecturers',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'raumtypalternativ',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Raumtyp Alternativ',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Room Alternative',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'startkw',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Start KW',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Start CW',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'stundenblockung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Stunden Block',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Hours Block',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'wochenrhythmus',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Wochenrhythmus',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Weekly rhythm',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehrfunktion',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrfunktion',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching function',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'anmerkung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Info an DepL/KFL',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Info to DepL/KFL',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'planstunden',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Plan Stunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course-Plan Hours',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'leplanstunden',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Planstunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Plan Hours',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'default',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Default',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Default',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'stundensatz',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Stundensatz',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Hourly Rate',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'bismelden',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'BIS-Melden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Report BIS',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'gesamtkosten',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gesamtkosten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Total costs',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'daten',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Daten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Data',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehreinheit_id',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehreinheit ID',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching Unit ID',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'verplant',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Verplant',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Planned',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'addLektor',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LektorIn hinzufügen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Add lector',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'gruppen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gruppen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Groups',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'addGroup',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gruppe hinzufügen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Add group',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'assignPerson',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Person zuordnen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Assign person',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'assignedPersons',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Direkt zugeordnete Personen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Directly assigned persons',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'geaendert',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => '<b>Geändert</b>',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => '<b>Changed</b>',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'vertragurfassung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Vertragsdetails lt. Urfassung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Contract details as per original version',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'vertragsdetails',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Vertragsdetails',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Contract details',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'semesterstunden',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Semesterstunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Semester hours',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'vertragsstatus',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Vertragsstatus',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Contract status',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'auslvplanentfernen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Stunden aus LV-Plan entfernen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Remove hours from course plan',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lehrfach',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lehrfach',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course',
'description' => '',
'insertvon' => 'system'
)
)
),
/////////// FHC4 Phrases Messages START ///////////
array(
'app' => 'core',