Compare commits

..

5 Commits

Author SHA1 Message Date
ma0068 e23cadf39d use new api for getUri 2026-03-25 15:04:02 +01:00
ma0068 9b1774fabe refactor deprecated functions of LvUebersicht 2026-03-25 13:23:53 +01:00
ma0068 2112506832 refactor function deleteFile and delete comment 2026-03-25 10:37:24 +01:00
ma0068 bea4e2cf34 update comments 2026-03-24 14:05:26 +01:00
ma0068 b0da4e7dc5 update comments for notiz factory 2026-03-24 13:57:39 +01:00
86 changed files with 1327 additions and 9668 deletions
-20
View File
@@ -1,20 +0,0 @@
<?php
/**
* Configs for the Long Run Tasks
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
// Maximum LRTs for a single user in parallel
$config['lrt_max_number_single_user'] = 10;
// Maximum LRTs for the whole system in parallel
$config['lrt_max_number_system'] = 100;
// Maximum running time in hours for a single LRT before killing it
$config['lrt_max_run_timeout'] = 48;
// List of existing LRT types
$config['lrt_types'] = array('LRTDocumentConvertion');
+1 -8
View File
@@ -208,14 +208,7 @@ $config['navigation_header'] = array(
'expand' => true,
'sort' => 30,
'requiredPermissions' => 'lehre/anrechnungszeitfenster:rw'
),
'dashboardadmin' => array(
'link' => site_url('dashboard/Admin'),
'description' => 'Dashboard Admin',
'expand' => true,
'sort' => 40,
'requiredPermissions' => 'dashboard/admin:r'
)
)
)
)
)
@@ -1,121 +0,0 @@
<?php
/**
* Copyright (C) 2026 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');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about addresses
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Board extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'list' => 'dashboard/admin:r',
'create' => 'dashboard/admin:rw',
'update' => 'dashboard/admin:rw',
'delete' => 'dashboard/admin:rw'
]);
// Models
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
}
public function list()
{
$result = $this->DashboardModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
public function create()
{
$dashboard_kurzbz = $this->input->post('dashboard_kurzbz');
$result = $this->DashboardModel->insert([
'dashboard_kurzbz' => $dashboard_kurzbz
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function update()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard_id', 'Dashboard ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_id = $this->input->post('dashboard_id');
$dashboard_kurzbz = $this->input->post('dashboard_kurzbz');
$beschreibung = $this->input->post('beschreibung');
$result = $this->DashboardModel->update([
'dashboard_id' => $dashboard_id
], [
'dashboard_kurzbz' => $dashboard_kurzbz,
'beschreibung' => $beschreibung
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
public function delete()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard_id', 'Dashboard ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_id = $this->input->post('dashboard_id');
//delete all presets
$this->load->model('dashboard/Dashboard_Preset_model', 'DashboardPresetModel');
$result = $this->DashboardPresetModel->delete([
'dashboard_id' => $dashboard_id
]);
$this->getDataOrTerminateWithError($result);
//delete all widgets
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
$result = $this->DashboardWidgetModel->delete([
'dashboard_id' => $dashboard_id
]);
$this->getDataOrTerminateWithError($result);
$result = $this->DashboardModel->delete($dashboard_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
}
@@ -1,200 +0,0 @@
<?php
/**
* Copyright (C) 2026 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');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about addresses
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Preset extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'list' => 'dashboard/admin:r',
'getBatch' => 'dashboard/admin:r',
'addWidget' => 'dashboard/admin:rw',
'removeWidget' => 'dashboard/admin:rw'
]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
// Libraries
$this->load->library('dashboard/DashboardLib');
// Models
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function list($dashboard_kurzbz)
{
$sql = "
WITH
dashboard_presets AS (
SELECT
*
FROM
dashboard.tbl_dashboard_preset dp
JOIN
dashboard.tbl_dashboard d ON d.dashboard_id = dp.dashboard_id
WHERE
d.dashboard_kurzbz = {$this->db->escape($dashboard_kurzbz)}
),
general AS (
SELECT
'general' AS funktion_kurzbz,
'Allgemein' AS beschreibung
)
(
SELECT
f.funktion_kurzbz,
f.beschreibung,
COUNT(p.preset_id) AS has_preset
FROM
general f
LEFT JOIN
dashboard_presets p ON p.funktion_kurzbz IS NULL
GROUP BY
f.funktion_kurzbz, f.beschreibung
)
UNION ALL
(
SELECT
f.funktion_kurzbz,
f.beschreibung,
COUNT(p.preset_id) AS has_preset
FROM
public.tbl_funktion f
LEFT JOIN
dashboard_presets p ON p.funktion_kurzbz = f.funktion_kurzbz
GROUP BY
f.funktion_kurzbz, f.beschreibung
ORDER BY
f.beschreibung ASC
)
";
$result = $this->FunktionModel->execReadOnlyQuery($sql);
$funktionen = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($funktionen);
}
public function getBatch()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('db', 'Dashboard', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$db = $this->input->post('db');
$funktionen = $this->input->post('funktionen') ?: [];
$result = [];
foreach ($funktionen as $funktion) {
$conf = $this->dashboardlib->getPreset($db, $funktion);
if ($conf) {
$preset = json_decode($conf->preset, true);
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
$result[$funktion] = [];
else
$result[$funktion] = $preset[$funktion]['widgets'];
} else {
$result[$funktion] = [];
}
}
return $this->terminateWithSuccess($result);
}
public function addWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard', 'Dashboard', 'required');
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required');
$this->form_validation->set_rules('widget[widget]', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_kurzbz = $this->input->post('dashboard');
$funktion_kurzbz = $this->input->post('funktion_kurzbz');
$widget = $this->input->post('widget');
if (!isset($widget['widgetid']))
$widget['widgetid'] = $this->dashboardlib->generateWidgetId($dashboard_kurzbz);
$preset = $this->dashboardlib->getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz);
$preset_decoded = json_decode($preset->preset, true);
$this->dashboardlib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, [$widget]);
$preset->preset = json_encode($preset_decoded);
$result = $this->dashboardlib->insertOrUpdatePreset($preset);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($widget['widgetid']);
}
public function removeWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('db', 'Dashboard', 'required');
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required');
$this->form_validation->set_rules('widgetid', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_kurzbz = $this->input->post('db');
$funktion_kurzbz = $this->input->post('funktion_kurzbz');
$widgetid = $this->input->post('widgetid');
$preset = $this->dashboardlib->getPreset($dashboard_kurzbz, $funktion_kurzbz);
if (!$preset)
show_404();
$preset_decoded = json_decode($preset->preset, true);
if (!$this->dashboardlib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
show_404();
$preset->preset = json_encode($preset_decoded);
$result = $this->dashboardlib->insertOrUpdatePreset($preset);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(array('msg' => $this->p->t('dashboard', 'success_savePreset')));
}
}
@@ -1,159 +0,0 @@
<?php
/**
* Copyright (C) 2026 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');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about the users dashboard
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class User extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'get' => 'dashboard/benutzer:r',
'addWidget' => 'dashboard/benutzer:rw',
'removeWidget' => 'dashboard/benutzer:rw'
]);
// Libraries
$this->load->library('dashboard/DashboardLib');
// Models
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function get($dashboard_kurzbz)
{
$dashboard = $this->dashboardlib->getDashboardByKurzbz($dashboard_kurzbz);
if (!$dashboard)
show_404();
$uid = $this->authlib->getAuthObj()->username;
/*$mergedconfig = $this->dashboardlib->getMergedConfig($dashboard->dashboard_id, $uid);
$this->terminateWithSuccess([
'general' => call_user_func_array(
'array_merge_recursive',
$mergedconfig
)
]);*/
$defaultconfig = $this->dashboardlib->getDefaultConfig($dashboard->dashboard_id);
$userconfig = $this->dashboardlib->getUserConfig($dashboard->dashboard_id, $uid);
$defaultconfig_squashed = $defaultconfig ? call_user_func_array('array_replace_recursive', $defaultconfig) : [];
$userconfig_squashed = $userconfig ? call_user_func_array('array_replace_recursive', $userconfig) : [];
$mergedconfig = array_replace_recursive($defaultconfig_squashed, $userconfig_squashed);
$this->terminateWithSuccess([
DashboardLib::SECTION_IF_FUNKTION_KURZBZ_IS_NULL => $mergedconfig
]);
}
public function addWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard', 'Dashboard', 'required');
$this->form_validation->set_rules('widget[widget]', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$widget = $this->input->post('widget');
$dashboard_kurzbz = $this->input->post('dashboard');
$uid = $this->authlib->getAuthObj()->username;
if (!isset($widget['widgetid']))
$widget['widgetid'] = $this->dashboardlib->generateWidgetId($dashboard_kurzbz);
$override = $this->dashboardlib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid);
$override_decoded = json_decode($override->override, true);
if (!isset($override_decoded['general']) || !is_array($override_decoded['general']))
$override_decoded['general'] = [];
if (!isset($override_decoded['general']['widgets']))
$override_decoded['general']['widgets'] = [];
$override_decoded['general']['widgets'][$widget['widgetid']] = $widget;
// NOTE(chris): remove doubles in other funktionen
foreach ($override_decoded as $funktion => $array) {
if ($funktion == 'general')
continue;
if (isset($array['widgets']) && isset($array['widgets'][$widget['widgetid']]))
unset($override_decoded[$funktion]['widgets'][$widget['widgetid']]);
}
$override->override = json_encode($override_decoded);
$result = $this->dashboardlib->insertOrUpdateOverride($override);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($widget['widgetid']);
}
public function removeWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard', 'Dashboard', 'required');
$this->form_validation->set_rules('widget', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$widget_id = $this->input->post('widget');
$dashboard_kurzbz = $this->input->post('dashboard');
$uid = $this->authlib->getAuthObj()->username;
$override = $this->dashboardlib->getOverride($dashboard_kurzbz, $uid);
if (!$override)
show_404();
$override_decoded = json_decode($override->override, true);
foreach (array_keys($override_decoded) as $k) {
if (!isset($override_decoded[$k]["widgets"])) {
unset($override_decoded[$k]);
continue;
}
if (isset($override_decoded[$k]["widgets"][$widget_id])) {
unset($override_decoded[$k]["widgets"][$widget_id]);
}
if (!$override_decoded[$k]["widgets"]) {
unset($override_decoded[$k]);
}
}
$override->override = json_encode($override_decoded);
$result = $this->dashboardlib->insertOrUpdateOverride($override);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess();
}
}
@@ -1,137 +0,0 @@
<?php
/**
* Copyright (C) 2026 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');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about the users dashboard
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Widget extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'get' => ['dashboard/benutzer:r', 'dashboard/admin:r'],
'list' => 'dashboard/admin:r',
'listAllowed' => ['dashboard/benutzer:rw', 'dashboard/admin:r'],
'setAllowed' => 'dashboard/admin:rw'
]);
// Libraries
$this->load->library('dashboard/DashboardLib');
// Models
$this->load->model('dashboard/Widget_model', 'WidgetModel');
}
public function get($id)
{
$result = $this->WidgetModel->load($id);
$widget = $this->getDataOrTerminateWithError($result);
if (!$widget)
return $this->terminateWithSuccess([
"widget_id" => 0,
"widget_kurzbz" => "notfound",
"arguments" => [
"className" => 'alert-danger',
"title" => 'Widget Not Found',
"msg" => 'The widget with the id ' . $id . ' could not be found'
],
"setup" => [
"name" => 'Widget Not Found',
"file" => absoluteJsImportUrl('public/js/components/DashboardWidget/Default.js'),
"width" => 1,
"height" => 1
]
]);
$widget = current($widget);
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
$this->terminateWithSuccess($widget);
}
public function list($dashboard)
{
$result = $this->WidgetModel->getWithAllowedForDashboard($dashboard);
$widgets = $this->getDataOrTerminateWithError($result);
$widgets = array_map(function ($widget) {
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $widget;
}, $widgets);
$this->terminateWithSuccess($widgets);
}
public function listAllowed($dashboard)
{
$result = $this->WidgetModel->getForDashboard($dashboard);
$widgets = $this->getDataOrTerminateWithError($result);
$widgets = array_map(function ($widget) {
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $widget;
}, $widgets);
$this->terminateWithSuccess($widgets);
}
public function setAllowed()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard_id', 'Dashboard', 'required');
$this->form_validation->set_rules('widget_id', 'Widget', 'required');
$this->form_validation->set_rules('allowed', 'Allowed', 'is_bool');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$data = [
'dashboard_id' => $this->input->post('dashboard_id'),
'widget_id' => $this->input->post('widget_id')
];
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
if ($this->input->post('allowed'))
$result = $this->DashboardWidgetModel->insert($data);
else
$result = $this->DashboardWidgetModel->delete($data);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -42,22 +42,14 @@ class Messages extends FHCAPI_Controller
]);
}
public function getMessages($id, $type_id, $size=null, $page=null)
public function getMessages($id, $type_id, $size, $page)
{
if($type_id != 'person_id'){
$id = $this->_getPersonId($id, $type_id);
}
if(!(is_null($size) && is_null($page)))
{
$offset = $size * ($page - 1);
$limit = $size;
}
else
{
$offset = null;
$limit = null;
}
$offset = $size * ($page - 1);
$limit = $size;
$result = $this->MessageModel->getMessagesForTable($id, $offset, $limit);
@@ -626,7 +626,7 @@ class Students extends FHCAPI_Controller
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere($where);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
@@ -851,44 +851,40 @@ class Students extends FHCAPI_Controller
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$this->load->config('stv');
$tags = $this->config->item('stv_prestudent_tags');
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
{
$tags = $this->config->item('stv_prestudent_tags');
$whereTags = '';
if (is_array($tags) && !isEmptyArray($tags)) {
$tags = array_keys($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 nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
foreach ($tags as $key => $tag) {
$tags[$key] = $this->db->escape($tag);
}
$subQueryTag = "
(
SELECT
tag.prestudent_id,
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
nz.prestudent_id
FROM public.tbl_notizzuordnung AS nz
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz "
. $whereTags .
"
) AS tag
GROUP BY tag.prestudent_id
) AS tag_data_agg
";
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
}
$subQueryTag = "
(
SELECT
tag.prestudent_id,
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
nz.prestudent_id
FROM public.tbl_notizzuordnung AS nz
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz "
. $whereTags .
"
) AS tag
GROUP BY tag.prestudent_id
) AS tag_data_agg
";
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
@@ -911,17 +907,11 @@ class Students extends FHCAPI_Controller
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT');
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
{
$this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
}
$this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
$this->PrestudentModel->addSelect("b.uid");
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
{
$this->PrestudentModel->addSelect('tag_data_agg.tags');
}
$this->PrestudentModel->addSelect('tag_data_agg.tags');
$this->PrestudentModel->addSelect('titelpre');
$this->PrestudentModel->addSelect('nachname');
$this->PrestudentModel->addSelect('vorname');
@@ -1,52 +0,0 @@
<?php
/**
* Copyright (C) 2026 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 Admin extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'dashboard/admin:rw',
'preview' => 'dashboard/admin:r',
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->view('dashboard/admin.php', []);
}
public function preview($dashboard_kurzbz = 'CIS')
{
$this->load->view('dashboard/preview.php', [
'dashboard_kurzbz' => $dashboard_kurzbz
]);
}
}
+76
View File
@@ -0,0 +1,76 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
class Api extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/admin:rw',
'getNews' => 'dashboard/benutzer:r',
'getAmpeln' => 'dashboard/benutzer:r',
)
);
$this->load->library('AuthLib', null, 'AuthLib');
$this->_setAuthUID();
}
public function index()
{
echo 'Dashboard API Controller';
}
/**
* Get News.
*/
public function getNews()
{
$limit = $this->input->get('limit');
$this->load->model('content/News_model', 'NewsModel');
$result = $this->NewsModel->getAll($limit);
if (hasData($result))
{
$this->outputJson(getData($result), REST_Controller::HTTP_OK);
}
else
{
$this->terminateWithJsonError('fehler entdeckt');
}
}
/**
* Get Ampeln.
*/
public function getAmpeln()
{
$this->load->model('content/Ampel_model', 'AmpelModel');
$result = $this->AmpelModel->getByUser($this->_uid);
if (hasData($result))
{
$this->outputJson(getData($result), REST_Controller::HTTP_OK);
}
else
{
$this->terminateWithJsonError('fehler entdeckt');
}
}
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
@@ -0,0 +1,216 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Config
*
* @author bambi
*/
class Config extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/benutzer:r',
'dummy' => 'dashboard/benutzer:r',
'genWidgetId' => 'dashboard/benutzer:rw',
'addWidgetsToPreset' => 'dashboard/admin:rw',
'removeWidgetFromPreset' => 'dashboard/admin:rw',
'addWidgetsToUserOverride' => 'dashboard/benutzer:rw',
'removeWidgetFromUserOverride' => 'dashboard/benutzer:rw',
'funktionen' => 'dashboard/admin:r',
'preset' => 'dashboard/admin:r',
'presetBatch' => 'dashboard/admin:r'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->library('AuthLib', null, 'AuthLib');
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function index()
{
$dashboard_kurzbz = $this->input->get('db');
$uid = $this->AuthLib->getAuthObj()->username;
$dashboard = $this->DashboardLib->getDashboardByKurzbz($dashboard_kurzbz);
if(!$dashboard) {
http_response_code(404);
$this->terminateWithJsonError(array(
'error' => 'Dashboard ' . $dashboard_kurzbz . ' not found.'
));
}
$mergedconfig = $this->DashboardLib->getMergedConfig($dashboard->dashboard_id, $uid);
$this->outputJsonSuccess($mergedconfig);
}
public function genWidgetId()
{
$dashboard_kurzbz = $this->input->get('db');
$widgetid = $this->DashboardLib->generateWidgetId($dashboard_kurzbz);
$this->outputJsonSuccess(array(
'widgetid' => $widgetid
));
}
public function addWidgetsToPreset()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$preset = $this->DashboardLib->getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz);
$preset_decoded = json_decode($preset->preset, true);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$preset->preset = json_encode($preset_decoded);
$result = $this->DashboardLib->insertOrUpdatePreset($preset);
if (isError($result)) {
http_response_code(500);
$this->terminateWithJsonError('preset could not be saved');
}
$this->outputJsonSuccess(array('msg' => 'preset successfully stored.', 'data' => $preset_decoded));
}
public function removeWidgetFromPreset()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$widgetid = $input->widgetid;
$preset = $this->DashboardLib->getPreset($dashboard_kurzbz, $funktion_kurzbz);
if ($preset === null) {
http_response_code(404);
$this->terminateWithJsonError('preset for dashboard ' . $dashboard_kurzbz . ' and funktion ' . $funktion_kurzbz . ' not found.');
}
$preset_decoded = json_decode($preset->preset, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
}
$preset->preset = json_encode($preset_decoded);
$result = $this->DashboardLib->insertOrUpdatePreset($preset);
if (isError($result))
{
http_response_code(500);
$this->terminateWithJsonError('failed to remove widget');
}
$this->outputJsonSuccess(array('msg' => 'preset successfully updated.'));
}
public function addWidgetsToUserOverride()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$uid = $this->AuthLib->getAuthObj()->username;
$override = $this->DashboardLib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid);
$override_decoded = json_decode($override->override, true);
$this->DashboardLib->addWidgetsToWidgets($override_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$override->override = json_encode($override_decoded);
$result = $this->DashboardLib->insertOrUpdateOverride($override);
if (isError($result)) {
http_response_code(500);
$this->terminateWithJsonError('override could not be saved');
}
$this->outputJsonSuccess(array('msg' => 'override successfully stored.', 'data' => $override_decoded));
}
public function removeWidgetFromUserOverride()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$uid = $this->AuthLib->getAuthObj()->username;
$widgetid = $input->widgetid;
$override = $this->DashboardLib->getOverride($dashboard_kurzbz, $uid);
if (empty($override)) {
http_response_code(404);
$this->terminateWithJsonError('userconfig for dashboard ' . $dashboard_kurzbz . ' not found.');
}
$override_decoded = json_decode($override->override, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
}
$override->override = json_encode($override_decoded);
$result = $this->DashboardLib->insertOrUpdateOverride($override, $uid);
if (isError($result))
{
http_response_code(500);
$this->terminateWithJsonError('failed to remove widget');
}
$this->outputJsonSuccess(array('msg' => 'override successfully updated.'));
}
public function funktionen()
{
$funktionen = $this->FunktionModel->load();
if (isError($funktionen)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($funktionen)
]);
}
return $this->outputJsonSuccess(getData($funktionen) ?: []);
}
public function preset()
{
$db = $this->input->get('db');
$funktion = $this->input->get('funktion');
$conf = $this->DashboardLib->getPreset($db, $funktion);
if (!$conf)
return $this->outputJsonSuccess(['widgets' => [$funktion => []]]);
return $this->outputJsonSuccess(json_decode($conf->preset, true));
}
public function presetBatch()
{
$db = $this->input->get('db');
$funktionen = $this->input->get('funktionen');
$result = [];
foreach ($funktionen as $funktion) {
$conf = $this->DashboardLib->getPreset($db, $funktion);
if ($conf)
{
$preset = json_decode($conf->preset, true);
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
$result[$funktion] = [];
else
$result[$funktion] = $preset[$funktion]['widgets'];
}
else
$result[$funktion] = [];
}
return $this->outputJsonSuccess($result);
}
}
@@ -0,0 +1,86 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Widget
*
* @author chris
*/
class Dashboard extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/admin:r',
'create' => 'dashboard/admin:rw',
'update' => 'dashboard/admin:rw',
'delete' => 'dashboard/admin:rw'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
}
public function index()
{
$result = $this->DashboardModel->load();
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function create()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->insert($input);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function update()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->update($input->dashboard_id, $input);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function delete()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->delete($input->dashboard_id);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
}
@@ -0,0 +1,58 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*/
class DashboardDemo extends Auth_Controller
{
private $_uid; // uid of the logged user
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'dashboard/benutzer:r',
'admin' => 'dashboard/admin:rw'
)
);
$this->load->library('AuthLib');
$this->load->library('WidgetLib');
$this->_setAuthUID(); // sets property uid
$this->setControllerId(); // sets the controller id
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->view('dashboard/dashboard_demo.php', []);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function admin()
{
$this->load->view('dashboard/dashboard_demo_admin.php', []);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
@@ -0,0 +1,134 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Widget
*
* @author chris
*/
class Widget extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => ['dashboard/benutzer:r', 'dashboard/admin:r'],
'getAll' => 'dashboard/admin:r',
'getWidgetsForDashboard' => ['dashboard/benutzer:rw', 'dashboard/admin:r'],
'setAllowed' => 'dashboard/admin:rw'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->model('dashboard/Widget_model', 'WidgetModel');
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
}
public function index()
{
$widget_id = $this->input->get('id');
$widget = $this->WidgetModel->load($widget_id);
if (isError($widget) || !getData($widget))
return $this->outputJsonSuccess([
"widget_id" => 0,
"widget_kurzbz" => "notfound",
"arguments" => [
"className" => 'alert-danger',
"title" => 'Widget Not Found',
"msg" => 'The widget with the id ' . $widget_id . ' could not be found'
],
"setup" => [
"name" => 'Widget Not Found',
"file" => absoluteJsImportUrl('public/js/components/DashboardWidget/Default.js'),
"width" => 1,
"height" => 1
]
]);
$widget = current(getData($widget));
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $this->outputJsonSuccess($widget);
}
public function getAll()
{
$dashboard_id = $this->input->get('dashboard_id');
$result = $this->WidgetModel->getWithAllowedForDashboard($dashboard_id);
if (isError($result))
return $this->outputJsonError(getError($result));
$tmpwidgets = getData($result) ?: [];
$widgets = array_map(function($widget) {
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $widget;
}, $tmpwidgets);
$this->outputJsonSuccess($widgets);
}
public function getWidgetsForDashboard()
{
$db = $this->input->get('db');
$result = $this->WidgetModel->getForDashboard($db);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
$tmpwidgets = getData($result) ?: [];
$widgets = array_map(function($widget) {
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $widget;
}, $tmpwidgets);
$this->outputJsonSuccess($widgets);
}
public function setAllowed()
{
$input = $this->getPostJSON();
$dashboard_id = $input->dashboard_id;
$widget_id = $input->widget_id;
$action = $input->action;
if ($action == 'add') {
$result = $this->DashboardWidgetModel->insert([
'dashboard_id' => $dashboard_id,
'widget_id' => $widget_id
]);
} elseif ($action == 'delete') {
$result = $this->DashboardWidgetModel->delete([
'dashboard_id' => $dashboard_id,
'widget_id' => $widget_id
]);
} else {
http_response_code(404); // TODO(chris): 400?
$this->terminateWithJsonError([
'error' => 'action value invalid'
]);
}
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result));
}
}
-73
View File
@@ -1,73 +0,0 @@
<?php
if (!defined("BASEPATH")) exit("No direct script access allowed");
/**
* Long Run Task
*
* This controller acts as interface of the LongRunTaskLib that contains
* all the needed functionalities to operate with the Long Run Task system
* that is built on top of the Jobs Queue System
* This is an abstract class that provide basic functionalities,
* it has to be extended to broaden its logic
*/
abstract class LRT_Controller extends JQW_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
// Changes the needed configs for LogLib
$this->LogLibJob->setConfigs(
array(
'dbExecuteUser' => 'LRTs queue system',
'requestId' => 'LTR'
)
);
// Loads LongRunTaskLib library
$this->load->library('LongRunTaskLib');
}
//------------------------------------------------------------------------------------------------------------------
// Protected methods
/**
* Get the oldest added LRTs to the queue having status = new
*/
protected function getLRTs()
{
$lrts = $this->longruntasklib->getLRTs();
// If an error occurred then log it in database
if (isError($lrts)) $this->logError(getError($lrts));
return $lrts;
}
/**
*
*/
protected function addNewLRTsToQueue($type, $lrts)
{
$result = $this->longruntasklib->addNewLRTsToQueue($type, $lrts);
// If an error occurred then log it in database
if (isError($result)) $this->logError(getError($result), $type);
return $result;
}
/**
* Utility method to generate a job with the given parameters and return it inside an array
* ready to be used by addNewJobsToQueue and updateJobsQueue
*/
protected function generateJobs($status, $input)
{
return JobsQueueLib::generateJobs($status, $input);
}
}
+1 -1
View File
@@ -128,7 +128,7 @@ class AntragLib
return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id);
}
// NOTE(chris): get last status that is not pause
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum', 'DESC');
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum');
$this->_ci->StudierendenantragstatusModel->addLimit(1);
$result = $this->_ci->StudierendenantragstatusModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
+2 -4
View File
@@ -2,8 +2,6 @@
if (!defined('BASEPATH')) exit('No direct script access allowed');
use \stdClass as stdClass;
/**
* Library that contains all the needed functionalities to operate with the Jobs Queue System
*/
@@ -26,12 +24,12 @@ class JobsQueueLib
const PROPERTY_END_TIME = 'endtime';
const PROPERTY_ERROR = 'error';
protected $_ci; // CI instance
private $_ci; // CI instance
/**
* Constructor
*/
public function __construct()
public function __construct($authenticate = true)
{
// Gets CI instance
$this->_ci =& get_instance();
-66
View File
@@ -1,66 +0,0 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Library that contains all the needed functionalities to operate with the Long Run Tasks
*/
class LongRunTaskLib extends JobsQueueLib
{
const CFG_LRT_MAX_NUMBER_SYSTEM = 'lrt_max_number_system';
const CFG_LRT_TYPES = 'lrt_types';
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
// Loads the Long Run Tasks configs
$this->_ci->config->load('lrt');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Get the oldest added LRTs to the queue having status = new
* The maximum number of returned queued LRTs is limited by:
* number of currently running LRTs - maximum allowed number of LRTs for the system
*/
public function getLRTs()
{
// Get all the running LRTs
$runningLrtsResult = $this->getJobsByTypeStatus($this->_ci->config->item(self::CFG_LRT_TYPES)), JobsQueueLib::STATUS_RUNNING);
if (isError($runningLrtsResult)) return $runningLrtsResult;
// The number of the currently running LRTs - the maximum LRTs for the system
$max_number_of_lrts = $this->_ci->config->item(self::CFG_LRT_MAX_NUMBER_SYSTEM)) - count(getData($runningLrtsResult));
// Get the oldest LRTs added to the queue
return $this->getOldestJobs($this->_ci->config->item(self::CFG_LRT_TYPES)), $max_number_of_lrts);
}
/**
*
*/
public function addNewLRTsToQueue($type, $lrts)
{
return $this->addNewJobsToQueue($type, $lrts);
}
//------------------------------------------------------------------------------------------------------------------
// Public static methods
/**
* Utility method to generate a LTR with the given parameters and return it inside an array
* ready to be used by addNewLRTsToQueue
*/
public static function generateLtrs($status, $input)
{
return self::generateJobs($status, $input);
}
}
+1 -16
View File
@@ -50,7 +50,6 @@ class PermissionLib
const LOGINAS_PERSONIDS_BLACKLIST = 'permission_loginas_personids_blacklist';
private $_ci; // CI instance
private $access_rights; // current users access rights
private static $bb; // benutzerberechtigung
/**
@@ -62,8 +61,6 @@ class PermissionLib
// Loads CI instance
$this->_ci =& get_instance();
$this->access_rights = null;
$this->_ci->config->load('permission'); // Loads permission configuration
// If it's NOT called from command line
@@ -72,10 +69,8 @@ class PermissionLib
// API Caller rights initialization
$authObj = $this->_ci->authlib->getAuthObj();
self::$bb = new benutzerberechtigung();
if ($authObj) {
if ($authObj)
self::$bb->getBerechtigungen($authObj->{AuthLib::AO_USERNAME});
$this->access_rights = self::$bb->berechtigungen;
}
}
}
@@ -345,16 +340,6 @@ class PermissionLib
}
}
/**
* Returns the access rights for the current user
*
* @return array|null
*/
public function getAccessRights()
{
return $this->access_rights;
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
@@ -49,7 +49,7 @@ class DashboardLib
public function getMergedConfig($dashboard_id, $uid)
{
$defaultconfig = $this->getDefaultConfig($dashboard_id);
$defaultconfig = $this->getDefaultConfig($dashboard_id, $uid);
$userconfig = $this->getUserConfig($dashboard_id, $uid);
$mergedconfig = array_replace_recursive($defaultconfig, $userconfig);
@@ -57,31 +57,14 @@ class DashboardLib
return $mergedconfig;
}
public function getDefaultConfig($dashboard_id)
public function getDefaultConfig($dashboard_id, $uid)
{
$funktion_kurzbzs = [];
$rights = $this->_ci->permissionlib->getAccessRights();
if ($rights)
$funktion_kurzbzs = array_unique(array_map(function ($right) {
return $right->funktion_kurzbz;
}, $rights));
$this->_ci->DashboardPresetModel->db
->group_start()
->where_in('funktion_kurzbz', $funktion_kurzbzs)
->or_where('funktion_kurzbz IS NULL')
->group_end();
$this->_ci->DashboardPresetModel->addOrder('funktion_kurzbz', 'DESC');
$result = $this->_ci->DashboardPresetModel->loadWhere([
'dashboard_id' => $dashboard_id
]);
$res_presets = $this->_ci->DashboardPresetModel->getPresets($dashboard_id, $uid);
$defaultconfig = array();
if (hasData($result))
if (hasData($res_presets))
{
$presets = getData($result);
$presets = getData($res_presets);
foreach ($presets as $presetobj)
{
$preset = json_decode($presetobj->preset, true);
@@ -154,10 +137,8 @@ class DashboardLib
$dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz);
$funktion_kurzbz = ($section === self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL) ? null : $section;
$result = $this->_ci->DashboardPresetModel->loadWhere([
'dashboard_id' => $dashboard->dashboard_id,
'funktion_kurzbz' => $funktion_kurzbz
]);
$result = $this->_ci->DashboardPresetModel
->getPresetByDashboardAndFunktion($dashboard->dashboard_id, $funktion_kurzbz);
if (hasData($result))
{
@@ -214,11 +195,11 @@ class DashboardLib
{
foreach ($addwigets as $widget)
{
if(!isset($widget['widgetid']))
if(!isset($widget->widgetid))
{
$widget['widgetid'] = $this->generateWidgetId($dashboard_kurzbz);
$widget->widgetid = $this->generateWidgetId($dashboard_kurzbz);
}
$this->addWidgetToWidgets($widgets, $section, $widget, $widget['widgetid']);
$this->addWidgetToWidgets($widgets, $section, $widget, $widget->widgetid);
}
}
@@ -3,7 +3,6 @@ namespace vertragsbestandteil;
use Exception;
use vertragsbestandteil\VertragsbestandteilStunden;
use vertragsbestandteil\VertragsbestandteilLohnguide;
/**
* Description of VertragsbestandteilFactory
@@ -23,7 +22,6 @@ class VertragsbestandteilFactory
const VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH = 'urlaubsanspruch';
const VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG = 'zeitaufzeichnung';
const VERTRAGSBESTANDTEIL_LEHRE = 'lehre';
const VERTRAGSBESTANDTEIL_LOHNGUIDE = 'lohnguide';
public static function getVertragsbestandteil($data, $fromdb=false)
{
@@ -71,11 +69,6 @@ class VertragsbestandteilFactory
$vertragsbestandteil = new VertragsbestandteilZeitaufzeichnung();
$vertragsbestandteil->hydrateByStdClass($data, $fromdb);
break;
case self::VERTRAGSBESTANDTEIL_LOHNGUIDE:
$vertragsbestandteil = new VertragsbestandteilLohnguide();
$vertragsbestandteil->hydrateByStdClass($data, $fromdb);
break;
default:
throw new Exception('Unknown vertragsbestandteiltyp_kurzbz '
@@ -134,12 +127,6 @@ class VertragsbestandteilFactory
$vertragsbestandteildbmodel = $CI->VertragsbestandteilZeitaufzeichnung_model;
break;
case self::VERTRAGSBESTANDTEIL_LOHNGUIDE:
$CI->load->model('vertragsbestandteil/VertragsbestandteilLohnguide_model',
'VertragsbestandteilLohnguide_model');
$vertragsbestandteildbmodel = $CI->VertragsbestandteilLohnguide_model;
break;
default:
throw new Exception('Unknown vertragsbestandteil_kurzbz '
. $vertragsbestandteil_kurzbz);
@@ -10,7 +10,6 @@ require_once __DIR__ . '/VertragsbestandteilKuendigungsfrist.php';
require_once __DIR__ . '/VertragsbestandteilUrlaubsanspruch.php';
require_once __DIR__ . '/VertragsbestandteilFreitext.php';
require_once __DIR__ . '/VertragsbestandteilKarenz.php';
require_once __DIR__ . '/VertragsbestandteilLohnguide.php';
require_once __DIR__ . '/VertragsbestandteilFactory.php';
require_once __DIR__ . '/OverlapChecker.php';
@@ -1,155 +0,0 @@
<?php
namespace vertragsbestandteil;
use vertragsbestandteil\Vertragsbestandteil;
use vertragsbestandteil\VertragsbestandteilFactory;
class VertragsbestandteilLohnguide extends Vertragsbestandteil
{
protected $stellenbezeichnung;
protected $vordienstzeit;
protected $fachrichtung_kurzbz;
protected $modellstelle_kurzbz;
protected $kommentar_person;
protected $kommentar_modellstelle;
public function __construct()
{
parent::__construct();
$this->setVertragsbestandteiltyp_kurzbz(
VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_LOHNGUIDE);
}
public function getStellenbezeichnung()
{
return $this->stellenbezeichnung;
}
public function setStellenbezeichnung($stellenbezeichnung): self
{
$this->markDirty('stellenbezeichnung', $this->stellenbezeichnung, $stellenbezeichnung);
$this->stellenbezeichnung = $stellenbezeichnung;
return $this;
}
public function getVordienstzeit()
{
return $this->vordienstzeit;
}
public function setVordienstzeit($vordienstzeit): self
{
$this->markDirty('vordienstzeit', $this->vordienstzeit, $vordienstzeit);
$this->vordienstzeit = $vordienstzeit;
return $this;
}
public function getFachrichtung_kurzbz()
{
return $this->fachrichtung_kurzbz;
}
public function setFachrichtung_kurzbz($fachrichtung_kurzbz): self
{
$this->markDirty('fachrichtung_kurzbz', $this->fachrichtung_kurzbz, $fachrichtung_kurzbz);
$this->fachrichtung_kurzbz = $fachrichtung_kurzbz;
return $this;
}
public function getModellstelle_kurzbz()
{
return $this->modellstelle_kurzbz;
}
public function setModellstelle_kurzbz($modellstelle_kurzbz): self
{
$this->markDirty('modellstelle_kurzbz', $this->modellstelle_kurzbz, $modellstelle_kurzbz);
$this->modellstelle_kurzbz = $modellstelle_kurzbz;
return $this;
}
public function getKommentar_person()
{
return $this->kommentar_person;
}
public function setKommentar_person($kommentar_person): self
{
$this->markDirty('kommentar_person', $this->kommentar_person, $kommentar_person);
$this->kommentar_person = $kommentar_person;
return $this;
}
public function getKommentar_modellstelle()
{
return $this->kommentar_modellstelle;
}
public function setKommentar_modellstelle($kommentar_modellstelle): self
{
$this->markDirty('kommentar_modellstelle', $this->kommentar_modellstelle, $kommentar_modellstelle);
$this->kommentar_modellstelle = $kommentar_modellstelle;
return $this;
}
public function hydrateByStdClass($data, $fromdb=false)
{
parent::hydrateByStdClass($data, $fromdb);
$this->fromdb = $fromdb;
isset($data->fachrichtung_kurzbz) && $this->setFachrichtung_kurzbz($data->fachrichtung_kurzbz);
isset($data->stellenbezeichnung) && $this->setStellenbezeichnung($data->stellenbezeichnung);
isset($data->vordienstzeit) && $this->setVordienstzeit($data->vordienstzeit);
isset($data->modellstelle_kurzbz) && $this->setModellstelle_kurzbz($data->modellstelle_kurzbz);
isset($data->kommentar_person) && $this->setKommentar_person($data->kommentar_person);
isset($data->kommentar_modellstelle) && $this->setKommentar_modellstelle($data->kommentar_modellstelle);
$this->fromdb = false;
}
public function toStdClass(): \stdClass
{
$tmp = array(
'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(),
'stellenbezeichnung' => $this->getStellenbezeichnung(),
'vordienstzeit' => $this->getVordienstzeit(),
'fachrichtung_kurzbz' => $this->getFachrichtung_kurzbz(),
'modellstelle_kurzbz' => $this->getModellstelle_kurzbz(),
'kommentar_person' => $this->getKommentar_person(),
'kommentar_modellstelle' => $this->getKommentar_modellstelle(),
);
$tmp = array_filter($tmp, function($k) {
return in_array($k, $this->modifiedcolumns);
}, ARRAY_FILTER_USE_KEY);
return (object) $tmp;
}
public function __toString()
{
$txt = <<<EOTXT
modellstelle_kurzbz: {$this->getModellstelle_kurzbz()}
EOTXT;
return parent::__toString() . $txt;
}
/* public function validate()
{
if( !(filter_var($this->tage, FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
'max_range' => 50
)
)
)) ) {
$this->validationerrors[] = 'Urlaubsanspruch muss eine Tagesanzahl im Bereich 1 bis 50 sein.';
}
return parent::validate();
} */
}
@@ -11,4 +11,57 @@ class Dashboard_Preset_model extends DB_Model
$this->dbTable = 'dashboard.tbl_dashboard_preset';
$this->pk = 'preset_id';
}
/**
* Get Presets of given uid.
* @param integer dashboard_id
* @param string $uid
* @return array
*/
public function getPresets($dashboard_id, $uid)
{
// TODO: get Funktionen for uid and load all preset for all funktionen for uid
//return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'funktion_kurzbz'=> null));
$sql = <<<EOSQL
SELECT
*
FROM
dashboard.tbl_dashboard_preset
WHERE
dashboard_id = ?
AND (
funktion_kurzbz IN (
SELECT
DISTINCT funktion_kurzbz
FROM
public.tbl_benutzerfunktion
WHERE
uid = ?
AND
NOW()::date
BETWEEN
COALESCE(datum_von, '1970-01-01')
AND
COALESCE(datum_bis, '2170-12-31')
)
OR
funktion_kurzbz IS NULL
)
ORDER BY
funktion_kurzbz DESC
EOSQL;
return $this->execQuery($sql, array($dashboard_id, $uid));
}
/**
* Get Preset by Dashboard and Funktion
* @param integer dashboard_id
* @param string funktion_kurzbz
* @return array
*/
public function getPresetByDashboardAndFunktion($dashboard_id, $funktion_kurzbz)
{
return $this->loadWhere(array('dashboard_id' => $dashboard_id, 'funktion_kurzbz' => $funktion_kurzbz));
}
}
@@ -402,17 +402,14 @@ class Lehrveranstaltung_model extends DB_Model
SELECT
vorname, nachname, mitarbeiter_uid, lehrfunktion_kurzbz
FROM
lehre.tbl_lehreinheit le
lehre.tbl_lehreinheit
JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id)
JOIN public.tbl_benutzer b ON b.uid = lema.mitarbeiter_uid
JOIN public.tbl_person p using (person_id)
WHERE
le.lehrveranstaltung_id= ?
AND le.studiensemester_kurzbz = ?
tbl_lehreinheit.lehrveranstaltung_id= ?
AND tbl_lehreinheit.studiensemester_kurzbz = ?
AND lehrfunktion_kurzbz = 'LV-Leitung'
AND lema.mitarbeiter_uid NOT like '_Dummy%'
AND b.aktiv = TRUE
AND p.aktiv = TRUE
ORDER BY
lema.insertamum DESC
LIMIT 1
@@ -79,10 +79,10 @@ class Paabgabe_model extends DB_Model
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
JOIN public.tbl_person USING (person_id)
WHERE (campus.tbl_paabgabe.insertamum::date = CURRENT_DATE - INTERVAL ?
OR campus.tbl_paabgabe.updateamum::date = CURRENT_DATE - INTERVAL ?)
AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
WHERE (campus.tbl_paabgabe.insertamum >= NOW() - INTERVAL ?
OR campus.tbl_paabgabe.updateamum >= NOW() - INTERVAL ?)
AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
return $this->execQuery($query, [$interval, $interval, $relevantTypes]);
}
@@ -108,7 +108,7 @@ class Paabgabe_model extends DB_Model
JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
WHERE campus.tbl_paabgabe.abgabedatum IS NOT NULL
AND campus.tbl_paabgabe.abgabedatum = CURRENT_DATE - INTERVAL ?";
AND campus.tbl_paabgabe.abgabedatum >= NOW() - INTERVAL ?";
if($relevantTypes !== null) {
$query .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
@@ -594,10 +594,7 @@ class Studiengang_model extends DB_Model
$this->addSelect('p.prestudent_id');
$this->addSelect('pers.vorname');
$this->addSelect('pers.nachname');
$this->addSelect("CONCAT(UPPER(pers.nachname), ' ', pers.vorname, ' (', "
. $this->dbTable . ".bezeichnung, ', ', "
. "UPPER(" . $this->dbTable . ".typ), "
. "UPPER(" . $this->dbTable . ".kurzbz),')') AS name");
$this->addSelect("CONCAT(UPPER(pers.nachname), ' ', pers.vorname, ' (', " . $this->dbTable . ".bezeichnung, ')') AS name");
$this->addJoin('public.tbl_prestudent p', 'studiengang_kz');
$this->addJoin(
@@ -261,42 +261,6 @@ class Benutzerfunktion_model extends DB_Model
}
/**
* Get active Kompetenzfeldleitung bei UID.
*
* @param $uid
* @return array|stdClass|null
*/
public function getKFLByUID($uid)
{
$query = '
SELECT
bf.uid,
bf.oe_kurzbz,
oe.organisationseinheittyp_kurzbz
FROM
public.tbl_benutzerfunktion bf
JOIN public.tbl_organisationseinheit oe USING (oe_kurzbz)
JOIN public.tbl_benutzer b USING (uid)
WHERE
b.uid = ?
AND b.aktiv = TRUE
AND funktion_kurzbz = \'Leitung\'
AND organisationseinheittyp_kurzbz = \'Kompetenzfeld\'
AND (datum_von IS NULL OR datum_von <= now())
AND (datum_bis IS NULL OR datum_bis >= now())
';
$parameters_array = array();
if (is_string($uid))
{
$parameters_array[] = $uid;
}
return $this->execQuery($query, $parameters_array);
}
public function insertBenutzerfunktion($Json)
{
unset($Json['benutzerfunktion_id']);
+4 -6
View File
@@ -242,7 +242,6 @@ class Message_model extends DB_Model
*/
public function getMessagesForTable($person_id, $offset, $limit)
{
$limitoffset = (!is_null($offset) && !is_null($limit)) ? 'limit ? offset ?' : '';
$sql = <<<EOSQL
with filtered_messages as (
select
@@ -311,12 +310,11 @@ class Message_model extends DB_Model
public.tbl_person pr on pr.person_id = fm.recipient_id
order by
m.insertamum DESC
{$limitoffset}
limit ?
offset ?;
EOSQL;
$parametersArray = $limitoffset
? array($person_id, $person_id, $limit, $offset)
: array($person_id, $person_id);
$parametersArray = array($person_id, $person_id, $limit, $offset);
$count = 0;
$data = $this->execQuery($sql, $parametersArray);
@@ -327,7 +325,7 @@ EOSQL;
$data = getData($data);
if($data)
{
$count = is_null($limit) ? 1 : ceil($data[0]->total_msgs / $limit);
$count = ceil($data[0]->total_msgs / $limit);
}
return success(['data' => $data, 'count' => $count]);
@@ -1,11 +0,0 @@
<?php
class VertragsbestandteilLohnguide_model extends DB_Model
{
public function __construct()
{
parent::__construct();
$this->dbTable = 'hr.tbl_vertragsbestandteil_lohnguide';
$this->pk = 'vertragsbestandteil_id';
}
}
@@ -37,8 +37,7 @@ class Vertragsbestandteil_model extends DB_Model
kf.arbeitgeber_frist, kf.arbeitnehmer_frist,
s.wochenstunden, s.teilzeittyp_kurzbz,
u.tage,
z.zeitaufzeichnung, z.azgrelevant, z.homeoffice,
lg.stellenbezeichnung, lg.vordienstzeit, lg.fachrichtung_kurzbz, lg.modellstelle_kurzbz, lg.kommentar_person, lg.kommentar_modellstelle
z.zeitaufzeichnung, z.azgrelevant, z.homeoffice
FROM
hr.tbl_vertragsbestandteil v
LEFT JOIN
@@ -64,8 +63,6 @@ class Vertragsbestandteil_model extends DB_Model
hr.tbl_vertragsbestandteil_urlaubsanspruch u USING(vertragsbestandteil_id)
LEFT JOIN
hr.tbl_vertragsbestandteil_zeitaufzeichnung z USING(vertragsbestandteil_id)
LEFT JOIN
hr.tbl_vertragsbestandteil_lohnguide lg USING(vertragsbestandteil_id)
EOSQL;
return $sql;
}
@@ -8,15 +8,9 @@ $this->load->view(
'axios027' => true,
'restclient' => true,
'vue3' => true,
'primevue3' => true,
'vuedatepicker11' => true,
'customJSs' => [
'vendor/moment/luxonjs/luxon.min.js'
],
'customJSModules' => ['public/js/apps/Dashboard/Admin.js'],
'customJSModules' => ['public/js/apps/Dashboard.js'],
'customCSSs' => [
'public/css/components/dashboard.css',
'public/css/components/primevue.css',
'public/css/components/dashboard.css'
],
'navigationcomponent' => true
)
@@ -31,7 +25,7 @@ $this->load->view(
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Dashboard</h1>
</div>
<dashboard-admin></dashboard-admin>
<core-dashboard dashboard="CIS" apiurl="<?= site_url('dashboard'); ?>"></core-dashboard>
</div>
</div>
@@ -8,12 +8,7 @@ $this->load->view(
'axios027' => true,
'restclient' => true,
'vue3' => true,
'vuedatepicker11' => true,
'primevue3' => true,
'customJSs' => [
'vendor/moment/luxonjs/luxon.min.js'
],
'customJSModules' => ['public/js/apps/Dashboard/Preview.js'],
'customJSModules' => ['public/js/apps/DashboardAdmin.js'],
'customCSSs' => [
'public/css/components/dashboard.css'
],
@@ -28,9 +23,9 @@ $this->load->view(
<div id="content">
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Dashboard <?= $dashboard_kurzbz ?></h1>
<h1 class="h2">Dashboard</h1>
</div>
<core-dashboard dashboard="<?= $dashboard_kurzbz ?>"></core-dashboard>
<dashboard-admin dashboard="CIS" apiurl="<?= site_url('dashboard'); ?>"></dashboard-admin>
</div>
</div>
+4 -6
View File
@@ -46,13 +46,12 @@ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<link rel="stylesheet" href="../../../skin/tablesort.css" type="text/css"/>
<link rel="stylesheet" href="../../../skin/style.css.php" type="text/css">
<link rel="stylesheet" type="text/css" href="../../../skin/jquery-ui-1.9.2.custom.min.css">
<script type="text/javascript" src="../../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="../../../vendor/christianbach/tablesorter/jquery.tablesorter.min.js"></script>
<script type="text/javascript" src="../../../vendor/components/jqueryui/jquery-ui.min.js"></script>
<script type="text/javascript" src="../../../include/js/jquery.ui.datepicker.translation.js"></script>
<script type="text/javascript" src="../../../vendor/jquery/sizzle/sizzle.js"></script>';
include('../../../include/meta/jquery.php');
include('../../../include/meta/jquery-tablesorter.php');
const MOODLE_ADDON_KURZBZ = 'moodle';
// Load Addons to get Moodle_Path
@@ -72,7 +71,7 @@ echo '
$("#myTable").tablesorter(
{
sortList: [[0,0],[1,0]],
widgets: [\'zebra\',\'filter\']
widgets: [\'zebra\']
});
}
);
@@ -152,9 +151,8 @@ foreach($service->result as $row)
$person = new person();
$person->getPersonFromBenutzer($row->operativ_uid);
$operativ = $person->nachname.' '.$person->vorname;
$oeBez = new organisationseinheit($row->oe_kurzbz);
echo '<tr>';
echo '<td>',$oeBez->bezeichnung,'</td>';
echo '<td>',$row->oe_kurzbz,'</td>';
echo '<td><b>'.$row->bezeichnung.'</b></td>';
echo '<td>',$row->beschreibung,'</td>';
echo '<td><nobr><a href="../profile/index.php?uid='.$row->design_uid.'">',$design,'</a></nobr></td>';
+1 -1
View File
@@ -293,7 +293,7 @@ else if (isset($_SESSION['pruefling_id']))
}
$lastsemester = $row->semester;
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px; margin-top: 5px;">';
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px;">';
echo '<tr><td class="HeaderTesttool">'. ($row->semester == '1' ? $p->t('testtool/basisgebiete') : $p->t('testtool/quereinstiegsgebiete')).'</td></tr>';
}
@@ -342,8 +342,6 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
<vbox>
<checkbox id="mitarbeiter-entwicklungsteam-detail-checkbox-neu" checked="true" hidden="true" />
<textbox id="mitarbeiter-entwicklungsteam-detail-textbox-studiengang" hidden="true" />
<textbox id="mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id" hidden="true" />
<groupbox id="mitarbeiter-entwicklungsteam-detail-groupbox" flex="1">
<caption label="Details" />
<grid id="mitarbeiter-entwicklungsteam-detail-grid" style="margin:4px;" flex="1">
@@ -1708,7 +1708,6 @@ function MitarbeiterEntwicklungsteamSelect()
document.getElementById('mitarbeiter-entwicklungsteam-detail-textbox-studiengang').value=studiengang_kz;
document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-beginn').value=beginn;
document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-ende').value=ende;
document.getElementById('mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id').value=entwicklungsteam_id;
MitarbeiterEntwicklungsteamDetailDisableFields(false);
}
@@ -1726,7 +1725,6 @@ function MitarbeiterEntwicklungsteamSpeichern()
studiengang_kz_old = document.getElementById('mitarbeiter-entwicklungsteam-detail-textbox-studiengang').value;
beginn = document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-beginn').value;
ende = document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-ende').value;
entwicklungsteam_id = document.getElementById('mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id').value;
if(studiengang_kz=='')
{
@@ -802,10 +802,6 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#fgm" />
<splitter class="tree-splitter"/>
<treecol id="student-prestudent-tree-rolle-faktiv" label="F-Aktiv" flex="1" hidden="true" persist="hidden, width, ordinal"
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#faktiv" />
<splitter class="tree-splitter"/>
</treecols>
<template>
@@ -832,7 +828,6 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/prestudentrolle/rdf#aktiv rdf:http://www.technikum-wien.at/prestudentrolle/rdf#stichtagsaktiv" label="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#updateamum"/>
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/prestudentrolle/rdf#aktiv rdf:http://www.technikum-wien.at/prestudentrolle/rdf#stichtagsaktiv" label="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#updatevon"/>
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/prestudentrolle/rdf#aktiv rdf:http://www.technikum-wien.at/prestudentrolle/rdf#stichtagsaktiv" label="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#fgm"/>
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/prestudentrolle/rdf#aktiv rdf:http://www.technikum-wien.at/prestudentrolle/rdf#stichtagsaktiv" label="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#faktiv"/>
</treerow>
</treeitem>
</treechildren>
-10
View File
@@ -3550,19 +3550,9 @@ function StudentZeugnisDokumentArchivieren()
case 'microcredentialzertifikat_1':
case 'microcredentialzertifikat_2':
case 'microcredentialzertifikat_3':
case 'microcredentialzertifikat_4':
case 'microcredential_1':
case 'microcredential_2':
case 'microcredential_3':
case 'microcredential_4':
case 'microdegree_1':
case 'microdegree_2':
case 'microdegree_3':
case 'microdegree_4':
case 'microdegreeabschluss_1':
case 'microdegreeabschluss_2':
case 'microdegreeabschluss_3':
case 'microdegreeabschluss_4':
xml = 'microcredential.xml.php';
break;
+1 -3
View File
@@ -364,10 +364,9 @@ class entwicklungsteam extends basis_db
$bismeldung_jahr = $datetime->format('Y');
//laden des Datensatzes
$qry = "SELECT tbl_entwicklungsteam.*, tbl_besqual.*, tbl_studiengang.studiengang_kz, tbl_studiengang.melderelevant
$qry = "SELECT *
FROM bis.tbl_entwicklungsteam
JOIN bis.tbl_besqual USING(besqualcode)
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)."
AND (beginn is NULL OR beginn <= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 12, 31))
AND (ende is NULL OR ende >= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 1, 1))";
@@ -395,7 +394,6 @@ class entwicklungsteam extends basis_db
$obj->insertvon = $row->insertvon;
$obj->ext_id = $row->ext_id;
$obj->besqual = $row->besqualbez;
$obj->melderelevant = $this->db_parse_bool($row->melderelevant);
$this->result[] = $obj;
}
+7 -164
View File
@@ -552,41 +552,9 @@ class lehreinheitmitarbeiter extends basis_db
$beginn = new DateTime($beginn);
$ende = new DateTime($ende);
// get relevant Studiensemester
$studiensemester_kurzbz_arr = [];
$qry = '
SELECT
studiensemester_kurzbz
FROM
public.tbl_studiensemester
WHERE
start BETWEEN
'. $this->db_add_param($beginn->format('Y-m-d')). ' AND
'. $this->db_add_param($ende->format('Y-m-d'));
if ($this->db_query($qry))
{
while($row = $this->db_fetch_object())
{
$studiensemester_kurzbz_arr[] = $row->studiensemester_kurzbz;
}
}
else
{
$this->errormsg = 'Fehler bei der Datenbankabfrage';
return false;
}
$lehrgaengeDistr = $this->_getLehrgaengeForDistribution($studiensemester_kurzbz_arr);
if (!is_array($studiensemester_kurzbz_arr) || empty($studiensemester_kurzbz_arr)) return true;
$qry = '
WITH semester_sws_tbl AS (
SELECT
DISTINCT lehreinheit_id, studiensemester_kurzbz, lema.semesterstunden,
stg.studiengang_kz, stg.melde_studiengang_kz, stg.lgartcode, stg.melderelevant
SELECT DISTINCT lehreinheit_id, studiensemester_kurzbz, lema.semesterstunden, stg.studiengang_kz
FROM lehre.tbl_lehreinheitmitarbeiter lema
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
@@ -596,104 +564,38 @@ class lehreinheitmitarbeiter extends basis_db
JOIN public.tbl_studiengang stg ON stg.studiengang_kz = sto.studiengang_kz
JOIN public.tbl_studiensemester ss USING (studiensemester_kurzbz)
WHERE mitarbeiter_uid = '. $this->db_add_param($uid). '
AND ss.studiensemester_kurzbz IN ('.$this->implode4SQL($studiensemester_kurzbz_arr).')
AND (
ss.start BETWEEN
'. $this->db_add_param($beginn->format('Y-m-d')). ' AND
'. $this->db_add_param($ende->format('Y-m-d')). ')
-- nur lehre, die bisgemeldet wird
AND lema.bismelden
AND stg.melderelevant
-- keine lehreinheiten ohne semesterstunden
AND lema.semesterstunden != 0
AND lema.semesterstunden != 0
)
SELECT
studiengang_kz,
studiensemester_kurzbz,
melde_studiengang_kz,
lgartcode,
sum(semesterstunden) AS summe,
round(sum(semesterstunden) / 15, 2) AS sws
FROM
semester_sws_tbl
GROUP BY
studiengang_kz,
studiensemester_kurzbz,
melde_studiengang_kz,
lgartcode
studiensemester_kurzbz
ORDER BY
studiengang_kz;
';
if ($this->db_query($qry))
{
$additionalLehrgaenge = [];
while($row = $this->db_fetch_object())
{
$obj = new StdClass();
$obj->studiengang_kz = $row->studiengang_kz;
$obj->studiensemester_kurzbz = $row->studiensemester_kurzbz;
$obj->melde_studiengang_kz = $row->melde_studiengang_kz;
$obj->lgartcode = $row->lgartcode;
$obj->sws = $row->sws;
if (isset($lehrgaengeDistr[$uid][$row->studiensemester_kurzbz]))
{
$lehrgaenge = $lehrgaengeDistr[$uid][$row->studiensemester_kurzbz];
foreach ($lehrgaenge as $lehreinheit_id => $lehrgangKzArr)
{
// wenn lehrgang gefunden, zusammenhängende Lehrgaenge holen und sws aufteilen
if (array_key_exists($row->studiengang_kz, $lehrgangKzArr))
{
foreach ($lehrgangKzArr as $studiengang_kz => $lehrgang)
{
// check: nur eine Studiengangsverknüpfung pro Mitarbeiter, Semester, und Referenzstudiengang
if (
$studiengang_kz == $row->studiengang_kz
|| isset(
$additionalLehrgaenge[$uid][$row->studiensemester_kurzbz][$row->studiengang_kz][$studiengang_kz]
)
) continue;
// Lehrgang erstellen
$lg = new StdClass();
$lg->mitarbeiter_uid = $uid;
$lg->melde_studiengang_kz = $lehrgang->melde_studiengang_kz;
$lg->lgartcode = $lehrgang->lgartcode;
$lg->studiengang_kz = $lehrgang->studiengang_kz;
$lg->studiensemester_kurzbz = $lehrgang->studiensemester_kurzbz;
$lg->summe = $row->summe;
$lg->sws = $row->sws;
// Lehrgang, der mit Ursprungsstudiengang aufgrund lehreinheit "verknüpft" ist, hinzufügen
$additionalLehrgaenge[$uid][$row->studiensemester_kurzbz][$row->studiengang_kz][$studiengang_kz] = $lg;
}
}
}
// ignorieren, wenn für den Studiengang keine verknüpften Lehrgaenge hat
if (isset($additionalLehrgaenge[$uid][$row->studiensemester_kurzbz][$row->studiengang_kz]))
{
$addLehrgaenge = $additionalLehrgaenge[$uid][$row->studiensemester_kurzbz][$row->studiengang_kz];
// sws Durchschnitt über alle verknuepften Lehrgaenge berechnet
$summeSws = $row->summe/(count($addLehrgaenge) + 1);
$sws = $row->sws/(count($addLehrgaenge) + 1);
// neue sws zuweisen
$obj->summe = $summeSws;
$obj->sws = $sws;
foreach ($addLehrgaenge as $conn_ws_studiengang_kz => $lehrgang)
{
// sws fuer jeden verknuepften Lehrgang zuweisen
$lehrgang->summe = $summeSws;
$lehrgang->sws = $sws;
// neue lehrgang sws hinzufuegen
$this->result [] = $lehrgang;
}
}
}
$this->result []= $obj;
}
return true;
@@ -753,63 +655,4 @@ class lehreinheitmitarbeiter extends basis_db
return false;
}
/**
* Get "connected" Lehrgaenge for equal sws distribution.
* @param $studiensemester_kurzbz_arr all semester for which Lehrgaenge should be retrieved
* @return object success or error
*/
private function _getLehrgaengeForDistribution($studiensemester_kurzbz_arr)
{
if (!is_array($studiensemester_kurzbz_arr) || empty($studiensemester_kurzbz_arr)) return [];
$qry = "
WITH gruppen AS (
SELECT
mitarbeiter_uid, lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, sem.start, sem.ende,
lehreinheitgruppe_id, studiengang_kz, melde_studiengang_kz, lgartcode
FROM
lehre.tbl_lehreinheitmitarbeiter lema
JOIN lehre.tbl_lehreinheit le USING (lehreinheit_id)
JOIN lehre.tbl_lehreinheitgruppe legr USING (lehreinheit_id)
JOIN public.tbl_studiengang stg USING (studiengang_kz)
JOIN public.tbl_studiensemester sem USING (studiensemester_kurzbz)
WHERE
bismelden
AND stg.melderelevant
AND stg.typ = 'l'
AND le.studiensemester_kurzbz IN (".$this->implode4SQL($studiensemester_kurzbz_arr).")
)
SELECT
DISTINCT mitarbeiter_uid, studiensemester_kurzbz, lehreinheit_id, studiengang_kz, melde_studiengang_kz, lgartcode
FROM
gruppen gr
GROUP BY
mitarbeiter_uid, studiensemester_kurzbz, lehreinheit_id, studiengang_kz, melde_studiengang_kz, lgartcode
ORDER BY
mitarbeiter_uid, studiensemester_kurzbz, lehreinheit_id, studiengang_kz, melde_studiengang_kz, lgartcode";
$lehrgaengeDistributions = [];
if($this->db_query($qry))
{
while($row = $this->db_fetch_object())
{
// group by properties
$lehrgaengeDistributions
[$row->mitarbeiter_uid]
[$row->studiensemester_kurzbz]
[$row->lehreinheit_id]
[$row->studiengang_kz]
= $row;
}
}
else
{
$this->errormsg = 'Fehler bei der Datenbankabfrage';
return false;
}
return $lehrgaengeDistributions;
}
}
-1
View File
@@ -706,7 +706,6 @@ class prestudent extends person
$rolle->bestaetigtam = $row->bestaetigtam;
$rolle->bestaetigtvon = $row->bestaetigtvon;
$rolle->fgm = $row->fgm;
$rolle->faktiv = $this->db_parse_bool($row->faktiv);
$rolle->anmerkung_status = $row->anmerkung;
$rolle->bewerbung_abgeschicktamum = $row->bewerbung_abgeschicktamum;
$rolle->rt_stufe = $row->rt_stufe;
-3
View File
@@ -193,6 +193,3 @@
word-break: break-word;
}
.news-list-item p {
word-break: break-word;
}
@@ -16,31 +16,23 @@
*/
export default {
get(widget) {
getAllStudienSemester(studiensemester, studiengang, semester, studienplan) {
return {
method: 'get',
url: '/api/frontend/v1/dashboard/widget/get/' + widget
url: 'api/frontend/v1/Studium/getStudienAllSemester/',
params: {studiensemester, studiengang, semester, studienplan}
};
},
list(dashboard) {
getLvPlanForStudiensemester(studiensemester, lvid) {
return {
method: 'get',
url: '/api/frontend/v1/dashboard/widget/list/' + dashboard
url: '/api/frontend/v1/LvPlan/getLvPlanForStudiensemester/'+ studiensemester + '/' + lvid
};
},
listAllowed(dashboard) {
getLvEvaluierungInfo(studiensemester_kurzbz, lvid) {
return {
method: 'get',
url: '/api/frontend/v1/dashboard/widget/listAllowed/' + dashboard
url: 'api/frontend/v1/Studium/getLvEvaluierungInfo/' + studiensemester_kurzbz + '/' + lvid
};
},
setAllowed(dashboard_id, widget_id, allowed) {
return {
method: 'post',
url: '/api/frontend/v1/dashboard/widget/setAllowed',
params: {
dashboard_id, widget_id, allowed
}
};
}
};
}
-46
View File
@@ -1,46 +0,0 @@
/**
* Copyright (C) 2026 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 {
list() {
return {
method: 'get',
url: 'api/frontend/v1/dashboard/board/list'
};
},
add(params) {
return {
method: 'post',
url: 'api/frontend/v1/dashboard/board/create',
params
};
},
update(params) {
return {
method: 'post',
url: 'api/frontend/v1/dashboard/board/update',
params
};
},
delete(dashboard_id) {
return {
method: 'post',
url: 'api/frontend/v1/dashboard/board/delete',
params: { dashboard_id }
};
}
}
-47
View File
@@ -1,47 +0,0 @@
/**
* Copyright (C) 2026 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 {
list(dashboard_kurzbz) {
return {
method: 'get',
url: 'api/frontend/v1/dashboard/preset/list/'
+ encodeURIComponent(dashboard_kurzbz)
};
},
getBatch(params) {
return {
method: 'post',
url: 'api/frontend/v1/dashboard/preset/getBatch',
params
};
},
addWidget(params) {
return {
method: 'post',
url: 'api/frontend/v1/dashboard/preset/addWidget',
params
};
},
removeWidget(params) {
return {
method: 'post',
url: 'api/frontend/v1/dashboard/preset/removeWidget',
params
};
}
};
-45
View File
@@ -1,45 +0,0 @@
/**
* Copyright (C) 2026 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(dashboard) {
return {
method: 'get',
url: '/api/frontend/v1/dashboard/user/get/' + dashboard
};
},
addWidget(dashboard, widget) {
return {
method: 'post',
url: '/api/frontend/v1/dashboard/user/addWidget',
params: {
dashboard,
widget
}
};
},
removeWidget(dashboard, widget) {
return {
method: 'post',
url: '/api/frontend/v1/dashboard/user/removeWidget',
params: {
dashboard,
widget
}
};
}
};
+5 -8
View File
@@ -17,16 +17,13 @@
export default {
getMessages(params) {
let url = 'api/frontend/v1/messages/messages/getMessages'
+ '/' + params.id
+ '/' + params.type;
if(params.size && params.page) {
url += '/' + params.size
+ '/' + params.page;
}
return {
method: 'get',
url: url
url: 'api/frontend/v1/messages/messages/getMessages/'
+ params.id + '/'
+ params.type + '/'
+ params.size + '/'
+ params.page
};
},
getVorlagen(){
-1
View File
@@ -60,7 +60,6 @@ export default {
};
},
deleteFile(akte_id){
console.log("in deleteFile " + akte_id);
return {
method: 'post',
url: 'api/frontend/v1/stv/dokumente/deleteAkte/' + akte_id,
+9 -60
View File
@@ -1,67 +1,16 @@
import { CoreNavigationCmpt } from '../../components/navigation/Navigation.js';
import {CoreNavigationCmpt} from '../../components/navigation/Navigation.js';
import DashboardAdmin from '../../components/Dashboard/Admin.js';
import PluginsPhrasen from '../../plugins/Phrasen.js';
import ApiRenderers from '../../api/factory/renderers.js';
const app = Vue.createApp({
name: 'DashboardAdminApp',
data: () => ({
appSideMenuEntries: {},
renderers: null
}),
components: {
CoreNavigationCmpt,
DashboardAdmin
},
provide() {
return {
// TODO(chris): move those two into the components that need it
renderers: Vue.computed(() => this.renderers),
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone
};
},
created() {
this.$api
.call(ApiRenderers.loadRenderers())
.then(res => {
for (let rendertype of Object.keys(res.data)) {
let modalTitle = null;
let modalContent = null;
let calendarEvent = null;
if (res.data[rendertype].modalTitle)
modalTitle = Vue.markRaw(Vue.defineAsyncComponent(() => import(res.data[rendertype].modalTitle)));
if (res.data[rendertype].modalContent)
modalContent = Vue.markRaw(Vue.defineAsyncComponent(() => import(res.data[rendertype].modalContent)));
if (res.data[rendertype].calendarEvent)
calendarEvent = Vue.markRaw(Vue.defineAsyncComponent(() => import(res.data[rendertype].calendarEvent)));
if (res.data[rendertype].calendarEventStyles) {
var head = document.head;
if (!head.querySelector(`link[href="${res.data[rendertype].calendarEventStyles}"]`)) {
var link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.href = res.data[rendertype].calendarEventStyles;
head.appendChild(link);
}
}
if (this.renderers === null) {
this.renderers = {};
}
if (!this.renderers[rendertype]) {
this.renderers[rendertype] = {}
}
this.renderers[rendertype].modalTitle = modalTitle;
this.renderers[rendertype].modalContent = modalContent;
this.renderers[rendertype].calendarEvent = calendarEvent;
}
})
.catch(this.$fhcAlert.handleSystemErrors);
}
name: 'AdminApp',
data: () => ({
appSideMenuEntries: {}
}),
components: {
CoreNavigationCmpt,
DashboardAdmin
}
});
app.use(PluginsPhrasen);
app.directive('tooltip', primevue.tooltip);
app.mount('#main');
-17
View File
@@ -1,17 +0,0 @@
import {CoreNavigationCmpt} from '../../components/navigation/Navigation.js';
import CoreDashboard from '../../components/Dashboard/Dashboard.js';
import PluginsPhrasen from '../../plugins/Phrasen.js';
const app = Vue.createApp({
name: 'DashboardPreviewApp',
data: () => ({
appSideMenuEntries: {}
}),
components: {
CoreNavigationCmpt,
CoreDashboard
}
});
app.use(PluginsPhrasen);
app.directive('tooltip', primevue.tooltip);
app.mount('#main');
+1 -1
View File
@@ -17,7 +17,7 @@ export default {
</template>
<template v-slot:footer>
<button type="button" class="btn btn-primary" @click="result=true;this.hide()">OK</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{this.$p.t('ui', 'cancel')}}</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
</template>
</bs-modal>`
}
@@ -2,6 +2,7 @@ import BsModal from "../../Bootstrap/Modal.js";
import LvMenu from "./LvMenu.js";
import ApiAddons from '../../../api/factory/addons.js';
import ApiCisStudium from '../../../api/factory/cis/studium.js';
export default {
@@ -63,7 +64,8 @@ export default {
// check lv evaluierung info
if (this.studium_studiensemester) {
this.$fhcApi.factory.studium.getLvEvaluierungInfo(this.studium_studiensemester, this.event.lehreinheit_id ?? this.event.lehrveranstaltung_id)
this.$api
.call(ApiCisStudium.getLvEvaluierungInfo(this.studium_studiensemester, this.event.lehreinheit_id ?? this.event.lehrveranstaltung_id))
.then(data => data.data)
.then(res => {
this.lvEvaluierungMessage = res.message;
@@ -72,7 +74,8 @@ export default {
// check if the lv has lvplan entries for this studiensemester
if (this.studiensemester && this.event) {
return this.$fhcApi.factory.studium.getLvPlanForStudiensemester(this.studiensemester, this.event.lehreinheit_id ?? this.event.lehrveranstaltung_id)
return this.$api
.call(ApiCisStudium.getLvPlanForStudiensemester(this.studiensemester, this.event.lehreinheit_id ?? this.event.lehrveranstaltung_id))
.then(data => data.data)
.then(res => {
if (Array.isArray(res) && res.length > 0) {
+16 -11
View File
@@ -1,4 +1,5 @@
import LvUebersicht from "../Mylv/LvUebersicht.js";
import ApiCisStudium from '../../../api/factory/cis/studium.js';
export default {
@@ -97,28 +98,32 @@ export default {
return value;
},
changeSelectedStudienSemester(studiensemester_kurzbz) {
this.$fhcApi.factory.studium.getAllStudienSemester(studiensemester_kurzbz, this.selectedStudiengang, this.selectedSemester, this.selectedStudienordnung)
return this.$api
.call(ApiCisStudium.getAllStudienSemester(studiensemester_kurzbz, this.selectedStudiengang, this.selectedSemester, this.selectedStudienordnung))
.then(data => data.data)
.then(res => {
this.extractPropertyValues(res);
})
},
changeSelectedStudienGang(studiengang_kz) {
this.$fhcApi.factory.studium.getAllStudienSemester(this.selectedStudiensemester, studiengang_kz, this.selectedSemester, this.selectedStudienordnung)
return this.$api
.call(ApiCisStudium.getAllStudienSemester(this.selectedStudiensemester, studiengang_kz, this.selectedSemester, this.selectedStudienordnung))
.then(data => data.data)
.then(res => {
this.extractPropertyValues(res);
})
},
changeSelectedSemester(semester) {
this.$fhcApi.factory.studium.getAllStudienSemester(this.selectedStudiensemester, this.selectedStudiengang, semester, this.selectedStudienordnung)
return this.$api
.call(ApiCisStudium.getAllStudienSemester(this.selectedStudiensemester, this.selectedStudiengang, semester, this.selectedStudienordnung))
.then(data => data.data)
.then(res => {
this.extractPropertyValues(res);
})
},
changeSelectedStudienPlan(studienplan_id) {
this.$fhcApi.factory.studium.getAllStudienSemester(this.selectedStudiensemester, this.selectedStudiengang, this.selectedSemester, studienplan_id)
return this.$api
.call(ApiCisStudium.getAllStudienSemester(this.selectedStudiensemester, this.selectedStudiengang, this.selectedSemester, studienplan_id))
.then(data => data.data)
.then(res => {
this.extractPropertyValues(res);
@@ -209,7 +214,7 @@ export default {
default:
return `${studiensemester}`;
}
}
},
},
computed:{
@@ -256,12 +261,12 @@ export default {
const studienordnung = JSON.parse(this.getDataFromLocalStorage("studienordnung")) ?? undefined;
// only fetch default data if no data is stored in the local storage
this.$fhcApi.factory.studium.getAllStudienSemester(studiensemester, studiengang, semester, studienordnung)
.then(data => data.data)
.then(res => {
this.extractPropertyValues(res);
})
this.$api
.call(ApiCisStudium.getAllStudienSemester(studiensemester, studiengang, semester, studienordnung))
.then(data => data.data)
.then(res => {
this.extractPropertyValues(res);
})
},
template: `
+34 -66
View File
@@ -3,20 +3,15 @@ import DashboardAdminEdit from "./Admin/Edit.js";
import DashboardAdminWidgets from "./Admin/Widgets.js";
import DashboardAdminPresets from "./Admin/Presets.js";
import ApiDashboardBoard from "../../api/factory/dashboard/board.js";
import ApiDashboardWidget from "../../api/factory/dashboard/widget.js";
export default {
name: 'DashboardAdmin',
components: {
DashboardAdminEdit,
DashboardAdminWidgets,
DashboardAdminPresets,
DashboardAdminPresets
},
provide() {
return {
adminMode: true,
widgetsSetup: Vue.computed(() => this.dashboards[this.current] ? this.dashboards[this.current].widgetSetup : null)
adminMode: true
};
},
data() {
@@ -27,6 +22,9 @@ export default {
};
},
computed: {
apiurl() {
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/dashboard';
},
dashboard() {
return this.dashboards.find(el => el.dashboard_id == this.current);
}
@@ -37,50 +35,33 @@ export default {
BsPrompt.popup('New Dashboard name').then(
name => {
_name = name;
const params = {
return axios.post(this.apiurl + '/Dashboard/create', {
dashboard_kurzbz: name
};
return this.$api
.call(ApiDashboardBoard.add(params))
.then(response =>{
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
let newDashboard = {
dashboard_id: response.data,
dashboard_kurzbz: _name,
beschreibung: ''
};
this.dashboards.push(newDashboard);
this.current = newDashboard.dashboard_id;
})
.catch(this.$fhcAlert.handleSystemError);
});
})
}
).then(res => {
let newDashboard = {
dashboard_id: res.data.retval,
dashboard_kurzbz: _name,
beschreibung: ''
};
this.dashboards.push(newDashboard);
this.current = newDashboard.dashboard_id;
}).catch(err => err !== undefined ? console.error('ERROR:', err) : 0);
},
dashboardUpdate(dashboard) {
return this.$api
.call(ApiDashboardBoard.update(dashboard))
.then(response =>{
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
let old = this.dashboards.find(el => el.dashboard_id == dashboard.dashboard_id);
old.dashboard_kurzbz = dashboard.dashboard_kurzbz;
old.beschreibung = dashboard.beschreibung;
})
.catch(this.$fhcAlert.handleSystemError);
// TODO(chris): Loading or message
axios.post(this.apiurl + '/Dashboard/update', dashboard).then(() => {
let old = this.dashboards.find(el => el.dashboard_id == dashboard.dashboard_id);
old.dashboard_kurzbz = dashboard.dashboard_kurzbz;
old.beschreibung = dashboard.beschreibung;
}).catch(err => console.error('ERROR:', err));
},
dashboardDelete(dashboard_id) {
return this.$api
.call(ApiDashboardBoard.delete(dashboard_id))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.current = -1;
this.dashboards = this.dashboards.filter(el => el.dashboard_id != dashboard_id);
});
axios.post(this.apiurl + '/Dashboard/delete', {dashboard_id}).then(() => {
this.current = -1;
this.dashboards = this.dashboards.filter(el => el.dashboard_id != dashboard_id);
}).catch(err => console.error('ERROR:', err));
},
assignWidgets(widgets) {
this.widgets = widgets;
@@ -91,35 +72,22 @@ export default {
}
},
created() {
this.$api
.call(ApiDashboardBoard.list())
.then(result => {
this.dashboards = result.data.retval;
for (const dashboard of this.dashboards) {
this.$api
.call(ApiDashboardWidget.list(dashboard.dashboard_id))
.then(res => {
dashboard.widgetSetup = res.data;
})
.catch(this.$fhcAlert.handleSystemError);
}
})
.catch(this.$fhcAlert.handleSystemError);
axios.get(this.apiurl + '/Dashboard').then(res => {
this.dashboards = res.data.retval;
}).catch(err => console.error('ERROR:', err));
},
template: `<div class="dashboard-admin">
<div class="input-group">
<label for="dashboard-select" class="input-group-text">Dashboard:</label>
<select id="dashboard-select" class="form-select" v-model="current">
<label for="dashbaord-select" class="input-group-text">Dashboard:</label>
<select id="dashbaord-select" class="form-select" v-model="current">
<option v-for="dashboard in dashboards" :key="dashboard.dashboard_id" :value="dashboard.dashboard_id">{{dashboard.dashboard_kurzbz}}</option>
</select>
<button class="btn btn-outline-secondary" type="button" @click="dashboardAdd"><i class="fa-solid fa-plus"></i></button>
</div>
<div v-if="dashboard">
<ul class="nav nav-tabs mt-3" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link" id="edit-tab" data-bs-toggle="tab" data-bs-target="#edit" type="button" role="tab" aria-controls="edit" aria-selected="false">{{this.$p.t('ui', 'bearbeiten')}}</button>
<button class="nav-link" id="edit-tab" data-bs-toggle="tab" data-bs-target="#edit" type="button" role="tab" aria-controls="edit" aria-selected="false">Edit</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link active" id="widgets-tab" data-bs-toggle="tab" data-bs-target="#widgets" type="button" role="tab" aria-controls="widgets" aria-selected="true">Widgets</button>
@@ -133,7 +101,7 @@ export default {
<dashboard-admin-edit v-bind="dashboard" :key="dashboard.dashboard_id" @change="dashboardUpdate($event)" @delete="dashboardDelete($event)"></dashboard-admin-edit>
</div>
<div class="tab-pane fade show active" id="widgets" role="tabpanel" aria-labelledby="widgets-tab">
<dashboard-admin-widgets :key="dashboard.dashboard_id" :dashboard_id="dashboard.dashboard_id" :widgets="widgets" @assign-widgets="assignWidgets"></dashboard-admin-widgets>
<dashboard-admin-widgets :key="dashboard.dashboard_id" :dashboard_id="dashboard.dashboard_id" :widgets="widgets" @change="test" @assign-widgets="assignWidgets"></dashboard-admin-widgets>
</div>
<div class="tab-pane fade" id="presets" role="tabpanel" aria-labelledby="presets-tab">
<dashboard-admin-presets :dashboard="dashboard.dashboard_kurzbz" :widgets="widgets"></dashboard-admin-presets>
+3 -4
View File
@@ -18,8 +18,7 @@ export default {
},
methods: {
sendDelete() {
BsConfirm.popup(this.$p.t('ui', 'confirm_delete') + " " + this.$p.t('ui', 'deleteInfo'))
.then(() => this.$emit('delete', this.dashboard_id)).catch();
BsConfirm.popup('Sure?').then(() => this.$emit('delete', this.dashboard_id)).catch();
}
},
template: `<div class="dashboard-admin-edit px-3">
@@ -32,8 +31,8 @@ export default {
<textarea id="dashboard-admin-edit-beschreibung" class="form-control" v-model="desc"></textarea>
</div>
<div>
<button class="btn btn-danger" @click="sendDelete">{{this.$p.t('ui', 'loeschen')}}</button>
<button class="btn btn-primary" @click="$emit('change', {dashboard_id,dashboard_kurzbz:kurzbz,beschreibung:desc})">{{this.$p.t('ui', 'btnAktualisieren')}}</button>
<button class="btn btn-danger" @click="sendDelete">Delete</button>
<button class="btn btn-primary" @click="$emit('change', {dashboard_id,dashboard_kurzbz:kurzbz,beschreibung:desc})">Update</button>
</div>
</div>`
}
+89 -111
View File
@@ -1,7 +1,6 @@
import DashboardSection from "../Section.js";
import DashboardWidgetPicker from "../Widget/Picker.js";
import ObjectUtils from "../../../helpers/ObjectUtils.js";
import ApiDashboardPreset from "../../../api/factory/dashboard/preset.js";
export default {
components: {
@@ -18,6 +17,9 @@ export default {
tmpLoading: ''
}),
computed: {
apiurl() {
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/dashboard';
},
pickerWidgets() {
return this.widgets.filter(widget => widget.allowed);
}
@@ -26,7 +28,6 @@ export default {
widgetAdd(section_name, widget) {
this.$refs.widgetpicker.getWidget().then(widget_id => {
widget.widget = widget_id;
widget.id = 'loading_' + String((new Date()).valueOf());
delete widget.custom;
widget.preset = 1;
let loading = {...widget};
@@ -35,153 +36,130 @@ export default {
if (section.name == section_name)
section.widgets.push(loading);
});
const params = {
dashboard: this.dashboard,
axios.post(this.apiurl + '/Config/addWidgetsToPreset', {
db: this.dashboard,
funktion_kurzbz: section_name,
widget
};
return this.$api
.call(ApiDashboardPreset.addWidget(params))
.then(result => {
let newId = result.data;
widget.id = newId;
widget.custom = 1;
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.splice(section.widgets.indexOf(loading),1);
section.widgets.push(widget);
}
});
this.funktionen.forEach(funktion => {
if(funktion.funktion_kurzbz === section_name && funktion.has_preset < 1) {
funktion.has_preset = 1;
}
});
})
.catch(this.$fhcAlert.handleSystemError);
})
.catch(() => {});
widgets: [widget]
}).then(result => {
let newId = Object.keys(result.data.retval.data[section_name].widgets).pop();
widget.id = newId;
widget.custom = 1;
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.splice(section.widgets.indexOf(loading),1);
section.widgets.push(widget);
}
});
}).catch(error => {
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
}).catch(() => {});
},
widgetUpdate(section_name, payload) {
payload = payload[section_name];
for (var k in payload) {
const section = this.sections.find(section => section.name == section_name);
for (var wid in section.widgets) {
if (section.widgets[wid].id == k) {
payload[k] = ObjectUtils.mergeDeep(section.widgets[wid], payload[k]);
// NOTE(chris): remove internal props
for (var prop of ['_x', '_y', '_w', '_h', 'index', 'id'])
if (payload[k][prop])
delete payload[k][prop];
for (var i in this.sections) {
if (this.sections[i].name == section_name) {
for (var wid in this.sections[i].widgets) {
if (this.sections[i].widgets[wid].id == k) {
payload[k] = ObjectUtils.mergeDeep(this.sections[i].widgets[wid], payload[k]);
// NOTE(chris): remove internal props
for (var prop in {_x:1,_y:1,_w:1,_h:1,index:1,id:1})
if (payload[k][prop])
delete payload[k][prop];
break;
}
}
break;
}
}
payload[k].widgetid = k;
delete payload[k].custom;
}
this.$api
.call(Object.entries(payload).map(([key, widget]) => [
key,
ApiDashboardPreset.addWidget({
dashboard: this.dashboard,
funktion_kurzbz: section_name,
widget
})
]))
.then(result => {
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.forEach((widget, i) => {
if (payload[widget.id]) {
payload[widget.id].id = widget.id;
payload[widget.id].index = widget.index;
section.widgets[i] = payload[widget.id];
section.widgets[i].custom = 1;
}
});
}
});
})
.catch(this.$fhcAlert.handleSystemError);
axios.post(this.apiurl + '/Config/addWidgetsToPreset', {
db: this.dashboard,
funktion_kurzbz: section_name,
widgets: payload
}).then(() => {
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.forEach((widget, i) => {
if (payload[widget.id]) {
payload[widget.id].id = widget.id;
payload[widget.id].index = widget.index;
section.widgets[i] = payload[widget.id];
section.widgets[i].custom = 1;
}
});
}
});
}).catch(error => {
// TODO(chris): revert placement on failure
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
},
widgetRemove(section_name, id) {
const params = {
axios.post(this.apiurl + '/Config/removeWidgetFromPreset', {
db: this.dashboard,
funktion_kurzbz: section_name,
widgetid: id
};
return this.$api
.call(ApiDashboardPreset.removeWidget(params))
.then(result => {
this.sections.forEach(section => {
if (section.name == section_name)
section.widgets = section.widgets.filter(widget => widget.id != id);
});
})
.catch(this.$fhcAlert.handleSystemError);
}).then(() => {
this.sections.forEach(section => {
if (section.name == section_name)
section.widgets = section.widgets.filter(widget => widget.id != id);
});
}).catch(error => {
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
},
loadSections(evt) {
let funktionen = Array.from(evt.target.querySelectorAll("option:checked"),e=>e.value);
this.sections = [];
this.tmpLoading = funktionen.join('###');
const params = {
axios.get(this.apiurl + '/Config/presetBatch', {params: {
db: this.dashboard,
funktionen
};
return this.$api
.call(ApiDashboardPreset.getBatch(params))
.then(result => {
if (this.tmpLoading !== funktionen.join('###'))
return; // NOTE(chris): prevent race condition
for (var section in result.data) {
let widgets = [];
for (var wid in result.data[section]) {
result.data[section][wid].id = wid;
result.data[section][wid].custom = 1;
widgets.push(result.data[section][wid]);
}
this.sections.push({
name: section,
widgets
});
}}).then(res => {
if (this.tmpLoading !== funktionen.join('###'))
return; // NOTE(chris): prevent race condition
for (var section in res.data.retval) {
let widgets = [];
for (var wid in res.data.retval[section]) {
res.data.retval[section][wid].id = wid;
res.data.retval[section][wid].custom = 1;
widgets.push(res.data.retval[section][wid]);
}
})
.catch(this.$fhcAlert.handleSystemError);
},
loadFunktionen() {
this.$api
.call(ApiDashboardPreset.list(this.dashboard))
.then(result => {
this.funktionen = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.sections.push({
name: section,
widgets
});
}
}).catch(err => console.error('ERROR:', err));
}
},
created() {
this.loadFunktionen();
axios.get(this.apiurl + '/Config/funktionen').then(res => {
this.funktionen = {general: 'GENERAL'};
res.data.retval.forEach(funktion => {
this.funktionen[funktion.funktion_kurzbz] = funktion.beschreibung;
});
}).catch(err => console.error('ERROR:', err));
},
watch: {
dashboard() {
// TODO(chris): this should be done without a watcher
this.loadSections({target:this.$refs.funktionenList});
this.loadFunktionen();
}
},
template: `<div class="dashboard-admin-presets">
<div class="row">
<div class="col-3">
<select ref="funktionenList" style="height:30em" class="form-control" multiple @input="loadSections">
<option
v-for="funktion in funktionen"
:key="funktion.funktion_kurzbz"
:value="funktion.funktion_kurzbz"
:class="(funktion.has_preset > 0) ? 'fw-bold' : ''"
>{{ funktion.beschreibung }}</option>
<option v-for="name,id in funktionen" :key="id" :value="id">{{ name }}</option>
</select>
</div>
<div class="col-9">
+20 -13
View File
@@ -1,5 +1,3 @@
import ApiDashboardWidget from "../../../api/factory/dashboard/widget.js";
export default {
emits: [
"change",
@@ -9,25 +7,34 @@ export default {
dashboard_id: Number,
widgets: Array
},
computed: {
apiurl() {
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/dashboard';
}
},
methods: {
sendChange(widget_id) {
let allow = !this.widgets.find(el => el.widget_id == widget_id).allowed;
this.$api
.call(ApiDashboardWidget.setAllowed(this.dashboard_id, widget_id, allow))
.catch(this.$fhcAlert.handleSystemError);
axios.post(this.apiurl + '/Widget/setAllowed', {
dashboard_id: this.dashboard_id,
widget_id,
action: allow ? 'add' : 'delete'
}).catch(err => console.error('ERROR: ' + err));
}
},
created() {
this.$api
.call(ApiDashboardWidget.list(this.dashboard_id))
.then(result => {
this.$emit('assignWidgets', result.data.map(el => ({
axios.get(this.apiurl + '/Widget/getAll', {
params:{
dashboard_id: this.dashboard_id
}
}).then(
result => {
this.$emit('assignWidgets', result.data.retval.map(el => ({
...el,
allowed: !!el.allowed
...{setup:JSON.parse(el.setup),arguments:JSON.parse(el.arguments),allowed:!!el.allowed}
})));
})
.catch(this.$fhcAlert.handleSystemError);
}
).catch(err => console.error('ERROR:', err));
},
template: `
<div class="dashboard-admin-widgets">
+138 -105
View File
@@ -2,8 +2,7 @@ import DashboardSection from "./Section.js";
import DashboardWidgetPicker from "./Widget/Picker.js";
import ObjectUtils from "../../helpers/ObjectUtils.js";
import ApiDashboardWidget from '../../api/factory/dashboard/widget.js';
import ApiDashboardUser from '../../api/factory/dashboard/user.js';
import ApiDashboard from '../../api/factory/cis/dashboard.js';
export default {
name: 'Dashboard',
@@ -21,147 +20,181 @@ export default {
type: Object,
required: true,
validator(value) {
return value && value.name && value.timezone
return value && value.name && value.uid && value.timezone
}
}
},
data() {
return {
widgets: [],
originalWidgets: {},
widgetsSetup: null,
editMode: false
sections: [],
widgets: null,
editMode: false,
viewDataInternal: this.viewData
}
},
provide() {
return {
editMode: Vue.computed(()=>this.editMode),
widgetsSetup: Vue.computed(() => this.widgetsSetup),
widgetsSetup: Vue.computed(() => this.widgets),
timezone: Vue.computed(() => this.viewData.timezone)
}
},
computed: {
apiurl() {
return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/dashboard';
}
},
methods: {
widgetAdd(section_name, widget) {
// TODO(chris): remove section_name? (change order of params => get rid of it)
this.$refs.widgetpicker
.getWidget()
.then(widget_id => {
widget.widget = widget_id;
widget.id = 'loading_' + String((new Date()).valueOf());
let loading = { ...widget };
loading.loading = true;
this.widgets.push(loading);
this.$api
.call(ApiDashboardUser.addWidget(this.dashboard, widget))
.then(result => {
widget.id = result.data;
this.widgets.splice(this.widgets.indexOf(loading), 1);
this.widgets.push(widget);
this.originalWidgets[widget.id] = structuredClone(ObjectUtils.deepToRaw(widget));
})
.catch(this.$fhcAlert.handleSystemError);
})
.catch(() => {});
if (this.widgets === null) {
axios.get(this.apiurl + '/Widget/getWidgetsForDashboard', {params:{
db: this.dashboard
}}).then(res => {
res.data.retval.forEach(widget => {
widget.arguments = JSON.parse(widget.arguments);
widget.setup = JSON.parse(widget.setup);
});
this.widgets = res.data.retval;
}).catch(err => console.error('ERROR:', err));
}
this.$refs.widgetpicker.getWidget().then(widget_id => {
widget.widget = widget_id;
widget.id = 'loading_' + String((new Date()).valueOf());
let loading = {...widget};
loading.loading = true;
this.sections.forEach(section => {
if (section.name == section_name)
section.widgets.push(loading);
});
axios.post(this.apiurl + '/Config/addWidgetsToUserOverride', {
db: this.dashboard,
funktion_kurzbz: section_name,
widgets: [widget]
}).then(result => {
let newId = Object.keys(result.data.retval.data[section_name].widgets).pop();
widget.id = newId;
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.splice(section.widgets.indexOf(loading),1);
section.widgets.push(widget);
}
});
}).catch(error => {
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
}).catch(() => {});
},
widgetUpdate(section_name, payload) {
payload = payload[section_name];
for (var k in payload) {
for (var wid in this.widgets) {
if (this.widgets[wid].id == k) {
payload[k] = ObjectUtils.mergeDeep(this.widgets[wid], payload[k]);
// NOTE(chris): remove internal props
for (var prop of ['_x','_y','_w','_h','index','id','preset'])
if (payload[k][prop])
delete payload[k][prop];
for (var i in this.sections) {
if (this.sections[i].name == section_name) {
for (var wid in this.sections[i].widgets) {
if (this.sections[i].widgets[wid].id == k) {
payload[k] = ObjectUtils.mergeDeep(this.sections[i].widgets[wid], payload[k]);
// NOTE(chris): remove internal props
for (var prop in {_x:1,_y:1,_w:1,_h:1,index:1,id:1,preset:1})
if (payload[k][prop])
delete payload[k][prop];
break;
}
}
break;
}
}
payload[k].widgetid = k;
}
this.$api
.call(Object.entries(payload).map(([key, widget]) => [
key,
ApiDashboardUser.addWidget(this.dashboard, widget)
]))
.then(result => {
const failed = result
.filter(o => o.status == 'rejected')
.map(o => o.reason.config.errorHeader);
this.widgets.forEach((widget, i) => {
if (failed.includes(widget.id)) {
this.widgets[i] = structuredClone(ObjectUtils.deepToRaw(this.originalWidgets[widget.id]));
/** NOTE(chris): if you wanna hide or unhide a
* preset and it fails: switch around the hidden
* value to revert it properly (checkboxes can't
* really handle it otherwise)
*/
if (payload[widget.id].hidden !== undefined) {
this.widgets[i].hidden = payload[widget.id].hidden;
this.$nextTick(() => {
this.widgets[i] = structuredClone(ObjectUtils.deepToRaw(this.originalWidgets[widget.id]));
});
axios.post(this.apiurl + '/Config/addWidgetsToUserOverride', {
db: this.dashboard,
funktion_kurzbz: section_name,
widgets: payload
}).then(() => {
this.sections.forEach(section => {
if (section.name == section_name) {
section.widgets.forEach((widget, i) => {
if (payload[widget.id]) {
payload[widget.id].id = widget.id;
payload[widget.id].index = widget.index;
section.widgets[i] = payload[widget.id];
}
} else if (payload[widget.id]) {
payload[widget.id].id = widget.id;
payload[widget.id].index = widget.index;
this.widgets[i] = payload[widget.id];
this.originalWidgets[widget.id] = structuredClone(ObjectUtils.deepToRaw(this.widgets[i]));
}
});
})
.catch(this.$fhcAlert.handleSystemError);
});
}
});
}).catch(error => {
// TODO(chris): revert placement on failure
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
},
widgetRemove(section_name, id) {
this.$api
.call(ApiDashboardUser.removeWidget(this.dashboard, id))
.then(() => {
this.widgets = this.widgets.filter(widget => widget.id != id);
})
.catch(this.$fhcAlert.handleSystemError);
axios.post(this.apiurl + '/Config/removeWidgetFromUserOverride', {
db: this.dashboard,
funktion_kurzbz: section_name,
widgetid: id
}).then(() => {
this.sections.forEach(section => {
if (section.name == section_name)
section.widgets = section.widgets.filter(widget => widget.id != id);
});
}).catch(error => {
console.error('ERROR: ', error);
alert('ERROR: ' + error.response.data.retval);
});
}
},
created() {
this.$p.loadCategory('dashboard');
axios.get(this.apiurl + '/Widget/getWidgetsForDashboard', {
params: {
db: this.dashboard
}
}).then(res => {
this.widgets = res.data.retval;
}).catch(err => console.error('ERROR:', err));
this.$api
.call(ApiDashboardWidget.listAllowed(this.dashboard))
.then(res => {
this.widgetsSetup = res.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiDashboardUser.get(this.dashboard))
.then(res => {
const widgets = [];
const remove = [];
for (var wid in res.data.general.widgets) {
let widget = res.data.general.widgets[wid];
widget.id = wid;
if (widget.custom || widget.preset) {
widgets.push(widget);
this.originalWidgets[wid] = structuredClone(widget);
} else {
axios.get(this.apiurl + '/Config', {params:{
db: this.dashboard
}}).then(res => {
for (var name in res.data.retval) {
let widgets = [];
let remove = [];
for (var wid in res.data.retval[name].widgets) {
res.data.retval[name].widgets[wid].id = wid;
if (res.data.retval[name].widgets[wid].custom || res.data.retval[name].widgets[wid].preset)
widgets.push(res.data.retval[name].widgets[wid]);
else
remove.push(wid);
}
}
remove.forEach(wid => this.widgetRemove('general', wid));
this.widgets = widgets;
})
.catch(this.$fhcAlert.handleSystemError);
this.sections.push({
name: name,
widgets: widgets
});
remove.forEach(wid => this.widgetRemove(name, wid));
}
this.sections = this.sections.sort((section1, section2) => {
if(section1.name == 'custom')
return 1;
if (section2.name == 'custom')
return -1;
return section2.widgets.length - section1.widgets.length;
});
}).catch(err => console.error('ERROR:', err));
},
async beforeMount() {
if (!this.viewData.name || !this.viewData.uid) {
const res = await this.$api.call(ApiDashboard.getViewData());
this.viewDataInternal = res.data
}
},
template: `
<div class="core-dashboard">
<h3>
{{ $p.t('global/personalGreeting', [ viewData?.name ]) }}
<h3 v-show="viewDataInternal?.name">
{{ $p.t('global/personalGreeting', [ viewDataInternal?.name ]) }}
<button style="margin-left: 8px;" class="btn" @click="editMode = !editMode" aria-label="edit dashboard" v-tooltip="{showDelay:1000,value:'edit dashboard'}"><i class="fa-solid fa-gear" aria-hidden="true"></i></button>
</h3>
<dashboard-section :seperator="0" name="general" :widgets="widgets" @widgetAdd="widgetAdd" @widgetUpdate="widgetUpdate" @widgetRemove="widgetRemove"></dashboard-section>
<dashboard-widget-picker ref="widgetpicker" :widgets="widgetsSetup"></dashboard-widget-picker>
<dashboard-section v-for="(section, index) in sections" :key="section.name" :seperator="index" :name="section.name" :widgets="section.widgets" @widgetAdd="widgetAdd" @widgetUpdate="widgetUpdate" @widgetRemove="widgetRemove"></dashboard-section>
<dashboard-widget-picker ref="widgetpicker" :widgets="widgets"></dashboard-widget-picker>
</div>`
}
+3 -17
View File
@@ -1,5 +1,5 @@
import BsModal from "../Bootstrap/Modal.js";
import { useCachedWidgetLoader } from "../../composables/Dashboard/CachedWidgetLoader.js";
import CachedWidgetLoader from "../../composables/Dashboard/CachedWidgetLoader.js";
import HeightTransition from "../Tranistion/HeightTransition.js";
export default {
@@ -70,14 +70,6 @@ export default {
ready() {
return this.component && this.arguments !== null;
},
visible: {
get() {
return !this.hidden;
},
set(value) {
this.$emit('remove', this.hidden);
}
}
},
methods: {
unpin(){
@@ -150,14 +142,8 @@ export default {
this.isLoading = false;
},
},
setup() {
const { actions } = useCachedWidgetLoader();
return {
loadWidget: actions.load
};
},
async created() {
this.widget = await this.loadWidget(this.id);
this.widget = await CachedWidgetLoader.loadWidget(this.id);
let component = (await import(this.widget.setup.file)).default;
this.$options.components["widget" + this.widget.widget_id] = component;
this.component = "widget" + this.widget.widget_id;
@@ -199,7 +185,7 @@ export default {
</a>
<Transition>
<div v-if="!custom && editMode" class="col-auto px-1 form-switch">
<input class="form-check-input ms-0" type="checkbox" role="switch" aria-label="toggle widget" id="flexSwitchCheckChecked" v-model="visible" :value="true">
<input class="form-check-input ms-0" type="checkbox" role="switch" aria-label="toggle widget" id="flexSwitchCheckChecked" :checked="!hidden" @input="$emit('remove', hidden)">
</div>
</Transition>
</div>
+7 -14
View File
@@ -1,7 +1,7 @@
import BsConfirm from "../Bootstrap/Confirm.js";
import DropGrid from '../Drop/Grid.js'
import DashboardItem from "./Item.js";
import { useCachedWidgetLoader } from "../../composables/Dashboard/CachedWidgetLoader.js";
import CachedWidgetLoader from "../../composables/Dashboard/CachedWidgetLoader.js";
import WidgetIcon from "./Widget/WidgetIcon.js"
export default {
@@ -125,23 +125,23 @@ export default {
},
checkResizeLimit(item, w, h) {
// NOTE(chris): widgets needs to be loaded for this to work
let widget = this.widgetState[item.widget];
let widget = CachedWidgetLoader.getWidget(item.widget);
if (widget) {
let minmaxW = { ...widget.setup.width };
let minmaxW = widget.setup.width;
if (minmaxW.max)
minmaxW.min = minmaxW.min || 1;
else
minmaxW = { min: minmaxW, max: minmaxW };
minmaxW = {min:minmaxW,max:minmaxW};
if (w < minmaxW.min)
w = minmaxW.min;
if (w > minmaxW.max)
w = minmaxW.max;
let minmaxH = { ...widget.setup.height };
let minmaxH = widget.setup.height;
if (minmaxH.max)
minmaxH.min = minmaxH.min || 1;
else
minmaxH = { min: minmaxH, max: minmaxH };
minmaxH = {min:minmaxH,max:minmaxH};
if (h < minmaxH.min)
h = minmaxH.min;
if (h > minmaxH.max)
@@ -151,7 +151,7 @@ export default {
},
removeWidget(item, revert) {
if (item.custom) {
BsConfirm.popup(this.$p.t('dashboard', 'alert_deleteWidget')).then(() => this.$emit('widgetRemove', this.name, item.id));
BsConfirm.popup('Are you sure you want to delete this widget?').then(() => this.$emit('widgetRemove', this.name, item.id));
} else {
let update = {};
update[item.id] = { hidden: !revert };
@@ -199,13 +199,6 @@ export default {
this.$emit('widgetUpdate', this.name, payload);
}
},
setup() {
const { state: widgetState } = useCachedWidgetLoader();
return {
widgetState
};
},
mounted() {
let self = this;
let cont = self.$refs.container;
@@ -133,7 +133,6 @@ export default {
return this.$api
.call(ApiMessages.getDataVorlage(vorlage_kurzbz))
.then(response => {
this.editor.setContent(response.data.text);
this.formData.body = response.data.text;
this.formData.subject = response.data.subject;
}).catch(this.$fhcAlert.handleSystemError);
@@ -204,6 +203,24 @@ export default {
},
},
watch: {
'formData.body': {
handler(newVal) {
const tinymcsVal = this.editor.getContent();
if (newVal && tinymcsVal != newVal) {
//Inhalt des Editors aktualisieren
this.editor.setContent(newVal);
}
}
},
'formData.vorlage_kurzbz': {
handler(newVal){
if (newVal && newVal != null) {
this.formData.subject = newVal;
return this.getDataVorlage(newVal);
}
}
},
messageId: {
immediate: true,
handler: async function (newMessageId) {
@@ -214,7 +231,6 @@ export default {
this.replyData = result.data;
if (this.replyData.length > 0) {
this.editor.setContent(this.replyData[0].replyBody);
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = newMessageId;
@@ -274,6 +290,19 @@ export default {
})
.catch(this.$fhcAlert.handleSystemError);
//case of reply
if(this.messageId) {
this.$api
.call(ApiMessages.getReplyData(this.messageId))
.then(result => {
this.replyData = result.data;
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = this.messageId;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
async mounted() {
this.initTinyMCE();
@@ -64,16 +64,7 @@ export default {
target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component
//height: 800,
//plugins: ['lists'],
toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify | link',
plugins: 'link',
link_context_toolbar: true,
automatic_uploads: true,
default_link_target: "_blank",
link_title: true,
target_list: [
{ title: 'New tab', value: '_blank' },
{ title: 'Same tab', value: '_self' }
],
toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify',
style_formats: [
{title: 'Blocks', block: 'div'},
{title: 'Paragraph', block: 'p'},
@@ -107,8 +98,7 @@ export default {
return this.$api
.call(ApiMessages.sendMessage(this.typeId, data))
.then(response => {
if(this.openMode == "inSamePage")
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent'));
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent'));
this.hideTemplate();
this.resetForm();
this.messageSent = true;
@@ -124,17 +114,19 @@ export default {
return this.$api
.call(ApiMessages.getDataVorlage(vorlage_kurzbz))
.then(response => {
this.editor.setContent(response.data.text);
this.formData.body = response.data.text;
this.formData.subject = response.data.subject;
}).catch(this.$fhcAlert.handleSystemError);
},
getPreviewText(){
console.log("subj" + this.formData.subject);
const data = new FormData();
data.append('data', JSON.stringify(this.formData.body));
data.append('ids', JSON.stringify(this.id));
console.log("subj" + this.formData.subject);
return this.$api
.call(ApiMessages.getPreviewText(
this.typeId, data))
@@ -203,7 +195,6 @@ export default {
.call(ApiMessages.getReplyData(messageId))
.then(result => {
this.replyData = result.data;
this.editor.setContent(this.replyData[0].replyBody);
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = messageId;
@@ -211,6 +202,27 @@ export default {
.catch(this.$fhcAlert.handleSystemError);
}
},
watch: {
'formData.body': {
handler(newVal) {
const tinymcsVal = this.editor.getContent();
if (newVal && tinymcsVal != newVal) {
//Inhalt des Editors aktualisieren
this.editor.setContent(newVal);
}
}
},
'formData.vorlage_kurzbz': {
handler(newVal){
if (newVal && newVal != null) {
this.formData.subject = newVal;
return this.getDataVorlage(newVal);
}
}
},
},
created(){
const missingparamsmsgs = [];
if(!this.typeId)
@@ -279,8 +291,17 @@ export default {
.catch(this.$fhcAlert.handleSystemError);
//case of reply
if(this.messageId) {
if(this.messageId != null) {
this.loadReplyData(this.messageId);
/* this.$api
.call(ApiMessages.getReplyData(this.messageId))
.then(result => {
this.replyData = result.data;
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = this.messageId;
})
.catch(this.$fhcAlert.handleSystemError);*/
}
},
@@ -478,10 +499,10 @@ export default {
<div class="row">
<div class="col-6" style="border-right: 1px">
You can safely close this window/tab.
You can safely close this window.
</div>
<div class="col-6">
Fenster/Reiter kann geschlossen werden!
Sie können dieses Fenster schließen.
</div>
</div>
</div>
@@ -65,14 +65,7 @@ export default {
buildTreemap(messages) {
if (!messages || !messages.data || messages.data.length === 0)
{
if(this.tabulatorOptions.pagination)
{
return {data: [], last_page: 0};
}
else
{
return [];
}
return {data: [], last_page: 0};
}
const last_page = messages.meta.count;
@@ -113,15 +106,7 @@ export default {
// to avoid endless loop
if (iteration > messages.length) break;
}
if(this.tabulatorOptions.pagination)
{
return {data: messageNested, last_page: last_page};
}
else
{
return messageNested;
}
return {data: messageNested, last_page: last_page};
},
loadAjaxCall(url, config, params){
return this.$api.call(
@@ -267,7 +252,7 @@ export default {
frozen: true
}
],
pagination: false,
pagination: true,
paginationMode: "remote",
paginationSize: 15,
paginationInitialPage: 1,
+6 -8
View File
@@ -82,16 +82,14 @@ export default {
this.$refs.modalMsg.show();
}
else if (this.openMode == "inSamePage"){
console.log("in same Page");
this.isVisibleDiv = true;
if(messageId)
this.$refs.templateNewDivMessage.loadReplyData(messageId);
else
this.$refs.templateNewDivMessage.resetForm();
this.$nextTick(() => {
if(messageId)
this.$refs.templateNewDivMessage.loadReplyData(messageId);
else
this.$refs.templateNewDivMessage.resetForm();
this.$refs.templateNewDivMessage.showTemplate();
});
this.$refs.templateNewDivMessage.showTemplate();
}
else
console.log("no valid openMode");
@@ -74,24 +74,6 @@ export default {
],
'abschlussdokument_lehrgaenge.xml.php': [
'AbschlussdokumentLehrgaenge'
],
'microcredential.xml.php' : [
'microcredentialzertifikat_1',
'microcredentialzertifikat_2',
'microcredentialzertifikat_3',
'microcredentialzertifikat_4',
'microcredential_1',
'microcredential_2',
'microcredential_3',
'microcredential_4',
'microdegree_1',
'microdegree_2',
'microdegree_3',
'microdegree_4',
'microdegreeabschluss_1',
'microdegreeabschluss_2',
'microdegreeabschluss_3',
'microdegreeabschluss_4',
]
},
documentDropdownObject: {}
@@ -306,7 +306,8 @@ export default {
});
},
deleteFile(akte_id){
return this.$fhcApi.factory.stv.documents.deleteFile(akte_id)
return this.$api
.call(ApiStvDocuments.deleteFile(akte_id))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
@@ -18,7 +18,7 @@ export default {
template: `
<div class="stv-details-notizen h-100 pb-3">
<!-- Test Version classicFas for enter with one click vs popupModal-->
<!-- Test Version popupModal-->
<core-notiz
class="overflow-hidden"
:endpoint="endpoint"
@@ -32,15 +32,15 @@ export default {
@reload="$emit('update:suffix')"
tabulator-persistence-id="stv-notiz-20260217"
>
</core-notiz>
</core-notiz>
<!--
---------------------------------------------------------------------------------------------
-------------------- DESCRIPTION FOR PARAMETER PROPS ----------------------------------------
---------------------------------------------------------------------------------------------
endpoint: for corecontroller: eg: :endpoint="$fhcApi.factory.notiz.person"
(...prestudent, ...mitarbeiter, ...bestellung, ...lehreinheit, ...projekt, ...projektphase, ...projekttask, ...anrechnung)
endpoints for coreControllers: prestudent, mitarbeiter, bestellung, lehreinheit, projekt, projektphase, projekttask, anrechnung
import ApiNotiz[...] from '../../../../api/factory/notiz/[...].js';
for extensions: write own controller extending core NotizController
@@ -58,7 +58,7 @@ showDocument: if true: section with documentHandling will be displayed
showTinyMCE: if true: section with WYSIWYG Editor for Text will be displayed
visibleColumns: list, which fields shoult be showed as default in filter component
visibleColumns: list, which fields should be shown as default in filter component
fullVersion: :visibleColumns="['titel','text','bearbeiter','verfasser','von','bis','dokumente','erledigt','notiz_id','notizzuordnung_id','id','lastupdate']"
@@ -76,7 +76,7 @@ visibleColumns: list, which fields shoult be showed as default in filter compone
---------------------------------------------------------------------------------------------
<core-notiz
:endpoint="$fhcApi.factory.notiz.mitarbeiter"
:endpoint="endpoint"
ref="formc"
type-id="uid"
:id= "'ma0068'"
@@ -89,7 +89,7 @@ visibleColumns: list, which fields shoult be showed as default in filter compone
</core-notiz>
<core-notiz
:endpoint="$fhcApi.factory.notiz.prestudent"
:endpoint="endpoint"
ref="formc"
type-id="prestudent_id"
:id="modelValue.prestudent_id"
@@ -102,7 +102,7 @@ visibleColumns: list, which fields shoult be showed as default in filter compone
</core-notiz>
<core-notiz
:endpoint="$fhcApi.factory.notiz.projekt"
:endpoint="endpoint"
ref="formc"
type-id="projekt_kurzbz"
:id="'EA74'"
+1 -1
View File
@@ -52,7 +52,7 @@ export default {
let url = this.res.content_url;
if (url.substr(0, 16) == '../index.ci.php/')
url = this.$fhcApi.getUri(url.substr(16));
url = this.$api.getUri(url.substr(16));
else if (url.substr(0, 3) == '../')
url = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/\/+$/, '') + url.substr(2);
return '<a href="' + url + '">' + url + '</a>';
@@ -1,36 +1,29 @@
import ApiWidget from "../../api/factory/dashboard/widget.js";
let __widgets = {};
let __widgetsStarted = {};
let __path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/dashboard/Widget';
const promises = Vue.ref([]);
const stateRef = Vue.ref([]);
const state = Vue.readonly(stateRef);
export default {
getWidget(id) {
return __widgets[id];
},
loadWidget(id) {
if (__widgets[id])
return Promise.resolve(__widgets[id]);
if (__widgetsStarted[id])
return __widgetsStarted[id];
if (!__path)
return Promise.reject('Widget could not be loaded because there is no path yet!');
export function useCachedWidgetLoader() {
const $api = Vue.inject('$api');
const $fhcAlert = Vue.inject('$fhcAlert');
function load(id) {
if (state.value[id])
return Promise.resolve(state.value[id]);
if (!promises.value[id])
promises.value[id] = new Promise((resolve, reject) => {
$api
.call(ApiWidget.get(id))
.then(res => {
stateRef.value[id] = res.data;
promises.value[id] = undefined;
resolve(state.value[id]);
})
.catch($fhcAlert.handleSystemError);
});
return promises.value[id];
__widgetsStarted[id] = new Promise((resolve, reject) => {
axios.get(__path, {params:{id}}).then(res => {
__widgets[id] = res.data.retval;
__widgetsStarted[id] = undefined;
resolve(__widgets[id]);
}).catch(error => reject(error.response.data.retval.error));
});
return __widgetsStarted[id];
},
setPath(path) {
__path = path;
}
return {
state,
actions: {
load
}
};
}
+29 -70
View File
@@ -1,72 +1,31 @@
/**
* Performs a deep merge of objects and returns new object. Does not modify
* objects (immutable) and merges arrays via concatenation.
*
* @param {...object} objects - Objects to merge
* @returns {object} New object with merged key/values
*/
function mergeDeep(...objects) {
const isObject = obj => obj && typeof obj === 'object';
return objects.reduce((prev, obj) => {
Object.keys(obj).forEach(key => {
const pVal = prev[key];
const oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = pVal.concat(...oVal);
}
else if (isObject(pVal) && isObject(oVal)) {
prev[key] = this.mergeDeep(pVal, oVal);
}
else {
prev[key] = oVal;
}
});
return prev;
}, {});
}
/**
* Extends VUEs toRaw() function to nested Proxies
* @see https://www.reddit.com/r/javascript/comments/10gzynk/deep_cloning_objects_in_javascript_the_modern_way/
*
* @param object sourceObj - Object to transform
* @returns object
*/
function deepToRaw(sourceObj) {
const objectIterator = input => {
if (Array.isArray(input))
return input.map(objectIterator);
if (Vue.isRef(input) || Vue.isReactive(input) || Vue.isProxy(input))
return objectIterator(Vue.toRaw(input));
if (input && typeof input === 'object') {
/** use custom handling of 'Date' objects to avoid data loss if treating it like any other object.
* reminder:
* typeof (new Date()) ==> 'object'
* Object.keys(new Date()) ==> []
*/
if (input instanceof Date)
return input;
return Object.keys(input).reduce((acc, key) => {
acc[key] = objectIterator(input[key]);
return acc;
}, {});
}
return input;
};
return objectIterator(sourceObj);
}
export {
mergeDeep,
deepToRaw
}
export default {
mergeDeep,
deepToRaw
/**
* Performs a deep merge of objects and returns new object. Does not modify
* objects (immutable) and merges arrays via concatenation.
*
* @param {...object} objects - Objects to merge
* @returns {object} New object with merged key/values
*/
mergeDeep(...objects) {
const isObject = obj => obj && typeof obj === 'object';
return objects.reduce((prev, obj) => {
Object.keys(obj).forEach(key => {
const pVal = prev[key];
const oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = pVal.concat(...oVal);
}
else if (isObject(pVal) && isObject(oVal)) {
prev[key] = this.mergeDeep(pVal, oVal);
}
else {
prev[key] = oVal;
}
});
return prev;
}, {});
}
}
+8 -8
View File
@@ -430,16 +430,16 @@ export default {
fhcApiAxios.interceptors.response.use(
response => {
const errorConfig = get_error_handler(response.config);
if (!errorConfig.success)
if (response.config?.errorHandling == 'off'
|| response.config?.errorHandling === false
|| response.config?.errorHandling == 'fail')
return clean_return_value(response);
const errors = popHandleableErrors(errorConfig, response.data.errors);
for (var type in errors) {
errorConfig.handler[type](errors[type]);
}
// NOTE(chris): loop through errors
if (response.data.errors)
response.data.errors = response.data.errors.filter(
err => (response.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$api._defaultErrorHandlers[err.type])(err, response.config)
);
return clean_return_value(response);
},
-1
View File
@@ -144,7 +144,6 @@ foreach($ps->result as $row)
<ROLLE:stichtagsaktiv><![CDATA['.$stichtagsaktiv.']]></ROLLE:stichtagsaktiv>
<ROLLE:aktiv><![CDATA['.$aktiv.']]></ROLLE:aktiv>
<ROLLE:fgm><![CDATA['.$row->fgm.']]></ROLLE:fgm>
<ROLLE:faktiv><![CDATA['.($row->faktiv?'Ja':'Nein').']]></ROLLE:faktiv>
</RDF:Description>
</RDF:li>
';
+3 -3
View File
@@ -450,18 +450,18 @@ td.MarkLine
td.HeaderTesttool /*fuer die Button-Optik beim Testtool*/
{
color: #FFFFFF;
background-color: #71787D;
background-color: #00639C;
white-space:nowrap;
line-height: 25px;
box-shadow: inset 0 0 2px #FFFFFF;
padding: 0 10px;
padding: 10px;
width: 170px;
}
td.HeaderTesttoolSTG /*fuer die Button-Optik der Quereinstiegs-Studiengänge beim Testtool*/
{
color: white;
border: 2px solid #73a9d6;
padding: 0 10px;
padding: 10px;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
+107 -5998
View File
File diff suppressed because it is too large Load Diff
+1 -9
View File
@@ -92,9 +92,6 @@ require_once('dbupdate_3.4/68744_StV_settings.php');
require_once('dbupdate_3.4/62889_reihungstest_ueberwachung_mit_constructor.php');
require_once('dbupdate_3.4/71399_dashboard_update_widget_paths.php');
require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php');
require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php');
require_once('dbupdate_3.4/70376_lohnguide.php');
require_once('dbupdate_3.4/76203_Asynchrone_Tasks.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
@@ -242,11 +239,6 @@ $tabellen=array(
"hr.tbl_valorisierung_instanz" => array("updateamum", "oe_kurzbz", "valorisierungsdatum", "valorisierung_kurzbz", "beschreibung", "ausgewaehlt", "updatevon", "valorisierung_instanz_id"),
"hr.tbl_valorisierung_instanz_methode" => array("valorisierung_instanz_id", "valorisierung_methode_kurzbz", "beschreibung", "valorisierung_methode_parameter"),
"hr.tbl_valorisierung_methode" => array("beschreibung", "valorisierung_methode_kurzbz"),
"hr.tbl_lohnguide_jobfamilie" => array("jobfamilie_kurzbz", "bezeichnung", "aktiv", "sort", "insertvon", "insertamum", "updatevon", "updateamum"),
"hr.tbl_lohnguide_modellfunktion" => array("modellfunktion_kurzbz", "bezeichnung", "jobfamilie_kurzbz", "aktiv", "sort", "insertvon", "insertamum", "updatevon", "updateamum"),
"hr.tbl_lohnguide_modellstelle" => array("modellstelle_kurzbz", "bezeichnung", "grade", "modellfunktion_kurzbz", "aktiv", "sort", "insertvon", "insertamum", "updatevon", "updateamum"),
"hr.tbl_lohnguide_fachrichtung" => array("fachrichtung_kurzbz", "bezeichnung", "aktiv", "insertvon", "insertamum", "updatevon", "updateamum"),
"hr.tbl_vertragsbestandteil_lohnguide" => array("vertragsbestandteil_id", "stellenbezeichnung", "vordienstzeit", "fachrichtung_kurzbz", "modellstelle_kurzbz", "kommentar_person", "kommentar_modellstelle"),
"lehre.tbl_abschlussbeurteilung" => array("abschlussbeurteilung_kurzbz","bezeichnung","bezeichnung_english","sort"),
"lehre.tbl_abschlusspruefung" => array("abschlusspruefung_id","student_uid","vorsitz","pruefer1","pruefer2","pruefer3","abschlussbeurteilung_kurzbz","akadgrad_id","pruefungstyp_kurzbz","datum","uhrzeit","sponsion","anmerkung","updateamum","updatevon","insertamum","insertvon","ext_id","note","protokoll","endezeit","pruefungsantritt_kurzbz","freigabedatum"),
"lehre.tbl_abschlusspruefung_antritt" => array("pruefungsantritt_kurzbz","bezeichnung","bezeichnung_english","sort"),
@@ -430,7 +422,7 @@ $tabellen=array(
"system.tbl_log" => array("log_id","person_id","zeitpunkt","app","oe_kurzbz","logtype_kurzbz","logdata","insertvon","taetigkeit_kurzbz"),
"system.tbl_logtype" => array("logtype_kurzbz", "data_schema"),
"system.tbl_filters" => array("filter_id","app","dataset_name","filter_kurzbz","person_id","description","sort","default_filter","filter","oe_kurzbz","statistik_kurzbz"),
"system.tbl_jobsqueue" => array("jobid", "type", "creationtime", "status", "input", "output", "starttime", "endtime", "insertvon", "insertamum", "pid", "uid", "progress"),
"system.tbl_jobsqueue" => array("jobid", "type", "creationtime", "status", "input", "output", "starttime", "endtime", "insertvon", "insertamum"),
"system.tbl_jobstatuses" => array("status"),
"system.tbl_jobtriggers" => array("type", "status", "following_type"),
"system.tbl_jobtypes" => array("type", "description"),
+1 -14
View File
@@ -1,19 +1,6 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
if ($result = @$db->db_query("SELECT 1 FROM system.tbl_app WHERE app='lvevaluierung' LIMIT 1"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO system.tbl_app (app) VALUES ('lvevaluierung');";
if(!$db->db_query($qry))
echo '<strong>system.tbl_app: '.$db->db_last_error().'</strong><br>';
else
echo ' system.tbl_app: lvevaluierung hinzugefügt<br>';
}
}
//Add column evaluierung to lehre.tbl_lehrveranstaltung
if(!@$db->db_query("SELECT evaluierung FROM lehre.tbl_lehrveranstaltung LIMIT 1"))
{
@@ -25,4 +12,4 @@ if(!@$db->db_query("SELECT evaluierung FROM lehre.tbl_lehrveranstaltung LIMIT 1"
echo '<strong>lehre.tbl_lehrveranstaltung '.$db->db_last_error().'</strong><br>';
else
echo '<br>Spalte evaluierung zu Tabelle lehre.tbl_lehrveranstaltung hinzugefügt';
}
}
-357
View File
@@ -1,357 +0,0 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table_name='tbl_lohnguide_jobfamilie' AND table_schema='hr'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_jobfamilie (
jobfamilie_kurzbz character varying(32) NOT NULL,
bezeichnung varchar(64) NOT NULL,
aktiv boolean DEFAULT FALSE,
sort smallint,
insertvon character varying(32) NOT NULL,
insertamum timestamp without time zone DEFAULT now() NOT NULL,
updatevon character varying(32),
updateamum timestamp without time zone,
CONSTRAINT tbl_lohnguide_jobfamilie_pkey PRIMARY KEY (jobfamilie_kurzbz)
);
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_jobfamilie TO vilesci;
INSERT INTO hr.tbl_lohnguide_jobfamilie(jobfamilie_kurzbz, bezeichnung,aktiv, sort, insertvon, insertamum) VALUES
('FÜHRUNG','Führung',true,1,'system',NOW()),
('AKADEMIA','Akademia',true,2,'system',NOW()),
('VERWALTUNG','Verwaltung',true,3,'system',NOW()),
('TECHNIK','Technik',true,4,'system',NOW()),
('IT_SOFTWARE','IT & Software',true,5,'system',NOW()),
('TECHN_DIENSTE','Technische Dienste',true,6,'system',NOW())
ON CONFLICT (jobfamilie_kurzbz) DO NOTHING;
";
if (! $db->db_query($qry))
echo '<strong>Lohnguide Jobfamilie: ' . $db->db_last_error() . '</strong><br>';
else
echo 'hr.tbl_lohnguide_jobfamilie wurde neu erstellt<br>';
}
}
if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table_name='tbl_lohnguide_modellfunktion' AND table_schema='hr'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_modellfunktion (
modellfunktion_kurzbz character varying(32) NOT NULL,
bezeichnung varchar(64) NOT NULL,
jobfamilie_kurzbz character varying(32) NOT NULL,
aktiv boolean DEFAULT FALSE,
sort smallint,
insertvon character varying(32) NOT NULL,
insertamum timestamp without time zone DEFAULT now() NOT NULL,
updatevon character varying(32),
updateamum timestamp without time zone,
CONSTRAINT tbl_lohnguide_modellfunktion_pkey PRIMARY KEY (modellfunktion_kurzbz),
CONSTRAINT tbl_lohnguide_modellfunktion_jobfamilie_fk FOREIGN KEY (jobfamilie_kurzbz) REFERENCES hr.tbl_lohnguide_jobfamilie (jobfamilie_kurzbz) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE
);
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_modellfunktion TO vilesci;
INSERT INTO hr.tbl_lohnguide_modellfunktion(modellfunktion_kurzbz, bezeichnung, jobfamilie_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('ABTEILUNGSLEITUNG','Abteilungsleitung','FÜHRUNG',true,1,'system',NOW()),
('GF','Geschäftsführung','FÜHRUNG',true,2,'system',NOW()),
('KOMPETENZFELDLEITER','Kompetenzfeldleiter*in','FÜHRUNG',true,3,'system',NOW()),
('DEPARTMENTSLEITER','Departmentsleiter*in','FÜHRUNG',true,4,'system',NOW()),
('FAKULTÄTSLEITER','Fakultätsleiter*in','FÜHRUNG',true,5,'system',NOW()),
/* Akademia */
('STUDENTISCHE_MA','Studentische MA','AKADEMIA',true,6,'system',NOW()),
('JUNIOR_LEC_RES','Junior Lecturer/Researcher','AKADEMIA',true,7,'system',NOW()),
('LEC_RES','Lecturer/Researcher','AKADEMIA',true,8,'system',NOW()),
('SEN_LEC_RES','Senior Lecturer/Researcher','AKADEMIA',true,9,'system',NOW()),
('STUDIENGANGSLEITUNG','Studiengangsleitung','AKADEMIA',true,10,'system',NOW()),
/* Verwaltung */
('FK_VERWALTUNG','Fachkraft Verwaltung','VERWALTUNG',true,11,'system',NOW()),
('SFK_VERWALTUNG','Spezial-Fachkraft Verwaltung','VERWALTUNG',true,12,'system',NOW()),
('SP_VERWALTUNG','Spezialist:in Verwaltung','VERWALTUNG',true,13,'system',NOW()),
('EXP_VERWALTUNG','Expert:in Verwaltung','VERWALTUNG',true,14,'system',NOW()),
/* Technik */
('FK_TECHNIK','Fachkraft Technik','TECHNIK',true,15,'system',NOW()),
/* IT & Software */
('FK_IT','Fachkraft IT & Software','IT_SOFTWARE',true,16,'system',NOW()),
('SFK_IT','Spezial-Fachkraft IT & Software','IT_SOFTWARE',true,17,'system',NOW()),
('SP_IT','Spezialist:in IT & Software','IT_SOFTWARE',true,18,'system',NOW()),
('EXP_IT','Expert:in IT & Software','IT_SOFTWARE',true,19,'system',NOW()),
/* Technische Dienste */
('HK_TECHN_DIENSTE','Hilfskraft Technische Dienste','TECHN_DIENSTE',true,20,'system',NOW()),
('FK_TECHN_DIENSTE','Fachkraft Technische Dienste','TECHN_DIENSTE',true,21,'system',NOW()),
('SFK_TECHN_DIENSTE','Spezial-Fachkraft Technische Dienste','TECHN_DIENSTE',true,22,'system',NOW())
ON CONFLICT (modellfunktion_kurzbz) DO NOTHING;
";
if (! $db->db_query($qry))
echo '<strong>Lohnguide Modellfunktion: ' . $db->db_last_error() . '</strong><br>';
else
echo 'hr.tbl_lohnguide_modellfunktion wurde neu erstellt<br>';
}
}
if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table_name='tbl_lohnguide_modellstelle' AND table_schema='hr'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_modellstelle (
modellstelle_kurzbz character varying(32) NOT NULL,
bezeichnung varchar(128) NOT NULL,
code character varying(32) NOT NULL,
grade int NOT NULL,
modellfunktion_kurzbz character varying(32) NOT NULL,
aktiv boolean DEFAULT FALSE,
sort smallint,
insertvon character varying(32) NOT NULL,
insertamum timestamp without time zone DEFAULT now() NOT NULL,
updatevon character varying(32),
updateamum timestamp without time zone,
CONSTRAINT tbl_lohnguide_modellstelle_pkey PRIMARY KEY (modellstelle_kurzbz),
CONSTRAINT tbl_lohnguide_modellstelle_modellfunktion_fk FOREIGN KEY (modellfunktion_kurzbz) REFERENCES hr.tbl_lohnguide_modellfunktion (modellfunktion_kurzbz) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE
);
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_modellstelle TO vilesci;
-- FÜHRUNG
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz,bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('ABTL_1_4', 'Abteilungsleitung 1/4', '111', 16, 'ABTEILUNGSLEITUNG', true, 1, 'system', NOW()),
('ABTL_2A_4', 'Abteilungsleitung 2a/4', '112a', 17, 'ABTEILUNGSLEITUNG', true, 2, 'system', NOW()),
('ABTL_2B_4', 'Abteilungsleitung 2b/4', '112b', 17, 'ABTEILUNGSLEITUNG', true, 3, 'system', NOW()),
('ABTL_3A_4', 'Abteilungsleitung 3a/4', '113a', 18, 'ABTEILUNGSLEITUNG', true, 4, 'system', NOW()),
('ABTL_3B_4', 'Abteilungsleitung 3b/4', '113b', 18, 'ABTEILUNGSLEITUNG', true, 5, 'system', NOW()),
('ABTL_4_4', 'Abteilungsleitung 4/4', '114', 19, 'ABTEILUNGSLEITUNG', true, 6, 'system', NOW()),
('GF_1_2', 'Geschäftsführung 1/2', '121', 22, 'GF', true, 7, 'system', NOW()),
('GF_2_2', 'Geschäftsführung 2/2', '122', 23, 'GF', true, 8, 'system', NOW()),
('KOMFL_1_1', 'Kompetenzfeldleiter*in 1/1', '131', 15, 'KOMPETENZFELDLEITER', true, 9, 'system', NOW()),
('DEPL_1_1', 'Departmentleiter*in 1/1', '141', 18, 'DEPARTMENTSLEITER', true, 10, 'system', NOW()),
('FAKL_1_1', 'Fakultätsleiter*in 1/1', '151', 20, 'FAKULTÄTSLEITER', true, 11, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- AKADEMIA
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('STUDENTISCHE_MA_1_1', 'Studentische MA 1/1', '211', 5, 'STUDENTISCHE_MA', true, 12, 'system', NOW()),
('JUNIOR_LEC_RES_1_2', 'Junior Lecturer/Researcher 1/2', '221', 8, 'JUNIOR_LEC_RES', true, 13, 'system', NOW()),
('JUNIOR_LEC_RES_2_2', 'Junior Lecturer/Researcher 2/2', '222', 9, 'JUNIOR_LEC_RES', true, 14, 'system', NOW()),
('LEC_RES_1_2', 'Lecturer/Researcher 1/2', '231', 11, 'LEC_RES', true, 15, 'system', NOW()),
('LEC_RES_2_2', 'Lecturer/Researcher 2/2', '232', 12, 'LEC_RES', true, 16, 'system', NOW()),
('SEN_LEC_RES_1_2', 'Senior Lecturer/Researcher 1/2', '241', 13, 'SEN_LEC_RES', true, 17, 'system', NOW()),
('SEN_LEC_RES_2_2', 'Senior Lecturer/Researcher 2/2', '242', 14, 'SEN_LEC_RES', true, 18, 'system', NOW()),
('STGL_1_2', 'Studiengangsleitung 1/2', '251', 15, 'STUDIENGANGSLEITUNG', true, 19, 'system', NOW()),
('STGL_2_2', 'Studiengangsleitung 2/2', '252', 16, 'STUDIENGANGSLEITUNG', true, 20, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- VERWALTUNG
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FK_VERWALTUNG_1_3', 'Fachkraft Verwaltung 1/3', '311', 4, 'FK_VERWALTUNG', true, 21, 'system', NOW()),
('FK_VERWALTUNG_2A_3', 'Fachkraft Verwaltung 2a/3', '312a', 5, 'FK_VERWALTUNG', true, 22, 'system', NOW()),
('FK_VERWALTUNG_2B_3', 'Fachkraft Verwaltung 2b/3', '312b', 5, 'FK_VERWALTUNG', true, 23, 'system', NOW()),
('FK_VERWALTUNG_3_3', 'Fachkraft Verwaltung 3/3', '313', 6, 'FK_VERWALTUNG', true, 24, 'system', NOW()),
('SFK_VERWALTUNG_1_4', 'Spezial-Fachkraft Verwaltung 1/4', '321', 7, 'SFK_VERWALTUNG', true, 25, 'system', NOW()),
('SFK_VERWALTUNG_2A_4', 'Spezial-Fachkraft Verwaltung 2a/4', '322a', 8, 'SFK_VERWALTUNG', true, 26, 'system', NOW()),
('SFK_VERWALTUNG_2B_4', 'Spezial-Fachkraft Verwaltung 2b/4', '322b', 8, 'SFK_VERWALTUNG', true, 27, 'system', NOW()),
('SFK_VERWALTUNG_3A_4', 'Spezial-Fachkraft Verwaltung 3a/4', '323a', 9, 'SFK_VERWALTUNG', true, 28, 'system', NOW()),
('SFK_VERWALTUNG_3B_4', 'Spezial-Fachkraft Verwaltung 3b/4', '323b', 9, 'SFK_VERWALTUNG', true, 29, 'system', NOW()),
('SFK_VERWALTUNG_4_4', 'Spezial-Fachkraft Verwaltung 4/4', '324', 10, 'SFK_VERWALTUNG', true, 30, 'system', NOW()),
('SP_VERWATLTUNG_1_4', 'Spezialist:in Verwaltung 1/4', '331', 11, 'SP_VERWALTUNG', true, 31, 'system', NOW()),
('SP_VERWATLTUNG_2A_4', 'Spezialist:in Verwaltung 2a/4', '332a', 12, 'SP_VERWALTUNG', true, 32, 'system', NOW()),
('SP_VERWATLTUNG_2B_4', 'Spezialist:in Verwaltung 2b/4', '332b', 12, 'SP_VERWALTUNG', true, 33, 'system', NOW()),
('SP_VERWATLTUNG_3A_4', 'Spezialist:in Verwaltung 3a/4', '333a', 13, 'SP_VERWALTUNG', true, 34, 'system', NOW()),
('SP_VERWATLTUNG_3B_4', 'Spezialist:in Verwaltung 3b/4', '333b', 13, 'SP_VERWALTUNG', true, 35, 'system', NOW()),
('SP_VERWATLTUNG_4_4', 'Spezialist:in Verwaltung 4/4', '334', 14, 'SP_VERWALTUNG', true, 36, 'system', NOW()),
('EXP_VERWALTUNG_1_1', 'Expert:in Verwaltung 1/1', '341', 15, 'EXP_VERWALTUNG', true, 37, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- TECHNIK
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FK_TECHNIK_1_3', 'Fachkraft Technik 1/3', '311', 4, 'FK_TECHNIK', true, 38, 'system', NOW()),
('FK_TECHNIK_2a_3', 'Fachkraft Technik 2a/3', '312a', 5, 'FK_TECHNIK', true, 39, 'system', NOW()),
('FK_TECHNIK_2b_3','Fachkraft Technik 2b/3', '312b', 5, 'FK_TECHNIK', true, 40, 'system', NOW()),
('FK_TECHNIK_3_3', 'Fachkraft Technik 3/3', '313', 6, 'FK_TECHNIK', true, 41, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- IT & Software
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FK_IT_1_2', 'Fachkraft IT & Software 1/2', '411', 5, 'FK_IT', true, 42, 'system', NOW()),
('FK_IT_2_2', 'Fachkraft IT & Software 2/2', '412', 6, 'FK_IT', true, 43, 'system', NOW()),
('SFK_IT_1_4', 'Spezial-Fachkraft IT & Software 1/4', '421', 7, 'SFK_IT', true, 44, 'system', NOW()),
('SFK_IT_2_4', 'Spezial-Fachkraft IT & Software 2/4', '422', 8, 'SFK_IT', true, 45, 'system', NOW()),
('SFK_IT_3_4', 'Spezial-Fachkraft IT & Software 3/4', '423', 9, 'SFK_IT', true, 46, 'system', NOW()),
('SFK_IT_4_4', 'Spezial-Fachkraft IT & Software 4/4', '424', 10, 'SFK_IT', true, 47, 'system', NOW()),
('SP_IT_1_4', 'Spezialist:in IT & Software 1/4', '431', 11, 'SP_IT', true, 48, 'system', NOW()),
('SP_IT_2A_4', 'Spezialist:in IT & Software 2a/4', '432a', 12, 'SP_IT', true, 49, 'system', NOW()),
('SP_IT_2B_4', 'Spezialist:in IT & Software 2b/4', '432b', 12, 'SP_IT', true, 50, 'system', NOW()),
('SP_IT_3A_4', 'Spezialist:in IT & Software 3a/4', '433a', 13, 'SP_IT', true, 51, 'system', NOW()),
('SP_IT_3B_4', 'Spezialist:in IT & Software 3b/4', '433b', 13, 'SP_IT', true, 52, 'system', NOW()),
('SP_IT_4_4', 'Spezialist:in IT & Software 4/4', '434', 14, 'SP_IT', true, 53, 'system', NOW()),
('EXP_IT_1_1', 'Expert:in IT & Software 1/1', '441', 15, 'EXP_IT', true, 54, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- TECHNISCHE DIENSTE
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('HK_TECHN_DIENSTE_1_4', 'Hilfskraft Technische Dienste 1/4', '511', 1, 'HK_TECHN_DIENSTE', true, 55, 'system', NOW()),
('HK_TECHN_DIENSTE_2_4', 'Hilfskraft Technische Dienste 2/4', '512', 2, 'HK_TECHN_DIENSTE', true, 56, 'system', NOW()),
('HK_TECHN_DIENSTE_3_4', 'Hilfskraft Technische Dienste 3/4', '513', 3, 'HK_TECHN_DIENSTE', true, 57, 'system', NOW()),
('HK_TECHN_DIENSTE_4_4', 'Hilfskraft Technische Dienste 4/4', '514', 4, 'HK_TECHN_DIENSTE', true, 58, 'system', NOW()),
('FK_TECHN_DIENSTE_1_2', 'Fachkraft Technische Dienste 1/2', '521', 5, 'FK_TECHN_DIENSTE', true, 59, 'system', NOW()),
('FK_TECHN_DIENSTE_2_2', 'Fachkraft Technische Dienste 2/2', '522', 6, 'FK_TECHN_DIENSTE', true, 60, 'system', NOW()),
('SFK_TECHN_DIENSTE_1_4', 'Spezial-Fachkraft Technische Dienste 1/4', '531', 7, 'SFK_TECHN_DIENSTE', true, 61, 'system', NOW()),
('SFK_TECHN_DIENSTE_2_4', 'Spezial-Fachkraft Technische Dienste 2/4', '532', 8, 'SFK_TECHN_DIENSTE', true, 62, 'system', NOW()),
('SFK_TECHN_DIENSTE_3_4', 'Spezial-Fachkraft Technische Dienste 3/4', '533', 9, 'SFK_TECHN_DIENSTE', true, 63, 'system', NOW()),
('SFK_TECHN_DIENSTE_4_4', 'Spezial-Fachkraft Technische Dienste 4/4', '534', 10, 'SFK_TECHN_DIENSTE', true, 64, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
";
if (! $db->db_query($qry))
echo '<strong>Lohnguide Modellstelle: ' . $db->db_last_error() . '</strong><br>';
else
echo 'hr.tbl_lohnguide_modellstelle wurde neu erstellt<br>';
}
}
if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table_name='tbl_lohnguide_fachrichtung' AND table_schema='hr'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_fachrichtung (
fachrichtung_kurzbz character varying(32) NOT NULL,
bezeichnung varchar(32) NOT NULL,
aktiv boolean DEFAULT FALSE,
insertvon character varying(32) NOT NULL,
insertamum timestamp without time zone DEFAULT now() NOT NULL,
updatevon character varying(32),
updateamum timestamp without time zone,
CONSTRAINT tbl_lohnguide_fachrichtung_pkey PRIMARY KEY (fachrichtung_kurzbz)
);
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_fachrichtung TO vilesci;
INSERT INTO hr.tbl_lohnguide_fachrichtung(fachrichtung_kurzbz,bezeichnung,aktiv,insertvon,insertamum) VALUES
('FA00','Keine Berücksichtigung',true,'system',NOW())
ON CONFLICT (fachrichtung_kurzbz) DO NOTHING;
";
if (! $db->db_query($qry))
echo '<strong>Lohnguide Fachrichtung: ' . $db->db_last_error() . '</strong><br>';
else
echo 'hr.tbl_lohnguide_fachrichtung wurde neu erstellt<br>';
}
}
if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table_name='tbl_vertragsbestandteil_lohnguide' AND table_schema='hr'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
CREATE TABLE IF NOT EXISTS hr.tbl_vertragsbestandteil_lohnguide (
vertragsbestandteil_id integer NOT NULL,
vordienstzeit int,
stellenbezeichnung varchar(255),
fachrichtung_kurzbz character varying(32) NOT NULL,
modellstelle_kurzbz character varying(32) NOT NULL,
kommentar_person varchar(255),
kommentar_modellstelle varchar(255),
CONSTRAINT tbl_vertragsbestandteil_lohnguide_pk PRIMARY KEY (vertragsbestandteil_id),
CONSTRAINT tbl_vertragsbestandteil_fk FOREIGN KEY (vertragsbestandteil_id) REFERENCES hr.tbl_vertragsbestandteil (vertragsbestandteil_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT tbl_vertragsbestandteil_lohnguide_fachrichtung_fk FOREIGN KEY (fachrichtung_kurzbz) REFERENCES hr.tbl_lohnguide_fachrichtung (fachrichtung_kurzbz) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
CONSTRAINT tbl_vertragsbestandteil_modellstelle_fachrichtung_fk FOREIGN KEY (modellstelle_kurzbz) REFERENCES hr.tbl_lohnguide_modellstelle (modellstelle_kurzbz) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE
);
COMMENT ON TABLE hr.tbl_vertragsbestandteil_lohnguide IS E'Zuordnung für EU-Entgelttransparenzrichtlinie';
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_vertragsbestandteil_lohnguide TO vilesci;
";
if (! $db->db_query($qry))
echo '<strong>Vertragsbestandteil Lohnguide: ' . $db->db_last_error() . '</strong><br>';
else
echo 'hr.tbl_vertragsbestandteil_lohnguide wurde neu erstellt<br>';
}
}
if($result = $db->db_query("SELECT 1 FROM hr.tbl_vertragsbestandteiltyp WHERE vertragsbestandteiltyp_kurzbz = 'lohnguide'"))
{
if($db->db_num_rows($result) === 0)
{
$qry = "insert into hr.tbl_vertragsbestandteiltyp (vertragsbestandteiltyp_kurzbz,bezeichnung,ueberlappend) values('lohnguide','Lohnguide',false)";
if(!$db->db_query($qry))
echo '<strong>Public Tabelle person: '.$db->db_last_error().'</strong><br>';
else
echo "<br>Vertragsbestandteiltyp 'lohnguide' hinzugefuegt";
}
}
if ($result = $db->db_query("SELECT * FROM information_schema.columns WHERE column_name='vordienstzeit' AND table_name='tbl_vertragsbestandteil_lohnguide' AND table_schema='hr'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
ALTER TABLE
hr.tbl_vertragsbestandteil_lohnguide
ADD COLUMN
vordienstzeit int;
";
if (! $db->db_query($qry))
echo '<strong>Lohnguide: ' . $db->db_last_error() . '</strong><br>';
else
echo 'Spalte vordienstzeit wurde in hr.tbl_vertragsbestandteil_lohnguide neu erstellt<br>';
}
}
if ($result = $db->db_query("SELECT * FROM hr.tbl_gehaltstyp WHERE gehaltstyp_kurzbz='ueberstundenpauschale'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
INSERT INTO hr.tbl_gehaltstyp
(gehaltstyp_kurzbz, bezeichnung, valorisierung, sort, aktiv, lvexport)
VALUES
('ueberstundenpauschale','Überstundenpauschale', true, 8, true, true);
";
if (! $db->db_query($qry))
echo '<strong>Gehaltstyp: ' . $db->db_last_error() . '</strong><br>';
else
echo 'Gehaltstyp "Überstundenpauschale" erstellt.<br />';
}
}
if ($result = $db->db_query("SELECT * FROM hr.tbl_gehaltstyp WHERE gehaltstyp_kurzbz='sachbezug_pkw'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
INSERT INTO hr.tbl_gehaltstyp
(gehaltstyp_kurzbz, bezeichnung, valorisierung, sort, aktiv, lvexport)
VALUES
('sachbezug_pkw','Sachbezug PKW', true, 9, true, true);
";
if (! $db->db_query($qry))
echo '<strong>Gehaltstyp: ' . $db->db_last_error() . '</strong><br>';
else
echo 'Gehaltstyp "Sachbezug PKW" erstellt.<br />';
}
}
@@ -1,15 +0,0 @@
<?php
// neuen Organisationseinheittyp (Programm) als Zeile hinzufügen
if($result = @$db->db_query("SELECT 1 FROM public.tbl_organisationseinheittyp WHERE organisationseinheittyp_kurzbz= 'Programm';"))
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_organisationseinheittyp(organisationseinheittyp_kurzbz, beschreibung, bezeichnung) VALUES ('Programm', 'Programm', 'Programm');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_organisationseinheittyp: '.$db->db_last_error().'</strong><br>';
else
echo '<br>public.tbl_organisationseinheittyp: Zeile Programm hinzugefuegt!<br>';
}
}
@@ -1,59 +0,0 @@
<?php
// Add column pid to system.tbl_jobsqueue
if (!$result = @$db->db_query('SELECT "pid" FROM "system"."tbl_jobsqueue" LIMIT 1'))
{
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD "pid" INT NULL DEFAULT 0;';
if (!$db->db_query($qry))
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Added column pid to table system.tbl_jobsqueue';
}
// Add column uid to system.tbl_jobsqueue
if (!$result = @$db->db_query('SELECT "uid" FROM "system"."tbl_jobsqueue" LIMIT 1'))
{
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD "uid" VARCHAR(32) NULL DEFAULT NULL;';
if (!$db->db_query($qry))
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Added column uid to table system.tbl_jobsqueue';
}
// Add column progress to system.tbl_jobsqueue
if (!$result = @$db->db_query('SELECT "progress" FROM "system"."tbl_jobsqueue" LIMIT 1'))
{
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD "progress" NUMERIC(2,1) NULL DEFAULT 0;';
if (!$db->db_query($qry))
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Added column progress to table system.tbl_jobsqueue';
}
// Add foreign key fk_jobsqueue_benutzer_uid on system.tbl_jobsqueue.uid with public.tbl_benutzer.uid
if ($result = $db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'fk_jobsqueue_benutzer_uid'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = 'ALTER TABLE "system"."tbl_jobsqueue" ADD CONSTRAINT "fk_jobsqueue_benutzer_uid" FOREIGN KEY ("uid") REFERENCES "public"."tbl_benutzer" ("uid") ON DELETE RESTRICT ON UPDATE CASCADE;';
if (!$db->db_query($qry))
echo '<strong>system.tbl_jobsqueue: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Created foreign key fk_jobsqueue_benutzer_uid';
}
}
// Add new webservice type in system.tbl_webservicetyp
if ($result = @$db->db_query("SELECT 1 FROM system.tbl_webservicetyp WHERE webservicetyp_kurzbz = 'lrt';"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO system.tbl_webservicetyp(webservicetyp_kurzbz, beschreibung) VALUES('lrt', 'Long Run Task');";
if (!$db->db_query($qry))
echo '<strong>system.tbl_webservicetyp '.$db->db_last_error().'</strong><br>';
else
echo ' system.tbl_webservicetyp: Added webservice type "lrt"<br>';
}
}
-981
View File
@@ -57009,906 +57009,6 @@ I have been informed that I am under no obligation to consent to the transmissio
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'lektorseiteTitle',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Evaluation | Übersicht LV-Leitung und Lehrende',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'LV-Evaluation | Overview Course Leader and Lecturers',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluierungebeneGesamt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Evaluierung der LV erfolgt auf Gesamt-Ebene',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'This course is evaluated at the overall level',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluierungGruppen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Evaluierung der LV erfolgt auf Gruppen-Ebene',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'This course is evaluated at group level',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipVerbindlichGewaehlt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Evaluierung ist verbindlich vorgesehen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course evaluation is mandatory',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipVerbindlichAbgewaehlt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV wird nicht evaluiert (Abwahl durch STGL)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course evaluation is disabled (cancelled by STGL)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipAlleStudierendeAngemailt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alle Studierenden wurden zur LV-Evaluierung eingeladen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'All students were invited to the course evaluation',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipNichtAlleStudierendenAngemailt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Studierende müssen noch zur LV-Evaluierung eingeladen werden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Students still have to be invited to the course evaluation',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipRuecklauf',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Abgeschlossene LV-Evaluierungen / zur LV-Evaluierung eingeladene Studierende',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Completed course evaluations / students invited to course evaluation',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluationNotAvailable',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ergebnisse LV-Evaluierung und LV-Reflexion noch nicht verfügbar.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Results of course evaluation and course reflection not yet available.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipReflexionNotAvailable',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ergebnisse LV-Evaluierung noch nicht verfügbar, LV-Reflexion noch nicht möglich.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Results of course evaluation not yet available, course reflection not yet possible.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluationAvailable',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ergebnisse LV- Evaluierung verfügbar, LV-Reflexion durchzuführen.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Results of course evaluation available, course reflection required.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluationReady',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ergebnisse LV- Evaluierung und LV-Reflexion.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Results of course evaluation and course reflection.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'verbindlich',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'verbindlich',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'mandatory',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'abgewaehlt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'abgewählt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'disabled',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'enddatum',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Enddatum',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Enddate',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'startdatum',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Startdatum',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Startdate',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'startdatum',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Startdatum',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Startdate',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'gespeichertAmVon',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gespeichert am {date} von {name}',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Saved on {date} von {name}',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'xEingeladeneStudierende',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => '{x} eingeladene Studierende',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => '{x} invited students',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'studierendeEinladen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Studierende zur LV-Evaluierung einladen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Invite students to course evaluation',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'xEmailsVersandt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => '{x} E-Mail-Einladungen versandt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => '{x} invitation emails sent',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'email',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'E-Mail',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'email',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'emailVersandBereit',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bereit zum Versand der E-Mail-Einladungen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Ready to send inivitation mails',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'bearbeitungNurLehrende',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bearbeitung nur durch Lehrende*n möglich',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Only lecturer of course can edit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'bearbeitungNurLvLeitung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bearbeitung nur durch LV-Leitung möglich',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Only course leader can edit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'notAvailableEvaluierungGruppenebene',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Evaluierung auf Gruppen-Ebene ist nicht verfügbar, da die Zuordnung Studierendenverband zu einer*m Lehrenden nicht eindeutig möglich ist',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course evaluation at group level is not available, as it is not possible to link a specific student group to one lecturer',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'noChangeGruppenebene',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Entscheidung für Gesamt- oder Gruppen-Ebene kann nicht mehr verändert werden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Decision for overall or group level can no longer be changed',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'evalPeriodAlreadyStarted',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Evaluierungszeitfenster kann nicht mehr verändert werden, da Studierende bereits eingeladen wurden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Evaluation response window can no longer be changed, as students have already been invited',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluierungByLv',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => "Die Evaluierung der LV erfolgt auf Gesamt-Ebene.<br><br>Das Start-und enddatum der LV-Evaluierung kann geändert bzw. angepasst werden, solange die Studierenden noch nicht eingelanden wurden.<br><br>Der Zugriff für Studierende ist auf dieses Evaluierungsfenster beschränkt.",
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => "This course is evaluated at the overall level.<br><br>The start and end dates of the course evaluation can be changed or adjusted as long as the students have not yet been invited.<br><br>Student access is limited to this evaluation response window.",
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipEvaluierungByLe',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => "Die Evaluierung der LV erfolgt auf Gruppen-Ebene.<br><br>Das Start-und enddatum der LV-Evaluierung kann geändert bzw. angepasst werden, solange die Studierenden noch nicht eingelanden wurden.<br><br>Der Zugriff für Studierende ist auf dieses Evaluierungsfenster beschränkt.",
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => "This course is evaluated at the group level.<br><br>The start and end dates of the course evaluation can be changed or adjusted as long as the students have not yet been invited.<br><br>Student access is limited to this evaluation response window.",
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'infoStudierendenlink',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => "Der Versand der E-Mail-Einladung zur LV-Evaluierung ist nur einmalig möglich. Jede*r Studierende*r erhält einen anonymen Zugangslink.",
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => "The email invitation to the course evaluation can only be sent once. Each student receives an anonymous access link.",
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'stglseiteTitle',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Evaluation | Übersicht Studiengangsleitung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'LV-Evaluation | Overview Program Director',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'kfseiteTitle',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Evaluation | Übersicht Kompetenzfeldleitung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'LV-Evaluation | Overview Head of Competence Center',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'confirmHeader',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bitte bestätigen Sie:',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Please confirm:',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'malveSubmitBtn',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'MALVE-STGL abschließen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Close MALVE-STGL',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'malveSubmitConfirmMessage',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ich habe alle LV-Evaluierungen des Studiengangs {studiengang} im {studiensemester} geprüft. Notwendige Maßnahmen für die STG-Weiterentwicklung wurden abgeleitet.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'I have reviewed all the course evaluations for the {studiengang} degree programme in {studiensemester}. The necessary measures for further developing the STG have been identified.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'evaluationsebene',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Evaluationsebene',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Evaluation level',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'confirmHeader',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bitte bestätigen Sie:',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Please confirm:',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'geprueft',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Geprüft',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Checked',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipGeprueft',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Optional zur besseren persönlichen Übersicht',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Optional for better personal overview.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'lvKeinQuellkurs',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV mit keinem Quellkurs verknüpft',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Course not linked to any (Moodle) source template',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'stgWeiterentwicklungBtn',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'STG-Weiterentwicklung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'STG-Continued Improvement',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipStgWeiterentwicklungBtn',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'MALVE-STGL: Schnittstelle zur Maßnahmenableitung für den STG in OP.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'MALVE-STGL: An interface for deriving measures for the degree programme in OP.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'tooltipLvWeiterentwicklungBtn',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Schnittstelle zur Maßnahmenableitung für die einzelnen LVs in OP.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Interface for deriving measures for individual courses in OP.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'lvevaluierung',
'category' => 'global',
'phrase' => 'endedatumMussInZukunftLiegen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Das Endedatum muss mindestens {minutes} Minuten in der Zukunft liegen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The end date must be at least {minutes} minutes in the future',
'description' => '',
'insertvon' => 'system'
)
)
),
// ### DOKUMENTE ERSTELLEN PHRASEN END ###
// ### Personen zusammenlegen Phrasen BEGIN
array(
@@ -58096,87 +57196,6 @@ I have been informed that I am under no obligation to consent to the transmissio
)
),
// ### Phrases Dashboard Admin START
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'deleteInfo',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Mit dieser Aktion werden auch alle Voreinstellungen der verbundenen Widgets gelöscht.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'This action will also delete all presets of the connected widgets.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'success_savePreset',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Voreinstellung erfolgreich aktualisiert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Preset successfully updated',
'description' => '',
'insertvon' => 'system'
)
)
), array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'alert_deleteWidget',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Sind Sie sicher, dass Sie dieses Widget löschen möchten?',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Are you sure you want to delete this widget?',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'confirm_delete',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Möchten Sie wirklich löschen?',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Do you really want to delete?',
'description' => '',
'insertvon' => 'system'
)
)
),
// ### Phrases Dashboard Admin END
);
+13 -23
View File
@@ -742,7 +742,7 @@ function _getFunktionscontainer_Funktionscode123456($bisfunktion_arr)
$has_oe_lehrgang = !($studiengang->studiengang_kz > 0 && $studiengang->studiengang_kz < 10000);
// STG, die nicht BIS-bemeldet werden, ueberspringen
if (in_array($studiengang->studiengang_kz, BIS_EXCLUDE_STG) || !$studiengang->melderelevant)
if (in_array($studiengang->studiengang_kz, BIS_EXCLUDE_STG))
{
continue;
}
@@ -825,7 +825,6 @@ function _addFunktionscontainer_Funktionscode7($uid, $funktion_arr, $stichtag)
$entwicklungsteam_arr = array_filter($entwicklungsteam_arr, function ($obj) {
return
!in_array($obj->studiengang_kz, BIS_EXCLUDE_STG) &&
$obj->melderelevant &&
$obj->studiengang_kz > 0 &&
$obj->studiengang_kz < 10000;
});
@@ -876,6 +875,7 @@ function _getLehrecontainer($sws_proStg_arr)
$sws_proStg_arr = array_filter($sws_proStg_arr, function ($obj) {
return
!in_array($obj->studiengang_kz, BIS_EXCLUDE_STG) &&
$obj->studiengang_kz > 0 &&
$obj->studiengang_kz < 10000;
});
}
@@ -886,17 +886,13 @@ function _getLehrecontainer($sws_proStg_arr)
{
$is_sommersemester = substr($sws_proStg->studiensemester_kurzbz, 0, 2) == 'SS';
$is_wintersemester = substr($sws_proStg->studiensemester_kurzbz, 0, 2) == 'WS';
$is_lehrgang = isset($sws_proStg->lgartcode);
$kennzeichen_name = $is_lehrgang ? 'LehrgangNr' : 'StgKz';
// Lehreobjekt generieren
if (empty($lehre_arr) || !lehre_stg_exists($sws_proStg->melde_studiengang_kz, $lehre_arr))
if (empty($lehre_arr) || !lehre_stg_exists($sws_proStg->studiengang_kz, $lehre_arr))
{
$lehre_obj = new StdClass();
$lehre_obj->{$kennzeichen_name} = $sws_proStg->melde_studiengang_kz;
//~ $lehre_obj->StgKz = setLeadingZero(intval($sws_proStg->studiengang_kz), 4);
$lehre_obj->StgKz = setLeadingZero(intval($sws_proStg->studiengang_kz), 4);
$lehre_obj->SommersemesterSWS = $is_sommersemester ? $sws_proStg->sws : 0.00;
$lehre_obj->WintersemesterSWS = $is_wintersemester ? $sws_proStg->sws : 0.00;
@@ -905,8 +901,8 @@ function _getLehrecontainer($sws_proStg_arr)
}
else // Lehrecontainer mit STG schon vorhanden
{
$lehre_obj_arr = array_filter($lehre_arr, function (&$obj) use ($sws_proStg, $kennzeichen_name) {
return isset($obj->{$kennzeichen_name}) && $obj->{$kennzeichen_name} == $sws_proStg->melde_studiengang_kz;
$lehre_obj_arr = array_filter($lehre_arr, function (&$obj) use ($sws_proStg) {
return $obj->StgKz == $sws_proStg->studiengang_kz;
});
// SWS ergaenzen
@@ -1024,14 +1020,9 @@ function _generateXML($person_arr)
foreach ($person->lehre_arr as $lehre)
{
$xml .= '<Lehre>';
if (isset($lehre->LehrgangNr))
$xml .= '<LehrgangNr><![CDATA['. $lehre->LehrgangNr. ']]></LehrgangNr>';
else
$xml .= '<StgKz><![CDATA['. $lehre->StgKz. ']]></StgKz>';
$xml .= '<SommersemesterSWS><![CDATA['. number_format($lehre->SommersemesterSWS, 2, '.', ''). ']]></SommersemesterSWS>';
$xml .= '<WintersemesterSWS><![CDATA['. number_format($lehre->WintersemesterSWS, 2, '.', ''). ']]></WintersemesterSWS>';
$xml .= '<StgKz><![CDATA['. $lehre->StgKz. ']]></StgKz>';
$xml .= '<SommersemesterSWS><![CDATA['. $lehre->SommersemesterSWS. ']]></SommersemesterSWS>';
$xml .= '<WintersemesterSWS><![CDATA['. $lehre->WintersemesterSWS. ']]></WintersemesterSWS>';
$xml .= '</Lehre>';
}
@@ -1220,7 +1211,7 @@ function _outputHTML($person_arr)
{
echo '
<tr>
<td>'. (isset($lehre->LehrgangNr) ? $lehre->LehrgangNr : $lehre->StgKz). '</td>
<td>'. $lehre->StgKz. '</td>
<td>'. $lehre->SommersemesterSWS. '</td>
<td>'. $lehre->WintersemesterSWS. '</td>
</tr>';
@@ -1360,16 +1351,15 @@ function verwendung_exists($bisverwendung, $verwendung_arr)
/**
* Prueft ob ein Studiengang bereits im Lehre Container vorhanden ist
* @param $melde_studiengang_kz Studiengangskennzahl
* @param $studiengang_kz Studiengangskennzahl
* @param $lehre_arr Array mit Lehre Objekten
* @return true wenn der Studiengang bereits existiert
*/
function lehre_stg_exists($melde_studiengang_kz, $lehre_arr)
function lehre_stg_exists($studiengang_kz, $lehre_arr)
{
foreach($lehre_arr as $row)
{
$kennzeichenName = isset($row->LehrgangNr) ? 'LehrgangNr' : 'StgKz';
if(isset($row->{$kennzeichenName}) && $row->{$kennzeichenName} == $melde_studiengang_kz)
if($row->StgKz == $studiengang_kz)
return true;
}
return false;
+3 -12
View File
@@ -227,8 +227,7 @@ if (isset($_GET['sendform']))
<table class="tablesorter" id="t1">
<thead>
<tr>
<th><button type="button" class="resetsaved" title="Reset Filter">Reset Filter</button>
<span class="tooltip"><img src="../../skin/images/information.png" height="20px" name="infoicon"/>
<th><span class="tooltip"><img src="../../skin/images/information.png" height="20px" name="infoicon"/>
'.$tooltiptext.'
</span>
</th>
@@ -365,10 +364,9 @@ if (isset($_GET['sendform']))
$("#t1").tablesorter(
{
sortList: [[3,0]],
widgets: ["saveSort", "zebra", "filter", "stickyHeaders"],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: { 0: { filter: false, sorter: false }},
widgetOptions : { filter_saveFilters : true,
filter_functions : {
widgetOptions : { filter_functions : {
// Add select menu to this column
8 : {
"True" : function(e, n, f, i, $r, c, data) { return /t/.test(e); },
@@ -383,13 +381,6 @@ if (isset($_GET['sendform']))
"False" : function(e, n, f, i, $r, c, data) { return /f/.test(e); }
}
}}
});
$('.resetsaved').click(function()
{
$("#t1").trigger("filterReset");
location.reload(forceGet);
return false;
});
});
@@ -588,9 +588,7 @@ if(isset($_POST['testergebnisanzeigen']) && isset($_POST['prestudent_id']))
{
if(is_numeric($_POST['prestudent_id']) && $_POST['prestudent_id']!='')
{
$qry="SELECT nachname,vorname,person_id,prestudent_id,tbl_pruefling.pruefling_id,
tbl_pruefling_frage.begintime,bezeichnung,kurzbz,tbl_frage.nummer,level,
tbl_vorschlag.nummer as antwortnummer, tbl_vorschlag.punkte, tbl_frage.frage_id
$qry="SELECT nachname,vorname,person_id,prestudent_id,tbl_pruefling.pruefling_id,tbl_pruefling_frage.begintime,bezeichnung,kurzbz,tbl_frage.nummer,level, tbl_vorschlag.nummer as antwortnummer, tbl_vorschlag.punkte
FROM testtool.tbl_antwort
JOIN testtool.tbl_vorschlag USING(vorschlag_id)
JOIN testtool.tbl_frage USING (frage_id)
@@ -617,7 +615,6 @@ if(isset($_POST['testergebnisanzeigen']) && isset($_POST['prestudent_id']))
<th>Level</th>
<th>Antwort #</th>
<th>Punkte</th>
<th>FrageID</th>
</tr>
</thead>
<tbody>';
@@ -635,7 +632,6 @@ if(isset($_POST['testergebnisanzeigen']) && isset($_POST['prestudent_id']))
echo "<td>$row->level</td>";
echo "<td>$row->antwortnummer</td>";
echo "<td>$row->punkte</td>";
echo "<td>$row->frage_id</td>";
echo '</tr>';
}
echo '</tbody></table>';
+2 -29
View File
@@ -837,25 +837,6 @@ if(isset($_GET['excel']))
<script src="../../vendor/fgelinas/timepicker/jquery.ui.timepicker.js" type="text/javascript" ></script>
<script type="text/javascript">
$.tablesorter.addParser({
id: "customDate",
is: function(s) {
//return false;
//use the above line if you don\'t want table sorter to auto detected this parser
// match dd.mm.yyyy e.g. 01.01.2001 as regex
//return /\d{1,4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2} .*/.test(s);
return /\d{1,2}.\d{1,2}.\d{1,4}.*/.test(s);
},
// replace regex-wildcards and return new date
format: function(s) {
s = s.replace(/\-/g," ");
s = s.replace(/:/g," ");
s = s.replace(/\./g," ");
s = s.split(" ");
return $.tablesorter.formatFloat(new Date(s[2], s[1]-1, s[0]).getTime());
},
type: "numeric"
});
$(document).ready(function()
{
// Check, ob Räume zugeteilt sind oder max_teilnehmer gesetzt ist, wenn "öffentlich" gesetzt wird
@@ -1026,7 +1007,7 @@ if(isset($_GET['excel']))
{
widgets: ["zebra", "filter", "stickyHeaders"],
sortList: [[2,0],[3,0]],
headers: {0: { sorter: false},10: { sorter: "customDate"},11: { sorter: "customDate"}},
headers: {0: { sorter: false}},
widgetOptions: {filter_cssFilter: [
"filter_clm_null",
"filter_clm_prestudent_id",
@@ -1039,7 +1020,6 @@ if(isset($_GET['excel']))
"filter_clm_studienplan",
"filter_clm_einstiegssemester",
"filter_clm_geburtsdatum",
"filter_clm_anmeldedatum",
"filter_clm_email",
"filter_clm_absolviert"]}
});
@@ -1092,7 +1072,6 @@ if(isset($_GET['excel']))
'clm_studienplan',
'clm_einstiegssemester',
'clm_geburtsdatum',
"filter_clm_anmeldedatum",
'clm_email',
'clm_absolviert'];
for (var i in arr)
@@ -2718,8 +2697,7 @@ if($reihungstest_id!='')
WHERE prestudent_id = tbl_prestudent.prestudent_id
AND status_kurzbz = 'Interessent'
) LIMIT 1
) AS orgform_kurzbz,
tbl_rt_person.anmeldedatum
) AS orgform_kurzbz
FROM PUBLIC.tbl_rt_person
JOIN PUBLIC.tbl_person USING (person_id)
JOIN PUBLIC.tbl_reihungstest rt ON (rt_id = rt.reihungstest_id)
@@ -2808,7 +2786,6 @@ if($reihungstest_id!='')
echo '<div id="clm_studienplan" class="active" onclick="hideColumn(\'clm_studienplan\')">Studienplan</div>';
echo '<div id="clm_einstiegssemester" class="active" onclick="hideColumn(\'clm_einstiegssemester\')">Einstiegssemester</div>';
echo '<div id="clm_geburtsdatum" class="active" onclick="hideColumn(\'clm_geburtsdatum\')">Geburtsdatum</div>';
echo '<div id="clm_anmeldedatum" class="active" onclick="hideColumn(\'clm_anmeldedatum\')">Geburtsdatum</div>';
echo '<div id="clm_email" class="active" onclick="hideColumn(\'clm_email\')">EMail</div>';
echo '<div id="clm_absolviert" class="active" onclick="hideColumn(\'clm_absolviert\')">Absolvierte Tests <span class="wait"></span></div>';
//echo '<div id="clm_ergebnis" class="active" onclick="hideColumn(\'clm_ergebnis\')">Ergebnis <span class="wait"></span></div>';
@@ -2850,7 +2827,6 @@ if($reihungstest_id!='')
<th style="display: table-cell" class="clm_studienplan">Studienplan</th>
<th style="display: table-cell" class="clm_einstiegssemester">Einstiegssemester</th>
<th style="display: table-cell" class="clm_geburtsdatum">Geburtsdatum</th>
<th style="display: table-cell" class="clm_anmeldedatum">Anmeldedatum</th>
<th style="display: table-cell" class="clm_email">EMail</th>
<th style="display: table-cell" class="clm_absolviert">bereits absolvierte Verfahren</th>
<!--<th style="display: table-cell" class="clm_ergebnis">Ergebnis</th>
@@ -2970,7 +2946,6 @@ if($reihungstest_id!='')
<td style="display: table-cell" class="clm_studienplan">'.$db->convert_html_chars($studienplan_bezeichnung).' ('.$row->studienplan_id.')</td>
<td style="display: table-cell" class="clm_einstiegssemester">'.$db->convert_html_chars($row->ausbildungssemester).'</td>
<td style="display: table-cell" class="clm_geburtsdatum">'.$db->convert_html_chars($row->gebdatum!=''?$datum_obj->convertISODate($row->gebdatum):' ').'</td>
<td style="display: table-cell" class="clm_anmeldedatum">'.$db->convert_html_chars($row->anmeldedatum!=''?$datum_obj->convertISODate($row->anmeldedatum):' ').'</td>
<td style="display: table-cell; text-align: center" class="clm_email"><a href="mailto:'.$db->convert_html_chars($row->email).'"><img src="../../skin/images/button_mail.gif" name="mail"></a></td>
<td style="display: table-cell;" class="clm_absolviert">'.$rt_in_anderen_stg.'</td>
</tr>';
@@ -3034,7 +3009,6 @@ if($reihungstest_id!='')
<th style="display: table-cell" class="clm_studienplan">Studienplan</th>
<th style="display: table-cell" class="clm_einstiegssemester">Einstiegssemester</th>
<th style="display: table-cell" class="clm_geburtsdatum">Geburtsdatum</th>
<th style="display: table-cell" class="clm_anmeldedatum">Anmeldedatum</th>
<th style="display: table-cell" class="clm_email">EMail</th>
<th style="display: table-cell" class="clm_absolviert">bereits absolvierte Verfahren</th>
<!--<th style="display: table-cell" class="clm_ergebnis">Ergebnis</th>
@@ -3154,7 +3128,6 @@ if($reihungstest_id!='')
<td style="display: table-cell" class="clm_studienplan">'.$db->convert_html_chars($studienplan_bezeichnung).' ('.$row->studienplan_id.')</td>
<td style="display: table-cell" class="clm_einstiegssemester">'.$db->convert_html_chars($row->ausbildungssemester).'</td>
<td style="display: table-cell" class="clm_geburtsdatum">'.$db->convert_html_chars($row->gebdatum!=''?$datum_obj->convertISODate($row->gebdatum):' ').'</td>
<td style="display: table-cell" class="clm_anmeldedatum">'.$db->convert_html_chars($row->anmeldedatum!=''?$datum_obj->convertISODate($row->anmeldedatum):' ').'</td>
<td style="display: table-cell; text-align: center" class="clm_email"><a href="mailto:'.$db->convert_html_chars($row->email).'"><img src="../../skin/images/button_mail.gif" name="mail"></a></td>
<td style="display: table-cell;" class="clm_absolviert">'.$rt_in_anderen_stg.'</td>';
/*echo '<td style="display: table-cell; align: right" class="clm_ergebnis">'.($rtergebnis==0?'-':number_format($rtergebnis,2,'.','')).' %</td>