mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-16 22:42:16 +00:00
Merge branch 'master' into feature-62462/FHC4_Studierendenverwaltung_Delete_Photo
This commit is contained in:
@@ -7,3 +7,9 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
$config['cis_menu_root_content_id'] = 11087;
|
||||
// send Mails for ProfilUpdate
|
||||
$config['cis_send_profil_update_mails'] = true;
|
||||
// Vilesci CI BaseUrl
|
||||
$config['cis_vilesci_base_url'] = defined('VILESCI_ROOT') ? VILESCI_ROOT : APP_ROOT;
|
||||
$config['cis_vilesci_index_page'] = 'index.ci.php';
|
||||
// Cis CI BaseUrl
|
||||
$config['cis_base_url'] = defined('CIS_ROOT') ? CIS_ROOT : APP_ROOT;
|
||||
$config['cis_index_page'] = 'cis.php';
|
||||
|
||||
@@ -63,6 +63,7 @@ $route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1';
|
||||
|
||||
$route['Cis/LvPlan/.*'] = 'Cis/LvPlan/index/$1';
|
||||
$route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1';
|
||||
$route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1';
|
||||
|
||||
// Studierendenverwaltung List Routes
|
||||
$route['api/frontend/v1/stv/[sS]tudents/inout'] = 'api/frontend/v1/stv/Students/index';
|
||||
@@ -75,34 +76,34 @@ $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/outgoing'] = 'api/
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/gemeinsamestudien'] = 'api/frontend/v1/stv/Students/getGemeinsamestudien';
|
||||
|
||||
// (studiengang_kz)/prestudent[/(studiensemester_kurzbz)[/(filter)[/(otherfilter)]]]
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudents/$1';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/prestudent/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/prestudent/([WS]S[0-9]{4})/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/prestudent/([WS]S[0-9]{4})/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudents/$1';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent/([WS]S[0-9]{4})/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent/([WS]S[0-9]{4})/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2/$4';
|
||||
|
||||
// (studiengang_kz)/(orgform)/prestudent[/(studiensemester_kurzbz)[/(filter)[/(otherfilter)]]]
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/([A-Z]{2,3})/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(:num)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3/$5';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3/$5';
|
||||
|
||||
// (studiensemester_kurzbz)/(studiengang_kz)/(semester)/grp/(gruppe)
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/(:num)/grp/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsSpezialgruppe/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)/grp/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsSpezialgruppe/$1/$2/$3/$4';
|
||||
|
||||
// (studiensemester_kurzbz)/(studiengang_kz)[/(semester)[/(verband)[/(gruppe)]]]
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/(:num)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/(:num)/(:any)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/(:num)/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3/$4/$5';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)/(:any)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3/$4/$5';
|
||||
|
||||
// (studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/grp/(gruppe)
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/([A-Z]{2,3})/(:num)/grp/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgformSpezialgruppe/$1/$2/$3/$4/$5';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)/grp/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgformSpezialgruppe/$1/$2/$3/$4/$5';
|
||||
|
||||
// (studiensemester_kurzbz)/(studiengang_kz)/(orgform)[/(semester)[/(verband)[/(gruppe)]]]
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/([A-Z]{2,3})'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/([A-Z]{2,3})/(:num)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/([A-Z]{2,3})/(:num)/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4/$5';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(:num)/([A-Z]{2,3})/(:num)/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4/$5/$6';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4/$5';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4/$5/$6';
|
||||
|
||||
// // (studiensemester_kurzbz)/uid/(uid)
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/uid/(:any)'] = 'api/frontend/v1/stv/Students/getStudent/$1/$2';
|
||||
@@ -111,24 +112,30 @@ $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/prestudent/(:num)'] = 'a
|
||||
// // (studiensemester_kurzbz)/person/(person_id)
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/person/(:num)'] = 'api/frontend/v1/stv/Students/getPerson/$1/$2';
|
||||
|
||||
// load routes from extensions
|
||||
$subdir = 'application/config/extensions';
|
||||
$dirlist = scandir($subdir);
|
||||
// load routes from extensions, also look for environment-specific configs
|
||||
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
|
||||
|
||||
if ($dirlist)
|
||||
foreach($subdirs as $subdir)
|
||||
{
|
||||
$files = array_diff($dirlist, array('.','..'));
|
||||
|
||||
foreach ($files as &$item)
|
||||
if(is_dir($subdir))
|
||||
{
|
||||
if (is_dir($subdir . DIRECTORY_SEPARATOR . $item))
|
||||
$dirlist = scandir($subdir);
|
||||
if ($dirlist)
|
||||
{
|
||||
$routes_file = $subdir . DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . 'routes.php';
|
||||
$files = array_diff($dirlist, array('.','..'));
|
||||
|
||||
if (file_exists($routes_file))
|
||||
foreach ($files as &$item)
|
||||
{
|
||||
require($routes_file);
|
||||
if (is_dir($subdir . DIRECTORY_SEPARATOR . $item))
|
||||
{
|
||||
$routes_file = $subdir . DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . 'routes.php';
|
||||
|
||||
if (file_exists($routes_file))
|
||||
{
|
||||
require($routes_file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ $config['student']['resultfields'] = [
|
||||
"(p.vorname || ' ' || p.nachname) AS name",
|
||||
"ARRAY[s.student_uid || '@' || '" . DOMAIN . "'] AS email",
|
||||
"CASE
|
||||
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
|
||||
WHEN (p.foto_sperre = false AND p.foto IS NOT NULL) THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
|
||||
ELSE NULL END
|
||||
AS photo_url",
|
||||
"b.aktiv"
|
||||
|
||||
@@ -58,6 +58,10 @@ $config['tabs'] =
|
||||
//if true, Anrechnungen can be added and edited in tab Anrechnungen
|
||||
'editableAnrechnungen' => false,
|
||||
],
|
||||
'notes' => [
|
||||
//if true, the count of Messages will be shown in the header of the Tab Messages
|
||||
'showCountNotes' => true
|
||||
]
|
||||
];
|
||||
|
||||
// List of fields to show when ZGV_DOKTOR_ANZEIGEN is defined
|
||||
@@ -79,3 +83,33 @@ if (!defined('ZGV_DOKTOR_ANZEIGEN') || !ZGV_DOKTOR_ANZEIGEN) {
|
||||
$fieldsZgvDoktor
|
||||
);
|
||||
}
|
||||
|
||||
$config['student_tab_order'] = [
|
||||
'details',
|
||||
'notes',
|
||||
'messages',
|
||||
'contact',
|
||||
'prestudent',
|
||||
'status',
|
||||
'documents',
|
||||
'archive',
|
||||
'banking',
|
||||
'grades',
|
||||
'exam',
|
||||
'exemptions',
|
||||
'finalexam',
|
||||
'mobility',
|
||||
'jointstudies',
|
||||
'admissionDates',
|
||||
'groups',
|
||||
'functions',
|
||||
'coursedates',
|
||||
'resources',
|
||||
];
|
||||
$config['students_tab_order'] = [
|
||||
'banking',
|
||||
'status',
|
||||
'groups',
|
||||
'finalexam',
|
||||
'archive',
|
||||
];
|
||||
|
||||
@@ -72,6 +72,7 @@ class Auth extends FHC_Controller
|
||||
{
|
||||
$this->load->library('AuthLib');
|
||||
$this->authlib->logout();
|
||||
redirect('/Cis/Auth/login', 'refresh');
|
||||
setcookie('fhclogout', 'fhclogout', 0, '/');
|
||||
redirect(base_url('/cis/private/logout.php'), 'refresh');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,54 +9,21 @@ if (!defined('BASEPATH'))
|
||||
class ProfilUpdate extends Auth_Controller
|
||||
{
|
||||
|
||||
public static $STATUS_PENDING = NULL;
|
||||
public static $STATUS_ACCEPTED = NULL;
|
||||
public static $STATUS_REJECTED = NULL;
|
||||
|
||||
public static $TOPICS = [];
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'index' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
|
||||
'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
|
||||
'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
|
||||
'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
|
||||
'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
|
||||
'show' => ['basis/cis:r'],
|
||||
|
||||
'insertProfilRequest' => ['basis/cis:rw'],
|
||||
'updateProfilRequest' => ['basis/cis:rw'],
|
||||
'deleteProfilRequest' => ['basis/cis:rw'],
|
||||
'selectProfilRequest' => ['basis/cis:r'],
|
||||
'insertFile' => ['basis/cis:rw'],
|
||||
'getProfilRequestFiles' => ['basis/cis:r'],
|
||||
'getStatus' => ['basis/cis:r'],
|
||||
'getTopic' => ['basis/cis:r'],
|
||||
'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r']
|
||||
]);
|
||||
|
||||
$this->load->config('cis');
|
||||
|
||||
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
|
||||
$this->load->model('person/Kontakt_model', 'KontaktModel');
|
||||
$this->load->model('person/Adresse_model', 'AdresseModel');
|
||||
$this->load->model('person/Adressentyp_model', 'AdressenTypModel');
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
$this->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
$this->load->model('system/Sprache_model', 'SpracheModel');
|
||||
$this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel');
|
||||
$this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel');
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases(
|
||||
array(
|
||||
'ui',
|
||||
'global',
|
||||
'person',
|
||||
'profil',
|
||||
'profilUpdate'
|
||||
)
|
||||
);
|
||||
@@ -64,32 +31,10 @@ class ProfilUpdate extends Auth_Controller
|
||||
$this->load->library('DmsLib');
|
||||
$this->load->library('PermissionLib');
|
||||
|
||||
//? put the uid and pid inside the controller for reusability
|
||||
$this->uid = getAuthUID();
|
||||
$this->pid = getAuthPersonID();
|
||||
|
||||
// setup the ProfilUpdate states
|
||||
$this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']);
|
||||
$status_kurzbz = $this->ProfilUpdateStatusModel->load();
|
||||
if (hasData($status_kurzbz)) {
|
||||
list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz);
|
||||
|
||||
self::$STATUS_PENDING = $status_pending->status_kurzbz;
|
||||
self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz;
|
||||
self::$STATUS_REJECTED = $status_rejected->status_kurzbz;
|
||||
}
|
||||
// setup the ProfilUpdate topics
|
||||
$this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']);
|
||||
$topic_kurzbz = $this->ProfilUpdateTopicModel->load();
|
||||
|
||||
if (hasData($topic_kurzbz)) {
|
||||
foreach (getData($topic_kurzbz) as $topic) {
|
||||
self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function index()
|
||||
{
|
||||
$this->load->view('Cis/ProfilUpdate');
|
||||
@@ -100,129 +45,14 @@ class ProfilUpdate extends Auth_Controller
|
||||
$this->load->view('Cis/ProfilUpdate', ['profil_update_id' => $profil_update_id]);
|
||||
}
|
||||
|
||||
public function getStatus()
|
||||
{
|
||||
echo json_encode([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]);
|
||||
}
|
||||
|
||||
public function getTopic()
|
||||
{
|
||||
echo json_encode(self::$TOPICS);
|
||||
}
|
||||
|
||||
private function sendEmail_onProfilUpdate_response($uid, $topic, $status)
|
||||
{
|
||||
if($this->config->item('cis_send_profil_update_mails') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->load->helper('hlp_sancho_helper');
|
||||
$email = $uid . "@" . DOMAIN;
|
||||
|
||||
|
||||
function languageQuery($language)
|
||||
{
|
||||
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
|
||||
}
|
||||
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
|
||||
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
|
||||
if (isError($status_translation)) {
|
||||
show_error($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
|
||||
}
|
||||
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
|
||||
if (isset($status_translation)) {
|
||||
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
|
||||
if (!$mail_res) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic)
|
||||
{
|
||||
if($this->config->item('cis_send_profil_update_mails') === false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->load->helper('hlp_sancho_helper');
|
||||
$emails = [];
|
||||
|
||||
$isMitarbeiter_res = $this->MitarbeiterModel->isMitarbeiter($uid);
|
||||
if (isError($isMitarbeiter_res)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
|
||||
}
|
||||
$isMitarbeiter_res = getData($isMitarbeiter_res);
|
||||
|
||||
//! if the $uid is a mitarbeiter and student, only the hr is notified by email
|
||||
if ($isMitarbeiter_res) {
|
||||
//? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung
|
||||
//? use constant variable MAIL_GST to mail to the personalverwaltung
|
||||
$this->MitarbeiterModel->addSelect([TRUE]);
|
||||
$this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid");
|
||||
//? check if the the userID is a mitarbeiter and if the benutzer is active
|
||||
$res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]);
|
||||
if (isError($res)) {
|
||||
show_error("was not able to query the mitarbeiter and benutzer by the uid: " . $uid);
|
||||
}
|
||||
if (hasData($res)) {
|
||||
array_push($emails, MAIL_GST);
|
||||
} else {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
|
||||
}
|
||||
} else {
|
||||
//? if it is not a mitarbeiter, check whether it is a student and send email to studiengang
|
||||
$isStudent_res = $this->StudentModel->isStudent($uid);
|
||||
if (isError($isStudent_res)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error'));
|
||||
}
|
||||
$isStudent_res = getData($isStudent_res);
|
||||
if ($isStudent_res) {
|
||||
//? Send email to the Studiengangsassistentinnen
|
||||
$this->StudentModel->addSelect(["public.tbl_studiengang.email"]);
|
||||
$this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid");
|
||||
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
|
||||
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
|
||||
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
|
||||
//* check if the benutzer itself is active
|
||||
//* check if the student status is Student or Diplomand (active students)
|
||||
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
|
||||
$res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]);
|
||||
if (isError($res)) {
|
||||
show_error(getData($res));
|
||||
} else {
|
||||
$res = hasData($res) ? getData($res) : [];
|
||||
foreach ($res as $emailObj) {
|
||||
array_push($emails, $emailObj->email);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$mail_res = [];
|
||||
//? sending email
|
||||
foreach ($emails as $email) {
|
||||
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
|
||||
}
|
||||
foreach ($mail_res as $m_res) {
|
||||
if (!$m_res) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function show($dms_id)
|
||||
{
|
||||
|
||||
$profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]);
|
||||
$profil_update = hasData($profil_update) ? getData($profil_update)[0] : null;
|
||||
|
||||
//? checks if an profil update exists with the dms_id requested from the user
|
||||
if ($profil_update) {
|
||||
if ($profil_update)
|
||||
{
|
||||
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid));
|
||||
$is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid));
|
||||
|
||||
@@ -230,7 +60,8 @@ class ProfilUpdate extends Auth_Controller
|
||||
$this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update ||
|
||||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update ||
|
||||
$this->uid == $profil_update->uid
|
||||
) {
|
||||
)
|
||||
{
|
||||
// Get file to be downloaded from DMS
|
||||
$newFilename = $this->uid . "/document_" . $dms_id;
|
||||
$download = $this->dmslib->download($dms_id);
|
||||
@@ -239,576 +70,17 @@ class ProfilUpdate extends Auth_Controller
|
||||
|
||||
// Download file
|
||||
$this->outputFile(getData($download));
|
||||
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_dms_error'));
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function insertFile($replace)
|
||||
{
|
||||
$replace = json_decode($replace);
|
||||
|
||||
if (!count($_FILES)) {
|
||||
echo json_encode([]);
|
||||
return;
|
||||
}
|
||||
|
||||
//? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced
|
||||
if (isset($replace)) {
|
||||
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
|
||||
$profilUpdate = $this->ProfilUpdateModel->load([$replace]);
|
||||
if (isError($profilUpdate)) {
|
||||
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
|
||||
}
|
||||
//? get the attachmentID
|
||||
$dms_id = hasData($profilUpdate) ? getData($profilUpdate)[0]->attachment_id : null;
|
||||
|
||||
//? delete old dms_file of Profil Update
|
||||
$this->deleteOldVersionFile($dms_id);
|
||||
}
|
||||
|
||||
|
||||
$files = $_FILES['files'];
|
||||
$file_count = count($files['name']);
|
||||
|
||||
$res = [];
|
||||
|
||||
for ($i = 0; $i < $file_count; $i++) {
|
||||
$_FILES['files']['name'] = $files['name'][$i];
|
||||
$_FILES['files']['type'] = $files['type'][$i];
|
||||
$_FILES['files']['tmp_name'] = $files['tmp_name'][$i];
|
||||
$_FILES['files']['error'] = $files['error'][$i];
|
||||
$_FILES['files']['size'] = $files['size'][$i];
|
||||
|
||||
$dms = [
|
||||
"kategorie_kurzbz" => "profil_aenderung",
|
||||
"version" => 0,
|
||||
"name" => $_FILES['files']['name'],
|
||||
"mimetype" => $_FILES['files']['type'],
|
||||
"beschreibung" => $this->uid . " Profil Änderung",
|
||||
"insertvon" => $this->uid,
|
||||
"insertamum" => "NOW()",
|
||||
];
|
||||
|
||||
$tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf"));
|
||||
|
||||
$tmp_res = hasData($tmp_res) ? getData($tmp_res) : null;
|
||||
array_push($res, $tmp_res);
|
||||
}
|
||||
|
||||
echo json_encode($res);
|
||||
}
|
||||
|
||||
|
||||
public function selectProfilRequest()
|
||||
{
|
||||
$_GET = json_decode($this->input->raw_input_stream, true);
|
||||
$uid = $this->input->get('uid');
|
||||
$id = $this->input->get('id');
|
||||
$whereClause = ['uid' => $this->uid];
|
||||
|
||||
if (isset($uid))
|
||||
$whereClause['uid'] = $uid;
|
||||
if (isset($id))
|
||||
$whereClause['id'] = $id;
|
||||
|
||||
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause);
|
||||
$res = hasData($res) ? getData($res) : null;
|
||||
echo json_encode($res);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function getProfilRequestFiles()
|
||||
{
|
||||
$id = json_decode($this->input->raw_input_stream);
|
||||
|
||||
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
|
||||
$attachmentID = $this->ProfilUpdateModel->load([$id]);
|
||||
if (isError($attachmentID)) {
|
||||
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
|
||||
}
|
||||
//? get the attachmentID
|
||||
$dms_id = hasData($attachmentID) ? getData($attachmentID)[0]->attachment_id : null;
|
||||
|
||||
//? get the name to the file
|
||||
$this->DmsVersionModel->addSelect(["name", "dms_id"]);
|
||||
$attachment = $this->DmsVersionModel->load([$dms_id, 0]);
|
||||
if (isError($attachment)) {
|
||||
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
|
||||
}
|
||||
$attachment = hasData($attachment) ? getData($attachment) : null;
|
||||
//? returns {name:..., dms_id:...}
|
||||
echo json_encode($attachment);
|
||||
}
|
||||
|
||||
public function insertProfilRequest()
|
||||
{
|
||||
|
||||
$json = json_decode($this->input->raw_input_stream);
|
||||
|
||||
$payload = $json->payload;
|
||||
$identifier = property_exists($json->payload, "kontakt_id") ? "kontakt_id" : (property_exists($json->payload, "adresse_id") ? "adresse_id" : null);
|
||||
|
||||
$data = ["topic" => $json->topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending'];
|
||||
|
||||
//? insert fileID in the dataset if sent with post request
|
||||
if (isset($json->fileID)) {
|
||||
$data['attachment_id'] = $json->fileID;
|
||||
|
||||
}
|
||||
|
||||
//? loops over all updateRequests from a user to validate if the new request is valid
|
||||
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]);
|
||||
if (isError($res)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_loading_error'));
|
||||
}
|
||||
$res = hasData($res) ? getData($res) : null;
|
||||
|
||||
//? the user cannot delete a zustelladresse/kontakt
|
||||
if (isset($payload->delete) && $payload->{$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"}) {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
|
||||
return;
|
||||
}
|
||||
|
||||
//? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised
|
||||
if (isset($payload->delete) && $identifier == "adresse_id") {
|
||||
$adr = $this->AdresseModel->load($payload->$identifier);
|
||||
$adr = getData($adr)[0];
|
||||
if ($adr->heimatadresse) {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ($res) {
|
||||
$pending_changes = array_filter($res, function ($element) {
|
||||
return $element->status == (self::$STATUS_PENDING ?: "Pending");
|
||||
});
|
||||
|
||||
foreach ($pending_changes as $update_request) {
|
||||
$existing_change = $update_request->requested_change;
|
||||
|
||||
//? the user can add as many new kontakte/adressen as he likes
|
||||
if (!isset($payload->add) && property_exists($existing_change, $identifier) && property_exists($payload, $identifier) && $existing_change->$identifier == $payload->$identifier) {
|
||||
//? the kontakt_id / adresse_id of a change has to be unique
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error')));
|
||||
return;
|
||||
}
|
||||
|
||||
//? if it is not updating any kontakt/adresse, the topic has to be unique
|
||||
elseif (!$identifier && $update_request->topic == $json->topic) {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic])));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$insertID = $this->ProfilUpdateModel->insert($data);
|
||||
|
||||
if (isError($insertID)) {
|
||||
show_error(getData($insertID));
|
||||
} else {
|
||||
$insertID = hasData($insertID) ? getData($insertID) : null;
|
||||
|
||||
//? sends emails to the correspondents of the $uid
|
||||
$this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $json->topic);
|
||||
echo json_encode(success($insertID));
|
||||
}
|
||||
}
|
||||
|
||||
public function updateProfilRequest()
|
||||
{
|
||||
$json = json_decode($this->input->raw_input_stream);
|
||||
|
||||
$updateData = ["requested_change" => json_encode($json->payload), "updateamum" => "NOW()", "updatevon" => $this->uid];
|
||||
if (isset($json->fileID)) {
|
||||
$updateData['attachment_id'] = json_decode($json->fileID);
|
||||
}
|
||||
$updateID = $this->ProfilUpdateModel->update([$json->ID], $updateData);
|
||||
//? insert fileID in the dataset if sent with post request
|
||||
|
||||
if (isError($updateID)) {
|
||||
//catch error
|
||||
} else {
|
||||
$updateID = hasData($updateID) ? getData($updateID)[0] : null;
|
||||
//TODO: should an email be sent to the responsable people when the user changes his profil update
|
||||
echo json_encode(success($updateID));
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteProfilRequest()
|
||||
{
|
||||
|
||||
$json = json_decode($this->input->raw_input_stream);
|
||||
$delete_res = $this->ProfilUpdateModel->delete([$json]);
|
||||
echo json_encode($delete_res);
|
||||
}
|
||||
|
||||
|
||||
public function getProfilUpdateWithPermission($status = null)
|
||||
{
|
||||
// early return if no status has been passed as argument
|
||||
if (!isset($status)) {
|
||||
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
|
||||
return;
|
||||
}
|
||||
|
||||
// get the sprache of the user
|
||||
$sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]);
|
||||
$sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null;
|
||||
|
||||
if (isset($sprachenIndex) && isset($status)) {
|
||||
// get the corresponding status kurz_bz primary key out of the translation
|
||||
$status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]);
|
||||
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
|
||||
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
|
||||
|
||||
echo json_encode($res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function getOE_from_student($student_uid)
|
||||
{
|
||||
|
||||
//? returns the oe_einheit eines Studenten
|
||||
$query = "SELECT public.tbl_studiengang.oe_kurzbz
|
||||
FROM public.tbl_student
|
||||
JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
|
||||
WHERE public.tbl_student.student_uid = ?;";
|
||||
|
||||
$res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]);
|
||||
if (!isSuccess($res)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_loadingOE_error'));
|
||||
}
|
||||
$res = hasData($res) ? getData($res) : [];
|
||||
$res = array_map(
|
||||
function ($item) {
|
||||
return $item->oe_kurzbz;
|
||||
},
|
||||
$res
|
||||
);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
public function acceptProfilRequest()
|
||||
{
|
||||
$_POST = json_decode($this->input->raw_input_stream, true);
|
||||
$id = $this->input->post('profil_update_id', true);
|
||||
$uid = $this->input->post('uid', true);
|
||||
|
||||
//? fetching person_id using UID
|
||||
$personID = $this->PersonModel->getByUid($uid);
|
||||
$personID = hasData($personID) ? getData($personID)[0]->person_id : null;
|
||||
$status_message = $this->input->post('status_message', true);
|
||||
$topic = $this->input->post('topic', true);
|
||||
|
||||
//! somehow the xss check converted boolean false to empty string
|
||||
$requested_change = $this->input->post('requested_change');
|
||||
|
||||
//! check for required information
|
||||
if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) {
|
||||
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error')));
|
||||
}
|
||||
|
||||
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
|
||||
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
|
||||
|
||||
|
||||
//? check if the permissions are set correctly
|
||||
if (
|
||||
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
|
||||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
|
||||
) {
|
||||
|
||||
if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) {
|
||||
$insertID = $this->handleAdresse($requested_change, $personID);
|
||||
$insertID = hasData($insertID) ? getData($insertID) : null;
|
||||
if (isset($insertID)) {
|
||||
$requested_change['adresse_id'] = $insertID;
|
||||
$update_res = $this->updateRequestedChange($id, $requested_change);
|
||||
if (isError($update_res)) {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID])));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) {
|
||||
$insertID = $this->handleKontakt($requested_change, $personID);
|
||||
$insertID = hasData($insertID) ? getData($insertID) : null;
|
||||
if (isset($insertID)) {
|
||||
$requested_change['kontakt_id'] = $insertID;
|
||||
$update_res = $this->updateRequestedChange($id, $requested_change);
|
||||
if (isError($update_res)) {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID])));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
switch ($topic) {
|
||||
// mapping phrasen to database columns to make the update with the correct column names
|
||||
case self::$TOPICS['Titel']:
|
||||
$topic = "titelpre";
|
||||
break;
|
||||
case self::$TOPICS['Postnomen']:
|
||||
$topic = "titelpost";
|
||||
break;
|
||||
case self::$TOPICS['Vorname']:
|
||||
$topic = "vorname";
|
||||
break;
|
||||
case self::$TOPICS['Nachname']:
|
||||
$topic = "nachname";
|
||||
break;
|
||||
default:
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic]));
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]);
|
||||
if (isError($result)) {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_insert_error')));
|
||||
return;
|
||||
}
|
||||
}
|
||||
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED);
|
||||
|
||||
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change));
|
||||
} else {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function denyProfilRequest()
|
||||
{
|
||||
|
||||
$_POST = json_decode($this->input->raw_input_stream, true);
|
||||
$id = $this->input->post('profil_update_id', true);
|
||||
$uid = $this->input->post('uid', true);
|
||||
$topic = $this->input->post('topic', true);
|
||||
$status_message = $this->input->post('status_message', true);
|
||||
|
||||
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
|
||||
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
|
||||
|
||||
|
||||
if (
|
||||
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
|
||||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
|
||||
) {
|
||||
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED);
|
||||
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message));
|
||||
} else {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function updateRequestedChange($id, $requested_change)
|
||||
{
|
||||
return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]);
|
||||
}
|
||||
|
||||
private function setStatusOnUpdateRequest($id, $status, $status_message)
|
||||
{
|
||||
return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]);
|
||||
}
|
||||
|
||||
private function deleteOldVersionFile($dms_id)
|
||||
{
|
||||
if (!isset($dms_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
//? collect all the results of the deleted versions in an array
|
||||
$res = array();
|
||||
|
||||
//? delete all the different versions of the dms_file
|
||||
$dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]);
|
||||
$dmsVersions = hasData($dmsVersions) ? getData($dmsVersions) : null;
|
||||
if (isset($dmsVersions)) {
|
||||
$zwischen_res = array_map(function ($item) {
|
||||
return $item->version;
|
||||
}, $dmsVersions);
|
||||
foreach ($zwischen_res as $version) {
|
||||
array_push($res, $this->DmsVersionModel->delete([$dms_id, $version]));
|
||||
}
|
||||
} else {
|
||||
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
|
||||
}
|
||||
|
||||
//? returns a result for each deleted dms_file
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
private function handleKontakt($requested_change, $personID)
|
||||
{
|
||||
$kontakt_id = $requested_change["kontakt_id"];
|
||||
//? removes the kontakt_id because we don't want to update the kontakt_id in the database
|
||||
unset($requested_change["kontakt_id"]);
|
||||
|
||||
|
||||
//! ADD
|
||||
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
|
||||
//? removes add flag
|
||||
unset($requested_change['add']);
|
||||
$requested_change['person_id'] = $personID;
|
||||
$requested_change['insertamum'] = "NOW()";
|
||||
$requested_change['insertvon'] = getAuthUID();
|
||||
$insertID = $this->KontaktModel->insert($requested_change);
|
||||
$insert_kontakt_id = $insertID;
|
||||
if (isError($insert_kontakt_id)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error'));
|
||||
}
|
||||
$insert_kontakt_id = hasData($insert_kontakt_id) ? getData($insert_kontakt_id) : null;
|
||||
if ($insert_kontakt_id) {
|
||||
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//! DELETE
|
||||
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
|
||||
$this->KontaktModel->delete($kontakt_id);
|
||||
}
|
||||
//! UPDATE
|
||||
else {
|
||||
$requested_change['updateamum'] = "NOW()";
|
||||
$requested_change['updatevon'] = getAuthUID();
|
||||
|
||||
$update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change);
|
||||
|
||||
if (isError($update_kontakt_id)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error'));
|
||||
}
|
||||
$update_kontakt_id = hasData($update_kontakt_id) ? getData($update_kontakt_id) : null;
|
||||
if ($update_kontakt_id) {
|
||||
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id);
|
||||
}
|
||||
}
|
||||
return isset($insertID) ? $insertID : null;
|
||||
}
|
||||
|
||||
private function handleAdresse($requested_change, $personID)
|
||||
{
|
||||
|
||||
$this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]);
|
||||
$adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]);
|
||||
$adr_kurzbz = hasData($adr_kurzbz) ? getData($adr_kurzbz)[0]->adressentyp_kurzbz : null;
|
||||
//? replace the address_typ with its correct kurzbz foreign key
|
||||
$requested_change['typ'] = $adr_kurzbz;
|
||||
|
||||
$adresse_id = $requested_change["adresse_id"];
|
||||
//? removes the adresse_id because we don't want to update the kontakt_id in the database
|
||||
unset($requested_change["adresse_id"]);
|
||||
|
||||
|
||||
//! ADD
|
||||
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
|
||||
|
||||
//? removes add flag
|
||||
unset($requested_change['add']);
|
||||
$requested_change['insertamum'] = "NOW()";
|
||||
$requested_change['insertvon'] = getAuthUID();
|
||||
$requested_change['person_id'] = $personID;
|
||||
//TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet
|
||||
$insertID = $this->AdresseModel->insert($requested_change);
|
||||
$insert_adresse_id = $insertID;
|
||||
if (isError($insert_adresse_id)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error'));
|
||||
}
|
||||
$insert_adresse_id = hasData($insert_adresse_id) ? getData($insert_adresse_id) : null;
|
||||
if ($insert_adresse_id) {
|
||||
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id);
|
||||
}
|
||||
|
||||
}
|
||||
//! DELETE
|
||||
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
|
||||
$this->AdresseModel->delete($adresse_id);
|
||||
}
|
||||
//! UPDATE
|
||||
else {
|
||||
$requested_change['updateamum'] = "NOW()";
|
||||
$requested_change['updatevon'] = getAuthUID();
|
||||
$update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change);
|
||||
if (isError($update_adresse_id)) {
|
||||
show_error($this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error'));
|
||||
}
|
||||
$update_adresse_id = hasData($update_adresse_id) ? getData($update_adresse_id) : null;
|
||||
if ($update_adresse_id) {
|
||||
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id);
|
||||
}
|
||||
}
|
||||
return isset($insertID) ? $insertID : null;
|
||||
}
|
||||
|
||||
|
||||
private function handleDupplicateZustellKontakte($zustellung, $kontakt_id)
|
||||
{
|
||||
if ($zustellung) {
|
||||
$this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id");
|
||||
$this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id");
|
||||
$zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]);
|
||||
if (!isSuccess($zustellKontakteArray)) {
|
||||
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error'));
|
||||
}
|
||||
$zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null;
|
||||
|
||||
if ($zustellung && count($zustellKontakteArray) > 0) {
|
||||
$zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) {
|
||||
return $kontakt->kontakt_id != $kontakt_id;
|
||||
});
|
||||
foreach ($zustellKontakteArray as $kontakt) {
|
||||
$this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function handleDupplicateZustellAdressen($zustellung, $adresse_id)
|
||||
{
|
||||
if ($zustellung) {
|
||||
$this->PersonModel->addSelect("public.tbl_adresse.adresse_id");
|
||||
$this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id");
|
||||
$zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]);
|
||||
if (!isSuccess($zustellAdressenArray)) {
|
||||
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error'));
|
||||
}
|
||||
$zustellAdressenArray = hasData($zustellAdressenArray) ? getData($zustellAdressenArray) : null;
|
||||
|
||||
if ($zustellung && count($zustellAdressenArray) > 0) {
|
||||
|
||||
$zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) {
|
||||
|
||||
return $adresse->adresse_id != $adresse_id;
|
||||
});
|
||||
foreach ($zustellAdressenArray as $adresse) {
|
||||
$this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
|
||||
$this->load->library("PermissionLib", null, 'PermissionLib');
|
||||
|
||||
$this->load->library("PhrasesLib");
|
||||
$this->load->library("PhrasesLib", null, 'PhrasesLib');
|
||||
$this->loadPhrases(array('global', 'lehre'));
|
||||
}
|
||||
|
||||
@@ -269,6 +269,8 @@ class LvMenu extends FHCAPI_Controller
|
||||
'lehrfach_id'=>$lehrfach_id,
|
||||
'lektor_der_lv'=>$lektor_der_lv,
|
||||
'lehrfach_oe_kurzbz_arr'=>$lehrfach_oe_kurzbz_arr,
|
||||
'permissionLib' => &$this->PermissionLib,
|
||||
'phrasesLib' => &$this->PhrasesLib
|
||||
];
|
||||
|
||||
Events::trigger('lvMenuBuild',
|
||||
@@ -331,6 +333,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id'=>'core_menu_lvinfo',
|
||||
'position'=>'10',
|
||||
'name'=>$this->p->t('lehre', 'lehrveranstaltungsinformation'),
|
||||
'phrase' => 'lehre/lehrveranstaltungsinformation',
|
||||
'icon'=>'../../../skin/images/button_lvinfo.png',
|
||||
'link'=>'',
|
||||
'c4_icon'=> base_url('skin/images/button_lvinfo.png'),
|
||||
@@ -349,6 +352,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id'=>'core_menu_feedback',
|
||||
'position'=>'60',
|
||||
'name'=>$this->p->t('lehre', 'feedback'),
|
||||
'phrase' => 'lehre/feedback',
|
||||
'c4_icon'=> base_url('skin/images/button_feedback.png'),
|
||||
'c4_link'=> base_url('feedback.php?lvid='.$lvid),
|
||||
);
|
||||
@@ -366,6 +370,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id'=>'core_menu_gesamtnote',
|
||||
'position'=>'80',
|
||||
'name'=>$this->p->t('lehre', 'gesamtnote'),
|
||||
'phrase' => 'lehre/gesamtnote',
|
||||
'c4_icon'=> base_url('skin/images/button_endnote.png'),
|
||||
'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
|
||||
//'c4_link'=> base_url('benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
|
||||
@@ -378,6 +383,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id'=>'core_menu_gesamtnote',
|
||||
'position'=>'80',
|
||||
'name'=>$this->p->t('lehre', 'gesamtnote'),
|
||||
'phrase'=>'lehre/gesamtnote',
|
||||
'c4_icon'=>base_url('skin/images/button_endnote.png'),
|
||||
'c4_link'=>'#',
|
||||
'c4_linkList'=>[[$this->p->t('lehre', 'noteneingabedeaktiviert'),'#']],
|
||||
@@ -450,6 +456,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id'=>'core_menu_mailanstudierende',
|
||||
'position'=>'100',
|
||||
'name'=>$this->p->t('lehre', 'mail'),
|
||||
'phrase' => 'lehre/mail',
|
||||
'c4_icon'=>base_url('skin/images/button_feedback.png'),
|
||||
'c4_icon2' => 'fa-regular fa-envelope',
|
||||
'c4_link'=>$mailto,
|
||||
@@ -474,6 +481,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id'=>'core_menu_abmeldung',
|
||||
'position'=>'120',
|
||||
'name'=>$this->p->t('lehre', 'abmelden'),
|
||||
'phrase'=>'lehre/abmelden',
|
||||
'c4_icon'=>base_url('skin/images/button_studiupload.png'),
|
||||
'c4_link'=>base_url('abmeldung.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)),
|
||||
);
|
||||
@@ -508,6 +516,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse',
|
||||
'position' => '128',
|
||||
'name' => $this->p->t('lehre', 'anrechnung'),
|
||||
'phrase' => 'lehre/anrechnung',
|
||||
'c4_icon' => base_url('skin/images/button_listen.png'),
|
||||
'c4_icon2' => 'fa-regular fa-folder-open',
|
||||
'c4_link' => base_url('cis.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid))
|
||||
@@ -525,6 +534,7 @@ class LvMenu extends FHCAPI_Controller
|
||||
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen',
|
||||
'position' => '128',
|
||||
'name' => $this->p->t('lehre', 'anrechnungen'),
|
||||
'phrase' => 'lehre/anrechnung',
|
||||
'c4_icon'=> base_url('skin/images/button_listen.png'),
|
||||
'c4_icon2' => 'fa-regular fa-folder-open',
|
||||
'c4_link' => base_url('cis.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem))
|
||||
|
||||
@@ -176,6 +176,7 @@ class LvPlan extends FHCAPI_Controller
|
||||
{
|
||||
$this->load->model('ressource/Stunde_model', 'StundeModel');
|
||||
|
||||
$this->StundeModel->addOrder('stunde', 'ASC');
|
||||
$stunden = $this->StundeModel->load();
|
||||
|
||||
$stunden = $this->getDataOrTerminateWithError($stunden);
|
||||
|
||||
@@ -573,8 +573,7 @@ class ProfilUpdate extends FHCAPI_Controller
|
||||
{
|
||||
// early return if no status has been passed as argument
|
||||
if (!isset($status)) {
|
||||
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
|
||||
return;
|
||||
$this->terminateWithSuccess($this->ProfilUpdateModel->getProfilUpdateWithPermission());
|
||||
}
|
||||
|
||||
// get the sprache of the user
|
||||
@@ -587,7 +586,7 @@ class ProfilUpdate extends FHCAPI_Controller
|
||||
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
|
||||
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
|
||||
|
||||
echo json_encode($res);
|
||||
$this->terminateWithSuccess($res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,6 +640,7 @@ class ProfilUpdate extends FHCAPI_Controller
|
||||
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
|
||||
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
|
||||
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
|
||||
$this->StudentModel->addGroupBy(["public.tbl_studiengang.email"]);
|
||||
//* check if the benutzer itself is active
|
||||
//* check if the student status is Student or Diplomand (active students)
|
||||
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
|
||||
@@ -657,8 +657,10 @@ class ProfilUpdate extends FHCAPI_Controller
|
||||
}
|
||||
$mail_res = [];
|
||||
//? sending email
|
||||
foreach ($emails as $email) {
|
||||
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
|
||||
foreach ($emails as $email)
|
||||
{
|
||||
$href = $this->config->item('cis_vilesci_base_url') . $this->config->item('cis_vilesci_index_page') . '/Cis/ProfilUpdate/id/' . $profil_update_id;
|
||||
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => $href], $email, ("Profil Änderung von " . $uid)));
|
||||
}
|
||||
foreach ($mail_res as $m_res) {
|
||||
if (!$m_res) {
|
||||
@@ -681,21 +683,21 @@ class ProfilUpdate extends FHCAPI_Controller
|
||||
|
||||
function languageQuery($language)
|
||||
{
|
||||
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
|
||||
return "select index from public.tbl_sprache where sprache = '" . $language . "'";
|
||||
}
|
||||
|
||||
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
|
||||
|
||||
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
|
||||
|
||||
if (isError($status_translation)) {
|
||||
$this->terminateWithError($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
|
||||
}
|
||||
|
||||
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
|
||||
|
||||
if (isset($status_translation)) {
|
||||
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
|
||||
if (isset($status_translation))
|
||||
{
|
||||
$href = $this->config->item('cis_base_url') . $this->config->item('cis_index_page') . '/Cis/Profil';
|
||||
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => $href], $email, ("Profil Änderung " . $status_translation->status_de . ' / Profile Update ' . $status_translation->status_en));
|
||||
if (!$mail_res) {
|
||||
$this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error'));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2024 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
if (!defined('BASEPATH'))
|
||||
exit('No direct script access allowed');
|
||||
|
||||
class RouteInfo extends FHCAPI_Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'info' => self::PERM_LOGGED,
|
||||
]);
|
||||
|
||||
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
|
||||
}
|
||||
|
||||
public function info()
|
||||
{
|
||||
$payload = json_decode($this->input->raw_input_stream);
|
||||
|
||||
if (isset($payload->app) && isset($payload->path) && $this->isValidApp($payload->app) && $this->isValidPath($payload->path))
|
||||
{
|
||||
$this->WebservicelogModel->insert(array(
|
||||
'webservicetyp_kurzbz' => 'content',
|
||||
'beschreibung' => $payload->app,
|
||||
'request_data' => $payload->path,
|
||||
'execute_user' => getAuthUID(),
|
||||
'execute_time' => 'NOW()'
|
||||
));
|
||||
}
|
||||
$this->terminateWithSuccess(true);
|
||||
}
|
||||
|
||||
protected function isValidApp($app)
|
||||
{
|
||||
return preg_match("/^[A-Za-z0-9\-_]+$/", $app);
|
||||
}
|
||||
|
||||
protected function isValidPath($path)
|
||||
{
|
||||
return preg_match("/^[\/A-Za-z0-9_.\-~?%=&;]+$/", $path);
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,8 @@ class Searchbar extends FHCAPI_Controller
|
||||
'searchCis' => self::PERM_LOGGED,
|
||||
'searchStv' => self::PERM_LOGGED
|
||||
]);
|
||||
|
||||
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
@@ -103,6 +105,17 @@ class Searchbar extends FHCAPI_Controller
|
||||
// Convert to json the result from searchlib->search
|
||||
$result = $this->searchlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM));
|
||||
|
||||
$this->WebservicelogModel->insert(array(
|
||||
'webservicetyp_kurzbz' => 'content',
|
||||
'beschreibung' => $config['config'],
|
||||
'request_data' => json_encode(array(
|
||||
self::SEARCHSTR_PARAM => $this->input->post(self::SEARCHSTR_PARAM),
|
||||
self::TYPES_PARAM => $this->input->post(self::TYPES_PARAM)
|
||||
)),
|
||||
'execute_user' => getAuthUID(),
|
||||
'execute_time' => 'NOW()'
|
||||
));
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->addMeta('time', $result->meta['time']);
|
||||
|
||||
@@ -60,7 +60,11 @@ class BetriebsmittelP extends FHCAPI_Controller
|
||||
|
||||
public function getAllBetriebsmittel($type_id, $id)
|
||||
{
|
||||
$result = $this->BetriebsmittelpersonModel->getBetriebsmittelData($id, $type_id);
|
||||
$betriebsmitteltypes = null;
|
||||
if ($this->input->get('betriebsmitteltypes') !== null && !isEmptyArray($this->input->get('betriebsmitteltypes')))
|
||||
$betriebsmitteltypes = $this->input->get('betriebsmitteltypes');
|
||||
|
||||
$result = $this->BetriebsmittelpersonModel->getBetriebsmittelData($id, $type_id, $betriebsmitteltypes);
|
||||
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
@@ -370,6 +374,12 @@ class BetriebsmittelP extends FHCAPI_Controller
|
||||
$this->load->model('ressource/Betriebsmitteltyp_model', 'BetriebsmitteltypModel');
|
||||
|
||||
$this->BetriebsmitteltypModel->addOrder('beschreibung', 'ASC');
|
||||
|
||||
if ($this->input->get('betriebsmitteltypes') !== null && !isEmptyArray($this->input->get('betriebsmitteltypes')))
|
||||
{
|
||||
$this->BetriebsmitteltypModel->db->where_in('betriebsmitteltyp', $this->input->get('betriebsmitteltypes'));
|
||||
}
|
||||
|
||||
$result = $this->BetriebsmitteltypModel->load(); // load All
|
||||
|
||||
if (isError($result)) {
|
||||
|
||||
@@ -418,6 +418,10 @@ class Messages extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
if (count($data) < 1)
|
||||
{
|
||||
$this->terminateWithError('Error: Messages API no person_id found.');
|
||||
}
|
||||
$person = current($data);
|
||||
|
||||
return $person->person_id;
|
||||
@@ -432,8 +436,12 @@ class Messages extends FHCAPI_Controller
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
if (count($data) < 1)
|
||||
{
|
||||
$this->terminateWithError('Error: Messages API no prestudent_id found.');
|
||||
}
|
||||
$student = current($data);
|
||||
// $this->terminateWithError($student->prestudent_id, self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $student->prestudent_id;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ class NotizPerson extends Notiz_Controller
|
||||
'loadDokumente' => ['admin:r', 'assistenz:r'],
|
||||
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
|
||||
'isBerechtigt' => ['admin:r', 'assistenz:r'],
|
||||
'getCountNotes' => ['admin:r', 'assistenz:r'],
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -62,10 +62,15 @@ class Config extends FHCAPI_Controller
|
||||
'component' => './Stv/Studentenverwaltung/Details/Details.js',
|
||||
'config' => $config['details']
|
||||
];
|
||||
|
||||
$result['notes'] = [
|
||||
'title' => $this->p->t('stv', 'tab_notes'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Notizen.js'
|
||||
'component' => './Stv/Studentenverwaltung/Details/Notizen.js',
|
||||
'config' => $config['notes'],
|
||||
'showSuffix' => ($config['notes']['showCountNotes'] ?? false),
|
||||
'suffixhelper' => APP_ROOT . 'public/js/helpers/Stv/Studentenverwaltung/Details/Notizen/NotizenSuffixHelper.js'
|
||||
];
|
||||
|
||||
$result['contact'] = [
|
||||
'title' => $this->p->t('stv', 'tab_contact'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Kontakt.js',
|
||||
@@ -179,7 +184,9 @@ class Config extends FHCAPI_Controller
|
||||
return $result;
|
||||
});
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
$sortConfig = $this->config->item('student_tab_order');
|
||||
|
||||
$this->terminateWithSuccess($this->sortTabList($result, $sortConfig));
|
||||
}
|
||||
|
||||
public function students()
|
||||
@@ -226,7 +233,9 @@ class Config extends FHCAPI_Controller
|
||||
return $result;
|
||||
});
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
$sortConfig = $this->config->item('students_tab_order');
|
||||
|
||||
$this->terminateWithSuccess($this->sortTabList($result, $sortConfig));
|
||||
}
|
||||
|
||||
protected function kontoColumns()
|
||||
@@ -502,4 +511,34 @@ class Config extends FHCAPI_Controller
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort tab list
|
||||
*
|
||||
* @param array $input
|
||||
* @param array $config
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function sortTabList($input, $config)
|
||||
{
|
||||
// prepare config
|
||||
if (!$config || !is_array($config))
|
||||
$config = [];
|
||||
else
|
||||
$config = array_flip($config);
|
||||
|
||||
// fill missing items in config
|
||||
foreach (array_keys($input) as $key) {
|
||||
if (!isset($config[$key]))
|
||||
$config[$key] = count($config);
|
||||
}
|
||||
|
||||
// do the sorting
|
||||
uksort($input, function ($a, $b) use ($config) {
|
||||
return $config[$a] - $config[$b];
|
||||
});
|
||||
|
||||
return $input;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,6 @@ class Favorites extends FHCAPI_Controller
|
||||
|
||||
// Load models
|
||||
$this->load->model('system/Variable_model', 'VariableModel');
|
||||
|
||||
// TODO(chris): variable table might be to small to store favorites!
|
||||
}
|
||||
|
||||
public function index()
|
||||
@@ -62,6 +60,17 @@ class Favorites extends FHCAPI_Controller
|
||||
|
||||
$favorites = $this->input->post('favorites');
|
||||
|
||||
$removed = [];
|
||||
while (strlen($favorites) > 64) {
|
||||
$favObj = json_decode($favorites);
|
||||
if (!$favObj->list)
|
||||
break;
|
||||
$removed[] = array_shift($favObj->list);
|
||||
$favorites = json_encode($favObj);
|
||||
}
|
||||
if ($removed)
|
||||
$this->addMeta('removed', $removed);
|
||||
|
||||
$result = $this->VariableModel->setVariable(getAuthUID(), 'stv_favorites', $favorites);
|
||||
|
||||
$this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -16,7 +16,8 @@ class Notiz extends Notiz_Controller
|
||||
'updateNotiz' => ['admin:rw', 'assistenz:rw'], // TODO(manu): self::PERM_LOGGED
|
||||
'deleteNotiz' => ['admin:r', 'assistenz:r'],
|
||||
'loadDokumente' => ['admin:r', 'assistenz:r'],
|
||||
'getMitarbeiter' => ['admin:r', 'assistenz:r']
|
||||
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
|
||||
'getCountNotes' => ['admin:r', 'assistenz:r'],
|
||||
]);
|
||||
|
||||
//Load Models
|
||||
|
||||
@@ -24,7 +24,6 @@ class Status extends FHCAPI_Controller
|
||||
'updateStatus' => ['admin:rw', 'assistenz:rw'],
|
||||
'advanceStatus' => ['admin:rw', 'assistenz:rw'],
|
||||
'confirmStatus' => ['admin:rw', 'assistenz:rw'],
|
||||
|
||||
]);
|
||||
|
||||
//Load Models
|
||||
@@ -440,9 +439,10 @@ class Status extends FHCAPI_Controller
|
||||
]);
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
{
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
}
|
||||
|
||||
|
||||
$this->load->library('PrestudentLib');
|
||||
|
||||
$this->db->trans_start();
|
||||
@@ -628,8 +628,9 @@ class Status extends FHCAPI_Controller
|
||||
]);
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
{
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
}
|
||||
|
||||
// Start DB transaction
|
||||
$this->db->trans_start();
|
||||
|
||||
@@ -106,6 +106,7 @@ class Student extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect('p.staatsbuergerschaft');
|
||||
$this->PrestudentModel->addSelect('p.matr_nr');
|
||||
$this->PrestudentModel->addSelect('p.anrede');
|
||||
$this->PrestudentModel->addSelect('p.zugangscode');
|
||||
|
||||
if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) {
|
||||
$this->PrestudentModel->addSelect(
|
||||
@@ -253,7 +254,6 @@ class Student extends FHCAPI_Controller
|
||||
'gebdatum',
|
||||
'gebort',
|
||||
'geburtsnation',
|
||||
'svnr',
|
||||
'ersatzkennzeichen',
|
||||
'staatsbuergerschaft',
|
||||
'matr_nr',
|
||||
@@ -698,7 +698,7 @@ class Student extends FHCAPI_Controller
|
||||
return $result;
|
||||
}*/
|
||||
|
||||
$this->terminateWithSuccess(true);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
public function requiredIfNotPersonId($value)
|
||||
@@ -714,4 +714,9 @@ class Student extends FHCAPI_Controller
|
||||
return true;
|
||||
return !!$value;
|
||||
}
|
||||
|
||||
public function isValidDate($value)
|
||||
{
|
||||
return isValidDate($value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -761,7 +761,6 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect('wahlname');
|
||||
$this->PrestudentModel->addSelect('vornamen');
|
||||
$this->PrestudentModel->addSelect('titelpost');
|
||||
$this->PrestudentModel->addSelect('svnr');
|
||||
$this->PrestudentModel->addSelect('ersatzkennzeichen');
|
||||
$this->PrestudentModel->addSelect('gebdatum');
|
||||
$this->PrestudentModel->addSelect('geschlecht');
|
||||
|
||||
@@ -188,6 +188,7 @@ class Verband extends FHCAPI_Controller
|
||||
array_unshift($list, [
|
||||
'name' => 'PreStudent',
|
||||
'link' => $link . 'prestudent',
|
||||
'stg_kz' => (int)$studiengang_kz,
|
||||
'children' => $this->getStdSem($link . 'prestudent/', $studiengang_kz)
|
||||
]);
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class UHSTAT1 extends FHC_Controller
|
||||
const CODEX_UNKNOWN_YEAR = 9999;
|
||||
const CODEX_UNKNOWN_NATION = 'XXX';
|
||||
const CODEX_UNKNOWN_BILDUNGMAX = 999;
|
||||
const CODEX_EXCLUDED_NATIONS = ['ZZZ'];
|
||||
const LOWER_BOUNDARY_YEARS = 160;
|
||||
const UPPER_BOUNDARY_YEARS = 20;
|
||||
|
||||
@@ -32,8 +33,7 @@ class UHSTAT1 extends FHC_Controller
|
||||
$this->load->library('PermissionLib');
|
||||
|
||||
// load models
|
||||
$this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel');
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
$this->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
$this->load->model('system/Sprache_model', 'SpracheModel');
|
||||
$this->load->model('codex/Abschluss_model', 'AbschlussModel');
|
||||
$this->load->model('codex/Uhstat1daten_model', 'Uhstat1datenModel');
|
||||
@@ -104,7 +104,7 @@ class UHSTAT1 extends FHC_Controller
|
||||
{
|
||||
$saved = false;
|
||||
|
||||
$person_id = $this->_getValidPersonId('sui');
|
||||
$person_id = $this->_getUHSTATPersonId('sui');
|
||||
|
||||
$this->form_validation->set_error_delimiters('<span class="text-danger">', '</span>');
|
||||
|
||||
@@ -245,7 +245,7 @@ class UHSTAT1 extends FHC_Controller
|
||||
// uhstat data can only be deleted with permission
|
||||
if (!$this->_checkPermission('suid')) show_error('no permission');
|
||||
|
||||
$person_id = $this->_getValidPersonId('suid');
|
||||
$person_id = $this->_getUHSTATPersonId('suid');
|
||||
|
||||
$uhstat1datenRes = $this->Uhstat1datenModel->delete(
|
||||
array('person_id' => $person_id)
|
||||
@@ -287,13 +287,17 @@ class UHSTAT1 extends FHC_Controller
|
||||
*/
|
||||
private function _getFormMetaData()
|
||||
{
|
||||
$person_id = $this->_getValidPersonId('s');
|
||||
$person_id = $this->_getUHSTATPersonId('s');
|
||||
|
||||
// read only display param
|
||||
$readOnly = $this->input->get('readOnly');
|
||||
|
||||
// depending on permissions, editing or deleting is possible
|
||||
$editPermission = $this->_checkPermission('sui');
|
||||
// checking permissions for form
|
||||
|
||||
// saving is possible if there permission or student log in (but not from application tool)
|
||||
$savePermission = $this->_checkPermission('sui') || ($this->_getUserPersonId() && !$this->_getApplicationToolPersonId());
|
||||
|
||||
// deleting only possible with permission
|
||||
$deletePermission = $this->_checkPermission('suid');
|
||||
|
||||
$languageIdx = $this->_getLanguageIndex();
|
||||
@@ -304,7 +308,7 @@ class UHSTAT1 extends FHC_Controller
|
||||
'abschluss_nicht_oesterreich' => array(),
|
||||
'jahre' => array(),
|
||||
'person_id' => $person_id,
|
||||
'editPermission' => $editPermission,
|
||||
'savePermission' => $savePermission,
|
||||
'deletePermission' => $deletePermission,
|
||||
'readOnly' => $readOnly
|
||||
);
|
||||
@@ -336,15 +340,19 @@ class UHSTAT1 extends FHC_Controller
|
||||
|
||||
if (hasData($nationRes))
|
||||
{
|
||||
$dropdownNations = [];
|
||||
$nations = getData($nationRes);
|
||||
|
||||
// put austria in beginning of selection
|
||||
foreach ($nations as $nation)
|
||||
{
|
||||
if ($nation->nation_code == self::CODEX_OESTERREICH) array_unshift($nations, $nation);
|
||||
// put austria in beginning of selection
|
||||
if ($nation->nation_code == self::CODEX_OESTERREICH)
|
||||
array_unshift($dropdownNations, $nation);
|
||||
elseif (!in_array($nation->nation_code, self::CODEX_EXCLUDED_NATIONS)) // add nation if not excluded
|
||||
$dropdownNations[] = $nation;
|
||||
}
|
||||
|
||||
$formMetaData['nation'] = $nations;
|
||||
$formMetaData['nation'] = $dropdownNations;
|
||||
}
|
||||
|
||||
// get abschluss list
|
||||
@@ -386,7 +394,7 @@ class UHSTAT1 extends FHC_Controller
|
||||
*/
|
||||
private function _getUHSTAT1Data()
|
||||
{
|
||||
$person_id = $this->_getValidPersonId('s');
|
||||
$person_id = $this->_getUHSTATPersonId('s');
|
||||
|
||||
$this->Uhstat1datenModel->addSelect(
|
||||
implode(', ', array_keys($this->_uhstat1Fields))
|
||||
@@ -417,29 +425,70 @@ class UHSTAT1 extends FHC_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Id of person having permissions to manage UHSTAT1 data.
|
||||
* Can be passed as parameter or be in session.
|
||||
* Gets Id of person, for which UHSTAT1 data is edited.
|
||||
* Can be passed as parameter, id of logged in person, or be in session.
|
||||
* @param berechtigungsArt type of permission (suid)
|
||||
* @return int person_id
|
||||
*/
|
||||
private function _getValidPersonId($berechtigungsArt)
|
||||
private function _getUHSTATPersonId($berechtigungsArt)
|
||||
{
|
||||
// if coming from bewerbungstool - person id is in session (person must be logged in bewerbungstool)
|
||||
$applicationToolPersonId = $this->_getApplicationToolPersonId();
|
||||
if (isset($applicationToolPersonId) && is_numeric($applicationToolPersonId)) return $applicationToolPersonId;
|
||||
|
||||
// if successfully logged in
|
||||
$loggedInPersonId = $this->_getUserPersonId();
|
||||
if (isset($loggedInPersonId) && is_numeric($loggedInPersonId))
|
||||
{
|
||||
// if person id passed directly...
|
||||
$person_id = $this->input->post('person_id');
|
||||
if (!isset($person_id)) $person_id = $this->input->get('person_id');
|
||||
|
||||
if (isset($person_id))
|
||||
{
|
||||
if (!is_numeric($person_id)) show_error("invalid person id");
|
||||
// ...check if there is a permission for editing UHSTAT1 data
|
||||
if ($this->_checkPermission($berechtigungsArt)) return $person_id;
|
||||
}
|
||||
|
||||
// if no id passed, use logged in person id
|
||||
return $loggedInPersonId;
|
||||
}
|
||||
|
||||
show_error("No permission");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets person Id if there is a application tool login.
|
||||
* @return person Id or null
|
||||
*/
|
||||
private function _getApplicationToolPersonId()
|
||||
{
|
||||
// if coming from aplication tool - person id is in session (person must be logged in bewerbungstool)
|
||||
if (isset($_SESSION[self::PERSON_ID_SESSION_INDEX])
|
||||
&& is_numeric($_SESSION[self::PERSON_ID_SESSION_INDEX])
|
||||
&& isset($_SESSION[self::LOGIN_SESSION_INDEX])
|
||||
)
|
||||
return $_SESSION[self::PERSON_ID_SESSION_INDEX];
|
||||
|
||||
// if person id passed directly...
|
||||
$person_id = $this->input->post('person_id');
|
||||
if (!isset($person_id)) $person_id = $this->input->get('person_id');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($person_id) || !is_numeric($person_id)) show_error("invalid person id");
|
||||
|
||||
// ...check if there is a permission for editing UHSTAT1 data
|
||||
if ($this->_checkPermission($berechtigungsArt)) return $person_id;
|
||||
|
||||
show_error("No permission");
|
||||
/**
|
||||
* Gets person Id if there is a user login.
|
||||
* @return person Id or null
|
||||
*/
|
||||
private function _getUserPersonId()
|
||||
{
|
||||
$loggedInPersonId = getAuthPersonId();
|
||||
if (isset($loggedInPersonId) && is_numeric($loggedInPersonId))
|
||||
{
|
||||
// check if the the user is a student and if the benutzer is active
|
||||
$this->BenutzerModel->addSelect('1');
|
||||
$res = $this->BenutzerModel->loadWhere(["public.tbl_benutzer.person_id" => $loggedInPersonId, "public.tbl_benutzer.aktiv" => TRUE]);
|
||||
if (hasData($res)) return $loggedInPersonId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1275,7 +1275,6 @@ class InfoCenter extends Auth_Controller
|
||||
'nachname' => $this->input->post('nachname'),
|
||||
'titelpost' => isEmptyString($this->input->post('titelpost')) ? null : $this->input->post('titelpost'),
|
||||
'gebdatum' => isEmptyString($this->input->post('gebdatum')) ? null : date("Y-m-d", strtotime($this->input->post('gebdatum'))),
|
||||
'svnr' => isEmptyString($this->input->post('svnr')) ? null : $this->input->post('svnr'),
|
||||
'staatsbuergerschaft' => isEmptyString($this->input->post('buergerschaft')) ? null : $this->input->post('buergerschaft'),
|
||||
'geschlecht' => $this->input->post('geschlecht'),
|
||||
'geburtsnation' => isEmptyString($this->input->post('gebnation')) ? null : $this->input->post('gebnation'),
|
||||
@@ -1816,7 +1815,7 @@ class InfoCenter extends Auth_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all necessary Person data: Stammdaten (name, svnr, contact, ...), Dokumente, Logs and Notizen
|
||||
* Loads all necessary Person data: Stammdaten (name, contact, ...), Dokumente, Logs and Notizen
|
||||
* @param $person_id
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -21,6 +21,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
|
||||
'loadDokumente' => self::DEFAULT_PERMISSION_R,
|
||||
'getMitarbeiter' => self::DEFAULT_PERMISSION_R,
|
||||
'isBerechtigt' => self::DEFAULT_PERMISSION_R,
|
||||
'getCountNotes' => self::DEFAULT_PERMISSION_R,
|
||||
];
|
||||
|
||||
if(!is_array($permissions))
|
||||
@@ -459,4 +460,20 @@ abstract class Notiz_Controller extends FHCAPI_Controller
|
||||
return $this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
public function getCountNotes($person_id)
|
||||
{
|
||||
$this->NotizzuordnungModel->addSelect('COUNT(*) AS anzahl', false);
|
||||
|
||||
$result = $this->NotizzuordnungModel->loadWhere(
|
||||
array('person_id' => $person_id)
|
||||
);
|
||||
|
||||
if (isError($result)) {
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$anzahl = current(getData($result));
|
||||
return $this->terminateWithSuccess($anzahl->anzahl ?: 0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -670,7 +670,7 @@ class DmsLib
|
||||
$fileObj = new stdClass();
|
||||
$fileObj->filename = getData($result)[0]->filename;
|
||||
$fileObj->file = DMS_PATH.getData($result)[0]->filename;
|
||||
$fileObj->name = DMS_PATH.getData($result)[0]->name; // original user filename
|
||||
$fileObj->name = getData($result)[0]->name; // original user filename
|
||||
$fileObj->mimetype = getData($result)[0]->mimetype;
|
||||
|
||||
return success($fileObj);
|
||||
|
||||
@@ -122,6 +122,7 @@ class PhrasesLib
|
||||
$tmpText = substr($tmpText, 0, strlen($tmpText) - 4);
|
||||
}
|
||||
}
|
||||
$tmpText = str_replace(['<span class="caps">', '</span>'], '', $tmpText);
|
||||
|
||||
$result->retval[$i]->text = $tmpText;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ class GehaltsbestandteilLib
|
||||
$this->CI = get_instance();
|
||||
$this->CI->load->model('vertragsbestandteil/Gehaltsbestandteil_model',
|
||||
'GehaltsbestandteilModel');
|
||||
$this->CI->load->library('extensions/FHC-Core-Personalverwaltung/abrechnung/GehaltsLib');
|
||||
$this->GehaltsbestandteilModel = $this->CI->GehaltsbestandteilModel;
|
||||
}
|
||||
|
||||
@@ -121,10 +120,6 @@ class GehaltsbestandteilLib
|
||||
{
|
||||
$this->setUIDtoPGSQL();
|
||||
|
||||
// delete Gehaltsabrechnung
|
||||
$ret = $this->CI->gehaltslib->deleteAbrechnung($gehaltsbestandteil);
|
||||
|
||||
//
|
||||
$ret = $this->GehaltsbestandteilModel->delete($gehaltsbestandteil->getGehaltsbestandteil_id());
|
||||
|
||||
if (isError($ret))
|
||||
|
||||
@@ -28,6 +28,11 @@ class Lehreinheit_model extends DB_Model
|
||||
{
|
||||
$lehreinheiten = array();
|
||||
|
||||
$this->addSelect(
|
||||
'lehreinheit_id, lehrveranstaltung_id, studiensemester_kurzbz, lehrform_kurzbz,
|
||||
stundenblockung, wochenrythmus, start_kw, raumtyp, raumtypalternativ,
|
||||
sprache, lehre, unr, lvnr, lehrfach_id, gewicht'
|
||||
);
|
||||
$this->addOrder('lehreinheit_id');
|
||||
$les = $this->loadWhere(
|
||||
array('lehrveranstaltung_id' => $lehrveranstaltung_id,
|
||||
|
||||
@@ -97,7 +97,7 @@ class Betriebsmittelperson_model extends DB_Model
|
||||
return $this->loadWhere($condition);
|
||||
}
|
||||
|
||||
public function getBetriebsmittelData($id, $type_id)
|
||||
public function getBetriebsmittelData($id, $type_id, $betriesmitteltypes = null)
|
||||
{
|
||||
switch ($type_id) {
|
||||
case 'person_id':
|
||||
@@ -113,6 +113,15 @@ class Betriebsmittelperson_model extends DB_Model
|
||||
return error("ID nicht gültig");
|
||||
}
|
||||
|
||||
$cond .= " = ? ";
|
||||
$params[] = $id;
|
||||
|
||||
if ($betriesmitteltypes && !isEmptyArray($betriesmitteltypes))
|
||||
{
|
||||
$cond .= " AND bm.betriebsmitteltyp IN ?";
|
||||
$params[] = $betriesmitteltypes;
|
||||
}
|
||||
|
||||
$query = "
|
||||
SELECT
|
||||
bm.nummer, bmp.person_id, bm.betriebsmitteltyp, bmp.anmerkung as anmerkung,
|
||||
@@ -126,9 +135,9 @@ class Betriebsmittelperson_model extends DB_Model
|
||||
JOIN
|
||||
wawi.tbl_betriebsmittel bm ON (bmp.betriebsmittel_id = bm.betriebsmittel_id)
|
||||
WHERE
|
||||
" . $cond . " = ? ";
|
||||
" . $cond;
|
||||
|
||||
return $this->execQuery($query, array($id));
|
||||
return $this->execQuery($query, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ $vater_bildungsstaat = isset($uhstatData->vater_bildungsstaat) ? $uhstatData->va
|
||||
$vater_bildungmax = isset($uhstatData->vater_bildungmax) ? $uhstatData->vater_bildungmax : set_value('vater_bildungmax');
|
||||
$readOnly = isset($formMetaData['readOnly']);
|
||||
$disabled = $readOnly ? ' disabled' : '';
|
||||
$editPermission = isset($formMetaData['editPermission']) && $formMetaData['editPermission'] === true;
|
||||
$savePermission = isset($formMetaData['savePermission']) && $formMetaData['savePermission'] === true;
|
||||
$deletePermission = isset($formMetaData['deletePermission']) && $formMetaData['deletePermission'] === true;
|
||||
$saved = isset($saved) && $saved === true;
|
||||
?>
|
||||
@@ -51,7 +51,7 @@ $saved = isset($saved) && $saved === true;
|
||||
<?php echo $this->p->t('uhstat', 'uhstat1EinleitungSvnrtext') ?>
|
||||
</p>
|
||||
<br>
|
||||
<?php if ($editPermission): ?>
|
||||
<?php if ($savePermission): ?>
|
||||
<?php if (isset($successMessage) && !isEmptyString($successMessage)): ?>
|
||||
<div class="alert alert-success" id="uhstat_success_alert">
|
||||
<button type="button" class="close" data-dismiss="alert">x</button>
|
||||
@@ -288,7 +288,7 @@ $saved = isset($saved) && $saved === true;
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<?php if ($editPermission && !$readOnly): ?>
|
||||
<?php if ($savePermission && !$readOnly): ?>
|
||||
<br>
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
|
||||
@@ -32,12 +32,6 @@
|
||||
<div class='stammdaten' id="gebdatum"><?php echo date_format(date_create($stammdaten->gebdatum), 'd.m.Y') ?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php echo ucfirst($this->p->t('person','svnr')) ?></strong></td>
|
||||
<td>
|
||||
<div class='stammdaten' id="svnr"><?php echo $stammdaten->svnr ?></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong><?php echo ucfirst($this->p->t('person','staatsbuergerschaft')) ?></strong></td>
|
||||
<td>
|
||||
|
||||
@@ -843,7 +843,6 @@ function meine_uid_informationen_detail($db,$uid,$count=0)
|
||||
|
||||
$aktiv=$db->db_result($erg,0,"aktiv");
|
||||
|
||||
$svnr=$db->db_result($erg,0,"svnr");
|
||||
|
||||
$titelpre=$db->db_result($erg,0,"titelpre");
|
||||
$titelpost=$db->db_result($erg,0,"titelpost");
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
require_once('../../config/cis.config.inc.php');
|
||||
|
||||
if (isset($_COOKIE['fhclogout']) && ($_COOKIE['fhclogout'] === 'fhclogout'))
|
||||
{
|
||||
setcookie('fhclogout', '', -1, '/');
|
||||
http_response_code(401);
|
||||
header('WWW-Authenticate: Basic realm="' . AUTH_NAME . '"');
|
||||
?>
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>FH-Complete logout Basic Auth</title>
|
||||
<meta http-equiv="refresh" content="2; url=<?php echo APP_ROOT . 'cis/'; ?>"/>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function logout()
|
||||
{
|
||||
console.log('FH-Complete logout Basic Auth');
|
||||
window.location.href = '<?php echo APP_ROOT . 'cis/'; ?>';
|
||||
}
|
||||
|
||||
logout();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<?php
|
||||
}
|
||||
else
|
||||
{
|
||||
http_response_code(303);
|
||||
header('Location:' . APP_ROOT . 'cis/');
|
||||
}
|
||||
@@ -285,15 +285,16 @@ function showHideBezeichnungDropDown()
|
||||
if (dd.options[dd.selectedIndex].value == 'DienstV')
|
||||
{
|
||||
var str = '<select name="bezeichnung" class="dd_breit">';
|
||||
str += '<option value="Eheschließung">a) Eigene Eheschließung (3 Tage)</option>';
|
||||
str += '<option value="Eheschließung">a) Eigene Eheschließung oder Verpartnerung (3 Tage)</option>';
|
||||
str += '<option value="Geburt eigenes Kind">b) Geburt eines Kindes der Ehefrau/Lebensgefährtin (2 Tage)</option>';
|
||||
str += '<option value="Heirat Kind/Geschwister">c) Eheschließung eines Kindes/eigener Geschwister (1 Tag)</option>';
|
||||
str += '<option value="Heirat Kind/Geschwister">c) Eheschließung oder Verpartnerung eines Kindes/eigener Geschwister (1 Tag)</option>';
|
||||
str += '<option value="Eigene Sponsion/Promotion">d) Teilnahme an eigener Sponsion/Promotion (1 Tag)</option>';
|
||||
str += '<option value="Lebensbedr. Erkrankung P/K/E">e) Lebensbedrohliche Erkrankung Partner/Kinder/Eltern (3 Tage)</option>';
|
||||
str += '<option value="Ableben P/K/E">f) Ableben Partner/Kinder/Elternteil (3 Tage)</option>';
|
||||
str += '<option value="Bestattung G/S/G">g) Teilnahme an Bestattung Geschwister/Schwiegereltern/eigener Großeltern (1 Tag)</option>';
|
||||
str += '<option value="Wohnungswechsel">h) Wohnungswechsel in eigenen Haushalt (2 Tage)</option>';
|
||||
str += '<option value="Bundesheer">i) Einberufung Bundesheer</option>';
|
||||
str += '<option value="Volksschultag">j) erster Volksschultag (1 Tag)</option>';
|
||||
str += '</select>';
|
||||
|
||||
sp.innerHTML = str;
|
||||
|
||||
@@ -45,6 +45,7 @@ require_once('../../../include/benutzerberechtigung.class.php');
|
||||
require_once('../../../include/zeitaufzeichnung_import_csv.class.php');
|
||||
require_once('../../../include/zeitaufzeichnung_import_post.class.php');
|
||||
require_once('../../../include/vertragsbestandteil.class.php');
|
||||
require_once('../../../include/benutzerfunktion.class.php');
|
||||
|
||||
$sprache = getSprache();
|
||||
$p=new phrasen($sprache);
|
||||
@@ -112,6 +113,13 @@ else
|
||||
$activities = array('Admin', 'FuE','FuEallg','Lehre', 'Pause', 'Arztbesuch', 'DienstreiseMT', 'Behoerde', 'Ersatzruhe', 'Weiterbildung', 'LVEntwicklung');
|
||||
}
|
||||
|
||||
// Wenn die Funktion Lehrling zugeteilt ist, kann zusaetzlich Berufsschule als Aktivitaet gewaehlt werden
|
||||
$benutzerfunktion = new benutzerfunktion();
|
||||
if ($benutzerfunktion->benutzerfunktion_exists($user, 'lehrling', true))
|
||||
{
|
||||
$activities[] = 'Berufsschule';
|
||||
}
|
||||
|
||||
$activities_str = "'".implode("','", $activities)."'";
|
||||
|
||||
// definiert bis zu welchem Datum die Eintragung nicht mehr möglich ist
|
||||
@@ -690,7 +698,7 @@ echo '
|
||||
function checkPausenblock()
|
||||
{
|
||||
var sel = $("#aktivitaet").val();
|
||||
var activities = ["Admin", "Lehre", "FuE", "Operativ", "Betrieb", "Design", "LVEntwicklung", "Weiterbildung", "FuEallg"];
|
||||
var activities = ["Admin", "Lehre", "FuE", "Operativ", "Betrieb", "Design", "LVEntwicklung", "Weiterbildung", "FuEallg", "Berufsschule"];
|
||||
if (activities.includes(sel))
|
||||
showPausenblock();
|
||||
else
|
||||
|
||||
@@ -307,8 +307,6 @@ foreach($prestudent_ids as $pid)
|
||||
$nation->load($prestudent->zgvnation);
|
||||
$zgvnation = $nation->kurztext;
|
||||
|
||||
$svnr = ($prestudent->svnr == '')?($prestudent->ersatzkennzeichen != ''?'Ersatzkennzeichen: '.$prestudent->ersatzkennzeichen:''):$prestudent->svnr;
|
||||
|
||||
foreach($adresse->result as $row_adresse)
|
||||
{
|
||||
if($row_adresse->heimatadresse)
|
||||
@@ -439,7 +437,6 @@ foreach($prestudent_ids as $pid)
|
||||
'zustell_ort' => $zustellOrt,
|
||||
'zustell_bundesland' => $zustellBundesland,
|
||||
'geburtsnation' => $geburtsnation,
|
||||
'svnr' => $svnr,
|
||||
'staatsbuergerschaft' => $staatsbuergerschaft,
|
||||
'geschlecht' => $prestudent->geschlecht,
|
||||
'telefonnummer' => $telefonnummer,
|
||||
|
||||
@@ -125,8 +125,6 @@ $worksheet->write($zeile, ++$i, "PERSONENKENNZEICHEN", $format_bold);
|
||||
$maxlength[$i] = 19;
|
||||
$worksheet->write($zeile, ++$i, "STAATSBÜRGERSCHAFT", $format_bold);
|
||||
$maxlength[$i] = 16;
|
||||
$worksheet->write($zeile, ++$i, "SVNR", $format_bold);
|
||||
$maxlength[$i] = 4;
|
||||
$worksheet->write($zeile, ++$i, "PERSON_ID", $format_bold);
|
||||
$maxlength[$i] = 6;
|
||||
$worksheet->write($zeile, ++$i, "ERSATZKENNZEICHEN", $format_bold);
|
||||
@@ -396,12 +394,7 @@ function draw_content($row)
|
||||
$worksheet->write($zeile, $i, $row->staatsbuergerschaft);
|
||||
$i++;
|
||||
|
||||
//SVNR
|
||||
if (mb_strlen($row->svnr) > $maxlength[$i])
|
||||
$maxlength[$i] = mb_strlen($row->svnr);
|
||||
$worksheet->write($zeile, $i, $row->svnr);
|
||||
$i++;
|
||||
|
||||
|
||||
//Person_id
|
||||
if (mb_strlen($row->person_id) > $maxlength[$i])
|
||||
$maxlength[$i] = mb_strlen($row->person_id);
|
||||
|
||||
@@ -594,7 +594,6 @@ if(!$error)
|
||||
$student->anmerkungen = $_POST['anmerkung'];
|
||||
$student->homepage = $_POST['homepage'];
|
||||
$student->matr_nr = $_POST['matr_nr'];
|
||||
$student->svnr = $_POST['svnr'];
|
||||
$student->ersatzkennzeichen = $_POST['ersatzkennzeichen'];
|
||||
$student->familienstand = $_POST['familienstand'];
|
||||
$student->geschlecht = $_POST['geschlecht'];
|
||||
@@ -746,7 +745,6 @@ if(!$error)
|
||||
$person->gebzeit = $_POST['geburtszeit'];
|
||||
$person->anmerkungen = $_POST['anmerkung'];
|
||||
$person->homepage = $_POST['homepage'];
|
||||
$person->svnr = $_POST['svnr'];
|
||||
$person->ersatzkennzeichen = $_POST['ersatzkennzeichen'];
|
||||
$person->familienstand = $_POST['familienstand'];
|
||||
$person->geschlecht = $_POST['geschlecht'];
|
||||
|
||||
@@ -134,8 +134,7 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
|
||||
|
||||
</row>
|
||||
<row>
|
||||
<label value="SVNR" control="student-detail-textbox-svnr"/>
|
||||
<hbox><textbox id="student-detail-textbox-svnr" disabled="true" maxlength="16" size="10"/></hbox>
|
||||
|
||||
<label value="Ersatzkennzeichen" control="student-detail-textbox-ersatzkennzeichen"/>
|
||||
<hbox><textbox id="student-detail-textbox-ersatzkennzeichen" disabled="true" maxlength="10" size="15"/></hbox>
|
||||
<label value="Geburtszeit" control="student-detail-textbox-geburtszeit" hidden="true"/>
|
||||
|
||||
@@ -284,10 +284,6 @@ else
|
||||
class="sortDirectionIndicator"
|
||||
sort="rdf:http://www.technikum-wien.at/student/rdf#titelpost" onclick="StudentTreeSort()"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="student-treecol-svnr" label="SVNR" flex="1" hidden="false" persist="hidden, width, ordinal"
|
||||
class="sortDirectionIndicator"
|
||||
sort="rdf:http://www.technikum-wien.at/student/rdf#svnr" onclick="StudentTreeSort()"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol id="student-treecol-ersatzkennzeichen" label="Ersatzkennzeichen" flex="1" hidden="false" persist="hidden, width, ordinal"
|
||||
class="sortDirectionIndicator"
|
||||
sort="rdf:http://www.technikum-wien.at/student/rdf#ersatzkennzeichen" onclick="StudentTreeSort()"/>
|
||||
@@ -445,7 +441,6 @@ else
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#wahlname" />
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#vornamen" />
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#titelpost" />
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#svnr" />
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#ersatzkennzeichen" />
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#geburtsdatum" />
|
||||
<treecell properties="Aktiv_rdf:http://www.technikum-wien.at/student/rdf#aktiv" label="rdf:http://www.technikum-wien.at/student/rdf#geschlecht" />
|
||||
|
||||
@@ -786,7 +786,6 @@ function StudentDetailReset()
|
||||
document.getElementById('student-detail-textbox-geburtszeit').value='';
|
||||
document.getElementById('student-detail-textbox-anmerkung').value='';
|
||||
document.getElementById('student-detail-textbox-homepage').value='';
|
||||
document.getElementById('student-detail-textbox-svnr').value='';
|
||||
document.getElementById('student-detail-textbox-ersatzkennzeichen').value='';
|
||||
document.getElementById('student-detail-menulist-familienstand').value='l';
|
||||
document.getElementById('student-detail-menulist-geschlecht').value='m';
|
||||
@@ -819,7 +818,6 @@ function StudentDetailDisableFields(val)
|
||||
document.getElementById('student-detail-textbox-geburtszeit').disabled=val;
|
||||
document.getElementById('student-detail-textbox-anmerkung').disabled=val;
|
||||
document.getElementById('student-detail-textbox-homepage').disabled=val;
|
||||
document.getElementById('student-detail-textbox-svnr').disabled=val;
|
||||
document.getElementById('student-detail-textbox-ersatzkennzeichen').disabled=val;
|
||||
document.getElementById('student-detail-menulist-familienstand').disabled=val;
|
||||
document.getElementById('student-detail-menulist-geschlecht').disabled=val;
|
||||
@@ -860,7 +858,6 @@ function StudentDetailSave()
|
||||
geburtszeit = document.getElementById('student-detail-textbox-geburtszeit').value;
|
||||
anmerkung = document.getElementById('student-detail-textbox-anmerkung').value;
|
||||
homepage = document.getElementById('student-detail-textbox-homepage').value;
|
||||
svnr = document.getElementById('student-detail-textbox-svnr').value;
|
||||
ersatzkennzeichen = document.getElementById('student-detail-textbox-ersatzkennzeichen').value;
|
||||
familienstand = document.getElementById('student-detail-menulist-familienstand').value;
|
||||
geschlecht = document.getElementById('student-detail-menulist-geschlecht').value;
|
||||
@@ -919,7 +916,6 @@ function StudentDetailSave()
|
||||
req.add('geburtszeit', geburtszeit);
|
||||
req.add('anmerkung', anmerkung);
|
||||
req.add('homepage', homepage);
|
||||
req.add('svnr', svnr);
|
||||
req.add('ersatzkennzeichen', ersatzkennzeichen);
|
||||
req.add('familienstand', familienstand);
|
||||
req.add('geschlecht', geschlecht);
|
||||
@@ -1167,7 +1163,6 @@ function StudentAuswahl()
|
||||
geburtszeit=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#gebzeit" ));
|
||||
anmerkung=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#anmerkungen" ));
|
||||
homepage=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#homepage" ));
|
||||
svnr=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#svnr" ));
|
||||
ersatzkennzeichen=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#ersatzkennzeichen" ));
|
||||
familienstand=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#familienstand" ));
|
||||
geschlecht=getTargetHelper(dsource,subject,rdfService.GetResource( predicateNS + "#geschlecht" ));
|
||||
@@ -1211,7 +1206,6 @@ function StudentAuswahl()
|
||||
document.getElementById('student-detail-textbox-geburtszeit').value=geburtszeit;
|
||||
document.getElementById('student-detail-textbox-anmerkung').value=anmerkung;
|
||||
document.getElementById('student-detail-textbox-homepage').value=homepage;
|
||||
document.getElementById('student-detail-textbox-svnr').value=svnr;
|
||||
document.getElementById('student-detail-textbox-ersatzkennzeichen').value=ersatzkennzeichen;
|
||||
document.getElementById('student-detail-menulist-familienstand').value=familienstand;
|
||||
|
||||
@@ -3553,6 +3547,15 @@ function StudentZeugnisDokumentArchivieren()
|
||||
xml = 'abschlussdokument_lehrgaenge.xml.php';
|
||||
break;
|
||||
|
||||
case 'microcredentialzertifikat_1':
|
||||
case 'microcredentialzertifikat_2':
|
||||
case 'microcredentialzertifikat_3':
|
||||
case 'microcredential_1':
|
||||
case 'microcredential_2':
|
||||
case 'microcredential_3':
|
||||
xml = 'microcredential.xml.php';
|
||||
break;
|
||||
|
||||
default:
|
||||
alert('Das Archivieren fuer diesen Dokumenttyp wird derzeit nicht unterstuetzt');
|
||||
return
|
||||
@@ -4783,7 +4786,7 @@ function StudentNotenMoveFromAntrag()
|
||||
|
||||
var uid = document.getElementById('student-detail-textbox-uid').value;
|
||||
req.add('student_uid', uid);
|
||||
|
||||
|
||||
var txt = "?";
|
||||
for(var q in req.parms) {
|
||||
txt = txt+'&'+req.parms[q].name+'='+encodeURIComponent(req.parms[q].value);
|
||||
|
||||
@@ -1051,7 +1051,6 @@ class prestudent extends person
|
||||
//$ps->foto = $row->foto;
|
||||
$ps->anmerkungen = $row->anmerkungen;
|
||||
$ps->homepage = $row->homepage;
|
||||
$ps->svnr = $row->svnr;
|
||||
$ps->ersatzkennzeichen = $row->ersatzkennzeichen;
|
||||
$ps->familienstand = $row->familienstand;
|
||||
$ps->geschlecht = $row->geschlecht;
|
||||
|
||||
@@ -294,7 +294,6 @@ class student extends benutzer
|
||||
$l->gebort=$row->gebort;
|
||||
$l->gebzeit=$row->gebzeit;
|
||||
$l->familienstand = $row->familienstand;
|
||||
$l->svnr=$row->svnr;
|
||||
$l->foto=$row->foto;
|
||||
$l->anmerkungen=$row->anmerkung;
|
||||
$l->aktiv=$this->db_parse_bool($row->aktiv);
|
||||
@@ -649,7 +648,7 @@ class student extends benutzer
|
||||
{
|
||||
$sql_query = "SELECT
|
||||
person_id, staatsbuergerschaft, geburtsnation, sprache, anrede, titelpost, titelpre,
|
||||
nachname, vorname, vornamen, gebdatum, gebort, gebzeit, anmerkung, homepage, svnr,
|
||||
nachname, vorname, vornamen, gebdatum, gebort, gebzeit, anmerkung, homepage,
|
||||
ersatzkennzeichen, familienstand, geschlecht, anzahlkinder, tbl_person.aktiv, kurzbeschreibung,
|
||||
tbl_benutzer.aktiv as bnaktiv, tbl_student.studiengang_kz, tbl_student.semester, tbl_student.verband,
|
||||
tbl_student.gruppe, tbl_student.prestudent_id, tbl_benutzer.uid
|
||||
@@ -691,7 +690,6 @@ class student extends benutzer
|
||||
$l->gebzeit = $row->gebzeit;
|
||||
$l->anmerkungen = $row->anmerkung;
|
||||
$l->homepage = $row->homepage;
|
||||
$l->svnr = $row->svnr;
|
||||
$l->ersatzkennzeichen = $row->ersatzkennzeichen;
|
||||
$l->familienstand = $row->familienstand;
|
||||
$l->geschlecht = $row->geschlecht;
|
||||
|
||||
@@ -244,10 +244,10 @@ function checkZeilenUmbruch()
|
||||
if(defined('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN && $angemeldet
|
||||
&& (!defined('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN_STG') || in_array($lv->studiengang_kz, unserialize(CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN_STG)))
|
||||
&& (!defined('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN_LVA') || in_array($lv->lehrveranstaltung_id, unserialize(CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN_LVA)))
|
||||
&& ($rechte->isBerechtigt('extension/anw_ent_admin')
|
||||
|| $rechte->isBerechtigt('extension/anwesenheit_lektor')
|
||||
|| $rechte->isBerechtigt('extension/anwesenheit_student')
|
||||
|| $rechte->isBerechtigt('extension/anwesenheit_admin')))
|
||||
&& ($rechte->isBerechtigt('extension/anw_r_ent_assistenz')
|
||||
|| $rechte->isBerechtigt('extension/anw_r_lektor')
|
||||
|| $rechte->isBerechtigt('extension/anw_r_student')
|
||||
|| $rechte->isBerechtigt('extension/anw_r_full_assistenz')))
|
||||
{
|
||||
$link='';
|
||||
$text='';
|
||||
|
||||
@@ -203,3 +203,14 @@
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.hiddenWidget{
|
||||
background: var(--fhc-disabled-background);
|
||||
opacity: 40%;
|
||||
}
|
||||
|
||||
.hiddenWidget .card,
|
||||
.hiddenWidget .card-body,
|
||||
.hiddenWidget .card-body *{
|
||||
background: inherit !important;
|
||||
}
|
||||
|
||||
@@ -3973,6 +3973,10 @@
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
}
|
||||
.p-tabview-panel .btn-close,
|
||||
.p-tabview-panel .carousel-indicators [data-bs-target] {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.p-toolbar {
|
||||
background: #efefef;
|
||||
|
||||
@@ -89,7 +89,8 @@
|
||||
--fhc-link: var(--fhc-blue-10);
|
||||
|
||||
/* disabled */
|
||||
--fhc-disabled: var(--fhc-gray-10);
|
||||
--fhc-disabled: var(--fhc-gray-90);
|
||||
--fhc-disabled-background: var(--fhc-gray-30);
|
||||
|
||||
/* status colors */
|
||||
--fhc-danger: var(--fhc-red-10);
|
||||
@@ -135,6 +136,7 @@
|
||||
|
||||
/* disabled */
|
||||
--fhc-disabled: var(--fhc-gray-10);
|
||||
--fhc-disabled-background: var(--fhc-gray-120);
|
||||
|
||||
/* status colors */
|
||||
--fhc-danger: var(--fhc-red-10);
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
getAllBetriebsmittel(type, id) {
|
||||
getAllBetriebsmittel(type, id, betriebsmitteltypes) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/betriebsmittel/betriebsmittelP/getAllBetriebsmittel/' + type + '/' + id
|
||||
url: 'api/frontend/v1/betriebsmittel/betriebsmittelP/getAllBetriebsmittel/' + type + '/' + id,
|
||||
params: {
|
||||
betriebsmitteltypes
|
||||
}
|
||||
};
|
||||
},
|
||||
addNewBetriebsmittel(person_id, params) {
|
||||
@@ -48,10 +51,13 @@ export default {
|
||||
url: 'api/frontend/v1/betriebsmittel/betriebsmittelP/deleteBetriebsmittel/' + betriebsmittelperson_id
|
||||
};
|
||||
},
|
||||
getTypenBetriebsmittel() {
|
||||
getTypenBetriebsmittel(betriebsmitteltypes) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/betriebsmittel/betriebsmittelP/getTypenBetriebsmittel/'
|
||||
url: 'api/frontend/v1/betriebsmittel/betriebsmittelP/getTypenBetriebsmittel/',
|
||||
params: {
|
||||
betriebsmitteltypes
|
||||
}
|
||||
};
|
||||
},
|
||||
loadInventarliste(query) {
|
||||
|
||||
@@ -83,5 +83,11 @@ export default {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/notiz/notizPerson/isBerechtigt/'
|
||||
};
|
||||
},
|
||||
getCountNotes(person_id){
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/notiz/notizPerson/getCountNotes/' + person_id
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,5 +22,19 @@ export default {
|
||||
url: '/api/frontend/v1/Ort/ContentID',
|
||||
params: { ort_kurzbz: ort_kurbz }
|
||||
};
|
||||
},
|
||||
getRooms(datum, von, bis, typ, personenanzahl = 0) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Ort/getRooms',
|
||||
params: { datum, von, bis, typ, personenanzahl }
|
||||
};
|
||||
},
|
||||
getRoomTypes() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/Ort/getTypes',
|
||||
params: { }
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -68,6 +68,13 @@ export default {
|
||||
params: dms
|
||||
};
|
||||
},
|
||||
getProfilUpdateWithPermission(filter) {
|
||||
const url_filter = (filter !== '') ? '/' + encodeURIComponent(filter) : '';
|
||||
return {
|
||||
method: 'get',
|
||||
url: '/api/frontend/v1/ProfilUpdate/getProfilUpdateWithPermission' + url_filter
|
||||
};
|
||||
},
|
||||
getProfilRequestFiles(requestID) {
|
||||
return {
|
||||
method: 'get',
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (C) 2025 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export default {
|
||||
info(app, path) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/RouteInfo/info',
|
||||
params: {
|
||||
app: app,
|
||||
path: path
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -18,6 +18,7 @@ import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.j
|
||||
import Studium from "../../components/Cis/Studium/Studium.js";
|
||||
|
||||
import ApiRenderers from '../../api/factory/renderers.js';
|
||||
import ApiRouteInfo from '../../api/factory/routeinfo.js';
|
||||
|
||||
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
|
||||
@@ -138,10 +139,10 @@ const router = VueRouter.createRouter({
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: `/Cis/MyLv`,
|
||||
path: `/Cis/MyLv/:studiensemester?`,
|
||||
name: 'MyLv',
|
||||
component: MylvStudent,
|
||||
props: true
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: `/Cis/MyLv/Info/:studien_semester/:lehrveranstaltung_id`,
|
||||
@@ -319,6 +320,7 @@ const app = Vue.createApp({
|
||||
|
||||
// kind of a bandaid for bad css on some pages to avoid horizontal scroll
|
||||
setScrollbarWidth();
|
||||
|
||||
app.use(router);
|
||||
app.use(primevue.config.default, {
|
||||
zIndex: {
|
||||
@@ -331,3 +333,7 @@ app.use(PluginsPhrasen);
|
||||
app.use(Theme);
|
||||
app.directive('contrast', contrast);
|
||||
app.mount('#fhccontent');
|
||||
|
||||
router.afterEach((to, from, failure) => {
|
||||
app.config.globalProperties.$api.call(ApiRouteInfo.info('cis4', to.fullPath));
|
||||
});
|
||||
@@ -29,14 +29,24 @@ export default {
|
||||
uid: {
|
||||
type: [Number, String],
|
||||
required: true
|
||||
}
|
||||
},
|
||||
/** List of types to allow for creation */
|
||||
betriebsmittelTypes: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* If true: only show the types specified in 'betriebsmittelTypes'.
|
||||
* If false: show all available types.
|
||||
*/
|
||||
filterByProvidedTypes: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabulatorOptions: {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: () => this.$api.call(
|
||||
this.endpoint.getAllBetriebsmittel(this.typeId, this.id)
|
||||
this.endpoint.getAllBetriebsmittel(this.typeId, this.id, (this.filterByProvidedTypes ? this.betriebsmittelTypes : null))
|
||||
),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
columns: [
|
||||
@@ -294,7 +304,7 @@ export default {
|
||||
},
|
||||
created() {
|
||||
return this.$api
|
||||
.call(this.endpoint.getTypenBetriebsmittel())
|
||||
.call(this.endpoint.getTypenBetriebsmittel(this.betriebsmittelTypes))
|
||||
.then(result => {
|
||||
this.listBetriebsmitteltyp = result.data;
|
||||
})
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
export default {
|
||||
name: 'BootstrapModal',
|
||||
data: () => ({
|
||||
modal: null
|
||||
modal: null,
|
||||
fullscreen: false
|
||||
}),
|
||||
props: {
|
||||
backdrop: {
|
||||
@@ -34,6 +35,10 @@ export default {
|
||||
footerClass: {
|
||||
type: [String,Array,Object],
|
||||
default: ''
|
||||
},
|
||||
allowFullscreenExpand: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: [
|
||||
@@ -58,6 +63,9 @@ export default {
|
||||
},
|
||||
toggle() {
|
||||
return this.modal.toggle();
|
||||
},
|
||||
toggleFullscreen() {
|
||||
this.fullscreen = !this.fullscreen
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -122,13 +130,18 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
template: `<div ref="modal" class="bootstrap-modal modal" tabindex="-1" @[\`hide.bs.modal\`]="$emit('hideBsModal')" @[\`hidden.bs.modal\`]="$emit('hiddenBsModal')" @[\`hidePrevented.bs.modal\`]="$emit('hidePreventedBsModal')" @[\`show.bs.modal\`]="$emit('showBsModal')" >
|
||||
<div class="modal-dialog" :class="dialogClass">
|
||||
template: `<div ref="modal" class="bootstrap-modal modal" tabindex="-1" @[\`hide.bs.modal\`]="$emit('hideBsModal')" @[\`hidden.bs.modal\`]="$emit('hiddenBsModal')" @[\`hidePrevented.bs.modal\`]="$emit('hidePreventedBsModal')" @[\`show.bs.modal\`]="$emit('showBsModal')" @[\`shown.bs.modal\`]="$emit('shownBsModal')">
|
||||
<div class="modal-dialog" :class="fullscreen ? 'modal-fullscreen' : dialogClass">
|
||||
<div class="modal-content">
|
||||
<div v-if="$slots.title" class="modal-header" :class="headerClass">
|
||||
<h5 class="modal-title"><slot name="title"/></h5>
|
||||
<slot name="popoutButton"></slot>
|
||||
<button v-if="!noCloseBtn" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
<div class="d-flex align-items-center ms-auto">
|
||||
<button type="button" class="btn ms-auto" style="filter: invert(1)" v-if="allowFullscreenExpand" @click="toggleFullscreen">
|
||||
<i v-if="!fullscreen" class="fa-solid fa-expand"></i>
|
||||
<i v-else class="fa-solid fa-compress"></i>
|
||||
</button>
|
||||
<button v-if="!noCloseBtn" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<slot name="modal-header-content"></slot>
|
||||
</div>
|
||||
<div class="modal-body" :class="bodyClass">
|
||||
|
||||
@@ -44,11 +44,16 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
currentDate() {
|
||||
this.rangeOffset = this.currentDate.startOf('day').diff(this.focusDate.startOf('day'), 'days').days;
|
||||
if (this.rangeOffset) {
|
||||
this.$refs.view.$refs.grid.disableAutoScroll();
|
||||
if (this.currentDate.locale != this.focusDate.locale) {
|
||||
this.focusDate = this.currentDate;
|
||||
this.$emit('update:range', this.range);
|
||||
this.$refs.slider.slidePages(this.rangeOffset).then(this.updatePage);
|
||||
} else {
|
||||
this.rangeOffset = this.currentDate.startOf('day').diff(this.focusDate.startOf('day'), 'days').days;
|
||||
if (this.rangeOffset) {
|
||||
this.$refs.view.$refs.grid.disableAutoScroll();
|
||||
this.$emit('update:range', this.range);
|
||||
this.$refs.slider.slidePages(this.rangeOffset).then(this.updatePage);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -47,10 +47,15 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
currentDate() {
|
||||
this.rangeOffset = this.currentDate.startOf('day').diff(this.focusDate.startOf('day'), 'days').days;
|
||||
if (this.rangeOffset) {
|
||||
if (this.currentDate.locale != this.focusDate.locale) {
|
||||
this.focusDate = this.currentDate;
|
||||
this.$emit('update:range', this.range);
|
||||
this.$refs.slider.slidePages(this.rangeOffset).then(this.updatePage);
|
||||
} else {
|
||||
this.rangeOffset = this.currentDate.startOf('day').diff(this.focusDate.startOf('day'), 'days').days;
|
||||
if (this.rangeOffset) {
|
||||
this.$emit('update:range', this.range);
|
||||
this.$refs.slider.slidePages(this.rangeOffset).then(this.updatePage);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -57,65 +57,70 @@ export default {
|
||||
p.style.setProperty('white-space', 'normal');
|
||||
p.style.setProperty('max-width', '400px');
|
||||
})
|
||||
},
|
||||
prepareContent() {
|
||||
// replaces the tablesorter with the tabulator
|
||||
let tables = Array.from(document.getElementsByClassName("tablesorter"));
|
||||
|
||||
tables.forEach((table, index) => {
|
||||
this.sanitizeLegacyTables(table)
|
||||
|
||||
new Tabulator(table, {
|
||||
index: index,
|
||||
layout: "fitDataFill",
|
||||
|
||||
columnDefaults: {
|
||||
formatter: "html",
|
||||
resizable: true,
|
||||
minWidth: "100px"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
|
||||
el.addEventListener("click", (evt) => {
|
||||
evt.preventDefault();
|
||||
BsConfirm.popup(el.dataset.confirm)
|
||||
.then(() => {
|
||||
Axios.get(el.href)
|
||||
.then((res) => {
|
||||
// TODO(chris): check for success then show message and/or reload
|
||||
location = location;
|
||||
})
|
||||
.catch((err) => console.error("ERROR:", err));
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
});
|
||||
document.querySelectorAll("#cms [data-href]").forEach((el) => {
|
||||
el.href = el.dataset.href.replace(
|
||||
/^ROOT\//,
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
);
|
||||
});
|
||||
|
||||
document.querySelectorAll("[href]").forEach((element) => {
|
||||
let orignal_href = element.getAttribute("href");
|
||||
let new_href = replaceRelativeLegacyLink(orignal_href);
|
||||
element.href = new_href;
|
||||
});
|
||||
|
||||
document.querySelectorAll("[style*=background-color]").forEach((element) => {
|
||||
if (element.style.backgroundColor == "rgb(255, 255, 255)"){
|
||||
element.style.backgroundColor = "var(--fhc-background)";
|
||||
}
|
||||
if(element.querySelector("*[style*=background-color]")){
|
||||
element.style.backgroundColor = "var(--fhc-tertiary)";
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
// replaces the tablesorter with the tabulator
|
||||
let tables = Array.from(document.getElementsByClassName("tablesorter"));
|
||||
|
||||
tables.forEach((table, index) => {
|
||||
this.sanitizeLegacyTables(table)
|
||||
|
||||
new Tabulator(table, {
|
||||
index: index,
|
||||
layout: "fitDataFill",
|
||||
|
||||
columnDefaults: {
|
||||
formatter: "html",
|
||||
resizable: true,
|
||||
minWidth: "100px"
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
document.querySelectorAll("#cms [data-confirm]").forEach((el) => {
|
||||
el.addEventListener("click", (evt) => {
|
||||
evt.preventDefault();
|
||||
BsConfirm.popup(el.dataset.confirm)
|
||||
.then(() => {
|
||||
Axios.get(el.href)
|
||||
.then((res) => {
|
||||
// TODO(chris): check for success then show message and/or reload
|
||||
location = location;
|
||||
})
|
||||
.catch((err) => console.error("ERROR:", err));
|
||||
})
|
||||
.catch(() => {});
|
||||
});
|
||||
});
|
||||
document.querySelectorAll("#cms [data-href]").forEach((el) => {
|
||||
el.href = el.dataset.href.replace(
|
||||
/^ROOT\//,
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
);
|
||||
});
|
||||
|
||||
document.querySelectorAll("[href]").forEach((element) => {
|
||||
let orignal_href = element.getAttribute("href");
|
||||
let new_href = replaceRelativeLegacyLink(orignal_href);
|
||||
element.href = new_href;
|
||||
});
|
||||
|
||||
document.querySelectorAll("[style*=background-color]").forEach((element) => {
|
||||
if (element.style.backgroundColor == "rgb(255, 255, 255)"){
|
||||
element.style.backgroundColor = "var(--fhc-background)";
|
||||
}
|
||||
if(element.querySelector("*[style*=background-color]")){
|
||||
element.style.backgroundColor = "var(--fhc-tertiary)";
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
updated() {
|
||||
this.prepareContent();
|
||||
},
|
||||
mounted(){
|
||||
this.prepareContent();
|
||||
},
|
||||
template: /*html*/ `
|
||||
<!-- div that contains the content -->
|
||||
<div v-if="content" class="container" style="max-width: 100%;"><div class="row"><div class="col">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { replaceRelativeLegacyLink } from "../../../../helpers/LegacyLinkReplaceHelper.js"
|
||||
export default {
|
||||
name: "GeneralComponent",
|
||||
name: "NewsContentType",
|
||||
props:{
|
||||
content:{
|
||||
type:String,
|
||||
|
||||
@@ -12,7 +12,7 @@ export default {
|
||||
required:true,
|
||||
},
|
||||
content_id:{
|
||||
type:Number,
|
||||
type: [Number, String],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -129,7 +129,7 @@ export default {
|
||||
template: /*html*/ `
|
||||
<!-- div that contains the content -->
|
||||
<!-- TODO: test with more img content from cms-->
|
||||
<div v-if="imgContent"><img v-bind="imgContent"></img></div>
|
||||
<div v-if="imgContent"><img v-bind="imgContent"/></div>
|
||||
<div v-html="content" v-else-if="content" ></div>
|
||||
<p v-else>Content was not found</p>
|
||||
`,
|
||||
|
||||
@@ -43,6 +43,13 @@ export default {
|
||||
return menuItem.c4_link ?? null;
|
||||
}
|
||||
},
|
||||
getMenuName(menuItem) {
|
||||
if(menuItem.phrase) {
|
||||
return this.$p.t(menuItem.phrase)
|
||||
} else {
|
||||
return menuItem.name
|
||||
}
|
||||
}
|
||||
},
|
||||
template:/*html*/`
|
||||
<div v-if="!menu">{{$p.t('lehre','lehrveranstaltungsUnavailable')}}</div>
|
||||
@@ -54,7 +61,7 @@ export default {
|
||||
:disabled="c4_disabled(menuItem)" :data-bs-toggle="menuItem.c4_moodle_links?.length?'dropdown':null"
|
||||
class="menu-entry p-2 w-100 text-wrap border border-1 rounded-3 d-flex flex-column align-items-center justify-content-center text-center text-decoration-none link h-100">
|
||||
<img :src="menuItem.c4_icon" :alt="menuItem.name" />
|
||||
<p class="w-100 mt-2 mb-0">{{menuItem.name}}</p>
|
||||
<p class="w-100 mt-2 mb-0">{{ getMenuName(menuItem) }}</p>
|
||||
<a v-for="([text,link],index) in menuItem.c4_linkList" target="_blank" :href="link" class="my-1 w-100 submenu text-decoration-none" :index="index">{{text}}</a>
|
||||
</a>
|
||||
<ul v-if="menuItem.c4_moodle_links?.length" class="dropdown-menu p-0" :aria-labelledby="menuItem.name">
|
||||
|
||||
@@ -19,6 +19,7 @@ export default {
|
||||
props: {
|
||||
lehrveranstaltung_id: Number,
|
||||
bezeichnung: String,
|
||||
bezeichnung_eng: String,
|
||||
module: String,
|
||||
farbe: String,
|
||||
lvinfo: Boolean,
|
||||
|
||||
@@ -75,21 +75,26 @@ export default {
|
||||
this.$refs.studiensemester.selectedIndex++;
|
||||
this.$refs.studiensemester.dispatchEvent(new Event('change', { bubbles: true }));
|
||||
},
|
||||
setHash(val) {
|
||||
// TODO: make this a router param to enable history
|
||||
location.hash = val;
|
||||
updateRouter(val) {
|
||||
this.$router.push(`/Cis/MyLv/${val}`);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Cis/Mylv/Studiensemester').then(res => {
|
||||
this.studiensemester = res.data.retval || [];
|
||||
const hash = location.hash.substring(1);
|
||||
if (hash && this.studiensemester.filter(s => s.studiensemester_kurzbz == hash).length)
|
||||
this.currentSemester = hash;
|
||||
const routerStudiensemester = this.$route.params.studiensemester;
|
||||
if (routerStudiensemester && this.studiensemester.filter(s => s.studiensemester_kurzbz == routerStudiensemester).length)
|
||||
this.currentSemester = routerStudiensemester;
|
||||
else
|
||||
this.currentSemester = this.nearestSem;
|
||||
});
|
||||
},
|
||||
beforeRouteUpdate(to, from, next){
|
||||
if (to.params.studiensemester && this.studiensemester.filter(s => s.studiensemester_kurzbz == to.params.studiensemester).length && to.params.studiensemester != this.currentSemester)
|
||||
this.currentSemester = to.params.studiensemester;
|
||||
next();
|
||||
|
||||
},
|
||||
template: `
|
||||
|
||||
<h2>{{$p.t('lehre/myLV')}}</h2>
|
||||
@@ -104,7 +109,7 @@ export default {
|
||||
<button :aria-label="$p.t('lehre','previousStudSemester')" v-tooltip.top="{showDelay:1000, value:$p.t('lehre','previousStudSemester')}" class="btn btn-outline-secondary" type="button" :disabled="currentIsFirst" @click="prevSem">
|
||||
<i class="fa fa-caret-left" aria-hidden="true"></i>
|
||||
</button>
|
||||
<select ref="studiensemester" v-model="currentSemester" class="form-select" :aria-label="$p.t('global/studiensemester_auswaehlen')" @change="setHash($event.target.value)">
|
||||
<select ref="studiensemester" v-model="currentSemester" class="form-select" :aria-label="$p.t('global/studiensemester_auswaehlen')" @change="updateRouter($event.target.value)">
|
||||
<option v-for="semester in studiensemester" :key="semester.studiensemester_kurzbz">{{semester.studiensemester_kurzbz}}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" :aria-label="$p.t('lehre','nextStudSemester')" v-tooltip.top="{showDelay:1000, value:$p.t('lehre','nextStudSemester')}" type="button" :disabled="currentIsLast" @click="nextSem">
|
||||
|
||||
@@ -167,11 +167,11 @@ export default {
|
||||
this.$api
|
||||
.call(ApiProfilUpdate.selectProfilRequest())
|
||||
.then((request) => {
|
||||
if (!request.error && request) {
|
||||
if (!request.error && request.data) {
|
||||
this.data.profilUpdates = request.data;
|
||||
this.data.profilUpdates.sort(this.sortProfilUpdates);
|
||||
} else {
|
||||
console.error("Error when fetching profile updates: " + res.data);
|
||||
console.error("Error when fetching profile updates: " + request);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
@@ -88,6 +88,18 @@ export default {
|
||||
if (isMitarbeiter) {
|
||||
content["isMitarbeiter"] = isMitarbeiter;
|
||||
}
|
||||
|
||||
const filesFromDatabase =
|
||||
await this.$api
|
||||
.call(ApiProfilUpdate.getProfilRequestFiles(
|
||||
updateRequest.profil_update_id
|
||||
))
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
});
|
||||
|
||||
files = filesFromDatabase;
|
||||
content["files"] = files;
|
||||
}
|
||||
|
||||
//? adds the status information if the profil update request was rejected or accepted
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import Dms from "../../../../Form/Upload/Dms.js";
|
||||
|
||||
import ApiProfil from '../../../../../api/factory/profil.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AutoComplete: primevue.autocomplete,
|
||||
Dms: Dms
|
||||
},
|
||||
|
||||
props: {
|
||||
@@ -11,9 +14,13 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
files: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
},
|
||||
|
||||
inject: ["getZustelladressenCount"],
|
||||
inject: ["getZustelladressenCount", "updateFileID"],
|
||||
|
||||
data() {
|
||||
return {
|
||||
@@ -23,6 +30,8 @@ export default {
|
||||
nationenList: [],
|
||||
originalValue: null,
|
||||
zustellAdressenCount: null,
|
||||
dmsData: [],
|
||||
fileschanged: false
|
||||
};
|
||||
},
|
||||
|
||||
@@ -83,6 +92,11 @@ export default {
|
||||
//? sets the value of a property to null when an empty string is entered to keep the isChanged function valid
|
||||
if (bind === "zustelladresse") {
|
||||
this.data[bind] = event.target.checked;
|
||||
} else if(bind === 'files') {
|
||||
if(this.dmsData.length > 0 && this.dmsData[0].type !== 'application/x.fhc-dms+json') {
|
||||
this.fileschanged = true;
|
||||
}
|
||||
this.updateFileID(this.dmsData);
|
||||
} else {
|
||||
this.data[bind] = event.target.value === "" ? null : event.target.value;
|
||||
}
|
||||
@@ -91,6 +105,11 @@ export default {
|
||||
// update the zustellAdressen count
|
||||
this.zustellAdressenCount = this.getZustelladressenCount();
|
||||
},
|
||||
|
||||
deleteDmsData: function() {
|
||||
this.dmsData = [];
|
||||
this.updateValue(null, 'files');
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
@@ -111,12 +130,14 @@ export default {
|
||||
!this.data.strasse ||
|
||||
!this.data.plz ||
|
||||
!this.data.ort ||
|
||||
!this.data.typ
|
||||
!this.data.typ ||
|
||||
this.dmsData.length === 0
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.originalValue !== JSON.stringify(this.data);
|
||||
const datachanged = this.originalValue !== JSON.stringify(this.data);
|
||||
return datachanged || this.fileschanged;
|
||||
},
|
||||
},
|
||||
|
||||
@@ -133,6 +154,12 @@ export default {
|
||||
this.zustellAdressenCount = this.getZustelladressenCount();
|
||||
},
|
||||
|
||||
mounted() {
|
||||
if (this.files) {
|
||||
this.dmsData = this.files;
|
||||
}
|
||||
},
|
||||
|
||||
template: /*html*/ `
|
||||
<div class="gy-3 row justify-content-center align-items-center">
|
||||
<!-- warning message for too many zustellungs Adressen -->
|
||||
@@ -212,9 +239,28 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col">
|
||||
<div class="form-underline-titel">{{$p.t('profilUpdate','meldebestaetigung')}}*</div>
|
||||
<dms
|
||||
ref="update"
|
||||
id="files"
|
||||
name="files"
|
||||
:multiple="false"
|
||||
v-model="dmsData"
|
||||
@update:model-value="updateValue($event,'files')"
|
||||
></dms>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<div> </div>
|
||||
<button
|
||||
@click="deleteDmsData"
|
||||
class="btn btn-danger"
|
||||
:aria-label="$p.t('profilUpdate','deleteAttachment')"
|
||||
:title="$p.t('profilUpdate','deleteAttachment')"
|
||||
><i style="color:white" class="fa fa-trash" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`,
|
||||
|
||||
@@ -112,14 +112,17 @@ export default {
|
||||
<div class="form-underline-titel">{{topic}}</div>
|
||||
<span class="form-underline-content">{{data.value}} </span>
|
||||
</div>
|
||||
<div v-if="files?.length" class="ms-2">
|
||||
|
||||
<a target="_blank" :href="getDocumentLink(file.dms_id)" v-for="file in files">{{file.name}}</a>
|
||||
</div>
|
||||
</template>
|
||||
<component v-else :is="getComponentView" :data="data"></component>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="files?.length" class="card mt-4">
|
||||
<div class="card-header">{{$p.t('profilUpdate','nachweisdokumente')}}</div>
|
||||
<div class="card-body">
|
||||
<a target="_blank" :href="getDocumentLink(file.dms_id)" v-for="file in files">{{file.name}}</a>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -133,11 +133,11 @@ export default {
|
||||
this.$api
|
||||
.call(ApiProfilUpdate.selectProfilRequest())
|
||||
.then((request) => {
|
||||
if (!request.error && res) {
|
||||
if (!request.error && request.data) {
|
||||
this.data.profilUpdates = request.data;
|
||||
this.data.profilUpdates.sort(this.sortProfilUpdates);
|
||||
} else {
|
||||
console.error("Error when fetching profile updates: " + res.data);
|
||||
console.error("Error when fetching profile updates: " + request);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
|
||||
@@ -188,16 +188,21 @@ export default {
|
||||
|
||||
<span class="form-underline-content" >{{data.requested_change.value}}</span>
|
||||
</div>
|
||||
<div v-if="files?.length" class="ms-2">
|
||||
|
||||
<a v-for="file in files" target="_blank" :href="getDocumentLink(file.dms_id)" >{{file.name}}</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<component v-else :is="getComponentView" :withZustelladresse="getComponentView==='adresse'?true:false" :data="data.requested_change"></component>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="files?.length" class="card mt-3">
|
||||
<div class="card-header">{{$p.t('profilUpdate','nachweisdokumente')}}</div>
|
||||
<div class="card-body">
|
||||
<a v-for="file in files" target="_blank" :href="getDocumentLink(file.dms_id)" >{{file.name}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ export default {
|
||||
Loading,
|
||||
AcceptDenyUpdate,
|
||||
},
|
||||
inject: ["profilUpdateTopic", "profilUpdateStates"],
|
||||
inject: ["profilUpdateStates"],
|
||||
props: {
|
||||
id: {
|
||||
type: Number,
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
@@ -44,51 +44,53 @@ export default {
|
||||
modalData: null,
|
||||
loading: false,
|
||||
filter: "Pending",
|
||||
events: [],
|
||||
profil_update_id: Number(this.id),
|
||||
|
||||
};
|
||||
},
|
||||
computed:{
|
||||
profilUpdateOptions: function(){
|
||||
return {
|
||||
ajaxURL:
|
||||
FHC_JS_DATA_STORAGE_OBJECT.app_root +
|
||||
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
|
||||
`/Cis/ProfilUpdate/`,
|
||||
|
||||
ajaxURLGenerator: (url, config, params) => {
|
||||
//? this function needs to be an array function in order to access the this properties of the Vue component
|
||||
|
||||
switch (this.filter) {
|
||||
case this.profilUpdateStates["Pending"]:
|
||||
return (
|
||||
url +
|
||||
`getProfilUpdateWithPermission/${this.profilUpdateStates["Pending"]}`
|
||||
);
|
||||
case this.profilUpdateStates["Accepted"]:
|
||||
return (
|
||||
url +
|
||||
`getProfilUpdateWithPermission/${this.profilUpdateStates["Accepted"]}`
|
||||
);
|
||||
case this.profilUpdateStates["Rejected"]:
|
||||
return (
|
||||
url +
|
||||
`getProfilUpdateWithPermission/${this.profilUpdateStates["Rejected"]}`
|
||||
);
|
||||
default:
|
||||
return url + `getProfilUpdateWithPermission`;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
profilUpdateEvents: function () {
|
||||
return [
|
||||
{
|
||||
"event": "dataProcessed",
|
||||
"handler": this.handleDataProcessed
|
||||
}
|
||||
];
|
||||
},
|
||||
profilUpdateOptions: function () {
|
||||
return {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: (url, config, params) => {
|
||||
return this.$api.call(ApiProfilUpdate.getProfilUpdateWithPermission(params.filter));
|
||||
},
|
||||
ajaxParams: () => {
|
||||
let filter = '';
|
||||
switch (this.filter) {
|
||||
case this.profilUpdateStates["Pending"]:
|
||||
filter = this.profilUpdateStates["Pending"];
|
||||
break;
|
||||
case this.profilUpdateStates["Accepted"]:
|
||||
filter = this.profilUpdateStates["Accepted"];
|
||||
break;
|
||||
case this.profilUpdateStates["Rejected"]:
|
||||
filter = this.profilUpdateStates["Rejected"];
|
||||
break;
|
||||
default:
|
||||
filter = '';
|
||||
}
|
||||
return {
|
||||
"filter": filter
|
||||
};
|
||||
},
|
||||
ajaxResponse: (url, params, response) => {
|
||||
//url - the URL of the request
|
||||
//params - the parameters passed with the request
|
||||
//response - the JSON object returned in the body of the response.
|
||||
//? sorts the response data from the backend
|
||||
if (response)
|
||||
response.sort((ele1, ele2) => sortProfilUpdates(ele1, ele2, this));
|
||||
if (response?.data)
|
||||
response.data.sort((ele1, ele2) => sortProfilUpdates(ele1, ele2, this));
|
||||
|
||||
return response;
|
||||
return response.data;
|
||||
},
|
||||
//? adds tooltip with the status message of a profil update request if its status is not pending
|
||||
columnDefaults: {
|
||||
@@ -356,7 +358,19 @@ export default {
|
||||
this.$refs.UpdatesTable.tabulator.setData();
|
||||
//? store the selected view in the session storage of the browser
|
||||
sessionStorage.setItem("filter", event.target.value);
|
||||
},
|
||||
},
|
||||
handleDataProcessed: function () {
|
||||
if (this.profil_update_id) {
|
||||
const arrayRowData = this.$refs.UpdatesTable.tabulator
|
||||
.getData()
|
||||
.filter((row) => {
|
||||
return row.profil_update_id === this.profil_update_id;
|
||||
});
|
||||
if (arrayRowData.length) {
|
||||
this.showAcceptDenyModal(arrayRowData[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
loading: function (newValue, oldValue) {
|
||||
@@ -374,20 +388,7 @@ export default {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
//? opens the AcceptDenyUpdate Modal if a preselected profil_update_id was passed to the component (used for email links)
|
||||
if (this.profil_update_id) {
|
||||
this.$refs.UpdatesTable.tabulator.on("dataProcessed", () => {
|
||||
const arrayRowData = this.$refs.UpdatesTable.tabulator
|
||||
.getData()
|
||||
.filter((row) => {
|
||||
return row.profil_update_id === this.profil_update_id;
|
||||
});
|
||||
if (arrayRowData.length) {
|
||||
this.showAcceptDenyModal(arrayRowData[0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//? opens the AcceptDenyUpdate Modal if a preselected profil_update_id was passed to the component (used for email links)
|
||||
if (sessionStorage.getItem("filter")) {
|
||||
this.filter = sessionStorage.getItem("filter");
|
||||
}
|
||||
@@ -409,7 +410,7 @@ export default {
|
||||
</div>
|
||||
<loading ref="loadingModalRef" :timeout="0"></loading>
|
||||
|
||||
<core-filter-cmpt v-if="profilUpdateStates && categoryLoaded" :title="$p.t('profilUpdate','profilUpdateRequests')" ref="UpdatesTable" :tabulatorEvents="events" :tabulator-options="profilUpdateOptions" tableOnly :sideMenu="false" />
|
||||
<core-filter-cmpt v-if="profilUpdateStates && categoryLoaded" :title="$p.t('profilUpdate','profilUpdateRequests')" ref="UpdatesTable" :tabulatorEvents="profilUpdateEvents" :tabulator-options="profilUpdateOptions" tableOnly :sideMenu="false" />
|
||||
|
||||
</div>`,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {CoreFilterCmpt} from "../../../components/filter/Filter.js";
|
||||
import VueDatePicker from '../../vueDatepicker.js.php';
|
||||
|
||||
import ApiOrt from '../../../api/factory/ort.js'
|
||||
export const Raumsuche = {
|
||||
name: "Raumsuche",
|
||||
props: {
|
||||
@@ -13,6 +13,8 @@ export const Raumsuche = {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
phrasenPromise: null,
|
||||
phrasenResolved: false,
|
||||
tabulatorUuid: Vue.ref(0),
|
||||
tableBuiltResolve: null,
|
||||
tableBuiltPromise: null,
|
||||
@@ -54,8 +56,8 @@ export const Raumsuche = {
|
||||
columns: [
|
||||
{title: Vue.computed(() => this.$p.t('rauminfo/raum_kurzbz')), field: 'ort_kurzbz', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('global/bezeichnung')), field: 'bezeichnung', widthGrow: 2},
|
||||
{title: Vue.computed(() => this.$p.t('global/nummer')), field: 'nummer', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('global/personen')), field: 'personen', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('rauminfo/raumnummer')), field: 'nummer', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('rauminfo/personcap')), field: 'personen', widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('rauminfo/rauminfo')),
|
||||
field: 'linkInfo', formatter: this.linkFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$p.t('rauminfo/roomReservations')),
|
||||
@@ -68,17 +70,6 @@ export const Raumsuche = {
|
||||
handler: async () => {
|
||||
this.tableBuiltResolve()
|
||||
}
|
||||
},
|
||||
{
|
||||
event: "cellClick",
|
||||
handler: async (e, cell) => {
|
||||
|
||||
if((cell.column.field === 'linkInfo' || cell.column.field === 'linkRes') && cell.value){
|
||||
window.open(cell.value, '_blank');
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
]};
|
||||
},
|
||||
@@ -132,7 +123,8 @@ export const Raumsuche = {
|
||||
this.$refs.raumsucheTable.tabulator.setData(d);
|
||||
},
|
||||
loadRoomTypes() {
|
||||
this.$fhcApi.factory.ort.getRoomTypes().then(res => {
|
||||
this.$api.call(ApiOrt.getRoomTypes())
|
||||
.then(res => {
|
||||
res?.data?.forEach(type => {
|
||||
type.beschreibung = type.beschreibung.replace('&', '&')
|
||||
})
|
||||
@@ -141,7 +133,7 @@ export const Raumsuche = {
|
||||
})
|
||||
},
|
||||
loadRooms() {
|
||||
this.$fhcApi.factory.ort.getRooms(this.datum.toISOString(), this.getTimeString(this.von), this.getTimeString(this.bis), this.selectedType?.raumtyp_kurzbz ?? '', this.anzahl)
|
||||
this.$api.call(ApiOrt.getRooms(this.datum.toISOString(), this.getTimeString(this.von), this.getTimeString(this.bis), this.selectedType?.raumtyp_kurzbz ?? '', this.anzahl))
|
||||
.then(res => {
|
||||
if(res?.data?.retval) this.setupData(res.data.retval)
|
||||
})
|
||||
@@ -167,6 +159,7 @@ export const Raumsuche = {
|
||||
return `${hours}:${minutes}`;
|
||||
},
|
||||
async setupMounted() {
|
||||
|
||||
this.tableBuiltPromise = new Promise(this.tableResolve)
|
||||
await this.tableBuiltPromise
|
||||
|
||||
@@ -182,7 +175,7 @@ export const Raumsuche = {
|
||||
if(this.$refs.raumsucheTable) {
|
||||
this.$refs.raumsucheTable.$refs.table.style.setProperty('height', h+'px')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -191,7 +184,8 @@ export const Raumsuche = {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
this.phrasenPromise = this.$p.loadCategory(['rauminfo', 'global'])
|
||||
this.phrasenPromise.then(()=> {this.phrasenResolved = true})
|
||||
},
|
||||
mounted() {
|
||||
this.setupMounted()
|
||||
@@ -239,7 +233,7 @@ export const Raumsuche = {
|
||||
</VueDatePicker>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-auto">
|
||||
<div class="col-12 col-lg-3">
|
||||
<select ref="raumtyp" id="raumtypSelect" v-model="selectedType" class="form-select"
|
||||
:aria-label="$p.t('global/studiensemester_auswaehlen')" @change="setRoute($event.target.value)">
|
||||
<option :key="defaultType" selected :value="defaultType">{{defaultType.beschreibung}}</option>
|
||||
@@ -248,16 +242,21 @@ export const Raumsuche = {
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-4 col-lg-2">
|
||||
<InputNumber v-model="anzahl" :prefix="$p.t('rauminfo/anzahlPersonen') + ': '" inputId="anzahlInput" :min="1" :max="100" />
|
||||
<div class="col-12 col-lg-3">
|
||||
<InputNumber v-model="anzahl"
|
||||
:prefix="$p.t('rauminfo/minCapacity') + ': '"
|
||||
inputId="anzahlInput" :min="1" :max="1000"
|
||||
:style="{'width': '100%'}"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-8 col-lg-2 d-flex justify-content-center align-items-center">
|
||||
<div class="col-12 col-lg-2">
|
||||
<button class="btn btn-primary border-0" @click="search">{{ $p.t('rauminfo/roomSearch') }} <i class="fa fa-magnifying-glass"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<core-filter-cmpt
|
||||
v-if="phrasenResolved"
|
||||
@uuidDefined="handleUuidDefined"
|
||||
:title="''"
|
||||
ref="raumsucheTable"
|
||||
|
||||
@@ -23,14 +23,6 @@ export default {
|
||||
this.$p.t('person/ort'),
|
||||
this.event.ort_kurzbz
|
||||
].join(": "));
|
||||
|
||||
this.event.lektor = [
|
||||
this.event.lektor[0],
|
||||
this.event.lektor[0],
|
||||
this.event.lektor[0],
|
||||
this.event.lektor[0],
|
||||
this.event.lektor[0],
|
||||
];
|
||||
|
||||
if (Array.isArray(this.event.lektor) && this.event.lektor.length > 0) {
|
||||
if (this.event.lektor.length > 3) {
|
||||
|
||||
@@ -156,7 +156,7 @@ export default {
|
||||
<i class="fa-solid fa-spinner fa-pulse fa-3x"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!hidden || editMode" :id="widgetID" class="dashboard-item card overflow-hidden h-100 position-relative" :class="{'draggedItem':dragstate, 'dashboard-item-overlay':resizeOverlay, [arguments?.className]:arguments && arguments.className}">
|
||||
<div v-else-if="!hidden || editMode" :id="widgetID" class="dashboard-item card overflow-hidden h-100 position-relative" :class="{'hiddenWidget':hidden, 'draggedItem':dragstate, 'dashboard-item-overlay':resizeOverlay, [arguments?.className]:arguments && arguments.className}">
|
||||
<div v-show="!dragstate" class="h-100 card border-0">
|
||||
<div v-if="widget" class="card-header d-flex ps-0 pe-2 align-items-center">
|
||||
<Transition>
|
||||
|
||||
@@ -106,7 +106,7 @@ export default {
|
||||
setPrev() {
|
||||
const thisIndex = this.allNewsList.findIndex(n=>n.news_id == this.selected.news_id)
|
||||
const prevIndex = thisIndex ? thisIndex - 1 : this.allNewsList.length - 1
|
||||
|
||||
|
||||
this.setSelected(this.allNewsList[prevIndex])
|
||||
this.updateNewsContentClasses();
|
||||
},
|
||||
@@ -118,14 +118,14 @@ export default {
|
||||
return classString
|
||||
},
|
||||
async setSelected(news) {
|
||||
let clickedElement = document.getElementById('card-'+news.news_id);
|
||||
let clickedElementIndex = this.allNewsList.indexOf(news);
|
||||
let oldElementIndex = this.allNewsList.indexOf(this.selected);
|
||||
const clickedElement = document.getElementById('card-'+news.news_id);
|
||||
const clickedElementIndex = this.allNewsList.indexOf(news);
|
||||
const oldElementIndex = this.allNewsList.indexOf(this.selected);
|
||||
|
||||
//if the clicked element is already active, do nothing
|
||||
if(clickedElementIndex === oldElementIndex) return;
|
||||
//add prev/next class to the clicked element
|
||||
if(clickedElementIndex > oldElementIndex){
|
||||
if(clickedElementIndex > oldElementIndex) {
|
||||
clickedElement.classList.add('carousel-item-next');
|
||||
}else{
|
||||
clickedElement.classList.add('carousel-item-prev');
|
||||
|
||||
@@ -159,7 +159,7 @@ export default {
|
||||
// this.$emit('setConfig', true); -> use this to enable widget config mode if needed
|
||||
},
|
||||
template: /*html*/ `
|
||||
<div class="widgets-url w-100 h-100 overflow-scroll" style="padding: 1rem 1rem;">
|
||||
<div class="widgets-url w-100 h-100 overflow-auto" style="padding: 1rem 1rem;">
|
||||
<div class="d-flex flex-column justify-content-between">
|
||||
<button class="btn btn-outline-secondary btn-sm w-100 mt-2 card" @click="openCreateModal" type="button">{{$p.t('bookmark','newLink')}}</button>
|
||||
|
||||
|
||||
@@ -274,8 +274,23 @@ export default {
|
||||
dragging(event){
|
||||
if(this.mode == MODE_MOVE){
|
||||
this.toggleDraggedItemOverlay(true);
|
||||
this.clonedWidget.style.top = `${this.clientY-20}px`;
|
||||
this.clonedWidget.style.left = `${this.clientX-15}px`;
|
||||
|
||||
const containerRect = this.$refs.container.getBoundingClientRect();
|
||||
const clonedWidgetRect = this.clonedWidget.getBoundingClientRect();
|
||||
|
||||
let desiredTop = this.clientY - 20;
|
||||
let desiredLeft = this.clientX - 15;
|
||||
|
||||
const minTop = 0;
|
||||
const maxTop = containerRect.height - clonedWidgetRect.height;
|
||||
const minLeft = 0;
|
||||
const maxLeft = containerRect.width - clonedWidgetRect.width;
|
||||
|
||||
const constrainedTop = Math.max(minTop, Math.min(maxTop, desiredTop));
|
||||
const constrainedLeft = Math.max(minLeft, Math.min(maxLeft, desiredLeft));
|
||||
|
||||
this.clonedWidget.style.top = `${constrainedTop}px`;
|
||||
this.clonedWidget.style.left = `${constrainedLeft}px`;
|
||||
}
|
||||
},
|
||||
createNewGrid(items) {
|
||||
@@ -413,11 +428,14 @@ export default {
|
||||
setTimeout(() => {
|
||||
this.draggedNode = evt.target.closest(".drop-grid-item");
|
||||
//clones the widget for the drag Image
|
||||
|
||||
let clone = evt.target.closest(".drop-grid-item")?.cloneNode(true);
|
||||
|
||||
clone.style.zIndex = 5;
|
||||
clone.classList.add("widgetClone");
|
||||
this.$refs.container.appendChild(clone);
|
||||
const hiddenWidget = clone.querySelector("[style='display: none;']");
|
||||
hiddenWidget.style.removeProperty("display");
|
||||
this.clonedWidget = clone;
|
||||
}, 0);
|
||||
|
||||
@@ -434,12 +452,9 @@ export default {
|
||||
},
|
||||
dragOver(evt) {
|
||||
if ((this.y + 1) > this.rows && (this.mode == MODE_MOVE || this.mode == MODE_RESIZE)) {
|
||||
this.positionUpdates = this.positionUpdates?.filter(item => {
|
||||
return item.widgetid == this.draggedItem.data.widgetid;
|
||||
})
|
||||
this.dragEnd();
|
||||
this.dragCancel();
|
||||
}
|
||||
|
||||
}
|
||||
if (!this.active)
|
||||
return this.dragCancel();
|
||||
this.checkPinnedWidgetAnimation();
|
||||
@@ -454,17 +469,17 @@ export default {
|
||||
let x = this.x + this.draggedOffset[0];
|
||||
let y = this.y + this.draggedOffset[1];
|
||||
if (x < 0) {
|
||||
this.draggedOffset[0] -= x;
|
||||
this.draggedOffset[0] += x;
|
||||
x = 0;
|
||||
} else if (x + this.draggedItem.w > this.cols) {
|
||||
this.draggedOffset[0] += this.cols - this.draggedItem.w - x;
|
||||
x = this.cols - this.draggedItem.w;
|
||||
}
|
||||
if (y < 0) {
|
||||
this.draggedOffset[1] -= y;
|
||||
this.draggedOffset[1] += y;
|
||||
y = 0;
|
||||
}
|
||||
this.positionUpdates = this.dragGrid.move(this.draggedItem, x, y);
|
||||
this.positionUpdates= this.dragGrid.move(this.draggedItem, x, y);
|
||||
break;
|
||||
}
|
||||
case MODE_RESIZE: {
|
||||
@@ -481,6 +496,7 @@ export default {
|
||||
}
|
||||
},
|
||||
dragCancel() {
|
||||
this.removeWidgetClones();
|
||||
this.additionalRowComputed = false;
|
||||
this.toggleDraggedItemOverlay(false);
|
||||
this.mode = MODE_IDLE;
|
||||
@@ -492,8 +508,12 @@ export default {
|
||||
|
||||
},
|
||||
dragEnd() {
|
||||
if (this.mode == MODE_IDLE)
|
||||
this.removeWidgetClones();
|
||||
this.toggleDraggedItemOverlay(false);
|
||||
|
||||
if (this.mode == MODE_IDLE){
|
||||
return;
|
||||
}
|
||||
// clean up unused classes
|
||||
let draggedItemNode = document.getElementById(this.draggedItem.data.widgetid);
|
||||
draggedItemNode.classList.remove("border-danger");
|
||||
@@ -501,19 +521,19 @@ export default {
|
||||
ele.classList.remove("denied-dragging-animation");
|
||||
})
|
||||
|
||||
let widgetClones = document.getElementsByClassName("widgetClone");
|
||||
for (let i=0; i <widgetClones.length; i++){
|
||||
this.$refs.container.removeChild(widgetClones[i]);
|
||||
}
|
||||
|
||||
if (!this.active || this.x < 0 || this.y < 0 || this.x >= this.cols)
|
||||
return this.dragCancel();
|
||||
//if (!this.active || this.x < 0 || this.y < 0 || this.x >= this.cols)
|
||||
//return this.dragCancel();
|
||||
|
||||
this.mode = MODE_IDLE;
|
||||
let updated = [];
|
||||
this.convertGridResultToUpdate(this.positionUpdates, updated);
|
||||
updated = this._updateFixedPositions(updated);
|
||||
if (updated.length)
|
||||
this.$emit('rearrangeItems', updated.filter(v => v));
|
||||
|
||||
this.draggedItem = null;
|
||||
this.draggedNode = null;
|
||||
this.$emit('draggedItem', null);
|
||||
},
|
||||
_updateFixedPositions(updated) {
|
||||
updated.forEach((item, index) => {
|
||||
@@ -597,6 +617,12 @@ export default {
|
||||
draggedItemNode.classList.remove("border-danger");
|
||||
}
|
||||
},
|
||||
removeWidgetClones(){
|
||||
let widgetClones = Array.from(document.getElementsByClassName("widgetClone"));
|
||||
for (let i = 0; i < widgetClones.length; i++) {
|
||||
this.$refs.container.removeChild(widgetClones[i]);
|
||||
}
|
||||
},
|
||||
mouseDown(){
|
||||
this.mode = MODE_MOUSE_DOWN;
|
||||
},
|
||||
@@ -612,7 +638,7 @@ export default {
|
||||
@touchmove="dragOver"
|
||||
@touchend="dragCancel"
|
||||
@dragover.prevent="dragOver"
|
||||
@drop="dragEnd"
|
||||
@drop="dragEnd($event)"
|
||||
@mousemove="updateCursorOnMouseMove"
|
||||
@mouseleave="mouseLeave">
|
||||
<TransitionGroup tag="div">
|
||||
@@ -626,7 +652,7 @@ export default {
|
||||
@mouse-up="mouseUp"
|
||||
@start-resize="startResize"
|
||||
@dragging="dragging"
|
||||
@end-drag="dragCancel"
|
||||
@end-drag="dragEnd"
|
||||
@touch-end="dragEnd();mouseUp();"
|
||||
@touch-start="updateCursorOnMouseMove($event); mouseDown();"
|
||||
class="position-absolute"
|
||||
|
||||
@@ -3,6 +3,7 @@ import FhcFragment from "../Fragment.js";
|
||||
let _uuid = {};
|
||||
|
||||
export default {
|
||||
name: "FormInput",
|
||||
inheritAttrs: false,
|
||||
components: {
|
||||
FhcFragment
|
||||
@@ -220,7 +221,7 @@ export default {
|
||||
if (this.tag == 'VueDatePicker' && !this._.components.VueDatePicker) {
|
||||
this._.components.VueDatePicker = Vue.defineAsyncComponent(() => import("../vueDatepicker.js.php"));
|
||||
} else if (this.tag == 'PvAutocomplete' && !this._.components.PvAutocomplete) {
|
||||
this._.components.PvAutocomplete = Vue.defineAsyncComponent(() => import(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/public/js/components/primevue/autocomplete/autocomplete.esm.min.js"));
|
||||
this._.components.PvAutocomplete = primevue.autocomplete;
|
||||
} else if (this.tag == 'UploadImage' && !this._.components.UploadImage) {
|
||||
this._.components.UploadImage = Vue.defineAsyncComponent(() => import("./Upload/Image.js"));
|
||||
} else if (this.tag == 'UploadDms' && !this._.components.UploadDms) {
|
||||
|
||||
@@ -23,7 +23,8 @@ export default {
|
||||
if (!Array.isArray(feedback))
|
||||
feedback = [feedback];
|
||||
const ts = Date.now();
|
||||
this.feedback[valid ? 'success' : 'danger'] = feedback.map(msg => [msg, ts]);
|
||||
this.feedback[valid ? 'success' : 'danger']
|
||||
.push(...feedback.map(msg => [msg, ts]));
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -295,7 +295,7 @@ export default {
|
||||
showType_id: false,
|
||||
showId: false,
|
||||
showLastupdate: false
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -464,7 +464,6 @@ export default {
|
||||
});
|
||||
},
|
||||
initTinyMCE() {
|
||||
|
||||
const vm = this;
|
||||
tinymce.init({
|
||||
target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component
|
||||
@@ -502,15 +501,15 @@ export default {
|
||||
const columnToShow = "show" + column.charAt(0).toUpperCase() + column.slice(1);
|
||||
this.showVariables[columnToShow] = true;
|
||||
});
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initializeShowVariables();
|
||||
this.getUid();
|
||||
},
|
||||
async mounted() {
|
||||
if(this.showTinyMce){
|
||||
this.initTinyMCE();
|
||||
if (this.showTinyMce) {
|
||||
await this.initTinyMCE();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -548,16 +547,17 @@ export default {
|
||||
this.reload();
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if(this.showTinyMce) {
|
||||
this.editor.destroy();
|
||||
beforeUnmount() {
|
||||
if (this.editor && tinymce.get(this.editor.id)) {
|
||||
tinymce.get(this.editor.id).remove();
|
||||
this.editor = null;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="core-notiz">
|
||||
|
||||
<div v-if="notizLayout=='classicFas'">
|
||||
|
||||
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
|
||||
@@ -318,16 +318,6 @@ export default {
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
v-if="!config.hiddenFields.includes('svnr')"
|
||||
container-class="col-4 stv-details-details-svnr"
|
||||
:label="$p.t('person', 'svnr')"
|
||||
type="text"
|
||||
v-model="data.svnr"
|
||||
name="svnr"
|
||||
maxlength="16"
|
||||
>
|
||||
</form-input>
|
||||
<form-input
|
||||
v-if="!config.hiddenFields.includes('ersatzkennzeichen')"
|
||||
container-class="col-4 stv-details-details-ersatzkennzeichen"
|
||||
|
||||
@@ -17,21 +17,23 @@ export default {
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-notizen h-100 pb-3">
|
||||
<!-- mit factory als endpoint -->
|
||||
<core-notiz
|
||||
class="overflow-hidden"
|
||||
:endpoint="endpoint"
|
||||
ref="formc"
|
||||
notiz-layout="popupModal"
|
||||
type-id="person_id"
|
||||
:id="modelValue.person_id"
|
||||
show-document
|
||||
show-tiny-mce
|
||||
:visible-columns="['titel','text','verfasser','bearbeiter','dokumente']"
|
||||
>
|
||||
</core-notiz>
|
||||
|
||||
|
||||
|
||||
<!-- Test Version classicFas for enter with one click vs popupModal-->
|
||||
<core-notiz
|
||||
class="overflow-hidden"
|
||||
:endpoint="endpoint"
|
||||
ref="formc"
|
||||
notiz-layout="popupModal"
|
||||
type-id="person_id"
|
||||
:id="modelValue.person_id"
|
||||
show-document
|
||||
show-tiny-mce
|
||||
:visibleColumns="['titel','text','verfasser','bearbeiter','dokumente']"
|
||||
@reload="$emit('update:suffix')"
|
||||
>
|
||||
</core-notiz>
|
||||
|
||||
<!--
|
||||
---------------------------------------------------------------------------------------------
|
||||
-------------------- DESCRIPTION FOR PARAMETER PROPS ----------------------------------------
|
||||
|
||||
@@ -146,14 +146,25 @@ export default {
|
||||
this.addStudent({status_kurzbz: 'student', statusgrund_id});
|
||||
},
|
||||
addStudent(data) {
|
||||
Promise
|
||||
.allSettled(
|
||||
this.prestudentIds.map(prestudent_id => this.$api.call(
|
||||
ApiStvStatus.addStudent(prestudent_id, data),
|
||||
{ errorHeader: prestudent_id }
|
||||
))
|
||||
)
|
||||
.then(res => this.showFeedback(res, data.status_kurzbz));
|
||||
this.$api.call(this.prestudentIds.map(prestudent_id => [
|
||||
prestudent_id,
|
||||
ApiStvStatus.addStudent(prestudent_id, data),
|
||||
{ errorHeader: prestudent_id }
|
||||
]))
|
||||
.then(result => {
|
||||
const messagesSuccessful = result.filter(res => res.status == 'fulfilled');
|
||||
if (messagesSuccessful.length) {
|
||||
this.$fhcAlert.alertDefault(
|
||||
'info',
|
||||
'Feedback',
|
||||
messagesSuccessful.length + " erfolgreiche Statusänderung(en) durchgeführt", // TODO(chris): translate
|
||||
false,
|
||||
true
|
||||
);
|
||||
}
|
||||
this.$emit('reloadTable');
|
||||
this.$reloadList();
|
||||
});
|
||||
},
|
||||
changeStatusToAbbrecher(statusgrund_id) {
|
||||
this
|
||||
@@ -247,31 +258,15 @@ export default {
|
||||
},
|
||||
changeStatus(data) {
|
||||
data.currentSemester = this.currentSemester;
|
||||
Promise
|
||||
.allSettled(
|
||||
this.prestudentIds.map(prestudent_id => this.$api.call(
|
||||
ApiStvStatus.changeStatus(prestudent_id, data),
|
||||
{ errorHeader: prestudent_id }
|
||||
))
|
||||
)
|
||||
.then(res => this.showFeedback(res, data.status_kurzbz));
|
||||
},
|
||||
showFeedback(results, status_kurzbz) {
|
||||
const countSuccess = results.filter(result => result.status == "fulfilled").length;
|
||||
const countError = results.length - countSuccess;
|
||||
|
||||
//Feedback Success als infoalert
|
||||
this.$fhcAlert.alertInfo(this.$p.t('ui', 'successNewStatus', {
|
||||
countSuccess,
|
||||
status: status_kurzbz,
|
||||
countError
|
||||
}));
|
||||
|
||||
if(results.length == 1 && countSuccess > 0){
|
||||
this.$api.call(this.prestudentIds.map(prestudent_id => [
|
||||
prestudent_id,
|
||||
ApiStvStatus.changeStatus(prestudent_id, data)
|
||||
]))
|
||||
.then(() => {
|
||||
this.$emit('reloadTable');
|
||||
}
|
||||
this.$reloadList();
|
||||
}
|
||||
this.$reloadList();
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
@@ -359,4 +354,4 @@ export default {
|
||||
</ul>
|
||||
</div>
|
||||
</div>`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -50,7 +50,6 @@ export default {
|
||||
{title:"Wahlname", field:"wahlname", visible:false, headerFilter: true},
|
||||
{title:"Vornamen", field:"vornamen", visible:false, headerFilter: true},
|
||||
{title:"TitelPost", field:"titelpost", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title:"SVNR", field:"svnr", headerFilter: true},
|
||||
{title:"Ersatzkennzeichen", field:"ersatzkennzeichen", headerFilter: true},
|
||||
{title:"Geburtsdatum", field:"gebdatum", formatter:dateFormatter,
|
||||
headerFilter: true, headerFilterFunc: function(headerValue, rowValue, rowData, filterParams) {
|
||||
|
||||
@@ -193,7 +193,7 @@ export default {
|
||||
|
||||
// TODO(chris): move to fhcapi.factory
|
||||
this.$refs.form
|
||||
.send('api/frontend/v1/stv/student/add', data)
|
||||
.post('api/frontend/v1/stv/student/add', data)
|
||||
.then(result => {
|
||||
this.$fhcAlert.alertSuccess('Gespeichert');
|
||||
this.$refs.modal.hide();
|
||||
@@ -213,7 +213,7 @@ export default {
|
||||
},
|
||||
template: `
|
||||
<fhc-form ref="form" class="stv-list-new" @submit.prevent="send">
|
||||
<bs-modal ref="modal" dialog-class="modal-lg modal-scrollable" @hidden-bs-modal="reset">
|
||||
<bs-modal ref="modal" dialog-class="modal-lg modal-dialog-scrollable" @hidden-bs-modal="reset">
|
||||
<template #title>
|
||||
InteressentIn anlegen
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import {CoreRESTClient} from '../../../RESTClient.js';
|
||||
|
||||
|
||||
import PvTree from "../../../../../index.ci.php/public/js/components/primevue/tree/tree.esm.min.js";
|
||||
import PvTreetable from "../../../../../index.ci.php/public/js/components/primevue/treetable/treetable.esm.min.js";
|
||||
import PvColumn from "../../../../../index.ci.php/public/js/components/primevue/column/column.esm.min.js";
|
||||
import ApiStvVerband from '../../../api/factory/stv/verband.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PvTree,
|
||||
PvTreetable,
|
||||
PvColumn
|
||||
PvTreetable: primevue.treetable,
|
||||
PvColumn: primevue.column
|
||||
},
|
||||
emits: [
|
||||
'selectVerband'
|
||||
@@ -31,14 +25,15 @@ export default {
|
||||
selectedKey: [],
|
||||
expandedKeys: {},
|
||||
filters: {}, // TODO(chris): filter only 1st level?
|
||||
favnodes: [],
|
||||
favorites: {on: false, list: []}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
filteredNodes() {
|
||||
// TODO(chris): what to display actually?
|
||||
return this.favorites.on ? this.favnodes : this.nodes;
|
||||
if (this.favorites.on)
|
||||
return this.nodes.filter(node => this.favorites.list.includes(node.key));
|
||||
|
||||
return this.nodes;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -118,69 +113,49 @@ export default {
|
||||
return cp;
|
||||
},
|
||||
async filterFav() {
|
||||
if (!this.favorites.on && !this.favnodes.length && this.favorites.list.length) {
|
||||
this.loading = true;
|
||||
this.favnodes = await this.loadNodes(this.favorites.list);
|
||||
}
|
||||
this.favorites.on = !this.favorites.on;
|
||||
this.$api
|
||||
.call(this.endpoint.favorites.set(
|
||||
JSON.stringify(this.favorites)
|
||||
));
|
||||
this.loading = false;
|
||||
},
|
||||
async loadNodes(links) {
|
||||
let sortedInParents = links.reduce((o, link) => {
|
||||
link = link + '';
|
||||
let parent,
|
||||
parts = link.split('/');
|
||||
if (parts.length == 1) {
|
||||
parent = '_';
|
||||
} else {
|
||||
parts.pop();
|
||||
parent = parts.join('/');
|
||||
}
|
||||
if (!o[parent])
|
||||
o[parent] = [link];
|
||||
else
|
||||
o[parent].push(link);
|
||||
return o;
|
||||
}, {});
|
||||
|
||||
let promises = [];
|
||||
for (let parent in sortedInParents)
|
||||
promises.push(
|
||||
this.$api
|
||||
.call(this.endpoint.get(parent == '_' ? '' : parent))
|
||||
.then(res => res.data)
|
||||
.then(res => res.filter(node => sortedInParents[parent].includes(node.link + '')))
|
||||
);
|
||||
|
||||
// NOTE(chris): merge the resulting arrays and transform them to an associative one
|
||||
let result = [].concat.apply([], await Promise.all(promises)).reduce((o, node) => {
|
||||
o[node.link + ''] = this.mapResultToTreeData({...node, leaf: true, children: undefined});
|
||||
return o;
|
||||
}, {});
|
||||
|
||||
return links.map(link => result[link]);
|
||||
))
|
||||
.then(result => {
|
||||
if (result.meta?.removed) {
|
||||
this.favorites.list = this.favorites.list
|
||||
.filter(fav => !result.meta.removed.includes(fav));
|
||||
const items = result.meta.removed.map(
|
||||
rem => this.nodes.find(
|
||||
node => node.data.link == rem
|
||||
).label
|
||||
).join(',\n');
|
||||
this.$fhcAlert.alertWarning(this.$p.t('stv/warn_removed_favs', { items }));
|
||||
}
|
||||
});
|
||||
},
|
||||
async markFav(key) {
|
||||
let index = this.favorites.list.indexOf(key.data.link + '');
|
||||
|
||||
if (index != -1) {
|
||||
if (this.favnodes.length)
|
||||
this.favnodes = this.favnodes.filter(node => node.data.link != key.data.link);
|
||||
this.favorites.list.splice(index, 1);
|
||||
} else {
|
||||
if (this.favnodes.length || this.favorites.on)
|
||||
this.favnodes.push((await this.loadNodes([key.data.link])).pop());
|
||||
this.favorites.list.push(key.data.link + '');
|
||||
}
|
||||
|
||||
this.$api
|
||||
.call(this.endpoint.favorites.set(
|
||||
JSON.stringify(this.favorites)
|
||||
));
|
||||
))
|
||||
.then(result => {
|
||||
if (result.meta?.removed) {
|
||||
this.favorites.list = this.favorites.list
|
||||
.filter(fav => !result.meta.removed.includes(fav));
|
||||
const items = "\n" + result.meta.removed.map(
|
||||
rem => this.nodes.find(
|
||||
node => node.data.link == rem
|
||||
).label
|
||||
).join(",\n");
|
||||
this.$fhcAlert.alertWarning(this.$p.t('stv/warn_removed_favs', { items }));
|
||||
}
|
||||
});
|
||||
},
|
||||
unsetFavFocus(e) {
|
||||
if (e.target.dataset?.linkFavAdd !== undefined) {
|
||||
@@ -215,6 +190,24 @@ export default {
|
||||
if (!currentNode)
|
||||
return;
|
||||
|
||||
const currentSelectedKey = Object.keys(this.selectedKey).find(Boolean);
|
||||
if (currentSelectedKey) {
|
||||
if (currentSelectedKey == currentKey)
|
||||
return;
|
||||
/**
|
||||
* Do not select a new entry if the current is a child of the new one.
|
||||
* This happens if a child entry of a new stg is selected and the router
|
||||
* tries to select the stg root entry (because subtrees do not have
|
||||
* routes yet)
|
||||
*/
|
||||
const isChild = this.findNodeByKey(
|
||||
currentSelectedKey,
|
||||
currentNode.children
|
||||
);
|
||||
if (isChild)
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 1; i < parts.length; i++)
|
||||
{
|
||||
this.expandedKeys[currentNode.key] = true;
|
||||
@@ -238,7 +231,10 @@ export default {
|
||||
this.$api
|
||||
.call(this.endpoint.get())
|
||||
.then(result => {
|
||||
this.nodes = result.data.map(this.mapResultToTreeData);
|
||||
this.nodes = result.data.map(el => {
|
||||
el.root = true;
|
||||
return this.mapResultToTreeData(el);
|
||||
});
|
||||
this.setPreselection();
|
||||
this.loading = false;
|
||||
})
|
||||
@@ -248,21 +244,12 @@ export default {
|
||||
.call(this.endpoint.favorites.get())
|
||||
.then(result => {
|
||||
if (result.data) {
|
||||
let f = JSON.parse(result.data);
|
||||
if (f.on) {
|
||||
this.loading = true;
|
||||
this.favorites = f;
|
||||
this.loadNodes(this.favorites.list).then(res => {
|
||||
this.favnodes = res;
|
||||
this.loading = false;
|
||||
});
|
||||
} else
|
||||
this.favorites = f;
|
||||
this.favorites = JSON.parse(result.data);
|
||||
}
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
template: `
|
||||
template: /* html */`
|
||||
<div class="overflow-auto" tabindex="-1">
|
||||
<pv-treetable
|
||||
ref="tree"
|
||||
@@ -278,39 +265,68 @@ export default {
|
||||
@focusin="setFavFocus"
|
||||
@focusout="unsetFavFocus"
|
||||
:filters="filters"
|
||||
>
|
||||
<pv-column
|
||||
field="name"
|
||||
expander
|
||||
class="text-break"
|
||||
>
|
||||
<pv-column field="name" expander>
|
||||
<template #header>
|
||||
<div class="text-right">
|
||||
<div class="p-input-icon-left">
|
||||
<i class="pi pi-search"></i>
|
||||
<input type="text" v-model="filters['global']" class="form-control ps-5" placeholder="Search" />
|
||||
<input
|
||||
type="text"
|
||||
v-model="filters['global']"
|
||||
class="form-control ps-5"
|
||||
placeholder="Search"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #body="{node}">
|
||||
<span :data-tree-item-key="node.key" :title="node.data.studiengang_kz">
|
||||
<template #body="{ node }">
|
||||
<span
|
||||
:data-tree-item-key="node.key"
|
||||
:title="node.data.studiengang_kz"
|
||||
>
|
||||
{{node.data.name}}
|
||||
</span>
|
||||
</template>
|
||||
</pv-column>
|
||||
<pv-column field="fav" headerStyle="flex: 0 0 auto" style="flex: 0 0 auto">
|
||||
<pv-column
|
||||
field="fav"
|
||||
class="flex-shrink-0 flex-grow-0"
|
||||
header-class="flex-shrink-0 flex-grow-0"
|
||||
>
|
||||
<template #header>
|
||||
<a href="#" @click.prevent="filterFav"><i :class="favorites.on ? 'fa-solid' : 'fa-regular'" class="fa-star"></i></a>
|
||||
</template>
|
||||
<template #body="{node, column}">
|
||||
<a
|
||||
v-if="favorites.on || favorites.list.length"
|
||||
href="#"
|
||||
@click.prevent="filterFav"
|
||||
>
|
||||
<i
|
||||
:class="favorites.on ? 'fa-solid' : 'fa-regular'"
|
||||
class="fa-star"
|
||||
></i>
|
||||
</a>
|
||||
</template>
|
||||
<template #body="{ node }">
|
||||
<a
|
||||
v-if="node.data.root"
|
||||
href="#"
|
||||
@click.prevent="markFav(node)"
|
||||
@keydown.enter.stop.prevent="markFav(node)"
|
||||
tabindex="-1"
|
||||
data-link-fav-add
|
||||
>
|
||||
<i :class="favorites.list.includes(node.data.link + '') ? 'fa-solid' : 'fa-regular'" class="fa-star"></i>
|
||||
@click.prevent="markFav(node)"
|
||||
@keydown.enter.stop.prevent="markFav(node)"
|
||||
>
|
||||
<i
|
||||
:class="favorites.list.includes(node.data.link + '') ? 'fa-solid' : 'fa-regular'"
|
||||
class="fa-star"
|
||||
></i>
|
||||
</a>
|
||||
</template>
|
||||
</pv-column>
|
||||
<pv-column field="studiengang_kz" class="d-none"></pv-column>
|
||||
</pv-treetable>
|
||||
</div>`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ export default {
|
||||
currentTab() {
|
||||
if (this.tabs[this.current])
|
||||
return this.tabs[this.current];
|
||||
|
||||
|
||||
return { component: 'div' };
|
||||
},
|
||||
value: {
|
||||
@@ -67,9 +67,9 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleTabClick: function(index) {
|
||||
handleTabClick: function (e) {
|
||||
let keys = Object.keys(this.tabs);
|
||||
this.change(keys[index]);
|
||||
this.change(keys[e.index]);
|
||||
},
|
||||
change(key) {
|
||||
this.$emit("change", key)
|
||||
@@ -97,13 +97,20 @@ export default {
|
||||
if (!item.component)
|
||||
return console.error('Component missing for ' + key);
|
||||
|
||||
//making it reactive for showing headerSuffix
|
||||
const value = Vue.reactive({
|
||||
suffix: '',
|
||||
showSuffix: item.showSuffix || false
|
||||
});
|
||||
|
||||
tabs[key] = {
|
||||
component: Vue.markRaw(Vue.defineAsyncComponent(() => import(item.component))),
|
||||
title: Vue.computed(() => item.title || key),
|
||||
config: item.config,
|
||||
key,
|
||||
value: {}
|
||||
}
|
||||
value,
|
||||
suffixhelper: item.suffixhelper ?? null
|
||||
};
|
||||
}
|
||||
|
||||
if (Array.isArray(config))
|
||||
@@ -118,36 +125,67 @@ export default {
|
||||
this.current = Object.keys(tabs)[0];
|
||||
}
|
||||
this.tabs = tabs;
|
||||
},
|
||||
updateSuffix() {
|
||||
this.getTabSuffix(this.currentTab);
|
||||
},
|
||||
async getTabSuffix(tab) {
|
||||
if (!tab.value.showSuffix) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tab.suffixhelper !== null) {
|
||||
const suffixhelper = await import(tab.suffixhelper);
|
||||
const suffix = await suffixhelper.getSuffix(this.$api, this.modelValue);
|
||||
tab.value.suffix = suffix;
|
||||
} else {
|
||||
tab.value.suffix = '';
|
||||
}
|
||||
},
|
||||
getTabSuffixes() {
|
||||
Object.entries(this.tabs).forEach(([key, item]) => this.getTabSuffix(item));
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initConfig(this.config);
|
||||
},
|
||||
mounted() {
|
||||
this.getTabSuffixes();
|
||||
},
|
||||
updated() {
|
||||
this.getTabSuffixes();
|
||||
},
|
||||
template: `
|
||||
<template v-if="useprimevue">
|
||||
|
||||
<tabview
|
||||
:scrollable="true"
|
||||
:lazy="true"
|
||||
:activeIndex="calcActiveIndex"
|
||||
@tab-click="handleTabClick"
|
||||
>
|
||||
<tabpanel
|
||||
v-for="tab in tabs"
|
||||
:key="tab.key"
|
||||
:header="tab.title"
|
||||
<tabview
|
||||
:scrollable="true"
|
||||
:lazy="true"
|
||||
:activeIndex="calcActiveIndex"
|
||||
@tab-click="handleTabClick"
|
||||
>
|
||||
<keep-alive>
|
||||
<component :is="tab.component" v-model="value" :config="tab.config"></component>
|
||||
</keep-alive>
|
||||
</tabpanel>
|
||||
</tabview>
|
||||
<tabpanel
|
||||
v-for="tab in tabs"
|
||||
:key="tab.key"
|
||||
:header="tab.title + ((tab.value.showSuffix && tab.value.suffix !== '') ? ' ' + tab.value.suffix : '')"
|
||||
>
|
||||
<keep-alive>
|
||||
<component
|
||||
:is="tab.component"
|
||||
v-model="value"
|
||||
:config="tab.config"
|
||||
@update:suffix="updateSuffix($event)"
|
||||
></component>
|
||||
</keep-alive>
|
||||
</tabpanel>
|
||||
</tabview>
|
||||
|
||||
</template>
|
||||
<template v-else="">
|
||||
|
||||
<div class="fhc-tabs d-flex" :class="vertical ? 'align-items-stretch gap-3' : (border ? 'flex-column' : 'flex-column gap-3')" v-if="Object.keys(tabs).length">
|
||||
<div class="nav" :class="vertical ? 'nav-pills flex-column' : 'nav-tabs'">
|
||||
|
||||
<div
|
||||
v-for="tab in tabs"
|
||||
:key="tab.key"
|
||||
@@ -157,15 +195,22 @@ export default {
|
||||
:aria-current="tab.key == current ? 'page' : ''"
|
||||
v-accessibility:tab.[vertical]
|
||||
>
|
||||
{{tab.title}}
|
||||
{{tab.title}} <span v-if="tab.value.showSuffix && tab.value.suffix"> {{ tab.value.suffix }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div :style="vertical ? '' : 'flex: 1 1 0%; height: 0%'" class="overflow-auto flex-grow-1" :class="vertical || !border ? '' : 'p-3 border-bottom border-start border-end'">
|
||||
<keep-alive>
|
||||
<component ref="current" :is="currentTab.component" v-model="value" :config="currentTab.config"></component>
|
||||
<component
|
||||
ref="current"
|
||||
:is="currentTab.component"
|
||||
v-model="value"
|
||||
:config="currentTab.config"
|
||||
@update:suffix="updateSuffix($event)"
|
||||
></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>`
|
||||
};
|
||||
|
||||
|
||||
@@ -95,7 +95,6 @@ export const CoreFilterCmpt = {
|
||||
dataset: null,
|
||||
datasetMetadata: null,
|
||||
selectedFields: null,
|
||||
notSelectedFields: null,
|
||||
filterFields: null,
|
||||
|
||||
availableFilters: null,
|
||||
@@ -107,6 +106,8 @@ export const CoreFilterCmpt = {
|
||||
fetchCmptApiFunctionParams: null,
|
||||
fetchCmptDataFetched: null,
|
||||
|
||||
fetchResult: null,
|
||||
|
||||
tabulator: null,
|
||||
tableBuilt: false,
|
||||
tabulatorHasSelector: false,
|
||||
@@ -122,6 +123,11 @@ export const CoreFilterCmpt = {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
notSelectedFields() {
|
||||
if (!this.fields || !this.selectedFields)
|
||||
return null;
|
||||
return this.fields.filter(x => this.selectedFields.indexOf(x) === -1)
|
||||
},
|
||||
filteredData() {
|
||||
if (!this.dataset)
|
||||
return [];
|
||||
@@ -219,6 +225,32 @@ export const CoreFilterCmpt = {
|
||||
await this.$p.loadCategory('ui');
|
||||
placeholder = this.$p.t('ui/keineDatenVorhanden');
|
||||
}
|
||||
|
||||
if (!this.tableOnly) {
|
||||
// prefetch data to get fields & selectedFields for filteredColumns & filteredData
|
||||
await new Promise(resolve => {
|
||||
const filterId = window.location.hash ? window.location.hash.slice(1) : null;
|
||||
|
||||
const resolvePromiseFunc = data => {
|
||||
this.setRenderData(data);
|
||||
resolve();
|
||||
};
|
||||
// get the filter data
|
||||
if (filterId === null)
|
||||
this.startFetchCmpt(
|
||||
wsParams => this.$api.call(ApiFilter.getFilter(wsParams)),
|
||||
null,
|
||||
resolvePromiseFunc
|
||||
);
|
||||
else
|
||||
this.startFetchCmpt(
|
||||
wsParams => this.$api.call(ApiFilter.getFilterById(wsParams)),
|
||||
{ filterId },
|
||||
resolvePromiseFunc
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Define a default tabulator options in case it was not provided
|
||||
let tabulatorOptions = {...{
|
||||
layout: "fitDataStretchFrozen",
|
||||
@@ -240,6 +272,11 @@ export const CoreFilterCmpt = {
|
||||
if (!this.tableOnly) {
|
||||
tabulatorOptions.data = this.filteredData;
|
||||
tabulatorOptions.columns = this.filteredColumns;
|
||||
} else {
|
||||
tabulatorOptions.columns.forEach(col => {
|
||||
if (col.visible === undefined)
|
||||
col.visible = true;
|
||||
});
|
||||
}
|
||||
|
||||
if (tabulatorOptions.selectable || (tabulatorOptions.columns && tabulatorOptions.columns.filter(el => el.formatter == 'rowSelection').length))
|
||||
@@ -359,18 +396,14 @@ export const CoreFilterCmpt = {
|
||||
this.render
|
||||
);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
render(response) {
|
||||
let data = response;
|
||||
setRenderData(data) {
|
||||
this.fetchResult = data;
|
||||
this.filterName = data.filterName;
|
||||
this.dataset = data.dataset;
|
||||
this.datasetMetadata = data.datasetMetadata;
|
||||
|
||||
this.fields = data.fields;
|
||||
this.selectedFields = data.selectedFields;
|
||||
this.notSelectedFields = this.fields.filter(x => this.selectedFields.indexOf(x) === -1);
|
||||
this.filterFields = [];
|
||||
|
||||
for (let i = 0; i < data.datasetMetadata.length; i++)
|
||||
@@ -387,6 +420,14 @@ export const CoreFilterCmpt = {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
render(response) {
|
||||
let data = response;
|
||||
|
||||
this.setRenderData(data);
|
||||
|
||||
// If the side menu is active
|
||||
if (this.sideMenu === true)
|
||||
@@ -627,11 +668,10 @@ export const CoreFilterCmpt = {
|
||||
this.$emit('uuidDefined', this.uuid)
|
||||
},
|
||||
mounted() {
|
||||
|
||||
this.initTabulator().then(() => {
|
||||
if (!this.tableOnly) {
|
||||
this.selectedFilter = window.location.hash ? window.location.hash.slice(1) : null;
|
||||
this.getFilter(); // get the filter data
|
||||
this.render(this.fetchResult);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ class GridLogic {
|
||||
prefer = DIR_RIGHT;
|
||||
}
|
||||
|
||||
const originalFrame = [...item.frame];
|
||||
const originalFrame = Array.isArray(item.frame) ? [...item.frame] : [item.frame];
|
||||
|
||||
const currItem = {...item};
|
||||
currItem.x = x;
|
||||
@@ -146,6 +146,7 @@ class GridLogic {
|
||||
}
|
||||
}
|
||||
replaceUpdate[item.index] = { index: item.index, x, y };
|
||||
|
||||
return replaceUpdate;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import ApiNotizPerson from '../../../../../api/factory/notiz/person.js';
|
||||
|
||||
export async function getSuffix(api, modelValue) {
|
||||
const response = await api
|
||||
.call(ApiNotizPerson.getCountNotes(modelValue.person_id));
|
||||
const suffix = '(' + response.data + ')';
|
||||
return suffix;
|
||||
}
|
||||
@@ -44,7 +44,6 @@ $(document).ready(function ()
|
||||
"nachname" : $('#nachname_input').val(),
|
||||
"titelpost" : $('#titelpost_input').val(),
|
||||
"gebdatum" : $('#gebdatum_input').val(),
|
||||
"svnr" : $('#svnr_input').val(),
|
||||
"buergerschaft" : $('#buergerschaft').val(),
|
||||
"geschlecht" : $('#geschlecht').val(),
|
||||
"gebnation" : $('#gebnation').val(),
|
||||
|
||||
+418
-184
@@ -10,7 +10,232 @@ export default {
|
||||
if (!app.config.globalProperties.$fhcAlert)
|
||||
app.use(FhcAlert);
|
||||
|
||||
function _get_config(form, uri, data, config) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
function _send_array_or_object(errors, func) {
|
||||
if (Array.isArray(errors))
|
||||
errors.forEach(func);
|
||||
else
|
||||
Object.entries(errors).forEach(
|
||||
([title, errs]) => errs.forEach(
|
||||
error => func(error, title)
|
||||
)
|
||||
);
|
||||
}
|
||||
let DEFAULT_ERROR_CONFIG = {
|
||||
success: true,
|
||||
fail: true,
|
||||
combine: {
|
||||
form: ['validation', 'general'],
|
||||
toast: ['validation', 'general', 'not_found', 'site_failed']
|
||||
},
|
||||
handler: {
|
||||
form(form, errors) {
|
||||
form.clearValidation();
|
||||
errors.forEach(err => form.setFeedback(
|
||||
false,
|
||||
err.messages || err.message
|
||||
));
|
||||
},
|
||||
async toast(errors) {
|
||||
const $p = app.config.globalProperties.$p;
|
||||
if (!$p)
|
||||
return Promise.reject('Phrasen plugin not loaded!');
|
||||
|
||||
async function _format_toast(errors) {
|
||||
errors = errors.reduce((result, err) => {
|
||||
switch (err.type) {
|
||||
case 'not_found':
|
||||
case 'site_failed':
|
||||
if (err.message)
|
||||
result[err.message] = [err.url];
|
||||
else
|
||||
result._default = [err.url];
|
||||
break;
|
||||
case 'general':
|
||||
if (!result._default)
|
||||
result._default = [];
|
||||
result._default.push(err.message);
|
||||
break;
|
||||
case 'validation':
|
||||
Object.entries(err.messages)
|
||||
.forEach(([field, msg]) => {
|
||||
if (!result[field])
|
||||
result[field] = [];
|
||||
if (Array.isArray(msg))
|
||||
result[field].push(...msg);
|
||||
else
|
||||
result[field].push(msg);
|
||||
});
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
let counter = 0;
|
||||
const msgs = await Promise.all(Object.entries(errors)
|
||||
.sort((a, b) => ['_default'].indexOf(b[0]) - ['_default'].indexOf(a[0])) // sort _default first
|
||||
.map(async ([field, msgs]) => {
|
||||
if (field == '_default') {
|
||||
await $p.loadCategory('dashboard');
|
||||
const general = $p.t('dashboard/general');
|
||||
field = '<dt class="d-none">' + general + '</dt>';
|
||||
} else {
|
||||
field = '<dt>' + field + '</dt>';
|
||||
}
|
||||
counter += msgs.length;
|
||||
return field
|
||||
+ '<dd>'
|
||||
+ msgs.join('</dd><dd>')
|
||||
+ '</dd>';
|
||||
}));
|
||||
return {
|
||||
counter,
|
||||
msgs
|
||||
}
|
||||
}
|
||||
|
||||
let counter, msgs;
|
||||
if (Array.isArray(errors)) {
|
||||
({ counter, msgs } = await _format_toast(errors));
|
||||
} else {
|
||||
({ counter, msgs } = await Object.entries(errors)
|
||||
.reduce(async (res, [title, errs]) => {
|
||||
const result = await res;
|
||||
const { counter, msgs } = await _format_toast(errs);
|
||||
result.counter += counter;
|
||||
result.msgs.push('<dt>'
|
||||
+ title
|
||||
+ '</dt><dd><dl>'
|
||||
+ msgs.join('')
|
||||
+ '</dl></dd>');
|
||||
return result;
|
||||
}, Promise.resolve({ counter: 0, msgs: []})));
|
||||
}
|
||||
|
||||
await $p.loadCategory('ui');
|
||||
const n_errors = $p.t('ui/n_errors', { n: counter });
|
||||
|
||||
$fhcAlert.alertDefault(
|
||||
'error',
|
||||
n_errors,
|
||||
'<dl>' + msgs.join('') + '</dl>',
|
||||
true,
|
||||
true
|
||||
);
|
||||
},
|
||||
php(errors) {
|
||||
_send_array_or_object(errors, (error, title) => {
|
||||
var message = '';
|
||||
message += 'Message: ' + error.message + '\n\n';
|
||||
message += 'Filename: ' + error.filename + '\n';
|
||||
message += 'Line Number: ' + error.line + '\n';
|
||||
if (error.backtrace && error.backtrace.length) {
|
||||
message += '\nBacktrace: ';
|
||||
error.backtrace.forEach(err => {
|
||||
message += '\n\tFile: ' + err.file + '\n';
|
||||
message += '\tLine: ' + err.line + '\n';
|
||||
message += '\tFunction: ' + err.function + '\n';
|
||||
});
|
||||
}
|
||||
switch (error.severity) {
|
||||
case 'Warning':
|
||||
case 'Core Warning':
|
||||
case 'Compile Warning':
|
||||
case 'User Warning':
|
||||
if (title)
|
||||
title += ': PHP ' + error.severity;
|
||||
else
|
||||
title = 'PHP ' + error.severity;
|
||||
$fhcAlert.alertDefault('warn', title, message, true);
|
||||
break;
|
||||
case 'Notice':
|
||||
case 'User Notice':
|
||||
case 'Runtime Notice':
|
||||
if (title)
|
||||
title += ': PHP ' + error.severity;
|
||||
else
|
||||
title = 'PHP ' + error.severity;
|
||||
$fhcAlert.alertDefault('info', title, message, true);
|
||||
break;
|
||||
default:
|
||||
message = 'Type: PHP ' + error.severity + '\n\n' + message;
|
||||
if (title)
|
||||
message = title + '\n\n' + message;
|
||||
$fhcAlert.alertSystemError(message);
|
||||
break;
|
||||
}
|
||||
});
|
||||
},
|
||||
exception(errors) {
|
||||
_send_array_or_object(errors, (error, title) => {
|
||||
var message = '';
|
||||
if (title)
|
||||
message += title + '\n\n';
|
||||
message += 'Type: ' + error.class + '\n\n';
|
||||
message += 'Message: ' + error.message + '\n\n';
|
||||
message += 'Filename: ' + error.filename + '\n';
|
||||
message += 'Line Number: ' + error.line + '\n';
|
||||
if (error.backtrace && error.backtrace.length) {
|
||||
message += '\nBacktrace: ';
|
||||
error.backtrace.forEach(err => {
|
||||
message += '\n\tFile: ' + err.file + '\n';
|
||||
message += '\tLine: ' + err.line + '\n';
|
||||
message += '\tFunction: ' + err.function + '\n';
|
||||
});
|
||||
}
|
||||
$fhcAlert.alertSystemError(message);
|
||||
});
|
||||
},
|
||||
db(errors) {
|
||||
_send_array_or_object(errors, (error, title) => {
|
||||
var message = '';
|
||||
if (title)
|
||||
message += title + '\n\n';
|
||||
if (error.heading !== undefined)
|
||||
message += error.heading + '\n\n';
|
||||
if (error.code !== undefined)
|
||||
message += 'Code: ' + error.code + '\n\n';
|
||||
if (error.sql !== undefined)
|
||||
message += 'SQL: ' + error.sql + '\n\n';
|
||||
if (error.message !== undefined)
|
||||
message += 'Message: ' + error.message + '\n\n';
|
||||
else if (error.messages !== undefined)
|
||||
message += 'Messages: ' + error.messages.join('\n\t') + '\n\n';
|
||||
if (error.filename !== undefined)
|
||||
message += 'Filename: ' + error.filename + '\n';
|
||||
if (error.line !== undefined)
|
||||
message += 'Line Number: ' + error.line + '\n';
|
||||
|
||||
$fhcAlert.alertSystemError(message);
|
||||
});
|
||||
},
|
||||
auth(errors) {
|
||||
_send_array_or_object(errors, (error, title) => {
|
||||
if (title)
|
||||
title += ': ' + error.message;
|
||||
else
|
||||
title = error.message;
|
||||
|
||||
var message = '';
|
||||
message += 'Controller name: ' + error.controller + '\n';
|
||||
message += 'Method name: ' + error.method + '\n';
|
||||
message += 'Required permissions: ' + error.required_permissions;
|
||||
|
||||
$fhcAlert.alertDefault(
|
||||
'error',
|
||||
title,
|
||||
message,
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (options?.errorHandling !== undefined)
|
||||
DEFAULT_ERROR_CONFIG = _merge_error_config(options.errorHandling);
|
||||
|
||||
function get_config(form, uri, data, config) {
|
||||
if (typeof form == 'string' && config === undefined) {
|
||||
[uri, data, config] = [form, uri, data];
|
||||
form = undefined;
|
||||
@@ -40,22 +265,125 @@ export default {
|
||||
|
||||
return [uri, data, config];
|
||||
}
|
||||
function clean_return_value(response) {
|
||||
if (typeof response.data === 'string' || response.data instanceof String)
|
||||
return clean_return_value({ data: response });
|
||||
|
||||
function _clean_return_value(response) {
|
||||
const result = response.data;
|
||||
delete response.data;
|
||||
if (!result)
|
||||
return {meta: {response}, data: null};
|
||||
if (!result.meta)
|
||||
result.meta = {response};
|
||||
result.meta = { response };
|
||||
else
|
||||
result.meta.response = response;
|
||||
return result;
|
||||
}
|
||||
const baseURL = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/";
|
||||
function _merge_error_config(config) {
|
||||
if (config === false || config === 'off')
|
||||
return { ...DEFAULT_ERROR_CONFIG, success: false, fail: false };
|
||||
|
||||
if (!config || config === true)
|
||||
return { ...DEFAULT_ERROR_CONFIG };
|
||||
|
||||
if (config === 'success')
|
||||
return { ...DEFAULT_ERROR_CONFIG, fail: false };
|
||||
|
||||
if (config === 'fail')
|
||||
return { ...DEFAULT_ERROR_CONFIG, success: false };
|
||||
|
||||
const { success, fail, handler, combine } = config;
|
||||
|
||||
config = { ...DEFAULT_ERROR_CONFIG };
|
||||
|
||||
Object.entries({ fail, success }).forEach(([key, value]) => {
|
||||
if (value !== undefined)
|
||||
config[key] = value;
|
||||
});
|
||||
Object.entries({ handler, combine }).forEach(([key, value]) => {
|
||||
if (value !== undefined)
|
||||
config[key] = { ...config[key], ...value };
|
||||
});
|
||||
|
||||
return config;
|
||||
}
|
||||
function get_error_handler(config) {
|
||||
const result = _merge_error_config(config?.errorHandling);
|
||||
|
||||
if (!config?.form) {
|
||||
result.combine = { ...result.combine, form: [] };
|
||||
} else {
|
||||
const formHandler = result.handler.form;
|
||||
result.handler = { ...result.handler, form: errors => formHandler(config.form, errors) };
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
function get_error_list(error) {
|
||||
if (error.response) {
|
||||
if (error.response.status == 404) {
|
||||
return [{
|
||||
type: 'not_found',
|
||||
message: error.message,
|
||||
url: error.request.responseURL
|
||||
}];
|
||||
} else {
|
||||
return error.response.data.errors;
|
||||
}
|
||||
} else if (error.request) {
|
||||
return [{
|
||||
type: 'site_failed',
|
||||
message: error.message,
|
||||
url: error.request.responseURL
|
||||
}];
|
||||
} else {
|
||||
return [{
|
||||
type: 'script',
|
||||
message: error.message
|
||||
}];
|
||||
}
|
||||
}
|
||||
function popHandleableErrors(errorHandling, errors) {
|
||||
const result = {};
|
||||
const copy = [];
|
||||
while (errors.length)
|
||||
copy.push(errors.pop());
|
||||
for (var error of copy) {
|
||||
let type = error.type;
|
||||
let newType = null;
|
||||
for (var t in errorHandling.combine) {
|
||||
let newTypeCombinesType = errorHandling
|
||||
.combine[t]
|
||||
.includes(type);
|
||||
let newTypeHasHandler = errorHandling.handler[t];
|
||||
if (newTypeCombinesType && newTypeHasHandler) {
|
||||
newType = t;
|
||||
if (newType == 'form')
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (newType)
|
||||
type = newType;
|
||||
const handler = errorHandling.handler[type];
|
||||
if (handler) {
|
||||
if (!result[type])
|
||||
result[type] = [];
|
||||
if (Array.isArray(error))
|
||||
result[type].push(...error);
|
||||
else
|
||||
result[type].push(error);
|
||||
continue;
|
||||
}
|
||||
errors.push(error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const fhcApiAxios = axios.create({
|
||||
timeout: 500000,
|
||||
baseURL: FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/"
|
||||
baseURL: FHC_JS_DATA_STORAGE_OBJECT.app_root
|
||||
+ FHC_JS_DATA_STORAGE_OBJECT.ci_router
|
||||
+ "/"
|
||||
});
|
||||
|
||||
fhcApiAxios.interceptors.request.use(config => {
|
||||
@@ -97,57 +425,51 @@ export default {
|
||||
return config;
|
||||
});
|
||||
|
||||
fhcApiAxios.interceptors.response.use(response => {
|
||||
if (response.config?.errorHandling == 'off'
|
||||
|| response.config?.errorHandling === false
|
||||
|| response.config?.errorHandling == 'fail')
|
||||
return _clean_return_value(response);
|
||||
|
||||
// NOTE(chris): loop through errors
|
||||
if (response.data.errors)
|
||||
response.data.errors = response.data.errors.filter(
|
||||
err => (response.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$api._defaultErrorHandlers[err.type])(err, response.config)
|
||||
);
|
||||
|
||||
return _clean_return_value(response);
|
||||
}, error => {
|
||||
if (error.code == 'ERR_CANCELED')
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
|
||||
if (error.config?.errorHandling == 'off'
|
||||
|| error.config?.errorHandling === false
|
||||
|| error.config?.errorHandling == 'success')
|
||||
return Promise.reject(error);
|
||||
|
||||
if (error.response) {
|
||||
if (error.response.status == 404) {
|
||||
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL, true);
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
}
|
||||
fhcApiAxios.interceptors.response.use(
|
||||
response => {
|
||||
if (response.config?.errorHandling == 'off'
|
||||
|| response.config?.errorHandling === false
|
||||
|| response.config?.errorHandling == 'fail')
|
||||
return clean_return_value(response);
|
||||
|
||||
// NOTE(chris): loop through errors
|
||||
error.response.data.errors = error.response.data.errors.filter(
|
||||
err => (error.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$api._defaultErrorHandlers[err.type])(err, error.config)
|
||||
);
|
||||
if (!error.response.data.errors.length)
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
} else if (error.request) {
|
||||
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL);
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
} else {
|
||||
app.config.globalProperties.$fhcAlert.alertError(error.message);
|
||||
return Promise.reject({...{handled: true}, ...error});
|
||||
}
|
||||
if (response.data.errors)
|
||||
response.data.errors = response.data.errors.filter(
|
||||
err => (response.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$api._defaultErrorHandlers[err.type])(err, response.config)
|
||||
);
|
||||
|
||||
return Promise.reject(error);
|
||||
});
|
||||
return clean_return_value(response);
|
||||
},
|
||||
error => {
|
||||
if (error.code == 'ERR_CANCELED')
|
||||
return Promise.reject({ handled: true, ...error });
|
||||
|
||||
const errorConfig = get_error_handler(error.config);
|
||||
|
||||
if (!errorConfig.fail)
|
||||
return Promise.reject(error);
|
||||
|
||||
const remaining = get_error_list(error);
|
||||
|
||||
const errors = popHandleableErrors(errorConfig, remaining);
|
||||
|
||||
for (var type in errors) {
|
||||
errorConfig.handler[type](errors[type]);
|
||||
}
|
||||
|
||||
if (remaining.length)
|
||||
return Promise.reject(error);
|
||||
|
||||
return Promise.reject({ handled: true, ...error });
|
||||
}
|
||||
);
|
||||
|
||||
app.config.globalProperties.$api = {
|
||||
getUri(url) {
|
||||
return fhcApiAxios.getUri({url});
|
||||
},
|
||||
get(form, uri, params, config) {
|
||||
[uri, params, config] = _get_config(form, uri, params, config);
|
||||
[uri, params, config] = get_config(form, uri, params, config);
|
||||
if (params) {
|
||||
if (config)
|
||||
config.params = params;
|
||||
@@ -157,11 +479,58 @@ export default {
|
||||
return fhcApiAxios.get(uri, config);
|
||||
},
|
||||
post(form, uri, data, config) {
|
||||
[uri, data, config] = _get_config(form, uri, data, config);
|
||||
[uri, data, config] = get_config(form, uri, data, config);
|
||||
return fhcApiAxios.post(uri, data, config);
|
||||
},
|
||||
call(factory, configoverwrite, form) {
|
||||
let {method, url, params, config} = factory;
|
||||
if (Array.isArray(factory)) {
|
||||
const $api = app.config.globalProperties.$api;
|
||||
|
||||
return Promise
|
||||
.allSettled(factory.map((config, index) => {
|
||||
if (!Array.isArray(config))
|
||||
config = ['#' + index, config];
|
||||
return $api.call(config[1], {
|
||||
errorHeader: config[0],
|
||||
errorHandling: false
|
||||
});
|
||||
}))
|
||||
.then(result => {
|
||||
const [ , , config ] = get_config(form, undefined, undefined, configoverwrite || {});
|
||||
const errorConfig = get_error_handler(config);
|
||||
|
||||
if (!errorConfig.success && !errorConfig.fail) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const typedErrors = {};
|
||||
for (var res of result) {
|
||||
const [ allowed, item ] = res.status === 'fulfilled'
|
||||
? [ errorConfig.success, res.value ]
|
||||
: [ errorConfig.fail, res.reason ];
|
||||
if (!allowed)
|
||||
return;
|
||||
|
||||
const errors = popHandleableErrors(errorConfig, get_error_list(item));
|
||||
|
||||
for (var type in errors) {
|
||||
if (!typedErrors[type])
|
||||
typedErrors[type] = {
|
||||
[item.config.errorHeader]: errors[type]
|
||||
};
|
||||
else
|
||||
typedErrors[type][item.config.errorHeader] = errors[type];
|
||||
}
|
||||
};
|
||||
|
||||
for (var errType in typedErrors) {
|
||||
errorConfig.handler[errType](typedErrors[errType]);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
let { method, url, params, config } = factory;
|
||||
if (configoverwrite !== undefined) {
|
||||
config = configoverwrite;
|
||||
}
|
||||
@@ -177,141 +546,6 @@ export default {
|
||||
} else {
|
||||
console.error("FhcApi: method not allowed:", method);
|
||||
}
|
||||
},
|
||||
_defaultErrorHandlers: {
|
||||
validation(error, config) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
if (config?.form) {
|
||||
config.form.clearValidation();
|
||||
config.form.setFeedback(false, error.messages);
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(error.messages)) {
|
||||
error.messages.forEach($fhcAlert.alertError);
|
||||
return false;
|
||||
} else if (typeof error.messages == 'object') {
|
||||
if (config?.errorHeader)
|
||||
Object.values(error.messages).forEach(
|
||||
value => $fhcAlert.alertDefault(
|
||||
'error',
|
||||
Array.isArray(config.errorHeader) ? app.config.globalProperties.$p.t.apply(null, config.errorHeader) : config.errorHeader,
|
||||
value,
|
||||
true
|
||||
)
|
||||
);
|
||||
else
|
||||
Object.entries(error.messages).forEach(
|
||||
([key, value]) => $fhcAlert.alertDefault('error', key, value, true)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
general(error, config) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
if (config?.form)
|
||||
config.form.setFeedback(false, error.message);
|
||||
else if (config?.errorHeader)
|
||||
$fhcAlert.alertDefault(
|
||||
'error',
|
||||
Array.isArray(config.errorHeader) ? app.config.globalProperties.$p.t.apply(null, config.errorHeader) : config.errorHeader,
|
||||
error.message,
|
||||
true
|
||||
);
|
||||
else
|
||||
$fhcAlert.alertError(error.message);
|
||||
},
|
||||
php(error) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
var message = '';
|
||||
message += 'Message: ' + error.message + '\n\n';
|
||||
message += 'Filename: ' + error.filename + '\n';
|
||||
message += 'Line Number: ' + error.line + '\n';
|
||||
if (error.backtrace && error.backtrace.length) {
|
||||
message += '\nBacktrace: ';
|
||||
error.backtrace.forEach(err => {
|
||||
message += '\n\tFile: ' + err.file + '\n';
|
||||
message += '\tLine: ' + err.line + '\n';
|
||||
message += '\tFunction: ' + err.function + '\n';
|
||||
});
|
||||
}
|
||||
switch (error.severity) {
|
||||
case 'Warning':
|
||||
case 'Core Warning':
|
||||
case 'Compile Warning':
|
||||
case 'User Warning':
|
||||
$fhcAlert.alertDefault('warn', 'PHP ' + error.severity, message, true);
|
||||
break;
|
||||
case 'Notice':
|
||||
case 'User Notice':
|
||||
case 'Runtime Notice':
|
||||
$fhcAlert.alertDefault('info', 'PHP ' + error.severity, message, true);
|
||||
break;
|
||||
default:
|
||||
message = 'Type: PHP ' + error.severity + '\n\n' + message;
|
||||
$fhcAlert.alertSystemError(message);
|
||||
break;
|
||||
}
|
||||
},
|
||||
exception(error) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
var message = '';
|
||||
message += 'Type: ' + error.class + '\n\n';
|
||||
message += 'Message: ' + error.message + '\n\n';
|
||||
message += 'Filename: ' + error.filename + '\n';
|
||||
message += 'Line Number: ' + error.line + '\n';
|
||||
if (error.backtrace && error.backtrace.length) {
|
||||
message += '\nBacktrace: ';
|
||||
error.backtrace.forEach(err => {
|
||||
message += '\n\tFile: ' + err.file + '\n';
|
||||
message += '\tLine: ' + err.line + '\n';
|
||||
message += '\tFunction: ' + err.function + '\n';
|
||||
});
|
||||
}
|
||||
$fhcAlert.alertSystemError(message);
|
||||
},
|
||||
db(error) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
var message = '';
|
||||
if (error.heading !== undefined)
|
||||
message += error.heading + '\n\n';
|
||||
if (error.code !== undefined)
|
||||
message += 'Code: ' + error.code + '\n\n';
|
||||
if (error.sql !== undefined)
|
||||
message += 'SQL: ' + error.sql + '\n\n';
|
||||
if (error.message !== undefined)
|
||||
message += 'Message: ' + error.message + '\n\n';
|
||||
else if (error.messages !== undefined)
|
||||
message += 'Messages: ' + error.messages.join('\n\t') + '\n\n';
|
||||
if (error.filename !== undefined)
|
||||
message += 'Filename: ' + error.filename + '\n';
|
||||
if (error.line !== undefined)
|
||||
message += 'Line Number: ' + error.line + '\n';
|
||||
|
||||
$fhcAlert.alertSystemError(message);
|
||||
},
|
||||
auth(error, config) {
|
||||
const $fhcAlert = app.config.globalProperties.$fhcAlert;
|
||||
|
||||
var message = '';
|
||||
message += 'Controller name: ' + error.controller + '\n';
|
||||
message += 'Method name: ' + error.method + '\n';
|
||||
message += 'Required permissions: ' + error.required_permissions;
|
||||
if (config?.errorHeader)
|
||||
$fhcAlert.alertDefault(
|
||||
'error',
|
||||
Array.isArray(config.errorHeader) ? app.config.globalProperties.$p.t.apply(null, config.errorHeader) : config.errorHeader,
|
||||
error.message,
|
||||
true
|
||||
);
|
||||
else
|
||||
$fhcAlert.alertDefault('error', error.message, message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -140,7 +140,16 @@ const helperApp = Vue.createApp({
|
||||
}
|
||||
},
|
||||
template: /* html */`
|
||||
<pv-toast ref="toast" class="fhc-alert" :base-z-index="99999"></pv-toast>
|
||||
<pv-toast ref="toast" class="fhc-alert" :base-z-index="99999">
|
||||
<template #message="{ message }">
|
||||
<!--span :class="slotProps.iconClass"></span-->
|
||||
<div class="p-toast-message-text">
|
||||
<span class="p-toast-summary">{{ message.summary }}</span>
|
||||
<div v-if="message.detail && message.html" class="p-toast-detail" v-html="message.detail"></div>
|
||||
<div v-else-if="message.detail" class="p-toast-detail">{{ message.detail }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</pv-toast>
|
||||
<pv-toast ref="alert" class="fhc-alert" :base-z-index="99999" position="center">
|
||||
<template #message="slotProps">
|
||||
<i class="fa fa-circle-exclamation fa-2xl mt-3"></i>
|
||||
@@ -263,18 +272,18 @@ export default {
|
||||
});
|
||||
});
|
||||
},
|
||||
alertDefault(severity, title, message, sticky = false) {
|
||||
let options = { severity: severity, summary: title, detail: message};
|
||||
alertDefault(severity, title, message, sticky = false, html = false) {
|
||||
let options = { severity: severity, summary: title, detail: message, html };
|
||||
|
||||
if (!sticky)
|
||||
options.life = 3000;
|
||||
|
||||
helperAppInstance.$refs.toast.add(options);
|
||||
},
|
||||
alertMultiple(messageArray, severity = 'info', title = 'Info', sticky = false){
|
||||
alertMultiple(messageArray, severity = 'info', title = 'Info', sticky = false, html = false){
|
||||
// Check, if array has only string values
|
||||
if (messageArray.every(message => typeof message === 'string')) {
|
||||
messageArray.forEach(message => this.alertDefault(severity, title, message, sticky));
|
||||
messageArray.forEach(message => this.alertDefault(severity, title, message, sticky, html));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -123,8 +123,6 @@ foreach($uid_arr as $uid)
|
||||
$studiengang_bezeichnung = empty($studiengangbezeichnung) ? $studiengang->bezeichnung : $studiengangbezeichnung;
|
||||
$studiengang_bezeichnung_englisch = empty($studiengangbezeichnung_englisch) ? $studiengang->english : $studiengangbezeichnung_englisch;
|
||||
|
||||
$svnr = ($student->svnr == '')?'Ersatzkennzeichen: '.$student->ersatzkennzeichen:$student->svnr;
|
||||
|
||||
//Wenn Lehrgang, dann Erhalter-KZ vor die Studiengangs-Kz hängen
|
||||
if ($studiengang->studiengang_kz<0)
|
||||
{
|
||||
@@ -146,7 +144,6 @@ foreach($uid_arr as $uid)
|
||||
echo "\t\t<gebdatum>".$gebdatum."</gebdatum>\n";
|
||||
echo "\t\t<gebort>".$student->gebort."</gebort>\n";
|
||||
echo "\t\t<staatsbuergerschaft>".$staatsbuergerschaft->langtext."</staatsbuergerschaft>\n";
|
||||
echo "\t\t<svnr>".$svnr."</svnr>\n";
|
||||
echo "\t\t<matrikelnr>".trim($student->matrikelnr)."</matrikelnr>\n";
|
||||
echo "\t\t<studiengang>".$db->convert_html_chars($studiengang_bezeichnung)."</studiengang>\n";
|
||||
echo "\t\t<studiengang_englisch>".$db->convert_html_chars($studiengang_bezeichnung_englisch)."</studiengang_englisch>\n";
|
||||
@@ -340,8 +337,6 @@ foreach($prestudent_arr as $prest_id)
|
||||
$studiengang_bezeichnung = empty($studiengangbezeichnung) ? $studiengang->bezeichnung : $studiengangbezeichnung;
|
||||
$studiengang_bezeichnung_englisch = empty($studiengangbezeichnung_englisch) ? $studiengang->english : $studiengangbezeichnung_englisch;
|
||||
|
||||
$svnr = ($person->svnr == '')?($person->ersatzkennzeichen != ''?'Ersatzkennzeichen: '.$person->ersatzkennzeichen:''):$person->svnr;
|
||||
|
||||
//Wenn Lehrgang, dann Erhalter-KZ vor die Studiengangs-Kz hängen
|
||||
if ($studiengang->studiengang_kz<0)
|
||||
{
|
||||
@@ -363,7 +358,6 @@ foreach($prestudent_arr as $prest_id)
|
||||
echo "\t\t<gebdatum>".$gebdatum."</gebdatum>\n";
|
||||
echo "\t\t<gebort>".$person->gebort."</gebort>\n";
|
||||
echo "\t\t<staatsbuergerschaft>".$staatsbuergerschaft->langtext."</staatsbuergerschaft>\n";
|
||||
echo "\t\t<svnr>".$svnr."</svnr>\n";
|
||||
echo "\t\t<studiengang>".$db->convert_html_chars($studiengang_bezeichnung)."</studiengang>\n";
|
||||
echo "\t\t<studiengang_englisch>".$db->convert_html_chars($studiengang_bezeichnung_englisch)."</studiengang_englisch>\n";
|
||||
echo "\t\t<studiengang_kurzbz>".$studiengang->kurzbzlang."</studiengang_kurzbz>\n";
|
||||
|
||||
+2
-7
@@ -235,7 +235,6 @@ function draw_content_liste($row)
|
||||
<STUDENT:vorname><![CDATA['.$row->vorname.']]></STUDENT:vorname>
|
||||
<STUDENT:nachname><![CDATA['.$row->nachname.']]></STUDENT:nachname>
|
||||
<STUDENT:geschlecht><![CDATA['.$row->geschlecht.']]></STUDENT:geschlecht>
|
||||
<STUDENT:svnr>'.($row->svnr==''?' ':'<![CDATA['.$row->svnr.']]>').'</STUDENT:svnr>
|
||||
<STUDENT:ersatzkennzeichen>'.($row->ersatzkennzeichen==''?' ':'<![CDATA['.$row->ersatzkennzeichen.']]>').'</STUDENT:ersatzkennzeichen>
|
||||
<STUDENT:geburtsdatum><![CDATA['.$datum_obj->convertISODate($row->gebdatum).']]></STUDENT:geburtsdatum>
|
||||
<STUDENT:geburtsdatum_iso><![CDATA['.$row->gebdatum.']]></STUDENT:geburtsdatum_iso>
|
||||
@@ -349,7 +348,6 @@ function draw_content($row)
|
||||
<STUDENT:gebzeit><![CDATA['.$row->gebzeit.']]></STUDENT:gebzeit>
|
||||
<STUDENT:anmerkungen>'.($row->anmerkungen==''?' ':'<![CDATA['.$row->anmerkungen.']]>').'</STUDENT:anmerkungen>
|
||||
<STUDENT:anrede><![CDATA['.$row->anrede.']]></STUDENT:anrede>
|
||||
<STUDENT:svnr><![CDATA['.$row->svnr.']]></STUDENT:svnr>
|
||||
<STUDENT:ersatzkennzeichen><![CDATA['.$row->ersatzkennzeichen.']]></STUDENT:ersatzkennzeichen>
|
||||
<STUDENT:familienstand><![CDATA['.$row->familienstand.']]></STUDENT:familienstand>
|
||||
<STUDENT:geschlecht><![CDATA['.$row->geschlecht.']]></STUDENT:geschlecht>
|
||||
@@ -470,7 +468,6 @@ function draw_empty_content()
|
||||
<STUDENT:gebzeit><![CDATA[]]></STUDENT:gebzeit>
|
||||
<STUDENT:anmerkungen><![CDATA[]]></STUDENT:anmerkungen>
|
||||
<STUDENT:anrede><![CDATA[]]></STUDENT:anrede>
|
||||
<STUDENT:svnr><![CDATA[]]></STUDENT:svnr>
|
||||
<STUDENT:ersatzkennzeichen><![CDATA[]]></STUDENT:ersatzkennzeichen>
|
||||
<STUDENT:familienstand><![CDATA[]]></STUDENT:familienstand>
|
||||
<STUDENT:geschlecht><![CDATA[]]></STUDENT:geschlecht>
|
||||
@@ -647,7 +644,7 @@ if($xmlformat=='rdf')
|
||||
$sql_query="
|
||||
SELECT
|
||||
p.person_id, tbl_student.prestudent_id, tbl_benutzer.uid, titelpre, titelpost,vorname, wahlname, vornamen, geschlecht,
|
||||
nachname, gebdatum, tbl_prestudent.anmerkung,ersatzkennzeichen,svnr, tbl_student.matrikelnr, p.anmerkung as anmerkungen,
|
||||
nachname, gebdatum, tbl_prestudent.anmerkung,ersatzkennzeichen, tbl_student.matrikelnr, p.anmerkung as anmerkungen,
|
||||
tbl_studentlehrverband.semester, tbl_studentlehrverband.verband, tbl_studentlehrverband.gruppe,
|
||||
tbl_student.studiengang_kz, aufmerksamdurch_kurzbz, mentor, public.tbl_benutzer.aktiv AS bnaktiv,
|
||||
( SELECT kontakt
|
||||
@@ -985,8 +982,7 @@ if($xmlformat=='rdf')
|
||||
$qry .= " prestudent_id = ".$db->db_add_param($searchItems_string_orig).";";
|
||||
else
|
||||
$qry .= " matrikelnr = ".$db->db_add_param($searchItems_string_orig)." OR
|
||||
matr_nr = ".$db->db_add_param($searchItems_string_orig)." OR
|
||||
svnr = ".$db->db_add_param($searchItems_string_orig).";";
|
||||
matr_nr = ".$db->db_add_param($searchItems_string_orig).";";
|
||||
}
|
||||
if($result = $db->db_query($qry))
|
||||
{
|
||||
@@ -1282,7 +1278,6 @@ else
|
||||
<lv_studiengang_art><![CDATA['.$lv_studiengang_art.']]></lv_studiengang_art>
|
||||
<anrede><![CDATA['.$student->anrede.']]></anrede>
|
||||
<geschlecht><![CDATA['.$student->geschlecht.']]></geschlecht>
|
||||
<svnr><![CDATA['.$student->svnr.']]></svnr>
|
||||
<ersatzkennzeichen><![CDATA['.$student->ersatzkennzeichen.']]></ersatzkennzeichen>
|
||||
<familienstand><![CDATA['.$student->familienstand.']]></familienstand>
|
||||
<rektor><![CDATA['.$rektor.']]></rektor>
|
||||
|
||||
@@ -105,9 +105,6 @@ foreach($uid_arr as $uid)
|
||||
$staatsbuergerschaft = new nation();
|
||||
$staatsbuergerschaft->load($student->staatsbuergerschaft);
|
||||
|
||||
|
||||
$svnr = ($student->svnr == '')?'Ersatzkennzeichen: '.$student->ersatzkennzeichen:$student->svnr;
|
||||
|
||||
$geschlecht_obj = new geschlecht();
|
||||
$geschlecht_obj->load($student->geschlecht);
|
||||
|
||||
@@ -143,7 +140,6 @@ foreach($uid_arr as $uid)
|
||||
echo "\t\t<gebdatum><![CDATA[".$gebdatum."]]></gebdatum>\n";
|
||||
echo "\t\t<gebort><![CDATA[".$student->gebort."]]></gebort>\n";
|
||||
echo "\t\t<staatsbuergerschaft><![CDATA[".$staatsbuergerschaft->langtext."]]></staatsbuergerschaft>\n";
|
||||
echo "\t\t<svnr><![CDATA[".$svnr."]]></svnr>\n";
|
||||
echo "\t\t<matr_nr><![CDATA[".trim($student->matr_nr)."]]></matr_nr>\n";
|
||||
echo "\t\t<matrikelnr><![CDATA[".trim($student->matrikelnr)."]]></matrikelnr>\n";
|
||||
echo "\t\t<studiengang><![CDATA[".$studienordnung->studiengangbezeichnung."]]></studiengang>\n";
|
||||
|
||||
@@ -77,6 +77,7 @@ require_once('dbupdate_3.4/55614_perm_verwaltetoe.php');
|
||||
require_once('dbupdate_3.4/25999_C4_dashboard.php');
|
||||
require_once('dbupdate_3.4/61730_Dashboard_Anpassungen.php');
|
||||
require_once('dbupdate_3.4/40128_search.php');
|
||||
require_once('dbupdate_3.4/66982_berufsschule.php');
|
||||
|
||||
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
||||
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
|
||||
$raum_contentmittitel_xslt_xhtml= <<<EOD
|
||||
<xsl:stylesheet version="1.0" xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
@@ -8,27 +9,56 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||
<head>
|
||||
<title><xsl:value-of select="titel" /></title>
|
||||
<link rel="stylesheet" href="../skin/style.css.php" type="text/css" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/tabulator/5.0.7/css/tabulator.min.css" rel="stylesheet" />
|
||||
<script type="text/javascript" src="https://c3p0.ma0594.technikum-wien.at/fh-core/vendor/olifolkerd/tabulator5/dist/js/tabulator.min.js?2019102903"></script>
|
||||
<link rel="stylesheet" href="../skin/jquery.css" type="text/css" />
|
||||
<link rel="stylesheet" type="text/css" href="../skin/jquery-ui-1.9.2.custom.min.css" />
|
||||
<script type="text/javascript" src="../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>
|
||||
<script type="text/javascript" src="../vendor/christianbach/tablesorter/jquery.tablesorter.min.js"></script>
|
||||
<script type="text/javascript" src="../vendor/components/jqueryui/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="../include/js/jquery.ui.datepicker.translation.js"></script>
|
||||
<script type="text/javascript" src="../vendor/jquery/sizzle/sizzle.js"></script>
|
||||
<link rel="stylesheet" href="../skin/tablesort.css" type="text/css"/>
|
||||
<script type="text/javascript">
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function()
|
||||
{
|
||||
let tables = document.getElementsByClassName("tablesorter");
|
||||
for(table of tables){
|
||||
new Tabulator(table, {
|
||||
layout:"fitDataFill",
|
||||
autoResize:true,
|
||||
resizableRows:true,
|
||||
columnDefaults:{
|
||||
formatter:"html",
|
||||
resizable:true,
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
$(document).ready(function()
|
||||
{
|
||||
$(".tablesorter").each(function()
|
||||
{
|
||||
var col=0;
|
||||
var sort=0;
|
||||
var no_sort=1;
|
||||
var classes = $(this).attr("class");
|
||||
var class_arr = classes.split(" ");
|
||||
var headersobj={};
|
||||
|
||||
for(i in class_arr)
|
||||
{
|
||||
if(class_arr[i].indexOf("tablesorter_col_")!=-1)
|
||||
{
|
||||
col = class_arr[i].substr(16);
|
||||
}
|
||||
|
||||
if(class_arr[i].indexOf("tablesorter_sort_")!=-1)
|
||||
{
|
||||
sort = class_arr[i].substr(17);
|
||||
}
|
||||
|
||||
if(class_arr[i].indexOf("tablesorter_no_sort_")!=-1)
|
||||
{
|
||||
no_sort = class_arr[i].substr(20);
|
||||
headersobj[no_sort]={sorter:false};
|
||||
}
|
||||
}
|
||||
|
||||
$(this).tablesorter(
|
||||
{
|
||||
sortList: [[col,sort]],
|
||||
widgets: ["zebra"],
|
||||
headers: headersobj
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1><xsl:value-of select="titel" /></h1>
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/* Copyright (C) 2025 fhcomplete.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 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.
|
||||
*
|
||||
* Authors: Andreas Österreicher <oesi@technikum-wien.at>,
|
||||
*
|
||||
* Beschreibung:
|
||||
* Aktivität Berufsschule für Zeitaufzeichnung
|
||||
*/
|
||||
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||
|
||||
// Add permission: basis/gehaelter
|
||||
if($result = @$db->db_query("SELECT 1 FROM fue.tbl_aktivitaet WHERE aktivitaet_kurzbz = 'Berufsschule';"))
|
||||
{
|
||||
if($db->db_num_rows($result) == 0)
|
||||
{
|
||||
$qry = "INSERT INTO fue.tbl_aktivitaet(aktivitaet_kurzbz, beschreibung, sort) VALUES('Berufsschule', 'Berufsschule','5');";
|
||||
|
||||
if(!$db->db_query($qry))
|
||||
{
|
||||
echo '<strong>fue.tbl_aktivitaet '.$db->db_last_error().'</strong><br>';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo 'fue.tbl_aktivitaet: Added Aktivitaet "berufsschule"<br>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1456,6 +1456,109 @@ $filters = array(
|
||||
',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
array(
|
||||
'app' => 'personalverwaltung',
|
||||
'dataset_name' => 'schluesselverwaltung',
|
||||
'filter_kurzbz' => 'ma4schluesselverwaltung',
|
||||
'description' => '{MA Schluesselverwaltung}',
|
||||
'sort' => 1,
|
||||
'default_filter' => true,
|
||||
'filter' => '
|
||||
{
|
||||
"name": "MA Schlüsselverwaltung",
|
||||
"columns": [
|
||||
{"name": "UID"},
|
||||
{"name": "PersonId"},
|
||||
{"name": "Vorname"},
|
||||
{"name": "Nachname"},
|
||||
{"name": "EMail"},
|
||||
{"name": "Unternehmen"},
|
||||
{"name": "Vertragsart"},
|
||||
{"name": "DV_von"},
|
||||
{"name": "DV_bis"},
|
||||
{"name": "Wochenstunden"},
|
||||
{"name": "WS_von"},
|
||||
{"name": "WS_bis"},
|
||||
{"name": "Standardkostenstelle"},
|
||||
{"name": "DV_status"}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "DV_status",
|
||||
"option": "",
|
||||
"operation": "nequal",
|
||||
"condition": "beendet"
|
||||
}
|
||||
]
|
||||
}
|
||||
',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
array(
|
||||
'app' => 'personalverwaltung',
|
||||
'dataset_name' => 'schluesselverwaltung',
|
||||
'filter_kurzbz' => 'ma4schluesselverwaltung_beendet',
|
||||
'description' => '{MA Schluesselverwaltung (DV beendet)}',
|
||||
'sort' => 2,
|
||||
'default_filter' => false,
|
||||
'filter' => '
|
||||
{
|
||||
"name": "MA Schlüsselverwaltung (DV beendet)",
|
||||
"columns": [
|
||||
{"name": "UID"},
|
||||
{"name": "PersonId"},
|
||||
{"name": "Vorname"},
|
||||
{"name": "Nachname"},
|
||||
{"name": "EMail"},
|
||||
{"name": "Unternehmen"},
|
||||
{"name": "Vertragsart"},
|
||||
{"name": "DV_von"},
|
||||
{"name": "DV_bis"},
|
||||
{"name": "Wochenstunden"},
|
||||
{"name": "WS_von"},
|
||||
{"name": "WS_bis"},
|
||||
{"name": "Standardkostenstelle"},
|
||||
{"name": "DV_status"}
|
||||
],
|
||||
"filters": [
|
||||
{
|
||||
"name": "DV_status",
|
||||
"option": "",
|
||||
"operation": "equal",
|
||||
"condition": "beendet"
|
||||
}
|
||||
]
|
||||
}
|
||||
',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
array(
|
||||
'app' => 'personalverwaltung',
|
||||
'dataset_name' => 'kontaktdatenverwaltung',
|
||||
'filter_kurzbz' => 'ma4kontaktdaten',
|
||||
'description' => '{MA Kontaktdatenverwaltung}',
|
||||
'sort' => 1,
|
||||
'default_filter' => true,
|
||||
'filter' => '
|
||||
{
|
||||
"name": "MA Kontaktdatenverwaltung",
|
||||
"columns": [
|
||||
{"name": "UID"},
|
||||
{"name": "PersonId"},
|
||||
{"name": "Vorname"},
|
||||
{"name": "Nachname"},
|
||||
{"name": "Unternehmen"},
|
||||
{"name": "Vertragsart"},
|
||||
{"name": "DV_von"},
|
||||
{"name": "DV_bis"},
|
||||
{"name": "Disziplinaere_Zuordnung"},
|
||||
{"name": "DV_status"}
|
||||
],
|
||||
"filters": []
|
||||
}',
|
||||
'oe_kurzbz' => null,
|
||||
),
|
||||
|
||||
);
|
||||
|
||||
// Loop through the filters array
|
||||
|
||||
+951
-44
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user