Compare commits

...
Author SHA1 Message Date
adisposkofh 4058ecebdf displaying wahlname where applicable in old cis search results and profile 2026-10-09 11:43:48 +02:00
adisposkofh 5c0cbcd234 phrase fix wahlname -> wahlvorname 2026-10-08 17:38:38 +02:00
adisposkofh aa68181a3b displaying chosen name in mailing lists 2026-10-08 16:57:36 +02:00
adisposkofh cad122bef6 neu cis displaying wahlname 2026-10-08 15:02:12 +02:00
Andreas Österreicher 0c4d102850 Merge branch 'bug-83698/StudVW_Projektarbeit_Kontaktdaten' 2026-10-07 09:11:42 +02:00
Andreas Österreicher 2e15f2c5ab Edit Dialog von Kontaktdaten bei Projektbetreuer die Mitarbeiter sind wird nicht angezeigt 2026-10-07 09:10:51 +02:00
Harald Bamberger 784e5693b4 compat component add/remove css class via lifecycle hooks to apply compat specific rules 2026-10-06 15:22:16 +02:00
Andreas Österreicher 88b49b70e9 Fehlermeldung korrigiert beim Endupload wenn Zweitbetreuer keine E-Mail hinterlegt hat 2026-10-06 14:47:45 +02:00
Harald Bamberger 67a33f2ceb revert dashboard item overscroll-behavior to auto, so scrolling the page is not only possible on the page borders 2026-10-06 14:15:46 +02:00
Harald Bamberger 751445c199 Merge branch 'feature-83444/lvverwaltung_suche_nach_le_und_lv_inkl_router' 2026-10-06 10:59:19 +02:00
Harald Bamberger 916f5dd68e disable search for lv and le for the moment 2026-10-06 10:58:20 +02:00
Harald Bamberger efc8fa1eeb Merge branch 'master' into feature-83444/lvverwaltung_suche_nach_le_und_lv_inkl_router 2026-10-06 10:27:46 +02:00
Harald Bamberger d58edff92d fix propertyname for api response 2026-10-05 18:26:42 +02:00
Harald Bamberger 643929a0c6 add cis4 class to body to make it harder for cms content style sheets to override padding, add names to calendar events renderer components, show lvmenu not only for route MyLvPlan but e.g. also in Dashboard LvPlan Widget 2026-10-05 17:56:57 +02:00
Harald Bamberger 4ba2869632 Merge branch 'master' into bugfix-83059_incorrect-ical-semester-parameters 2026-10-05 11:22:59 +02:00
Andreas Österreicher 293bb77179 Merge branch 'bug-44023/EingabemaskeEntwicklungsteamNamenOhneUid2' 2026-10-02 13:23:02 +02:00
Andreas Österreicher 3fe10d715d Fixed Saving of Entwicklungsteam 2026-10-02 13:14:41 +02:00
Manuela Thamer 3034615455 fix pagelock of modals
prevent editing contact data of employees
2026-10-01 17:27:54 +02:00
Andreas Österreicher 36064afbba Fixed Testing Projektarbeit Seeds 2026-10-01 15:33:05 +02:00
Harald Bamberger f3d031ab16 cismenu: add cis-main-menu class to main nav, add li elements to ul, style cis-main-menu ul and li to prevent interferec with cms content styles, add draggable false to cis menu entries to improve menu scrolling especially on mobile devices 2026-10-01 11:48:51 +02:00
Harald Bamberger 3d8c4fa4d0 Merge branch 'feature-77757/WidgetsBerechtigung' 2026-09-30 15:48:00 +02:00
Harald Bamberger 272014bd78 remove odd phrases 2026-09-30 15:38:43 +02:00
Harald Bamberger 76a8e00edf Merge branch 'master' into feature-77757/WidgetsBerechtigung 2026-09-30 15:23:08 +02:00
Harald Bamberger ce62713790 Merge branch 'bug-82297/ausweis-date-preview-issue' 2026-09-30 12:11:13 +02:00
Harald Bamberger 34761db664 rename phrase 2026-09-30 10:56:30 +02:00
Harald Bamberger c7131ed775 revert changes to old cis since issue does not occur there 2026-09-30 10:53:01 +02:00
Harald Bamberger b57e1984a8 Merge branch 'master' into bug-82297/ausweis-date-preview-issue 2026-09-30 10:20:28 +02:00
ma0048 e369a8c03f LV-Verwaltung:
- Semester unter Orgform im Verbandsbaum
- Kombinierte LV/LE-Suche
- Semester/Orgform/Lehrform in Suchergebnissen
2026-09-28 08:42:37 +02:00
Harald Bamberger acedc11be8 adapt styling detailheader employees 2026-09-24 14:39:38 +02:00
Harald Bamberger 15c1da74a2 CisMenu: do not overwrite calculated url if menuitem is multiple times in menu tree 2026-09-23 16:09:42 +02:00
Harald Bamberger d33b45d7cb Merge branch 'bhdev_backport_compat' 2026-09-23 14:58:26 +02:00
Andreas Österreicher b3b6d847a7 Merge branch 'feature-62260/international_skills_groupheader_filter' 2026-09-23 14:36:13 +02:00
Andreas Österreicher 80365de28c Merge branch 'feature-62602/mehrfachnennungen_innerhalb_einer_kategorie' 2026-09-23 14:35:36 +02:00
Andreas Österreicher 2d74522a4f Merge branch 'feature-54225/reihungstest_ablauf_fuer_quereinsteiger' 2026-09-23 12:28:35 +02:00
ma0048 d00aef66e1 master gemerged 2026-09-23 11:32:01 +02:00
ma0048 241eec3ef2 Merge remote-tracking branch 'origin/master' into feature-54225/reihungstest_ablauf_fuer_quereinsteiger
# Conflicts:
#	cis/testtool/menu.php
#	system/dbupdate_3.4.php
2026-09-23 11:29:43 +02:00
Harald Bamberger 8b44e4475b Merge branch 'master' of github.com:FH-Complete/FHC-Core into bhdev_backport_compat 2026-09-22 16:51:34 +02:00
Harald Bamberger d251987850 backport compat controller and component 2026-09-22 16:50:56 +02:00
ma0048 faad2c4a9a lv auch anzeigen wenn keine lvteile in dem semester dran haengen
phrasen hinzugefuegt
2026-09-18 12:34:47 +02:00
ma0048 224cef7fad bug beim Loeschen von Antworten eines Prueflings in reihungstet_administration.php fixed 2026-09-17 13:29:58 +02:00
ma0048 2ffaf36270 suche fuer lehreinheiten und lehrveranstaltungen in der lvverwaltung 2026-09-15 15:46:48 +02:00
Harald Bamberger c8c7d1566c Merge branch 'master' into bugfix-83059_incorrect-ical-semester-parameters 2026-09-11 11:43:23 +02:00
adisposkofh 9d4218bf38 implemented displayed semester/ical dates changes from my lv plan to other lv plan 2026-09-09 11:36:19 +02:00
adisposkofh 67f30c7765 fixed issue with wrong semester displayed and wrong ical dates used in my lv plan 2026-09-09 11:30:43 +02:00
Ivymaster 5fff45e302 Added check for date existence 2026-08-27 11:00:43 +02:00
Johann Hoffmann d40040efd8 added new fkey to tbl_widget for system.tbl_berechtigung; check for permission status during load & in widget picker; if widget was already picked/configured but not permitted anymore -> show a generalized "missing permission" screen via fallback component during widget init; 2026-07-21 18:14:26 +02:00
Andreas Österreicher 9629345473 Merge branch 'master' into feature-62260/international_skills_groupheader_filter 2026-07-08 15:28:23 +02:00
Andreas Österreicher 4d72b0047a Merge branch 'master' into feature-62602/mehrfachnennungen_innerhalb_einer_kategorie 2026-07-08 15:26:41 +02:00
ma0048 c664c14afc phrase hinzugefuegt 2025-12-18 11:10:08 +01:00
ma0048 9183c4f04c massnahme einmalig flag hinzugefuegt 2025-10-01 12:03:18 +02:00
ma0048 6495f741b9 added missing phrase 2025-07-09 14:02:41 +02:00
ma0048 d3210f0d3d - foreign keys hinzugefuegt
- beim zuruecksetzen der gebiete, wird auch tbl_pruefling_gebiet zurueckgesetzt
2025-02-18 13:51:20 +01:00
ma0048 a0dce925d4 - rt holt sich zusätzlich alle gebiete aus den semestern davor 2025-01-14 10:56:28 +01:00
72 changed files with 1729 additions and 261 deletions
+8 -2
View File
@@ -129,13 +129,19 @@ $route['api/frontend/v1/treemenudata/stv/.*'] = 'api/frontend/v1/stv/students/in
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/semester/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/semester/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStgOrgform/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/le/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByLe/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/lv/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByLv/$1/$2';
// load routes from extensions, also look for environment-specific configs
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
+44 -4
View File
@@ -26,6 +26,10 @@ $config['person'] = [
'comparison' => 'similar',
'field' => 'nachname'
],
'wahlname' => [
'comparison' => 'similar',
'field' => 'wahlname'
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)"
@@ -68,7 +72,7 @@ $config['person'] = [
'resultfields' => [
"ARRAY( SELECT uid FROM public.tbl_benutzer WHERE person_id = p.person_id ) AS uids",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"CASE WHEN p.wahlname IS NOT NULL THEN (p.wahlname || ' ' || p.nachname) ELSE (p.vorname || ' ' || p.nachname) END AS name",
"ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email",
"CASE
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
@@ -117,6 +121,20 @@ $config['student'] = [
]
]
],
'wahlname' => [
'comparison' => 'similar',
'field' => 'wahlname',
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
@@ -196,7 +214,7 @@ $config['student'] = [
"s.student_uid AS uid",
"s.matrikelnr",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"CASE WHEN p.wahlname IS NOT NULL THEN (p.wahlname || ' ' || p.nachname) ELSE (p.vorname || ' ' || p.nachname) END AS name",
"(s.student_uid || '@" . DOMAIN . "') || ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email",
"CASE
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
@@ -257,6 +275,14 @@ $config['prestudent'] = [
'using' => "person_id"
]
],
'wahlname' => [
'comparison' => 'similar',
'field' => 'wahlname',
'join' => [
'table' => "public.tbl_person",
'using' => "person_id"
]
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
@@ -314,7 +340,7 @@ $config['prestudent'] = [
"s.matrikelnr",
"p.person_id",
"b.uid",
"(p.vorname || ' ' || p.nachname) AS name",
"CASE WHEN p.wahlname IS NOT NULL THEN (p.wahlname || ' ' || p.nachname) ELSE (p.vorname || ' ' || p.nachname) END AS name",
"(b.uid || '@" . DOMAIN . "') || ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email",
"CASE
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
@@ -390,6 +416,20 @@ $config['employee'] = [
]
]
],
'wahlname' => [
'comparison' => 'similar',
'field' => "wahlname",
'join' => [
[
'table' => "public.tbl_benutzer",
'on' => "uid = mitarbeiter_uid"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
@@ -472,7 +512,7 @@ $config['employee'] = [
'resultfields' => [
"b.uid",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"CASE WHEN p.wahlname IS NOT NULL THEN (p.wahlname || ' ' || p.nachname) ELSE (p.vorname || ' ' || p.nachname) END AS name",
"ARRAY(
SELECT
'[' || ot.bezeichnung || '] ' || o.bezeichnung AS bezeichnung
+1 -1
View File
@@ -25,7 +25,7 @@ $config['student']['resultfields'] = [
"s.matrikelnr AS personenkennzeichen",
"p.person_id",
"p.matr_nr AS matrikelnummer",
"(p.vorname || ' ' || p.nachname) AS name",
"CASE WHEN p.wahlname IS NOT NULL THEN (p.wahlname || ' ' || p.nachname) ELSE (p.vorname || ' ' || p.nachname) END AS name",
"ARRAY[s.student_uid || '@' || '" . DOMAIN . "'] AS email",
"CASE
WHEN (p.foto_sperre = false AND p.foto IS NOT NULL) THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
+3 -2
View File
@@ -26,7 +26,8 @@ $config['root'] = [
'verband' => [
'group'
]
],
'orgform'
]
]
];
$config['root']['stg']['orgform'] = $config['root']['stg'];
+44
View File
@@ -0,0 +1,44 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Compat extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'ci' => ['basis/cis:r'],
'legacy' => ['basis/cis:r'],
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @access public
* @return void
*/
public function ci()
{
$this->load->view('CisRouterView/CisRouterView.php',['route' => 'Compat']);
}
/**
* @access public
* @return void
*/
public function legacy()
{
$this->load->view('CisRouterView/CisRouterView.php',['route' => 'Compat']);
}
}
@@ -1916,7 +1916,7 @@ class Abgabe extends FHCAPI_Controller
if (!$mailres)
{
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general');
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general');
}
}
@@ -50,6 +50,7 @@ class Cis4FhcApi extends FHCAPI_Controller
$viewData = array(
'uid' => getAuthUID(),
'name' => $personData->vorname,
'wahlname' => $personData->wahlname,
'person_id' => $personData->person_id,
'timezone' => $this->config->item('timezone'),
);
@@ -67,8 +67,11 @@ class CisMenu extends FHCAPI_Controller
private function generateUrlForMenuItem($menuItem)
{
$menuItem->url = $this->menuItemUrlHelper($menuItem);
unset($menuItem->content);
if(!isset($menuItem->url))
{
$menuItem->url = $this->menuItemUrlHelper($menuItem);
unset($menuItem->content);
}
if ($menuItem->childs && count($menuItem->childs)) {
$menuItem->childs = $this->generateUrlsForMenuItems($menuItem->childs);
@@ -83,7 +86,7 @@ class CisMenu extends FHCAPI_Controller
return site_url("/CisVue/Cms/content/" . $menuItem->content_id);
}
if (!$menuItem->content || !mb_strlen($menuItem->content)) {
if (!isset($menuItem->content) || !$menuItem->content || !mb_strlen($menuItem->content)) {
return '';
}
@@ -28,7 +28,10 @@ class Lehrveranstaltung extends FHCAPI_Controller
{
parent::__construct([
'getByEmp' => ['admin:r', 'assistenz:r'],
'getByLe' => ['admin:r', 'assistenz:r'],
'getByLv' => ['admin:r', 'assistenz:r'],
'getByStg' => ['admin:r', 'assistenz:r'],
'getByStgOrgform' => ['admin:r', 'assistenz:r'],
'loadByLV' => ['admin:r', 'assistenz:r'],
]);
@@ -77,41 +80,117 @@ class Lehrveranstaltung extends FHCAPI_Controller
$this->terminateWithSuccess($tree);
}
public function getByLe($studiensemester_kurzbz = null, $lehreinheit_id = null)
{
if (is_null($lehreinheit_id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$lehreinheiten = $this->_ci->LehreinheitModel->getByLeStudiensemester($lehreinheit_id, $studiensemester_kurzbz);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
$this->terminateWithSuccess($lehreinheiten_data);
}
public function getByLv($studiensemester_kurzbz = null, $lehrveranstaltung_id = null)
{
if (is_null($lehrveranstaltung_id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$tree = [];
$this->_ci->LehrveranstaltungModel->addSelect('studiengang_kz');
$lv = $this->_ci->LehrveranstaltungModel->load($lehrveranstaltung_id);
$lv = $this->getDataOrTerminateWithError($lv);
if (empty($lv))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehrveranstaltungen_data = array();
foreach ($this->_loadLvRows(current($lv)->studiengang_kz, $studiensemester_kurzbz) as $row)
{
if ((string)$row->lehrveranstaltung_id === (string)$lehrveranstaltung_id)
{
$lehrveranstaltungen_data[] = $row;
break;
}
}
if (empty($lehrveranstaltungen_data))
{
$this->_ci->LehrveranstaltungModel->addSelect('
tbl_lehrveranstaltung.*,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
lehrveranstaltung_id,
lehrtyp_kurzbz,
studiengang_kz as lv_studiengang_kz,
UPPER(CONCAT(tbl_studiengang.typ, tbl_studiengang.kurzbz)) as studiengang,
semester as semester,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
ects as lv_ects,
lehreverzeichnis as lv_lehreverzeichnis,
planfaktor as lv_planfaktor,
planlektoren as lv_planlektoren,
planpersonalkosten as lv_planpersonalkosten,
plankostenprolektor as lv_plankostenprolektor,
tbl_lehrveranstaltung.orgform_kurzbz as orgform_kurzbz,
tbl_lehrveranstaltung.sprache as sprache,
lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english,
semesterstunden as lv_semesterstunden,
');
$this->_ci->LehrveranstaltungModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$lehrveranstaltungen = $this->_ci->LehrveranstaltungModel->load($lehrveranstaltung_id);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
}
foreach ($lehrveranstaltungen_data as $lehrveranstaltung)
{
$lehreinheiten = $this->_ci->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
if (!isset($lehrveranstaltung->_children))
{
$lehrveranstaltung->_children = $lehreinheiten_data;
}
$tree[] = $lehrveranstaltung;
}
$counter = 0;
$this->assignUniqueIndex($tree, $counter);
$this->terminateWithSuccess($tree);
}
public function getByStg($studiensemester_kurzbz = null, $stg_kz = null, $semester = null)
{
$this->_getLvTree($studiensemester_kurzbz, $stg_kz, $semester, null);
}
public function getByStgOrgform($studiensemester_kurzbz = null, $stg_kz = null, $orgform = null, $semester = null)
{
$orgform_kurzbz = $this->getOrgformKurzbz($orgform);
$this->_getLvTree($studiensemester_kurzbz, $stg_kz, $semester, $orgform_kurzbz);
}
private function _getLvTree($studiensemester_kurzbz, $stg_kz, $semester, $orgform_kurzbz)
{
$studiengang_kz = $this->getStudiengangKz($stg_kz);
if (is_null($studiengang_kz) || !preg_match("/^(-?[1-9][0-9]*|0)$/", (string)$studiengang_kz))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$verband = null;
if (!is_null($semester) && !is_numeric($semester))
{
$verband = $this->getOrgformKurzbz($semester);
$semester = null;
}
$this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel');
if (!is_null($semester) && !ctype_digit((string)$semester))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$studienplan_ids = array();
$only_ids = array();
$placeholders = array();
if (hasData($studienplan_data))
{
foreach (getData($studienplan_data) as $studienplan) {
$placeholders[] = "(?, ?)";
$studienplan_ids[] = $studienplan->studienplan_id;
$studienplan_ids[] = $studienplan->semester;
$only_ids[] = $studienplan->studienplan_id;
}
}
$lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$lehrveranstaltungen_data = hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array();
$lehrveranstaltungen_data = $this->_loadLvRows($studiengang_kz, $studiensemester_kurzbz, $semester, $orgform_kurzbz);
$tree = [];
foreach ($lehrveranstaltungen_data as $row)
@@ -244,6 +323,31 @@ class Lehrveranstaltung extends FHCAPI_Controller
$this->LehreinheitModel->getLvsByFachbereich($fachbereich, $studiensemester_kurzbz, $mitarbeiter_uid);
}*/
private function _loadLvRows($studiengang_kz, $studiensemester_kurzbz, $semester = null, $orgform_kurzbz = null)
{
$this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel');
$studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $orgform_kurzbz);
$studienplan_ids = array();
$only_ids = array();
$placeholders = array();
if (hasData($studienplan_data))
{
foreach (getData($studienplan_data) as $studienplan) {
$placeholders[] = "(?, ?)";
$studienplan_ids[] = $studienplan->studienplan_id;
$studienplan_ids[] = $studienplan->semester;
$only_ids[] = $studienplan->studienplan_id;
}
}
$lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $orgform_kurzbz);
return hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array();
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
@@ -309,8 +413,8 @@ class Lehrveranstaltung extends FHCAPI_Controller
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
return $orgform_kurzbz;
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return current($data)->orgform_kurzbz;
}
}
}
@@ -62,6 +62,7 @@ class OtherLvPlan extends FHCAPI_Controller
"foto" => $profileData->data->foto,
"vorname" => $profileData->data->vorname,
"nachname" => $profileData->data->nachname,
"wahlname" => $profileData->data->wahlname,
"titel" => $profileData->data->titel,
"postnomen" => $profileData->data->postnomen,
],
@@ -101,6 +101,9 @@ class Widget extends FHCAPI_Controller
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
$widget->permitted = empty($widget->berechtigung_kurzbz)
|| $this->permissionlib->isBerechtigt($widget->berechtigung_kurzbz);
return $widget;
}, $widgets);
@@ -28,7 +28,8 @@ class Studiensemester extends FHCAPI_Controller
'getStudienjahrByStudiensemester' => self::PERM_LOGGED,
'getAllStudiensemesterAndAktOrNext' => self::PERM_LOGGED,
'current' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
'set' => self::PERM_LOGGED,
'getContainingOrNearestByDateRange' => self::PERM_LOGGED,
)
);
// Load model StudiensemesterModel
@@ -203,4 +204,15 @@ class Studiensemester extends FHCAPI_Controller
$this->terminateWithSuccess(true);
}
public function getContainingOrNearestByDateRange()
{
$from = $this->input->get("from");
$to = $this->input->get("to");
$result = $this->StudiensemesterModel->getContainingOrNearestByDateRange($from, $to);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -574,6 +574,19 @@ class Kontakt extends FHCAPI_Controller
$person_id = $this->input->post('person_id');
$standort_id = $this->input->post('standort_id');
//check person_id: allow editing only of persons who are no mitarbeiter
if($person_id)
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->BenutzerModel->addJoin('public.tbl_mitarbeiter ma', 'ON (ma.mitarbeiter_uid = public.tbl_benutzer.uid)');
$result = $this->BenutzerModel->loadWhere([
'person_id' => $person_id
]);
if(hasData($result))
return $this->terminateWithError($this->p->t('ui', 'editingMitarbeiterPVonly'), self::ERROR_TYPE_GENERAL);
}
$result = $this->KontaktModel->update(
[
'kontakt_id' => $kontakt_id
+1 -1
View File
@@ -329,7 +329,7 @@ class ProfilLib{
private function getPersonInfo($uid, $geburtsInfo = null)
{
$this->ci->load->model("person/Benutzer_model","BenutzerModel");
$selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"];
$selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname", "wahlname"];
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
+101 -4
View File
@@ -33,7 +33,7 @@ class SearchBarLib
const ERROR_NOT_AUTH = 'ERR005';
// List of allowed types of search
const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student','studentStv', 'prestudent', 'document', 'cms'];
const ALLOWED_TYPES = ['mitarbeiter', 'mitarbeiter_ohne_zuordnung', 'organisationunit', 'raum', 'person', 'student','studentStv', 'prestudent', 'document', 'cms', 'lehreinheit', 'lehrveranstaltung'];
const PHOTO_IMG_URL = '/cis/public/bild.php?src=person&person_id=';
@@ -180,10 +180,14 @@ class SearchBarLib
protected function buildSearchClause(DB_Model $dbModel, array $columns, $searchstr)
{
$searchstr = preg_replace('/[[:punct:]]/', ' ', $searchstr);
$words = preg_split('/\s+/', trim($searchstr), -1, PREG_SPLIT_NO_EMPTY);
if (empty($words)) return array();
$document = implode(' || \' \' || ', $columns);
$query = '\'' . implode(':* & ', explode(' ', trim($searchstr))) . ':*\'';
$reversequery = '\'*:' . implode(' & *:', explode(' ', trim($searchstr))) . '\'';
$nospacequery = '\'' . implode('', explode(' ', trim($searchstr))) . ':*\'';
$query = '\'' . implode(':* & ', $words) . ':*\'';
$reversequery = '\'*:' . implode(' & *:', $words) . '\'';
$nospacequery = '\'' . implode('', $words) . ':*\'';
$searchclause = <<<EOSC
to_tsvector(lower(regexp_replace({$document}, '[[:punct:]]', ' ', 'g'))) @@ to_tsquery(lower({$query}))
@@ -596,5 +600,98 @@ EOSC;
// Otherwise return an empty array
return array();
}
private function _lehreinheit($searchstr, $type)
{
$dbModel = new DB_Model();
$idwhere = '';
if (ctype_digit(trim($searchstr)))
{
$id = (int)trim($searchstr);
$idwhere = ' OR le.lehreinheit_id = ' . $id;
}
$lehreinheit = $dbModel->execReadOnlyQuery('
SELECT
\'teachingunit\' AS renderer,
\''.$type.'\' AS type,
le.lehreinheit_id AS id,
le.studiensemester_kurzbz,
lv.bezeichnung,
\'lv_table_icon icon-\' AS foto,
UPPER(stg.typ || stg.kurzbz) AS studiengang,
le.lehrform_kurzbz,
lv.semester
FROM lehre.tbl_lehreinheit le
JOIN lehre.tbl_lehrveranstaltung lv ON (lv.lehrveranstaltung_id = le.lehrveranstaltung_id)
JOIN public.tbl_studiengang stg ON (stg.studiengang_kz = lv.studiengang_kz)
JOIN public.tbl_studiensemester sem ON (sem.studiensemester_kurzbz = le.studiensemester_kurzbz)
WHERE (' .
$this->buildSearchClause(
$dbModel,
array(
'(stg.typ || stg.kurzbz)',
'lv.semester',
'lv.bezeichnung'
),
$searchstr
) . ')' . $idwhere . '
');
// If something has been found then return it
if (hasData($lehreinheit)) return getData($lehreinheit);
// Otherwise return an empty array
return array();
}
private function _lehrveranstaltung($searchstr, $type)
{
$dbModel = new DB_Model();
$idwhere = '';
if (ctype_digit(trim($searchstr)))
{
$id = (int)trim($searchstr);
$idwhere = ' OR tbl_lehrveranstaltung.lehrveranstaltung_id = ' . $id;
}
$lehreinheit = $dbModel->execReadOnlyQuery('
SELECT
\'teachingunit\' AS renderer,
\''.$type.'\' AS type,
lehrveranstaltung_id as id,
tbl_lehrveranstaltung.bezeichnung,
\'lv_table_icon icon-lv\' as foto,
UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as studiengang,
semester,
lehrform_kurzbz,
tbl_organisationseinheit.bezeichnung as oe_bezeichnung
FROM lehre.tbl_lehrveranstaltung
JOIN public.tbl_studiengang USING(studiengang_kz)
JOIN public.tbl_organisationseinheit ON tbl_lehrveranstaltung.oe_kurzbz = tbl_organisationseinheit.oe_kurzbz
WHERE (' .
$this->buildSearchClause(
$dbModel,
array(
'(tbl_studiengang.typ || tbl_studiengang.kurzbz)',
'semester',
'tbl_lehrveranstaltung.bezeichnung'
),
$searchstr
) . ')' . $idwhere . '
');
// If something has been found then return it
if (hasData($lehreinheit)) return getData($lehreinheit);
// Otherwise return an empty array
return array();
}
}
@@ -159,8 +159,6 @@ class LvVwLib
if (!$stg->mischform)
return [];
$this->_ci->StudiengangModel->db->select('TRUE AS leaf', false);
return $this->_ci->stglib->orgform($path_template, $stg->studiengang_kz);
}
@@ -340,6 +340,20 @@ EOSQL;
}
public function getByLeStudiensemester($lehreinheit_id, $studiensemester_kurzbz)
{
$qry = "WITH lehreinheiten AS (
SELECT *
FROM lehre.tbl_lehreinheit
WHERE lehreinheit_id = ?
AND studiensemester_kurzbz = ?
)," . $this->_getLeCTE();
$params = array($lehreinheit_id, $studiensemester_kurzbz);
return $this->execReadOnlyQuery($qry, $params);
}
public function getByLvidStudiensemester($lv_id, $studiensemester_kurzbz, $mitarbeiter_uid = null, $fachbereich_kurzbz = null)
{
$qry = "WITH lehreinheiten AS (
@@ -347,35 +361,7 @@ EOSQL;
FROM lehre.tbl_lehreinheit
WHERE lehrveranstaltung_id = ?
AND studiensemester_kurzbz = ?
),
". $this->_getGruppenCTE() . ",
". $this->_getLektorenCTE() . ",
". $this->_getFachbereichCTE() . ",
". $this->_getTagsCTE() . "
SELECT lehreinheiten.*,
lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
COALESCE(tag_data_agg.tags, '[]'::json) AS tags,
gruppen.gruppen,
mitarbeiter.lektoren,
mitarbeiter.le_planstunden,
mitarbeiter.vorname,
mitarbeiter.nachname,
mitarbeiter.semesterstunden,
fachbereich.bezeichnung as fachbereich,
UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang,
semester
FROM lehreinheiten
LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id
LEFT JOIN mitarbeiter ON lehreinheiten.lehreinheit_id = mitarbeiter.lehreinheit_id
LEFT JOIN fachbereich ON lehreinheiten.lehreinheit_id = fachbereich.lehreinheit_id
LEFT JOIN gruppen ON lehreinheiten.lehreinheit_id = gruppen.lehreinheit_id
WHERE true
";
)," . $this->_getLeCTE();
$params = array($lv_id, $studiensemester_kurzbz);
@@ -395,9 +381,83 @@ EOSQL;
return $this->execReadOnlyQuery($qry, $params);
}
private function getLVTmp($stg_kz = null)
public function getOffeneStunden($lehreinheit_ids)
{
$qry = "SELECT DISTINCT ON(lehrveranstaltung_id) *,
if (!is_array($lehreinheit_ids))
$lehreinheit_ids = [$lehreinheit_ids];
if (empty($lehreinheit_ids))
return success([]);
$db = new DB_Model();
$placeholders = implode(',', array_fill(0, count($lehreinheit_ids), '?'));
$qry = "WITH eventdauer AS (
SELECT
tbl_kalender_lehreinheit.lehreinheit_id,
tbl_kalender.von,
tbl_kalender.bis,
tbl_kalender.kalender_id
FROM lehre.tbl_lehreinheit
JOIN lehre.tbl_kalender_lehreinheit USING(lehreinheit_id)
JOIN lehre.tbl_kalender USING(kalender_id)
WHERE tbl_lehreinheit.lehreinheit_id IN ($placeholders)
AND NOT EXISTS (SELECT 1 FROM lehre.tbl_kalender nachfolger
WHERE nachfolger.vorgaenger_kalender_id = tbl_kalender.kalender_id)
AND tbl_kalender.status_kurzbz NOT IN ('deleted', 'todelete', 'archived')
GROUP BY tbl_kalender_lehreinheit.lehreinheit_id, tbl_kalender.von, tbl_kalender.bis, tbl_kalender.kalender_id
),
raster AS (
SELECT
eventdauer.lehreinheit_id,
eventdauer.kalender_id,
eventdauer.von,
eventdauer.bis,
vonstunde.stunde AS vonstunde_nr,
bisstunde.stunde AS bisstunde_nr
FROM eventdauer
LEFT JOIN lehre.tbl_stunde vonstunde ON eventdauer.von::time = vonstunde.beginn
LEFT JOIN lehre.tbl_stunde bisstunde ON eventdauer.bis::time = bisstunde.ende
),
unterrichtsdauer AS (
SELECT
raster.lehreinheit_id,
raster.kalender_id,
sum(EXTRACT(EPOCH FROM (LEAST(stunde.ende, raster.bis::time) - GREATEST(stunde.beginn, raster.von::time))) / 60) AS minuten
FROM raster JOIN lehre.tbl_stunde stunde ON stunde.beginn < raster.bis::time AND stunde.ende > raster.von::time
WHERE raster.vonstunde_nr IS NULL OR raster.bisstunde_nr IS NULL
GROUP BY raster.lehreinheit_id, raster.kalender_id
),
verplantestunden AS (
SELECT raster.lehreinheit_id, raster.kalender_id,
CASE
WHEN raster.vonstunde_nr IS NOT NULL AND raster.bisstunde_nr IS NOT NULL
THEN (raster.bisstunde_nr - raster.vonstunde_nr + 1)
ELSE coalesce(unterrichtsdauer.minuten, 0) / 45
END AS verplantestunde
FROM raster LEFT JOIN unterrichtsdauer ON unterrichtsdauer.lehreinheit_id = raster.lehreinheit_id AND unterrichtsdauer.kalender_id = raster.kalender_id
),
verplant_gesamt AS (
SELECT lehreinheit_id, SUM(verplantestunde) AS verplant
FROM verplantestunden
GROUP BY lehreinheit_id
)
SELECT
lema.lehreinheit_id,
lema.mitarbeiter_uid,
lema.planstunden,
ROUND(coalesce(verplant_gesamt.verplant, 0), 2) AS verplant,
ROUND((lema.planstunden - coalesce(verplant_gesamt.verplant, 0)), 2) AS offenestunden
FROM lehre.tbl_lehreinheitmitarbeiter lema
LEFT JOIN verplant_gesamt ON verplant_gesamt.lehreinheit_id = lema.lehreinheit_id
WHERE lema.lehreinheit_id IN ($placeholders)";
return $db->execReadOnlyQuery($qry, array_merge($lehreinheit_ids, $lehreinheit_ids));
}
private function getLVTmp()
{
return "SELECT DISTINCT ON(lehrveranstaltung_id) *,
'' as stundenblockung,
'' as lehreinheit_id,
'' as wochenrythmus,
@@ -408,24 +468,33 @@ EOSQL;
'' as studienplan_beeichnung,
UPPER(CONCAT(vw_lehreinheit.stg_typ, vw_lehreinheit.stg_kurzbz)) as studiengang
FROM campus.vw_lehreinheit
WHERE mitarbeiter_uid = ?
AND studiensemester_kurzbz = ?";
if (!is_null($stg_kz)) {
$qry .= " AND lv_studiengang_kz = ?";
}
return $qry;
WHERE studiensemester_kurzbz = ? ";
}
public function getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz = null)
public function getLvsById($lehrveranstaltung_id, $studiensemester_kurzbz)
{
$qry = "WITH lvs AS (" . $this->getLVTmp($stg_kz) . ")
$where = ' AND lehrveranstaltung_id = ?';
$qry = "WITH lvs AS (" . $this->getLVTmp() . $where .")
SELECT lvs.*
FROM lvs
";
";
$params = array($studiensemester_kurzbz, $lehrveranstaltung_id);
return $this->execReadOnlyQuery($qry, $params);
}
public function getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz = null)
{
$where = ' AND mitarbeiter_uid = ?';
if ($stg_kz != null)
$where .= " AND lv_studiengang_kz = ?";
$qry = "WITH lvs AS (" . $this->getLVTmp() . $where .")
SELECT lvs.*
FROM lvs";
$params = array($studiensemester_kurzbz, $mitarbeiter_uid);
$params = array($mitarbeiter_uid, $studiensemester_kurzbz);
if (!is_null($stg_kz))
{
$params[] = $stg_kz;
@@ -632,6 +701,36 @@ EOSQL;
return success('Contract successfully updated.');
}
private function _getLeCTE()
{
return $this->_getGruppenCTE() . ",
". $this->_getLektorenCTE() . ",
". $this->_getFachbereichCTE() . ",
". $this->_getTagsCTE() . "
SELECT lehreinheiten.*,
lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz,
tbl_lehrveranstaltung.kurzbz as lv_kurzbz,
tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung,
COALESCE(tag_data_agg.tags, '[]'::json) AS tags,
gruppen.gruppen,
mitarbeiter.lektoren,
mitarbeiter.le_planstunden,
mitarbeiter.vorname,
mitarbeiter.nachname,
mitarbeiter.semesterstunden,
fachbereich.bezeichnung as fachbereich,
UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang,
semester
FROM lehreinheiten
LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id
LEFT JOIN mitarbeiter ON lehreinheiten.lehreinheit_id = mitarbeiter.lehreinheit_id
LEFT JOIN fachbereich ON lehreinheiten.lehreinheit_id = fachbereich.lehreinheit_id
LEFT JOIN gruppen ON lehreinheiten.lehreinheit_id = gruppen.lehreinheit_id
WHERE true";
}
private function _getGruppenCTE()
{
return "gruppen AS (
@@ -292,13 +292,29 @@ class Studiensemester_model extends DB_Model
COALESCE(
(SELECT studiensemester_kurzbz FROM semester_interval_startdate),
(SELECT studiensemester_kurzbz FROM nearest_semester_interval_startdate)
) AS studiensemester_kurzbz
) AS studiensemester_kurzbz,
COALESCE(
(SELECT start FROM semester_interval_startdate),
(SELECT start FROM nearest_semester_interval_startdate)
) as start,
COALESCE(
(SELECT ende FROM semester_interval_startdate),
(SELECT ende FROM nearest_semester_interval_startdate)
) as ende
UNION
SELECT
COALESCE(
(SELECT studiensemester_kurzbz FROM semester_interval_enddate),
(SELECT studiensemester_kurzbz FROM nearest_semester_interval_enddate)
) AS studiensemester_kurzbz
) AS studiensemester_kurzbz,
COALESCE(
(SELECT start FROM semester_interval_enddate),
(SELECT start FROM nearest_semester_interval_enddate)
) as start,
COALESCE(
(SELECT ende FROM semester_interval_enddate),
(SELECT ende FROM nearest_semester_interval_enddate)
) as ende
EOSQL;
+1 -1
View File
@@ -245,7 +245,7 @@ class Person_model extends DB_Model
*/
public function getByUid($uid)
{
$this->addSelect('vorname, nachname, gebdatum, person_id, bpk, matr_nr, foto');
$this->addSelect('vorname, nachname, wahlname, gebdatum, person_id, bpk, matr_nr, foto');
$this->addJoin('tbl_benutzer', 'person_id');
return $this->loadWhere(array('uid' => $uid));
@@ -21,6 +21,7 @@ $this->load->view('templates/FHC-Header', $includesArray);
?>
<script type="text/javascript">
document.body.classList.add("cis4");
if (window.self !== window.top)
document.body.classList.add("in-frame");
</script>
+4 -3
View File
@@ -179,7 +179,8 @@ echo ' <title>' . $p->t('mailverteiler/personenImVerteiler') . '</title>
<body id="inhalt">';
$qry = "SELECT
uid, vorname, nachname, geschlecht, fixangestellt
uid, vorname, nachname, wahlname, geschlecht, fixangestellt,
CASE WHEN wahlname IS NOT NULL THEN wahlname ELSE vorname END AS orderVorname
FROM
campus.vw_benutzer
JOIN
@@ -202,7 +203,7 @@ $qry = "SELECT
}
$qry .= " ORDER BY
nachname, vorname";
nachname, orderVorname";
echo '<p>'.$p->t('mailverteiler/anleitungstextMailPersInGroup').'<p>';
echo '<a class="buttongreen" href="#" onclick="SendMail()" id="mailSendButton">' . $p->t('mailverteiler/mailAnAlleSenden') . '</a>';
@@ -236,7 +237,7 @@ if ($result = $db->db_query($qry))
echo '<tr>';
echo ' <td style="text-align: center"><input type="checkbox" class="chkbox" id="checkbox_'.$row->uid.'" name="checkbox['.$row->uid.']"></td>';
echo ' <td>'.$row->nachname.'</td>';
echo ' <td>'.$row->vorname.'</td>';
echo ' <td>'. ($row->wahlname ? $row->wahlname : $row->vorname) .'</td>';
echo ' <td>'.strtoupper($row->geschlecht).'</td>';
echo ' <td>'.($row->fixangestellt != '' ? ($row->fixangestellt == 't' ? 'Ja' : 'Nein') :'-').'</td>';
echo ' <td class="clm_email"><a href="mailto:'.$row->uid.'@' . DOMAIN . '" class="Item">'.$row->uid .'@' . DOMAIN . '</a></td>';
+3 -1
View File
@@ -256,7 +256,9 @@ echo '
'.$p->t('global/anrede').': '.$user->anrede.'<br>
'.$p->t('global/titel').': '.$user->titelpre.' <br>';
if (!$ansicht)
if ($user->wahlname)
echo $p->t('global/vorname').': '.$user->wahlname.' <br>';
else if (!$ansicht)
echo $p->t('global/vorname').': '.$user->vorname.' '.$user->vornamen.'<br>';
else
echo $p->t('global/vorname').': '.$user->vorname.' <br>';
+7 -5
View File
@@ -162,7 +162,8 @@ if (!isset($_GET['kz']))
if (isset($_GET['all']))
{
$qry = "SELECT
vorname, nachname, uid, geschlecht
vorname, nachname, wahlname, uid, geschlecht,
CASE WHEN wahlname IS NOT NULL THEN wahlname ELSE vorname END AS orderVorname
FROM
campus.vw_student
WHERE
@@ -170,12 +171,13 @@ if (isset($_GET['all']))
AND studiengang_kz=".$db->db_add_param($_GET['kz'])."
AND semester<10
AND semester>0
ORDER BY nachname, vorname";
ORDER BY nachname, orderVorname";
}
else
{
$qry = "SELECT
vorname, nachname, uid, geschlecht
vorname, nachname, wahlname, uid, geschlecht,
CASE WHEN wahlname IS NOT NULL THEN wahlname ELSE vorname END AS orderVorname
FROM
campus.vw_student
WHERE
@@ -191,7 +193,7 @@ else
if (isset($_GET['grp']))
$qry.=" AND gruppe=".$db->db_add_param($_GET['grp']);
$qry.= ' ORDER BY nachname, vorname';
$qry.= ' ORDER BY nachname, orderVorname';
}
echo '<p>'.$p->t('mailverteiler/anleitungstextMailPersInGroup').'<p>';
echo '<a class="buttongreen" href="#" onclick="SendMail()" id="mailSendButton">' . $p->t('mailverteiler/mailAnAlleSenden') . '</a>';
@@ -223,7 +225,7 @@ if ($result = $db->db_query($qry))
echo "<tr>";
echo ' <td style="text-align: center"><input type="checkbox" class="chkbox" id="checkbox_'.$row->uid.'" name="checkbox['.$row->uid.']"></td>';
echo " <td>$row->nachname</td>";
echo " <td>$row->vorname</td>";
echo " <td>" . ($row->wahlname ? $row->wahlname : $row->vorname) . "</td>";
echo ' <td>'.strtoupper($row->geschlecht).'</td>';
echo ' <td class="clm_email"><a href="mailto:'.$row->uid.'@' . DOMAIN . '" class="Item">'.$row->uid .'@' . DOMAIN . '</a></td>';
echo "</tr>";
+1 -1
View File
@@ -180,7 +180,7 @@ function searchPerson($searchItems)
echo '<td>',$row->anrede,'</td>';
if ($row->wahlname)
echo '<td>',$row->wahlname, ' ' ,$row->vorname, '</td>';
echo '<td>',$row->wahlname,'</td>';
else
echo '<td>',$row->vorname, '</td>';
+1
View File
@@ -632,6 +632,7 @@ elseif (isset($prestudent_id))
$ps_obj->lastStatus = $ps_tmp->status_kurzbz; // letzten Status dem result array hinzufügen
$ps_obj->status_mehrsprachig = $ps_tmp->status_mehrsprachig;
$ps_obj->ausbildungssemester = $ps_tmp->ausbildungssemester;
}
// Falls Status 'Abgewiesene' vorhanden, nach hinten reihen
+33 -15
View File
@@ -29,6 +29,7 @@ require_once('../../include/sprache.class.php');
require_once '../../include/phrasen.class.php';
require_once '../../include/studiengang.class.php';
require_once('../../include/gebiet.class.php');
require_once('../../include/gebiet_pruefling.class.php');
if (!$db = new basis_db())
die('Fehler beim Oeffnen der Datenbankverbindung');
@@ -198,8 +199,8 @@ else if (isset($_SESSION['pruefling_id']))
)
SELECT DISTINCT ON
(gebiet_id, semester, reihung)
SELECT * FROM (SELECT DISTINCT ON
(gebiet_id)
semester,
gebiet_id,
STRING_AGG(studiengang_kz::TEXT, ', ' ORDER BY studiengang_kz) AS studiengang_kz_list,
@@ -226,13 +227,7 @@ else if (isset($_SESSION['pruefling_id']))
JOIN
testtool.tbl_gebiet USING (gebiet_id)
WHERE
(
(prestudent_data.semester= 1 AND tbl_ablauf.semester = 1)
OR
(prestudent_data.semester= 2 AND tbl_ablauf.semester = 2)
OR
(prestudent_data.semester= 3 AND tbl_ablauf.semester IN (1,3))
)
tbl_ablauf.semester <= prestudent_data.semester
AND (
prestudent_data.studienplan_id = tbl_ablauf.studienplan_id
OR
@@ -259,9 +254,7 @@ else if (isset($_SESSION['pruefling_id']))
JOIN
testtool.tbl_gebiet USING (gebiet_id)
WHERE
(prestudent_data.semester= 1 AND tbl_ablauf.semester = 1)
OR
(prestudent_data.semester= 3 AND tbl_ablauf.semester IN (1,3))
tbl_ablauf.semester <= prestudent_data.semester
)
) temp
) temp2
@@ -270,7 +263,7 @@ else if (isset($_SESSION['pruefling_id']))
semester,
gebiet_id,
bezeichnung,
". $bezeichnung_mehrsprachig_sel ."
". $bezeichnung_mehrsprachig_sel ." ) temp3
ORDER BY
semester,
@@ -283,6 +276,8 @@ else if (isset($_SESSION['pruefling_id']))
$lastsemester = '';
$quereinsteiger_stg = '';
$_SESSION['alleGebiete']= [];
$gebiet_pruefling = new gebiet_pruefling();
$quereinsteiger_menu = false;
while($row = $db->db_fetch_object($result))
{
//Jedes Semester in einer eigenen Tabelle anzeigen
@@ -294,8 +289,25 @@ 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 '<tr><td class="HeaderTesttool">'. ($row->semester == '1' ? $p->t('testtool/basisgebiete') : $p->t('testtool/quereinstiegsgebiete')).'</td></tr>';
if ($row->semester == '1')
{
// Basisgebiete anzeigen
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px; margin-top: 5px;">';
echo '<tr><td class="HeaderTesttool">' . $p->t('testtool/basisgebiete') . '</td></tr>';
}
else
{
if (!$quereinsteiger_menu)
{
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px; margin-top: 5px;">';
echo '<tr><td class="HeaderTesttool">' . $p->t('testtool/quereinstiegsgebiete') . '</td></tr>';
$quereinsteiger_menu = true;
}
else
{
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px; margin-top: 5px;">';
}
}
}
// Bei Quereinstiegsgebieten nach STG clustern und die STG anzeigen
@@ -394,6 +406,12 @@ else if (isset($_SESSION['pruefling_id']))
</td>
<!--<td width="10" class="ItemTesttoolRight" nowrap>&nbsp;</td>-->
</tr>';
if (!$gebiet_pruefling->checkIfExists($_SESSION['pruefling_id'], $row->gebiet_id))
{
$gebiet_pruefling->pruefling_id = $_SESSION['pruefling_id'];
$gebiet_pruefling->gebiet_id = $row->gebiet_id;
$gebiet_pruefling->saveGebietForPruefling();
}
$_SESSION['alleGebiete'][] = $row->gebiet_id;
}
else
+63 -25
View File
@@ -21,6 +21,7 @@
* Manuela Thamer <[email protected]>
*/
require_once(dirname(__FILE__).'/basis_db.class.php');
require_once(dirname(__FILE__).'/mitarbeiter.class.php');
class entwicklungsteam extends basis_db
{
@@ -43,7 +44,6 @@ class entwicklungsteam extends basis_db
public $ext_id;
public $besqual;
public $studiengang_kz_old;
/**
* Konstruktor
@@ -74,7 +74,7 @@ class entwicklungsteam extends basis_db
$qry = "SELECT * FROM bis.tbl_entwicklungsteam JOIN bis.tbl_besqual USING(besqualcode)
WHERE entwicklungsteam_id=".$this->db_add_param($entwicklungsteam_id);
$qry.=";";
$qry.=";";
if($this->db_query($qry))
{
@@ -147,6 +147,11 @@ class entwicklungsteam extends basis_db
$this->errormsg = 'Es muss ein Mitarbeiter angegeben werden';
return false;
}
if(!$this->checkIfExistingUid($this->mitarbeiter_uid))
{
$this->errormsg = 'Bitte einen Eintrag aus dem Dropdown Personensuche auswählen!';
return false;
}
if($this->studiengang_kz=='')
{
$this->errormsg = 'Es muss ein Studiengang angegeben werden';
@@ -162,6 +167,26 @@ class entwicklungsteam extends basis_db
$this->errormsg = 'Endedatum darf nicht vor Anfangsdatum liegen';
return false;
}
if($this->beginn != '')
{
$beginnParts = explode('-', $this->beginn);
if (!checkdate((int)$beginnParts[1], (int)$beginnParts[2], (int)$beginnParts[0])) {
$this->errormsg = 'Anfangsdatum ist ungültig';
return false;
}
}
if($this->ende != '')
{
$endeParts = explode('-', $this->ende);
if (!checkdate((int)$endeParts[1], (int)$endeParts[2], (int)$endeParts[0]))
{
$this->errormsg = 'Endedatum ist ungültig';
return false;
}
}
return true;
}
@@ -183,30 +208,28 @@ class entwicklungsteam extends basis_db
//Neuen Datensatz anlegen
$qry = "INSERT INTO bis.tbl_entwicklungsteam (mitarbeiter_uid, studiengang_kz, besqualcode, beginn, ende,
updateamum, updatevon, insertamum, insertvon) VALUES (".
$this->db_add_param($this->mitarbeiter_uid).', '.
$this->db_add_param($this->studiengang_kz, FHC_INTEGER).', '.
$this->db_add_param($this->besqualcode, FHC_INTEGER).', '.
$this->db_add_param($this->beginn).', '.
$this->db_add_param($this->ende).', '.
$this->db_add_param($this->updateamum).', '.
$this->db_add_param($this->updatevon).', '.
$this->db_add_param($this->insertamum).', '.
$this->db_add_param($this->insertvon).');';
$this->db_add_param($this->mitarbeiter_uid).', '.
$this->db_add_param($this->studiengang_kz, FHC_INTEGER).', '.
$this->db_add_param($this->besqualcode, FHC_INTEGER).', '.
$this->db_add_param($this->beginn).', '.
$this->db_add_param($this->ende).', '.
$this->db_add_param($this->updateamum).', '.
$this->db_add_param($this->updatevon).', '.
$this->db_add_param($this->insertamum).', '.
$this->db_add_param($this->insertvon).');';
}
else
{
if($this->studiengang_kz_old=='')
$this->studiengang_kz_old = $this->studiengang_kz;
//Bestehenden Datensatz aktualisieren
$qry= "UPDATE bis.tbl_entwicklungsteam SET".
" besqualcode=".$this->db_add_param($this->besqualcode, FHC_INTEGER).",".
" beginn=".$this->db_add_param($this->beginn).",".
" studiengang_kz=".$this->db_add_param($this->studiengang_kz, FHC_INTEGER).",".
" ende=".$this->db_add_param($this->ende).",".
" updateamum=".$this->db_add_param($this->updateamum).",".
" updatevon=".$this->db_add_param($this->updatevon).
" WHERE entwicklungsteam_id=".$this->db_add_param($this->entwicklungsteam_id).";";
" besqualcode=".$this->db_add_param($this->besqualcode, FHC_INTEGER).",".
" beginn=".$this->db_add_param($this->beginn).",".
" studiengang_kz=".$this->db_add_param($this->studiengang_kz, FHC_INTEGER).",".
" ende=".$this->db_add_param($this->ende).",".
" mitarbeiter_uid=".$this->db_add_param($this->mitarbeiter_uid).",".
" updateamum=".$this->db_add_param($this->updateamum).",".
" updatevon=".$this->db_add_param($this->updatevon).
" WHERE entwicklungsteam_id=".$this->db_add_param($this->entwicklungsteam_id).";";
}
if($this->db_query($qry))
@@ -234,7 +257,7 @@ class entwicklungsteam extends basis_db
if($studiengang_kz!=null)
$qry.=" AND studiengang_kz=".$this->db_add_param($studiengang_kz);
$qry.=";";
$qry.=";";
if($this->db_query($qry))
{
@@ -316,7 +339,7 @@ class entwicklungsteam extends basis_db
if ($sort != null)
{
$qry .= " ORDER BY ".$sort;
$qry .= " ORDER BY ".$sort;
}
$qry .= ";";
@@ -364,7 +387,7 @@ 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 tbl_entwicklungsteam.*, tbl_besqual.*, tbl_studiengang.studiengang_kz, tbl_studiengang.melderelevant
FROM bis.tbl_entwicklungsteam
JOIN bis.tbl_besqual USING(besqualcode)
JOIN public.tbl_studiengang USING(studiengang_kz)
@@ -375,7 +398,7 @@ class entwicklungsteam extends basis_db
if($studiengang_kz!=null)
$qry.=" AND studiengang_kz=".$this->db_add_param($studiengang_kz);
$qry.=";";
$qry.=";";
if($this->db_query($qry))
{
@@ -407,5 +430,20 @@ class entwicklungsteam extends basis_db
return false;
}
}
/*
* Überprüft, ob die übergebene Uid in der Tabelle tbl_mitarbeiter vorhanden ist
* @param String $uid UID des Mitarbeiters
* @return true wenn vorhanden, false wenn nicht
*/
private function checkIfExistingUid($uid)
{
$mitarbeiter = new mitarbeiter();
if(!$mitarbeiter->checkIfExistingUid($uid))
return false;
return true;
}
}
?>
+97
View File
@@ -0,0 +1,97 @@
<?php
/* Copyright (C) 2024 Technikum-Wien
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
require_once(dirname(__FILE__).'/basis_db.class.php');
class gebiet_pruefling extends basis_db
{
//Tabellenspalten
public $prueflinggebiet_id;
public $pruefling_id;
public $gebiet_id;
public $insertamum;
public function __construct()
{
parent::__construct();
}
public function loadByPruefling($pruefling_id)
{
$qry = "SELECT *
FROM testtool.tbl_pruefling_gebiet
WHERE pruefling_id = ".$this->db_add_param($pruefling_id, FHC_INTEGER);
if($this->db_query($qry))
{
if($row = $this->db_fetch_object())
{
$this->prueflinggebiet_id = $row->prueflinggebiet_id;
$this->pruefling_id = $row->pruefling_id;
$this->gebiet_id = $row->gebiet_id;
return true;
}
else
{
$this->errormsg = "Pruefling nicht gefunden";
return false;
}
}
else
{
$this->errormsg = "Fehler beim Laden der Gebiete für den Pruefling";
return false;
}
}
public function checkIfExists($pruefling_id, $gebiet_id)
{
$qry = "SELECT 1
FROM testtool.tbl_pruefling_gebiet
WHERE pruefling_id =".$this->db_add_param($pruefling_id, FHC_INTEGER) ." AND gebiet_id =".$this->db_add_param($gebiet_id, FHC_INTEGER);
if ($result = $this->db_query($qry))
{
if ($this->db_num_rows($result) > 0)
return true;
else
return false;
}
}
public function saveGebietForPruefling()
{
$qry = "INSERT INTO testtool.tbl_pruefling_gebiet
(pruefling_id, gebiet_id)
VALUES(".
$this->db_add_param($this->pruefling_id, FHC_INTEGER).','.
$this->db_add_param($this->gebiet_id, FHC_INTEGER).');';
if ($this->db_query($qry))
{
return true;
}
else
{
$this->errormsg = 'Fehler beim Speichern der Daten';
return true;
}
}
}
?>
+18
View File
@@ -1995,5 +1995,23 @@ class mitarbeiter extends benutzer
return true;
}
}
/**
* Prueft ob eine existierende ma_uid übergeben wurde
* @param String $mitarbeiter_uid mitarbeiter_uid
* @return bool True wenn mitarbeiter_uid vorhanden sonst false.
*/
public function checkIfExistingUid($mitarbeiter_uid)
{
$qry = "Select 1 from public.tbl_mitarbeiter where mitarbeiter_uid =".$this->db_add_param($mitarbeiter_uid);
if ($result = $this->db_query($qry))
{
if ($this->db_num_rows($result) > 0)
return true;
else
return false;
}
}
}
?>
+25 -4
View File
@@ -7,6 +7,11 @@ html {
font-size: 0.875em;
}
body.compat,
body.compat main#cis-main {
background-color: #fff;
}
.fhc-dark-bg{
background-color: var(--fhc-dark);
color:var(--fhc-light) !important;
@@ -454,8 +459,8 @@ html {
/* desktop */
@media (min-width: 992px) {
body {
display: flex;
body.cis4 {
display: flex;
padding-top: var(--fhc-cis-header-height);
width: calc(100svw - var(--scrollbar-width, 0px));
/* overflow: visible !important; */
@@ -760,7 +765,7 @@ html {
}
.dashboard-item {
overscroll-behavior: none;
overscroll-behavior: auto;
}
.abgabe-zieldatum-border-red,
@@ -853,4 +858,20 @@ html {
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 0.5rem;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
}
}
.cis-main-menu {
max-width: 100vw;
}
.cis-main-menu ul {
list-style: none;
margin: 0;
padding: 0;
}
.cis-main-menu ul li {
margin: 0;
padding: 0;
width: 100%;
}
+11 -1
View File
@@ -44,5 +44,15 @@ export default {
studiensemester_kurzbz
}
};
}
},
getContainingOrNearestByDateRange(from, to) {
return {
method: 'get',
url: 'api/frontend/v1/organisation/studiensemester/getContainingOrNearestByDateRange',
params: {
from,
to,
}
};
},
};
+14 -1
View File
@@ -19,6 +19,7 @@ import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.j
import Studium from "../../components/Cis/Studium/Studium.js";
import StgOrgLvPlan from "../../components/Cis/LvPlan/StgOrg.js";
import OtherLvPlan from "../../components/Cis/LvPlan/OtherLvPlan.js";
import Compat from "../../components/Cis/Compat.js";
import ApiRouteInfo from '../../api/factory/routeinfo.js';
import {capitalize} from "../../helpers/StringHelpers.js";
@@ -29,6 +30,18 @@ const isMobile = window.matchMedia("(max-width: 767px)").matches;
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(`/${ciPath}`),
routes: [
{
path: `/Cis/Compat/:mode(ci|legacy)/:path(.*)`,
name: 'Compat',
component: Compat,
props: (route) => {
return {
mode: route.params.mode,
path: route.params.path,
query_string: VueRouter.stringifyQuery(route.query)
};
}
},
{
path: `/Cis/Studium`,
name: 'Studium',
@@ -277,7 +290,7 @@ const app = Vue.createApp({
if (target && this.isInternalRoute(target.href)) {
const url = new URL(target.href)
const path = url.pathname
const path = url.pathname + url.search;
const base = this.$router.options.history.base
const route = path.replace(base, '') || '/'
+2
View File
@@ -17,6 +17,8 @@ const router = VueRouter.createRouter({
component: LVVerwaltung,
children: [
{ name: 'emp', path: 'emp/:emp/:treemenu(.*)*', component: LVVerwaltung },
{ name: 'le', path: 'le/:le', component: LVVerwaltung },
{ name: 'lv', path: 'lv/:lv', component: LVVerwaltung },
{ name: 'treemenu', path: ':treemenu(.*)*', component: LVVerwaltung }
]
},
+7
View File
@@ -103,6 +103,13 @@ export default {
keyboard: this.keyboard
});
},
//to avoid pagelocks if more than one instance
beforeUnmount() {
if (this.modal) {
this.modal.dispose();
this.modal = null;
}
},
popup(body, options, title, footer) {
const BsModal = this,
slots = {};
+99
View File
@@ -0,0 +1,99 @@
export default {
name: "Compat",
props: {
mode: { type: String, required: true },
path: { type: String, required: true },
query_string: { type: String, required: true, default: ''}
},
data: function() {
return {
lastLoadediFrameURL: '',
srcUrl: ''
};
},
computed: {
propsWatchHelper: function() {
return this.mode + '#' + this.path + '#' + this.query_string;
}
},
beforeMount: function() {
document.body.classList.add('compat');
},
mounted: function() {
this.srcUrl = this.buildSrcUrl();
},
beforeUnmount: function() {
document.body.classList.remove('compat');
},
watch: {
propsWatchHelper: function() {
if(this.lastLoadediFrameURL === '') {
return;
}
let currentiFrameURL = this.$refs.compatiframe ? this.$refs.compatiframe.src : '';
let url = this.buildSrcUrl();
if(this.lastLoadediFrameURL !== url) {
this.srcUrl = url;
if(this.srcUrl === url) {
this.$refs.compatiframe.contentWindow.location.href = url;
}
}
}
},
methods: {
buildSrcUrl: function() {
let url = false;
switch(this.mode) {
case 'ci':
url = FHC_JS_DATA_STORAGE_OBJECT.app_root + 'index.ci.php/' + this.path;
break;
case 'legacy':
url = FHC_JS_DATA_STORAGE_OBJECT.app_root + this.path;
break;
default:
url = false;
}
if(this.query_string !== '' && url) {
url += '?' + this.query_string;
}
return url;
},
loadHandler: function() {
let iframe_href = this.$refs.compatiframe.contentWindow.location.href;
let ci_urlstart = FHC_JS_DATA_STORAGE_OBJECT.app_root + 'index.ci.php/';
let legacy_urlstart = FHC_JS_DATA_STORAGE_OBJECT.app_root;
let routerpath = null;
this.lastLoadediFrameURL = iframe_href;
if(iframe_href.startsWith(ci_urlstart)) {
routerpath = iframe_href.replace(
ci_urlstart, '/Cis/Compat/ci/');
} else if(iframe_href.startsWith(legacy_urlstart)) {
routerpath = iframe_href.replace(
legacy_urlstart, '/Cis/Compat/legacy/');
} else {
return;
}
if(this.$route.fullPath !== routerpath) {
this.$router.push(routerpath);
}
}
},
template: `
<div class="w-100">
<iframe
ref="compatiframe"
v-if="srcUrl"
:src="srcUrl"
@load="loadHandler"
style="width:100%; height:90vh; border:0; display:block;"
></iframe>
<div v-else class="alert alert-warning">Keine URL gefunden.</div>
</div>
`
};
+30 -19
View File
@@ -1,6 +1,7 @@
import FhcCalendar from "../../Calendar/LvPlan.js";
import ApiLvPlan from '../../../api/factory/lvPlan.js';
import ApiStudienSemester from '../../../api/factory/studiensemester.js';
import ApiAuthinfo from '../../../api/factory/authinfo.js';
export const DEFAULT_MODE_LVPLAN_DESKTOP = "Week";
@@ -16,13 +17,12 @@ export default {
},
data() {
return {
studiensemester_kurzbz: null,
studiensemester_start: null,
studiensemester_ende: null,
uid: null,
isMitarbeiter: false,
isStudent: false,
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
startSemester: null,
endSemester: null,
};
},
inject: ["isMobile"],
@@ -48,9 +48,12 @@ export default {
return this.propsViewData?.mode;
},
downloadLinks() {
if (!this.studiensemester_start || !this.studiensemester_ende || !this.uid)
return false;
const startDate = this.startSemester?.start;
const endDate = this.endSemester ? this.endSemester.ende : this.startSemester?.ende;
if (!startDate || !endDate || !this.uid)
return false;
let type = false;
type = this.isStudent ? 'student' : type;
type = this.isMitarbeiter ? 'lektor' : type;
@@ -61,10 +64,10 @@ export default {
const opts = { zone: this.timezone };
const start = luxon.DateTime
.fromISO(this.studiensemester_start, opts)
.fromISO(startDate, opts)
.toUnixInteger();
const ende = luxon.DateTime
.fromISO(this.studiensemester_ende, opts)
.fromISO(endDate, opts)
.toUnixInteger();
const download_link = FHC_JS_DATA_STORAGE_OBJECT.app_root
@@ -109,16 +112,21 @@ export default {
}
});
},
updateRange(rangeInterval) {
this.$api
.call(ApiLvPlan.studiensemesterDateInterval(
rangeInterval.end.startOf('week').toISODate()
))
.then(res => {
this.studiensemester_kurzbz = res.data.studiensemester_kurzbz;
this.studiensemester_start = res.data.start;
this.studiensemester_ende = res.data.ende;
});
async updateRange(rangeInterval) {
const semesterResponse = await this.$api.call(
ApiStudienSemester.getContainingOrNearestByDateRange(
rangeInterval.s.toISO().slice(0, 10),
rangeInterval.e.toISO().slice(0, 10),
),
);
this.startSemester =
semesterResponse.data.length
? semesterResponse.data[0]
: null;
this.endSemester =
semesterResponse.data.length > 1
? semesterResponse.data[1]
: null;
},
getPromiseFunc(start, end) {
return [
@@ -142,8 +150,11 @@ export default {
<div class="cis-lvplan-personal d-flex flex-column h-100">
<h2>
{{ $p.t('lehre/stundenplan') }}
<span v-if="studiensemester_kurzbz" class="ps-3">
{{ studiensemester_kurzbz }}
<span v-if="startSemester?.studiensemester_kurzbz">
{{ startSemester.studiensemester_kurzbz }}
<span v-if="endSemester?.studiensemester_kurzbz">
{{ "- " + endSemester.studiensemester_kurzbz }}
</span>
</span>
</h2>
<hr>
+33 -26
View File
@@ -5,6 +5,7 @@ import FhcCalendar from "../../Calendar/LvPlan.js";
import ApiLvPlan from "../.././../api/factory/lvPlan.js";
import ApiOtherLvPlan from "../.././../api/factory/otherLvPlan.js";
import ApiAuthinfo from "../../../api/factory/authinfo.js";
import ApiStudienSemester from '../../../api/factory/studiensemester.js';
export const DEFAULT_MODE_LVPLAN_DESKTOP = "Week";
export const DEFAULT_MODE_LVPLAN_MOBILE = "List";
@@ -22,9 +23,6 @@ export default {
data() {
return {
localProps: {},
studiensemester_kurzbz: null,
studiensemester_start: null,
studiensemester_ende: null,
isOtherPersonMitarbeiter: false,
isOtherPersonStudent: false,
currentStgBezeichnung: null,
@@ -36,6 +34,8 @@ export default {
photo: "",
},
timezone: FHC_JS_DATA_STORAGE_OBJECT.timezone,
startSemester: null,
endSemester: null,
};
},
inject: ["isMobile"],
@@ -67,11 +67,10 @@ export default {
// do not show download links in otherLvPlan Mode
return false;
if (
!this.studiensemester_start ||
!this.studiensemester_ende ||
!this.propsViewData.otherUid
)
const startDate = this.startSemester?.start;
const endDate = this.endSemester ? this.endSemester.ende : this.startSemester?.ende;
if (!startDate || !endDate || !this.uid)
return false;
const type = this.isOtherPersonStudent
@@ -84,11 +83,11 @@ export default {
const opts = { zone: this.timezone };
const start = luxon.DateTime.fromISO(
this.studiensemester_start,
startDate,
opts,
).toUnixInteger();
const ende = luxon.DateTime.fromISO(
this.studiensemester_ende,
endDate,
opts,
).toUnixInteger();
@@ -166,19 +165,21 @@ export default {
},
});
},
updateRange(rangeInterval) {
this.$api
.call(
ApiLvPlan.studiensemesterDateInterval(
rangeInterval.end.startOf("week").toISODate(),
),
)
.then((res) => {
this.studiensemester_kurzbz =
res.data.studiensemester_kurzbz;
this.studiensemester_start = res.data.start;
this.studiensemester_ende = res.data.ende;
});
async updateRange(rangeInterval) {
const semesterResponse = await this.$api.call(
ApiStudienSemester.getContainingOrNearestByDateRange(
rangeInterval.s.toISO().slice(0, 10),
rangeInterval.e.toISO().slice(0, 10),
),
);
this.startSemester =
semesterResponse.data.length
? semesterResponse.data[0]
: null;
this.endSemester =
semesterResponse.data.length > 1
? semesterResponse.data[1]
: null;
},
getPromiseFunc(start, end) {
return [
@@ -212,7 +213,7 @@ export default {
this.isOtherPersonStudent = !!viewData?.user_data?.is_student;
let fullNameWithTitleFragments = [
viewData?.user_data?.titel,
viewData?.user_data?.vorname,
viewData?.user_data?.wahlname ?? viewData?.user_data?.vorname,
viewData?.user_data?.nachname,
viewData?.user_data?.postnomen,
];
@@ -250,8 +251,14 @@ export default {
<div class="d-flex flex-column h-100">
<h2>
<div class="d-flex flex-row justify-content-between align-items-center">
<span>
{{ $p.t('lehre/stundenplan') + (studiensemester_kurzbz ? " " + studiensemester_kurzbz : "") }}
<span>
{{ $p.t('lehre/stundenplan') }}
<span v-if="startSemester?.studiensemester_kurzbz">
{{ startSemester.studiensemester_kurzbz }}
<span v-if="endSemester?.studiensemester_kurzbz">
{{ "- " + endSemester.studiensemester_kurzbz }}
</span>
</span>
</span>
<div @click="this.$router.push({name: 'ProfilView', params: {uid: propsViewData.otherUid}})" type="button" class="d-flex flex-row align-items-center gap-3">
<span v-if="otherPersonData.fullNameWithTitle?.length">
+1 -1
View File
@@ -186,7 +186,7 @@ export default {
</div>
</div>
<nav id="nav-main" class="offcanvas offcanvas-start" tabindex="-1" aria-labelledby="nav-main-btn" data-bs-backdrop="false">
<nav id="nav-main" class="cis-main-menu offcanvas offcanvas-start" tabindex="-1" aria-labelledby="nav-main-btn" data-bs-backdrop="false">
<div id="nav-main-sticky">
<div class="d-flex flex-row h-100">
<div class="offcanvas-body p-0">
+5 -1
View File
@@ -162,6 +162,7 @@ export default {
<div class="btn-group w-100">
<a :target="target"
:href="(entry.menu_open && hasFullLink) ? entry.url : null"
draggable="false"
@click="toggleCollapse"
:class="{
'btn btn-default rounded-0 text-start': true,
@@ -180,12 +181,15 @@ export default {
</div>
<ul ref="children"
class="nav w-100 collapse">
<cis-menu-entry :highestMatchingUrlCount="highestMatchingUrlCount" :activeContent="activeContent" v-for="child in entry.childs" :key="child" :entry="child" :level="level + 1"/>
<li>
<cis-menu-entry :highestMatchingUrlCount="highestMatchingUrlCount" :activeContent="activeContent" v-for="child in entry.childs" :key="child" :entry="child" :level="level + 1"/>
</li>
</ul>
</template>
<a v-else
:href="entry.url"
:target="target"
draggable="false"
:class="{
'btn btn-default rounded-0 w-100 text-start': true,
['btn-level-' + level]: true,
@@ -73,7 +73,7 @@ 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)
.then(data => data.data)
.then(data => data.data?.retval)
.then(res => {
if (Array.isArray(res) && res.length > 0) {
this.hasLvPlanEintraege = true;
@@ -114,4 +114,4 @@ export default {
`,
};
};
@@ -274,7 +274,7 @@ export default {
}
return {
Vorname: this.data.vorname,
Vorname: this.data.wahlname ?? this.data.vorname,
Nachname: this.data.nachname,
Username: this.data.username,
Anrede: this.data.anrede,
@@ -160,7 +160,7 @@ export default {
}
return {
Vorname: this.data.vorname,
Vorname: this.data.wahlname ?? this.data.vorname,
Nachname: this.data.nachname,
Username: this.data.username,
Anrede: this.data.anrede,
@@ -2,15 +2,16 @@ export default {
props: {
data: {
type: String,
}
},
},
data() {
return {}
return {};
},
template: /*html*/`
template: /*html*/ `
<div class="card">
<div class="card-body">
<span >{{$p.t('profil','fhAusweisStatus',[data])}}</span>
<span v-if="data">{{$p.t('profil','fhAusweisStatus',[data])}}</span>
<span v-else>{{$p.t('profil','fhAusweisStatusNichtAusgegeben')}}</span>
</div>
</div>`,
}
};
@@ -204,7 +204,7 @@ export default {
}
return {
Vorname: this.data.vorname,
Vorname: this.data.wahlname ?? this.data.vorname,
Nachname: this.data.nachname,
Username: this.data.username,
Anrede: this.data.anrede,
@@ -33,7 +33,7 @@ export default {
}
return {
Vorname: this.data.vorname,
Vorname: this.data.wahlname ?? this.data.vorname,
Nachname: this.data.nachname,
Username: this.data.username,
Anrede: this.data.anrede,
@@ -1,5 +1,6 @@
export default {
name: 'Cis-Renderer-Feiertag-CalendarEvent',
props: {
event: {
type: Object,
@@ -1,6 +1,7 @@
import { formatDate } from "../../../../helpers/DateHelpers.js"
export default {
name: 'Cis-Renderer-Feiertag-ModalContent',
props:{
event: {
type: Object,
@@ -1,4 +1,5 @@
export default {
name: 'Cis-Renderer-Feiertag-ModalTitle',
props:{
event: {
type: Object,
@@ -1,4 +1,5 @@
export default {
name: 'Cis-Renderer-Lehreinheit-CalendarEvent',
props:{
event: {
type: Object,
@@ -5,6 +5,7 @@ import ApiLvPlan from '../../../../api/factory/lvPlan.js';
import ApiAddons from '../../../../api/factory/addons.js';
export default {
name: 'Cis-Renderer-Lehreinheit-ModalContent',
components:{
LvMenu,
},
@@ -49,6 +50,16 @@ export default {
return this.event.ende;
}
return numberPadding(this.event.ende.getHours()) + ":" + numberPadding(this.event.ende.getMinutes());
},
showLvMenu: function() {
const hideOnRoutes = [
'OtherLvPlan',
'StgOrgLvPlan'
];
if(hideOnRoutes.includes(this.$route.name)) {
return false;
}
return true;
}
},
watch: {
@@ -162,6 +173,6 @@ export default {
</tr>
</tbody>
</table>
<lv-menu v-if="lvMenu.length && $route.name === 'MyLvPlan'" :containerStyles="['p-0']" :rowStyles="['m-0']" :menu="lvMenu" />
<lv-menu v-if="lvMenu.length && showLvMenu" :containerStyles="['p-0']" :rowStyles="['m-0']" :menu="lvMenu" />
</div>`,
}
@@ -1,4 +1,5 @@
export default {
name: 'Cis-Renderer-Lehreinheit-ModalTitle',
props:{
event: {
type: Object,
@@ -1,4 +1,5 @@
export default {
name: 'Cis-Renderer-Reservierung-CalendarEvent',
props: {
event: {
type: Object,
@@ -2,6 +2,7 @@ import { numberPadding, formatDate } from "../../../../helpers/DateHelpers.js"
import LvMenu from "../../Mylv/LvMenu.js";
export default {
name: 'Cis-Renderer-Reservierung-ModalContent',
props:{
event: {
type: Object,
@@ -1,4 +1,5 @@
export default {
name: 'Cis-Renderer-Reservierung-ModalTitle',
props:{
event: {
type: Object,
+1 -1
View File
@@ -184,7 +184,7 @@ export default {
let viewDataResult = await this.$api.call(ApiDashboard.getViewData());
const viewData = viewDataResult.data;
this.timezone = viewData?.timezone;
this.userFirstName = viewData?.name;
this.userFirstName = viewData?.wahlname ?? viewData?.name;
}
},
async created() {
+13 -2
View File
@@ -1,5 +1,6 @@
import BsModal from "../Bootstrap/Modal.js";
import HeightTransition from "../Tranistion/HeightTransition.js";
import MissingPermissionWidget from "../DashboardWidget/MissingPermission.js";
import { enableDragDropTouch } from "../../../../vendor/drag-drop-touch-js/dragdroptouch/dist/drag-drop-touch.esm.min.js";
@@ -112,6 +113,12 @@ export default {
isPinned() {
return this.place?.pinned ? true : false;
},
permitted() {
// widgets without a linked permission (or before the template loaded)
// are considered permitted; the backend sets permitted === false only
// when the user is missing the widget's required permission
return this.widgetTemplate?.permitted !== false;
},
ready() {
return this.component && this.arguments !== null;
}
@@ -169,7 +176,11 @@ export default {
&& this.widgetTemplate.widget_id
&& this.widgetTemplate.arguments
) {
let component = (await import(this.widgetTemplate.setup.file)).default;
// render the "missing permission" screen instead of the actual
// widget when the user does not hold the widget's linked permission
let component = this.permitted
? (await import(this.widgetTemplate.setup.file)).default
: MissingPermissionWidget;
this.$options.components["widget" + this.widgetTemplate.widget_id] = component;
this.component = "widget" + this.widgetTemplate.widget_id;
this.arguments = { ...this.widgetTemplate.arguments, ...this.config };
@@ -269,7 +280,7 @@ export default {
</template>
<!-- widget link -->
<a
v-if="widgetTemplate.setup.cis4link"
v-if="widgetTemplate.setup.cis4link && permitted"
:href="getWidgetC4Link(widgetTemplate)"
class="col-auto ms-auto"
:aria-label="$p.t('dashboard/widget_link')"
@@ -14,10 +14,14 @@ export default {
callbacks: {}
}),
computed: {
// filter widgets away the user has no permissions for
availableWidgets() {
return (this.widgets || []).filter(widget => widget.permitted !== false);
},
hasAnyWidgets() {
if (!this.widgets)
return false;
if (!this.widgets.length && !this.hiddenWidgets?.length)
if (!this.availableWidgets.length && !this.hiddenWidgets?.length)
return false;
return true;
}
@@ -54,7 +58,7 @@ export default {
<template v-slot:default>
<template v-if="widgets && hiddenWidgets">
<div
v-if="!widgets.length && !hiddenWidgets.length"
v-if="!availableWidgets.length && !hiddenWidgets.length"
class="row g-2"
>
<div>{{ $p.t('dashboard/noWidgetsAvailable') }}</div>
@@ -74,16 +78,17 @@ export default {
</div>
</div>
<div
v-if="widgets.length"
v-if="availableWidgets.length"
class="row g-2"
>
<div
v-for="widget in widgets"
<template
v-for="widget in availableWidgets"
:key="widget.widget_id"
class="widget-icon-container col-sm-6 col-md-4 col-lg-3 col-xl-2"
>
<widget-icon @select="pick" :widget="widget"></widget-icon>
</div>
<div v-if="widget.permitted" class="widget-icon-container col-sm-6 col-md-4 col-lg-3 col-xl-2">
<widget-icon @select="pick" :widget="widget"></widget-icon>
</div>
</template>
</div>
</template>
</template>
@@ -0,0 +1,21 @@
import AbstractWidget from './Abstract.js';
/**
* Fallback screen rendered in place of a widget when the current user is missing
* the permission (berechtigung_kurzbz) linked to that widget. Used for widgets
* that are already on a user's dashboard but whose required permission the user
* no longer holds.
*/
export default {
mixins: [
AbstractWidget
],
created() {
this.$emit('setConfig', false);
},
template: /*html*/`
<div class="dashboard-widget-missing-permission d-flex flex-column justify-content-center align-items-center text-center h-100 p-3 text-body-secondary">
<i class="fa-solid fa-lock fa-2x mb-2" aria-hidden="true"></i>
<p class="mb-0">{{ $p.t('dashboard/widget_missing_permission') }}</p>
</div>`
}
@@ -542,10 +542,10 @@ export default {
<template v-if="typeHeader==='mitarbeiter'">
<div class="foto-container col-md-2 d-flex justify-content-start align-items-center w-30 pb-3 gap-3 mt-3 position-relative" style="max-height: 8rem; max-width: 6rem; overflow: hidden;">
<div class="foto-container d-flex flex-column align-items-center h-100 position-relative d-inline-block">
<img
class="d-block w-100 h-100 rounded"
style="height: 84px; object-fit: contain;"
class="d-block rounded"
style="height: 96px;"
alt="Profilbild"
:src="getFotoSrc(headerDataMa.foto)"
/>
@@ -558,15 +558,13 @@ export default {
<template v-if="fotoEditable">
<button
type="button"
class="fotoedit btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute start-0"
style="z-index: 104; font-size: 1rem; width: 2.5rem; height: 2.5rem; opacity:0; transition: opacity 0.2s; top:13%;"
class="fotoedit buttonleft btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute start-0"
@click="showDeleteModal(person_id)">
<i class="fa fa-xmark"></i>
</button>
<button
type="button"
class="fotoedit btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute end-0"
style="z-index: 104; font-size: 1rem; width: 2.5rem; height: 2.5rem; opacity:0; transition: opacity 0.2s; top:13%;"
class="fotoedit buttonright btn btn-outline-dark btn-sm d-flex justify-content-center align-items-center position-absolute end-0"
@click="showModal(person_id)">
<i class="fa fa-pen"></i>
</button>
@@ -61,6 +61,7 @@ export default {
selected: [],
studiengang_kz: null,
selectedStudiensemester: this.defaultSemester,
preselected: null,
dropdowns: {
studiensemester_array: [],
sprachen_array: [],
@@ -73,7 +74,11 @@ export default {
calcheightonly: true,
types: [
"mitarbeiter",
"mitarbeiter_ohne_zuordnung"
"mitarbeiter_ohne_zuordnung",
/*
"lehreinheit",
"lehrveranstaltung",
*/
],
actions: {
employee: {
@@ -86,6 +91,26 @@ export default {
childactions: [
]
},
lehreinheit: {
defaultaction: {
type: "function",
action: (data) => {
this.onSelectLehreinheit(data);
}
},
childactions: [
]
},
lehrveranstaltung: {
defaultaction: {
type: "function",
action: (data) => {
this.onSelectLehrveranstaltung(data);
}
},
childactions: [
]
}
}
},
}
@@ -94,6 +119,8 @@ export default {
filter() {
let filter = {
emp: this.$route.params.emp,
le: this.$route.params.le,
lv: this.$route.params.lv,
studiensemester_kurzbz: this.selectedStudiensemester
};
let index;
@@ -105,7 +132,7 @@ export default {
if (index > -1)
filter.semester = this.$route.params.treemenu[index+1];
}
filter.activeFilter = filter.emp ? 'employee' : filter.stg ? 'verband' : null;
filter.activeFilter = filter.emp ? 'employee' : filter.stg ? 'verband' : filter.le ? 'lehreinheit' : filter.lv ? 'lehrveranstaltung' : null;
return filter;
},
emp() {
@@ -203,20 +230,50 @@ export default {
},
onSelectEmployee(emp)
{
let params = { ...this.$route.params }
delete params.le;
delete params.lv;
this.$router.push({
name: 'emp',
params: {
...this.$route.params,
...params,
emp
}
});
},
onSelectLehreinheit(lehreinheit)
{
this.$router.push({
name: 'le',
params: {
le: lehreinheit.id,
stdsem: lehreinheit.studiensemester_kurzbz.toLowerCase()
}
});
},
onSelectLehrveranstaltung(lehrveranstaltung)
{
this.$router.push({
name: 'lv',
params: {
lv: lehrveranstaltung.id,
stdsem: lehrveranstaltung?.studiensemester_kurzbz?.toLowerCase() ?? this.selectedStudiensemester.toLowerCase()
}
});
},
onSelectVerband({ path: link, stg_kz })
{
let params = { ...this.$route.params }
delete params.le;
delete params.lv;
this.$router.push({
name: this.$route.name == 'emp' ? 'emp' : 'treemenu',
params: {
...this.$route.params,
...params,
treemenu: link.split('/')
}
});
@@ -295,7 +352,7 @@ export default {
}
},
created() {
if (!this.$route.params.stdsem) {
if (this.$route.name !== 'le' && this.$route.name !== 'lv' && !this.$route.params.stdsem) {
this.$router.replace({
name: 'stdsem',
params: {
@@ -477,7 +534,8 @@ export default {
<template #top>
<lv-table ref="lvTable"
v-model:selected="selected"
@row-clicked="handleRowClicked"
@row-clicked="handleRowClicked"
@select-LV="onSelectLehrveranstaltung"
:filter="filter"
>
<template #filterzuruecksetzen v-if="filter.activeFilter === 'employee'">
@@ -57,7 +57,8 @@ export default {
},
emits: [
'update:selected',
'row-clicked'
'row-clicked',
'selectLV',
],
watch: {
filter: {
@@ -106,8 +107,24 @@ export default {
{
event: 'dataProcessed',
handler: (data) => {
this.reexpandRows()
this.$emit('update:selected', {})
if (this.$route.params.le)
{
this.$refs.table.tabulator.selectRow(this.$refs.table.tabulator.getRows());
}
else if (this.$route.params.lv)
{
this.$refs.table.tabulator.selectRow(this.$refs.table.tabulator.getRows());
this.allRows = this.getAllRows(this.$refs.table.tabulator.getRows());
this.allRows.forEach(row => {
row.treeExpand()
});
}
else
{
this.reexpandRows()
this.$emit('update:selected', {})
}
}
},
{
@@ -221,35 +238,35 @@ export default {
selectableRows: true,
rowContextMenu: (component, e) => {
if (e.getData()?.lehreinheit_id === undefined)
return;
if (e.getData()?.lehreinheit_id === undefined || !e.getData()?.lehreinheit_id)
return [];
return [
{
label: "LV-Teil kopieren",
label: this.$p.t('lehre', 'lvteilkopieren'),
menu: [
{
label: "Alles",
label: this.$p.t('lehre', 'alles'),
action: (e, row) =>
{
this.copyLehreinheit(row, "alle");
},
},
{
label: "Nur LV-Teil",
label: this.$p.t('lehre', 'nurlvteil'),
action: (e, row) =>
{
this.copyLehreinheit(row, "lvteil");
},
},
{
label: "Nur mit Gruppen",
label: this.$p.t('lehre', 'nurmitgruppen'),
action: (e, row) =>
{
this.copyLehreinheit(row, "gruppen");
},
},
{
label: "Nur mit Lehrenden",
label: this.$p.t('lehre', 'nurmitlehrende'),
action: (e, row) =>
{
this.copyLehreinheit(row, "lektoren");
@@ -258,7 +275,21 @@ export default {
],
},
{
label: "Entfernen",
label: this.$p.t('lehre', 'zurlvspringen'),
action: (e, row) => {
this.openLV(row)
},
},
{
label: this.$p.t('lehre', 'lvteillinkkopieren'),
action: (e, row) => {
let rowData = row.getData();
let link = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/LVVerwaltung/stdsem/' + rowData.studiensemester_kurzbz.toLowerCase() + '/le/' + rowData.lehreinheit_id;
navigator.clipboard.writeText(link);
},
},
{
label: this.$p.t('ui', 'entfernen'),
action: (e, row) => {
this.deleteLehreinheit(row)
},
@@ -355,7 +386,7 @@ export default {
},
buildApiUrl()
{
if (!['emp', 'treemenu'].includes(this.$route.name))
if (!['emp', 'treemenu', 'le', 'lv'].includes(this.$route.name))
return null;
let url = 'stdsem/' + this.$route.params.stdsem;
@@ -364,6 +395,14 @@ export default {
url += '/emp/' + this.$route.params.emp;
}
if (this.$route.params.le) {
url += '/le/' + this.$route.params.le;
}
if (this.$route.params.lv) {
url += '/lv/' + this.$route.params.lv;
}
if (this.$route.params.treemenu) {
url += '/' + this.$route.params.treemenu.join('/');
}
@@ -502,6 +541,17 @@ export default {
})
.catch(this.$fhcAlert.handleSystemError);
},
openLV(row)
{
let rowData = row.getData();
let data = {
id: rowData.lehrveranstaltung_id,
studiensemester_kurzbz: rowData.studiensemester_kurzbz
}
this.$emit('selectLV', data);
},
getAllRows(rows)
{
let result = [];
@@ -263,7 +263,7 @@ export default {
this.$refs[modalRef].hide();
},
reload() {
this.$refs.table.reloadTable();
this.$refs.table?.reloadTable();
},
searchFirma(event) {
if (this.abortController.firmen) {
@@ -30,6 +30,9 @@ export default {
computed: {
betreuerFormOpened() {
return this.newMode || this.editMode;
},
isMitarbeiter(){
return this.autocompleteSelectedBetreuer?.name?.includes('Mitarbeiter') ?? false;
}
},
props: {
@@ -430,6 +433,11 @@ export default {
},
actionKontaktdatenBearbeiten() {
if (!this.autocompleteSelectedBetreuer) return;
if (this.isMitarbeiter)
{
this.$fhcAlert.alertError(this.$p.t('ui', 'editingMitarbeiterPVonly'));
return;
}
this.$refs.kontaktdatenModal.show();
},
// stuff to do after new person has been saved
@@ -494,7 +502,12 @@ export default {
<button class="btn btn-outline-secondary" @click="actionNewPerson">{{ $p.t('projektarbeit', 'neuePersonAnlegen') }}</button>
</div>
<div class="col-6">
<button class="btn btn-outline-secondary float-end" @click="actionKontaktdatenBearbeiten">{{ $p.t('projektarbeit', 'kontaktdatenBearbeiten') }}</button>
<button
class="btn btn-outline-secondary float-end"
@click="actionKontaktdatenBearbeiten"
>
{{ $p.t('projektarbeit', 'kontaktdatenBearbeiten') }}
</button>
</div>
</div>
@@ -605,7 +618,7 @@ export default {
</contact>
</div>
</div>
</bs-modal>
`
}
@@ -0,0 +1,62 @@
import TemplateFrame from "./template/frame.js";
export default {
name: 'SearchbarResultTeachingUnit',
components: {
TemplateFrame
},
emits: [ 'actionexecuted' ],
props: {
res: Object,
actions: Object
},
template: `
<template-frame
class="searchbar-result-teachingunit"
:res="res"
:actions="actions"
:title="res.bezeichnung"
:image-fallback="res.foto"
@actionexecuted="$emit('actionexecuted')"
>
<div class="searchbar_table">
<div class="searchbar_tablerow">
<div class="searchbar_tablecell searchbar_label"> {{ res.type === 'lehreinheit' ? $p.t('lehre/lehreinheit') : $p.t('lehre/lehrveranstaltung') }}</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.id }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell searchbar_label">{{ $p.t('lehre/studiengang') }}</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.studiengang }}
</div>
</div>
<div class="searchbar_tablerow" v-if="res.oe_bezeichnung">
<div class="searchbar_tablecell searchbar_label">{{ $p.t('lehre/organisationseinheit') }}</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.oe_bezeichnung }}
</div>
</div>
<div class="searchbar_tablerow" v-if="res.studiensemester_kurzbz">
<div class="searchbar_tablecell searchbar_label">{{ $p.t('lehre/studiensemester') }}</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.studiensemester_kurzbz }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell searchbar_label">{{ $p.t('lehre/ausbildungssemester') }}</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.semester }}
</div>
</div>
<div class="searchbar_tablerow">
<div class="searchbar_tablecell searchbar_label">{{ $p.t('lehre/lehrform') }}</div>
<div class="searchbar_tablecell searchbar_value">
{{ res.lehrform_kurzbz }}
</div>
</div>
</div>
</template-frame>`
};
@@ -8,6 +8,7 @@ import dms from "./result/dms.js";
import cms from "./result/cms.js";
import mergedStudent from "./result/mergedstudent.js";
import mergedPerson from "./result/mergedperson.js";
import teachingunit from "./result/teachingunit.js";
import { debounce } from "../../helpers/DebounceHelper.js";
export default {
@@ -23,6 +24,7 @@ export default {
cms,
mergedStudent,
mergedPerson,
teachingunit,
},
props: {
searchoptions: {
+4 -1
View File
@@ -102,6 +102,8 @@ require_once('dbupdate_3.4/75959_StudVw_Automatische_Tags.php');
require_once('dbupdate_3.4/76160_lvv_favorites.php');
require_once('dbupdate_3.4/77080_tabulator_presets_table.php');
require_once('dbupdate_3.4/78292_gehaltsanpassungtyp.php');
require_once('dbupdate_3.4/54225_reihungstest_ablauf_fuer_quereinsteiger.php');
require_once('dbupdate_3.4/77757_widgets_berechtigungen.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
@@ -253,7 +255,7 @@ $tabellen=array(
"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"),
"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"),
@@ -421,6 +423,7 @@ $tabellen=array(
"testtool.tbl_pruefling_frage" => array("prueflingfrage_id","pruefling_id","frage_id","nummer","begintime","endtime"),
"testtool.tbl_frage_sprache" => array("frage_id","sprache","text","bild","audio","insertamum","insertvon","updateamum","updatevon"),
"testtool.tbl_vorschlag_sprache" => array("vorschlag_id","sprache","text","bild","audio","insertamum","insertvon","updateamum","updatevon"),
"testtool.tbl_pruefling_gebiet" => array("prueflinggebiet_id","pruefling_id","gebiet_id","insertamum"),
"system.tbl_app" => array("app"),
"system.tbl_appdaten" => array("appdaten_id","uid","app","appversion","version","bezeichnung","daten","freigabe","insertamum","insertvon","updateamum","updatevon"),
"system.tbl_cronjob" => array("cronjob_id","server_kurzbz","titel","beschreibung","file","last_execute","aktiv","running","jahr","monat","tag","wochentag","stunde","minute","standalone","reihenfolge","updateamum", "updatevon","insertamum","insertvon","variablen"),
@@ -0,0 +1,41 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
// Creates table public.tbl_notiz_typ if it doesn't exist and grants privileges
if (!$result = @$db->db_query('SELECT 1 FROM testtool.tbl_pruefling_gebiet LIMIT 1'))
{
$qry = 'CREATE TABLE testtool.tbl_pruefling_gebiet
(
prueflinggebiet_id integer NOT NULL,
pruefling_id integer NOT NULL,
gebiet_id integer NOT NULL,
insertamum timestamp DEFAULT now()
);
ALTER TABLE testtool.tbl_pruefling_gebiet OWNER TO fhcomplete;
ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT pk_tbl_pruefling_gebiet PRIMARY KEY (prueflinggebiet_id);
ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT fk_tbl_pruefling_gebiet_pruefling_id FOREIGN KEY (pruefling_id) REFERENCES testtool.tbl_pruefling(pruefling_id) ON UPDATE CASCADE ON DELETE RESTRICT;
ALTER TABLE testtool.tbl_pruefling_gebiet ADD CONSTRAINT fk_tbl_pruefling_gebiet_gebiet_id FOREIGN KEY (gebiet_id) REFERENCES testtool.tbl_gebiet(gebiet_id) ON UPDATE CASCADE ON DELETE RESTRICT;
CREATE SEQUENCE testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq OWNER TO fhcomplete;
ALTER TABLE testtool.tbl_pruefling_gebiet ALTER COLUMN prueflinggebiet_id SET DEFAULT nextval(\'testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq\');
GRANT SELECT, UPDATE, INSERT, DELETE ON testtool.tbl_pruefling_gebiet TO web;
GRANT SELECT, UPDATE, INSERT, DELETE ON testtool.tbl_pruefling_gebiet TO vilesci;
GRANT SELECT, UPDATE ON testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq TO vilesci;
GRANT SELECT, UPDATE ON testtool.tbl_pruefling_gebiet_prueflinggebiet_id_seq TO web;
';
if (!$db->db_query($qry))
echo '<strong>public.tbl_pruefling_gebiet: '.$db->db_last_error().'</strong><br>';
else
echo '<br>public.tbl_pruefling_gebiet table created';
}
@@ -0,0 +1,57 @@
<?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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Beschreibung:
* Dashboard Widgets: Verknüpfung einer (einzelnen) Berechtigung pro Widget.
* Neue Spalte dashboard.tbl_widget.berechtigung_kurzbz mit FK auf
* system.tbl_berechtigung. Ist die Spalte NULL, erfordert das Widget keine
* gesonderte Berechtigung. Benutzer denen die verknüpfte Berechtigung fehlt,
* bekommen das Widget nicht mehr zur Auswahl angezeigt bzw. sehen (falls bereits
* am Dashboard) einen "Fehlende Berechtigung"-Screen.
*/
if (! defined('DB_NAME')) exit('No direct script access allowed');
// Add column dashboard.tbl_widget.berechtigung_kurzbz (FK => system.tbl_berechtigung)
if ($result = @$db->db_query("
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'dashboard'
AND table_name = 'tbl_widget'
AND column_name = 'berechtigung_kurzbz';"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "
ALTER TABLE dashboard.tbl_widget
ADD COLUMN berechtigung_kurzbz VARCHAR(32) NULL;
ALTER TABLE dashboard.tbl_widget
ADD CONSTRAINT tbl_widget_berechtigung_fk
FOREIGN KEY (berechtigung_kurzbz)
REFERENCES system.tbl_berechtigung (berechtigung_kurzbz)
ON UPDATE CASCADE ON DELETE SET NULL;";
if (!$db->db_query($qry))
{
echo '<strong>dashboard.tbl_widget: '.$db->db_last_error().'</strong><br>';
}
else
{
echo 'dashboard.tbl_widget: Spalte berechtigung_kurzbz (FK system.tbl_berechtigung) hinzugefuegt<br>';
}
}
}
+283 -3
View File
@@ -19829,6 +19829,26 @@ array(
)
)
),
array(
'app' => 'international',
'category' => 'international',
'phrase' => 'massnahmeneinmalig',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Diese Maßnahme ist nur einmalig planbar.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'This measure may only be planned once.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'international',
'category' => 'international',
@@ -20609,6 +20629,26 @@ array(
)
)
),
array(
'app' => 'international',
'category' => 'international',
'phrase' => 'personenMassnahmen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'alle Maßnahmen der Personen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => ' all measures of the people',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'international',
'category' => 'international',
@@ -20689,6 +20729,46 @@ array(
)
)
),
array(
'app' => 'international',
'category' => 'international',
'phrase' => 'einmalig',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Nur einmal planbar',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'One-time only',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'international',
'category' => 'international',
'phrase' => 'erroreinmalig',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Diese Maßnahme kann nur einmal geplant werden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'This measure can only be planned once.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'gruppenmanagement',
@@ -29363,6 +29443,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'profil',
'phrase' => 'fhAusweisStatusNichtAusgegeben',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Der FH Ausweis wurde noch nicht ausgegeben.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The FH ID card has not been issued yet.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'profil',
@@ -49520,6 +49620,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'dashboard',
'phrase' => 'widget_missing_permission',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ihnen fehlt die erforderliche Berechtigung, um dieses Widget anzuzeigen.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'You do not have the permission required to display this widget.',
'description' => '',
'insertvon' => 'system'
)
)
),
// CIS4 phrases from legacy code end
// FHC4 Phrases Abschlusspruefung
array(
@@ -50354,7 +50474,7 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Wahlname',
'text' => 'Wahlvorname',
'description' => '',
'insertvon' => 'system'
),
@@ -53252,6 +53372,146 @@ and represent the current state of research on the topic. The prescribed citatio
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lvteilkopieren',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'LV-Teil kopieren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Copy teaching unit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'nurlvteil',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Nur LV-Teil',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Teaching unit only',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'nurmitgruppen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Nur mit Gruppen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'With groups only',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'nurmitlehrende',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Nur mit Lehrenden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'With lecturers only',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'zurlvspringen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zur LV Springen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Go to teaching unit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'lvteillinkkopieren',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Link zu diesem LV-Teil kopieren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Copy link to this teaching unit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
'phrase' => 'alles',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alles',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Everything',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'lehre',
@@ -61217,7 +61477,7 @@ I have been informed that I am under no obligation to consent to the transmissio
'insertvon' => 'system'
)
)
),
),
array(
'app' => 'core',
'category' => 'tabulator',
@@ -62491,8 +62751,28 @@ I have been informed that I am under no obligation to consent to the transmissio
'insertvon' => 'system'
)
)
)
),
// ### Infocenter Onboarding END
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'editingMitarbeiterPVonly',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kontaktdaten von Mitarbeiter*innen dürfen nur in der Personalverwaltung editiert werden.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Employee contact details may only be edited in the personnel administration system.',
'description' => '',
'insertvon' => 'system'
)
)
)
);
@@ -1,9 +1,9 @@
INSERT INTO lehre.tbl_projektarbeit
(projektarbeit_id, projekttyp_kurzbz, titel, lehreinheit_id, student_uid, firma_id, note, punkte, beginn, ende, faktor, freigegeben, gesperrtbis, stundensatz, themenbereich, anmerkung, updateamum, updatevon, insertamum, insertvon, ext_id, gesamtstunden, titel_english, sprache, seitenanzahl, abgabedatum, kontrollschlagwoerter, schlagwoerter, schlagwoerter_en, abstract, abstract_en, "final") VALUES
(1, 'Bachelor', 'Auswirkung der Sonneneinstrahlung auf die Gesundheit', 46111, 's46b413', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true),
(2, 'Bachelor', 'Neue Unterrichtsmethoden mit KI', 46111, 's46b414', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true),
(3, 'Bachelor', 'Betrugsbekämpfung bei Anwesenheitskontrolle', 46111, 's46b415', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true),
(4, 'Bachelor', 'Neuronale Netze', 46111, 's46b416', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true)
(projektarbeit_id, projekttyp_kurzbz, titel, lehreinheit_id, student_uid, firma_id, note, punkte, beginn, ende, faktor, freigegeben, gesperrtbis, stundensatz, themenbereich, anmerkung, updateamum, updatevon, insertamum, insertvon, ext_id, gesamtstunden, titel_english, sprache, seitenanzahl, abgabedatum, kontrollschlagwoerter, schlagwoerter, schlagwoerter_en, abstract, abstract_en, "final", lehrveranstaltung_id, studiensemester_kurzbz) VALUES
(1, 'Bachelor', 'Auswirkung der Sonneneinstrahlung auf die Gesundheit', 46111, 's46b413', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true, 4611, NearestWintersemester(1)),
(2, 'Bachelor', 'Neue Unterrichtsmethoden mit KI', 46111, 's46b414', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true, 4611, NearestWintersemester(1)),
(3, 'Bachelor', 'Betrugsbekämpfung bei Anwesenheitskontrolle', 46111, 's46b415', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true, 4611, NearestWintersemester(1)),
(4, 'Bachelor', 'Neuronale Netze', 46111, 's46b416', NULL, NULL, NULL, NULL, NULL, NULL, true, NULL, NULL, NULL, NULL, NULL, NULL, '2025-12-12 14:06:10.000', 'anondata', NULL, 3.0000, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, true, 4611, NearestWintersemester(1))
;
INSERT INTO lehre.tbl_projektbetreuer
+55 -2
View File
@@ -251,6 +251,31 @@ if ($deleteSingleResult)
exit();
}
$qry = "SELECT * FROM testtool.tbl_pruefling_gebiet
WHERE pruefling_id=" . $db->db_add_param($pruefling->pruefling_id) . " AND gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . "";
if ($db->db_query($qry))
{
while ($row = $db->db_fetch_object())
{
$undo .= " INSERT INTO testtool.tbl_pruefling_gebiet(prueflinggebiet_id,pruefling_id,gebiet_id, insertamum) VALUES (" .
$db->db_add_param($row->prueflinggebiet_id, FHC_INTEGER) . ', ' .
$db->db_add_param($row->pruefling_id, FHC_INTEGER) . ', ' .
$db->db_add_param($row->gebiet_id, FHC_INTEGER) . ', ' .
$db->db_add_param($row->insertamum) . ');';
}
}
else
{
$db->db_query('ROLLBACK');
echo json_encode(array(
'status' => 'fehler',
'msg' => 'Fehler beim Erstellen des UNDO Befehls fuer testtool.tbl_pruefling_gebiet'
));
exit();
}
//Antworten loeschen
$qry = "DELETE FROM testtool.tbl_pruefling_frage where pruefling_id=" . $db->db_add_param($pruefling->pruefling_id, FHC_INTEGER) . " AND
frage_id IN (SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . ");
@@ -258,7 +283,9 @@ if ($deleteSingleResult)
DELETE FROM testtool.tbl_antwort
WHERE pruefling_id=" . $db->db_add_param($pruefling->pruefling_id) . " AND
vorschlag_id IN (SELECT vorschlag_id FROM testtool.tbl_vorschlag WHERE frage_id IN
(SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . "));";
(SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . "));
DELETE FROM testtool.tbl_pruefling_gebiet where pruefling_id=" . $db->db_add_param($pruefling->pruefling_id, FHC_INTEGER) . " AND gebiet_id=" . $db->db_add_param($_POST['gebiet_id']) . ";";
if ($result = $db->db_query($qry))
{
@@ -388,9 +415,35 @@ if ($deleteAllResults)
exit();
}
$qry = "SELECT * FROM testtool.tbl_pruefling_gebiet WHERE pruefling_id=" . $db->db_add_param($pruefling->pruefling_id, FHC_INTEGER) . ";
";
if ($db->db_query($qry))
{
while ($row = $db->db_fetch_object())
{
$undo .= " INSERT INTO testtool.tbl_pruefling_gebiet(prueflinggebiet_id,pruefling_id,gebiet_id,insertamum) VALUES (" .
$db->db_add_param($row->prueflinggebiet_id, FHC_INTEGER) . ', ' .
$db->db_add_param($row->pruefling_id, FHC_INTEGER) . ', ' .
$db->db_add_param($row->gebiet_id, FHC_INTEGER) . ', ' .
$db->db_add_param($row->insertamum) . ');';
}
}
else
{
$db->db_query('ROLLBACK');
echo json_encode(array(
'status' => 'fehler',
'msg' => 'Fehler beim Erstellen des UNDO Befehls fuer testtool.tbl_pruefling_gebiet'
));
exit();
}
//Antworten loeschen
$qry = " DELETE FROM testtool.tbl_pruefling_frage where pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";
DELETE FROM testtool.tbl_antwort WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";";
DELETE FROM testtool.tbl_antwort where pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";
DELETE FROM testtool.tbl_pruefling_gebiet WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";";
if ($result = $db->db_query($qry))
{
@@ -402,7 +402,10 @@ if(isset($_POST['deleteteilgebiet']))
DELETE FROM testtool.tbl_antwort
WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id)." AND
vorschlag_id IN (SELECT vorschlag_id FROM testtool.tbl_vorschlag WHERE frage_id IN
(SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=".$db->db_add_param($_POST['gebiet'])."));";
(SELECT frage_id FROM testtool.tbl_frage WHERE gebiet_id=".$db->db_add_param($_POST['gebiet'])."));
DELETE FROM testtool.tbl_pruefling_gebiet
WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id)." AND gebiet_id=".$db->db_add_param($_POST['gebiet']).";";
if($result = $db->db_query($qry))
{
@@ -497,7 +500,8 @@ if(isset($_POST['delete_all']))
}
//Gebiet loeschen
$qry = "DELETE FROM testtool.tbl_pruefling_frage where pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";
DELETE FROM testtool.tbl_antwort WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";";
DELETE FROM testtool.tbl_antwort WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";
DELETE FROM testtool.tbl_pruefling_gebiet WHERE pruefling_id=".$db->db_add_param($pruefling->pruefling_id).";";
if($result = $db->db_query($qry))
{