mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-20 08:22:17 +00:00
Merge remote-tracking branch 'origin/master' into feature-67484/lvverwaltung_finetunning
This commit is contained in:
@@ -336,3 +336,24 @@ $config['navigation_menu']['system/issues/Issues/*'] = array(
|
||||
'requiredPermissions' => array('admin:rw')
|
||||
),
|
||||
);
|
||||
|
||||
$config['navigation_menu']['apps'] = [
|
||||
'stv' => [
|
||||
'link' => site_url('studentenverwaltung'),
|
||||
'description' => 'Studierendenverwaltung',
|
||||
#'icon' => 'users',
|
||||
'requiredPermissions' => array('admin:r', 'assistenz:r')
|
||||
],
|
||||
'lvv' => [
|
||||
'link' => site_url('lVVerwaltung'),
|
||||
'description' => 'LV Verwaltung',
|
||||
#'icon' => 'person-chalkboard',
|
||||
'requiredPermissions' => array('admin:r', 'assistenz:r')
|
||||
],
|
||||
'lav' => [
|
||||
'link' => site_url('lehre/lehrauftrag/Lehrauftrag/Dashboard'),
|
||||
'description' => 'Lehraufträge',
|
||||
#'icon' => 'person-chalkboard',
|
||||
'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r', 'lehre/lehrauftrag_erteilen:r')
|
||||
]
|
||||
];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/*
|
||||
| -------------------------------------------------------------------------
|
||||
@@ -51,7 +51,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
|
||||
| my-controller/my-method -> my_controller/my_method
|
||||
*/
|
||||
$route['default_controller'] = defined('CIS4') && CIS4 ? 'Cis4' : 'Vilesci';
|
||||
$route['translate_uri_dashes'] = FALSE;
|
||||
$route['translate_uri_dashes'] = false;
|
||||
|
||||
// Class name conflicts
|
||||
$route['api/v1/organisation/[S|s]tudiengang/(:any)'] = 'api/v1/organisation/studiengang2/$1';
|
||||
@@ -71,9 +71,9 @@ $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv
|
||||
|
||||
// (studiensemester_kurzbz)/inout[/(incoming|outgoing|gemeinsamestudien)]
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout'] = 'api/frontend/v1/stv/Students/index';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/incoming'] = 'api/frontend/v1/stv/Students/getIncoming';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/outgoing'] = 'api/frontend/v1/stv/Students/getOutgoing';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/gemeinsamestudien'] = 'api/frontend/v1/stv/Students/getGemeinsamestudien';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/incoming'] = 'api/frontend/v1/stv/Students/getIncoming/$1';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/outgoing'] = 'api/frontend/v1/stv/Students/getOutgoing/$1';
|
||||
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/gemeinsamestudien'] = 'api/frontend/v1/stv/Students/getGemeinsamestudien/$1';
|
||||
|
||||
// (studiengang_kz)/prestudent[/(studiensemester_kurzbz)[/(filter)[/(otherfilter)]]]
|
||||
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudents/$1';
|
||||
|
||||
@@ -29,7 +29,7 @@ $config['similar'] = [
|
||||
|
||||
$config['vector'] = [
|
||||
'priority' => 1,
|
||||
'rank' => "ts_rank({field}, to_tsquery('simple', {word}))",
|
||||
'compare' => "to_tsquery('simple', {word}) @@ {field}"
|
||||
'rank' => "ts_rank({field}, plainto_tsquery('simple', {word}))",
|
||||
'compare' => "plainto_tsquery('simple', {word}) @@ {field}"
|
||||
];
|
||||
|
||||
|
||||
@@ -7,5 +7,43 @@ $CI =& get_instance();
|
||||
|
||||
|
||||
$config['student'] = $CI->config->item('student', 'search');
|
||||
$config['student']['searchfields']['pkz'] = [
|
||||
'alias' => ['personenkennzeichen', 'personalid'],
|
||||
'comparison' => 'equals',
|
||||
'field' => 'matrikelnr'
|
||||
];
|
||||
$config['student']['searchfields']['matrnr'] = [
|
||||
'alias' => ['matrikelnr', 'matrikelnummer', 'matrno', 'matriculationno', 'matriculationnumber', 'studno', 'studentno', 'studentnumber'],
|
||||
'comparison' => 'equals',
|
||||
'field' => 'matr_nr',
|
||||
'join' => [
|
||||
[
|
||||
'table' => "public.tbl_prestudent",
|
||||
'using' => "prestudent_id"
|
||||
],
|
||||
[
|
||||
'table' => "public.tbl_person",
|
||||
'using' => "person_id"
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$config['prestudent'] = $CI->config->item('prestudent', 'search');
|
||||
$config['prestudent']['searchfields']['pkz'] = [
|
||||
'alias' => ['personenkennzeichen', 'personalid'],
|
||||
'comparison' => 'equals',
|
||||
'field' => 'matrikelnr',
|
||||
'join' => [
|
||||
'table' => "public.tbl_student",
|
||||
'using' => "prestudent_id"
|
||||
]
|
||||
];
|
||||
$config['prestudent']['searchfields']['matrnr'] = [
|
||||
'alias' => ['matrikelnr', 'matrikelnummer', 'matrno', 'matriculationno', 'matriculationnumber', 'studno', 'studentno', 'studentnumber'],
|
||||
'comparison' => 'equals',
|
||||
'field' => 'matr_nr',
|
||||
'join' => [
|
||||
'table' => "public.tbl_person",
|
||||
'using' => "person_id"
|
||||
]
|
||||
];
|
||||
|
||||
@@ -63,7 +63,7 @@ $config['tabs'] =
|
||||
'showCountNotes' => true
|
||||
]
|
||||
];
|
||||
|
||||
|
||||
// List of fields to show when ZGV_DOKTOR_ANZEIGEN is defined
|
||||
$fieldsZgvDoktor = ['zgvdoktorort', 'zgvdoktordatum', 'zgvdoktornation', 'zgvdoktor_erfuellt', 'zgvdoktor_code'];
|
||||
|
||||
@@ -84,6 +84,11 @@ if (!defined('ZGV_DOKTOR_ANZEIGEN') || !ZGV_DOKTOR_ANZEIGEN) {
|
||||
);
|
||||
}
|
||||
|
||||
$config['tabs']['projektarbeit']['defaultProjektbetreuerStunden'] = '4.0';
|
||||
$config['tabs']['projektarbeit']['defaultProjektbetreuerStundenDiplom'] = '5.0';
|
||||
$config['tabs']['projektarbeit']['lvLektroinnenzuteilungFixangestelltStundensatz'] = true;
|
||||
$config['tabs']['projektarbeit']['defaultProjektbetreuerStundensatz'] = '80.0';
|
||||
|
||||
$config['student_tab_order'] = [
|
||||
'details',
|
||||
'notes',
|
||||
@@ -97,6 +102,7 @@ $config['student_tab_order'] = [
|
||||
'grades',
|
||||
'exam',
|
||||
'exemptions',
|
||||
'projektarbeit',
|
||||
'finalexam',
|
||||
'mobility',
|
||||
'jointstudies',
|
||||
|
||||
@@ -16,7 +16,7 @@ class Messages extends FHCAPI_Controller
|
||||
'getNameOfDefaultRecipient' => ['admin:r', 'assistenz:r'],
|
||||
'sendMessage' => ['admin:r', 'assistenz:r'],
|
||||
'deleteMessage' => ['admin:r', 'assistenz:r'],
|
||||
'getVorlagentext' => ['admin:r', 'assistenz:r'],
|
||||
'getDataVorlage' => ['admin:r', 'assistenz:r'],
|
||||
'getPreviewText' => ['admin:r', 'assistenz:r'],
|
||||
'getReplyData' => ['admin:r', 'assistenz:r'],
|
||||
'getPersonId' => ['admin:r', 'assistenz:r'],
|
||||
@@ -52,11 +52,14 @@ class Messages extends FHCAPI_Controller
|
||||
|
||||
$result = $this->MessageModel->getMessagesForTable($id, $offset, $limit);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
if (hasData($result))
|
||||
{
|
||||
$data = getData($result);
|
||||
$this->addMeta('count', $data['count']);
|
||||
$this->terminateWithSuccess($data['data']);
|
||||
}
|
||||
|
||||
$this->addMeta('count', $data['count']);
|
||||
|
||||
$this->terminateWithSuccess($data['data']);
|
||||
$this->terminateWithSuccess(array());
|
||||
}
|
||||
|
||||
public function getVorlagen()
|
||||
@@ -66,33 +69,23 @@ class Messages extends FHCAPI_Controller
|
||||
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
|
||||
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$oe_kurzbz = current($data);
|
||||
if (hasData($result))
|
||||
{
|
||||
$this->load->model('system/Vorlage_model', 'VorlageModel');
|
||||
|
||||
$this->load->model('system/Vorlage_model', 'VorlageModel');
|
||||
$data = getData($result);
|
||||
|
||||
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$oe_kurzbz = array_column($data, 'oe_kurzbz');
|
||||
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
|
||||
}
|
||||
|
||||
//If admin
|
||||
$this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC');
|
||||
$result = $this->VorlageModel->loadWhere(
|
||||
array(
|
||||
'mimetype' => 'text/html'
|
||||
));
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
$this->terminateWithSuccess(array());
|
||||
}
|
||||
|
||||
public function getVorlagentext($vorlage_kurzbz)
|
||||
public function getDataVorlage($vorlage_kurzbz)
|
||||
{
|
||||
//$this->terminateWithError("vor " . $vorlage_kurzbz, self::ERROR_TYPE_GENERAL);
|
||||
//$studiengang_kz = 227; //TODO(Manu) dynamisieren NULL
|
||||
$studiengang_kz = 0;
|
||||
$this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
|
||||
$this->VorlagestudiengangModel->addOrder('version', 'DESC');
|
||||
@@ -104,12 +97,8 @@ class Messages extends FHCAPI_Controller
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
//not correct with Vorlage
|
||||
$vorlage = current($data);
|
||||
|
||||
//$this->terminateWithSuccess($data);
|
||||
$this->terminateWithSuccess($vorlage->text);
|
||||
$this->terminateWithSuccess($vorlage);
|
||||
}
|
||||
|
||||
public function getMessageVarsPerson($id, $typeId)
|
||||
@@ -154,7 +143,7 @@ class Messages extends FHCAPI_Controller
|
||||
public function sendMessage($recipient_id)
|
||||
{
|
||||
//has to be uid
|
||||
// $this->terminateWithError("uid", $recipient_id, self::ERROR_TYPE_GENERAL);
|
||||
// $this->terminateWithError("uid", $recipient_id, self::ERROR_TYPE_GENERAL);
|
||||
|
||||
//default setting
|
||||
$receiversPersonId = $this->_getPersonId($recipient_id, 'uid');
|
||||
@@ -223,8 +212,6 @@ class Messages extends FHCAPI_Controller
|
||||
}
|
||||
elseif($typeId == 'prestudent_id')
|
||||
{
|
||||
// $this->terminateWithError("prestudent_id ", self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $body);
|
||||
$bodyParsed = $this->getDataOrTerminateWithError($result);
|
||||
}
|
||||
@@ -429,7 +416,7 @@ class Messages extends FHCAPI_Controller
|
||||
|
||||
private function _getPrestudentIdFromUid($uid)
|
||||
{
|
||||
// $this->terminateWithError($uid, self::ERROR_TYPE_GENERAL);
|
||||
// $this->terminateWithError($uid, self::ERROR_TYPE_GENERAL);
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
$result = $this->StudentModel->loadWhere(
|
||||
['student_uid' => $uid]
|
||||
@@ -463,4 +450,4 @@ class Messages extends FHCAPI_Controller
|
||||
date_format(date_create($sentDate), 'd.m.Y H:i'), $receiverName, $receiverSurname, $body
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ class Abschlusspruefung extends FHCAPI_Controller
|
||||
'getBeurteilungen' => ['admin:rw', 'assistenz:rw'],
|
||||
'getAkadGrade' => ['admin:rw', 'assistenz:rw'],
|
||||
'getMitarbeiter' => ['admin:rw', 'assistenz:rw'],
|
||||
'getAllMitarbeiter' => ['admin:rw', 'assistenz:rw'],
|
||||
'getAllPersons' => ['admin:rw', 'assistenz:rw'],
|
||||
'getPruefer' => ['admin:rw', 'assistenz:rw'],
|
||||
'getTypStudiengang' => ['admin:rw', 'assistenz:rw'],
|
||||
'checkForExistingExams' => ['admin:rw', 'assistenz:rw'],
|
||||
@@ -102,35 +100,45 @@ class Abschlusspruefung extends FHCAPI_Controller
|
||||
{
|
||||
$abschlusspruefung_id = $this->input->post('id');
|
||||
|
||||
$this->AbschlusspruefungModel->addSelect('lehre.tbl_abschlusspruefung.*');
|
||||
$this->AbschlusspruefungModel->addSelect("
|
||||
CASE
|
||||
WHEN pruefer1 IS NOT NULL
|
||||
THEN CONCAT(p1.nachname, ' ', p1.vorname, COALESCE(' ' || p1.titelpre, ''))
|
||||
ELSE NULL
|
||||
END AS p1
|
||||
");
|
||||
$this->AbschlusspruefungModel->addSelect("
|
||||
CASE
|
||||
WHEN pruefer2 IS NOT NULL
|
||||
THEN CONCAT(p2.nachname, ' ', p2.vorname, COALESCE(' ' || p2.titelpre, ''))
|
||||
ELSE NULL
|
||||
END AS p2
|
||||
");
|
||||
$this->AbschlusspruefungModel->addSelect("
|
||||
CASE
|
||||
WHEN pruefer3 IS NOT NULL
|
||||
THEN CONCAT(p3.nachname, ' ', p3.vorname, COALESCE(' ' || p3.titelpre, ''))
|
||||
ELSE NULL
|
||||
END AS p3
|
||||
");
|
||||
$this->AbschlusspruefungModel->addSelect("
|
||||
CASE
|
||||
WHEN vorsitz IS NOT NULL
|
||||
THEN CONCAT(pv.nachname, ' ', pv.vorname, COALESCE(' ' || pv.titelpre, ''), ' (', ben.uid , ')' )
|
||||
ELSE NULL
|
||||
END AS pv
|
||||
");
|
||||
$this->AbschlusspruefungModel->addSelect(
|
||||
'lehre.tbl_abschlusspruefung.*,
|
||||
p1.person_id AS p1_person_id, p1.vorname AS p1_vorname, p1.nachname AS p1_nachname,
|
||||
p1.titelpre AS p1_titelpre, p1.titelpost AS p1_titelpost,
|
||||
p2.person_id AS p2_person_id, p2.vorname AS p2_vorname, p2.nachname AS p2_nachname,
|
||||
p2.titelpre AS p2_titelpre, p2.titelpost AS p2_titelpost,
|
||||
p3.person_id AS p3_person_id, p3.vorname AS p3_vorname, p3.nachname AS p3_nachname,
|
||||
p3.titelpre AS p3_titelpre, p3.titelpost AS p3_titelpost,
|
||||
pv.person_id AS pv_person_id, pv.vorname AS pv_vorname, pv.nachname AS pv_nachname,
|
||||
pv.titelpre AS pv_titelpre, pv.titelpost AS pv_titelpost, ben.uid AS pv_uid'
|
||||
);
|
||||
//~ $this->AbschlusspruefungModel->addSelect("
|
||||
//~ CASE
|
||||
//~ WHEN pruefer1 IS NOT NULL
|
||||
//~ THEN CONCAT(p1.nachname, ' ', p1.vorname, COALESCE(' ' || p1.titelpre, ''))
|
||||
//~ ELSE NULL
|
||||
//~ END AS p1
|
||||
//~ ");
|
||||
//~ $this->AbschlusspruefungModel->addSelect("
|
||||
//~ CASE
|
||||
//~ WHEN pruefer2 IS NOT NULL
|
||||
//~ THEN CONCAT(p2.nachname, ' ', p2.vorname, COALESCE(' ' || p2.titelpre, ''))
|
||||
//~ ELSE NULL
|
||||
//~ END AS p2
|
||||
//~ ");
|
||||
//~ $this->AbschlusspruefungModel->addSelect("
|
||||
//~ CASE
|
||||
//~ WHEN pruefer3 IS NOT NULL
|
||||
//~ THEN CONCAT(p3.nachname, ' ', p3.vorname, COALESCE(' ' || p3.titelpre, ''))
|
||||
//~ ELSE NULL
|
||||
//~ END AS p3
|
||||
//~ ");
|
||||
//~ $this->AbschlusspruefungModel->addSelect("
|
||||
//~ CASE
|
||||
//~ WHEN vorsitz IS NOT NULL
|
||||
//~ THEN CONCAT(pv.nachname, ' ', pv.vorname, COALESCE(' ' || pv.titelpre, ''), ' (', ben.uid , ')' )
|
||||
//~ ELSE NULL
|
||||
//~ END AS pv
|
||||
//~ ");
|
||||
$this->AbschlusspruefungModel->addJoin('public.tbl_benutzer ben', 'ON (ben.uid = lehre.tbl_abschlusspruefung.vorsitz)', 'LEFT');
|
||||
$this->AbschlusspruefungModel->addJoin('public.tbl_person pv', 'ON (pv.person_id = ben.person_id)', 'LEFT');
|
||||
$this->AbschlusspruefungModel->addJoin('public.tbl_person p1', 'ON (p1.person_id = lehre.tbl_abschlusspruefung.pruefer1)', 'LEFT');
|
||||
@@ -220,8 +228,10 @@ class Abschlusspruefung extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess($typStudiengang);
|
||||
}
|
||||
|
||||
public function getMitarbeiter($searchString)
|
||||
public function getMitarbeiter()
|
||||
{
|
||||
$searchString = $this->input->get('searchString') ?? '';
|
||||
|
||||
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
|
||||
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'mitAkadGrad');
|
||||
@@ -232,8 +242,10 @@ class Abschlusspruefung extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess($result ?: []);
|
||||
}
|
||||
|
||||
public function getPruefer($searchString)
|
||||
public function getPruefer()
|
||||
{
|
||||
$searchString = $this->input->get('searchString') ?? '';
|
||||
|
||||
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
|
||||
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid');
|
||||
@@ -444,58 +456,4 @@ class Abschlusspruefung extends FHCAPI_Controller
|
||||
}
|
||||
$this->terminateWithSuccess('step3');
|
||||
}
|
||||
|
||||
/*
|
||||
* returns list of all Mitarbeiter
|
||||
* as key value list to be used in select or autocomplete
|
||||
*/
|
||||
public function getAllMitarbeiter()
|
||||
{
|
||||
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
ma.mitarbeiter_uid as mitarbeiter_uid,
|
||||
CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid, ')') as label
|
||||
FROM
|
||||
public.tbl_mitarbeiter ma
|
||||
JOIN public.tbl_benutzer bn ON (bn.uid = ma.mitarbeiter_uid)
|
||||
JOIN public.tbl_person p ON (p.person_id = bn.person_id)
|
||||
ORDER BY
|
||||
p.nachname ASC
|
||||
";
|
||||
|
||||
$result = $this->MitarbeiterModel->execReadOnlyQuery($sql);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
/*
|
||||
* returns list of all Persons
|
||||
* as key value list to be used in select or autocomplete
|
||||
*/
|
||||
public function getAllPersons()
|
||||
{
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
|
||||
$sql = "
|
||||
SELECT
|
||||
p.vorname, p.nachname, p.person_id,
|
||||
CONCAT(p.nachname, ' ', p.vorname) as label
|
||||
FROM
|
||||
public.tbl_person p
|
||||
-- JOIN public.tbl_benutzer bn ON (p.person_id = bn.person_id)
|
||||
-- and bn.aktiv = 'true'
|
||||
ORDER BY
|
||||
p.nachname ASC
|
||||
";
|
||||
|
||||
//TODO(manu) check if filter active benutzer
|
||||
|
||||
$result = $this->PersonModel->execReadOnlyQuery($sql);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ class Archiv extends FHCAPI_Controller
|
||||
'archive' => ['admin:w', 'assistenz:w'],
|
||||
'download' => ['admin:w', 'assistenz:w'],
|
||||
'update' => ['admin:w'],
|
||||
'delete' => ['admin:w', 'assistenz:w']
|
||||
'delete' => ['admin:w', 'assistenz:w'],
|
||||
]);
|
||||
|
||||
// Load models
|
||||
@@ -107,13 +107,9 @@ class Archiv extends FHCAPI_Controller
|
||||
|
||||
$result = $this->AkteModel->load($akte_id);
|
||||
|
||||
|
||||
if (!hasData($result)) $this->terminateWithError('Akte not found');
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$data = getData($result)[0];
|
||||
//$this->addMeta("daa", $data->inhalt);
|
||||
|
||||
$fileObj = new stdClass();
|
||||
if (isset($data->inhalt) && $data->inhalt != '')
|
||||
@@ -133,12 +129,7 @@ class Archiv extends FHCAPI_Controller
|
||||
//header("Content-type: $data->mimetype");
|
||||
header('Content-Disposition: attachment; filename="'.$data->titel.'"');
|
||||
readfile($filename);
|
||||
//echo base64_decode($data->inhalt);
|
||||
die();
|
||||
//~ $fileObj->file = $data->inhalt;
|
||||
//~ $fileObj->name = $data->titel;
|
||||
//~ $fileObj->mimetype = $data->mimetype;
|
||||
//~ $fileObj->disposition = 'attachment';
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -146,12 +137,6 @@ class Archiv extends FHCAPI_Controller
|
||||
|
||||
$result = $this->aktelib->get($akte_id);
|
||||
}
|
||||
|
||||
/* $fileObj->filename
|
||||
* $fileObj->file
|
||||
* $fileObj->name
|
||||
* $fileObj->mimetype
|
||||
* $fileObj->disposition*/
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,7 @@ class Config extends FHCAPI_Controller
|
||||
{
|
||||
// TODO(chris): permissions
|
||||
parent::__construct([
|
||||
'filter' => ['admin:r', 'assistenz:r'],
|
||||
'student' => ['admin:r', 'assistenz:r'],
|
||||
'students' => ['admin:r', 'assistenz:r']
|
||||
]);
|
||||
@@ -45,13 +46,166 @@ class Config extends FHCAPI_Controller
|
||||
'lehre',
|
||||
'stv',
|
||||
'konto',
|
||||
'abschlusspruefung'
|
||||
'abschlusspruefung',
|
||||
'projektarbeit'
|
||||
]);
|
||||
|
||||
// Load Config
|
||||
$this->load->config('stv');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the config for the student filters
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function filter()
|
||||
{
|
||||
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
|
||||
|
||||
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
|
||||
|
||||
$this->BuchungstypModel->addOrder('beschreibung');
|
||||
|
||||
$result = $this->BuchungstypModel->load();
|
||||
|
||||
$buchungstyp_kurzbz = $this->getDataOrTerminateWithError($result);
|
||||
$buchungstyp_kurzbz_plus_all = array_merge([[
|
||||
'buchungstyp_kurzbz' => 'all',
|
||||
'beschreibung' => $this->p->t('stv', 'konto_all_types')
|
||||
]], $buchungstyp_kurzbz);
|
||||
|
||||
$this->load->model('crm/Statusgrund_model', 'StatusgrundModel');
|
||||
|
||||
$result = $this->StatusgrundModel->getAktiveGruende();
|
||||
|
||||
$statusgruende = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$result = [];
|
||||
|
||||
$result[] = [
|
||||
'id' => 'filter_konto_count_0',
|
||||
'label' => $this->p->t('stv', 'filter_konto_count_0'),
|
||||
'type' => 'konto',
|
||||
'fixed' => [
|
||||
'missing' => true,
|
||||
'usestdsem' => true
|
||||
],
|
||||
'dynamic' => [
|
||||
'buchungstyp_kurzbz' => [
|
||||
'type' => 'select',
|
||||
'values' => $buchungstyp_kurzbz,
|
||||
'value_key' => 'buchungstyp_kurzbz',
|
||||
'label_key' => 'beschreibung'
|
||||
]
|
||||
]
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_konto_missing_counter',
|
||||
'label' => $this->p->t('stv', 'filter_konto_missing_counter'),
|
||||
'type' => 'konto_counter',
|
||||
'dynamic' => [
|
||||
'buchungstyp_kurzbz' => [
|
||||
'type' => 'select',
|
||||
'values' => $buchungstyp_kurzbz_plus_all,
|
||||
'value_key' => 'buchungstyp_kurzbz',
|
||||
'label_key' => 'beschreibung'
|
||||
],
|
||||
'samestg' => [
|
||||
'type' => 'bool',
|
||||
'label' => $this->p->t('stv', 'filter_konto_samestg'),
|
||||
'default' => $this->variablelib->getVar('kontofilterstg') == 'true'
|
||||
]
|
||||
]
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_documents',
|
||||
'label' => $this->p->t('stv', 'filter_documents'),
|
||||
'type' => 'documents'
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_konto_missing_counter_past',
|
||||
'label' => $this->p->t('stv', 'filter_konto_missing_counter_past'),
|
||||
'type' => 'konto_counter',
|
||||
'fixed' => [
|
||||
'past' => true
|
||||
],
|
||||
'dynamic' => [
|
||||
'buchungstyp_kurzbz' => [
|
||||
'type' => 'select',
|
||||
'values' => $buchungstyp_kurzbz_plus_all,
|
||||
'value_key' => 'buchungstyp_kurzbz',
|
||||
'label_key' => 'beschreibung'
|
||||
],
|
||||
'samestg' => [
|
||||
'type' => 'bool',
|
||||
'label' => $this->p->t('stv', 'filter_konto_samestg'),
|
||||
'default' => $this->variablelib->getVar('kontofilterstg') == 'true'
|
||||
]
|
||||
]
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_konto_missing_studiengebuehr',
|
||||
'label' => $this->p->t('stv', 'filter_konto_missing_studiengebuehr'),
|
||||
'type' => 'konto',
|
||||
'fixed' => [
|
||||
'missing' => true,
|
||||
'usestdsem' => true
|
||||
],
|
||||
'dynamic' => [
|
||||
'buchungstyp_kurzbz' => [
|
||||
'type' => 'select',
|
||||
'values' => $buchungstyp_kurzbz,
|
||||
'value_key' => 'buchungstyp_kurzbz',
|
||||
'label_key' => 'beschreibung'
|
||||
]
|
||||
]
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_konto_studiengebuehrerhoeht',
|
||||
'label' => $this->p->t('stv', 'filter_konto_studiengebuehrerhoeht'),
|
||||
'type' => 'konto',
|
||||
'fixed' => [
|
||||
'usestdsem' => true
|
||||
],
|
||||
'dynamic' => [
|
||||
'buchungstyp_kurzbz' => [
|
||||
'type' => 'select',
|
||||
'values' => $buchungstyp_kurzbz,
|
||||
'value_key' => 'buchungstyp_kurzbz',
|
||||
'label_key' => 'beschreibung'
|
||||
]
|
||||
]
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_zgv_without_date',
|
||||
'label' => $this->p->t('stv', 'filter_zgv_without_date'),
|
||||
'type' => 'zgv'
|
||||
];
|
||||
$result[] = [
|
||||
'id' => 'filter_statusgrund',
|
||||
'label' => $this->p->t('stv', 'filter_statusgrund'),
|
||||
'type' => 'statusgrund',
|
||||
'fixed' => [
|
||||
'usestdsem' => true
|
||||
],
|
||||
'dynamic' => [
|
||||
'statusgrund_id' => [
|
||||
'type' => 'select',
|
||||
'values' => $statusgruende,
|
||||
'value_key' => 'statusgrund_id',
|
||||
'label_key' => 'bezeichnung'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
Events::trigger('stv_conf_filter', function & () use (&$result) {
|
||||
return $result;
|
||||
});
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
public function student()
|
||||
{
|
||||
$result = [];
|
||||
@@ -59,21 +213,21 @@ class Config extends FHCAPI_Controller
|
||||
|
||||
$result['details'] = [
|
||||
'title' => $this->p->t('stv', 'tab_details'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Details.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Details.js'),
|
||||
'config' => $config['details']
|
||||
];
|
||||
|
||||
$result['notes'] = [
|
||||
'title' => $this->p->t('stv', 'tab_notes'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Notizen.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/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'
|
||||
'suffixhelper' => absoluteJsImportUrl('public/js/helpers/Stv/Studentenverwaltung/Details/Notizen/NotizenSuffixHelper.js')
|
||||
];
|
||||
|
||||
$result['contact'] = [
|
||||
'title' => $this->p->t('stv', 'tab_contact'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Kontakt.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Kontakt.js'),
|
||||
'config' => [
|
||||
'showBankaccount' => $this->permissionlib->isBerechtigt('mitarbeiter/bankdaten')
|
||||
|| $this->permissionlib->isBerechtigt('student/bankdaten')
|
||||
@@ -81,20 +235,20 @@ class Config extends FHCAPI_Controller
|
||||
];
|
||||
$result['prestudent'] = [
|
||||
'title' => $this->p->t('stv', 'tab_prestudent'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Prestudent.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Prestudent.js'),
|
||||
'config' => $config['prestudent']
|
||||
];
|
||||
$result['status'] = [
|
||||
'title' => 'Status',
|
||||
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/MultiStatus.js')
|
||||
];
|
||||
$result['documents'] = [
|
||||
'title' => $this->p->t('stv', 'tab_documents'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Dokumente.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Dokumente.js')
|
||||
];
|
||||
$result['banking'] = [
|
||||
'title' => $this->p->t('stv', 'tab_banking'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Konto.js'),
|
||||
'config' => [
|
||||
'showZahlungsbestaetigung' => (defined('ZAHLUNGSBESTAETIGUNG_ANZEIGEN') && ZAHLUNGSBESTAETIGUNG_ANZEIGEN),
|
||||
'showBuchungsnr' => $this->permissionlib->isBerechtigt('admin'),
|
||||
@@ -106,20 +260,23 @@ class Config extends FHCAPI_Controller
|
||||
];
|
||||
$result['resources'] = [
|
||||
'title' => $this->p->t('stv', 'tab_resources'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Betriebsmittel.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
$result['groups'] = [
|
||||
'title' => $this->p->t('stv', 'tab_groups'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Gruppen.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Groups.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
$result['messages'] = [
|
||||
'title' => $this->p->t('stv', 'tab_messages'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Messages.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Messages.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
|
||||
$result['grades'] = [
|
||||
'title' => $this->p->t('stv', 'tab_grades'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Noten.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Noten.js'),
|
||||
'showOnlyWithUid' => true,
|
||||
'config' => [
|
||||
'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE,
|
||||
@@ -132,29 +289,42 @@ class Config extends FHCAPI_Controller
|
||||
|
||||
$result['exam'] = [
|
||||
'title' => $this->p->t('stv', 'tab_exam'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Pruefung.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Pruefung.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
|
||||
$result['exemptions'] = [
|
||||
'title' => $this->p->t('lehre', 'anrechnungen'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Anrechnungen.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Anrechnungen.js'),
|
||||
'config' => $config['exemptions']
|
||||
];
|
||||
|
||||
$result['finalexam'] = [
|
||||
'title' => $this->p->t('stv', 'tab_finalexam'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung.js'),
|
||||
'showOnlyWithUid' => true,
|
||||
'config' => $config['finalexam']
|
||||
];
|
||||
|
||||
$result['projektarbeit'] = [
|
||||
'title' => $this->p->t('stv', 'tab_projektarbeit'),
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit.js'),
|
||||
'config' => array_merge(
|
||||
$config['projektarbeit'],
|
||||
['showVertragsdetails' =>
|
||||
defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN') && FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN]
|
||||
)
|
||||
];
|
||||
|
||||
$result['mobility'] = [
|
||||
'title' => $this->p->t('stv', 'tab_mobility'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Mobility.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Mobility.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
|
||||
$result['archive'] = [
|
||||
'title' => $this->p->t('stv', 'tab_archive'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Archiv.js'),
|
||||
'config' => [
|
||||
'showEdit' => $this->permissionlib->isBerechtigt('admin')
|
||||
]
|
||||
@@ -162,22 +332,24 @@ class Config extends FHCAPI_Controller
|
||||
|
||||
$result['jointstudies'] = [
|
||||
'title' => $this->p->t('stv', 'tab_jointstudies'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/JointStudies.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/JointStudies.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
|
||||
$result['coursedates'] = [
|
||||
'title' => $this->p->t('stv', 'tab_courseDates'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine.js')
|
||||
];
|
||||
|
||||
$result['admissionDates'] = [
|
||||
'title' => $this->p->t('stv', 'tab_admissionDates'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Aufnahmetermine.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine.js')
|
||||
];
|
||||
|
||||
$result['functions'] = [
|
||||
'title' => $this->p->t('stv', 'tab_functions'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Funktionen.js'
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Funktionen.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
|
||||
Events::trigger('stv_conf_student', function & () use (&$result) {
|
||||
@@ -195,7 +367,7 @@ class Config extends FHCAPI_Controller
|
||||
$config = $this->config->item('tabs');
|
||||
$result['banking'] = [
|
||||
'title' => $this->p->t('stv', 'tab_banking'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Konto.js'),
|
||||
'config' => [
|
||||
'showZahlungsbestaetigung' => (defined('ZAHLUNGSBESTAETIGUNG_ANZEIGEN') && ZAHLUNGSBESTAETIGUNG_ANZEIGEN),
|
||||
'showBuchungsnr' => $this->permissionlib->isBerechtigt('admin'),
|
||||
@@ -205,9 +377,14 @@ class Config extends FHCAPI_Controller
|
||||
'additionalCols' => []
|
||||
]
|
||||
];
|
||||
$result['groups'] = [
|
||||
'title' => $this->p->t('stv', 'tab_groups'),
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Groups.js'),
|
||||
'showOnlyWithUid' => true
|
||||
];
|
||||
$result['status'] = [
|
||||
'title' => 'Status',
|
||||
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/MultiStatus.js'),
|
||||
'config' => [
|
||||
'changeStatusToAbbrecherStgl' => $this->permissionlib->isBerechtigt('admin'),
|
||||
'changeStatusToAbbrecherStud' => $this->permissionlib->isBerechtigt('admin'),
|
||||
@@ -218,17 +395,23 @@ class Config extends FHCAPI_Controller
|
||||
];
|
||||
$result['finalexam'] = [
|
||||
'title' => $this->p->t('stv', 'tab_finalexam'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung.js'),
|
||||
'showOnlyWithUid' => true,
|
||||
'config' => $config['finalexam']
|
||||
];
|
||||
$result['archive'] = [
|
||||
'title' => $this->p->t('stv', 'tab_archive'),
|
||||
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Archiv.js'),
|
||||
'config' => [
|
||||
'showEdit' => $this->permissionlib->isBerechtigt('admin')
|
||||
]
|
||||
];
|
||||
|
||||
$result['kontaktieren'] = [
|
||||
'title' => $this->p->t('stv', 'tab_kontaktieren'),
|
||||
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Kontaktieren.js'),
|
||||
];
|
||||
|
||||
Events::trigger('stv_conf_students', function & () use (&$result) {
|
||||
return $result;
|
||||
});
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use \CI3_Events as Events;
|
||||
use \DateTime as DateTime;
|
||||
|
||||
class Dokumente extends FHCAPI_Controller
|
||||
@@ -19,6 +20,8 @@ class Dokumente extends FHCAPI_Controller
|
||||
'getDoktypen' => ['admin:r', 'assistenz:r'],
|
||||
'uploadDokument' => ['admin:rw', 'assistenz:rw'],
|
||||
'download' => ['admin:rw', 'assistenz:rw'],
|
||||
'getDocumentDropDown' => ['admin:rw', 'assistenz:rw'],
|
||||
'getDocumentDropDownMulti' => ['admin:rw', 'assistenz:rw'],
|
||||
]);
|
||||
|
||||
// Load Libraries
|
||||
@@ -566,4 +569,395 @@ class Dokumente extends FHCAPI_Controller
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDocumentDropDown($prestudent_id, $studiensemester_kurzbz, $studiengang_kz)
|
||||
{
|
||||
$this->load->helper('hlp_common');
|
||||
//permission to create also odt, and doc outputs of certain documents(menu abschlusspruefung)
|
||||
$hasPermissionOutputformat = $this->permissionlib->isBerechtigt('system/change_outputformat', 's');
|
||||
|
||||
if (!$prestudent_id)
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent_id']), self::ERROR_TYPE_GENERAL);
|
||||
if (!$studiensemester_kurzbz)
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiensemester']), self::ERROR_TYPE_GENERAL);
|
||||
if(!$studiengang_kz)
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
|
||||
$uid = $this->_loadUIDFromPrestudent($prestudent_id);
|
||||
$semArray = $this->_getEntriesStudiensemester();
|
||||
$stgTyp = $this->_getStudiengangstyp($studiengang_kz);
|
||||
|
||||
$documents = [
|
||||
buildDropdownEntryPrintArray("accountinfo", "Accountinfoblatt", "xml=accountinfoblatt.xml.php&xsl=AccountInfo&output=pdf", $uid, 10, null),
|
||||
buildDropdownEntryPrintArray("ausbildungsvertrag", "Ausbildungsvertrag", "xml=ausbildungsvertrag.xml.php&xsl=Ausbildungsver&output=pdf", $uid, 20, null),
|
||||
buildDropdownEntryPrintArray("ausbildungsvertrag_en", "Ausbildungsvertrag Englisch", "xml=ausbildungsvertrag.xml.php&xsl=AusbVerEng&output=pdf", $uid, 21, null),
|
||||
buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf", $uid, 40, null),
|
||||
buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf", $uid, 41, null),
|
||||
buildDropdownEntryPrintArray("zutrittskarte", "Zutrittskarte", "xsl=ZutrittskarteStud&output=pdf&data=$uid", $uid,100, "zutrittskarte.php"),
|
||||
buildDropdownEntryPrintArray("studienblatt", "Studienblatt", "xml=studienblatt.xml.php&xsl=Studienblatt&output=pdf&ss=$studiensemester_kurzbz", $uid, 60, null),
|
||||
buildDropdownEntryPrintArray("studienblatt_eng", "Studienblatt Englisch", "xml=studienblatt.xml.php&xsl=StudienblattEng&output=pdf&ss=$studiensemester_kurzbz", $uid, 61, null),
|
||||
|
||||
$this->buildStudienerfolgSubmenu("de", $uid, $semArray, $studiensemester_kurzbz),
|
||||
$this->buildStudienerfolgSubmenu("en", $uid, $semArray, $studiensemester_kurzbz),
|
||||
$this->buildStudienerfolgSubmenu("de", $uid, $semArray, $studiensemester_kurzbz, true),
|
||||
$this->buildStudienerfolgSubmenu("en", $uid, $semArray, $studiensemester_kurzbz, true),
|
||||
|
||||
[
|
||||
"id" => "submenu_studstatus",
|
||||
"type" => "submenu",
|
||||
"name" => "Verwaltung des StudierendenStatus",
|
||||
"order" => 110,
|
||||
"data" => [
|
||||
buildDropdownEntryPrintArray("Abmeldung", "Abmeldung", "xml=AntragAbmeldung.xml.php&xsl=AntragAbmeldung&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
|
||||
buildDropdownEntryPrintArray("Abmeldung durch Stgl", "AntragAbmeldungStgl", "xml=AntragAbmeldungStgl.xml.php&xsl=AntragAbmeldungStgl&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
|
||||
buildDropdownEntryPrintArray("Unterbrechung", "Unterbrechung", "xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
|
||||
buildDropdownEntryPrintArray("Wiederholung", "Abmeldung durch Ablauf der Wiederholungsfrist", "xml=AntragWiederholung.xml.php&xsl=AntragWiederholung&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
|
||||
]
|
||||
],
|
||||
|
||||
$this->loadDropDownEntriesFinalExam($hasPermissionOutputformat, $stgTyp, $uid),
|
||||
|
||||
buildDropdownEntryPrintArray("bescheid", "Bescheid (nur Voransicht)", "xml=abschlusspruefung.rdf.php&xsl_stg_kz=$studiengang_kz&xsl=Bescheid&output=pdf", $uid, 80, null),
|
||||
buildDropdownEntryPrintArray("diplomasupp", "Diploma Supplement (nur Voransicht)", "xml=diplomasupplement.xml.php&xsl_stg_kz=$studiengang_kz&xsl=DiplSupplement&output=pdf", $uid, 81, null)
|
||||
];
|
||||
|
||||
Events::trigger('DocumentGenerationDropDown',
|
||||
// passing $menu per reference
|
||||
function & () use (&$documents) {
|
||||
return $documents;
|
||||
},
|
||||
$prestudent_id,
|
||||
$studiensemester_kurzbz,
|
||||
$studiengang_kz
|
||||
);
|
||||
|
||||
usort($documents, function ($a, $b) {
|
||||
$orderA = isset($a['order']) ? (int)$a['order'] : PHP_INT_MAX;
|
||||
$orderB = isset($b['order']) ? (int)$b['order'] : PHP_INT_MAX;
|
||||
return $orderA <=> $orderB;
|
||||
});
|
||||
|
||||
|
||||
$this->terminateWithSuccess($documents);
|
||||
return $documents || null;
|
||||
}
|
||||
|
||||
public function getDocumentDropDownMulti($studiensemester_kurzbz,$studiengang_kz)
|
||||
{
|
||||
//permission to create also odt, and doc outputs of certain documents (menu abschlusspruefung)
|
||||
$hasPermissionOutputformat = $this->permissionlib->isBerechtigt('system/change_outputformat', 's');
|
||||
|
||||
$studentUids = $this->input->get('studentUids');
|
||||
$prestudentIds = [];
|
||||
|
||||
if (is_array($studentUids) && !empty($studentUids)) {
|
||||
foreach ($studentUids as $uid) {
|
||||
$prestudent_id = $this-> _loadPrestudentFromUid($uid);
|
||||
$prestudentIds[] = $prestudent_id;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Array StudentUIDs']), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
if (!$studiensemester_kurzbz)
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiensemester']), self::ERROR_TYPE_GENERAL);
|
||||
if(!$studiengang_kz)
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
|
||||
$uidString = implode(";", $studentUids);
|
||||
$prestudentIdsString = implode(";", $prestudentIds);
|
||||
|
||||
$semArray = $this->_getEntriesStudiensemester();
|
||||
$stgTyp = $this->_getStudiengangstyp($studiengang_kz);
|
||||
|
||||
$documents = [
|
||||
buildDropdownEntryPrintArray("accountinfo", "Accountinfoblatt", "xml=accountinfoblatt.xml.php&xsl=AccountInfo&output=pdf", $uidString, 10, null),
|
||||
buildDropdownEntryPrintArray("ausbildungsvertrag", "Ausbildungsvertrag", "xml=ausbildungsvertrag.xml.php&xsl=Ausbildungsver&output=pdf", $uidString, 20, null),
|
||||
buildDropdownEntryPrintArray("ausbildungsvertrag_en", "Ausbildungsvertrag Englisch", "xml=ausbildungsvertrag.xml.php&xsl=AusbVerEng&output=pdf", $uidString, 21, null),
|
||||
buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf", $uidString, 40, null),
|
||||
buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf", $uidString, 41, null),
|
||||
buildDropdownEntryPrintArray("zutrittskarte", "Zutrittskarte", "xsl=ZutrittskarteStud&output=pdf&data=$uidString", $uidString,100, "zutrittskarte.php"),
|
||||
buildDropdownEntryPrintArray("studienblatt", "Studienblatt", "xml=studienblatt.xml.php&xsl=Studienblatt&output=pdf&ss=$studiensemester_kurzbz", $uidString, 60, null),
|
||||
buildDropdownEntryPrintArray("studienblatt_eng", "Studienblatt Englisch", "xml=studienblatt.xml.php&xsl=StudienblattEng&output=pdf&ss=$studiensemester_kurzbz", $uidString, 61, null),
|
||||
|
||||
// Studienerfolg Menüs automatisch
|
||||
$this->buildStudienerfolgSubmenu("de", $uidString, $semArray, $studiensemester_kurzbz),
|
||||
$this->buildStudienerfolgSubmenu("en", $uidString, $semArray, $studiensemester_kurzbz),
|
||||
$this->buildStudienerfolgSubmenu("de", $uidString, $semArray, $studiensemester_kurzbz, true),
|
||||
$this->buildStudienerfolgSubmenu("en", $uidString, $semArray, $studiensemester_kurzbz, true),
|
||||
|
||||
[
|
||||
"id" => "submenu_studstatus",
|
||||
"type" => "submenu",
|
||||
"name" => "Verwaltung des StudierendenStatus",
|
||||
"order" => 110,
|
||||
"data" => [
|
||||
buildDropdownEntryPrintArray("Abmeldung", "Abmeldung", "xml=AntragAbmeldung.xml.php&xsl=AntragAbmeldung&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
|
||||
buildDropdownEntryPrintArray("Abmeldung durch Stgl", "AntragAbmeldungStgl", "xml=AntragAbmeldungStgl.xml.php&xsl=AntragAbmeldungStgl&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
|
||||
buildDropdownEntryPrintArray("Unterbrechung", "Unterbrechung", "xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
|
||||
buildDropdownEntryPrintArray("Wiederholung", "Abmeldung durch Ablauf der Wiederholungsfrist", "xml=AntragWiederholung.xml.php&xsl=AntragWiederholung&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
|
||||
]
|
||||
],
|
||||
|
||||
$this->loadDropDownEntriesFinalExam($hasPermissionOutputformat, $stgTyp, $uidString),
|
||||
|
||||
//TODO(Manu) also in Fas multi not working
|
||||
/* buildDropdownEntryPrintArray("bescheid", "Bescheid (nur Voransicht)", "xml=abschlusspruefung.rdf.php&xsl_stg_kz=$studiengang_kz&xsl=Bescheid&output=pdf", $uidString, 80, null),
|
||||
*/
|
||||
|
||||
buildDropdownEntryPrintArray("diplomasupp", "Diploma Supplement (nur Voransicht)", "xml=diplomasupplement.xml.php&xsl_stg_kz=$studiengang_kz&xsl=DiplSupplement&output=pdf", $uidString, 81, null)
|
||||
];
|
||||
|
||||
Events::trigger('DocumentGenerationDropDownMulti',
|
||||
// passing $menu per reference
|
||||
function & () use (&$documents) {
|
||||
return $documents;
|
||||
},
|
||||
$studentUids,
|
||||
$studiensemester_kurzbz,
|
||||
$studiengang_kz
|
||||
);
|
||||
|
||||
usort($documents, function ($a, $b) {
|
||||
$orderA = isset($a['order']) ? (int)$a['order'] : PHP_INT_MAX;
|
||||
$orderB = isset($b['order']) ? (int)$b['order'] : PHP_INT_MAX;
|
||||
return $orderA <=> $orderB;
|
||||
});
|
||||
|
||||
|
||||
$this->terminateWithSuccess($documents);
|
||||
|
||||
return $documents || null;
|
||||
}
|
||||
|
||||
private function _loadUIDFromPrestudent($prestudent_id)
|
||||
{
|
||||
if(!$prestudent_id){
|
||||
return $this->terminateWithError("no prestudent ID received.");
|
||||
}
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
$result = $this->StudentModel->loadWhere(
|
||||
['prestudent_id' => $prestudent_id]
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$student = current($data);
|
||||
|
||||
return $student->student_uid;
|
||||
}
|
||||
|
||||
private function _loadPrestudentFromUid($studentUid)
|
||||
{
|
||||
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
$result = $this->StudentModel->loadWhere(
|
||||
['student_uid' => $studentUid]
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$student = current($data);
|
||||
|
||||
|
||||
return $student->prestudent_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* is building an array with studiensemesterkurzb
|
||||
* actual studiensemester plus the 5 studiensemester in the past
|
||||
|
||||
* @return Array Studiensemester_kurzbz
|
||||
*/
|
||||
private function _getEntriesStudiensemester(){
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
$this->StudiensemesterModel->addPlusMinus(1, 5);
|
||||
$this->StudiensemesterModel->addOrder('ende', 'DESC');
|
||||
$result = $this->StudiensemesterModel->load();
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
foreach($data as $sem)
|
||||
{
|
||||
$semArray[] = $sem->studiensemester_kurzbz;
|
||||
}
|
||||
|
||||
array_shift($semArray);
|
||||
|
||||
return $semArray;
|
||||
}
|
||||
/**
|
||||
* is returning the typ of Studiengang (Bakk oder Master)
|
||||
|
||||
* @return character eg. 'b' or 'm'
|
||||
*/
|
||||
private function _getStudiengangstyp($studiengang_kz)
|
||||
{
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
|
||||
$result = $this->StudiengangModel->loadWhere(
|
||||
array('studiengang_kz' => $studiengang_kz)
|
||||
);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$typStudiengang = current($data)->typ;
|
||||
|
||||
return $typStudiengang;
|
||||
}
|
||||
|
||||
/**
|
||||
* helper function to create ArrayStructure
|
||||
* actual studiensemester plus the 5 studiensemester in the past
|
||||
|
||||
* @return Array Studiensemester_kurzbz
|
||||
*/
|
||||
private function buildStudienerfolgSubmenu($lang, $uid, $semArray, $studiensemester_kurzbz, $fa = false)
|
||||
{
|
||||
$entries = [];
|
||||
|
||||
$xsl = $lang === "de" ? "Studienerfolg" : "StudienerfolgEng";
|
||||
$idPrefix = "submenu_studienerfolg_" . $lang . ($fa ? "_fa" : "");
|
||||
|
||||
$entries[] = buildDropdownEntryPrintArray(
|
||||
$idPrefix . "_aktuell",
|
||||
"ausgewähltes Semester",
|
||||
"xml=studienerfolg.rdf.php&xsl=$xsl&ss=$studiensemester_kurzbz" . ($fa ? "&typ=finanzamt" : ""),
|
||||
$uid
|
||||
);
|
||||
|
||||
//all semester
|
||||
$entries[] = buildDropdownEntryPrintArray(
|
||||
$idPrefix . "_all",
|
||||
"alle Semester",
|
||||
"xml=studienerfolg.rdf.php&xsl=$xsl&ss=$studiensemester_kurzbz&all=true" . ($fa ? "&typ=finanzamt" : ""),
|
||||
$uid
|
||||
);
|
||||
|
||||
//sem from array
|
||||
foreach ($semArray as $i => $sem) {
|
||||
$entries[] = buildDropdownEntryPrintArray(
|
||||
$idPrefix . ($i === 0 ? "_akt" : "_minus" . $i),
|
||||
$sem,
|
||||
"xml=studienerfolg.rdf.php&xsl=$xsl&ss=$sem" . ($fa ? "&typ=finanzamt" : ""),
|
||||
$uid
|
||||
);
|
||||
|
||||
}
|
||||
$order = 0;
|
||||
if ($lang === "de" && !$fa) $order = 75; // Studienerfolg
|
||||
if ($lang === "en" && !$fa) $order = 76; // Studienerfolg Englisch
|
||||
if ($lang === "de" && $fa) $order = 77; // Studienerfolg Finanzamt
|
||||
if ($lang === "en" && $fa) $order = 78; // Studienerfolg Finanzamt Englisch
|
||||
|
||||
return [
|
||||
"id" => $idPrefix,
|
||||
"type" => "submenu",
|
||||
"name" => "Studienerfolg " . ($fa ? " Finanzamt" : "") . ($lang === "de" ? "" : "Englisch") ,
|
||||
"order" => $order,
|
||||
"data" => $entries,
|
||||
];
|
||||
}
|
||||
|
||||
private function loadDropDownEntriesFinalExam($hasPermissionOutputformat, $stgTyp, $uid)
|
||||
{
|
||||
if ($stgTyp == 'b')
|
||||
$postfix = 'Bakk';
|
||||
else if ($stgTyp == 'm' || $stgTyp == 'd')
|
||||
$postfix = 'Master';
|
||||
else
|
||||
return [];
|
||||
|
||||
$arrayFinalExam = [
|
||||
'pruefungsprotokoll' => [
|
||||
'de' => [
|
||||
'Bakk' => 'PrProtBA',
|
||||
'Master' => 'PrProtMA',
|
||||
],
|
||||
'en' => [
|
||||
'Bakk' => 'PrProtBAEng',
|
||||
'Master' => 'PrProtMAEng',
|
||||
],
|
||||
],
|
||||
'pruefungszeugnis' => [
|
||||
'de' => [
|
||||
'Bakk' => 'Bakkzeugnis',
|
||||
'Master' => 'Diplomzeugnis',
|
||||
],
|
||||
'en' => [
|
||||
'Bakk' => 'BakkzeugnisEng',
|
||||
'Master' => 'DiplomzeugnisEng',
|
||||
],
|
||||
],
|
||||
'urkunde' => [
|
||||
'de' => [
|
||||
'Bakk' => 'Bakkurkunde',
|
||||
'Master' => 'Diplomurkunde',
|
||||
],
|
||||
'en' => [
|
||||
'Bakk' => 'BakkurkundeEng',
|
||||
'Master' => 'DiplomurkundeEng',
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$langLabels = [
|
||||
"de" => "Deutsch",
|
||||
"en" => "Englisch"
|
||||
];
|
||||
|
||||
$docLabels = [
|
||||
"pruefungsprotokoll" => "Prüfungsprotokoll",
|
||||
"pruefungszeugnis" => "Zeugnis",
|
||||
"urkunde" => "Urkunde"
|
||||
];
|
||||
|
||||
$submenuData = [];
|
||||
if ($hasPermissionOutputformat) {
|
||||
foreach ($arrayFinalExam as $docType => $langs) {
|
||||
foreach ($langs as $lang => $types) {
|
||||
$xsl = $types[$postfix];
|
||||
$idPrefix = $docType . "_" . $lang;
|
||||
|
||||
$baseName = $docLabels[$docType] . " " . $langLabels[$lang];
|
||||
$baseUrl = "xml=abschlusspruefung.rdf.php&xsl={$xsl}";
|
||||
|
||||
//3 outputformates
|
||||
foreach (["pdf", "odt", "docx"] as $format) {
|
||||
$submenuData[] = buildDropdownEntryPrintArray(
|
||||
$idPrefix . "_" . $format,
|
||||
$baseName . " (" . strtoupper($format) . ")",
|
||||
$baseUrl . "&output=" . $format,
|
||||
$uid
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($arrayFinalExam as $docType => $langs) {
|
||||
foreach ($langs as $lang => $types) {
|
||||
$xsl = $types[$postfix]; // Auswahl Bakk/Master für jeweilige Sprache
|
||||
$id = $docType . "_" . $lang;
|
||||
|
||||
$name = $docLabels[$docType] . " " . $langLabels[$lang];
|
||||
|
||||
$url = "xml=abschlusspruefung.rdf.php&xsl=" . $xsl . "&output=pdf";
|
||||
|
||||
$submenuData[] = buildDropdownEntryPrintArray($id, $name, $url, $uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [
|
||||
"id" => "submenu_finalexam",
|
||||
"type" => "submenu",
|
||||
"name" => "Abschlussprüfung",
|
||||
"data" => $submenuData,
|
||||
"order" => null,
|
||||
"order" => 80,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ class Gruppen extends FHCAPI_Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'add' => ['admin:rw', 'assistenz:rw'],
|
||||
'search' => ['admin:r', 'assistenz:r'],
|
||||
'getGruppen' => ['admin:r', 'assistenz:r'],
|
||||
'deleteGruppe' => ['admin:rw', 'assistenz:rw'],
|
||||
]);
|
||||
@@ -18,7 +20,9 @@ class Gruppen extends FHCAPI_Controller
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'ui', 'gruppenmanagement'
|
||||
'ui',
|
||||
'gruppenmanagement',
|
||||
'lehre'
|
||||
]);
|
||||
|
||||
// Load models
|
||||
@@ -26,15 +30,140 @@ class Gruppen extends FHCAPI_Controller
|
||||
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
|
||||
}
|
||||
|
||||
public function add()
|
||||
{
|
||||
$this->load->library("form_validation");
|
||||
|
||||
$this->form_validation->set_rules(
|
||||
'gruppe_kurzbz',
|
||||
$this->p->t('gruppenmanagement', 'gruppe'),
|
||||
'required|is_in_db[organisation/Gruppe_model]',
|
||||
[
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired'),
|
||||
'is_in_db' => $this->p->t('ui', 'error_fieldNotFound')
|
||||
]
|
||||
);
|
||||
$this->form_validation->set_rules(
|
||||
'uid',
|
||||
$this->p->t('ui', 'student_uid'),
|
||||
'required|is_in_db[crm/Student_model:student_uid]',
|
||||
[
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired'),
|
||||
'is_in_db' => $this->p->t('ui', 'error_fieldNotFound')
|
||||
]
|
||||
);
|
||||
$this->form_validation->set_rules(
|
||||
'studiensemester_kurzbz',
|
||||
$this->p->t('lehre', 'studiensemester'),
|
||||
'required|is_in_db[organisation/Studiensemester_model]',
|
||||
[
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired'),
|
||||
'is_in_db' => $this->p->t('ui', 'error_fieldNotFound')
|
||||
]
|
||||
);
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$gruppe_kurzbz = $this->input->post('gruppe_kurzbz');
|
||||
$uid = $this->input->post('uid');
|
||||
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
|
||||
|
||||
$result = $this->BenutzergruppeModel->load([
|
||||
$gruppe_kurzbz,
|
||||
$uid
|
||||
]);
|
||||
$benutzergruppe = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
if ($benutzergruppe) {
|
||||
$this->terminateWithError(
|
||||
$this->p->t('gruppenmanagement', 'error_alreadyInGroup', [
|
||||
'uid' => $uid,
|
||||
'studiensemester_kurzbz' => current($benutzergruppe)->studiensemester_kurzbz
|
||||
]),
|
||||
self::ERROR_TYPE_GENERAL
|
||||
);
|
||||
}
|
||||
|
||||
$result = $this->BenutzergruppeModel->insert([
|
||||
'uid' => $uid,
|
||||
'gruppe_kurzbz' => $gruppe_kurzbz,
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz,
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUID()
|
||||
]);
|
||||
|
||||
$this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess();
|
||||
}
|
||||
|
||||
public function search()
|
||||
{
|
||||
$query = $this->input->post('query');
|
||||
if (!$query)
|
||||
$this->terminateWithSuccess([]);
|
||||
|
||||
// add query to where clause
|
||||
$query = strtoupper($query);
|
||||
$query = $this->GruppeModel->db->escape_like_str($query);
|
||||
$query = '%' . str_replace(' ', '%', $query) . '%';
|
||||
|
||||
$this->GruppeModel->db->group_start();
|
||||
$this->GruppeModel->db->or_like('UPPER(gruppe_kurzbz)', $query, 'none', false);
|
||||
$this->GruppeModel->db->or_like('UPPER(bezeichnung)', $query, 'none', false);
|
||||
$this->GruppeModel->db->or_like('UPPER(beschreibung)', $query, 'none', false);
|
||||
$this->GruppeModel->db->group_end();
|
||||
|
||||
// add stg sorting 1
|
||||
$studiengang_kz = $this->input->post('studiengang_kz');
|
||||
$sort_stg = $studiengang_kz ? "WHEN studiengang_kz = " . $this->GruppeModel->escape($studiengang_kz) . " THEN 0" : "";
|
||||
|
||||
// add stg sorting 2
|
||||
$studiengang_kzs = [];
|
||||
$result = $this->permissionlib->getSTG_isEntitledFor('admin');
|
||||
if ($result)
|
||||
$studiengang_kzs = array_merge($studiengang_kzs, $result);
|
||||
$result = $this->permissionlib->getSTG_isEntitledFor('assistenz');
|
||||
if ($result)
|
||||
$studiengang_kzs = array_merge($studiengang_kzs, $result);
|
||||
|
||||
// selects
|
||||
$this->GruppeModel->addSelect("*");
|
||||
$this->GruppeModel->addSelect("CASE
|
||||
" . $sort_stg . "
|
||||
WHEN studiengang_kz IN (" . implode(",", $this->GruppeModel->db->escape($studiengang_kzs)) . ")
|
||||
THEN 1
|
||||
ELSE 2
|
||||
END AS sort_stg");
|
||||
|
||||
// ordering
|
||||
$this->GruppeModel->addOrder("sort_stg");
|
||||
$this->GruppeModel->addOrder("sort");
|
||||
$this->GruppeModel->addOrder("gruppe_kurzbz");
|
||||
|
||||
// default where clause & execute
|
||||
$result = $this->GruppeModel->loadWhere([
|
||||
'lehre' => true,
|
||||
'sichtbar' => true,
|
||||
'aktiv' => true,
|
||||
'direktinskription' => false
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function getGruppen($student_uid)
|
||||
{
|
||||
$this->BenutzergruppeModel ->addSelect('gruppe_kurzbz');
|
||||
$this->BenutzergruppeModel ->addSelect('bezeichnung');
|
||||
$this->BenutzergruppeModel ->addSelect('generiert');
|
||||
$this->BenutzergruppeModel ->addSelect('uid');
|
||||
$this->BenutzergruppeModel ->addSelect('studiensemester_kurzbz');
|
||||
$this->BenutzergruppeModel ->addJoin('public.tbl_gruppe', 'gruppe_kurzbz');
|
||||
$this->BenutzergruppeModel-> addOrder('bezeichnung', 'ASC');
|
||||
$this->BenutzergruppeModel->addSelect('gruppe_kurzbz');
|
||||
$this->BenutzergruppeModel->addSelect('bezeichnung');
|
||||
$this->BenutzergruppeModel->addSelect('generiert');
|
||||
$this->BenutzergruppeModel->addSelect('uid');
|
||||
$this->BenutzergruppeModel->addSelect('studiensemester_kurzbz');
|
||||
$this->BenutzergruppeModel->addJoin('public.tbl_gruppe', 'gruppe_kurzbz');
|
||||
$this->BenutzergruppeModel->addOrder('bezeichnung', 'ASC');
|
||||
|
||||
$result = $this->BenutzergruppeModel->loadWhere(
|
||||
array(
|
||||
@@ -49,29 +178,48 @@ class Gruppen extends FHCAPI_Controller
|
||||
|
||||
public function deleteGruppe()
|
||||
{
|
||||
$student_uid = $this->input->post('id');
|
||||
$this->load->library("form_validation");
|
||||
|
||||
$this->form_validation->set_rules(
|
||||
'uid',
|
||||
$this->p->t('person', 'UID'),
|
||||
'required',
|
||||
[
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired')
|
||||
]
|
||||
);
|
||||
|
||||
$this->form_validation->set_rules(
|
||||
'gruppe_kurzbz',
|
||||
$this->p->t('gruppenmanagement', 'gruppe'),
|
||||
'required',
|
||||
[
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired')
|
||||
]
|
||||
);
|
||||
|
||||
if (!$this->form_validation->run())
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$uid = $this->input->post('uid');
|
||||
$gruppe_kurzbz = $this->input->post('gruppe_kurzbz');
|
||||
|
||||
//Validate if automatic group generation
|
||||
$result = $this->GruppeModel-> loadWhere(
|
||||
array(
|
||||
'gruppe_kurzbz' => $gruppe_kurzbz
|
||||
)
|
||||
);
|
||||
// Validate if automatic group generation
|
||||
$result = $this->GruppeModel->loadWhere([
|
||||
'gruppe_kurzbz' => $gruppe_kurzbz
|
||||
]);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$generation = current($data);
|
||||
|
||||
if($generation->generiert)
|
||||
if ($generation->generiert)
|
||||
{
|
||||
$this->terminateWithError($this->p->t('gruppenmanagement', 'error_deleteGeneratedGroups'), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
$result = $this->BenutzergruppeModel->delete(
|
||||
array(
|
||||
'gruppe_kurzbz' => $gruppe_kurzbz,
|
||||
'uid' => $student_uid
|
||||
)
|
||||
);
|
||||
$result = $this->BenutzergruppeModel->delete([
|
||||
'gruppe_kurzbz' => $gruppe_kurzbz,
|
||||
'uid' => $uid
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ class Kontakt extends FHCAPI_Controller
|
||||
// Extra Permissionchecks
|
||||
$permsMa = [];
|
||||
$permsStud = [];
|
||||
$permsDefault = null;
|
||||
switch ($this->router->method) {
|
||||
case 'getBankverbindung':
|
||||
case 'loadBankverbindung':
|
||||
@@ -68,7 +69,7 @@ class Kontakt extends FHCAPI_Controller
|
||||
case 'getKontakte':
|
||||
case 'loadAddress':
|
||||
case 'loadContact':
|
||||
$permsMa = $permsStud = ['admin:r', 'assistenz:r'];
|
||||
$permsMa = $permsStud = $permsDefault = ['admin:r', 'assistenz:r'];
|
||||
break;
|
||||
case 'addNewAddress':
|
||||
case 'addNewContact':
|
||||
@@ -76,7 +77,7 @@ class Kontakt extends FHCAPI_Controller
|
||||
case 'updateContact':
|
||||
case 'deleteAddress':
|
||||
case 'deleteContact':
|
||||
$permsMa = $permsStud = ['admin:rw', 'assistenz:rw'];
|
||||
$permsMa = $permsStud = $permsDefault = ['admin:rw', 'assistenz:rw'];
|
||||
break;
|
||||
}
|
||||
if ($this->router->method == 'getAdressen'
|
||||
@@ -91,7 +92,7 @@ class Kontakt extends FHCAPI_Controller
|
||||
if (is_null($person_id) || !ctype_digit((string)$person_id))
|
||||
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
|
||||
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud, $permsDefault);
|
||||
} elseif ($this->router->method == 'loadAddress'
|
||||
|| $this->router->method == 'loadContact'
|
||||
|| $this->router->method == 'loadBankverbindung'
|
||||
@@ -135,7 +136,7 @@ class Kontakt extends FHCAPI_Controller
|
||||
|
||||
$person_id = current($data)->person_id;
|
||||
|
||||
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
|
||||
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud, $permsDefault);
|
||||
}
|
||||
}
|
||||
public function getAdressen($person_id)
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
|
||||
class Lehrverband extends FHCAPI_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'hasOrgforms' => ['admin:r', 'assistenz:r'],
|
||||
'getTree' => ['admin:r', 'assistenz:r'],
|
||||
'getSpecialgroups' => ['admin:r', 'assistenz:r']
|
||||
]);
|
||||
}
|
||||
|
||||
public function hasOrgforms($studiengang_kz)
|
||||
{
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
|
||||
$result = $this->StudiengangModel->load($studiengang_kz);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
if ($data) {
|
||||
$data = current($data)->mischform;
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function getTree($studiengang_kz)
|
||||
{
|
||||
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
|
||||
|
||||
$result = $this->LehrverbandModel->loadWhere([
|
||||
'studiengang_kz' => $studiengang_kz,
|
||||
'aktiv' => true
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function getSpecialgroups($studiengang_kz)
|
||||
{
|
||||
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
|
||||
|
||||
$where = [
|
||||
'studiengang_kz' => $studiengang_kz,
|
||||
'lehre' => true,
|
||||
'sichtbar' => true,
|
||||
'aktiv' => true,
|
||||
'direktinskription' => false
|
||||
];
|
||||
|
||||
$result = $this->GruppeModel->loadWhere($where);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,368 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use \DateTime as DateTime;
|
||||
|
||||
class Projektarbeit extends FHCAPI_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getProjektarbeit' => ['admin:r', 'assistenz:r'],
|
||||
'loadProjektarbeit' => ['admin:r', 'assistenz:r'],
|
||||
'insertProjektarbeit' => ['admin:rw', 'assistenz:rw'],
|
||||
'updateProjektarbeit' => ['admin:rw', 'assistenz:rw'],
|
||||
'deleteProjektarbeit' => ['admin:rw', 'assistenz:rw'],
|
||||
'getTypenProjektarbeit' => ['admin:r', 'assistenz:r'],
|
||||
'getFirmen' => ['admin:r', 'assistenz:r'],
|
||||
'getLehrveranstaltungen' => ['admin:r', 'assistenz:r'],
|
||||
'getNoten' => ['admin:r', 'assistenz:r']
|
||||
]);
|
||||
|
||||
// Load Libraries
|
||||
$this->load->library('form_validation');
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'ui',
|
||||
'person',
|
||||
'projektarbeit'
|
||||
]);
|
||||
|
||||
// Load models
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$this->load->model('education/Projekttyp_model', 'ProjekttypModel');
|
||||
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
|
||||
$this->load->model('ressource/Firma_model', 'FirmaModel');
|
||||
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
|
||||
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
|
||||
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
$this->load->model('education/Note_model', 'NoteModel');
|
||||
$this->load->model('education/Projektbetreuer_model', 'BetreuerModel');
|
||||
|
||||
// load libraries
|
||||
$this->load->library('PermissionLib');
|
||||
}
|
||||
|
||||
public function getProjektarbeit()
|
||||
{
|
||||
$student_uid = $this->input->get('uid');
|
||||
|
||||
if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->ProjektarbeitModel->getProjektarbeit($student_uid);
|
||||
|
||||
if (isError($result))
|
||||
{
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
if (!hasData($result)) $this->terminateWithSuccess([]);
|
||||
|
||||
$projektarbeiten = getData($result);
|
||||
|
||||
foreach ($projektarbeiten as $projektarbeit)
|
||||
{
|
||||
$projektarbeit_id = $projektarbeit->projektarbeit_id;
|
||||
$abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id);
|
||||
|
||||
if (isError($abgabeRes)) $this->terminateWithError(getError($abgabeRes), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (hasData($abgabeRes))
|
||||
{
|
||||
$paabgabe = getData($abgabeRes)[0];
|
||||
$projektarbeit->abgabedatum = $paabgabe->abgabedatum;
|
||||
}
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($projektarbeiten);
|
||||
}
|
||||
|
||||
public function loadProjektarbeit()
|
||||
{
|
||||
$projektarbeit_id = $this->input->get('projektarbeit_id');
|
||||
|
||||
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) return $this->terminateWithError('Projektarbeit Id missing', self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$this->ProjektarbeitModel->addSelect(
|
||||
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
|
||||
firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
|
||||
);
|
||||
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
|
||||
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
|
||||
$this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT');
|
||||
$result = $this->ProjektarbeitModel->loadWhere(
|
||||
array('projektarbeit_id' => $projektarbeit_id)
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess(current($data));
|
||||
}
|
||||
|
||||
public function insertProjektarbeit()
|
||||
{
|
||||
$student_uid = $this->input->post('uid');
|
||||
|
||||
if (!$student_uid) return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!$this->_hasBerechtigungForStudent($student_uid))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
|
||||
|
||||
$formData = $this->input->post('formData');
|
||||
|
||||
if ($this->_validate($formData) == false)
|
||||
{
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
}
|
||||
|
||||
$projektarbeit = $this->_getProjektarbeitArr($formData);
|
||||
|
||||
$result = $this->ProjektarbeitModel->insert(
|
||||
array_merge($projektarbeit, ['insertamum' => date('c'), 'insertvon' => getAuthUID(), 'student_uid' => $student_uid])
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function updateProjektarbeit()
|
||||
{
|
||||
$projektarbeit_id = $this->input->post('projektarbeit_id');
|
||||
|
||||
if (!$projektarbeit_id || !is_numeric($projektarbeit_id))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
|
||||
|
||||
$formData = $this->input->post('formData');
|
||||
|
||||
if ($this->_validate($formData) == false)
|
||||
{
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
}
|
||||
|
||||
$projektarbeit = $this->_getProjektarbeitArr($formData);
|
||||
|
||||
$result = $this->ProjektarbeitModel->update(
|
||||
$projektarbeit_id,
|
||||
array_merge($projektarbeit, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function deleteProjektarbeit()
|
||||
{
|
||||
$projektarbeit_id = $this->input->post('projektarbeit_id');
|
||||
|
||||
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID'], self::ERROR_TYPE_GENERAL));
|
||||
|
||||
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
|
||||
|
||||
$validate = $this->_validateDelete($projektarbeit_id);
|
||||
|
||||
if (isError($validate)) return $this->terminateWithError(getError($validate), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->ProjektarbeitModel->delete(
|
||||
['projektarbeit_id' => $projektarbeit_id]
|
||||
);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!hasData($result))
|
||||
{
|
||||
$this->outputJson($result);
|
||||
}
|
||||
|
||||
return $this->terminateWithSuccess(current(getData($result)) ? : null);
|
||||
}
|
||||
|
||||
public function getTypenProjektarbeit()
|
||||
{
|
||||
$result = $this->ProjekttypModel->loadWhere(['aktiv' => true]);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
|
||||
}
|
||||
|
||||
public function getFirmen()
|
||||
{
|
||||
$searchString = $this->input->get('searchString');
|
||||
|
||||
if (!isset($searchString))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_fieldRequired', ['field' => 'Search term']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->FirmaModel->searchFirmen($searchString, $aktiv = true);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
|
||||
}
|
||||
|
||||
public function getLehrveranstaltungen()
|
||||
{
|
||||
$student_uid = $this->input->get('student_uid');
|
||||
$studiengang_kz = $this->input->get('studiengang_kz');
|
||||
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
|
||||
$additional_lehrveranstaltung_id = $this->input->get('additional_lehrveranstaltung_id');
|
||||
|
||||
if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
|
||||
if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id);
|
||||
|
||||
if (isError($lvsResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$lvs = hasData($lvsResult) ? getData($lvsResult) : [];
|
||||
|
||||
foreach ($lvs as $lv)
|
||||
{
|
||||
$lehreinheiten = $this->LehreinheitModel->getLesForLv(
|
||||
$lv->lehrveranstaltung_id, $studiensemester_kurzbz
|
||||
);
|
||||
|
||||
foreach ($lehreinheiten as $lehreinheit)
|
||||
{
|
||||
if (!isEmptyArray($lehreinheit->lektoren))
|
||||
{
|
||||
$this->MitarbeiterModel->addSelect('kurzbz');
|
||||
$this->MitarbeiterModel->db->where_in('tbl_mitarbeiter.mitarbeiter_uid', $lehreinheit->lektoren);
|
||||
$maResult = $this->MitarbeiterModel->load();
|
||||
|
||||
if (isError($maResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$lehreinheit->lektoren = array_column(getData($maResult), 'kurzbz');
|
||||
}
|
||||
}
|
||||
|
||||
$lv->lehreinheiten = $lehreinheiten;
|
||||
}
|
||||
|
||||
return $this->terminateWithSuccess($lvs);
|
||||
}
|
||||
|
||||
public function getNoten()
|
||||
{
|
||||
$result = $this->NoteModel->load();
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _validate($formData)
|
||||
{
|
||||
$this->form_validation->set_data($formData);
|
||||
|
||||
$this->form_validation->set_rules('titel', 'Titel', 'required', [
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Titel'])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('projekttyp_kurzbz', 'Projekttyp', 'required', [
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Projekttyp'])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'required|is_natural', [
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']),
|
||||
'is_natural' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('beginn', 'Beginn', 'is_valid_date', [
|
||||
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Beginn'])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('ende', 'Ende', 'is_valid_date', [
|
||||
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Ende'])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('gesperrtbis', 'Ende', 'is_valid_date', [
|
||||
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Gesperrt bis'])
|
||||
]);
|
||||
|
||||
return $this->form_validation->run();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _getProjektarbeitArr($formData)
|
||||
{
|
||||
return [
|
||||
'titel' => $formData['titel'],
|
||||
'titel_english' => $formData['titel_english'] ?? null,
|
||||
'themenbereich' => $formData['themenbereich'] ?? null,
|
||||
'projekttyp_kurzbz' => $formData['projekttyp_kurzbz'],
|
||||
'firma_id' => $formData['firma_id'] ?? null,
|
||||
'lehreinheit_id' => $formData['lehreinheit_id'],
|
||||
'beginn' => isset($formData['beginn']) && !isEmptyString($formData['beginn']) ? $formData['beginn'] : null,
|
||||
'ende' => isset($formData['ende']) && !isEmptyString($formData['ende']) ? $formData['ende'] : null,
|
||||
'note' => $formData['note'] ?? null,
|
||||
'final' => $formData['final'] ?? null,
|
||||
'freigegeben' => $formData['freigegeben'] ?? null,
|
||||
'anmerkung' => $formData['anmerkung'] ?? null,
|
||||
'gesperrtbis' => isset($formData['gesperrtbis']) && !isEmptyString($formData['gesperrtbis']) ? $formData['gesperrtbis'] : null
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _validateDelete($projektarbeit_id)
|
||||
{
|
||||
$this->BetreuerModel->addSelect('1');
|
||||
$result = $this->BetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
|
||||
|
||||
if (isError($result)) return $result;
|
||||
|
||||
if (hasData($result)) return error($this->p->t('projektarbeit', 'error_betreuerNichtGeloescht'));
|
||||
|
||||
$this->PaabgabeModel->addSelect('1');
|
||||
$result = $this->PaabgabeModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
|
||||
|
||||
if (isError($result)) return $result;
|
||||
|
||||
if (hasData($result)) return error($this->p->t('projektarbeit', 'error_paabgabeNichtGeloescht'));
|
||||
|
||||
return success();
|
||||
}
|
||||
|
||||
private function _hasBerechtigungForStudent($student_uid)
|
||||
{
|
||||
if (!$student_uid)
|
||||
return false;
|
||||
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
|
||||
$this->StudentModel->addSelect('studiengang_kz');
|
||||
$result = $this->StudentModel->load([$student_uid]);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$studiengang_kz = getData($result)[0]->studiengang_kz;
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz))
|
||||
return true;
|
||||
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
use \DateTime as DateTime;
|
||||
use CI3_Events as Events;
|
||||
|
||||
class Projektbetreuer extends FHCAPI_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getProjektbetreuer' => ['admin:r', 'assistenz:r'],
|
||||
'saveProjektbetreuer' => ['admin:rw', 'assistenz:rw'],
|
||||
'deleteProjektbetreuer' => ['admin:rw', 'assistenz:rw'],
|
||||
'getBetreuerarten' => ['admin:r', 'assistenz:r'],
|
||||
'getNoten' => ['admin:r', 'assistenz:r'],
|
||||
'getDefaultStundensaetze' => ['admin:r', 'assistenz:r'],
|
||||
'getProjektbetreuerBySearchQuery' => ['admin:r', 'assistenz:r'],
|
||||
'getPerson' => ['admin:r', 'assistenz:r'],
|
||||
'validateProjektbetreuer' => ['admin:r', 'assistenz:r']
|
||||
]);
|
||||
|
||||
// Load Libraries
|
||||
$this->load->library('form_validation');
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'ui',
|
||||
'person',
|
||||
'projektarbeit'
|
||||
]);
|
||||
|
||||
// Load models
|
||||
$this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel');
|
||||
$this->load->model('education/Betreuerart_model', 'BetreuerartModel');
|
||||
$this->load->model('ressource/Stundensatz_model', 'StundensatzModel');
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$this->load->model('education/Note_model', 'NoteModel');
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
|
||||
// load libraries
|
||||
$this->load->library('PermissionLib');
|
||||
}
|
||||
|
||||
public function getProjektbetreuer()
|
||||
{
|
||||
$projektarbeit_id = $this->input->get('projektarbeit_id');
|
||||
|
||||
if (!isset($projektarbeit_id))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$this->ProjektbetreuerModel->addSelect(
|
||||
'projektarbeit_id, person_id, nachname, vorname, note, punkte, round(stunden, 1) AS stunden,
|
||||
stundensatz, betreuerart_kurzbz, vertrag_id, titelpre, titelpost'
|
||||
);
|
||||
$this->ProjektbetreuerModel->addSelect("CASE
|
||||
WHEN EXISTS
|
||||
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=pers.person_id)
|
||||
THEN 'Mitarbeiter'
|
||||
WHEN EXISTS
|
||||
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=pers.person_id)
|
||||
THEN 'Student'
|
||||
ELSE 'Person'
|
||||
END AS status");
|
||||
$this->ProjektbetreuerModel->addJoin('public.tbl_person pers', 'person_id');
|
||||
$result = $this->ProjektbetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
|
||||
|
||||
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!hasData($result)) $this->terminateWithSuccess([]);
|
||||
|
||||
$projektbetreuer = getData($result);
|
||||
|
||||
//~ foreach ($projektbetreuer as $projektarbeit)
|
||||
//~ {
|
||||
//~ $projektarbeit_id = $projektarbeit->projektarbeit_id;
|
||||
//~ $abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id);
|
||||
|
||||
//~ if (isError($abgabeRes)) $this->terminateWithError(getError($abgabeRes), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
//~ if (hasData($abgabeRes))
|
||||
//~ {
|
||||
//~ $paabgabe = getData($abgabeRes)[0];
|
||||
//~ $projektarbeit->abgabedatum = $paabgabe->abgabedatum;
|
||||
//~ }
|
||||
//~ }
|
||||
|
||||
foreach ($projektbetreuer as $pb)
|
||||
{
|
||||
$downloadLink = null;
|
||||
Events::trigger(
|
||||
'projektbeurteilung_download_link',
|
||||
$pb->projektarbeit_id,
|
||||
$pb->betreuerart_kurzbz,
|
||||
$pb->person_id,
|
||||
function ($value) use (&$downloadLink) {
|
||||
$downloadLink = $value;
|
||||
}
|
||||
);
|
||||
$pb->beurteilungDownloadLink = $downloadLink;
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($this->_addFullNameToBetreuer($projektbetreuer));
|
||||
}
|
||||
|
||||
public function saveProjektbetreuer()
|
||||
{
|
||||
$projektarbeit_id = $this->input->post('projektarbeit_id');
|
||||
|
||||
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
|
||||
|
||||
$projektbetreuer = $this->input->post('projektbetreuer');
|
||||
|
||||
if ($this->_validate($projektbetreuer) == false) $this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
|
||||
$result = null;
|
||||
|
||||
$betreuer = [
|
||||
'projektarbeit_id' => $projektarbeit_id,
|
||||
'person_id' => $projektbetreuer['person_id'],
|
||||
'note' => $projektbetreuer['note'],
|
||||
'stunden' => $projektbetreuer['stunden'],
|
||||
'stundensatz' => $projektbetreuer['stundensatz'],
|
||||
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz']
|
||||
];
|
||||
|
||||
if (isset($projektbetreuer['person_id_old']) && isset($projektbetreuer['betreuerart_kurzbz_old']))
|
||||
{
|
||||
$result = $this->ProjektbetreuerModel->update(
|
||||
[
|
||||
'projektarbeit_id' => $projektarbeit_id,
|
||||
'person_id' => $projektbetreuer['person_id_old'],
|
||||
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz_old']
|
||||
],
|
||||
array_merge($betreuer, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $this->ProjektbetreuerModel->insert(
|
||||
array_merge($betreuer, ['insertamum' => date('c'), 'insertvon' => getAuthUID()])
|
||||
);
|
||||
}
|
||||
|
||||
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$this->terminateWithSuccess(hasData($result) ? getData($result) : []);
|
||||
}
|
||||
|
||||
public function deleteProjektbetreuer()
|
||||
{
|
||||
$projektarbeit_id = $this->input->post('projektarbeit_id');
|
||||
$person_id = $this->input->post('person_id');
|
||||
$betreuerart_kurzbz = $this->input->post('betreuerart_kurzbz');
|
||||
|
||||
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'projektarbeit').' ID'], self::ERROR_TYPE_GENERAL));
|
||||
|
||||
if (!isset($person_id) || !is_numeric($person_id))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID'], self::ERROR_TYPE_GENERAL));
|
||||
|
||||
if (!isset($betreuerart_kurzbz))
|
||||
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'betreuerart')], self::ERROR_TYPE_GENERAL));
|
||||
|
||||
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
|
||||
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
|
||||
|
||||
$validate = $this->_validateDelete($projektarbeit_id, $person_id);
|
||||
|
||||
if (isError($validate)) return $this->terminateWithError(getError($validate), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->ProjektbetreuerModel->delete(
|
||||
['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id, 'betreuerart_kurzbz' => $betreuerart_kurzbz]
|
||||
);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!hasData($result))
|
||||
{
|
||||
$this->outputJson($result);
|
||||
}
|
||||
|
||||
return $this->terminateWithSuccess(current(getData($result)) ? : null);
|
||||
}
|
||||
|
||||
public function getBetreuerarten()
|
||||
{
|
||||
$result = $this->BetreuerartModel->loadWhere(['aktiv' => true]);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
|
||||
}
|
||||
|
||||
public function getNoten()
|
||||
{
|
||||
$result = $this->NoteModel->load();
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
|
||||
}
|
||||
|
||||
public function getDefaultStundensaetze()
|
||||
{
|
||||
$person_id = $this->input->get('person_id');
|
||||
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
|
||||
|
||||
$result = $this->StundensatzModel->getStundensatzForMitarbeiter($person_id, $studiensemester_kurzbz);
|
||||
|
||||
return $this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
public function getProjektbetreuerBySearchQuery()
|
||||
{
|
||||
$searchString = $this->input->get('searchString');
|
||||
|
||||
if (!isset($searchString))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_fieldRequired', ['field' => 'Search term']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->PersonModel->searchPerson($searchString);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? $this->_addFullNameToBetreuer(getData($result)) : []);
|
||||
}
|
||||
|
||||
public function getPerson()
|
||||
{
|
||||
$person_id = $this->input->get('person_id');
|
||||
|
||||
if (!isset($person_id))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_fieldRequired', ['field' => 'Person']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$this->PersonModel->addSelect("CASE
|
||||
WHEN EXISTS
|
||||
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=tbl_person.person_id)
|
||||
THEN 'Mitarbeiter'
|
||||
WHEN EXISTS
|
||||
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=tbl_person.person_id)
|
||||
THEN 'Student'
|
||||
ELSE 'Person'
|
||||
END AS status");
|
||||
$result = $this->PersonModel->addSelect('titelpre, titelpost, vorname, nachname, person_id');
|
||||
$result = $this->PersonModel->load($person_id);
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
return $this->terminateWithSuccess(hasData($result) ? $this->_addFullNameToBetreuer(getData($result))[0] : []);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
public function validateProjektbetreuer()
|
||||
{
|
||||
$projektbetreuerArr = $this->input->post('projektbetreuer');
|
||||
|
||||
if (!is_array($projektbetreuerArr)) $projektbetreuerArr = [$projektbetreuerArr];
|
||||
|
||||
foreach ($projektbetreuerArr as $pb)
|
||||
{
|
||||
if ($this->_validate($pb) == false)
|
||||
{
|
||||
$this->terminateWithValidationErrors($this->form_validation->error_array());
|
||||
}
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess([]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _validate($formData)
|
||||
{
|
||||
$this->form_validation->set_data($formData);
|
||||
|
||||
$this->form_validation->set_rules('betreuerart_kurzbz', 'Betreuerart', 'required', [
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('projektarbeit', 'betreuerart')])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('person_id', 'Person', 'required', [
|
||||
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('projektarbeit', 'betreuer')])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('stunden', 'Stunden', 'numeric', [
|
||||
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => $this->p->t('projektarbeit', 'stunden')])
|
||||
]);
|
||||
|
||||
$this->form_validation->set_rules('stundensatz', 'Stundensatz', 'numeric', [
|
||||
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => $this->p->t('projektarbeit', 'stundensatz')])
|
||||
]);
|
||||
|
||||
|
||||
return $this->form_validation->run();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _validateDelete($projektarbeit_id, $person_id)
|
||||
{
|
||||
$this->ProjektbetreuerModel->addSelect('vertrag_id');
|
||||
$result = $this->ProjektbetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id]);
|
||||
|
||||
if (isError($result)) return $result;
|
||||
|
||||
if (hasData($result) && getData($result)[0]->vertrag_id != null) return error($this->p->t('projektarbeit', 'error_betreuerHatVertrag'));
|
||||
|
||||
return success();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
private function _addFullNameToBetreuer($betreuerArr)
|
||||
{
|
||||
foreach ($betreuerArr as $betreuer)
|
||||
{
|
||||
$betreuer->name = ($betreuer->titelpre ? $betreuer->titelpre . ' ' : '') .
|
||||
$betreuer->nachname . ' ' . $betreuer->vorname . ($betreuer->titelpost ? ' ' . $betreuer->titelpre : '').
|
||||
' (' . $betreuer->status . ')';
|
||||
}
|
||||
|
||||
return $betreuerArr;
|
||||
}
|
||||
}
|
||||
@@ -114,9 +114,8 @@ class Status extends FHCAPI_Controller
|
||||
$this->load->model('codex/Bismeldestichtag_model', 'BismeldestichtagModel');
|
||||
|
||||
$result = $this->BismeldestichtagModel->getLastReachedMeldestichtag();
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
|
||||
}
|
||||
|
||||
public function isLastStatus($prestudent_id)
|
||||
@@ -296,7 +295,7 @@ class Status extends FHCAPI_Controller
|
||||
}],
|
||||
//Check if Rolle already exists
|
||||
['rolle_doesnt_exist', function () use ($prestudent_id, $status_kurzbz, $studiensemester_kurzbz, $ausbildungssemester) {
|
||||
if (!$status_kurzbz || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->PrestudentstatusModel->load([$ausbildungssemester, $studiensemester_kurzbz, $status_kurzbz, $prestudent_id]);
|
||||
@@ -903,7 +902,7 @@ class Status extends FHCAPI_Controller
|
||||
|
||||
$this->form_validation->set_rules('_default', '', [
|
||||
['rolle_doesnt_exist', function () use ($prestudent_id, $status_kurzbz, $studiensemester_kurzbz, $ausbildungssemester) {
|
||||
if (!$status_kurzbz || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->PrestudentstatusModel->load([$ausbildungssemester, $studiensemester_kurzbz, $status_kurzbz, $prestudent_id]);
|
||||
@@ -920,7 +919,7 @@ class Status extends FHCAPI_Controller
|
||||
) {
|
||||
if ($isBerechtigtNoStudstatusCheck)
|
||||
return true; // Skip if access right says so
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->prestudentstatuschecklib->checkStatusHistoryTimesequence(
|
||||
@@ -945,7 +944,7 @@ class Status extends FHCAPI_Controller
|
||||
) {
|
||||
if ($isBerechtigtNoStudstatusCheck)
|
||||
return true; // Skip if access right says so
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->prestudentstatuschecklib->checkStatusHistoryLaststatus(
|
||||
@@ -970,7 +969,7 @@ class Status extends FHCAPI_Controller
|
||||
) {
|
||||
if ($isBerechtigtNoStudstatusCheck)
|
||||
return true; // Skip if access right says so
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->prestudentstatuschecklib->checkStatusHistoryUnterbrechersemester(
|
||||
@@ -995,7 +994,7 @@ class Status extends FHCAPI_Controller
|
||||
) {
|
||||
if ($isBerechtigtNoStudstatusCheck)
|
||||
return true; // Skip if access right says so
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->prestudentstatuschecklib->checkStatusHistoryAbbrechersemester(
|
||||
@@ -1020,7 +1019,7 @@ class Status extends FHCAPI_Controller
|
||||
) {
|
||||
if ($isBerechtigtNoStudstatusCheck)
|
||||
return true; // Skip if access right says so
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
|
||||
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
|
||||
return true; // Error will be handled by the required statements above
|
||||
|
||||
$result = $this->prestudentstatuschecklib->checkStatusHistoryDiplomant(
|
||||
|
||||
@@ -36,6 +36,7 @@ class Student extends FHCAPI_Controller
|
||||
parent::__construct([
|
||||
'get' => ['admin:r', 'assistenz:r'],
|
||||
'save' => ['admin:rw', 'assistenz:rw'],
|
||||
'saveStudent' => ['admin:rw', 'assistenz:rw'],
|
||||
'check' => ['admin:rw', 'assistenz:rw'],
|
||||
'add' => ['admin:rw', 'assistenz:rw'] // TODO(chris): extra permissions
|
||||
]);
|
||||
@@ -55,7 +56,7 @@ class Student extends FHCAPI_Controller
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'ui', 'lehre'
|
||||
'ui', 'lehre', 'person'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -424,6 +425,31 @@ class Student extends FHCAPI_Controller
|
||||
), ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves data to a prestudent using their student_uid
|
||||
*
|
||||
* @param string $student_uid
|
||||
* @param string $studiensemester_kurzbz
|
||||
* @return void
|
||||
*/
|
||||
public function saveStudent($student_uid, $studiensemester_kurzbz)
|
||||
{
|
||||
$this->load->model('crm/Student_model', 'StudentModel');
|
||||
|
||||
$result = $this->StudentModel->load([$student_uid]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
if (!$data)
|
||||
show_404(); // No Student with that ID
|
||||
|
||||
$student = current($data);
|
||||
|
||||
$this->checkPermissionsForPrestudent($student->prestudent_id, ['admin:rw', 'assistenz:rw']);
|
||||
|
||||
return $this->save($student->prestudent_id, $studiensemester_kurzbz);
|
||||
}
|
||||
|
||||
public function check()
|
||||
{
|
||||
$this->load->library('form_validation');
|
||||
@@ -465,7 +491,6 @@ class Student extends FHCAPI_Controller
|
||||
if (!$this->input->post('person_id')) {
|
||||
if (!isset($_POST['address']) || !is_array($_POST['address']))
|
||||
$_POST['address'] = [];
|
||||
$_POST['address']['func'] = 1;
|
||||
}
|
||||
if ($this->input->post('incoming')) {
|
||||
$_POST['ausbildungssemester'] = 0;
|
||||
@@ -474,31 +499,37 @@ class Student extends FHCAPI_Controller
|
||||
$this->load->library('form_validation');
|
||||
|
||||
$this->form_validation->set_rules('nachname', 'Nachname', 'callback_requiredIfNotPersonId', [
|
||||
'requiredIfNotPersonId' => $this->p->t('ui', 'error_required')
|
||||
'requiredIfNotPersonId' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'nachname')])
|
||||
]);
|
||||
$this->form_validation->set_rules('geschlecht', 'Geschlecht', 'callback_requiredIfNotPersonId', [
|
||||
'requiredIfNotPersonId' => $this->p->t('ui', 'error_required')
|
||||
'requiredIfNotPersonId' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'geschlecht')])
|
||||
]);
|
||||
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'callback_isValidDate', [
|
||||
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', ['isValidDate', function($value) { return isValidDate($value); }], [
|
||||
'isValidDate' => $this->p->t('ui', 'error_invalid_date')
|
||||
]);
|
||||
$this->form_validation->set_rules('address[func]', 'Address', 'required|integer|less_than[2]|greater_than[-2]');
|
||||
$this->form_validation->set_rules('address[plz]', 'PLZ', 'callback_requiredIfAddressFunc', [
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'plz')])
|
||||
]);
|
||||
$this->form_validation->set_rules('address[gemeinde]', 'Gemeinde', 'callback_requiredIfAddressFunc', [
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'gemeinde')])
|
||||
]);
|
||||
$this->form_validation->set_rules('address[ort]', 'Ort', 'callback_requiredIfAddressFunc', [
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'ort')])
|
||||
]);
|
||||
$this->form_validation->set_rules('address[address]', 'Adresse', 'callback_requiredIfAddressFunc', [
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
|
||||
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'adresse')])
|
||||
]);
|
||||
$this->form_validation->set_rules('email', 'E-Mail', 'valid_email');
|
||||
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'required');
|
||||
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required');
|
||||
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'required|integer|less_than[9]|greater_than[-1]');
|
||||
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'callback_requiredIfStudentFunc', [
|
||||
'requiredIfStudentFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'studiengang')])
|
||||
]);
|
||||
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'callback_requiredIfStudentFunc', [
|
||||
'requiredIfStudentFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'studiensemester')])
|
||||
]);
|
||||
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'callback_requiredIfStudentFunc|integer|less_than[9]|greater_than[-1]', [
|
||||
'requiredIfStudentFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'ausbildungssemester')])
|
||||
]);
|
||||
// TODO(chris): validate studienplan with studiengang, semester and orgform?
|
||||
// TODO(chris): validate person_id, studiengang_kz, studiensemester_kurzbz, orgform_kurzbz, nation, gemeinde, ort, geschlecht?
|
||||
|
||||
@@ -518,7 +549,9 @@ class Student extends FHCAPI_Controller
|
||||
if ($this->db->trans_status() === FALSE)
|
||||
$this->terminateWithError('TODO(chris): TEXT', self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$this->terminateWithSuccess($result);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
protected function addInteressent()
|
||||
@@ -575,6 +608,8 @@ class Student extends FHCAPI_Controller
|
||||
'zustelladresse' => true,
|
||||
];
|
||||
if ($anlegen < 0) { // Überschreiben
|
||||
$this->AdresseModel->addSelect('adresse_id');
|
||||
$this->AdresseModel->addJoin('public.tbl_adressentyp', 'typ = adressentyp_kurzbz');
|
||||
$this->AdresseModel->addOrder('zustelladresse', 'DESC');
|
||||
$this->AdresseModel->addOrder('sort');
|
||||
$result = $this->AdresseModel->loadWhere([
|
||||
@@ -631,70 +666,74 @@ class Student extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
// Prestudent anlegen
|
||||
$data = [
|
||||
'aufmerksamdurch_kurzbz' => 'k.A.',
|
||||
'person_id' => $person_id,
|
||||
'studiengang_kz' => $this->input->post('studiengang_kz'),
|
||||
'ausbildungcode' => $this->input->post('letzteausbildung'),
|
||||
'anmerkung' => $this->input->post('anmerkungen'),
|
||||
'reihungstestangetreten' => false,
|
||||
'bismelden' => true
|
||||
];
|
||||
$ausbildungsart = $this->input->post('ausbildungsart');
|
||||
if ($ausbildungsart)
|
||||
$data['anmerkung'] .= ' Ausbildungsart:' . $ausbildungsart;
|
||||
// Incomings und ausserordentliche sind bei Meldung nicht förderrelevant
|
||||
$incoming = $this->input->post('incoming');
|
||||
if ($incoming || substr($data['studiengang_kz'], 0, 1) == '9')
|
||||
$data['foerderrelevant'] = false;
|
||||
// Wenn die Person schon im System erfasst ist, dann die ZGV des Datensatzes uebernehmen
|
||||
$this->PrestudentModel->addOrder('zgvmas_code');
|
||||
$this->PrestudentModel->addOrder('zgv_code', 'DESC');
|
||||
$this->PrestudentModel->addLimit(1);
|
||||
$result = $this->PrestudentModel->loadWhere([
|
||||
'person_id' => $person_id
|
||||
]);
|
||||
$prestudent = $this->getDataOrTerminateWithError($result);
|
||||
if ($prestudent) {
|
||||
$prestudent = current($prestudent);
|
||||
if ($prestudent->zgv_code) {
|
||||
$data['zgv_code'] = $prestudent->zgv_code;
|
||||
$data['zgvort'] = $prestudent->zgvort;
|
||||
$data['zgvdatum'] = $prestudent->zgvdatum;
|
||||
$personOnly = $anlegen = $this->input->post('personOnly');
|
||||
|
||||
$data['zgvmas_code'] = $prestudent->zgvmas_code;
|
||||
$data['zgvmaort'] = $prestudent->zgvmaort;
|
||||
$data['zgvmadatum'] = $prestudent->zgvmadatum;
|
||||
if (!$personOnly)
|
||||
{
|
||||
// Prestudent anlegen
|
||||
$data = [
|
||||
'aufmerksamdurch_kurzbz' => 'k.A.',
|
||||
'person_id' => $person_id,
|
||||
'studiengang_kz' => $this->input->post('studiengang_kz'),
|
||||
'ausbildungcode' => $this->input->post('letzteausbildung'),
|
||||
'anmerkung' => $this->input->post('anmerkungen'),
|
||||
'reihungstestangetreten' => false,
|
||||
'bismelden' => true
|
||||
];
|
||||
$ausbildungsart = $this->input->post('ausbildungsart');
|
||||
if ($ausbildungsart)
|
||||
$data['anmerkung'] .= ' Ausbildungsart:' . $ausbildungsart;
|
||||
// Incomings und ausserordentliche sind bei Meldung nicht förderrelevant
|
||||
$incoming = $this->input->post('incoming');
|
||||
if ($incoming || substr($data['studiengang_kz'], 0, 1) == '9')
|
||||
$data['foerderrelevant'] = false;
|
||||
// Wenn die Person schon im System erfasst ist, dann die ZGV des Datensatzes uebernehmen
|
||||
$this->PrestudentModel->addOrder('zgvmas_code');
|
||||
$this->PrestudentModel->addOrder('zgv_code', 'DESC');
|
||||
$this->PrestudentModel->addLimit(1);
|
||||
$result = $this->PrestudentModel->loadWhere([
|
||||
'person_id' => $person_id
|
||||
]);
|
||||
$prestudent = $this->getDataOrTerminateWithError($result);
|
||||
if ($prestudent) {
|
||||
$prestudent = current($prestudent);
|
||||
if ($prestudent->zgv_code) {
|
||||
$data['zgv_code'] = $prestudent->zgv_code;
|
||||
$data['zgvort'] = $prestudent->zgvort;
|
||||
$data['zgvdatum'] = $prestudent->zgvdatum;
|
||||
|
||||
$data['zgvmas_code'] = $prestudent->zgvmas_code;
|
||||
$data['zgvmaort'] = $prestudent->zgvmaort;
|
||||
$data['zgvmadatum'] = $prestudent->zgvmadatum;
|
||||
}
|
||||
}
|
||||
// Prestudent speichern
|
||||
$result = $this->PrestudentModel->insert($data);
|
||||
$prestudent_id = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
// Prestudent Rolle Anlegen
|
||||
$data = [
|
||||
'prestudent_id' => $prestudent_id,
|
||||
'status_kurzbz' => $incoming ? 'Incoming' : 'Interessent',
|
||||
'studiensemester_kurzbz' => $this->input->post('studiensemester_kurzbz'),
|
||||
'ausbildungssemester' => $this->input->post('ausbildungssemester') ?: 0,
|
||||
'orgform_kurzbz' => $this->input->post('orgform_kurzbz') ?: null,
|
||||
'studienplan_id' => $this->input->post('studienplan_id') ?: null,
|
||||
'datum' => date('Y-m-d'),
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUID()
|
||||
];
|
||||
$result = $this->PrestudentstatusModel->insert($data);
|
||||
$this->getDataOrTerminateWithError($result);
|
||||
|
||||
if ($incoming) {
|
||||
// TODO(chris): IMPLEMENT!
|
||||
//Matrikelnummer und UID generieren
|
||||
//Benutzerdatensatz anlegen
|
||||
//Studentendatensatz anlegen
|
||||
//StudentLehrverband anlegen
|
||||
}
|
||||
}
|
||||
// Prestudent speichern
|
||||
$result = $this->PrestudentModel->insert($data);
|
||||
$prestudent_id = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
// Prestudent Rolle Anlegen
|
||||
$data = [
|
||||
'prestudent_id' => $prestudent_id,
|
||||
'status_kurzbz' => $incoming ? 'Incoming' : 'Interessent',
|
||||
'studiensemester_kurzbz' => $this->input->post('studiensemester_kurzbz'),
|
||||
'ausbildungssemester' => $this->input->post('ausbildungssemester') ?: 0,
|
||||
'orgform_kurzbz' => $this->input->post('orgform_kurzbz') ?: null,
|
||||
'studienplan_id' => $this->input->post('studienplan_id') ?: null,
|
||||
'datum' => date('Y-m-d'),
|
||||
'insertamum' => date('c'),
|
||||
'insertvon' => getAuthUID()
|
||||
];
|
||||
$result = $this->PrestudentstatusModel->insert($data);
|
||||
$this->getDataOrTerminateWithError($result);
|
||||
|
||||
if ($incoming) {
|
||||
// TODO(chris): IMPLEMENT!
|
||||
//Matrikelnummer und UID generieren
|
||||
//Benutzerdatensatz anlegen
|
||||
//Studentendatensatz anlegen
|
||||
//StudentLehrverband anlegen
|
||||
}
|
||||
|
||||
// TODO(chris): DEBUG
|
||||
/*$result = $this->PrestudentModel->loadWhere([
|
||||
'pestudent_id' => 1
|
||||
@@ -703,7 +742,7 @@ class Student extends FHCAPI_Controller
|
||||
return $result;
|
||||
}*/
|
||||
|
||||
return success(true);
|
||||
return success($person_id);
|
||||
}
|
||||
|
||||
public function requiredIfNotPersonId($value)
|
||||
@@ -715,7 +754,14 @@ class Student extends FHCAPI_Controller
|
||||
|
||||
public function requiredIfAddressFunc($value)
|
||||
{
|
||||
if (!$_POST['address']['func'])
|
||||
if (!$_POST['address']['func'] || $_POST['address']['func'] == 0)
|
||||
return true;
|
||||
return !!$value;
|
||||
}
|
||||
|
||||
public function requiredIfStudentFunc($value)
|
||||
{
|
||||
if ($_POST['personOnly'])
|
||||
return true;
|
||||
return !!$value;
|
||||
}
|
||||
|
||||
@@ -44,14 +44,12 @@ class Students extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
// Load Libraries
|
||||
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
|
||||
$this->load->library('PhrasesLib');
|
||||
$this->loadPhrases(
|
||||
array(
|
||||
'lehre'
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +73,7 @@ class Students extends FHCAPI_Controller
|
||||
* /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz)/(filter) => getPrestudentsOrgform
|
||||
* /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz)/(filter)/(otherfilter) => getPrestudentsOrgform
|
||||
*
|
||||
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/grp/(gruppe) => getStudentsSpezialguppe
|
||||
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/grp/(gruppe) => getStudentsSpezialgruppe
|
||||
*
|
||||
* /(studiensemester_kurzbz)/(studiengang_kz) => getStudents
|
||||
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester) => getStudents
|
||||
@@ -101,39 +99,183 @@ class Students extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $studiensemester_kurzbz
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getIncoming()
|
||||
public function getIncoming($studiensemester_kurzbz)
|
||||
{
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
// TODO(chris): IMPLEMENT!
|
||||
$this->terminateWithSuccess([]);
|
||||
$this->addMeta('ci_params', [
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz
|
||||
]);
|
||||
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
|
||||
$this->PrestudentModel->addJoin(
|
||||
"(
|
||||
SELECT prestudent_id
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE status_kurzbz = 'Incoming'
|
||||
AND studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
) test",
|
||||
"prestudent_id"
|
||||
);
|
||||
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN pls.ausbildungssemester::text
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $studiensemester_kurzbz
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getOutgoing()
|
||||
public function getOutgoing($studiensemester_kurzbz)
|
||||
{
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
// TODO(chris): IMPLEMENT!
|
||||
$this->terminateWithSuccess([]);
|
||||
$this->addMeta('ci_params', [
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz
|
||||
]);
|
||||
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
|
||||
$this->PrestudentModel->addJoin(
|
||||
"(
|
||||
SELECT prestudent_id
|
||||
FROM bis.tbl_bisio bis
|
||||
JOIN public.tbl_student USING (student_uid)
|
||||
JOIN public.tbl_studiensemester stdsem ON (
|
||||
(bis.von >= stdsem.start AND bis.von <= stdsem.ende)
|
||||
OR
|
||||
(bis.bis >= stdsem.start AND bis.bis <= stdsem.ende)
|
||||
OR
|
||||
(bis.von <= stdsem.start AND bis.bis >= stdsem.ende)
|
||||
)
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE status_kurzbz = 'Incoming'
|
||||
AND prestudent_id = tbl_student.prestudent_id
|
||||
) AND stdsem.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
GROUP BY prestudent_id
|
||||
) test",
|
||||
"prestudent_id"
|
||||
);
|
||||
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN pls.ausbildungssemester::text
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $studiensemester_kurzbz
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getGemeinsamestudien()
|
||||
public function getGemeinsamestudien($studiensemester_kurzbz)
|
||||
{
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
// TODO(chris): IMPLEMENT!
|
||||
$this->terminateWithSuccess([]);
|
||||
$this->addMeta('ci_params', [
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz
|
||||
]);
|
||||
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
|
||||
$this->PrestudentModel->addJoin(
|
||||
"(
|
||||
SELECT prestudent_id
|
||||
FROM bis.tbl_mobilitaet
|
||||
WHERE studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
) bis",
|
||||
"prestudent_id"
|
||||
);
|
||||
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN pls.ausbildungssemester::text
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function getPrestudents($studiengang_kz,
|
||||
$studiensemester_kurzbz = null, $filter = null
|
||||
)
|
||||
{
|
||||
public function getPrestudents(
|
||||
$studiengang_kz,
|
||||
$studiensemester_kurzbz = null,
|
||||
$filter = null
|
||||
) {
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
$this->addMeta('ci_params', array(
|
||||
'studiengang_kz' => $studiengang_kz,
|
||||
@@ -144,10 +286,12 @@ class Students extends FHCAPI_Controller
|
||||
$this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter);
|
||||
}
|
||||
|
||||
public function getPrestudentsOrgform($studiengang_kz, $orgform_kurzbz,
|
||||
$studiensemester_kurzbz = null, $filter = null
|
||||
)
|
||||
{
|
||||
public function getPrestudentsOrgform(
|
||||
$studiengang_kz,
|
||||
$orgform_kurzbz,
|
||||
$studiensemester_kurzbz = null,
|
||||
$filter = null
|
||||
) {
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
$this->addMeta('ci_params', array(
|
||||
'studiengang_kz' => $studiengang_kz,
|
||||
@@ -227,7 +371,7 @@ class Students extends FHCAPI_Controller
|
||||
|
||||
$stg = $this->getDataOrTerminateWithError($result);
|
||||
if (!$stg)
|
||||
$this->terminateWithValidationErrors(['' => 'Studiengang does not exist']); // TODO(chris): phrase
|
||||
$this->terminateWithSuccess([]);
|
||||
$stg = current($stg);
|
||||
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
@@ -296,7 +440,10 @@ class Students extends FHCAPI_Controller
|
||||
break;
|
||||
default:
|
||||
if (!$studiensemester_kurzbz) {
|
||||
// TODO(chris): this does not work with $orgform_kurzbz != null
|
||||
/** NOTE(chris):
|
||||
* show all prestudents in this stg who don't have a status
|
||||
* $orgform_kurzbz does not change the results since orgform is stored in the status table
|
||||
*/
|
||||
$where['ps.status_kurzbz'] = null;
|
||||
} else {
|
||||
$this->PrestudentModel->db->where_in('ps.status_kurzbz', [
|
||||
@@ -310,42 +457,18 @@ class Students extends FHCAPI_Controller
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
|
||||
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus ps', '
|
||||
ps.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
AND ps.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT');*/
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("
|
||||
CASE WHEN ps.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN ps.ausbildungssemester::text
|
||||
ELSE ''::text END AS semester", false);
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN ps.ausbildungssemester::text
|
||||
ELSE ''::text
|
||||
END AS semester", false);
|
||||
$this->PrestudentModel->addSelect("'' AS verband");
|
||||
$this->PrestudentModel->addSelect("'' AS gruppe");
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus pss
|
||||
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
|
||||
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
|
||||
LIMIT 1
|
||||
) AS statusofsemester"
|
||||
);
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->PrestudentModel->loadWhere($where);
|
||||
@@ -355,10 +478,13 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function getStudents($studiensemester_kurzbz,
|
||||
$studiengang_kz, $semester = null, $verband = null, $gruppe = null
|
||||
)
|
||||
{
|
||||
public function getStudents(
|
||||
$studiensemester_kurzbz,
|
||||
$studiengang_kz,
|
||||
$semester = null,
|
||||
$verband = null,
|
||||
$gruppe = null
|
||||
) {
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
$this->addMeta('ci_params', array(
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz,
|
||||
@@ -371,10 +497,14 @@ class Students extends FHCAPI_Controller
|
||||
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, null);
|
||||
}
|
||||
|
||||
public function getStudentsOrgform($studiensemester_kurzbz,
|
||||
$studiengang_kz, $orgform_kurzbz, $semester = null, $verband = null, $gruppe = null
|
||||
)
|
||||
{
|
||||
public function getStudentsOrgform(
|
||||
$studiensemester_kurzbz,
|
||||
$studiengang_kz,
|
||||
$orgform_kurzbz,
|
||||
$semester = null,
|
||||
$verband = null,
|
||||
$gruppe = null
|
||||
) {
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
$this->addMeta('ci_params', array(
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz,
|
||||
@@ -388,10 +518,12 @@ class Students extends FHCAPI_Controller
|
||||
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, $orgform_kurzbz);
|
||||
}
|
||||
|
||||
public function getStudentsSpezialgruppe($studiensemester_kurzbz,
|
||||
$studiengang_kz, $semester, $gruppe_kurzbz,
|
||||
$orgform_kurzbz = null)
|
||||
{
|
||||
public function getStudentsSpezialgruppe(
|
||||
$studiensemester_kurzbz,
|
||||
$studiengang_kz,
|
||||
$semester,
|
||||
$gruppe_kurzbz
|
||||
) {
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
$this->addMeta('ci_params', array(
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz,
|
||||
@@ -403,10 +535,13 @@ class Students extends FHCAPI_Controller
|
||||
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, null);
|
||||
}
|
||||
|
||||
public function getStudentsOrgformSpezialgruppe($studiensemester_kurzbz,
|
||||
$orgform_kurzbz, $studiengang_kz, $semester, $gruppe_kurzbz
|
||||
)
|
||||
{
|
||||
public function getStudentsOrgformSpezialgruppe(
|
||||
$studiensemester_kurzbz,
|
||||
$orgform_kurzbz,
|
||||
$studiengang_kz,
|
||||
$semester,
|
||||
$gruppe_kurzbz
|
||||
) {
|
||||
$this->addMeta('ci_method', __FUNCTION__);
|
||||
$this->addMeta('ci_params', array(
|
||||
'studiensemester_kurzbz' => $studiensemester_kurzbz,
|
||||
@@ -430,8 +565,15 @@ class Students extends FHCAPI_Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null)
|
||||
{
|
||||
protected function fetchStudents(
|
||||
$studiensemester_kurzbz,
|
||||
$studiengang_kz,
|
||||
$semester = null,
|
||||
$verband = null,
|
||||
$gruppe = null,
|
||||
$gruppe_kurzbz = null,
|
||||
$orgform_kurzbz = null
|
||||
) {
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
@@ -440,21 +582,6 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
/*
|
||||
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
|
||||
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
|
||||
$this->PrestudentModel->addJoin(
|
||||
'public.tbl_studentlehrverband v',
|
||||
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz)
|
||||
);*/
|
||||
$this->prepareQuery($studiensemester_kurzbz, '');
|
||||
|
||||
$this->PrestudentModel->addSelect('v.semester');
|
||||
@@ -462,18 +589,6 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
$this->PrestudentModel->addSelect("'' AS priorisierung_relativ");
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus pss
|
||||
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
|
||||
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
|
||||
LIMIT 1
|
||||
) AS statusofsemester"
|
||||
);
|
||||
|
||||
|
||||
$where = [];
|
||||
|
||||
@@ -506,7 +621,6 @@ class Students extends FHCAPI_Controller
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
@@ -540,39 +654,18 @@ class Students extends FHCAPI_Controller
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
/*
|
||||
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
|
||||
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid', 'LEFT');
|
||||
$this->PrestudentModel->addJoin(
|
||||
'public.tbl_studentlehrverband v',
|
||||
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz),
|
||||
'LEFT'
|
||||
);*/
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false);
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus pss
|
||||
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
|
||||
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
|
||||
LIMIT 1
|
||||
) AS statusofsemester"
|
||||
);
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN pls.ausbildungssemester::text
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
@@ -609,40 +702,12 @@ class Students extends FHCAPI_Controller
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
/*
|
||||
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
|
||||
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
|
||||
$this->PrestudentModel->addJoin(
|
||||
'public.tbl_studentlehrverband v',
|
||||
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz),
|
||||
'LEFT'
|
||||
);*/
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect('v.semester');
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus pss
|
||||
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
|
||||
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
|
||||
LIMIT 1
|
||||
) AS statusofsemester"
|
||||
);
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
|
||||
@@ -681,33 +746,12 @@ class Students extends FHCAPI_Controller
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
/*
|
||||
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
|
||||
$this->PrestudentModel->addJoin(
|
||||
'public.tbl_studentlehrverband v',
|
||||
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz),
|
||||
'LEFT'
|
||||
);*/
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect('v.semester');
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus pss
|
||||
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
|
||||
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
|
||||
LIMIT 1
|
||||
) AS statusofsemester"
|
||||
);
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
@@ -771,6 +815,18 @@ class Students extends FHCAPI_Controller
|
||||
// verband
|
||||
// gruppe
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus pss
|
||||
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
|
||||
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
|
||||
LIMIT 1
|
||||
) AS statusofsemester"
|
||||
);
|
||||
|
||||
$this->PrestudentModel->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.studiengang_kz');
|
||||
$this->PrestudentModel->addSelect('stg.bezeichnung AS stg_bezeichnung');
|
||||
@@ -806,13 +862,6 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect('mentor');
|
||||
$this->PrestudentModel->addSelect('b.aktiv AS bnaktiv');
|
||||
|
||||
/*$this->PrestudentModel->addSelect('tbl_prestudent.reihungstest_id');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.anmeldungreihungstest');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.gsstudientyp_kurzbz');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.priorisierung');
|
||||
$this->PrestudentModel->addSelect('p.zugangscode');
|
||||
$this->PrestudentModel->addSelect('p.bpk');*/
|
||||
|
||||
$this->PrestudentModel->db->where_in('tbl_prestudent.studiengang_kz', $this->allowedStgs);
|
||||
|
||||
$this->PrestudentModel->addOrder('nachname');
|
||||
@@ -827,13 +876,13 @@ class Students extends FHCAPI_Controller
|
||||
$this->PrestudentModel->addSelect("(
|
||||
SELECT count(*)
|
||||
FROM (
|
||||
SELECT *, public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) AS laststatus
|
||||
FROM PUBLIC.tbl_prestudent pss
|
||||
JOIN PUBLIC.tbl_prestudentstatus USING (prestudent_id)
|
||||
SELECT *, public.get_rolle_prestudent(pss.prestudent_id, NULL) AS laststatus
|
||||
FROM public.tbl_prestudent pss
|
||||
JOIN public.tbl_prestudentstatus USING (prestudent_id)
|
||||
WHERE person_id = p.person_id
|
||||
AND studiensemester_kurzbz = (
|
||||
SELECT studiensemester_kurzbz
|
||||
FROM PUBLIC.tbl_prestudentstatus
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = tbl_prestudent.prestudent_id
|
||||
AND status_kurzbz = 'Interessent'
|
||||
LIMIT 1
|
||||
@@ -842,7 +891,7 @@ class Students extends FHCAPI_Controller
|
||||
) prest
|
||||
WHERE laststatus NOT IN ('Abbrecher', 'Abgewiesener', 'Absolvent')
|
||||
AND priorisierung <= tbl_prestudent.priorisierung
|
||||
) || ' (' || tbl_prestudent.priorisierung || ')' AS priorisierung_relativ", false);
|
||||
) || ' (' || COALESCE(tbl_prestudent.priorisierung::text, ' '::text) || ')' AS priorisierung_relativ", false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -854,40 +903,20 @@ class Students extends FHCAPI_Controller
|
||||
*/
|
||||
protected function addFilter($studiensemester_kurzbz)
|
||||
{
|
||||
$filter = json_decode($this->input->get('filter'), true);
|
||||
$filter = $this->input->post('filter');
|
||||
|
||||
if (!is_array($filter))
|
||||
{
|
||||
$this->addMeta('addfilter', 'invalid filter: ' . $this->input->get('filter'));
|
||||
$this->addMeta('addfilter', 'invalid filter: ' . json_encode($this->input->post('filter')));
|
||||
return;
|
||||
}
|
||||
if (isset($filter['konto_count_0'])) {
|
||||
$bt = $this->PrestudentModel->escape($filter['konto_count_0']);
|
||||
$stdsem = $this->PrestudentModel->escape($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->db->where('(
|
||||
SELECT count(*)
|
||||
FROM public.tbl_konto
|
||||
WHERE person_id=tbl_prestudent.person_id
|
||||
AND buchungstyp_kurzbz=' . $bt . '
|
||||
AND studiensemester_kurzbz=' . $stdsem . '
|
||||
) =', 0);
|
||||
$this->PrestudentModel->db->where('get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) !=', 'Incoming');
|
||||
}
|
||||
if (isset($filter['konto_missing_counter'])) {
|
||||
$bt = $this->PrestudentModel->escape($filter['konto_missing_counter']);
|
||||
$stg = '';
|
||||
if ($this->variablelib->getVar('kontofilterstg') == 'true')
|
||||
$stg = ' AND studiengang_kz=tbl_prestudent.studiengang_kz';
|
||||
|
||||
$bt = $bt == 'alle' ? '' : ' AND buchungstyp_kurzbz=' . $bt;
|
||||
|
||||
$this->PrestudentModel->db->where('(
|
||||
SELECT sum(betrag)
|
||||
FROM public.tbl_konto
|
||||
WHERE person_id=tbl_prestudent.person_id' .
|
||||
$bt .
|
||||
$stg . '
|
||||
) !=', 0);
|
||||
foreach ($filter as $item) {
|
||||
if (isset($item['usestdsem']) && $item['usestdsem'])
|
||||
$item['studiensemester_kurzbz'] = $studiensemester_kurzbz;
|
||||
if (!$this->PrestudentModel->addFilter($item)) {
|
||||
$this->addMeta('addfilter', 'invalid filter: ' . json_encode($item));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,6 +272,7 @@ class Verband extends FHCAPI_Controller
|
||||
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband ORDER BY gruppe LIMIT 1)) AS name", false);
|
||||
$this->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf");
|
||||
|
||||
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($semester) . ' AS semester');
|
||||
$this->StudiengangModel->addSelect('verband');
|
||||
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
|
||||
|
||||
@@ -320,6 +321,8 @@ class Verband extends FHCAPI_Controller
|
||||
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, gruppe, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband AND gruppe=v.gruppe ORDER BY gruppe LIMIT 1)) AS name", false);
|
||||
$this->StudiengangModel->addSelect("TRUE AS leaf", false);
|
||||
|
||||
$this->StudiengangModel->addSelect('v.semester');
|
||||
$this->StudiengangModel->addSelect('v.verband');
|
||||
$this->StudiengangModel->addSelect('gruppe');
|
||||
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
class Vertrag extends FHCAPI_Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getVertrag' => ['admin:r', 'assistenz:r'],
|
||||
'cancelVertrag' => ['admin:r', 'assistenz:r']
|
||||
]);
|
||||
|
||||
// Load Libraries
|
||||
$this->load->library('form_validation');
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'ui',
|
||||
'person',
|
||||
'projektarbeit'
|
||||
]);
|
||||
|
||||
// Load models
|
||||
$this->load->model('accounting/Vertrag_model', 'VertragModel');
|
||||
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
|
||||
$this->load->model('person/Benutzer_model', 'BenutzerModel');
|
||||
|
||||
// load libraries
|
||||
$this->load->library('PermissionLib');
|
||||
}
|
||||
|
||||
public function getVertrag()
|
||||
{
|
||||
$vertrag_id = $this->input->get('vertrag_id');
|
||||
|
||||
if (!isset($vertrag_id) || !is_numeric($vertrag_id))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Vertrag ID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->VertragModel->getVertragById($vertrag_id);
|
||||
|
||||
if (isError($result))
|
||||
{
|
||||
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
}
|
||||
|
||||
if (!hasData($result)) $this->terminateWithSuccess([]);
|
||||
|
||||
$vertrag = getData($result)[0];
|
||||
|
||||
$this->terminateWithSuccess($vertrag);
|
||||
}
|
||||
|
||||
public function cancelVertrag()
|
||||
{
|
||||
$vertrag_id = $this->input->post('vertrag_id');
|
||||
$person_id = $this->input->post('person_id');
|
||||
|
||||
if (!isset($vertrag_id) || !is_numeric($vertrag_id))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Vertrag ID']), self::ERROR_TYPE_GENERAL);
|
||||
if (!isset($person_id) || !is_numeric($person_id))
|
||||
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
// * first find lehrveranstaltung_id of the contracts lehrveranstaltung
|
||||
$this->VertragModel->addSelect('lehrveranstaltung_id');
|
||||
$this->VertragModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id', 'LEFT');
|
||||
$result = $this->VertragModel->loadWhere(['vertrag_id' => $vertrag_id]);
|
||||
|
||||
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!hasData($result)) $this->terminateWithSuccess([]);
|
||||
|
||||
$lehrveranstaltung_id = getData($result)[0]->lehrveranstaltung_id;
|
||||
|
||||
$allOe = $this->LehrveranstaltungModel->getAllOe($lehrveranstaltung_id);
|
||||
|
||||
if (isError($allOe)) $this->terminateWithError(getError($allOe), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$allOe = hasData($allOe) ? getData($allOe) : [];
|
||||
|
||||
$this->addMeta('oe', $allOe);
|
||||
|
||||
// * then check if the user has permissions to cancel the corresponding lv-organisational units
|
||||
if (!$this->permissionlib->isBerechtigtMultipleOe('admin', $allOe, 'suid') &&
|
||||
!$this->permissionlib->isBerechtigtMultipleOe('lehre/lehrauftrag_bestellen', $allOe, 'suid'))
|
||||
{
|
||||
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'lehrauftrag_bestellen:rw']]);
|
||||
}
|
||||
|
||||
$uidResult = $this->BenutzerModel->getFromPersonId($person_id);
|
||||
|
||||
if (isError($uidResult)) $this->terminateWithError(getError($uidResult), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
if (!hasData($uidResult)) $this->terminateWithError("no user found", self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$mitarbeiter_uid = getData($uidResult)[0]->uid;
|
||||
|
||||
$result = $this->VertragModel->cancelVertrag($vertrag_id, $mitarbeiter_uid);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
}
|
||||
@@ -51,13 +51,17 @@ class Vorlagen extends FHCAPI_Controller
|
||||
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
|
||||
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$oe_kurzbz = current($data);
|
||||
if (hasData($result))
|
||||
{
|
||||
$data = getData($result);
|
||||
|
||||
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
$oe_kurzbz = array_column($data, 'oe_kurzbz');
|
||||
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz);
|
||||
|
||||
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
|
||||
}
|
||||
$this->terminateWithSuccess(array());
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -70,20 +70,22 @@ abstract class Auth_Controller extends FHC_Controller
|
||||
/**
|
||||
* Checks for Permissions depending if the given person is a
|
||||
* Mitarbeiter and/or Student
|
||||
* If neither Student nor Mitarbeiter, default permissions are checked
|
||||
* and exits/outputs an error if they are not met.
|
||||
*
|
||||
* @param integer $person_id
|
||||
* @param array $permMa Perms if the person is a Mitarbeiter
|
||||
* @param array $permStud Perms if the person is a Student
|
||||
* @param array $permDefault Perms if the person is neither a Student nor a Mitarbeiter
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function checkPermissionsForPerson($person_id, $permMa, $permStud)
|
||||
protected function checkPermissionsForPerson($person_id, $permMa, $permStud, $permDefault = null)
|
||||
{
|
||||
$res = $this->hasPermissionsForPerson($person_id, $permMa, $permStud);
|
||||
|
||||
$res = $this->hasPermissionsForPerson($person_id, $permMa, $permStud, $permDefault);
|
||||
|
||||
if ($res) {
|
||||
$perm = array_keys(array_flip(array_merge($res|1 ? $permMa : [], $res|2 ? $permStud : [])));
|
||||
$perm = array_keys(array_flip(array_merge($res&1 ? $permMa : [], $res&2 ? $permStud : [], $res&4 ? $permDefault : [])));
|
||||
$this->_outputAuthError([$this->router->method => $perm]);
|
||||
}
|
||||
}
|
||||
@@ -108,16 +110,19 @@ abstract class Auth_Controller extends FHC_Controller
|
||||
* Checks for Permissions depending if the given person is a
|
||||
* Mitarbeiter and/or Student
|
||||
* and returns the result.
|
||||
*
|
||||
* If neither Student nor Mitarbeiter, default permissions are checked
|
||||
*
|
||||
* @param integer $person_id
|
||||
* @param array $permMa Perms if the person is a Mitarbeiter
|
||||
* @param array $permStud Perms if the person is a Student
|
||||
*
|
||||
* @param array $permDefault Perms if the person is neither a Student nor a Mitarbeiter
|
||||
* @return integer 0 if permission is granted
|
||||
*/
|
||||
protected function hasPermissionsForPerson($person_id, $permMa, $permStud)
|
||||
protected function hasPermissionsForPerson($person_id, $permMa, $permStud, $permDefault)
|
||||
{
|
||||
$res = 3;
|
||||
$res = 8;
|
||||
$isMitarbeiter = false;
|
||||
$isStudent = false;
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
$this->PersonModel->addJoin('public.tbl_benutzer', 'person_id');
|
||||
$this->PersonModel->addJoin('public.tbl_mitarbeiter', 'uid = mitarbeiter_uid');
|
||||
@@ -125,7 +130,8 @@ abstract class Auth_Controller extends FHC_Controller
|
||||
if (hasData($result)) {
|
||||
if ($this->permissionlib->isEntitled(['a' => $permMa], 'a'))
|
||||
return 0;
|
||||
$res = 1;
|
||||
$isMitarbeiter = true;
|
||||
$res += 1;
|
||||
}
|
||||
$this->PersonModel->addJoin('public.tbl_prestudent', 'person_id');
|
||||
$result = $this->PersonModel->load($person_id);
|
||||
@@ -140,8 +146,15 @@ abstract class Auth_Controller extends FHC_Controller
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$isStudent = true;
|
||||
$res += 2;
|
||||
}
|
||||
if (isset($permDefault) && !$isMitarbeiter && !$isStudent)
|
||||
{
|
||||
if ($this->permissionlib->isEntitled(['a' => $permDefault], 'a'))
|
||||
return 0;
|
||||
$res += 4;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
@@ -515,3 +515,73 @@ function has_permissions_for_stg($studiengang_kz, $permissions = '')
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if an entry exists in the database
|
||||
*/
|
||||
function is_in_db($key, $model = '')
|
||||
{
|
||||
if (!$model)
|
||||
return false;
|
||||
|
||||
$field = strstr($model, ":");
|
||||
if ($field) {
|
||||
$model = strstr($model, ":", true);
|
||||
$field = substr($field, 1);
|
||||
}
|
||||
|
||||
$CI =& get_instance();
|
||||
$CI->load->model($model, $model);
|
||||
|
||||
if ($field) {
|
||||
$result = $CI->$model->loadWhere([
|
||||
$field => $key
|
||||
]);
|
||||
} else {
|
||||
$result = $CI->$model->load($key);
|
||||
}
|
||||
|
||||
return (isSuccess($result) && hasData($result));
|
||||
}
|
||||
|
||||
/**
|
||||
* is building an array for Dropdown Entry in Print Dropdown
|
||||
* @param $id id for the Document to add to the Document Array
|
||||
* @param $name title of the dropdownEntry
|
||||
* @param $parameterUrl url of parameters xml, xsl, format etc as needed
|
||||
* WITHOUT BASEURL eg. "xml=abschlusspruefung.rdf.php&xsl_stg_kz=$studiengang_kz&xsl=Bescheid&output=pdf"
|
||||
* @param $uid default parameter, if null only parameterurl will be added
|
||||
* additional needed parameter: put in the parameterUrl
|
||||
* @param $alternativeBaseUrl: if baseUrl not pdfExport.php, put here alternative without ? char, eg. "zutrittskarte.php"
|
||||
*
|
||||
* @return Array
|
||||
*/
|
||||
function buildDropdownEntryPrintArray($id, $name, $parameterurl, $uid=null, $order=null, $alternativeBaseUrl=null)
|
||||
{
|
||||
//DEFAULT BASEURL
|
||||
$baseurl = "pdfExport.php?";
|
||||
|
||||
$uidString = $uid ? "&uid=" . $uid : "";
|
||||
|
||||
|
||||
|
||||
if($alternativeBaseUrl)
|
||||
{
|
||||
return [
|
||||
"id" => $id,
|
||||
"type" => "documenturl",
|
||||
"name" => $name,
|
||||
"url" => $alternativeBaseUrl . "?" . $parameterurl . $uidString,
|
||||
"order" => $order
|
||||
];
|
||||
}
|
||||
else
|
||||
return [
|
||||
"id" => $id,
|
||||
"type" => "documenturl",
|
||||
"name" => $name,
|
||||
"url" => $baseurl . $parameterurl . "&uid=" . $uid,
|
||||
"order" => $order
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
@@ -246,3 +246,10 @@ function generateSkipLink($skipID)
|
||||
$toPrint.='" class="fhcSkipLink" aria-label="Skip to main content"></a>';
|
||||
echo $toPrint;
|
||||
}
|
||||
|
||||
function absoluteJsImportUrl($relurl)
|
||||
{
|
||||
$ci =& get_instance();
|
||||
$url = base_url($relurl) . '?'. $ci->config->item('fhcomplete_build_version');
|
||||
return $url;
|
||||
}
|
||||
@@ -41,3 +41,4 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
|
||||
$lang['form_validation_has_write_permissions'] = 'You have no rights to edit {field} field.';
|
||||
$lang['form_validation_is_valid_date'] = 'The date format is invalid or out of range.';
|
||||
$lang['form_validation_has_permissions_for_stg'] = 'You have no rights for stg {field}.';
|
||||
$lang['form_validation_is_in_db'] = '{field} does not exist.';
|
||||
|
||||
@@ -402,6 +402,26 @@ class Vertrag_model extends DB_Model
|
||||
return $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid, 'lehreinheit_id' => $lehreinheit_id));
|
||||
}
|
||||
|
||||
public function getVertragById($vertrag_id)
|
||||
{
|
||||
$this->addSelect(
|
||||
'tbl_vertrag.vertrag_id, vertragstyp_kurzbz, vertragsstunden, vertragsstunden_studiensemester_kurzbz, status.vertragsstatus_kurzbz,
|
||||
status.bezeichnung AS vertragsstatus, tbl_vertrag.betrag, lema.semesterstunden, lema.stundensatz'
|
||||
);
|
||||
$this->addJoin('lehre.tbl_lehreinheitmitarbeiter lema', 'tbl_vertrag.vertrag_id = lema.vertrag_id', 'LEFT');
|
||||
$this->addJoin('
|
||||
(
|
||||
SELECT DISTINCT ON(vst.vertrag_id) vst.vertrag_id,
|
||||
bezeichnung,
|
||||
tbl_vertragsstatus.vertragsstatus_kurzbz
|
||||
FROM lehre.tbl_vertrag_vertragsstatus vst
|
||||
JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz)
|
||||
ORDER BY vst.vertrag_id, datum DESC
|
||||
) as status', 'status.vertrag_id = lehre.tbl_vertrag.vertrag_id', 'LEFT');
|
||||
|
||||
return $this->loadWhere(['tbl_vertrag.vertrag_id' => $vertrag_id]);
|
||||
}
|
||||
|
||||
public function cancelVertrag($vertrag_id, $mitarbeiter_uid)
|
||||
{
|
||||
$vertrag = $this->load($vertrag_id);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
use CI3_Events as Events;
|
||||
|
||||
class Prestudent_model extends DB_Model
|
||||
{
|
||||
/**
|
||||
@@ -782,4 +784,118 @@ class Prestudent_model extends DB_Model
|
||||
|
||||
return $this->execQuery($query, array($person_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a filter to the query builder
|
||||
*
|
||||
* @param array $filter
|
||||
* @return boolean
|
||||
*/
|
||||
public function addFilter($filter)
|
||||
{
|
||||
if (!isset($filter['type']))
|
||||
return false;
|
||||
|
||||
switch ($filter['type']) {
|
||||
case 'konto':
|
||||
$bt = '';
|
||||
$stdsem = '';
|
||||
$comp = '!=';
|
||||
|
||||
if (isset($filter['buchungstyp_kurzbz']) && $filter['buchungstyp_kurzbz'] != 'all')
|
||||
$bt = ' AND buchungstyp_kurzbz=' . $this->escape($filter['buchungstyp_kurzbz']);
|
||||
|
||||
if (isset($filter['studiensemester_kurzbz']))
|
||||
$stdsem = ' AND studiensemester_kurzbz=' . $this->escape($filter['studiensemester_kurzbz']);
|
||||
|
||||
if (isset($filter['missing']) && $filter['missing']) {
|
||||
$comp = '=';
|
||||
$this->db->where('get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) !=', 'Incoming');
|
||||
}
|
||||
|
||||
$this->db->where('(
|
||||
SELECT count(*)
|
||||
FROM public.tbl_konto
|
||||
WHERE person_id=tbl_prestudent.person_id
|
||||
' . $bt . '
|
||||
' . $stdsem . '
|
||||
) ' . $comp, 0);
|
||||
break;
|
||||
|
||||
case 'konto_counter':
|
||||
$bt = '';
|
||||
$samestg = '';
|
||||
$past = '';
|
||||
|
||||
if (isset($filter['buchungstyp_kurzbz']) && $filter['buchungstyp_kurzbz'] != 'all')
|
||||
$bt = ' AND buchungstyp_kurzbz = ' . $this->escape($filter['buchungstyp_kurzbz']);
|
||||
|
||||
if (isset($filter['samestg']) && $filter['samestg'])
|
||||
$samestg = ' AND studiengang_kz = tbl_prestudent.studiengang_kz';
|
||||
|
||||
if (isset($filter['past']) && $filter['past'])
|
||||
$past = ' AND buchungsdatum < NOW()';
|
||||
|
||||
$this->db->where('(
|
||||
SELECT sum(betrag)
|
||||
FROM public.tbl_konto
|
||||
WHERE person_id = tbl_prestudent.person_id
|
||||
' . $bt . '
|
||||
' . $samestg . '
|
||||
' . $past . '
|
||||
) !=', 0);
|
||||
break;
|
||||
|
||||
case 'zgv':
|
||||
$this->db
|
||||
->group_start()
|
||||
->group_start()
|
||||
->where('zgv_code IS NOT NULL')
|
||||
->where('zgvdatum IS NULL')
|
||||
->group_end()
|
||||
->or_group_start()
|
||||
->where('zgvmas_code IS NOT NULL')
|
||||
->where('zgvmadatum IS NULL')
|
||||
->group_end()
|
||||
->or_group_start()
|
||||
->where('zgvdoktor_code IS NOT NULL')
|
||||
->where('zgvdoktordatum IS NULL')
|
||||
->group_end()
|
||||
->group_end();
|
||||
break;
|
||||
|
||||
case 'documents':
|
||||
$this->db->where('(
|
||||
SELECT count(*)
|
||||
FROM public.tbl_dokumentstudiengang
|
||||
WHERE dokument_kurzbz NOT IN (
|
||||
SELECT dokument_kurzbz
|
||||
FROM tbl_dokumentprestudent
|
||||
WHERE prestudent_id=tbl_prestudent.prestudent_id
|
||||
)
|
||||
AND studiengang_kz=tbl_prestudent.studiengang_kz
|
||||
) !=', 0);
|
||||
break;
|
||||
|
||||
case 'statusgrund':
|
||||
if (!isset($filter['statusgrund_id']))
|
||||
return false;
|
||||
|
||||
if (isset($filter['studiensemester_kurzbz']))
|
||||
$stdsem = ' AND studiensemester_kurzbz=' . $this->escape($filter['studiensemester_kurzbz']);
|
||||
|
||||
$this->db->where('(
|
||||
SELECT count(*)
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = tbl_prestudent.prestudent_id
|
||||
AND statusgrund_id = ' . $this->escape($filter['statusgrund_id']) . '
|
||||
' . $stdsem . '
|
||||
) !=', 0);
|
||||
break;
|
||||
}
|
||||
|
||||
Events::trigger('prestudent_add_filter', $filter);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1255,4 +1255,61 @@ class Lehrveranstaltung_model extends DB_Model
|
||||
|
||||
return $this->execReadOnlyQuery($qry, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Lehrveranstaltungen for a student, as needed for a Projektarbeit.
|
||||
* @param student_uid
|
||||
* @param studiengang_kz optional, all Lvs of this Studiengang will be included
|
||||
* @param additional_lehrveranstaltung_id optional, this lv will be added to result
|
||||
* @return object success or error
|
||||
*/
|
||||
public function getLvsForProjektarbeit($student_uid, $studiengang_kz = null, $additional_lehrveranstaltung_id = null)
|
||||
{
|
||||
$params = array($student_uid, $student_uid);
|
||||
|
||||
$qry = "
|
||||
SELECT *
|
||||
FROM
|
||||
lehre.tbl_lehrveranstaltung
|
||||
WHERE
|
||||
(
|
||||
lehrveranstaltung_id IN (
|
||||
|
||||
SELECT
|
||||
lehrveranstaltung_id
|
||||
FROM
|
||||
campus.vw_student_lehrveranstaltung
|
||||
WHERE
|
||||
uid=?
|
||||
|
||||
UNION
|
||||
|
||||
SELECT
|
||||
lehrveranstaltung_id
|
||||
FROM
|
||||
lehre.tbl_zeugnisnote
|
||||
WHERE
|
||||
student_uid=?
|
||||
)";
|
||||
|
||||
if (isset($studiengang_kz))
|
||||
{
|
||||
$params[] = $studiengang_kz;
|
||||
$qry .= " OR (studiengang_kz = ? AND semester IS NOT NULL)";
|
||||
}
|
||||
|
||||
if (isset($additional_lehrveranstaltung_id))
|
||||
{
|
||||
$params[] = $additional_lehrveranstaltung_id;
|
||||
$qry .= " OR lehrveranstaltung_id = ?";
|
||||
}
|
||||
|
||||
$qry .= "
|
||||
)
|
||||
AND projektarbeit = TRUE
|
||||
ORDER BY
|
||||
semester, bezeichnung";
|
||||
|
||||
return $this->execQuery($qry, $params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,15 +24,16 @@ class Projektarbeit_model extends DB_Model
|
||||
public function getProjektarbeit($student_uid, $studiengang_kz = null, $studiensemester_kurzbz = null, $projekttyp = null, $final = null)
|
||||
{
|
||||
$qry = "SELECT
|
||||
tbl_projektarbeit.* , tbl_projekttyp.bezeichnung
|
||||
tbl_projektarbeit.*, tbl_projekttyp.bezeichnung,
|
||||
tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id,
|
||||
tbl_firma.name AS firma_name
|
||||
FROM
|
||||
lehre.tbl_projektarbeit
|
||||
JOIN
|
||||
lehre.tbl_projekttyp USING (projekttyp_kurzbz), lehre.tbl_lehreinheit, lehre.tbl_lehrveranstaltung
|
||||
|
||||
JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
|
||||
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
|
||||
JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
|
||||
LEFT JOIN public.tbl_firma USING (firma_id)
|
||||
WHERE
|
||||
tbl_projektarbeit.lehreinheit_id=tbl_lehreinheit.lehreinheit_id AND
|
||||
tbl_lehreinheit.lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id AND
|
||||
tbl_projektarbeit.student_uid = ?";
|
||||
|
||||
$params = array($student_uid);
|
||||
@@ -261,4 +262,30 @@ class Projektarbeit_model extends DB_Model
|
||||
|
||||
return $this->execReadOnlyQuery($qry, array($projektarbeit_id));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param
|
||||
* @return object success or error
|
||||
*/
|
||||
public function hasBerechtigungForProjektarbeit($projektarbeit_id)
|
||||
{
|
||||
if (!$projektarbeit_id || !is_numeric($projektarbeit_id))
|
||||
return false;
|
||||
|
||||
$this->ProjektarbeitModel->addSelect('studiengang_kz');
|
||||
$this->ProjektarbeitModel->addJoin('public.tbl_student', 'student_uid');
|
||||
$result = $this->ProjektarbeitModel->load($projektarbeit_id);
|
||||
if (isError($result) || !hasData($result))
|
||||
return false;
|
||||
|
||||
$studiengang_kz = getData($result)[0]->studiengang_kz;
|
||||
|
||||
if ($this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz))
|
||||
return true;
|
||||
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ class Projektbetreuer_model extends DB_Model
|
||||
parent::__construct();
|
||||
$this->dbTable = 'lehre.tbl_projektbetreuer';
|
||||
$this->pk = array('betreuerart_kurzbz', 'projektarbeit_id', 'person_id');
|
||||
$this->hasSequence = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -157,7 +157,6 @@ class Studienplan_model extends DB_Model
|
||||
return $this->execReadOnlyQuery($qry, array($lv_id));
|
||||
}
|
||||
|
||||
|
||||
public function getStudienplaeneForPerson($person_id)
|
||||
{
|
||||
$this->addDistinct();
|
||||
|
||||
@@ -207,7 +207,6 @@ class Notiz_model extends DB_Model
|
||||
";
|
||||
|
||||
return $this->execQuery($qry, array($type, $id));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -151,12 +151,21 @@ class Person_model extends DB_Model
|
||||
*/
|
||||
public function searchPerson($filter)
|
||||
{
|
||||
$this->addSelect('vorname, nachname, gebdatum, person_id');
|
||||
$this->addSelect('vorname, nachname, gebdatum, person_id, titelpre, titelpost');
|
||||
$this->addSelect("CASE
|
||||
WHEN EXISTS
|
||||
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=tbl_person.person_id)
|
||||
THEN 'Mitarbeiter'
|
||||
WHEN EXISTS
|
||||
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=tbl_person.person_id)
|
||||
THEN 'Student'
|
||||
ELSE 'Person'
|
||||
END AS status");
|
||||
$result = $this->loadWhere(
|
||||
'lower(nachname) like '.$this->db->escape('%'.$filter.'%')."
|
||||
'lower(nachname) like '.$this->db->escape('%'.mb_strtolower($filter).'%')."
|
||||
OR lower(vorname) like ".$this->db->escape('%'.$filter.'%')."
|
||||
OR lower(nachname || ' ' || vorname) like ".$this->db->escape('%'.$filter.'%')."
|
||||
OR lower(vorname || ' ' || nachname) like ".$this->db->escape('%'.$filter.'%')
|
||||
OR lower(nachname || ' ' || vorname) like ".$this->db->escape('%'.mb_strtolower($filter).'%')."
|
||||
OR lower(vorname || ' ' || nachname) like ".$this->db->escape('%'.mb_strtolower($filter).'%')
|
||||
);
|
||||
|
||||
return $result;
|
||||
@@ -411,4 +420,4 @@ class Person_model extends DB_Model
|
||||
return success($result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,17 +12,24 @@ class Firma_model extends DB_Model
|
||||
$this->pk = 'firma_id';
|
||||
}
|
||||
|
||||
public function searchFirmen($filter)
|
||||
public function searchFirmen($filter, $aktiv = null)
|
||||
{
|
||||
$params = [];
|
||||
$filter = strtoLower($filter);
|
||||
$qry = "
|
||||
SELECT
|
||||
SELECT
|
||||
f.name, f.firma_id
|
||||
FROM
|
||||
public.tbl_firma f
|
||||
WHERE
|
||||
lower (f.name) LIKE '%". $this->db->escape_like_str($filter)."%'";
|
||||
FROM
|
||||
public.tbl_firma f
|
||||
WHERE
|
||||
lower (f.name) LIKE '%". $this->db->escape_like_str($filter)."%'";
|
||||
|
||||
return $this->execQuery($qry);
|
||||
if (isset($aktiv) && is_bool($aktiv))
|
||||
{
|
||||
$params[] = $aktiv;
|
||||
$qry .= " AND aktiv = ?";
|
||||
}
|
||||
|
||||
return $this->execQuery($qry, $params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,12 +353,14 @@ class Mitarbeiter_model extends DB_Model
|
||||
{
|
||||
$filter = strtoLower($filter);
|
||||
|
||||
$returnwert = "p.person_id, p.nachname, p.vorname, p.titelpost, p.titelpre";
|
||||
|
||||
if ($mode == "mitAkadGrad")
|
||||
$returnwert = "ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' ', p.titelpost, ' ', p.titelpre, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter";
|
||||
$returnwert .= ", ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' ', p.titelpost, ' ', p.titelpre, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter";
|
||||
elseif ($mode == "ohneMaUid")
|
||||
$returnwert = "p.person_id, CONCAT(p.nachname, ' ', p.vorname, ' ', p.titelpost, ' ', p.titelpre) as mitarbeiter";
|
||||
$returnwert .= ", CONCAT(p.nachname, ' ', p.vorname, ' ', p.titelpost, ' ', p.titelpre) as mitarbeiter";
|
||||
else
|
||||
$returnwert = "ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter";
|
||||
$returnwert .= ", ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter";
|
||||
|
||||
$qry = "
|
||||
SELECT " . $returnwert . "
|
||||
@@ -373,7 +375,11 @@ class Mitarbeiter_model extends DB_Model
|
||||
OR
|
||||
lower (p.vorname) LIKE '%". $this->db->escape_like_str($filter)."%'
|
||||
OR
|
||||
(ma.mitarbeiter_uid) LIKE '%". $this->db->escape_like_str($filter)."%'";
|
||||
(ma.mitarbeiter_uid) LIKE '%". $this->db->escape_like_str($filter)."%'
|
||||
OR
|
||||
lower(vorname || ' ' || nachname || ' ' || vorname) like ".$this->db->escape('%'.mb_strtolower($filter).'%')."
|
||||
ORDER BY
|
||||
p.nachname, p.vorname, b.uid, p.person_id";
|
||||
|
||||
return $this->execQuery($qry);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
class Stundensatz_model extends DB_Model
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
@@ -43,6 +43,97 @@ class Stundensatz_model extends DB_Model
|
||||
return $this->execQuery($qry, $params);
|
||||
}
|
||||
|
||||
public function getStundensatzForMitarbeiter($person_id, $studiensemester_kurzbz)
|
||||
{
|
||||
$this->load->config('stv');
|
||||
|
||||
$useFixangestelltStundensatz = $this->config->item('tabs')['projektarbeit']['lvLektroinnenzuteilungFixangestelltStundensatz'];
|
||||
$defaultStundensatz = $this->config->item('tabs')['projektarbeit']['defaultProjektbetreuerStundensatz'];
|
||||
|
||||
$stundensatz = '';
|
||||
|
||||
if(isset($person_id) && isset($studiensemester_kurzbz))
|
||||
{
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
$this->StudiensemesterModel->addSelect('start, ende');
|
||||
$result = $this->StudiensemesterModel->load($studiensemester_kurzbz);
|
||||
|
||||
if (hasData($result))
|
||||
{
|
||||
$studiensemester = getData($result)[0];
|
||||
|
||||
if (isset($useFixangestelltStundensatz) && !$useFixangestelltStundensatz)
|
||||
{
|
||||
// load Mitarbeiter
|
||||
$params = [$person_id];
|
||||
$qry = "
|
||||
SELECT
|
||||
mitarbeiter_uid, fixangestellt
|
||||
FROM
|
||||
public.tbl_mitarbeiter
|
||||
JOIN public.tbl_benutzer ON(tbl_benutzer.uid=tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE
|
||||
person_id=?
|
||||
ORDER BY
|
||||
tbl_mitarbeiter.insertamum DESC NULLS LAST
|
||||
LIMIT 1";
|
||||
|
||||
$result = $this->execQuery($qry, $params);
|
||||
|
||||
if (hasData($result))
|
||||
{
|
||||
foreach (getData($result) as $ma)
|
||||
{
|
||||
if (!$ma->fixangestellt)
|
||||
{
|
||||
$stundensatzRes = $this->getStundensatzByDatum(
|
||||
$ma->mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre'
|
||||
);
|
||||
|
||||
if (hasData($stundensatzRes))
|
||||
$stundensatz = getData($stundensatzRes)[0]->stundensatz;
|
||||
else
|
||||
$stundensatz = '0.00';
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$stundensatz = '0.00';
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$params = [$person_id, $studiensemester->ende, $studiensemester->start];
|
||||
$qry = "SELECT ss.stundensatz
|
||||
FROM hr.tbl_stundensatz ss
|
||||
JOIN public.tbl_mitarbeiter ON ss.uid = tbl_mitarbeiter.mitarbeiter_uid
|
||||
JOIN public.tbl_benutzer ON(tbl_benutzer.uid=tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE person_id=?
|
||||
AND stundensatztyp = 'lehre'
|
||||
AND gueltig_von <= ?
|
||||
AND (gueltig_bis >= ? OR gueltig_bis IS NULL)
|
||||
ORDER BY gueltig_bis DESC NULLS FIRST, gueltig_von DESC NULLS LAST LIMIT 1";
|
||||
|
||||
$result = $this->execQuery($qry, $params);
|
||||
|
||||
if (hasData($result))
|
||||
{
|
||||
$stundensatz = getData($result)[0]->stundensatz;
|
||||
}
|
||||
else
|
||||
{
|
||||
$stundensatz = $defaultStundensatz;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $stundensatz;
|
||||
}
|
||||
|
||||
public function getDefaultStundensatz($mitarbeiter_uid, $beginn, $ende = null, $typ = null)
|
||||
{
|
||||
$stundensatz_result = $this->getStundensatzByDatum($mitarbeiter_uid, $beginn, $ende, $typ);
|
||||
@@ -58,4 +149,4 @@ class Stundensatz_model extends DB_Model
|
||||
}
|
||||
return $default_stundensatz;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,16 +107,10 @@ if(isset($_GET['getAnmeldung']))
|
||||
$abgeschlossen = false;
|
||||
$semesterlock = false;
|
||||
$regelerfuellt = true;
|
||||
|
||||
if ($kompatible_lv)
|
||||
{
|
||||
$lvregelExists = $lvregel->exists($kompatible_lv);
|
||||
if($lvregelExists)
|
||||
{
|
||||
if($lvregel->isAbgeschlossen($uid, $kompatible_lv))
|
||||
$abgeschlossen=true;
|
||||
else
|
||||
$abgeschlossen=false;
|
||||
}
|
||||
|
||||
if(!$lvregel->checkSemester($kompatible_lv, $semester))
|
||||
{
|
||||
@@ -135,7 +129,7 @@ if(isset($_GET['getAnmeldung']))
|
||||
}
|
||||
}
|
||||
|
||||
if (!(($lvregelExists && !$abgeschlossen) || $semesterlock || !$regelerfuellt))
|
||||
if (!$semesterlock && $regelerfuellt)
|
||||
{
|
||||
$anzahl++;
|
||||
// LV wird angeboten und Anmeldefenster ist offen
|
||||
@@ -152,7 +146,6 @@ if(isset($_GET['getAnmeldung']))
|
||||
echo '<br><input type="radio" disabled="true" value="'.$lvid.'" name="lv" /><span class="ok">'.$lv->bezeichnung.'</span><img src="../../../skin/images/information.png" title="'.$p->t('studienplan/bereitsAngemeldet').'"/>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* else
|
||||
{
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
@import './Fhc.css';
|
||||
@import './SvgIcons.css';
|
||||
@import './components/searchbar/searchbar.css';
|
||||
@import './components/verticalsplit.css';
|
||||
@import './components/FilterComponent.css';
|
||||
@import './components/Tabs.css';
|
||||
@import './components/Notiz.css';
|
||||
@import './components/Messages.css';
|
||||
@import './components/AppMenu.css';
|
||||
|
||||
html {
|
||||
font-size: .875em;
|
||||
}
|
||||
|
||||
#appMenu {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.navbar-dark .navbar-brand:focus {
|
||||
box-shadow: 0 0 0 .25rem rgba(13,110,253,.25);
|
||||
z-index: 3;
|
||||
@@ -37,10 +43,6 @@ html {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
#sidebarMenu {
|
||||
width: 0%;
|
||||
}
|
||||
|
||||
.tabulator-row.disabled.tabulator-row-odd .tabulator-cell {
|
||||
color: var(--gray-400);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/* Themable Variables */
|
||||
:root {
|
||||
--svg-icon-apps: var(--fhc-icon-apps, url('data:image/svg+xml,\
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">\
|
||||
<circle cx="15" cy="15" r="15"/>\
|
||||
<circle cx="15" cy="50" r="15"/>\
|
||||
<circle cx="15" cy="85" r="15"/>\
|
||||
<circle cx="50" cy="15" r="15"/>\
|
||||
<circle cx="50" cy="50" r="15"/>\
|
||||
<circle cx="50" cy="85" r="15"/>\
|
||||
<circle cx="85" cy="15" r="15"/>\
|
||||
<circle cx="85" cy="50" r="15"/>\
|
||||
<circle cx="85" cy="85" r="15"/>\
|
||||
</svg>'));
|
||||
}
|
||||
.svg-icon {
|
||||
display: inline-block;
|
||||
width: 1rem;
|
||||
line-height: 1;
|
||||
background-color: currentColor;
|
||||
}
|
||||
.svg-icon:before {
|
||||
content: "\00a0";
|
||||
}
|
||||
.svg-icon.svg-icon-apps {
|
||||
-webkit-mask-image: var(--svg-icon-apps);
|
||||
mask-image: var(--svg-icon-apps);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
.fhc-app-menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 0;
|
||||
margin: calc(var(--bs-offcanvas-padding-y) * -1) calc(var(--bs-offcanvas-padding-x) * -1);
|
||||
}
|
||||
.fhc-app-menu li {
|
||||
display: block;
|
||||
border: var(--bs-border-width) solid var(--bs-border-color);
|
||||
}
|
||||
.fhc-app-menu li + li {
|
||||
border-top-width: 0;
|
||||
}
|
||||
.fhc-app-menu li a {
|
||||
display: block;
|
||||
padding: .5rem 1rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
.fhc-app-menu li a.active,
|
||||
.fhc-app-menu li a:hover {
|
||||
--bs-link-color-rgb: var(--bs-link-hover-color-rgb);
|
||||
background: var(--surface-hover);
|
||||
}
|
||||
.fhc-app-menu li a.active {
|
||||
pointer-events: none;
|
||||
}
|
||||
@@ -5690,3 +5690,32 @@
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 .25rem rgba(13,110,253,.25);
|
||||
}
|
||||
|
||||
/* input-group */
|
||||
/* autocomplete */
|
||||
.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n+3) > .p-autocomplete > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-control > .p-autocomplete > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > .form-floating:not(:last-child) > .form-select > .p-autocomplete > .p-autocomplete-input,
|
||||
.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating) > .p-autocomplete > .p-autocomplete-input {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) > .p-autocomplete-input,
|
||||
.input-group > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) > .p-autocomplete > .p-autocomplete-input {
|
||||
margin-left: calc(var(--bs-border-width) * -1);
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
|
||||
.p-inputtext.is-invalid:enabled:hover {
|
||||
border-color: var(--bs-form-invalid-border-color);
|
||||
}
|
||||
.p-inputtext.is-invalid:enabled:focus,
|
||||
.was-validated .p-inputtext:invalid:focus {
|
||||
border-color: var(--bs-form-invalid-border-color);
|
||||
box-shadow: 0 0 0 .25rem rgba(var(--bs-danger-rgb),.25);
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ export default {
|
||||
url: 'api/frontend/v1/messages/messages/getUid/' + userParams.id + '/' + userParams.type_id
|
||||
};
|
||||
},
|
||||
getVorlagentext(vorlage_kurzbz){
|
||||
getDataVorlage(vorlage_kurzbz){
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz
|
||||
url: 'api/frontend/v1/messages/messages/getDataVorlage/' + vorlage_kurzbz
|
||||
};
|
||||
},
|
||||
getNameOfDefaultRecipient(params){
|
||||
|
||||
@@ -34,7 +34,7 @@ export default {
|
||||
url: '/api/frontend/v1/studstatus/leitung/getHistory/' + antrag_id
|
||||
};
|
||||
},
|
||||
getPrestudents(query, signal) {
|
||||
getPrestudents(query) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/studstatus/leitung/getPrestudents',
|
||||
|
||||
@@ -86,13 +86,15 @@ export default {
|
||||
getMitarbeiter(searchString) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/getMitarbeiter/' + searchString
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/getMitarbeiter',
|
||||
params: { searchString }
|
||||
};
|
||||
},
|
||||
getPruefer(searchString) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/getPruefer/' + searchString
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/getPruefer',
|
||||
params: { searchString }
|
||||
};
|
||||
},
|
||||
getNoten() {
|
||||
@@ -108,16 +110,11 @@ export default {
|
||||
params: { uids }
|
||||
};
|
||||
},
|
||||
getAllMitarbeiter(){
|
||||
searchPerson(searchString) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/getAllMitarbeiter/'
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/searchPerson/',
|
||||
params: { id }
|
||||
};
|
||||
},
|
||||
getAllPersons(){
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/abschlusspruefung/getAllPersons/'
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
configFilter() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/config/filter'
|
||||
};
|
||||
},
|
||||
configStudent() {
|
||||
return {
|
||||
method: 'get',
|
||||
|
||||
@@ -39,5 +39,5 @@ export default {
|
||||
url: 'api/frontend/v1/stv/archiv/delete',
|
||||
params: {akte_id, studiengang_kz}
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -35,4 +35,14 @@ export default {
|
||||
params
|
||||
};
|
||||
},
|
||||
saveStudent(student_uid, studiensemester_kurzbz, params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/student/saveStudent/'
|
||||
+ encodeURIComponent(student_uid)
|
||||
+ '/'
|
||||
+ encodeURIComponent(studiensemester_kurzbz),
|
||||
params
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -73,4 +73,17 @@ export default {
|
||||
params
|
||||
};
|
||||
},
|
||||
getDocumentDropdown(params){
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/dokumente/getDocumentDropDown/' + params.prestudent_id + '/' + params.studiensemester_kurzbz + '/' + params.studiengang_kz,
|
||||
};
|
||||
},
|
||||
getDocumentDropdownMulti(studentUids, params){
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/dokumente/getDocumentDropDownMulti/' + params.studiensemester_kurzbz + '/' + params.studiengang_kz,
|
||||
params: {studentUids}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,27 @@
|
||||
*/
|
||||
|
||||
export default {
|
||||
add(uid, gruppe_kurzbz, studiensemester_kurzbz) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/gruppen/add/',
|
||||
params: {
|
||||
uid,
|
||||
gruppe_kurzbz,
|
||||
studiensemester_kurzbz
|
||||
}
|
||||
};
|
||||
},
|
||||
search(query, studiengang_kz) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/gruppen/search/',
|
||||
params: {
|
||||
query,
|
||||
studiengang_kz
|
||||
}
|
||||
};
|
||||
},
|
||||
getGruppen(id) {
|
||||
return {
|
||||
method: 'get',
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* 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 {
|
||||
hasOrgforms(studiengang_kz) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/lehrverband/hasOrgforms/' + studiengang_kz
|
||||
};
|
||||
},
|
||||
getTree(studiengang_kz) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/lehrverband/getTree/' + studiengang_kz
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 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 {
|
||||
getProjektarbeit(uid) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/getProjektarbeit',
|
||||
params: { uid }
|
||||
};
|
||||
},
|
||||
getTypenProjektarbeit() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/getTypenProjektarbeit'
|
||||
};
|
||||
},
|
||||
getFirmen(searchString) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/getFirmen',
|
||||
params: {searchString}
|
||||
};
|
||||
},
|
||||
getLehrveranstaltungen(student_uid, studiengang_kz, studiensemester_kurzbz, additional_lehrveranstaltung_id) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/getLehrveranstaltungen',
|
||||
params: { student_uid, studiengang_kz, studiensemester_kurzbz, additional_lehrveranstaltung_id }
|
||||
};
|
||||
},
|
||||
getNoten() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/getNoten'
|
||||
};
|
||||
},
|
||||
loadProjektarbeit(projektarbeit_id) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/loadProjektarbeit',
|
||||
params: { projektarbeit_id }
|
||||
};
|
||||
},
|
||||
addNewProjektarbeit(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/insertProjektarbeit',
|
||||
params
|
||||
};
|
||||
},
|
||||
updateProjektarbeit(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/updateProjektarbeit',
|
||||
params
|
||||
};
|
||||
},
|
||||
deleteProjektarbeit(projektarbeit_id) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/projektarbeit/deleteProjektarbeit',
|
||||
params: { projektarbeit_id }
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* 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 {
|
||||
getProjektbetreuer(projektarbeit_id ) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/getProjektbetreuer',
|
||||
params: { projektarbeit_id }
|
||||
};
|
||||
},
|
||||
getBetreuerarten() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/getBetreuerarten'
|
||||
};
|
||||
},
|
||||
getDefaultStundensaetze(person_id, studiensemester_kurzbz) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/getDefaultStundensaetze',
|
||||
params: { person_id, studiensemester_kurzbz }
|
||||
};
|
||||
},
|
||||
getNoten() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/getNoten'
|
||||
};
|
||||
},
|
||||
saveProjektbetreuer(projektarbeit_id, projektbetreuer) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/saveProjektbetreuer',
|
||||
params: { projektarbeit_id, projektbetreuer }
|
||||
};
|
||||
},
|
||||
deleteProjektbetreuer(projektarbeit_id, person_id, betreuerart_kurzbz) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/deleteProjektbetreuer',
|
||||
params: { projektarbeit_id, person_id, betreuerart_kurzbz }
|
||||
};
|
||||
},
|
||||
getProjektbetreuerBySearchQuery(searchString) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/getProjektbetreuerBySearchQuery',
|
||||
params: { searchString }
|
||||
};
|
||||
},
|
||||
getPerson(person_id) {
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/getPerson',
|
||||
params: { person_id }
|
||||
};
|
||||
},
|
||||
validateProjektbetreuer(projektbetreuer) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/projektbetreuer/validateProjektbetreuer',
|
||||
params: { projektbetreuer }
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -58,5 +58,12 @@ export default {
|
||||
url: 'api/frontend/v1/stv/student/check',
|
||||
params
|
||||
};
|
||||
},
|
||||
add(params) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/student/add',
|
||||
params
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
export default {
|
||||
|
||||
getVertrag(vertrag_id)
|
||||
{
|
||||
return {
|
||||
method: 'get',
|
||||
url: 'api/frontend/v1/stv/vertrag/getVertrag',
|
||||
params: { vertrag_id },
|
||||
};
|
||||
},
|
||||
|
||||
cancelVertrag(data)
|
||||
{
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/stv/vertrag/cancelVertrag/',
|
||||
params: data
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -20,8 +20,8 @@ export default {
|
||||
getUid(params){
|
||||
return this.$fhcApi.get('api/frontend/v1/messages/messages/getUid/'+ params.id + '/' + params.type_id);
|
||||
},
|
||||
getVorlagentext(vorlage_kurzbz){
|
||||
return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz);
|
||||
getDataVorlage(vorlage_kurzbz){
|
||||
return this.$fhcApi.get('api/frontend/v1/messages/messages/getDataVorlage/' + vorlage_kurzbz);
|
||||
},
|
||||
getNameOfDefaultRecipient(params){
|
||||
return this.$fhcApi.get('api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id);
|
||||
|
||||
@@ -19,6 +19,7 @@ import Studium from "../../components/Cis/Studium/Studium.js";
|
||||
|
||||
import ApiRenderers from '../../api/factory/renderers.js';
|
||||
import ApiRouteInfo from '../../api/factory/routeinfo.js';
|
||||
import {capitalize} from "../../helpers/StringHelpers.js";
|
||||
|
||||
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
|
||||
|
||||
@@ -320,7 +321,7 @@ const app = Vue.createApp({
|
||||
|
||||
// kind of a bandaid for bad css on some pages to avoid horizontal scroll
|
||||
setScrollbarWidth();
|
||||
|
||||
app.config.globalProperties.$capitalize = capitalize;
|
||||
app.use(router);
|
||||
app.use(primevue.config.default, {
|
||||
zIndex: {
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (C) 2025 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import ApiNavigation from '../api/factory/navigation.js';
|
||||
|
||||
export default {
|
||||
name: 'AppMenu',
|
||||
props: {
|
||||
appIdentifier: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
navigationPage: {
|
||||
type: String,
|
||||
default: 'apps'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
navigationPage() {
|
||||
this.getItems();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getItems() {
|
||||
this.$api
|
||||
.call(ApiNavigation.getMenu(this.navigationPage))
|
||||
.then(result => {
|
||||
this.items = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getItems();
|
||||
},
|
||||
template: /* html */`
|
||||
<ul class="fhc-app-menu">
|
||||
<li v-for="(menu, key) in items" :key="key">
|
||||
<a
|
||||
:href="menu.link"
|
||||
@click="menu.onClickCall"
|
||||
:class="{ active: key === appIdentifier }"
|
||||
>
|
||||
<i v-if="menu.icon" class="fa fa-fw" :class="'fa-'+ menu.icon" />
|
||||
{{ menu.description }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>`
|
||||
};
|
||||
@@ -96,8 +96,11 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onDragstart(evt) {
|
||||
DragAndDrop.setTransferData(evt.detail.originalEvent, evt.detail.item.orig);
|
||||
this.draggedInternalEvent = evt.detail.item;
|
||||
const data = DragAndDrop.convertToTransferData(evt.detail.item.orig);
|
||||
if (DragAndDrop.isValidDragObject(data)) {
|
||||
DragAndDrop.setTransferData(evt.detail.originalEvent, data);
|
||||
this.draggedInternalEvent = evt.detail.item;
|
||||
}
|
||||
},
|
||||
onDragend() {
|
||||
this.draggedInternalEvent = null;
|
||||
|
||||
@@ -100,6 +100,11 @@ export default {
|
||||
link_element.href = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/CisVue/Cms/getRoomInformation/" + room_name;
|
||||
link_element.appendChild(title.cloneNode(true));
|
||||
title.replaceWith(link_element);
|
||||
|
||||
let lvplanlinks = document.querySelectorAll('.menubox a[href*="stpl_week.php"]');
|
||||
for(let lvplanlink of lvplanlinks) {
|
||||
lvplanlink.href = link_element.href;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -121,7 +121,8 @@ export default {
|
||||
class="d-flex flex-column align-items-center h-100 position-relative d-inline-block"
|
||||
>
|
||||
<img
|
||||
class="d-block h-100 rounded"
|
||||
class="d-block rounded"
|
||||
style="height: 84px;"
|
||||
alt="Profilbild"
|
||||
:src="getFotoSrc(person.foto)"
|
||||
/>
|
||||
@@ -175,7 +176,8 @@ export default {
|
||||
<div class="col-md-2 d-flex justify-content-start align-items-center w-30 pb-3 gap-3 position-relative"
|
||||
style="max-height: 8rem; max-width: 6rem; overflow: hidden;">
|
||||
<img
|
||||
class="d-block h-100 rounded"
|
||||
class="d-block rounded"
|
||||
style="height: 84px;"
|
||||
alt="Profilbild"
|
||||
:src="'data:image/jpeg;base64,' + headerDataMa.foto"
|
||||
/>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import CoreSearchbar from "../searchbar/searchbar.js";
|
||||
import VerticalSplit from "../verticalsplit/verticalsplit.js";
|
||||
import AppMenu from "../AppMenu.js";
|
||||
import StvVerband from "../Stv/Studentenverwaltung/Verband.js";
|
||||
import StvStudiensemester from "../Stv/Studentenverwaltung/Studiensemester.js";
|
||||
import LvTable from "./Setup/Table.js";
|
||||
@@ -17,6 +18,7 @@ export default {
|
||||
components: {
|
||||
CoreSearchbar,
|
||||
VerticalSplit,
|
||||
AppMenu,
|
||||
StvVerband,
|
||||
StvStudiensemester,
|
||||
LvTable,
|
||||
@@ -233,14 +235,47 @@ export default {
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
|
||||
template: `
|
||||
template: /* html */`
|
||||
<div class="stv">
|
||||
<header class="navbar navbar-expand-lg navbar-dark bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-md-4 col-lg-3 col-xl-2 me-0 px-3">LV Verwaltung</a>
|
||||
<div class="col-md-4 col-lg-3 col-xl-2 d-flex align-items-center">
|
||||
<button
|
||||
class="btn btn-outline-light border-0 m-1 collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#appMenu"
|
||||
aria-controls="appMenu"
|
||||
aria-expanded="false"
|
||||
:aria-label="$p.t('ui/toggle_nav')"
|
||||
>
|
||||
<span class="svg-icon svg-icon-apps"></span>
|
||||
</button>
|
||||
<a class="navbar-brand me-0">LV Verwaltung</a>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-outline-light border-0 d-md-none m-1 collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#sidebarMenu"
|
||||
aria-controls="sidebarMenu"
|
||||
aria-expanded="false"
|
||||
:aria-label="$p.t('ui/toggle_nav')"
|
||||
>
|
||||
<span class="fa-solid fa-table-list"></span>
|
||||
</button>
|
||||
<core-searchbar :searchoptions="searchbaroptions" :searchfunction=searchfunction class="searchbar w-100"></core-searchbar>
|
||||
</header>
|
||||
<div class="container-fluid overflow-hidden">
|
||||
<div class="row h-100">
|
||||
<aside id="appMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
|
||||
<div class="offcanvas-header">
|
||||
LV Verwaltung
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<app-menu app-identifier="lvv" />
|
||||
</div>
|
||||
</aside>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
|
||||
<div class="offcanvas-header justify-content-end px-1 d-md-none">
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
|
||||
@@ -136,17 +136,13 @@ export default {
|
||||
}
|
||||
);
|
||||
},
|
||||
getVorlagentext(vorlage_kurzbz){
|
||||
getDataVorlage(vorlage_kurzbz){
|
||||
return this.$api
|
||||
.call(this.endpoint.getVorlagentext(vorlage_kurzbz))
|
||||
.call(this.endpoint.getDataVorlage(vorlage_kurzbz))
|
||||
.then(response => {
|
||||
this.formData.body = response.data;
|
||||
}).catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
//this.resetForm();
|
||||
//closeModal
|
||||
//closewindwo
|
||||
});
|
||||
this.formData.body = response.data.text;
|
||||
this.formData.subject = response.data.subject;
|
||||
}).catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
getPreviewText(){
|
||||
const data = new FormData();
|
||||
@@ -197,8 +193,7 @@ export default {
|
||||
},
|
||||
handleSelectedVorlage(vorlage_kurzbz) {
|
||||
if (typeof vorlage_kurzbz === "string") {
|
||||
this.getVorlagentext(vorlage_kurzbz);
|
||||
this.formData.subject = vorlage_kurzbz;
|
||||
this.getDataVorlage(vorlage_kurzbz);
|
||||
}
|
||||
},
|
||||
showPreview(){
|
||||
@@ -240,7 +235,7 @@ export default {
|
||||
handler(newVal){
|
||||
if (newVal && newVal != null) {
|
||||
this.formData.subject = newVal;
|
||||
return this.getVorlagentext(newVal);
|
||||
return this.getDataVorlage(newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -136,15 +136,13 @@ export default {
|
||||
}
|
||||
);
|
||||
},
|
||||
getVorlagentext(vorlage_kurzbz){
|
||||
getDataVorlage(vorlage_kurzbz){
|
||||
return this.$api
|
||||
.call(this.endpoint.getVorlagentext(vorlage_kurzbz))
|
||||
.call(this.endpoint.getDataVorlage(vorlage_kurzbz))
|
||||
.then(response => {
|
||||
this.formData.body = response.data;
|
||||
}).catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
//this.resetForm();
|
||||
});
|
||||
this.formData.body = response.data.text;
|
||||
this.formData.subject = response.data.subject;
|
||||
}).catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
getPreviewText(id, typeId){
|
||||
const data = new FormData();
|
||||
@@ -164,20 +162,11 @@ export default {
|
||||
insertVariable(selectedItem){
|
||||
if (this.editor) {
|
||||
this.editor.insertContent(selectedItem.value + " ");
|
||||
//TODO(Manu) check: Laden von Variblen geht nicht wenn kein Zeichen danach kommt
|
||||
// nicht mal mit Punkt adden gehts ohne eintrag nach vars
|
||||
//this.editor.focus();
|
||||
// this.editor.setDirty(true);
|
||||
|
||||
this.editor.setDirty(true);//seting dirty true if changes appear
|
||||
// console.log(tinyMCE.activeEditor.isDirty());//dirty output = true
|
||||
|
||||
|
||||
//this.editor.undoManager.add();
|
||||
|
||||
//this.editor.insertContent(selectedItem.value + "\u00A0");
|
||||
//this.editor.insertContent(`<span>${selectedItem.value} </span>`);
|
||||
//this.editor.selection.setCursorLocation(this.editor.getBody(), 1);
|
||||
this.editor.fire('input');
|
||||
this.editor.fire('change');
|
||||
this.editor.setDirty(true);
|
||||
this.editor.save();
|
||||
|
||||
} else {
|
||||
console.error("Editor instance is not available.");
|
||||
@@ -202,8 +191,7 @@ export default {
|
||||
},
|
||||
handleSelectedVorlage(vorlage_kurzbz) {
|
||||
if (typeof vorlage_kurzbz === "string") {
|
||||
this.getVorlagentext(vorlage_kurzbz);
|
||||
this.formData.subject = vorlage_kurzbz;
|
||||
this.getDataVorlage(vorlage_kurzbz);
|
||||
}
|
||||
},
|
||||
hideTemplate(){
|
||||
@@ -248,7 +236,7 @@ export default {
|
||||
|
||||
if (newVal && newVal != null) {
|
||||
this.formData.subject = newVal;
|
||||
return this.getVorlagentext(newVal);
|
||||
return this.getDataVorlage(newVal);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -274,6 +274,11 @@ export default {
|
||||
this.$refs.table.reloadTable();
|
||||
},
|
||||
buildTreemap(messages) {
|
||||
if (!messages || !messages.data || messages.data.length === 0)
|
||||
{
|
||||
return {data: [], last_page: 0};
|
||||
}
|
||||
|
||||
const last_page = messages.meta.count;
|
||||
messages = messages.data;
|
||||
const messageMap = new Map();
|
||||
|
||||
@@ -37,16 +37,16 @@ export default {
|
||||
});
|
||||
},
|
||||
loadData(evt) {
|
||||
if( evt.query.length < 2 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (evt.query.length < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.abortController)
|
||||
{
|
||||
this.abortController.abort();
|
||||
}
|
||||
|
||||
if (this.abortController instanceof AbortController
|
||||
&& this.abortController.signal.aborted === false)
|
||||
{
|
||||
this.abortController.abort();
|
||||
}
|
||||
this.abortController = new AbortController();
|
||||
|
||||
this.$api
|
||||
@@ -56,16 +56,8 @@ export default {
|
||||
})
|
||||
.then(result => {
|
||||
this.data = result.data;
|
||||
this.abortController = null;
|
||||
})
|
||||
.catch(error => {
|
||||
if (this.abortController instanceof AbortController
|
||||
&& this.abortController.signal.aborted === false)
|
||||
{
|
||||
this.abortController.abort();
|
||||
}
|
||||
this.$fhcAlert.handleSystemError(error);
|
||||
});
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import CoreSearchbar from "../searchbar/searchbar.js";
|
||||
import VerticalSplit from "../verticalsplit/verticalsplit.js";
|
||||
import AppMenu from "../AppMenu.js";
|
||||
import StvVerband from "./Studentenverwaltung/Verband.js";
|
||||
import StvList from "./Studentenverwaltung/List.js";
|
||||
import StvDetails from "./Studentenverwaltung/Details.js";
|
||||
@@ -32,6 +33,7 @@ export default {
|
||||
components: {
|
||||
CoreSearchbar,
|
||||
VerticalSplit,
|
||||
AppMenu,
|
||||
StvVerband,
|
||||
StvList,
|
||||
StvDetails,
|
||||
@@ -345,11 +347,34 @@ export default {
|
||||
//FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto = 'ma0068@technikum-wien.at';this.$fhcAlert.handleSystemError(1);
|
||||
this.handlePersonUrl();
|
||||
},
|
||||
template: `
|
||||
template: /* html */`
|
||||
<div class="stv">
|
||||
<header class="navbar navbar-expand-lg navbar-dark bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-md-4 col-lg-3 col-xl-2 me-0 px-3" :href="stvRoot">StudVw: {{studiensemesterKurzbz}} {{studiengangKuerzel}}</a>
|
||||
<button class="navbar-toggler d-md-none m-1 collapsed" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" :aria-label="$p.t('ui/toggle_nav')"><span class="navbar-toggler-icon"></span></button>
|
||||
<div class="col-md-4 col-lg-3 col-xl-2 d-flex align-items-center">
|
||||
<button
|
||||
class="btn btn-outline-light border-0 m-1 collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#appMenu"
|
||||
aria-controls="appMenu"
|
||||
aria-expanded="false"
|
||||
:aria-label="$p.t('ui/toggle_nav')"
|
||||
>
|
||||
<span class="svg-icon svg-icon-apps"></span>
|
||||
</button>
|
||||
<a class="navbar-brand me-0" :href="stvRoot">StudVw: {{studiensemesterKurzbz}} {{studiengangKuerzel}}</a>
|
||||
</div>
|
||||
<button
|
||||
class="btn btn-outline-light border-0 d-md-none m-1 collapsed"
|
||||
type="button"
|
||||
data-bs-toggle="offcanvas"
|
||||
data-bs-target="#sidebarMenu"
|
||||
aria-controls="sidebarMenu"
|
||||
aria-expanded="false"
|
||||
:aria-label="$p.t('ui/toggle_nav')"
|
||||
>
|
||||
<span class="fa-solid fa-table-list"></span>
|
||||
</button>
|
||||
<core-searchbar
|
||||
:searchoptions="searchbaroptions"
|
||||
:searchfunction="searchfunction"
|
||||
@@ -358,6 +383,15 @@ export default {
|
||||
</header>
|
||||
<div class="container-fluid overflow-hidden">
|
||||
<div class="row h-100">
|
||||
<aside id="appMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
|
||||
<div class="offcanvas-header">
|
||||
StudVw: {{studiensemesterKurzbz}} {{studiengangKuerzel}}
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<app-menu app-identifier="stv" />
|
||||
</div>
|
||||
</aside>
|
||||
<nav id="sidebarMenu" class="bg-light offcanvas offcanvas-start col-md p-md-0 h-100">
|
||||
<div class="offcanvas-header justify-content-end px-1 d-md-none">
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" :aria-label="$p.t('ui/schliessen')"></button>
|
||||
|
||||
@@ -31,10 +31,14 @@ export default {
|
||||
if (this.students.length == 1) {
|
||||
const student = this.students[0];
|
||||
if (student.uid)
|
||||
return Object.fromEntries(Object.entries(this.configStudent).filter(([key, value]) => !value.showOnlyWithoutUid));
|
||||
return Object.fromEntries(Object.entries(this.configStudent).filter(([key, value]) => !value.showOnlyWithUid));
|
||||
return Object.fromEntries(Object.entries(this.configStudent).filter(([ , value ]) => !value.showOnlyWithoutUid));
|
||||
return Object.fromEntries(Object.entries(this.configStudent).filter(([ , value ]) => !value.showOnlyWithUid));
|
||||
} else if (this.students.every(student => student.uid)) {
|
||||
return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithoutUid));
|
||||
} else if (this.students.every(student => !student.uid)) {
|
||||
return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid));
|
||||
}
|
||||
return this.configStudents;
|
||||
return Object.fromEntries(Object.entries(this.configStudents).filter(([ , value ]) => !value.showOnlyWithUid && !value.showOnlyWithUid));
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -58,11 +62,11 @@ export default {
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details h-100 pb-3 d-flex flex-column">
|
||||
<div class="stv-details h-100 d-flex flex-column">
|
||||
<div v-if="!students?.length" class="justify-content-center d-flex h-100 align-items-center">
|
||||
{{$p.t('ui', 'chooseStudent')}}
|
||||
</div>
|
||||
<div v-else-if="configStudent && configStudents" class="d-flex flex-column h-100 pb-3">
|
||||
<div v-else-if="configStudent && configStudents" class="d-flex flex-column h-100">
|
||||
<fhc-header
|
||||
:headerData="students"
|
||||
typeHeader="student"
|
||||
|
||||
+99
-54
@@ -7,7 +7,6 @@ import AbschlusspruefungDropdown from "./AbschlusspruefungDropdown.js";
|
||||
|
||||
import ApiStudiengang from '../../../../../api/factory/studiengang.js';
|
||||
import ApiStvAbschlusspruefung from '../../../../../api/factory/stv/abschlusspruefung.js';
|
||||
import ApiStvAddress from "../../../../../api/factory/stv/kontakt/address.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -260,14 +259,16 @@ export default {
|
||||
arrAkadGrad: [],
|
||||
arrNoten: [],
|
||||
selectedVorsitz: null,
|
||||
listeFilteredMitarbeiter: [],
|
||||
listeAllMitarbeiter: [],
|
||||
listeAllPersons: [],
|
||||
filteredMitarbeiter: [],
|
||||
filteredPersons: [],
|
||||
selectedPruefer1: null,
|
||||
selectedPruefer2: null,
|
||||
selectedPruefer3: null,
|
||||
listeFilteredPersons: [],
|
||||
stgInfo: { typ: '', oe_kurzbz: '' }
|
||||
stgInfo: { typ: '', oe_kurzbz: '' },
|
||||
abortController: {
|
||||
mitarbeiter: null,
|
||||
persons: null
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -307,23 +308,39 @@ export default {
|
||||
actionEditAbschlusspruefung(abschlusspruefung_id) {
|
||||
this.resetForm();
|
||||
this.statusNew = false;
|
||||
this.loadAbschlusspruefung(abschlusspruefung_id).then(() => {
|
||||
this.loadAbschlusspruefung(abschlusspruefung_id).then((result) => {
|
||||
//set selectedData to enable viewing label in primevue autocomplete fields
|
||||
this.selectedVorsitz = this.listeAllMitarbeiter.find(
|
||||
item => item.mitarbeiter_uid === this.formData.vorsitz
|
||||
);
|
||||
this.selectedPruefer1 = this.listeAllPersons.find(
|
||||
item => item.person_id === this.formData.pruefer1
|
||||
);
|
||||
this.selectedPruefer2= this.listeAllPersons.find(
|
||||
item => item.person_id === this.formData.pruefer2
|
||||
);
|
||||
this.selectedPruefer3= this.listeAllPersons.find(
|
||||
item => item.person_id === this.formData.pruefer3
|
||||
);
|
||||
const data = result.data;
|
||||
this.selectedVorsitz = {
|
||||
label: this.getPersonLabel(data.pv_titelpre, data.pv_nachname, data.pv_vorname, data.pv_titelpost, data.pv_uid),
|
||||
person_id: data.pv_person_id,
|
||||
mitarbeiter_uid: data.pv_uid
|
||||
};
|
||||
if (data.p1_person_id) {
|
||||
this.selectedPruefer1 = {
|
||||
label: this.getPersonLabel(data.p1_titelpre, data.p1_nachname, data.p1_vorname, data.p1_titelpost),
|
||||
person_id: data.p1_person_id
|
||||
};
|
||||
}
|
||||
if (data.p2_person_id) {
|
||||
this.selectedPruefer2 = {
|
||||
label: this.getPersonLabel(data.p2_titelpre, data.p2_nachname, data.p2_vorname, data.p2_titelpost),
|
||||
person_id: data.p2_person_id
|
||||
}
|
||||
};
|
||||
if (data.p3_person_id) {
|
||||
this.selectedPruefer3= {
|
||||
label: this.getPersonLabel(data.p3_titelpre, data.p3_nachname, data.p3_vorname, data.p3_titelpost),
|
||||
person_id: data.p3_person_id
|
||||
};
|
||||
}
|
||||
});
|
||||
this.$refs.finalexamModal.show();
|
||||
},
|
||||
getPersonLabel(titelpre, nachname, vorname, titelpost, uid) {
|
||||
return nachname + ' ' + vorname + (titelpre ? ' ' + titelpre : '') + (titelpost ? ' ' + titelpost : '') + (uid ? ' (' + uid + ')' : '');
|
||||
|
||||
},
|
||||
actionDeleteAbschlusspruefung(abschlusspruefung_id) {
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
@@ -439,22 +456,61 @@ export default {
|
||||
printDocument(link) {
|
||||
window.open(link, '_blank');
|
||||
},
|
||||
filterMitarbeiter(event){
|
||||
const query = event?.query?.toLowerCase()?.trim() || "";
|
||||
searchMitarbeiter(event) {
|
||||
if (this.abortController.mitarbeiter) {
|
||||
this.abortController.mitarbeiter.abort();
|
||||
}
|
||||
|
||||
this.listeFilteredMitarbeiter = this.listeAllMitarbeiter.filter(item => {
|
||||
const label = (item.label || "").toLowerCase();
|
||||
return label.includes(query);
|
||||
});
|
||||
this.abortController.mitarbeiter = new AbortController();
|
||||
|
||||
return this.$api
|
||||
.call(ApiStvAbschlusspruefung.getMitarbeiter(event.query))
|
||||
.then(result => {
|
||||
this.filteredMitarbeiter = [];
|
||||
for (let mitarbeiter of result.data.retval) {
|
||||
this.filteredMitarbeiter.push(
|
||||
{
|
||||
label: this.getPersonLabel(
|
||||
mitarbeiter.titelpre,
|
||||
mitarbeiter.nachname,
|
||||
mitarbeiter.vorname,
|
||||
mitarbeiter.titelpost,
|
||||
mitarbeiter.mitarbeiter_uid
|
||||
),
|
||||
person_id: mitarbeiter.person_id,
|
||||
mitarbeiter_uid: mitarbeiter.mitarbeiter_uid
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
filterPersons(event){
|
||||
const query = event?.query?.toLowerCase()?.trim() || "";
|
||||
searchPerson(event) {
|
||||
if (this.abortController.persons) {
|
||||
this.abortController.persons.abort();
|
||||
}
|
||||
|
||||
this.listeFilteredPersons = this.listeAllPersons.filter(item => {
|
||||
const label = (item.label || "").toLowerCase();
|
||||
return label.includes(query);
|
||||
});
|
||||
}
|
||||
this.abortController.persons = new AbortController();
|
||||
|
||||
return this.$api
|
||||
.call(ApiStvAbschlusspruefung.getPruefer(event.query))
|
||||
.then(result => {
|
||||
this.filteredPersons = [];
|
||||
for (let person of result.data.retval) {
|
||||
this.filteredPersons.push(
|
||||
{
|
||||
label: this.getPersonLabel(
|
||||
person.titelpre,
|
||||
person.nachname,
|
||||
person.vorname,
|
||||
person.titelpost,
|
||||
person.person_uid
|
||||
),
|
||||
person_id: person.person_id
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
@@ -492,20 +548,6 @@ export default {
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvAbschlusspruefung.getAllMitarbeiter())
|
||||
.then(result => {
|
||||
this.listeAllMitarbeiter = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvAbschlusspruefung.getAllPersons())
|
||||
.then(result => {
|
||||
this.listeAllPersons = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
if (!this.student.length) {
|
||||
this.$api
|
||||
.call(ApiStudiengang.getStudiengangByKz(this.student.studiengang_kz))
|
||||
@@ -623,8 +665,8 @@ export default {
|
||||
optionValue="mitarbeiter_uid"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="listeFilteredMitarbeiter"
|
||||
@complete="filterMitarbeiter"
|
||||
:suggestions="filteredMitarbeiter"
|
||||
@complete="searchMitarbeiter"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
@@ -636,9 +678,10 @@ export default {
|
||||
v-model="selectedPruefer1"
|
||||
optionLabel="label"
|
||||
optionValue="person_id"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="listeFilteredPersons"
|
||||
@complete="filterPersons"
|
||||
:suggestions="filteredPersons"
|
||||
@complete="searchPerson"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
@@ -669,9 +712,10 @@ export default {
|
||||
v-model="selectedPruefer2"
|
||||
optionLabel="label"
|
||||
optionValue="person_id"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="listeFilteredPersons"
|
||||
@complete="filterPersons"
|
||||
:suggestions="filteredPersons"
|
||||
@complete="searchPerson"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
@@ -701,9 +745,10 @@ export default {
|
||||
v-model="selectedPruefer3"
|
||||
optionLabel="label"
|
||||
optionValue="person_id"
|
||||
dropdown
|
||||
forceSelection
|
||||
:suggestions="listeFilteredPersons"
|
||||
@complete="filterPersons"
|
||||
:suggestions="filteredPersons"
|
||||
@complete="searchPerson"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
|
||||
@@ -3,18 +3,29 @@ import FormInput from "../../../Form/Input.js";
|
||||
import AkteEdit from "./Archiv/Edit.js";
|
||||
|
||||
import ApiStvArchiv from '../../../../api/factory/stv/archiv.js';
|
||||
import ApiStvDocuments from '../../../../api/factory/stv/documents.js';
|
||||
import DocumentDropdown from "../Details/Archiv/DocumentDropdown.js";
|
||||
|
||||
|
||||
export default {
|
||||
name: 'Archiv',
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
FormInput,
|
||||
AkteEdit
|
||||
AkteEdit,
|
||||
DocumentDropdown
|
||||
},
|
||||
inject: {
|
||||
currentSemester: {
|
||||
from: 'currentSemester'
|
||||
}
|
||||
},
|
||||
/* isBerechtigtDocAndOdt: {
|
||||
from: 'hasPermissionOutputformat',
|
||||
default: false
|
||||
},*/
|
||||
cisRoot: {
|
||||
from: 'cisRoot'
|
||||
},
|
||||
},
|
||||
props: {
|
||||
modelValue: Object,
|
||||
@@ -64,7 +75,8 @@ export default {
|
||||
'abschlussdokument_lehrgaenge.xml.php': [
|
||||
'AbschlussdokumentLehrgaenge'
|
||||
]
|
||||
}
|
||||
},
|
||||
documentDropdownObject: {}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -184,6 +196,38 @@ export default {
|
||||
];
|
||||
|
||||
return events;
|
||||
},
|
||||
studentUids() {
|
||||
if (this.modelValue.uid)
|
||||
{
|
||||
return [this.modelValue.uid];
|
||||
}
|
||||
return this.modelValue.map(e => e.uid);
|
||||
},
|
||||
studentKzs(){
|
||||
if (this.modelValue.uid)
|
||||
{
|
||||
return [this.modelValue.studiengang_kz];
|
||||
}
|
||||
return this.modelValue.map(e => e.studiengang_kz);
|
||||
},
|
||||
stg_kz(){
|
||||
return this.studentKzs[0];
|
||||
},
|
||||
showAllFormats() {
|
||||
if( this.isBerechtigtDocAndOdt === false
|
||||
|| !Array.isArray(this.isBerechtigtDocAndOdt) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
let retval = this.isBerechtigtDocAndOdt.includes(this.stgInfo.oe_kurzbz);
|
||||
return retval;
|
||||
},
|
||||
showDropDownMulti(){
|
||||
if (this.modelValue.length) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -252,14 +296,43 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiStvArchiv.getArchivVorlagen())
|
||||
.then(result => {
|
||||
this.vorlagenArchiv = result.data;
|
||||
this.selectedVorlage = result.data.filter(o => o.vorlage_kurzbz == 'Zeugnis')[0];
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
if (this.modelValue.length) {
|
||||
const params = {
|
||||
studiensemester_kurzbz: this.currentSemester,
|
||||
studiengang_kz: this.stg_kz
|
||||
};
|
||||
this.$api
|
||||
.call(ApiStvArchiv.getArchivVorlagen())
|
||||
.then(result => {this.vorlagenArchiv = result.data; this.selectedVorlage = result.data.filter(o => o.vorlage_kurzbz == 'Zeugnis')[0];})
|
||||
.call(ApiStvDocuments.getDocumentDropdownMulti(this.studentUids, params))
|
||||
.then(result => {
|
||||
this.documentDropdownObject = result;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
} else {
|
||||
const params = {
|
||||
prestudent_id: this.modelValue.prestudent_id,
|
||||
studiensemester_kurzbz: this.currentSemester,
|
||||
studiengang_kz: this.modelValue.studiengang_kz
|
||||
};
|
||||
this.$api
|
||||
.call(ApiStvDocuments.getDocumentDropdown(params))
|
||||
.then(result => {
|
||||
this.documentDropdownObject = result;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-archiv h-100 d-flex flex-column">
|
||||
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
table-only
|
||||
@@ -270,6 +343,7 @@ export default {
|
||||
:reload-btn-infotext="this.$p.t('table', 'reload')"
|
||||
>
|
||||
<template #actions>
|
||||
|
||||
<div class="input-group w-auto">
|
||||
<select class="form-select" v-model="selectedVorlage">
|
||||
<option v-for="vorlage in vorlagenArchiv" :key="vorlage.vorlage_kurzbz" :value="vorlage">
|
||||
@@ -285,6 +359,17 @@ export default {
|
||||
{{ $p.t('stv/archiv_dokument_archivieren') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<document-dropdown
|
||||
v-if="documentDropdownObject.data"
|
||||
:documents="documentDropdownObject.data"
|
||||
:showAllFormats='true'
|
||||
:studentUids="studentUids"
|
||||
:showDropDownMulti="showDropDownMulti"
|
||||
:cisRoot="cisRoot"
|
||||
:stgKz="stg_kz"
|
||||
></document-dropdown>
|
||||
|
||||
</template>
|
||||
</core-filter-cmpt>
|
||||
<akte-edit ref="edit" :config="config" @saved="updateData"></akte-edit>
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
export default {
|
||||
name: "DocumentDropdown",
|
||||
props: {
|
||||
documents: {
|
||||
type: [Object, Array],
|
||||
required: true,
|
||||
},
|
||||
studentUids: {
|
||||
type: [Array, String],
|
||||
required: true,
|
||||
default: () => []
|
||||
},
|
||||
showDropDownMulti: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
cisRoot: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
stgKz: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
showAllFormats: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
printDokument(url, scope){
|
||||
//TODO Manu(check if logic not in content (Zutrittkarte also in content folder))
|
||||
let linkToPdf = this.cisRoot + 'content/' + url;
|
||||
window.open(linkToPdf, '_blank');
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="stv-document-dropdown btn-group">
|
||||
<button
|
||||
ref="toolbarButton"
|
||||
type="button"
|
||||
class="btn btn-secondary dropdown-toggle px-5 ms-5"
|
||||
data-bs-toggle="dropdown"
|
||||
data-bs-auto-close="outside"
|
||||
aria-expanded="false"
|
||||
>
|
||||
{{this.$p.t('dokumente','dokument_erstellen')}}
|
||||
</button>
|
||||
|
||||
<ul class="dropdown-menu dropdown-menu-right">
|
||||
<template v-for="doc in documents" :key="doc.id">
|
||||
<li v-if="doc.type === 'documenturl'">
|
||||
<button class="dropdown-item" type="button" @click="printDokument(doc.url, doc.scope)">
|
||||
{{ doc.name }}
|
||||
</button>
|
||||
</li>
|
||||
|
||||
<li v-else-if="doc.type === 'submenu'" class="dropend">
|
||||
<a
|
||||
class="dropdown-item dropdown-toggle"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
{{ doc.name }}
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu">
|
||||
<template v-for="child in doc.data" :key="child.id">
|
||||
<li v-if="child.type === 'documenturl'">
|
||||
<button class="dropdown-item" type="button" @click="printDokument(child.url, child.scope)">
|
||||
{{ child.name }}
|
||||
</button>
|
||||
</li>
|
||||
<li v-else-if="child.type === 'submenu'" class="dropend">
|
||||
<a
|
||||
class="dropdown-item dropdown-toggle"
|
||||
href="#"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
{{ child.name }}
|
||||
</a>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
|
||||
</div>`
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
import GroupsLvb from './Groups/Lvb.js';
|
||||
import GroupsSpecial from './Groups/Special.js';
|
||||
import GroupsList from './Groups/List.js';
|
||||
|
||||
import ApiStvGroups from '../../../../api/factory/stv/group.js';
|
||||
import ApiStvDetails from '../../../../api/factory/stv/details.js';
|
||||
|
||||
export default {
|
||||
name: 'TabGroups',
|
||||
components: {
|
||||
GroupsLvb,
|
||||
GroupsSpecial,
|
||||
GroupsList
|
||||
},
|
||||
inject: {
|
||||
$reloadList: {
|
||||
from: '$reloadList',
|
||||
required: true
|
||||
},
|
||||
currentSemester: {
|
||||
form: 'currentSemester',
|
||||
required: true
|
||||
}
|
||||
},
|
||||
props: {
|
||||
modelValue: [Object, Array]
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasOrgforms: false,
|
||||
lvbList: [],
|
||||
specialGroups: [],
|
||||
selectedOrgform: false,
|
||||
selectedSemester: false,
|
||||
selectedVerband: false,
|
||||
selectedGruppe: false,
|
||||
multiFormHandler: (form, errors) => {
|
||||
function _split_errors(result, [uid, errors]) {
|
||||
const gruppe_kurzbz = [];
|
||||
const studiensemester_kurzbz = [];
|
||||
const others = {};
|
||||
errors.forEach(error => {
|
||||
_split_messages(error.messages, gruppe_kurzbz, studiensemester_kurzbz, others);
|
||||
});
|
||||
if (gruppe_kurzbz.length) {
|
||||
if (!result.formFeedback.gruppe_kurzbz)
|
||||
result.formFeedback.gruppe_kurzbz = [];
|
||||
result.formFeedback.gruppe_kurzbz.push(...gruppe_kurzbz);
|
||||
}
|
||||
if (studiensemester_kurzbz.length) {
|
||||
if (!result.formFeedback.studiensemester_kurzbz)
|
||||
result.formFeedback.studiensemester_kurzbz = [];
|
||||
result.formFeedback.studiensemester_kurzbz.push(...studiensemester_kurzbz);
|
||||
}
|
||||
if (Object.keys(others).length) {
|
||||
result.toast[uid] = [
|
||||
{ type: 'validation', messages: others }
|
||||
];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function _split_messages(messages, gruppe_kurzbz, studiensemester_kurzbz, others) {
|
||||
Object.entries(messages).forEach(([field, msg]) => {
|
||||
if (field == 'gruppe_kurzbz') {
|
||||
gruppe_kurzbz.push(msg);
|
||||
} else if (field == 'studiensemester_kurzbz') {
|
||||
studiensemester_kurzbz.push(msg);
|
||||
} else {
|
||||
if (!others[field])
|
||||
others[field] = [];
|
||||
others[field].push(msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
const { formFeedback, toast } = Object.entries(errors)
|
||||
.reduce(_split_errors, { formFeedback: {}, toast: {} });
|
||||
|
||||
if (formFeedback.gruppe_kurzbz)
|
||||
formFeedback.gruppe_kurzbz = formFeedback.gruppe_kurzbz
|
||||
.filter((v,k,a) => a.indexOf(v) == k);
|
||||
if (formFeedback.studiensemester_kurzbz)
|
||||
formFeedback.studiensemester_kurzbz = formFeedback.studiensemester_kurzbz
|
||||
.filter((v,k,a) => a.indexOf(v) == k);
|
||||
|
||||
form.clearValidation();
|
||||
if (Object.keys(formFeedback)) {
|
||||
form.setFeedback(false, formFeedback);
|
||||
}
|
||||
|
||||
if (Object.keys(toast).length) {
|
||||
console.log(toast);
|
||||
this.$api.getErrorHandler().handler.toast(toast);
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
allAreStudents() {
|
||||
if (Array.isArray(this.modelValue))
|
||||
return this.modelValue.every(ps => ps.uid);
|
||||
return this.modelValue.uid;
|
||||
},
|
||||
sharedStg() {
|
||||
if (Array.isArray(this.modelValue)) {
|
||||
const first = this.modelValue.find(Boolean);
|
||||
if (this.modelValue.every(ps => ps.studiengang_kz === first.studiengang_kz))
|
||||
return first.studiengang_kz;
|
||||
return undefined;
|
||||
}
|
||||
return this.modelValue.studiengang_kz;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showNewGroupModal() {
|
||||
this.$refs.newGroupModal.show()
|
||||
},
|
||||
changeLvb(params) {
|
||||
let data = { semester: params.semester };
|
||||
if (params.verband && params.verband != " ") {
|
||||
data.verband = params.verband;
|
||||
if (params.gruppe && params.gruppe != " ")
|
||||
data.gruppe = params.gruppe;
|
||||
}
|
||||
|
||||
let endpoint;
|
||||
|
||||
if (Array.isArray(this.modelValue)) {
|
||||
endpoint = this.modelValue.map(student => [
|
||||
student.uid + ' (' + student.vorname + ' ' + student.nachname + ')',
|
||||
ApiStvDetails.save(
|
||||
student.prestudent_id,
|
||||
this.currentSemester,
|
||||
data
|
||||
)
|
||||
]);
|
||||
} else {
|
||||
endpoint = ApiStvDetails.save(
|
||||
this.modelValue.prestudent_id,
|
||||
this.currentSemester,
|
||||
data
|
||||
);
|
||||
}
|
||||
this.$api
|
||||
.call(endpoint)
|
||||
.then(() => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
this.$reloadList();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
addSpecialGroup() {
|
||||
const gruppe_kurzbz = this.$refs.newGroupModal.value.gruppe_kurzbz || this.$refs.newGroupModal.value;
|
||||
|
||||
if (Array.isArray(this.modelValue)) {
|
||||
this.$refs.newGroupModal.$refs.form
|
||||
.call(
|
||||
this.modelValue.map(student => [
|
||||
student.uid + ' (' + student.vorname + ' ' + student.nachname + ')',
|
||||
ApiStvGroups.add(
|
||||
student.uid,
|
||||
gruppe_kurzbz,
|
||||
this.currentSemester
|
||||
)
|
||||
]),
|
||||
{
|
||||
errorHandling: {
|
||||
combine: { form: ['validation'] },
|
||||
handler: { form: this.multiFormHandler }
|
||||
}
|
||||
}
|
||||
)
|
||||
.then(result => {
|
||||
const successes = result.filter(res => res.status == 'fulfilled');
|
||||
if (result.length == successes.length) {
|
||||
this.$refs.newGroupModal.hide();
|
||||
}
|
||||
if (successes.length) {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('gruppenmanagement/groups_added', { n: successes.length }));
|
||||
this.$refs.list.reload();
|
||||
}
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
} else {
|
||||
this.$refs.newGroupModal.$refs.form
|
||||
.call(ApiStvGroups.add(this.modelValue.uid, gruppe_kurzbz, this.currentSemester))
|
||||
.then(() => {
|
||||
this.$refs.newGroupModal.hide();
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('gruppenmanagement/groups_added', { n: 1 }));
|
||||
this.$refs.list.reload();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
}
|
||||
},
|
||||
template: /* html */`
|
||||
<div class="stv-details-groups h-100 d-flex flex-column">
|
||||
<h3>{{ $p.t('gruppenmanagement/special_groups') }}</h3>
|
||||
<groups-special
|
||||
ref="newGroupModal"
|
||||
:default-stg="sharedStg"
|
||||
@submit.capture.prevent="addSpecialGroup"
|
||||
/>
|
||||
<groups-list
|
||||
ref="list"
|
||||
class="mb-3"
|
||||
:students="modelValue"
|
||||
@new="showNewGroupModal"
|
||||
/>
|
||||
|
||||
<h3>{{ $p.t('lehre/lehrverband') }}</h3>
|
||||
<groups-lvb
|
||||
:students="modelValue"
|
||||
@submit="changeLvb"
|
||||
/>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,171 @@
|
||||
import { CoreFilterCmpt } from "../../../../filter/Filter.js";
|
||||
|
||||
import ApiStvGroups from '../../../../../api/factory/stv/group.js';
|
||||
|
||||
export default {
|
||||
name: 'TabGroupsList',
|
||||
components: {
|
||||
CoreFilterCmpt
|
||||
},
|
||||
inject: [
|
||||
"currentSemester"
|
||||
],
|
||||
props: {
|
||||
students: Object
|
||||
},
|
||||
emits: [
|
||||
"new"
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
phrasenLoaded: false,
|
||||
optionsReady: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
tabulatorOptions() {
|
||||
let ajaxRequestFunc, ajaxResponse, initialFilter;
|
||||
if (Array.isArray(this.students)) {
|
||||
ajaxRequestFunc = () => {
|
||||
return this.$api.call(
|
||||
this.students.map(student => ApiStvGroups.getGruppen(student.uid))
|
||||
);
|
||||
};
|
||||
ajaxResponse = (url, params, response) => {
|
||||
return response.reduce((data, result) => [
|
||||
...data,
|
||||
...result.value.data
|
||||
], []);
|
||||
};
|
||||
initialFilter = [
|
||||
this.students.map(student => {
|
||||
return { field: "uid", type: "=", value: student.uid };
|
||||
}),
|
||||
[
|
||||
{ field: "studiensemester_kurzbz", type: "=", value: null },
|
||||
{ field: "studiensemester_kurzbz", type: "=", value: this.currentSemester }
|
||||
]
|
||||
];
|
||||
} else {
|
||||
ajaxRequestFunc = () => {
|
||||
return this.$api.call(
|
||||
ApiStvGroups.getGruppen(this.students.uid)
|
||||
);
|
||||
};
|
||||
ajaxResponse = (url, params, response) => {
|
||||
return response.data;
|
||||
};
|
||||
initialFilter = [
|
||||
{ field: "uid", type: "=", value: this.students.uid },
|
||||
[
|
||||
{ field: "studiensemester_kurzbz", type: "=", value: null },
|
||||
{ field: "studiensemester_kurzbz", type: "=", value: this.currentSemester }
|
||||
]
|
||||
];
|
||||
}
|
||||
return {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc,
|
||||
ajaxResponse,
|
||||
initialFilter,
|
||||
columns: [
|
||||
{ title: this.$p.t('gruppenmanagement/gruppe'), field: "gruppe_kurzbz" },
|
||||
{ title: this.$p.t('ui/bezeichnung'), field: "bezeichnung" },
|
||||
{ title: this.$p.t('lehre/studiensemester'), field: "studiensemester_kurzbz" },
|
||||
{
|
||||
title: this.$p.t('gruppenmanagement/automatisch_generiert'),
|
||||
field: "generiert",
|
||||
formatter: "tickCross",
|
||||
hozAlign: "center",
|
||||
formatterParams: {
|
||||
tickElement: '<i class="fa fa-check text-success"></i>',
|
||||
crossElement: '<i class="fa fa-xmark text-danger"></i>'
|
||||
}
|
||||
},
|
||||
{ title: this.$p.t('ui/student_uid'), field: "uid" },
|
||||
{
|
||||
title: this.$p.t('global/actions'),
|
||||
field: 'actions',
|
||||
minWidth: 150, // Ensures Action-buttons will be always fully displayed
|
||||
formatter: (cell, formatterParams, onRendered) => {
|
||||
const container = document.createElement('div');
|
||||
container.className = "d-flex gap-2";
|
||||
|
||||
const data = cell.getData();
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-xmark"></i>';
|
||||
button.title = this.$p.t('ui', 'loeschen');
|
||||
button.addEventListener('click', () =>
|
||||
this.actionDeleteGroup(data)
|
||||
);
|
||||
if (data.generiert)
|
||||
button.disabled = true;
|
||||
container.append(button);
|
||||
|
||||
return container;
|
||||
},
|
||||
frozen: true
|
||||
}
|
||||
],
|
||||
height: 'auto',
|
||||
index: 'group_id',
|
||||
persistenceID: 'stv-details-group-list'
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tabulatorOptions() {
|
||||
// Refresh Tabulator if options have changed
|
||||
this.optionsReady = false;
|
||||
this.$nextTick(() => this.optionsReady = true);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
actionDeleteGroup(data) {
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
.then(result => result
|
||||
? data
|
||||
: Promise.reject({handled: true}))
|
||||
.then(this.deleteGroup)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
deleteGroup(params) {
|
||||
return this.$api
|
||||
.call(ApiStvGroups.deleteGroup(params))
|
||||
.then(response => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
|
||||
this.reload();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
reload() {
|
||||
this.$refs.table.reloadTable();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$p
|
||||
.loadCategory(['global', 'lehre', 'ui', 'gruppenmanagement'])
|
||||
.then(() => {
|
||||
this.phrasenLoaded = true;
|
||||
});
|
||||
},
|
||||
template: /* html */`
|
||||
<div class="stv-details-groups-list">
|
||||
<core-filter-cmpt
|
||||
v-if="phrasenLoaded && optionsReady"
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
reload
|
||||
:reload-btn-infotext="$p.t('table/reload')"
|
||||
new-btn-show
|
||||
:new-btn-label="$p.t('lehre/gruppe')"
|
||||
@click:new="$emit('new')"
|
||||
>
|
||||
</core-filter-cmpt>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,241 @@
|
||||
import FhcForm from "../../../../Form/Form.js";
|
||||
|
||||
import ApiStvLvb from '../../../../../api/factory/stv/lehrverband.js';
|
||||
|
||||
export default {
|
||||
name: 'TabGroupsLvb',
|
||||
components: {
|
||||
FhcForm
|
||||
},
|
||||
props: {
|
||||
students: Object
|
||||
},
|
||||
emits: [
|
||||
"submit"
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
lvbList: [],
|
||||
selectedSemester: false,
|
||||
selectedVerband: false,
|
||||
selectedGruppe: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
allAreStudents() {
|
||||
if (Array.isArray(this.students))
|
||||
return this.students.every(ps => ps.uid);
|
||||
return this.students.uid;
|
||||
},
|
||||
studiengang_kz() {
|
||||
if (Array.isArray(this.students)) {
|
||||
const first = this.students.find(Boolean);
|
||||
if (this.students.every(ps => ps.studiengang_kz === first.studiengang_kz))
|
||||
return first.studiengang_kz;
|
||||
return false;
|
||||
}
|
||||
return this.students.studiengang_kz;
|
||||
},
|
||||
semester: {
|
||||
get() {
|
||||
if (this.selectedSemester !== false) {
|
||||
if (this.lvbList.some(item => item.semester == this.selectedSemester))
|
||||
return this.selectedSemester;
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(this.students)) {
|
||||
const first = this.students.find(Boolean);
|
||||
if (this.lvbList.every(item => item.semester != first.semester))
|
||||
return false;
|
||||
if (this.students.every(ps => ps.semester === first.semester))
|
||||
return first.semester;
|
||||
return false;
|
||||
}
|
||||
if (this.lvbList.some(item => item.semester == this.students.semester))
|
||||
return this.students.semester;
|
||||
return false;
|
||||
},
|
||||
set(value) {
|
||||
this.selectedSemester = value;
|
||||
}
|
||||
},
|
||||
verband: {
|
||||
get() {
|
||||
if (this.semester === false)
|
||||
return false;
|
||||
if (this.selectedVerband !== false) {
|
||||
if (this.lvbListVerband.some(item => item.verband == this.selectedVerband))
|
||||
return this.selectedVerband;
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(this.students)) {
|
||||
const first = this.students.find(Boolean);
|
||||
if (this.lvbListVerband.every(item => item.verband != first.verband))
|
||||
return false;
|
||||
if (this.students.every(ps => ps.verband === first.verband))
|
||||
return first.verband;
|
||||
return false;
|
||||
}
|
||||
if (this.lvbListVerband.some(item => item.verband == this.students.verband))
|
||||
return this.students.verband;
|
||||
return false;
|
||||
},
|
||||
set(value) {
|
||||
this.selectedVerband = value;
|
||||
}
|
||||
},
|
||||
gruppe: {
|
||||
get() {
|
||||
if (this.verband === false)
|
||||
return false;
|
||||
if (this.selectedGruppe !== false) {
|
||||
if (this.lvbListGruppe.some(item => item.gruppe == this.selectedGruppe))
|
||||
return this.selectedGruppe;
|
||||
return false;
|
||||
}
|
||||
if (Array.isArray(this.students)) {
|
||||
const first = this.students.find(Boolean);
|
||||
if (this.lvbListGruppe.every(item => item.gruppe != first.gruppe))
|
||||
return false;
|
||||
if (this.students.every(ps => ps.gruppe === first.gruppe))
|
||||
return first.gruppe;
|
||||
return false;
|
||||
}
|
||||
if (this.lvbListGruppe.some(item => item.gruppe == this.students.gruppe))
|
||||
return this.students.gruppe;
|
||||
return false;
|
||||
},
|
||||
set(value) {
|
||||
this.selectedGruppe = value;
|
||||
}
|
||||
},
|
||||
stgSemester() {
|
||||
if (!this.lvbList.length)
|
||||
return [];
|
||||
|
||||
const semester = new Set(this.lvbList.map(lvb => lvb.semester));
|
||||
|
||||
return Array.from(semester).sort((a, b) => a - b);
|
||||
},
|
||||
lvbListVerband() {
|
||||
if (!this.lvbList.length)
|
||||
return [];
|
||||
if (this.semester === false)
|
||||
return [];
|
||||
|
||||
return this.lvbList.filter(lvb => this.semester == lvb.semester);
|
||||
},
|
||||
semesterVerband() {
|
||||
if (!this.lvbListVerband.length)
|
||||
return [];
|
||||
|
||||
const verband = new Set(this.lvbListVerband.map(lvb => lvb.verband.replace(/ /g, '')));
|
||||
|
||||
return Array.from(verband).filter(Boolean).sort();
|
||||
},
|
||||
lvbListGruppe() {
|
||||
if (!this.lvbListVerband.length)
|
||||
return [];
|
||||
if (this.verband === false)
|
||||
return [];
|
||||
|
||||
return this.lvbListVerband.filter(lvb => this.verband == lvb.verband);
|
||||
},
|
||||
verbandGruppe() {
|
||||
if (!this.lvbListGruppe.length)
|
||||
return [];
|
||||
|
||||
const gruppe = new Set(this.lvbListGruppe.map(lvb => lvb.gruppe.replace(/ /g, '')));
|
||||
|
||||
return Array.from(gruppe).filter(Boolean).sort();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
studiengang_kz() {
|
||||
this.loadGroupsForStg();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadGroupsForStg() {
|
||||
this.lvbList = [];
|
||||
|
||||
if (this.studiengang_kz === false)
|
||||
return;
|
||||
|
||||
this.$api
|
||||
.call(ApiStvLvb.getTree(this.studiengang_kz))
|
||||
.then(result => this.lvbList = result.data)
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
},
|
||||
onSubmit() {
|
||||
let params = {
|
||||
studiengang_kz: this.studiengang_kz,
|
||||
semester: this.semester,
|
||||
verband: this.verband,
|
||||
gruppe: this.gruppe
|
||||
};
|
||||
this.$emit("submit", params);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadGroupsForStg();
|
||||
},
|
||||
template: /* html */`
|
||||
<div class="stv-details-groups-lvb">
|
||||
<fhc-form
|
||||
v-if="allAreStudents && studiengang_kz"
|
||||
ref="form"
|
||||
class="input-group"
|
||||
@submit.prevent="onSubmit"
|
||||
>
|
||||
<span class="input-group-text">
|
||||
{{ $p.t('lehre/semester') }}
|
||||
</span>
|
||||
<select
|
||||
v-model="semester"
|
||||
class="form-select"
|
||||
>
|
||||
<option v-for="semester in stgSemester">{{ semester }}</option>
|
||||
</select>
|
||||
<span
|
||||
class="input-group-text"
|
||||
:class="{'text-muted': semester === false}"
|
||||
>
|
||||
{{ $p.t('lehre/verband') }}
|
||||
</span>
|
||||
<select
|
||||
v-model="verband"
|
||||
class="form-select"
|
||||
:disabled="semester === false"
|
||||
>
|
||||
<option v-for="verband in semesterVerband">{{ verband }}</option>
|
||||
</select>
|
||||
<span
|
||||
class="input-group-text"
|
||||
:class="{'text-muted': verband === false}"
|
||||
>
|
||||
{{ $p.t('lehre/gruppe') }}
|
||||
</span>
|
||||
<select
|
||||
v-model="gruppe"
|
||||
class="form-select"
|
||||
:disabled="verband === false"
|
||||
>
|
||||
<option v-for="gruppe in verbandGruppe">{{ gruppe }}</option>
|
||||
</select>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-primary"
|
||||
:disabled="gruppe === false && verband === false"
|
||||
>
|
||||
{{ $p.t('ui/change') }}
|
||||
</button>
|
||||
</fhc-form>
|
||||
<div v-if="!allAreStudents" class="alert alert-danger">
|
||||
{{ $p.t('stv/groups_error_notallstudents') }}
|
||||
</div>
|
||||
<div v-if="!studiengang_kz" class="alert alert-danger">
|
||||
{{ $p.t('stv/groups_error_notsamestg') }}
|
||||
</div>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,97 @@
|
||||
import BsModal from "../../../../Bootstrap/Modal.js";
|
||||
import FhcForm from "../../../../Form/Form.js";
|
||||
import FormValidation from "../../../../Form/Validation.js";
|
||||
import FormInput from "../../../../Form/Input.js";
|
||||
|
||||
import ApiStvGroups from '../../../../../api/factory/stv/group.js';
|
||||
|
||||
export default {
|
||||
name: 'TabGroupsSpecial',
|
||||
components: {
|
||||
BsModal,
|
||||
FhcForm,
|
||||
FormValidation,
|
||||
FormInput,
|
||||
PvAutocomplete: primevue.autocomplete
|
||||
},
|
||||
props: {
|
||||
defaultStg: Number
|
||||
},
|
||||
emits: [
|
||||
"chosen"
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
groupSuggestions: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
show() {
|
||||
this.$refs.popup.show();
|
||||
},
|
||||
hide() {
|
||||
this.$refs.popup.hide();
|
||||
},
|
||||
getGroupSuggestions({ query }) {
|
||||
this.$api
|
||||
.call(ApiStvGroups.search(query, this.defaultStg))
|
||||
.then(result => this.groupSuggestions = result.data)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
onSubmit(evt) {
|
||||
if (!evt.defaultPrevented) {
|
||||
evt.preventDefault();
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
onEnter() {
|
||||
/**
|
||||
* NOTE(chris): PrimeVue: AutoComplete: Enter does not submit form #5618
|
||||
* @see https://github.com/primefaces/primevue/issues/5618
|
||||
*
|
||||
* this is fixed in 3.52.0
|
||||
* until then this function fill fix it
|
||||
*/
|
||||
if (!this.$refs.autocomplete.$refs.input.overlayVisible) {
|
||||
this.$refs.form.$el.requestSubmit();
|
||||
}
|
||||
},
|
||||
modalOpened() {
|
||||
this.$refs.autocomplete.$refs.input.$refs.focusInput.focus();
|
||||
},
|
||||
modalClosed() {
|
||||
this.value = '';
|
||||
this.$refs.form.clearValidation();
|
||||
}
|
||||
},
|
||||
template: /* html */`
|
||||
<bs-modal
|
||||
ref="popup"
|
||||
class="stv-details-groups-special"
|
||||
@hide-bs-modal="modalClosed"
|
||||
@shown-bs-modal="modalOpened"
|
||||
>
|
||||
<template #title>
|
||||
{{ $p.t('gruppenmanagement/add_group') }}
|
||||
</template>
|
||||
<fhc-form ref="form" @submit="onSubmit">
|
||||
<form-validation />
|
||||
<div class="input-group">
|
||||
<form-input
|
||||
ref="autocomplete"
|
||||
type="autocomplete"
|
||||
name="gruppe_kurzbz"
|
||||
v-model="value"
|
||||
container-class="flex-grow-1"
|
||||
input-class="w-100"
|
||||
:suggestions="groupSuggestions"
|
||||
:option-label="el => el.gruppe_kurzbz + (el.bezeichnung ? ' (' + el.bezeichnung + ')' : '')"
|
||||
@complete="getGroupSuggestions"
|
||||
@keydown.enter.capture="onEnter"
|
||||
/>
|
||||
<button type="submit" class="btn btn-primary">{{ $p.t('ui/hinzufuegen') }}</button>
|
||||
</div>
|
||||
</fhc-form>
|
||||
</bs-modal>`
|
||||
};
|
||||
@@ -1,187 +0,0 @@
|
||||
import {CoreFilterCmpt} from "../../../../filter/Filter.js";
|
||||
|
||||
import ApiStvGroups from '../../../../../api/factory/stv/group.js';
|
||||
|
||||
export default {
|
||||
name: 'TblGroups',
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
},
|
||||
inject: {
|
||||
currentSemester: {
|
||||
from: 'currentSemester',
|
||||
},
|
||||
},
|
||||
props: {
|
||||
student: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabulatorOptions: {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: () => this.$api.call(
|
||||
ApiStvGroups.getGruppen(this.student.uid)
|
||||
),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
initialFilter: {
|
||||
logic: "and",
|
||||
filters: [
|
||||
{ field: "uid", operator: "eq", value: this.student.uid },
|
||||
{
|
||||
logic: "or",
|
||||
filters: [
|
||||
{ field: "studiensemester_kurzbz", operator: "eq", value: null },
|
||||
{ field: "studiensemester_kurzbz", operator: "eq", value: this.currentSemester }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
columns: [
|
||||
{title: "Gruppe", field: "gruppe_kurzbz"},
|
||||
{title: "Bezeichnung", field: "bezeichnung"},
|
||||
{title: "Semester", field: "studiensemester_kurzbz"},
|
||||
{
|
||||
title: "automatisch generiert",
|
||||
field: "generiert",
|
||||
formatter: "tickCross",
|
||||
hozAlign: "center",
|
||||
formatterParams: {
|
||||
tickElement: '<i class="fa fa-check text-success"></i>',
|
||||
crossElement: '<i class="fa fa-xmark text-danger"></i>'
|
||||
}
|
||||
},
|
||||
{title: "UID", field: "uid"},
|
||||
{
|
||||
title: 'Aktionen', field: 'actions',
|
||||
minWidth: 150, // Ensures Action-buttons will be always fully displayed
|
||||
formatter: (cell, formatterParams, onRendered) => {
|
||||
const container = document.createElement('div');
|
||||
container.className = "d-flex gap-2";
|
||||
|
||||
const data = cell.getData();
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-xmark"></i>';
|
||||
button.title = this.$p.t('ui', 'loeschen');
|
||||
button.addEventListener('click', () =>
|
||||
this.actionDeleteGroup(data.gruppe_kurzbz)
|
||||
);
|
||||
if (data.generiert)
|
||||
button.disabled = true;
|
||||
container.append(button);
|
||||
|
||||
return container;
|
||||
},
|
||||
frozen: true
|
||||
},
|
||||
],
|
||||
layout: 'fitDataFill',
|
||||
height: 'auto',
|
||||
index: 'group_id',
|
||||
persistenceID: 'stv-details-gruppe'
|
||||
},
|
||||
tabulatorEvents: [
|
||||
{
|
||||
event: 'tableBuilt',
|
||||
handler: async () => {
|
||||
|
||||
await this.$p.loadCategory(['global', 'person', 'stv', 'ui', 'gruppenmanagement']);
|
||||
|
||||
let cm = this.$refs.table.tabulator.columnManager;
|
||||
|
||||
cm.getColumnByField('gruppe_kurzbz').component.updateDefinition({
|
||||
title: this.$p.t('gruppenmanagement', 'gruppe')
|
||||
});
|
||||
|
||||
cm.getColumnByField('bezeichnung').component.updateDefinition({
|
||||
title: this.$p.t('ui', 'bezeichnung')
|
||||
});
|
||||
|
||||
cm.getColumnByField('generiert').component.updateDefinition({
|
||||
title: this.$p.t('gruppenmanagement', 'automatisch_generiert')
|
||||
});
|
||||
|
||||
cm.getColumnByField('uid').component.updateDefinition({
|
||||
title: this.$p.t('ui', 'student_uid')
|
||||
});
|
||||
|
||||
//Interference with Filter if not commented out
|
||||
/*
|
||||
cm.getColumnByField('studiensemester_kurzbz').component.updateDefinition({
|
||||
title: this.$p.t('lehre', 'studiensemester')
|
||||
});*/
|
||||
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
actionDeleteGroup(gruppe_kurzbz) {
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
.then(result => result
|
||||
? gruppe_kurzbz
|
||||
: Promise.reject({handled: true}))
|
||||
.then(this.deleteGroup)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
},
|
||||
deleteGroup(gruppe_kurzbz) {
|
||||
const group_id = {
|
||||
id: this.student.uid,
|
||||
gruppe_kurzbz: gruppe_kurzbz
|
||||
};
|
||||
|
||||
return this.$api
|
||||
.call(ApiStvGroups.deleteGroup(group_id))
|
||||
.then(response => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
|
||||
}).catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
window.scrollTo(0, 0);
|
||||
this.reload();
|
||||
});
|
||||
},
|
||||
reload() {
|
||||
this.$refs.table.reloadTable();
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
currentSemester(newVal) {
|
||||
if (newVal) {
|
||||
this.$refs.table.tabulator.clearFilter(); // Clear old filters
|
||||
|
||||
this.$refs.table.tabulator.setFilter((data) => {
|
||||
return (
|
||||
data.uid === this.student.uid &&
|
||||
(
|
||||
data.studiensemester_kurzbz === newVal ||
|
||||
data.studiensemester_kurzbz === null
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
student() {
|
||||
this.$refs.table.reloadTable();
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-gruppen h-100 pb-3">
|
||||
<h5>{{$p.t('stv', 'tab_groups')}}</h5>
|
||||
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
reload
|
||||
:reload-btn-infotext="this.$p.t('table', 'reload')"
|
||||
>
|
||||
</core-filter-cmpt>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
export default {
|
||||
name: "Kontaktieren",
|
||||
computed: {
|
||||
internMails() {
|
||||
if (this.modelValue.mail_intern)
|
||||
{
|
||||
return [this.modelValue.mail_intern];
|
||||
}
|
||||
return this.modelValue.map(e => e.mail_intern);
|
||||
},
|
||||
privateMails()
|
||||
{
|
||||
if (this.modelValue.mail_privat)
|
||||
{
|
||||
return [this.modelValue.mail_privat];
|
||||
}
|
||||
return this.modelValue.map(e => e.mail_privat);
|
||||
},
|
||||
},
|
||||
props: {
|
||||
modelValue: Object
|
||||
},
|
||||
|
||||
methods: {
|
||||
async splitMails(mails, event) {
|
||||
let splititem = ",";
|
||||
let maillist = mails.join(splititem);
|
||||
let mailto = "";
|
||||
|
||||
if (maillist.length > 2024)
|
||||
{
|
||||
if (await this.$fhcAlert.confirm({message: this.$p.t('stv', 'zuvieleEMails') }) === false)
|
||||
return;
|
||||
}
|
||||
|
||||
let firstrun = true;
|
||||
let useBcc = event?.ctrlKey || event?.metaKey;
|
||||
while (maillist.length > 0)
|
||||
{
|
||||
if (maillist.length > 2024)
|
||||
{
|
||||
let splitposition = maillist.lastIndexOf(splititem, 1900);
|
||||
mailto = maillist.substring(0, splitposition);
|
||||
maillist = maillist.substring(splitposition + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
mailto = maillist;
|
||||
maillist = "";
|
||||
}
|
||||
|
||||
let mailLink = useBcc ? `mailto:?bcc=${mailto}` : `mailto:${mailto}`;
|
||||
|
||||
if (firstrun)
|
||||
{
|
||||
window.location.href = mailLink;
|
||||
firstrun = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await this.$fhcAlert.confirm({message: this.$p.t('stv', 'weitereEMail')}) === true)
|
||||
{
|
||||
window.location.href = mailLink;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
internMail(event) {
|
||||
if (this.internMails.length)
|
||||
{
|
||||
this.splitMails(this.internMails, event);
|
||||
}
|
||||
},
|
||||
privateMail(event) {
|
||||
if (this.privateMails.length)
|
||||
{
|
||||
this.splitMails(this.privateMails, event);
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div id="elementID"></div>
|
||||
<div class="row">
|
||||
<div class="col-lg-2">
|
||||
<button class="btn btn-primary mb-2" @click="internMail($event)" :title="$p.t('stv', 'bccEMail')">
|
||||
<i class="fa-solid fa-mail"></i> {{$p.t('stv', 'internEMail')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-2">
|
||||
<button class="btn btn-primary mb-2" @click="privateMail($event)" :title="$p.t('stv', 'bccEMail')">
|
||||
<i class="fa-solid fa-mail"></i> {{$p.t('stv', 'privateEMail')}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>`
|
||||
};
|
||||
@@ -401,7 +401,7 @@ export default{
|
||||
this.$api
|
||||
.call(ApiStvPrestudent.getLastBismeldestichtag())
|
||||
.then(result => {
|
||||
this.dataMeldestichtag = result.data[0].meldestichtag;
|
||||
this.dataMeldestichtag = result.data[0]?.meldestichtag;
|
||||
if (this.$refs.table && this.$refs.table.tableBuilt)
|
||||
this.$refs.table.tabulator.redraw(true);
|
||||
})
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import Projektarbeit from './Projektarbeit/Projektarbeit.js';
|
||||
|
||||
export default {
|
||||
name: "TabProjektarbeit",
|
||||
components: {
|
||||
Projektarbeit
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
config: this.config
|
||||
};
|
||||
},
|
||||
props: {
|
||||
modelValue: Object,
|
||||
config: Object
|
||||
},
|
||||
data(){
|
||||
return {}
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-projektarbeit h-100 d-flex flex-column">
|
||||
<projektarbeit ref="projektarbeit" :student="modelValue"></projektarbeit>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,411 @@
|
||||
import FormForm from '../../../../Form/Form.js';
|
||||
import FormInput from '../../../../Form/Input.js';
|
||||
import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
|
||||
|
||||
import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormForm,
|
||||
FormInput,
|
||||
PvAutoComplete
|
||||
},
|
||||
emits: ['projekttypChanged'],
|
||||
inject: {
|
||||
defaultSemester: {
|
||||
from: 'defaultSemester'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// prepared Lehreinheiten (with compound Bezeichnung)
|
||||
arrLes() {
|
||||
let lehreinheiten = [];
|
||||
if (this.formData.lehrveranstaltung_id) {
|
||||
let lv = this.arrLvs.find(lv => {return lv.lehrveranstaltung_id == this.formData.lehrveranstaltung_id});
|
||||
if (lv) lehreinheiten = lv.lehreinheiten
|
||||
}
|
||||
|
||||
for (let le of lehreinheiten)
|
||||
{
|
||||
let bezeichnung = le.lehrfach_kurzbz + '-' + le.lehrform_kurzbz + ' ' + le.lehrfach_bezeichnung + ' ';
|
||||
|
||||
for (let grp of le.lehreinheitgruppen)
|
||||
{
|
||||
bezeichnung += grp.gruppe_kurzbz ? grp.gruppe_kurzbz : '' + grp.semester ?? '' + grp.verband ?? '' + grp.gruppe ?? '';
|
||||
}
|
||||
|
||||
bezeichnung += ' (' + le.lektoren.join(' ') + ') ID: ' + le.lehreinheit_id;
|
||||
|
||||
le.bezeichnung = bezeichnung;
|
||||
}
|
||||
|
||||
return lehreinheiten;
|
||||
}
|
||||
},
|
||||
props: {
|
||||
statusNew: Boolean,
|
||||
student: Object,
|
||||
projektarbeit: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
projektarbeit_id: null,
|
||||
titel: null,
|
||||
titel_english: null,
|
||||
themenbereich: null,
|
||||
projekttyp_kurzbz: null,
|
||||
firma: null,
|
||||
lehrveranstaltung_id: null,
|
||||
lehreinheit_id: null,
|
||||
beginn: null,
|
||||
ende: null,
|
||||
freigegeben: true,
|
||||
gesperrtbis: null,
|
||||
note: null,
|
||||
final: true,
|
||||
anmerkung: null
|
||||
},
|
||||
arrTypen: [],
|
||||
arrFirmen: [],
|
||||
arrLvs: [],
|
||||
arrNoten: [],
|
||||
filteredFirmen: [],
|
||||
abortController: {
|
||||
firma: null
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'formData.projekttyp_kurzbz'(newValue, oldValue) {
|
||||
this.$emit('projekttypChanged', newValue);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetForm() {
|
||||
this.formData.projektarbeit_id = null;
|
||||
this.formData.titel = null;
|
||||
this.formData.titel_english = null;
|
||||
this.formData.themenbereich = null;
|
||||
this.formData.projekttyp_kurzbz = null;
|
||||
this.formData.firma = null;
|
||||
this.formData.lehrveranstaltung_id = null;
|
||||
this.formData.lehreinheit_id = null;
|
||||
this.formData.beginn = null;
|
||||
this.formData.ende = null;
|
||||
this.formData.freigegeben = true;
|
||||
this.formData.gesperrtbis = null;
|
||||
this.formData.note = null;
|
||||
this.formData.final = true;
|
||||
this.formData.anmerkung = null;
|
||||
this.$refs.formDetails.clearValidation();
|
||||
},
|
||||
getFormData(statusNew, studiensemester_kurzbz, additional_lehrveranstaltung_id) {
|
||||
|
||||
this.$api
|
||||
.call(ApiStvProjektarbeit.getTypenProjektarbeit())
|
||||
.then(result => {
|
||||
this.arrTypen = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvProjektarbeit.getLehrveranstaltungen(
|
||||
this.student.uid,
|
||||
statusNew ? this.student.studiengang_kz : null,
|
||||
studiensemester_kurzbz ?? this.defaultSemester,
|
||||
additional_lehrveranstaltung_id
|
||||
))
|
||||
.then(result => {
|
||||
this.arrLvs = result.data
|
||||
}
|
||||
)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvProjektarbeit.getNoten())
|
||||
.then(result => {
|
||||
this.arrNoten = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
if (statusNew) this.resetForm();
|
||||
},
|
||||
loadProjektarbeit(projektarbeit_id) {
|
||||
|
||||
if (this?.formData?.projektarbeit_id == projektarbeit_id) return;
|
||||
this.resetForm();
|
||||
return this.$api
|
||||
.call(ApiStvProjektarbeit.loadProjektarbeit(projektarbeit_id))
|
||||
.then(result => {
|
||||
this.formData = result.data;
|
||||
if (this.formData.firma_id) this.formData.firma = {firma_id: this.formData.firma_id, name: this.formData.firma_name};
|
||||
return result;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
},
|
||||
addNewProjektarbeit() {
|
||||
|
||||
let dataToSend = {
|
||||
uid: this.student.uid,
|
||||
formData: this.getPreparedFormData()
|
||||
};
|
||||
|
||||
return this.$refs.formDetails
|
||||
.call(ApiStvProjektarbeit.addNewProjektarbeit(dataToSend));
|
||||
},
|
||||
updateProjektarbeit() {
|
||||
|
||||
let dataToSend = {
|
||||
projektarbeit_id: this.formData.projektarbeit_id,
|
||||
formData: this.getPreparedFormData()
|
||||
};
|
||||
return this.$refs.formDetails
|
||||
.call(ApiStvProjektarbeit.updateProjektarbeit(dataToSend));
|
||||
},
|
||||
searchFirma(event) {
|
||||
if (this.abortController.firma) {
|
||||
this.abortController.firma.abort();
|
||||
}
|
||||
this.abortController.firma = new AbortController();
|
||||
|
||||
return this.$api
|
||||
.call(ApiStvProjektarbeit.getFirmen(event.query))
|
||||
.then(result => {
|
||||
this.filteredFirmen = result.data;
|
||||
});
|
||||
},
|
||||
lvChanged(event) {
|
||||
this.formData.lehreinheit_id = null;
|
||||
},
|
||||
// enrich and modify data before sending
|
||||
getPreparedFormData() {
|
||||
let preparedFormData = JSON.parse(JSON.stringify(this.formData)); // deep copy
|
||||
|
||||
// set firma Id
|
||||
if (preparedFormData.firma)
|
||||
preparedFormData.firma_id = preparedFormData.firma.firma_id;
|
||||
else
|
||||
preparedFormData.firma_id = null;
|
||||
|
||||
// delete "helper" fields
|
||||
if (preparedFormData.projektarbeit_id == null) delete(preparedFormData.projektarbeit_id);
|
||||
delete(preparedFormData.firma);
|
||||
delete(preparedFormData.firma_name);
|
||||
delete(preparedFormData.lehrveranstaltung_id);
|
||||
|
||||
return preparedFormData;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<form-form v-if="!this.student.length" ref="formDetails" @submit.prevent>
|
||||
|
||||
<legend>Details</legend>
|
||||
<p v-if="statusNew">[{{$p.t('ui', 'neu')}}]</p>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-titel"
|
||||
type="text"
|
||||
name="titel"
|
||||
:label="$p.t('projektarbeit', 'titel')"
|
||||
v-model="formData.titel">
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-titel_english"
|
||||
type="text"
|
||||
name="titel_english"
|
||||
:label="$p.t('projektarbeit', 'titelEnglisch')"
|
||||
v-model="formData.titel_english"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-themenbereich"
|
||||
type="text"
|
||||
name="themenbereich"
|
||||
:label="$p.t('projektarbeit', 'themenbereich')"
|
||||
v-model="formData.themenbereich"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-typ"
|
||||
:label="$p.t('projektarbeit', 'typ')"
|
||||
type="select"
|
||||
v-model="formData.projekttyp_kurzbz"
|
||||
name="projekttyp_kurzbz"
|
||||
>
|
||||
<option
|
||||
v-for="typ in arrTypen"
|
||||
:key="typ.projekttyp_kurzbz"
|
||||
:value="typ.projekttyp_kurzbz"
|
||||
>
|
||||
{{typ.bezeichnung}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-firma"
|
||||
:label="$p.t('projektarbeit', 'firma')"
|
||||
type="autocomplete"
|
||||
optionLabel="name"
|
||||
v-model="formData.firma"
|
||||
name="firma"
|
||||
:suggestions="filteredFirmen"
|
||||
@complete="searchFirma"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-lv"
|
||||
:label="$p.t('projektarbeit', 'lehrveranstaltung')"
|
||||
type="select"
|
||||
v-model="formData.lehrveranstaltung_id"
|
||||
name="lehrveranstaltung_id"
|
||||
@change="lvChanged($event)"
|
||||
>
|
||||
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
|
||||
<option
|
||||
v-for="lv in arrLvs"
|
||||
:key="lv.lehrveranstaltung_id"
|
||||
:value="lv.lehrveranstaltung_id"
|
||||
>
|
||||
{{lv.bezeichnung + (lv.orgform_kurzbz ? ' ' + lv.orgform_kurzbz : '') + ' (' + lv.semester + ' Sem) ID: ' + lv.lehrveranstaltung_id}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-le"
|
||||
:label="$p.t('projektarbeit', 'lvTeil')"
|
||||
type="select"
|
||||
v-model="formData.lehreinheit_id"
|
||||
name="lehreinheit_id"
|
||||
>
|
||||
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
|
||||
<option
|
||||
v-for="le in arrLes"
|
||||
:key="le.lehreinheit_id"
|
||||
:value="le.lehreinheit_id"
|
||||
>
|
||||
{{le.bezeichnung}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="col-6 stv-details-projektarbeit-beginn"
|
||||
:label="$p.t('projektarbeit', 'beginn')"
|
||||
type="DatePicker"
|
||||
v-model="formData.beginn"
|
||||
auto-apply
|
||||
:enable-time-picker="false"
|
||||
text-input
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
name="beginn"
|
||||
>
|
||||
</form-input>
|
||||
<form-input
|
||||
container-class="col-6 stv-details-projektarbeit-ende"
|
||||
:label="$p.t('projektarbeit', 'ende')"
|
||||
type="DatePicker"
|
||||
v-model="formData.ende"
|
||||
auto-apply
|
||||
:enable-time-picker="false"
|
||||
text-input
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
name="ende"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<form-input
|
||||
container-class="col-8 stv-details-projektarbeit-gesperrtbis"
|
||||
:label="$p.t('projektarbeit', 'gesperrtBis')"
|
||||
type="DatePicker"
|
||||
v-model="formData.gesperrtbis"
|
||||
auto-apply
|
||||
:enable-time-picker="false"
|
||||
text-input
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
name="gesperrtbis"
|
||||
>
|
||||
</form-input>
|
||||
<div class="col-4">
|
||||
<form-input
|
||||
container-class="form-check stv-details-projektarbeit-freigegeben"
|
||||
type="checkbox"
|
||||
name="freigegeben"
|
||||
:label="$p.t('projektarbeit','freigegeben')"
|
||||
v-model="formData.freigegeben"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 align-items-center">
|
||||
<form-input
|
||||
container-class="col-8 stv-details-projektarbeit-note"
|
||||
:label="$p.t('projektarbeit', 'note')"
|
||||
type="select"
|
||||
v-model="formData.note"
|
||||
name="note"
|
||||
>
|
||||
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
|
||||
<option
|
||||
v-for="note in arrNoten"
|
||||
:key="note.note"
|
||||
:value="note.note"
|
||||
>
|
||||
{{note.bezeichnung}}
|
||||
</option>
|
||||
</form-input>
|
||||
<div class="col-4">
|
||||
<form-input
|
||||
container-class="form-check stv-details-projektarbeit-final"
|
||||
type="checkbox"
|
||||
name="final"
|
||||
label="final"
|
||||
v-model="formData.final"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="col-12 stv-details-abschlusspruefung-anmerkung"
|
||||
:label="$p.t('projektarbeit', 'anmerkung')"
|
||||
type="textarea"
|
||||
v-model="formData.anmerkung"
|
||||
name="anmerkung"
|
||||
:rows= 3
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
</form-form>`
|
||||
}
|
||||
@@ -0,0 +1,407 @@
|
||||
import {CoreFilterCmpt} from "../../../../filter/Filter.js";
|
||||
import BsModal from "../../../../Bootstrap/Modal.js";
|
||||
import FormForm from '../../../../Form/Form.js';
|
||||
import FormInput from '../../../../Form/Input.js';
|
||||
import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
|
||||
|
||||
import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js';
|
||||
import ProjektarbeitDetails from "./Details.js";
|
||||
import Projektbetreuer from "./Projektbetreuer.js";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
BsModal,
|
||||
FormForm,
|
||||
FormInput,
|
||||
PvAutoComplete,
|
||||
ProjektarbeitDetails,
|
||||
Projektbetreuer
|
||||
},
|
||||
inject: {
|
||||
cisRoot: {
|
||||
from: 'cisRoot'
|
||||
},
|
||||
config: {
|
||||
from: 'config',
|
||||
required: true
|
||||
},
|
||||
$reloadList: {
|
||||
from: '$reloadList',
|
||||
required: true
|
||||
}
|
||||
},
|
||||
props: {
|
||||
student: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabulatorEvents: [
|
||||
{
|
||||
event: 'dataLoaded',
|
||||
handler: data => this.tabulatorData = data.map(item => {
|
||||
item.actionDiv = document.createElement('div');
|
||||
return item;
|
||||
}),
|
||||
},
|
||||
{
|
||||
event: 'tableBuilt',
|
||||
handler: async() => {
|
||||
await this.$p.loadCategory(['global', 'person', 'stv', 'ui', 'projektarbeit']);
|
||||
|
||||
let cm = this.$refs.table.tabulator.columnManager;
|
||||
|
||||
cm.getColumnByField('projekttyp_kurzbz').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'typ')
|
||||
});
|
||||
cm.getColumnByField('titel').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'titel')
|
||||
});
|
||||
cm.getColumnByField('beginn').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'beginn')
|
||||
});
|
||||
cm.getColumnByField('ende').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'ende')
|
||||
});
|
||||
cm.getColumnByField('freigegeben').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'freigegeben')
|
||||
});
|
||||
cm.getColumnByField('gesperrtbis').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'gesperrtBis')
|
||||
});
|
||||
cm.getColumnByField('themenbereich').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'themenbereich')
|
||||
});
|
||||
cm.getColumnByField('anmerkung').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'anmerkung')
|
||||
});
|
||||
cm.getColumnByField('firma_id').component.updateDefinition({
|
||||
title: this.$p.t('projektarbeit', 'firmaId')
|
||||
});
|
||||
}
|
||||
},
|
||||
],
|
||||
tabulatorData: [],
|
||||
editedProjektarbeit: null,
|
||||
statusNew: true,
|
||||
studiensemester_kurzbz: null,
|
||||
lehrveranstaltung_id: null,
|
||||
activeTab: 'details'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tabulatorOptions() {
|
||||
const options = {
|
||||
ajaxURL: 'dummy',
|
||||
ajaxRequestFunc: () => this.$api.call(ApiStvProjektarbeit.getProjektarbeit(this.student.uid)),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
columns: [
|
||||
{title: "Projektarbeit ID", field: "projektarbeit_id", visible: false},
|
||||
{title: "Typ", field: "bezeichnung"},
|
||||
{title: "Typ Kurzbz", field: "projekttyp_kurzbz", visible: false},
|
||||
{title: "Studiensemester", field: "studiensemester_kurzbz"},
|
||||
{title: "Titel", field: "titel"},
|
||||
{
|
||||
title: "Abgabe Enduplad",
|
||||
field: "abgabedatum",
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
if (!dateStr) return "";
|
||||
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleString("de-DE", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
hour12: false
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Beginn",
|
||||
field: "beginn",
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
if (!dateStr) return "";
|
||||
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleString("de-DE", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
hour12: false
|
||||
});
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
title: "Ende",
|
||||
field: "ende",
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
if (!dateStr) return "";
|
||||
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleString("de-DE", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
hour12: false
|
||||
});
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
title:"Freigegeben",
|
||||
field:"freigegeben",
|
||||
formatter:"tickCross",
|
||||
hozAlign:"center",
|
||||
formatterParams: {
|
||||
tickElement: '<i class="fa fa-check text-success"></i>',
|
||||
crossElement: '<i class="fa fa-xmark text-danger"></i>'
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
title: "Gesperrt bis",
|
||||
field: "gesperrtbis",
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
if (!dateStr) return "";
|
||||
|
||||
const date = new Date(dateStr);
|
||||
return date.toLocaleString("de-DE", {
|
||||
day: "2-digit",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
hour12: false
|
||||
});
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{title: "Themenbereich", field: "themenbereich", visible: false},
|
||||
{title: "Anmerkung", field: "anmerkung", visible: false},
|
||||
{title: "Lehreinheit ID", field: "lehreinheit_id", visible: false},
|
||||
{title: "Student UID", field: "student_uid", visible: false},
|
||||
{
|
||||
title:"Final",
|
||||
field:"final",
|
||||
formatter:"tickCross",
|
||||
hozAlign:"center",
|
||||
formatterParams: {
|
||||
tickElement: '<i class="fa fa-check text-success"></i>',
|
||||
crossElement: '<i class="fa fa-xmark text-danger"></i>'
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{title: "Firma ID", field: "firma_id", visible: false},
|
||||
{
|
||||
title: 'Aktionen', field: 'actions',
|
||||
minWidth: 150, // Ensures Action-buttons will be always fully displayed
|
||||
formatter: (cell, formatterParams, onRendered) => {
|
||||
let container = document.createElement('div');
|
||||
container.className = "d-flex gap-2";
|
||||
|
||||
let button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-edit"></i>';
|
||||
button.title = this.$p.t('ui', 'bearbeiten');
|
||||
button.addEventListener('click', (event) => {
|
||||
let data = cell.getData();
|
||||
this.editedProjektarbeit = data;
|
||||
this.actionEditProjektarbeit();
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-users"></i>';
|
||||
button.title = this.$p.t('projektarbeit', 'betreuerBearbeiten');
|
||||
button.addEventListener('click', (event) => {
|
||||
let data = cell.getData();
|
||||
this.editedProjektarbeit = data;
|
||||
this.actionEditBetreuer();
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-xmark"></i>';
|
||||
button.title = this.$p.t('ui', 'loeschen');
|
||||
button.addEventListener('click', () =>
|
||||
this.actionDeleteProjektarbeit(cell.getData().projektarbeit_id)
|
||||
);
|
||||
container.append(button);
|
||||
|
||||
container.append(cell.getData().actionDiv);
|
||||
|
||||
return container;
|
||||
},
|
||||
frozen: true
|
||||
},
|
||||
],
|
||||
//layout: 'fitDataFill',
|
||||
height: 'auto',
|
||||
minHeight: '200',
|
||||
selectable: 1,
|
||||
index: 'projektarbeit_id',
|
||||
persistence:{
|
||||
columns: true, //persist column layout
|
||||
},
|
||||
persistenceID: 'stv-details-projektarbeit'
|
||||
}
|
||||
return options;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
actionNewProjektarbeit() {
|
||||
this.statusNew = true;
|
||||
this.editedProjektarbeit = null;
|
||||
this.toggleMenu('details');
|
||||
this.$refs.projektarbeitDetails.getFormData(this.statusNew);
|
||||
this.$refs.projektarbeitModal.show();
|
||||
},
|
||||
actionEditProjektarbeit() {
|
||||
this.statusNew = false;
|
||||
this.toggleMenu('details');
|
||||
this.$refs.projektarbeitModal.show();
|
||||
},
|
||||
actionEditBetreuer() {
|
||||
this.statusNew = false;
|
||||
this.toggleMenu('betreuer');
|
||||
this.$refs.projektarbeitModal.show();
|
||||
},
|
||||
actionDeleteProjektarbeit(projektarbeit_id) {
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
.then(result => result
|
||||
? projektarbeit_id
|
||||
: Promise.reject({handled: true}))
|
||||
.then(this.deleteProjektarbeit)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
addNewProjektarbeit() {
|
||||
this.$refs.projektarbeitDetails.addNewProjektarbeit()
|
||||
.then((result) => {
|
||||
this.projektarbeitSaved();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
updateProjektarbeit() {
|
||||
this.$refs.projektarbeitDetails.updateProjektarbeit()
|
||||
.then((result) => {
|
||||
this.projektarbeitSaved();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
deleteProjektarbeit(projektarbeit_id) {
|
||||
return this.$api
|
||||
.call(ApiStvProjektarbeit.deleteProjektarbeit(projektarbeit_id))
|
||||
.then(response => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
.finally(() => {
|
||||
this.reload();
|
||||
});
|
||||
},
|
||||
projektarbeitSaved() {
|
||||
this.reload();
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
this.hideModal('projektarbeitModal');
|
||||
},
|
||||
setDefaultStunden(projekttyp_kurzbz) {
|
||||
this.$refs.projektbetreuer.setDefaultStunden(projekttyp_kurzbz);
|
||||
},
|
||||
hideModal(modalRef){
|
||||
this.$refs[modalRef].hide();
|
||||
},
|
||||
reload() {
|
||||
this.$refs.table.reloadTable();
|
||||
},
|
||||
toggleMenu(tabId) {
|
||||
this.activeTab = tabId;
|
||||
if (this.statusNew == false) {
|
||||
switch(tabId) {
|
||||
case 'details':
|
||||
this.$refs.projektarbeitDetails.getFormData(
|
||||
this.statusNew, this.editedProjektarbeit?.studiensemester_kurzbz, this.editedProjektarbeit?.lehrveranstaltung_id
|
||||
);
|
||||
this.$refs.projektarbeitDetails.loadProjektarbeit(this.editedProjektarbeit?.projektarbeit_id);
|
||||
break;
|
||||
case 'betreuer':
|
||||
this.$refs.projektbetreuer.getFormData(
|
||||
this.editedProjektarbeit ? this.editedProjektarbeit.projekttyp_kurzbz : null
|
||||
);
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-projektarbeit h-100 pb-3">
|
||||
<h4>{{this.$p.t('stv','tab_projektarbeit')}}</h4>
|
||||
|
||||
<core-filter-cmpt
|
||||
v-if="!this.student.length"
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
reload
|
||||
new-btn-show
|
||||
:new-btn-label="this.$p.t('stv', 'tab_projektarbeit')"
|
||||
@click:new="actionNewProjektarbeit"
|
||||
>
|
||||
</core-filter-cmpt>
|
||||
|
||||
<!--Modal: projektarbeitModal-->
|
||||
<bs-modal ref="projektarbeitModal" dialog-class="modal-xl modal-dialog-scrollable" header-class="flex-wrap pb-0">
|
||||
<template #title>
|
||||
<p v-if="statusNew" class="fw-bold mt-3">{{$p.t('projektarbeit', 'projektarbeitAnlegen')}}</p>
|
||||
<p v-else class="fw-bold mt-3">{{$p.t('projektarbeit', 'projektarbeitBearbeiten')}}</p>
|
||||
</template>
|
||||
|
||||
<template #modal-header-content v-if="!statusNew">
|
||||
<ul class="nav nav-tabs w-100 mt-3 msg_preview" id="pa_tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="activeTab == 'details' ? 'active' : ''" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab" aria-controls="details" aria-selected="true" @click="toggleMenu('details')">Details</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer-tab" data-bs-toggle="tab" data-bs-target="#betreuer" type="button" role="tab" aria-controls="betreuer" aria-selected="false" @click="toggleMenu('betreuer')">{{$p.t('projektarbeit', 'betreuerGross')}}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<div class="tab-content" id="pa_content">
|
||||
<div class="tab-pane fade show" :class="activeTab == 'details' ? 'active' : ''" id="details" role="tabpanel" aria-labelledby="details-tab">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<projektarbeit-details ref="projektarbeitDetails" :student="student" @projekttyp-changed="setDefaultStunden">
|
||||
</projektarbeit-details>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade show" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer" role="tabpanel" aria-labelledby="betreuer-tab">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<projektbetreuer ref="projektbetreuer" :config="config"></projektbetreuer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button v-if="statusNew" class="btn btn-primary" @click="addNewProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-if="!statusNew && activeTab == 'details'" class="btn btn-primary" @click="updateProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
</template>
|
||||
|
||||
</bs-modal>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
+561
@@ -0,0 +1,561 @@
|
||||
import {CoreFilterCmpt} from "../../../../filter/Filter.js";
|
||||
import BsModal from "../../../../Bootstrap/Modal.js";
|
||||
import FormForm from '../../../../Form/Form.js';
|
||||
import FormInput from '../../../../Form/Input.js';
|
||||
import PvAutoComplete from "../../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
|
||||
import NewPerson from "../../List/New.js";
|
||||
import Contact from "../Kontakt/Contact.js";
|
||||
import Vertrag from "./Vertrag.js";
|
||||
|
||||
import ApiStvProjektbetreuer from '../../../../../api/factory/stv/projektbetreuer.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
BsModal,
|
||||
FormForm,
|
||||
FormInput,
|
||||
PvAutoComplete,
|
||||
NewPerson,
|
||||
Contact,
|
||||
Vertrag
|
||||
},
|
||||
provide() {
|
||||
return {
|
||||
configShowVertragsdetails: this.config.showVertragsdetails
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
betreuerFormOpened() {
|
||||
return this.newMode || this.editMode;
|
||||
}
|
||||
},
|
||||
props: {
|
||||
config: {
|
||||
type: Object,
|
||||
default: {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabulatorOptions: {
|
||||
columns: [
|
||||
{title: "Nachname", field: "nachname"},
|
||||
{title: "Vorname", field: "vorname"},
|
||||
{title: "Note", field: "note"},
|
||||
{title: "Punkte", field: "punkte"},
|
||||
{title: "Stunden", field: "stunden"},
|
||||
{title: "Stundensatz", field: "stundensatz", visible: false},
|
||||
{title: "Art", field: "betreuerart_kurzbz", visible: false},
|
||||
{title: "Person ID", field: "person_id", visible: false},
|
||||
{title: "Vertrag ID", field: "vertrag_id", visible: false},
|
||||
{title: "Projektarbeit ID", field: "projektarbeit_id", visible: false},
|
||||
{
|
||||
title: 'Aktionen',
|
||||
field: 'actions',
|
||||
minWidth: 150, // Ensures Action-buttons will be always fully displayed
|
||||
formatter: (cell, formatterParams, onRendered) => {
|
||||
let container = document.createElement('div');
|
||||
container.className = "d-flex gap-2";
|
||||
|
||||
let button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-edit"></i>';
|
||||
button.title = this.$p.t('ui', 'bearbeiten');
|
||||
button.addEventListener('click', (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let data = cell.getData();
|
||||
this.actionEditProjektbetreuer(data.projektarbeit_id, data.person_id, data.betreuerart_kurzbz);
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-xmark"></i>';
|
||||
button.title = this.$p.t('ui', 'loeschen');
|
||||
button.addEventListener('click', (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const data = cell.getData();
|
||||
this.actionDeleteProjektbetreuer(data.betreuer_id, data.projektarbeit_id, data.person_id, data.betreuerart_kurzbz)
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
let data = cell.getData();
|
||||
if (data.beurteilungDownloadLink !== null) {
|
||||
if (data.beurteilungDownloadLink == '') {
|
||||
button = document.createElement('span');
|
||||
button.title = this.$p.t('projektarbeit', 'projektarbeitNochNichtBeurteilt')
|
||||
button.innerHTML = '<button class="btn btn-outline-secondary btn-action" disabled>'+
|
||||
'<i class="fa-regular fa-file-pdf"></i></button>';
|
||||
button.addEventListener('click', (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
else {
|
||||
button = document.createElement('a');
|
||||
button.setAttribute('href', data.beurteilungDownloadLink);
|
||||
button.setAttribute('role', 'button');
|
||||
button.innerHTML = '<i class="fa fa-file-pdf"></i>';
|
||||
button.title = this.$p.t('projektarbeit', 'projektbeurteilungErstellen');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.addEventListener('click', (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
window.location.href = data.beurteilungDownloadLink;
|
||||
});
|
||||
}
|
||||
container.append(button);
|
||||
}
|
||||
|
||||
return container;
|
||||
},
|
||||
frozen: true
|
||||
},
|
||||
],
|
||||
//layout: 'fitDataFill',
|
||||
layoutColumnsOnNewData: false,
|
||||
height: 'auto',
|
||||
minHeight: '100',
|
||||
selectable: true,
|
||||
selectable: 1,
|
||||
index: 'betreuer_id',
|
||||
persistence:{
|
||||
columns: true, //persist column layout
|
||||
},
|
||||
persistenceID: 'stv-details-projektbetreuer'
|
||||
},
|
||||
tabulatorEvents: [
|
||||
{
|
||||
event: 'tableBuilt',
|
||||
handler: async() => {
|
||||
await this.$p.loadCategory(['global', 'person', 'stv', 'projektarbeit', 'ui']);
|
||||
|
||||
// Force layout recalculation for handling overflow text
|
||||
this.$refs.projektbetreuerTable.tabulator.redraw(true);
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
event: 'rowSelected',
|
||||
handler: row => {
|
||||
let data = row.getData();
|
||||
this.actionEditProjektbetreuer(data.projektarbeit_id, data.person_id, data.betreuerart_kurzbz);
|
||||
}
|
||||
}
|
||||
],
|
||||
formData: {
|
||||
betreuerart_kurzbz: null,
|
||||
note: null,
|
||||
stunden: null,
|
||||
stundensatz: null
|
||||
},
|
||||
newMode: false,
|
||||
editMode: false,
|
||||
initialFormData: null,
|
||||
defaultFormDataValues: {stunden: null, stundensatz: null},
|
||||
projektarbeit_id: null,
|
||||
editedBetreuerIdx: -1,
|
||||
arrBetreuerart: [],
|
||||
arrNoten: [],
|
||||
filteredBetreuer: [],
|
||||
autocompleteSelectedBetreuer: null,
|
||||
beurteilungDownloadLink: null,
|
||||
vertragFieldsDisabled: false,
|
||||
abortController: {
|
||||
betreuer: null
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
actionNewProjektbetreuer() {
|
||||
this.resetForm();
|
||||
this.newMode = !this.newMode;
|
||||
this.editMode = false;
|
||||
this.captureFormData();
|
||||
},
|
||||
actionEditProjektbetreuer(projektarbeit_id, person_id, betreuerart_kurzbz) {
|
||||
this.editMode = true;
|
||||
this.newMode = false;
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getDefaultStundensaetze(person_id, this.studiensemester_kurzbz))
|
||||
.then(result => {
|
||||
this.resetForm();
|
||||
|
||||
// get betreuer from tabulator list
|
||||
let projektbetreuerListe = this.$refs.projektbetreuerTable.tabulator.getData();
|
||||
const idx = projektbetreuerListe.findIndex(
|
||||
betr =>
|
||||
betr.person_id === person_id &&
|
||||
betr.projektarbeit_id === projektarbeit_id &&
|
||||
betr.betreuerart_kurzbz === betreuerart_kurzbz
|
||||
);
|
||||
|
||||
if (idx >= 0) { // if betreuer found
|
||||
|
||||
// set currently edited betreuer (deep copy)
|
||||
this.formData = JSON.parse(JSON.stringify(projektbetreuerListe[idx]));
|
||||
|
||||
// set download link
|
||||
if (this.formData.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = this.formData.beurteilungDownloadLink;
|
||||
|
||||
// set betreuer for autocomplete field
|
||||
this.autocompleteSelectedBetreuer = {
|
||||
person_id: this.formData.person_id,
|
||||
name: this.formData.name,
|
||||
vorname: this.formData.vorname,
|
||||
nachname: this.formData.nachname,
|
||||
vertrag_id: this.formData.vertrag_id
|
||||
};
|
||||
}
|
||||
|
||||
// set default stundensatz (if no other is set yet)
|
||||
if (this.formData.stundensatz == null) this.formData.stundensatz = result.data;
|
||||
|
||||
// capture initial form data for detecting changes
|
||||
this.captureFormData();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
actionDeleteProjektbetreuer(betreuer_id, projektarbeit_id, person_id, betreuerart_kurzbz) {
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
.then(result => result
|
||||
? {projektarbeit_id, person_id, betreuerart_kurzbz}
|
||||
: Promise.reject({handled: true}))
|
||||
.then(result => {
|
||||
return this.$api
|
||||
.call(ApiStvProjektbetreuer.deleteProjektbetreuer(projektarbeit_id, person_id, betreuerart_kurzbz))
|
||||
})
|
||||
.then(result => {
|
||||
this.$refs.projektbetreuerTable.tabulator.deleteRow(betreuer_id);
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
getFormData(projekttyp_kurzbz) {
|
||||
// default Stundensätze from config
|
||||
this.defaultFormDataValues.stunden = this.getDefaultStunden(projekttyp_kurzbz);
|
||||
this.defaultFormDataValues.stundensatz = this.config.defaultProjektbetreuerStundensatz;
|
||||
|
||||
// get other initial data
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getBetreuerarten())
|
||||
.then(result => {
|
||||
this.arrBetreuerart = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getNoten())
|
||||
.then(result => {
|
||||
this.arrNoten = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
getProjektbetreuer(projektarbeit_id, studiensemester_kurzbz) {
|
||||
if (projektarbeit_id) {
|
||||
// if projektarbeit changed, reset the form to hold new data
|
||||
if (this.projektarbeit_id != projektarbeit_id) {
|
||||
this.resetForm();
|
||||
this.resetModes();
|
||||
}
|
||||
this.projektarbeit_id = projektarbeit_id;
|
||||
this.studiensemester_kurzbz = studiensemester_kurzbz;
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getProjektbetreuer(this.projektarbeit_id))
|
||||
.then(result => {
|
||||
this.$refs.projektbetreuerTable.tabulator.replaceData(this.addIds(result.data));
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
} else {
|
||||
this.emptyBetreuer();
|
||||
}
|
||||
},
|
||||
saveProjektbetreuer() {
|
||||
this.$refs.formProjektbetreuer.call(
|
||||
ApiStvProjektbetreuer.saveProjektbetreuer(this.projektarbeit_id, this.getFormDataWithBetreuer())
|
||||
)
|
||||
.then(result => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
this.getProjektbetreuer(this.projektarbeit_id, this.studiensemester_kurzbz);
|
||||
this.resetModes();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
searchBetreuer(event) {
|
||||
if (this.abortController.betreuer) {
|
||||
this.abortController.betreuer.abort();
|
||||
}
|
||||
this.abortController.betreuer = new AbortController();
|
||||
|
||||
return this.$api
|
||||
.call(ApiStvProjektbetreuer.getProjektbetreuerBySearchQuery(event.query))
|
||||
.then(result => {
|
||||
this.filteredBetreuer = result.data;
|
||||
});
|
||||
},
|
||||
emptyBetreuer() {
|
||||
this.$refs.projektbetreuerTable.tabulator.clearData();
|
||||
},
|
||||
resetForm() {
|
||||
this.formData = this.getDefaultFormData();
|
||||
if (this.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = '';
|
||||
this.autocompleteSelectedBetreuer = null;
|
||||
this.initialFormData = null;
|
||||
if (this.projekttyp_kurzbz) this.setDefaultStunden(this.projekttyp_kurzbz);
|
||||
this.disableVertragFields(false);
|
||||
this.$refs.formProjektbetreuer.clearValidation();
|
||||
},
|
||||
resetModes() {
|
||||
this.newMode = false;
|
||||
this.editMode = false;
|
||||
},
|
||||
getDefaultFormData() {
|
||||
let formData = {betreuerart_kurzbz : null, note: null};
|
||||
|
||||
for (const name in this.defaultFormDataValues) {
|
||||
formData[name] = this.defaultFormDataValues[name];
|
||||
}
|
||||
|
||||
return formData;
|
||||
},
|
||||
captureFormData() {
|
||||
this.initialFormData = JSON.parse(JSON.stringify(this.formData)); // deep copy
|
||||
},
|
||||
// add own betreuer ids to betreuer liste
|
||||
addIds(betreuerListe) {
|
||||
|
||||
for (const idx in betreuerListe) {
|
||||
let betreuer = betreuerListe[idx];
|
||||
|
||||
betreuer.person_id_old = betreuer.person_id;
|
||||
betreuer.betreuerart_kurzbz_old = betreuer.betreuerart_kurzbz;
|
||||
betreuer.betreuer_id = parseInt(idx);
|
||||
}
|
||||
return betreuerListe;
|
||||
},
|
||||
// add the betreuer selected in automomplete to betreuer liste
|
||||
getFormDataWithBetreuer() {
|
||||
let preparedFormData = this.formData;
|
||||
|
||||
preparedFormData.projektarbeit_id = this.projektarbeit_id;
|
||||
if (this.autocompleteSelectedBetreuer) {
|
||||
preparedFormData.person_id = this.autocompleteSelectedBetreuer.person_id;
|
||||
preparedFormData.name = this.autocompleteSelectedBetreuer.name;
|
||||
preparedFormData.vorname = this.autocompleteSelectedBetreuer.vorname;
|
||||
preparedFormData.nachname = this.autocompleteSelectedBetreuer.nachname;
|
||||
}
|
||||
|
||||
return preparedFormData;
|
||||
},
|
||||
// get default values for stunden
|
||||
getDefaultStunden(projekttyp_kurzbz) {
|
||||
let stunden = '0.0';
|
||||
if (projekttyp_kurzbz == 'Bachelor') stunden = this.config.defaultProjektbetreuerStunden;
|
||||
if (projekttyp_kurzbz == 'Diplom') stunden = this.config.defaultProjektbetreuerStundenDiplom;
|
||||
return stunden;
|
||||
},
|
||||
setDefaultStunden(projekttyp_kurzbz) {
|
||||
this.projekttyp_kurzbz = projekttyp_kurzbz;
|
||||
// if form data has not already been modified by user, set the default stunden
|
||||
if (!this.formDataModified()) {
|
||||
let defaultStunden = this.getDefaultStunden(projekttyp_kurzbz);
|
||||
// adapt initial form data so it does not count as modified
|
||||
if (this.initialFormData) this.initialFormData.stunden = defaultStunden;
|
||||
// set default Stunden
|
||||
this.formData.stunden = defaultStunden;
|
||||
}
|
||||
},
|
||||
// check if form data has been modified since initial data has been captured
|
||||
formDataModified() {
|
||||
if (this.autocompleteSelectedBetreuer != null) return true;
|
||||
|
||||
for (const prop in this.initialFormData) {
|
||||
if (typeof this.formData[prop] == 'undefined') return true;
|
||||
if (this.formData[prop] != this.initialFormData[prop]) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
actionNewPerson() {
|
||||
this.$refs.newPersonModal.reset();
|
||||
this.$refs.newPersonModal.open();
|
||||
},
|
||||
actionKontaktdatenBearbeiten() {
|
||||
if (!this.autocompleteSelectedBetreuer) return;
|
||||
this.$refs.kontaktdatenModal.show();
|
||||
},
|
||||
// stuff to do after new person has been saved
|
||||
personSaved(result) {
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getPerson(result))
|
||||
.then(response => {
|
||||
// set the new person in Betreuer autocomplete field
|
||||
this.autocompleteSelectedBetreuer = response.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
},
|
||||
// disable fields which are dependent on Vertrag status
|
||||
disableVertragFields(statusAkzeptiert) {
|
||||
this.vertragFieldsDisabled = statusAkzeptiert;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="stv-details-projektbetreuer h-100 pb-3 row">
|
||||
|
||||
<div :class="this.config.showVertragsdetails ? 'col-9' : 'col-12'">
|
||||
|
||||
<legend>{{this.$p.t('projektarbeit','betreuerGross')}}</legend>
|
||||
|
||||
<core-filter-cmpt
|
||||
ref="projektbetreuerTable"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
:side-menu="false"
|
||||
new-btn-show
|
||||
:new-btn-label="this.$p.t('projektarbeit', 'betreuerGross')"
|
||||
@click:new="actionNewProjektbetreuer"
|
||||
>
|
||||
</core-filter-cmpt>
|
||||
|
||||
<form-form ref="formProjektbetreuer" v-show="betreuerFormOpened" @submit.prevent>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-betreuer"
|
||||
:label="$p.t('projektarbeit', 'betreuer')"
|
||||
type="autocomplete"
|
||||
optionLabel="name"
|
||||
v-model="autocompleteSelectedBetreuer"
|
||||
name="person_id"
|
||||
:suggestions="filteredBetreuer"
|
||||
@complete="searchBetreuer"
|
||||
:min-length="3"
|
||||
:disabled="vertragFieldsDisabled"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-6">
|
||||
<button class="btn btn-outline-secondary" @click="actionNewPerson">{{ $p.t('projektarbeit', 'neuePersonAnlegen') }}</button>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<button class="btn btn-outline-secondary float-end" @click="actionKontaktdatenBearbeiten">{{ $p.t('projektarbeit', 'kontaktdatenBearbeiten') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektbetreuer-betreuerart"
|
||||
:label="$p.t('projektarbeit', 'betreuerart')"
|
||||
type="select"
|
||||
v-model="formData.betreuerart_kurzbz"
|
||||
name="betreuerart_kurzbz"
|
||||
>
|
||||
<option
|
||||
v-for="art in arrBetreuerart"
|
||||
:key="art.betreuerart_kurzbz"
|
||||
:value="art.betreuerart_kurzbz"
|
||||
>
|
||||
{{art.beschreibung}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
container-class="stv-details-projektbetreuer-note"
|
||||
:label="$p.t('projektarbeit', 'note')"
|
||||
type="select"
|
||||
v-model="formData.note"
|
||||
name="note"
|
||||
>
|
||||
<option :value="null"> -- {{$p.t('fehlermonitoring', 'keineAuswahl')}} -- </option>
|
||||
<option
|
||||
v-for="note in arrNoten"
|
||||
:key="note.note"
|
||||
:value="note.note"
|
||||
>
|
||||
{{note.bezeichnung}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-6">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-stunden"
|
||||
type="text"
|
||||
name="stunden"
|
||||
:label="$p.t('projektarbeit', 'stunden')"
|
||||
:disabled="vertragFieldsDisabled"
|
||||
v-model="formData.stunden"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<form-input
|
||||
container-class="stv-details-projektarbeit-stundensatz"
|
||||
type="text"
|
||||
name="stundensatz"
|
||||
:label="$p.t('projektarbeit', 'stundensatz')"
|
||||
:disabled="vertragFieldsDisabled"
|
||||
v-model="formData.stundensatz"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form-form>
|
||||
|
||||
<button class="btn btn-primary" v-show="betreuerFormOpened" @click="saveProjektbetreuer">
|
||||
{{ $p.t('projektarbeit', 'betreuerSpeichern') }}
|
||||
</button>
|
||||
<!-- <div class = "mt-5" v-if="beurteilungDownloadLink !== null">
|
||||
<div class="mb-1">
|
||||
<a :href="beurteilungDownloadLink" class="btn btn-primary d-block" :class="{ 'disabled' : beurteilungDownloadLink === ''}">
|
||||
{{ $p.t('projektarbeit', 'projektbeurteilungErstellen') }}
|
||||
</a>
|
||||
</div>
|
||||
{{ autocompleteSelectedBetreuer?.person_id && beurteilungDownloadLink === '' ? $p.t('projektarbeit', 'projektarbeitNochNichtBeurteilt') : ''}}
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<vertrag ref="vertrag"
|
||||
:vertrag_id="autocompleteSelectedBetreuer?.vertrag_id"
|
||||
:person_id="autocompleteSelectedBetreuer?.person_id"
|
||||
:betreuerProjektarbeit="initialFormData"
|
||||
@vertragsstatusChanged="disableVertragFields">
|
||||
</vertrag>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Modal: new Person modal -->
|
||||
<new-person ref="newPersonModal" :personOnly="true" @saved="personSaved"></new-person>
|
||||
|
||||
<!--Modal: KontaktdatenModal -->
|
||||
<bs-modal
|
||||
ref="kontaktdatenModal"
|
||||
dialog-class="modal-xl modal-dialog-scrollable"
|
||||
v-if="autocompleteSelectedBetreuer && autocompleteSelectedBetreuer.person_id">
|
||||
|
||||
<template #title>
|
||||
<p class="fw-bold mt-3">{{$p.t('projektarbeit', 'kontaktdatenBearbeiten')}}</p>
|
||||
</template>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<contact ref="contact" :uid="autocompleteSelectedBetreuer.person_id">
|
||||
</contact>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</bs-modal>
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
import CoreForm from '../../../../Form/Form.js';
|
||||
import FormInput from '../../../../Form/Input.js';
|
||||
import ApiVertrag from '../../../../../api/factory/stv/vertrag.js';
|
||||
|
||||
export default{
|
||||
name: "ProjektarbeitVertrag",
|
||||
components: {
|
||||
CoreForm,
|
||||
FormInput
|
||||
},
|
||||
emits: [
|
||||
'canceledVertrag',
|
||||
'vertragsstatusChanged'
|
||||
],
|
||||
props: {
|
||||
vertrag_id: Number,
|
||||
person_id: Number,
|
||||
betreuerProjektarbeit: Object
|
||||
},
|
||||
|
||||
inject: {
|
||||
showVertragsdetails: {
|
||||
from: 'configShowVertragsdetails',
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return{
|
||||
data: {
|
||||
vertragsstatus: null,
|
||||
vertragsstunden: null,
|
||||
vertragsstunden_studiensemester_kurzbz: null
|
||||
},
|
||||
// status names for stages of Vertrag ("constants")
|
||||
vertragsstatus_akzeptiert: 'Akzeptiert',
|
||||
vertragsstatus_geaendert:'Geändert',
|
||||
vertragsstatus_storniert: 'Storno'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
vertrag_id:
|
||||
{
|
||||
//deep: true,
|
||||
handler(newVal, oldVal) {
|
||||
this.resetForm();
|
||||
if (newVal !== null && newVal !== undefined) this.getVertrag();
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
vertragsstatus() {
|
||||
// not show Vertragsstatus if no data
|
||||
if (!this.data?.vertragsstatus || !this.betreuerProjektarbeit?.betreuerart_kurzbz) return;
|
||||
|
||||
const betragVertrag = Number(this.data.betrag) || 0;
|
||||
const stundenVertrag = Number(this.data.vertragsstunden) || 0;
|
||||
|
||||
const semStunden = Number(this.betreuerProjektarbeit.stunden) || 0;
|
||||
const stundensatz = Number(this.betreuerProjektarbeit.stundensatz) || 0;
|
||||
|
||||
const kostenAktuell = semStunden * stundensatz;
|
||||
|
||||
// Vertragsstunden amount should be same as Semesterstunden amount, otherwise there has been a change
|
||||
let vertragsstatus = (stundenVertrag !== semStunden || betragVertrag !== kostenAktuell)
|
||||
? this.vertragsstatus_geaendert
|
||||
: (this.data.vertragsstatus || '');
|
||||
|
||||
// vertragsstatus changed to "akzeptiert"
|
||||
this.$emit('vertragsstatusChanged', vertragsstatus == this.vertragsstatus_akzeptiert);
|
||||
|
||||
return vertragsstatus;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getVertrag() {
|
||||
if (this.showVertragsdetails === false)
|
||||
return;
|
||||
|
||||
if (!this.vertrag_id)
|
||||
return;
|
||||
|
||||
this.$api.call(ApiVertrag.getVertrag(this.vertrag_id))
|
||||
.then(result => {
|
||||
if (result.data.vertragsstatus != this.vertragsstatus_storniert) {
|
||||
this.data = result.data;
|
||||
}
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
|
||||
cancelVertrag() {
|
||||
this.$fhcAlert
|
||||
.confirmDelete()
|
||||
.then(result => result
|
||||
? {vertrag_id: this.vertrag_id, person_id: this.person_id}
|
||||
: Promise.reject({handled: true}))
|
||||
.then(result => {
|
||||
return this.$api.call(ApiVertrag.cancelVertrag({vertrag_id: this.vertrag_id, person_id: this.person_id}))
|
||||
})
|
||||
.then(result => {
|
||||
this.resetForm();
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
|
||||
this.$emit('canceledVertrag');
|
||||
// vertragsstatus not "akzeptiert" anymore
|
||||
this.$emit('vertragsstatusChanged', false);
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
resetForm() {
|
||||
this.data = {
|
||||
vertrag_id: null,
|
||||
vertragsstatus: null,
|
||||
vertragsstunden: null,
|
||||
vertragsstunden_studiensemester_kurzbz: null
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<core-form ref="form">
|
||||
<fieldset class="overflow-hidden" v-if="showVertragsdetails">
|
||||
<legend>
|
||||
{{$p.t('lehre', 'vertragsdetails')}}
|
||||
</legend>
|
||||
<div class="mb-3">
|
||||
{{ betreuerProjektarbeit?.betreuerart_kurzbz && betreuerProjektarbeit?.vertrag_id == null ? ' – '+$p.t('lehre', 'nochKeinVertrag') : '' }}
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
{{ $p.t('lehre', 'vertragsstatus') }}: {{ vertragsstatus }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
{{$p.t('lehre', 'vertragurfassung')}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<div class="col-12">
|
||||
{{ $p.t('lehre', 'semesterstunden') }}: {{ data.vertragsstunden }}
|
||||
<br>
|
||||
<span class="text-capitalize">{{ $p.t('lehre', 'studiensemester') }}</span>: {{ data.vertragsstunden_studiensemester_kurzbz }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-3" v-if="data?.vertragsstatus">
|
||||
<div class="col-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary"
|
||||
:disabled="vertragsstatus == vertragsstatus_storniert"
|
||||
@click="cancelVertrag"
|
||||
>
|
||||
{{ $p.t('lehre', 'vertragStornieren') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</core-form>
|
||||
`
|
||||
};
|
||||
@@ -1,18 +1,28 @@
|
||||
import {CoreFilterCmpt} from "../../filter/Filter.js";
|
||||
import ListNew from './List/New.js';
|
||||
import ListFilter from './List/Filter.js';
|
||||
|
||||
import draggable from '../../../directives/draggable.js';
|
||||
|
||||
export default {
|
||||
name: "ListPrestudents",
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
ListNew
|
||||
ListNew,
|
||||
ListFilter
|
||||
},
|
||||
directives: {
|
||||
draggable
|
||||
},
|
||||
inject: {
|
||||
'lists': {
|
||||
lists: {
|
||||
from: 'lists',
|
||||
required: true
|
||||
},
|
||||
$reloadList: {
|
||||
from: '$reloadList',
|
||||
required: true
|
||||
},
|
||||
currentSemester: {
|
||||
from: 'currentSemester',
|
||||
required: true
|
||||
@@ -51,8 +61,12 @@ export default {
|
||||
{title:"Vornamen", field:"vornamen", visible:false, headerFilter: true},
|
||||
{title:"TitelPost", field:"titelpost", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title:"Ersatzkennzeichen", field:"ersatzkennzeichen", headerFilter: true},
|
||||
{title:"Geburtsdatum", field:"gebdatum", formatter:dateFormatter,
|
||||
headerFilter: true, headerFilterFunc: function(headerValue, rowValue, rowData, filterParams) {
|
||||
{
|
||||
title: "Geburtsdatum",
|
||||
field: "gebdatum",
|
||||
formatter: dateFormatter,
|
||||
headerFilter: true,
|
||||
headerFilterFunc(headerValue, rowValue) {
|
||||
const matches = headerValue.match(/^(([0-9]{2})\.)?([0-9]{2})\.([0-9]{4})?$/);
|
||||
let comparestr = headerValue;
|
||||
if(matches !== null) {
|
||||
@@ -119,7 +133,7 @@ export default {
|
||||
{
|
||||
return Promise.resolve({ data: []});
|
||||
}
|
||||
return this.$api.call({url, params});
|
||||
return this.$api.call({method: 'post', url, params});
|
||||
},
|
||||
ajaxResponse: (url, params, response) => {
|
||||
return response?.data;
|
||||
@@ -157,14 +171,63 @@ export default {
|
||||
],
|
||||
focusObj: null, // TODO(chris): this should be in the filter component
|
||||
lastSelected: null,
|
||||
filterKontoCount0: undefined,
|
||||
filterKontoMissingCounter: undefined,
|
||||
filter: [],
|
||||
count: 0,
|
||||
filteredcount: 0,
|
||||
selectedcount: 0,
|
||||
currentEndpointRawUrl: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
countsToHTML: function() {
|
||||
return this.$p.t('global/ausgewaehlt')
|
||||
+ ': <strong>' + (this.selectedcount || 0) + '</strong>'
|
||||
+ ' | '
|
||||
+ this.$p.t('global/gefiltert')
|
||||
+ ': '
|
||||
+ '<strong>' + (this.filteredcount || 0) + '</strong>'
|
||||
+ ' | '
|
||||
+ this.$p.t('global/gesamt')
|
||||
+ ': <strong>' + (this.count || 0) + '</strong>';
|
||||
},
|
||||
selectedDragObject() {
|
||||
return this.selected.map(item => {
|
||||
let type, id;
|
||||
if (item.uid) {
|
||||
type = 'student';
|
||||
id = item.uid;
|
||||
} else if (item.prestudent_id) {
|
||||
type = 'prestudent';
|
||||
id = item.prestudent_id;
|
||||
} else if (item.person_id) {
|
||||
type = 'person';
|
||||
id = item.person_id;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
type,
|
||||
id
|
||||
};
|
||||
});
|
||||
},
|
||||
downloadConfig() {
|
||||
return {
|
||||
csv: {
|
||||
formatter: 'csv',
|
||||
file: this.fileString,
|
||||
options: {
|
||||
delimiter: ';',
|
||||
bom: true,
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
fileString() {
|
||||
let today = new Date().toLocaleDateString('en-GB')
|
||||
.replace(/\//g, '_');
|
||||
return "StudentList_" + today + ".csv";
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
reload() {
|
||||
this.$refs.table.reloadTable();
|
||||
@@ -172,10 +235,19 @@ export default {
|
||||
actionNewPrestudent() {
|
||||
this.$refs.new.open();
|
||||
},
|
||||
rowSelectionChanged(data) {
|
||||
rowSelectionChanged(data, rows) {
|
||||
this.selectedcount = data.length;
|
||||
this.lastSelected = this.selected;
|
||||
this.$emit('update:selected', data);
|
||||
|
||||
// set selected elements draggable
|
||||
const tableEl = this.$refs.table?.$refs?.table;
|
||||
if (tableEl) {
|
||||
const oldDragables = tableEl.querySelectorAll('[draggable]');
|
||||
for (const draggable of oldDragables)
|
||||
draggable.removeAttribute('draggable');
|
||||
}
|
||||
rows.forEach(row => row.getElement().draggable = true);
|
||||
},
|
||||
autoSelectRows(data) {
|
||||
if (this.lastSelected) {
|
||||
@@ -194,6 +266,10 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
updateFilter(filter) {
|
||||
this.filter = filter;
|
||||
this.updateUrl();
|
||||
},
|
||||
updateUrl(endpoint, first) {
|
||||
this.lastSelected = first ? undefined : this.selected;
|
||||
|
||||
@@ -214,14 +290,9 @@ export default {
|
||||
encodeURIComponent(this.currentSemester)
|
||||
);
|
||||
|
||||
const params = {}, filter = {};
|
||||
if (this.filterKontoCount0)
|
||||
filter.konto_count_0 = this.filterKontoCount0;
|
||||
if (this.filterKontoMissingCounter)
|
||||
filter.konto_missing_counter = this.filterKontoMissingCounter;
|
||||
|
||||
if (filter.konto_count_0 || filter.konto_missing_counter)
|
||||
params.filter = filter;
|
||||
const params = {};
|
||||
if (this.filter.length)
|
||||
params.filter = this.filter;
|
||||
|
||||
if (!this.$refs.table.tableBuilt) {
|
||||
if (!this.$refs.table.tabulator) {
|
||||
@@ -234,14 +305,22 @@ export default {
|
||||
} else
|
||||
this.$refs.table.tabulator.setData(endpoint.url, params);
|
||||
},
|
||||
dragCleanup(evt) {
|
||||
if (evt.dataTransfer.dropEffect == 'none')
|
||||
return; // aborted or wrong target
|
||||
|
||||
this.$reloadList();
|
||||
},
|
||||
onKeydown(e) { // TODO(chris): this should be in the filter component
|
||||
if (!this.focusObj)
|
||||
return;
|
||||
|
||||
var next;
|
||||
switch (e.code) {
|
||||
case 'Enter':
|
||||
case 'Space':
|
||||
e.preventDefault();
|
||||
const e2 = new Event('click', e);
|
||||
var e2 = new Event('click', e);
|
||||
e2.altKey = e.altKey;
|
||||
e2.ctrlKey = e.ctrlKey;
|
||||
e2.shiftKey = e.shiftKey;
|
||||
@@ -250,13 +329,13 @@ export default {
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
e.preventDefault();
|
||||
var next = this.focusObj.previousElementSibling;
|
||||
next = this.focusObj.previousElementSibling;
|
||||
if (next)
|
||||
this.changeFocus(this.focusObj, next);
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
e.preventDefault();
|
||||
var next = this.focusObj.nextElementSibling;
|
||||
next = this.focusObj.nextElementSibling;
|
||||
if (next)
|
||||
this.changeFocus(this.focusObj, next);
|
||||
break;
|
||||
@@ -296,24 +375,19 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
countsToHTML: function() {
|
||||
return this.$p.t('global/ausgewaehlt')
|
||||
+ ': <strong>' + (this.selectedcount || 0) + '</strong>'
|
||||
+ ' | '
|
||||
+ this.$p.t('global/gefiltert')
|
||||
+ ': '
|
||||
+ '<strong>' + (this.filteredcount || 0) + '</strong>'
|
||||
+ ' | '
|
||||
+ this.$p.t('global/gesamt')
|
||||
+ ': <strong>' + (this.count || 0) + '</strong>';
|
||||
}
|
||||
},
|
||||
// TODO(chris): focusin, focusout, keydown and tabindex should be in the filter component
|
||||
// TODO(chris): filter component column chooser has no accessibilty features
|
||||
template: `
|
||||
<div class="stv-list h-100 pt-3">
|
||||
<div class="tabulator-container d-flex flex-column h-100" :class="{'has-filter': filterKontoCount0 || filterKontoMissingCounter}" tabindex="0" @focusin="onFocus" @keydown="onKeydown">
|
||||
<div
|
||||
class="tabulator-container d-flex flex-column h-100"
|
||||
:class="{'has-filter': filter.length}"
|
||||
tabindex="0"
|
||||
@focusin="onFocus"
|
||||
@keydown="onKeydown"
|
||||
v-draggable:copyLink.capture="selectedDragObject"
|
||||
@dragend="dragCleanup"
|
||||
>
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
:description="countsToHTML"
|
||||
@@ -322,6 +396,7 @@ export default {
|
||||
table-only
|
||||
:side-menu="false"
|
||||
reload
|
||||
:download="downloadConfig"
|
||||
` + /* TODO(chris): Ausgeblendet für Testing
|
||||
new-btn-show
|
||||
*/`
|
||||
@@ -331,29 +406,7 @@ export default {
|
||||
<template #filter>
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="input-group mb-3">
|
||||
<label class="input-group-text col-4" for="stv-list-filter-konto-count-0">{{ $p.t('stv/konto_filter_count_0') }}</label>
|
||||
<select class="form-select" id="stv-list-filter-konto-count-0" v-model="filterKontoCount0" @input="$nextTick(updateUrl)">
|
||||
<option v-for="typ in lists.buchungstypen" :key="typ.buchungstyp_kurzbz" :value="typ.buchungstyp_kurzbz">
|
||||
{{ typ.beschreibung }}
|
||||
</option>
|
||||
</select>
|
||||
<button v-if="filterKontoCount0" class="btn btn-outline-secondary" @click="filterKontoCount0 = undefined; updateUrl()">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<label class="input-group-text col-4" for="stv-list-filter-konto-missing-counter">{{ $p.t('stv/konto_filter_missing_counter') }}</label>
|
||||
<select class="form-select" id="stv-list-filter-konto-missing-counter" v-model="filterKontoMissingCounter" @input="$nextTick(updateUrl)">
|
||||
<option value="alle">{{ $p.t('stv/konto_all_types') }}</option>
|
||||
<option v-for="typ in lists.buchungstypen" :key="typ.buchungstyp_kurzbz" :value="typ.buchungstyp_kurzbz">
|
||||
{{ typ.beschreibung }}
|
||||
</option>
|
||||
</select>
|
||||
<button v-if="filterKontoMissingCounter" class="btn btn-outline-secondary" @click="filterKontoMissingCounter = undefined; updateUrl()">
|
||||
<i class="fa fa-times"></i>
|
||||
</button>
|
||||
</div>
|
||||
<list-filter @change="updateFilter" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import FilterItem from './Filter/Item.js';
|
||||
|
||||
import ApiStvApp from '../../../../api/factory/stv/app.js';
|
||||
|
||||
export default {
|
||||
name: "ListPrestudentsFilter",
|
||||
components: {
|
||||
FilterItem
|
||||
},
|
||||
emits: [
|
||||
'change'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
filters: [],
|
||||
filterConfig: [// TODO(chris): get from BE!
|
||||
{
|
||||
name: 'stv/konto_filter_count_0',
|
||||
type: 'konto',
|
||||
fixed: {
|
||||
missing: true,
|
||||
usestdsem: true
|
||||
},
|
||||
dynamic: {
|
||||
buchungstyp_kurzbz: {
|
||||
type: 'select',
|
||||
values: {
|
||||
test1: 'Test1',
|
||||
test2: 'Test2'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'stv/konto_filter_missing_counter',
|
||||
type: 'konto_counter',
|
||||
dynamic: {
|
||||
buchungstyp_kurzbz: {
|
||||
type: 'select',
|
||||
values: {
|
||||
test1: 'Test1',
|
||||
test2: 'Test2'
|
||||
}
|
||||
},
|
||||
samestg: {
|
||||
type: 'bool',
|
||||
label: 'stv/konto',
|
||||
default: true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cleanFilters() {
|
||||
return this.filters.filter(filter => {
|
||||
if (!filter.type)
|
||||
return false;
|
||||
if (Object.values(filter).some(v => v === undefined))
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
cleanFilters(n) {
|
||||
this.$emit('change', n);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add() {
|
||||
this.filters.push({});
|
||||
},
|
||||
remove(index) {
|
||||
this.filters.splice(index, 1);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiStvApp.configFilter())
|
||||
.then(result => {
|
||||
this.filterConfig = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
template: /* html */`
|
||||
<div class="stv-list-filter h-100">
|
||||
<button class="btn btn-outline-dark" type="button" @click="add">
|
||||
<span class="fa-solid fa-plus" aria-hidden="true"></span>
|
||||
{{ $p.t('filter/filter') }}
|
||||
</button>
|
||||
<filter-item
|
||||
v-for="(filter, i) in filters"
|
||||
:key="i"
|
||||
v-model="filters[i]"
|
||||
:filter-config="filterConfig"
|
||||
class="mt-3"
|
||||
@remove="remove(i)"
|
||||
/>
|
||||
</div>`
|
||||
};
|
||||
@@ -0,0 +1,113 @@
|
||||
export default {
|
||||
name: "FilterItem",
|
||||
props: {
|
||||
modelValue: Object,
|
||||
filterConfig: Array
|
||||
},
|
||||
emits: [
|
||||
'update:modelValue',
|
||||
'remove'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
//type: this.modelValue.type
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
value: {
|
||||
get() {
|
||||
return this.modelValue;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:modelValue', value);
|
||||
}
|
||||
},
|
||||
filterid: {
|
||||
get() {
|
||||
return this.modelValue.filterid
|
||||
},
|
||||
set(filterid) {
|
||||
const config = this.filterConfig.find(config => config.id == filterid);
|
||||
const dynamic = Object.fromEntries(
|
||||
Object.keys(config.dynamic || {}).map(key => {
|
||||
return [
|
||||
key,
|
||||
config.dynamic[key].default
|
||||
];
|
||||
})
|
||||
);
|
||||
this.value = {
|
||||
filterid,
|
||||
type: config.type,
|
||||
...(config.fixed || {}),
|
||||
...dynamic
|
||||
};
|
||||
}
|
||||
},
|
||||
currentConfig() {
|
||||
return this.filterConfig.find(config => config.id == this.filterid);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
update() {
|
||||
this.$emit('update:modelValue', this.value);
|
||||
}
|
||||
},
|
||||
template: /* html */`
|
||||
<div class="stv-list-filter-item input-group">
|
||||
<label
|
||||
class="input-group-text col-4"
|
||||
for="stv-list-filter-konto-count-0"
|
||||
>
|
||||
{{ $p.t('stv/filter_for') }}
|
||||
</label>
|
||||
<select
|
||||
v-model="filterid"
|
||||
id="stv-list-filter-konto-count-0"
|
||||
class="form-select"
|
||||
>
|
||||
<option
|
||||
v-for="(filter, i) in filterConfig"
|
||||
:key="i"
|
||||
:value="filter.id"
|
||||
>
|
||||
{{ filter.label }}
|
||||
</option>
|
||||
</select>
|
||||
<template v-for="(conf, key) in currentConfig?.dynamic" :key="key">
|
||||
<select
|
||||
v-if="conf.type == 'select'"
|
||||
v-model="modelValue[key]"
|
||||
class="form-select"
|
||||
@input="update"
|
||||
>
|
||||
<option
|
||||
v-for="(label, value) in conf.values"
|
||||
:key="conf.value_key ? label[conf.value_key] : value"
|
||||
:value="conf.value_key ? label[conf.value_key] : value"
|
||||
>
|
||||
{{ conf.label_key ? label[conf.label_key] : label }}
|
||||
</option>
|
||||
</select>
|
||||
<template v-else-if="conf.type == 'bool'">
|
||||
<div class="input-group-text">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
v-model="modelValue[key]"
|
||||
type="checkbox"
|
||||
class="form-check-input me-1"
|
||||
@input="update"
|
||||
>
|
||||
{{ conf.label }}
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
<button
|
||||
class="btn btn-outline-secondary"
|
||||
:title="$p.t('ui/entfernen')"
|
||||
:aria-label="$p.t('ui/entfernen')"
|
||||
@click="$emit('remove')"
|
||||
><i class="fa fa-times"></i></button>
|
||||
</div>`
|
||||
};
|
||||
@@ -10,7 +10,7 @@ import ApiStvStudents from '../../../../api/factory/stv/students.js';
|
||||
var _uuid = 0;
|
||||
const FORMDATA_DEFAULT = {
|
||||
address: {
|
||||
func: 0,
|
||||
func: 1,
|
||||
nation: 'A'
|
||||
},
|
||||
geburtsnation: 'A',
|
||||
@@ -33,7 +33,9 @@ export default {
|
||||
inject: [
|
||||
'lists'
|
||||
],
|
||||
emits: ['saved'],
|
||||
props: {
|
||||
personOnly: Boolean,
|
||||
studiengangKz: Number,
|
||||
studiensemesterKurzbz: String
|
||||
},
|
||||
@@ -108,7 +110,7 @@ export default {
|
||||
return;
|
||||
|
||||
this.abortController.suggestions = new AbortController();
|
||||
|
||||
|
||||
this.$api
|
||||
.call(ApiStvStudents.check({
|
||||
vorname: this.formData.vorname,
|
||||
@@ -119,6 +121,11 @@ export default {
|
||||
})
|
||||
.then(result => this.suggestions = result.data)
|
||||
.catch(error => {
|
||||
|
||||
if (error.code == 'ERR_BAD_REQUEST') {
|
||||
return this.suggestions = [];
|
||||
}
|
||||
|
||||
// NOTE(chris): repeat request
|
||||
if (error.code != "ERR_CANCELED")
|
||||
window.setTimeout(this.loadSuggestions, 100);
|
||||
@@ -191,14 +198,22 @@ export default {
|
||||
if (data.studiensemester_kurzbz === undefined)
|
||||
data.studiensemester_kurzbz = this.studiensemesterKurzbz;
|
||||
|
||||
// TODO(chris): move to fhcapi.factory
|
||||
this.$refs.form
|
||||
.post('api/frontend/v1/stv/student/add', data)
|
||||
.then(result => {
|
||||
this.$fhcAlert.alertSuccess('Gespeichert');
|
||||
this.$refs.modal.hide();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
data.personOnly = this.personOnly;
|
||||
|
||||
this.$refs.form.call(
|
||||
ApiStvStudents.add(data)
|
||||
)
|
||||
.then(result => {
|
||||
this.$emit('saved', result.data);
|
||||
this.$fhcAlert.alertSuccess('Gespeichert');
|
||||
this.$refs.modal.hide();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
setPerson(suggestion)
|
||||
{
|
||||
this.person = suggestion;
|
||||
this.formData.address.func = -1;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -215,7 +230,7 @@ export default {
|
||||
<fhc-form ref="form" class="stv-list-new" @submit.prevent="send">
|
||||
<bs-modal ref="modal" dialog-class="modal-lg modal-dialog-scrollable" @hidden-bs-modal="reset">
|
||||
<template #title>
|
||||
InteressentIn anlegen
|
||||
{{ personOnly ? $p.t('person', 'personAnlegen') : $p.t('lehre', 'interessentAnlegen') }}
|
||||
</template>
|
||||
<template #default>
|
||||
|
||||
@@ -225,36 +240,38 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Nachname*"
|
||||
:label="$p.t('person', 'nachname')+'*'"
|
||||
type="text"
|
||||
id="stv-list-new-nachname"
|
||||
name="nachname"
|
||||
v-model="formDataPerson['nachname']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
@input="loadSuggestions"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Vorname"
|
||||
:label="$p.t('person', 'vorname')"
|
||||
type="text"
|
||||
:id="'stv-list-new-vorname-' + uuid"
|
||||
name="vorname"
|
||||
v-model="formDataPerson['vorname']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
@input="loadSuggestions"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Geburtsdatum"
|
||||
:label="$p.t('person', 'geburtsdatum')"
|
||||
type="datepicker"
|
||||
uid="stv-list-new-gebdatum"
|
||||
name="gebdatum"
|
||||
v-model="formDataPerson['gebdatum']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
@update:model-value="loadSuggestions"
|
||||
text-input
|
||||
auto-apply
|
||||
@@ -267,13 +284,13 @@ export default {
|
||||
</div>
|
||||
<!-- TODO(chris): more details -->
|
||||
<table class="table caption-top table-striped table-hover">
|
||||
<caption>Prüfung ob Person bereits existiert</caption>
|
||||
<caption>{{ $p.t('person', 'personExistiertPruefung') }}</caption>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(suggestion, index) in suggestions"
|
||||
:key="suggestion.person_id"
|
||||
:class="{'active': index == 2}"
|
||||
@click="(index == 2) ? suggestions.shift() : person=suggestion"
|
||||
@click="(index == 2) ? suggestions.shift() : setPerson(suggestion)"
|
||||
v-accessibility:tab.vertical
|
||||
>
|
||||
<td>{{suggestion.vorname + ' ' + suggestion.nachname}}</td>
|
||||
@@ -286,34 +303,34 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Anrede"
|
||||
:label="$p.t('person', 'anrede')"
|
||||
type="text"
|
||||
id="stv-list-new-anrede"
|
||||
name="anrede"
|
||||
v-model="formDataPerson['anrede']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Titel (Pre)"
|
||||
:label="$p.t('person', 'titelPre')"
|
||||
type="text"
|
||||
id="stv-list-new-titelpre"
|
||||
name="titelpre"
|
||||
v-model="formDataPerson['titelpre']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Titel (Post)"
|
||||
:label="$p.t('person', 'titelPost')"
|
||||
type="text"
|
||||
id="stv-list-new-titelpost"
|
||||
name="titelpost"
|
||||
v-model="formDataPerson['titelpost']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
@@ -321,36 +338,38 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Nachname*"
|
||||
:label="$p.t('person', 'nachname')+'*'"
|
||||
type="text"
|
||||
id="stv-list-new-nachname"
|
||||
name="nachname"
|
||||
v-model="formDataPerson['nachname']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
@input="loadSuggestions"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Vorname"
|
||||
:label="$p.t('person', 'vorname')"
|
||||
type="text"
|
||||
id="stv-list-new-vorname"
|
||||
name="vorname"
|
||||
v-model="formDataPerson['vorname']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
@input="loadSuggestions"
|
||||
:min-length="3"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Weitere Vornamen"
|
||||
:label="$p.t('person', 'weitereVornamen')"
|
||||
type="text"
|
||||
id="stv-list-new-vornamen"
|
||||
name="vornamen"
|
||||
v-model="formDataPerson['vornamen']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
@@ -358,12 +377,12 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Wahlname"
|
||||
:label="$p.t('person', 'wahlname')"
|
||||
type="text"
|
||||
id="stv-list-new-wahlname"
|
||||
name="wahlname"
|
||||
v-model="formDataPerson['wahlname']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
@@ -371,24 +390,24 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Geschlecht*"
|
||||
:label="$p.t('person', 'geschlecht')+'*'"
|
||||
type="select"
|
||||
id="stv-list-new-geschlecht"
|
||||
name="geschlecht"
|
||||
v-model="formDataPerson['geschlecht']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
>
|
||||
<option v-for="geschlecht in lists.geschlechter" :key="geschlecht.geschlecht" :value="geschlecht.geschlecht">{{geschlecht.bezeichnung}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Geburtsdatum"
|
||||
:label="$p.t('person', 'geburtsdatum')"
|
||||
type="datepicker"
|
||||
uid="stv-list-new-gebdatum"
|
||||
name="gebdatum"
|
||||
v-model="formDataPerson['gebdatum']"
|
||||
:disabled="person"
|
||||
:disabled="!!person"
|
||||
@update:model-value="loadSuggestions"
|
||||
text-input
|
||||
auto-apply
|
||||
@@ -400,7 +419,7 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="person" class="row">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
@@ -408,19 +427,19 @@ export default {
|
||||
name="address[func]"
|
||||
v-model="formData['address']['func']"
|
||||
>
|
||||
<option value="-1">Bestehende Adresse überschreiben</option>
|
||||
<option value="1">Adresse hinzufügen</option>
|
||||
<option value="0">Adresse nicht anlegen</option>
|
||||
<option value="-1" v-if="person">{{ $p.t('person', 'bestehendeAdresseUeberschreiben') }}</option>
|
||||
<option value="1">{{ $p.t('person', 'adresseHinzufuegen') }}</option>
|
||||
<option value="0">{{ $p.t('person', 'adresseNichtAnlegen') }}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<fieldset v-if="!person || formData['address']['func']">
|
||||
<fieldset v-if="formData['address']['func'] != 0">
|
||||
<legend>Adresse</legend>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Land"
|
||||
:label="$p.t('person', 'land')"
|
||||
type="select"
|
||||
id="stv-list-new-address-nation"
|
||||
name="address[nation]"
|
||||
@@ -434,7 +453,7 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="PLZ"
|
||||
:label="$p.t('person', 'plz')"
|
||||
type="text"
|
||||
id="stv-list-new-address-plz"
|
||||
name="address[plz]"
|
||||
@@ -445,18 +464,18 @@ export default {
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Gemeinde"
|
||||
:label="$p.t('person', 'gemeinde')"
|
||||
type="select"
|
||||
v-if="formData['address']['nation'] == 'A'"
|
||||
id="stv-list-new-address-gemeinde"
|
||||
name="address[gemeinde]"
|
||||
v-model="formData['address']['gemeinde']"
|
||||
>
|
||||
<option v-if="!gemeinden.length" disabled>Bitte gültige PLZ wählen</option>
|
||||
<option v-if="!gemeinden.length" disabled>$p.t('ui', 'bittePlzWaehlen')</option>
|
||||
<option v-for="gemeinde in gemeinden" :key="gemeinde.name" :value="gemeinde.name">{{gemeinde.name}}</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
label="Gemeinde"
|
||||
:label="$p.t('person', 'gemeinde')"
|
||||
type="text"
|
||||
v-else
|
||||
id="stv-list-new-address-gemeinde"
|
||||
@@ -467,7 +486,7 @@ export default {
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Ort"
|
||||
:label="$p.t('person', 'ort')"
|
||||
type="select"
|
||||
v-if="formData['address']['nation'] == 'A'"
|
||||
id="stv-list-new-address-ort"
|
||||
@@ -478,7 +497,7 @@ export default {
|
||||
<option v-for="ort in orte" :key="ort.ortschaftsname" :value="ort.ortschaftsname">{{ort.ortschaftsname}}</option>
|
||||
</form-input>
|
||||
<form-input
|
||||
label="Ort"
|
||||
:label="$p.t('person', 'ort')"
|
||||
type="text"
|
||||
v-else
|
||||
id="stv-list-new-address-ort"
|
||||
@@ -491,7 +510,7 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-12 mb-3">
|
||||
<form-input
|
||||
label="Adresse"
|
||||
:label="$p.t('person', 'adresse')"
|
||||
type="text"
|
||||
id="stv-list-new-address-address"
|
||||
name="address[address]"
|
||||
@@ -505,7 +524,7 @@ export default {
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Geburtsnation"
|
||||
:label="$p.t('person', 'geburtsnation')"
|
||||
type="select"
|
||||
id="stv-list-new-geburtsnation"
|
||||
name="geburtsnation" class="form-select"
|
||||
@@ -516,7 +535,7 @@ export default {
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Staatsbürgerschaft"
|
||||
:label="$p.t('person', 'staatsbuergerschaft')"
|
||||
type="select"
|
||||
id="stv-list-new-staatsbuergerschaft"
|
||||
name="staatsbuergerschaft"
|
||||
@@ -539,7 +558,7 @@ export default {
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Telefon"
|
||||
:label="$p.t('person', 'telefon')"
|
||||
type="text"
|
||||
id="stv-list-new-telefon"
|
||||
name="telefon"
|
||||
@@ -549,7 +568,7 @@ export default {
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Mobil"
|
||||
:label="$p.t('person', 'mobil')"
|
||||
type="text"
|
||||
id="stv-list-new-mobil"
|
||||
name="mobil"
|
||||
@@ -558,126 +577,128 @@ export default {
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Letzte Ausbildung"
|
||||
type="select"
|
||||
id="stv-list-new-letzteausbildung"
|
||||
name="letzteausbildung"
|
||||
v-model="formData['letzteausbildung']"
|
||||
>
|
||||
<option v-for="ausbildung in lists.ausbildungen" :key="ausbildung.ausbildungcode" :value="ausbildung.ausbildungcode">{{ausbildung.ausbildungbez}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Ausbildungsart"
|
||||
type="text"
|
||||
id="stv-list-new-ausbildungsart"
|
||||
name="ausbildungsart"
|
||||
v-model="formDataPerson['ausbildungsart']"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 mb-3">
|
||||
<form-input
|
||||
label="Anmerkungen"
|
||||
type="textarea"
|
||||
id="stv-list-new-anmerkungen"
|
||||
name="anmerkungen"
|
||||
v-model="formDataPerson['anmerkungen']"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Studiengang*"
|
||||
type="select"
|
||||
id="stv-list-new-studiengang_kz"
|
||||
name="studiengang_kz"
|
||||
v-model="formDataStg"
|
||||
>
|
||||
<option v-for="stg in lists.active_stgs" :key="stg.studiengang_kz" :value="stg.studiengang_kz">{{stg.kuerzel}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Studiensemester*"
|
||||
type="select"
|
||||
id="stv-list-new-studiensemester_kurzbz"
|
||||
name="studiensemester_kurzbz"
|
||||
v-model="formDataSem"
|
||||
>
|
||||
<option v-for="sem in semester" :key="sem.studiensemester_kurzbz" :value="sem.studiensemester_kurzbz">{{sem.studiensemester_kurzbz}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Ausbildungssemester*"
|
||||
type="select"
|
||||
id="stv-list-new-ausbildungssemester"
|
||||
name="ausbildungssemester"
|
||||
v-model="formData['ausbildungssemester']"
|
||||
:disabled="formData['incoming']"
|
||||
@input="loadStudienplaene"
|
||||
>
|
||||
<option v-for="sem in Array.from({length:8}).map((u,i) => i+1)" :key="sem" :value="sem">{{sem}}. Semester</option>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="OrgForm"
|
||||
type="select"
|
||||
id="stv-list-new-orgform_kurzbz"
|
||||
name="orgform_kurzbz"
|
||||
v-model="formData['orgform_kurzbz']"
|
||||
@input="loadStudienplaene"
|
||||
>
|
||||
<option value="">-- keine Auswahl --</option>
|
||||
<option v-for="orgform in lists.orgforms" :key="orgform.orgform_kurzbz" :value="orgform.orgform_kurzbz">{{orgform.bezeichnung}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Studienplan"
|
||||
type="select"
|
||||
id="stv-list-new-studienplan_id"
|
||||
name="studienplan_id"
|
||||
v-model="formData['studienplan_id']"
|
||||
>
|
||||
<option value="">-- keine Auswahl --</option>
|
||||
<option v-for="plan in studienplaene" :key="plan.studienplan_id" :value="plan.studienplan_id">{{plan.bezeichnung}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-10 mb-3">
|
||||
<div class="form-check">
|
||||
<fieldset v-if="!personOnly">
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
label="Incoming"
|
||||
type="checkbox"
|
||||
id="stv-list-new-incoming"
|
||||
name="incoming"
|
||||
v-model="formData['incoming']"
|
||||
value="1"
|
||||
:label="$p.t('lehre', 'letzeAusbildung')"
|
||||
type="select"
|
||||
id="stv-list-new-letzteausbildung"
|
||||
name="letzteausbildung"
|
||||
v-model="formData['letzteausbildung']"
|
||||
>
|
||||
<option v-for="ausbildung in lists.ausbildungen" :key="ausbildung.ausbildungcode" :value="ausbildung.ausbildungcode">{{ausbildung.ausbildungbez}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'ausbildungsart')"
|
||||
type="text"
|
||||
id="stv-list-new-ausbildungsart"
|
||||
name="ausbildungsart"
|
||||
v-model="formDataPerson['ausbildungsart']"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-8 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'anmerkungen')"
|
||||
type="textarea"
|
||||
id="stv-list-new-anmerkungen"
|
||||
name="anmerkungen"
|
||||
v-model="formDataPerson['anmerkungen']"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'studiengang')+'*'"
|
||||
type="select"
|
||||
id="stv-list-new-studiengang_kz"
|
||||
name="studiengang_kz"
|
||||
v-model="formDataStg"
|
||||
>
|
||||
<option v-for="stg in lists.active_stgs" :key="stg.studiengang_kz" :value="stg.studiengang_kz">{{stg.kuerzel}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'studiensemester')+'*'"
|
||||
type="select"
|
||||
id="stv-list-new-studiensemester_kurzbz"
|
||||
name="studiensemester_kurzbz"
|
||||
v-model="formDataSem"
|
||||
>
|
||||
<option v-for="sem in semester" :key="sem.studiensemester_kurzbz" :value="sem.studiensemester_kurzbz">{{sem.studiensemester_kurzbz}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'ausbildungssemester')+'*'"
|
||||
type="select"
|
||||
id="stv-list-new-ausbildungssemester"
|
||||
name="ausbildungssemester"
|
||||
v-model="formData['ausbildungssemester']"
|
||||
:disabled="formData['incoming']"
|
||||
@input="loadStudienplaene"
|
||||
>
|
||||
<option v-for="sem in Array.from({length:8}).map((u,i) => i+1)" :key="sem" :value="sem">{{sem}}. Semester</option>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'organisationsform')"
|
||||
type="select"
|
||||
id="stv-list-new-orgform_kurzbz"
|
||||
name="orgform_kurzbz"
|
||||
v-model="formData['orgform_kurzbz']"
|
||||
@input="loadStudienplaene"
|
||||
>
|
||||
<option value="">-- keine Auswahl --</option>
|
||||
<option v-for="orgform in lists.orgforms" :key="orgform.orgform_kurzbz" :value="orgform.orgform_kurzbz">{{orgform.bezeichnung}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="col-sm-4 mb-3">
|
||||
<form-input
|
||||
:label="$p.t('lehre', 'studienplan')"
|
||||
type="select"
|
||||
id="stv-list-new-studienplan_id"
|
||||
name="studienplan_id"
|
||||
v-model="formData['studienplan_id']"
|
||||
>
|
||||
<option value="">-- keine Auswahl --</option>
|
||||
<option v-for="plan in studienplaene" :key="plan.studienplan_id" :value="plan.studienplan_id">{{plan.bezeichnung}}</option>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-10 mb-3">
|
||||
<div class="form-check">
|
||||
<form-input
|
||||
label="Incoming"
|
||||
type="checkbox"
|
||||
id="stv-list-new-incoming"
|
||||
name="incoming"
|
||||
v-model="formData['incoming']"
|
||||
value="1"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</template>
|
||||
</template>
|
||||
<template #footer>
|
||||
<button v-if="person !== null" type="button" class="btn btn-secondary" @click="person = null"><i class="fa fa-chevron-left"></i>Zurück</button>
|
||||
<button type="submit" class="btn btn-primary">{{ person === null ? 'Person anlegen' : 'InteressentIn anlegen' }}</button>
|
||||
<button v-if="person !== null" type="button" class="btn btn-secondary" @click="person = null; formData.address.func = 1;"><i class="fa fa-chevron-left"></i>{{ $p.t('ui', 'zurueck') }}</button>
|
||||
<button type="submit" class="btn btn-primary">{{ person === null || personOnly ? $p.t('person', 'personAnlegen') : $p.t('lehre', 'interessentAnlegen') }}</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
</fhc-form>`
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,10 +1,28 @@
|
||||
import ApiStvVerband from '../../../api/factory/stv/verband.js';
|
||||
import drop from '../../../directives/drop.js';
|
||||
import dragClick from '../../../directives/dragClick.js';
|
||||
|
||||
import ApiStvGroups from '../../../api/factory/stv/group.js';
|
||||
import ApiStvDetails from '../../../api/factory/stv/details.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
PvTreetable: primevue.treetable,
|
||||
PvColumn: primevue.column
|
||||
},
|
||||
directives: {
|
||||
drop,
|
||||
dragClick
|
||||
},
|
||||
inject: {
|
||||
$reloadList: {
|
||||
from: '$reloadList',
|
||||
required: true
|
||||
},
|
||||
currentSemester: {
|
||||
from: 'currentSemester',
|
||||
required: true
|
||||
}
|
||||
},
|
||||
emits: [
|
||||
'selectVerband'
|
||||
],
|
||||
@@ -204,6 +222,51 @@ export default {
|
||||
|
||||
this.selectedKey = {[currentNode.key]: true};
|
||||
this.onSelectTreeNode(currentNode);
|
||||
},
|
||||
async toggleTreeNode(node) {
|
||||
if (this.expandedKeys[node.key]) {
|
||||
delete this.expandedKeys[node.key];
|
||||
} else if (!node.leaf) {
|
||||
await this.onExpandTreeNode(node);
|
||||
this.expandedKeys[node.key] = true;
|
||||
}
|
||||
},
|
||||
getStudentAjaxId(student) {
|
||||
let res = student.id;
|
||||
if (student.vorname && student.nachname)
|
||||
res += ' (' + student.vorname + ' ' + student.nachname + ')';
|
||||
return res;
|
||||
},
|
||||
dropStudents(node, students) {
|
||||
const data = node.data;
|
||||
|
||||
let endpoint;
|
||||
if (data.gruppe_kurzbz) {
|
||||
endpoint = students.map(student => [
|
||||
this.getStudentAjaxId(student),
|
||||
ApiStvGroups.add(
|
||||
student.id,
|
||||
data.gruppe_kurzbz,
|
||||
this.currentSemester
|
||||
)
|
||||
]);
|
||||
} else {
|
||||
const { semester, verband, gruppe } = data;
|
||||
const params = { semester, verband, gruppe };
|
||||
endpoint = students.map(student => [
|
||||
this.getStudentAjaxId(student),
|
||||
ApiStvDetails.saveStudent(
|
||||
student.id,
|
||||
this.currentSemester,
|
||||
params
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
return this.$api
|
||||
.call(endpoint)
|
||||
.then(this.$reloadList)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -265,10 +328,21 @@ export default {
|
||||
</template>
|
||||
<template #body="{ node }">
|
||||
<span
|
||||
v-if="['semester', 'verband', 'gruppe', 'gruppe_kurzbz'].some(key => node.data.hasOwnProperty(key))"
|
||||
:data-tree-item-key="node.key"
|
||||
:title="node.data.studiengang_kz"
|
||||
v-drag-click="() => toggleTreeNode(node)"
|
||||
v-drop:link-strict.student-collection="(evt, students) => dropStudents(node, students)"
|
||||
>
|
||||
{{node.data.name}}
|
||||
{{ node.data.name }}
|
||||
</span>
|
||||
<span
|
||||
v-else
|
||||
:data-tree-item-key="node.key"
|
||||
:title="node.data.studiengang_kz"
|
||||
v-drag-click="() => toggleTreeNode(node)"
|
||||
>
|
||||
{{ node.data.name }}
|
||||
</span>
|
||||
</template>
|
||||
</pv-column>
|
||||
|
||||
@@ -158,10 +158,12 @@ export default {
|
||||
template: `
|
||||
<template v-if="useprimevue">
|
||||
|
||||
<tabview
|
||||
<tabview
|
||||
class="d-flex flex-column"
|
||||
:scrollable="true"
|
||||
:lazy="true"
|
||||
:activeIndex="calcActiveIndex"
|
||||
:pt="{navContainer:{style: 'flex: 0 0 auto;'}, panelContainer:{class: 'overflow-y-scroll', style: 'flex: 1 1 auto;'}}"
|
||||
@tab-click="handleTabClick"
|
||||
>
|
||||
<tabpanel
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { bindDragEnterLeave } from '../helpers/DragAndDrop.js';
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const delay = parseInt(binding.arg) || 300;
|
||||
|
||||
let timeout = null;
|
||||
function startCountdown() {
|
||||
timeout = window.setTimeout(binding.value, delay);
|
||||
}
|
||||
function stopCountdown() {
|
||||
if (timeout)
|
||||
window.clearTimeout(timeout);
|
||||
timeout = null;
|
||||
}
|
||||
|
||||
let lastTarget;
|
||||
let lastX;
|
||||
let lastY;
|
||||
|
||||
function onDragOver(evt) {
|
||||
if (lastX != evt.offsetX || lastY != evt.offsetY || lastTarget != evt.target) {
|
||||
// moved
|
||||
lastTarget = evt.target;
|
||||
lastX = evt.offsetX;
|
||||
lastY = evt.offsetY;
|
||||
|
||||
stopCountdown();
|
||||
startCountdown();
|
||||
}
|
||||
}
|
||||
|
||||
function onEnter(evt) {
|
||||
lastTarget = evt.target;
|
||||
lastX = evt.offsetX;
|
||||
lastY = evt.offsetY;
|
||||
|
||||
el.addEventListener('dragover', onDragOver);
|
||||
|
||||
startCountdown();
|
||||
}
|
||||
function onLeave() {
|
||||
stopCountdown();
|
||||
el.removeEventListener('dragover', onDragOver);
|
||||
}
|
||||
|
||||
el.fhcDragClickCleanup = bindDragEnterLeave(el, onEnter, onLeave);
|
||||
},
|
||||
beforeUnmount(el) {
|
||||
el.fhcDragClickCleanup();
|
||||
delete el.fhcDragClickCleanup;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import { setTransferData, convertToValidDragObject } from '../helpers/DragAndDrop.js';
|
||||
|
||||
const EFFECTS = [
|
||||
'none',
|
||||
'copy',
|
||||
'copyLink',
|
||||
'copyMove',
|
||||
'link',
|
||||
'linkMove',
|
||||
'move',
|
||||
'all',
|
||||
'uninitialized'
|
||||
];
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
updateValue(el, binding.value);
|
||||
updateEffectAllowed(el, binding.arg);
|
||||
|
||||
// if modifier capture is set we assume it's on a parent element
|
||||
// i.e: for dragging multiple elements
|
||||
// otherwise set draggable attribute
|
||||
if (!binding.modifiers.capture) {
|
||||
el.draggable = true;
|
||||
}
|
||||
|
||||
const bcc = new BroadcastChannel('fhc-dnd');
|
||||
let blocked = false;
|
||||
|
||||
function onStart(evt) {
|
||||
const value = el.dataset.fhcDraggableValue;
|
||||
if (value) {
|
||||
setTransferData(evt, JSON.parse(value), true);
|
||||
if (el.dataset.fhcEffectAllowed)
|
||||
evt.dataTransfer.effectAllowed = el.dataset.fhcEffectAllowed;
|
||||
|
||||
bcc.onmessage = e => {
|
||||
if (e.data == 'block') {
|
||||
blocked = true;
|
||||
} else if (e.data == 'release') {
|
||||
let evt = null;
|
||||
if (blocked && blocked.evt) {
|
||||
evt = blocked.evt;
|
||||
}
|
||||
blocked = false;
|
||||
if (evt)
|
||||
el.dispatchEvent(evt);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
evt.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function onEnd(evt) {
|
||||
if (blocked) {
|
||||
blocked = {
|
||||
evt,
|
||||
dt: evt.dataTransfer
|
||||
};
|
||||
evt.stopPropagation();
|
||||
el.dispatchEvent(new DragEvent("beforedragend", evt));
|
||||
} else {
|
||||
bcc.onmessage = () => {};
|
||||
}
|
||||
}
|
||||
el.addEventListener('dragstart', onStart, binding.modifiers.capture);
|
||||
|
||||
el.addEventListener('dragend', onEnd, true);
|
||||
|
||||
el.fhcDraggableCleanup = () => {
|
||||
el.removeEventListener('dragstart', onStart, binding.modifiers.capture);
|
||||
el.removeEventListener('dragend', onEnd, true);
|
||||
};
|
||||
},
|
||||
updated(el, binding) {
|
||||
updateValue(el, binding.value);
|
||||
updateEffectAllowed(el, binding.arg);
|
||||
},
|
||||
beforeUnmount(el) {
|
||||
el.fhcDraggableCleanup();
|
||||
delete el.fhcDraggableCleanup;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
function updateValue(el, value) {
|
||||
value = convertToValidDragObject(value);
|
||||
if (value) {
|
||||
el.dataset.fhcDraggableValue = JSON.stringify(value);
|
||||
} else if (el.dataset.fhcDraggableValue) {
|
||||
delete el.dataset.fhcDraggableValue;
|
||||
}
|
||||
}
|
||||
function updateEffectAllowed(el, effectAllowed) {
|
||||
if (effectAllowed && EFFECTS.includes(effectAllowed)) {
|
||||
el.dataset.fhcEffectAllowed = effectAllowed;
|
||||
} else if (el.dataset.fhcEffectAllowed) {
|
||||
delete el.dataset.fhcEffectAllowed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import { getValidTransferData, eventHasTypes, bindDragEnterLeave } from '../helpers/DragAndDrop.js';
|
||||
|
||||
const EFFECTS = [
|
||||
'move',
|
||||
'copy',
|
||||
'link',
|
||||
'none'
|
||||
];
|
||||
|
||||
export default {
|
||||
mounted(el, binding) {
|
||||
const allowedTypes = Object.keys(binding.modifiers);
|
||||
allowedTypes.forEach(type => {
|
||||
if (type.substr(-11) == '-collection') {
|
||||
const singleType = type.substr(0, type.length-11);
|
||||
if (!allowedTypes.includes(singleType))
|
||||
allowedTypes.push(singleType);
|
||||
}
|
||||
});
|
||||
|
||||
const strict = binding.arg.match(/(strict-|-strict)/);
|
||||
const arg = binding.arg.replace(/(strict-|-strict)/, '');
|
||||
const effect = EFFECTS.includes(arg) ? arg : null;
|
||||
|
||||
const bcc = new BroadcastChannel('fhc-dnd');
|
||||
let allowed = false;
|
||||
|
||||
function onEnter(evt) {
|
||||
allowed = eventHasTypes(evt, allowedTypes, strict);
|
||||
if (allowed) {
|
||||
evt.preventDefault();
|
||||
bcc.postMessage('block');
|
||||
}
|
||||
}
|
||||
function onLeave(evt, wasDropped) {
|
||||
if (allowed && !wasDropped) {
|
||||
bcc.postMessage('release');
|
||||
}
|
||||
}
|
||||
function onOver(evt) {
|
||||
if (allowed) {
|
||||
evt.preventDefault();
|
||||
if (effect)
|
||||
evt.dataTransfer.dropEffect = effect;
|
||||
}
|
||||
}
|
||||
function onDrop(evt) {
|
||||
let result = getValidTransferData(evt, allowedTypes, strict);
|
||||
if (!Array.isArray(result) && !binding.modifiers[result.type] && allowedTypes.includes(result.type + '-collection'))
|
||||
result = [result];
|
||||
|
||||
const res = binding.value(evt, result);
|
||||
|
||||
if (res instanceof Promise) {
|
||||
res.then(r => {
|
||||
bcc.postMessage('release');
|
||||
return r;
|
||||
});
|
||||
} else {
|
||||
bcc.postMessage('release');
|
||||
}
|
||||
}
|
||||
|
||||
const cleanupEnterLeave = bindDragEnterLeave(el, onEnter, onLeave);
|
||||
el.addEventListener('dragover', onOver);
|
||||
el.addEventListener('drop', onDrop);
|
||||
el.fhcDropCleanup = () => {
|
||||
cleanupEnterLeave();
|
||||
el.removeEventListener('dragover', onOver);
|
||||
el.removeEventListener('drop', onDrop);
|
||||
};
|
||||
},
|
||||
beforeUnmount(el) {
|
||||
el.fhcDropCleanup();
|
||||
delete el.fhcDropCleanup;
|
||||
}
|
||||
}
|
||||
@@ -1,67 +1,368 @@
|
||||
/**
|
||||
* TODO(chris): This is only a prototype!!!
|
||||
*/
|
||||
const DragAndDrop = {
|
||||
TYPE_LE: "lehreinheit",
|
||||
TYPE_VEVENT: "vevent",
|
||||
|
||||
getValidTransferData(event, allowedTypes) {
|
||||
const json = event.dataTransfer.getData('text');
|
||||
let obj;
|
||||
try {
|
||||
obj = JSON.parse(json);
|
||||
if (!obj.type)
|
||||
return null;
|
||||
if (allowedTypes && !allowedTypes.includes(obj.type))
|
||||
return null;
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
return obj;
|
||||
const TYPE_DEFINITION = {
|
||||
lehreinheit: {
|
||||
id: "lehreinheit_id",
|
||||
dragIcon: "fa-solid fa-chalkboard-user",
|
||||
extras: [
|
||||
"stundenblockung"
|
||||
]
|
||||
},
|
||||
isValidTransferData(event, allowedTypes) {
|
||||
return this.getValidTransferData(event, allowedTypes) ? true : false;
|
||||
vevent: {
|
||||
id: "uid",
|
||||
dragIcon: "fa-solid fa-calendar",
|
||||
extras: [
|
||||
"dtstart",
|
||||
"dtend",
|
||||
"summary"
|
||||
]
|
||||
},
|
||||
getTransferData(event) {
|
||||
const json = event.dataTransfer.getData('text');
|
||||
return JSON.parse(json);
|
||||
person: {
|
||||
id: "person_id",
|
||||
dragIcon: "fa-solid fa-user"
|
||||
},
|
||||
setTransferData(event, data) {
|
||||
switch (data.type) {
|
||||
case DragAndDrop.TYPE_LE:
|
||||
data = DragAndDrop.fromLe(data);
|
||||
break;
|
||||
default:
|
||||
if (data.dtstart && data.dtend && data.uid && data.summary) {
|
||||
data = DragAndDrop.fromVEvent(data);
|
||||
break;
|
||||
}
|
||||
return false; // No type found => abort
|
||||
}
|
||||
|
||||
event.dataTransfer.setData('text', JSON.stringify(data));
|
||||
return true;
|
||||
student: {
|
||||
id: "student_uid",
|
||||
dragIcon: "fa-solid fa-user-graduate"
|
||||
},
|
||||
fromLe(data) {
|
||||
const {
|
||||
type = DragAndDrop.TYPE_LE,
|
||||
lehreinheit_id: id,
|
||||
stundenblockung
|
||||
} = data;
|
||||
|
||||
return { type, id, stundenblockung };
|
||||
},
|
||||
fromVEvent(data) {
|
||||
const {
|
||||
type = DragAndDrop.TYPE_VEVENT,
|
||||
uid: id,
|
||||
dtstart,
|
||||
dtend,
|
||||
summary
|
||||
} = data;
|
||||
|
||||
return { type, id, dtstart, dtend, summary };
|
||||
prestudent: {
|
||||
id: "prestudent_id",
|
||||
dragIcon: "fa-solid fa-user-graduate text-muted"
|
||||
}
|
||||
// TODO: IMPLEMENT OTHER TYPES
|
||||
};
|
||||
|
||||
export default DragAndDrop;
|
||||
const VALID_TYPES = Object.keys(TYPE_DEFINITION);
|
||||
|
||||
const TYPE_CONSTANTS = Object.keys(TYPE_DEFINITION).reduce((res, type) => {
|
||||
res['TYPE_' + type.toUpperCase()] = type;
|
||||
return res;
|
||||
}, {});
|
||||
|
||||
function isValidDragObject(value) {
|
||||
if (!value)
|
||||
return false;
|
||||
if (Array.isArray(value))
|
||||
return value.every(isValidDragObject);
|
||||
if (!value.type)
|
||||
return false;
|
||||
|
||||
if (value.type.substr(-11) == '-collection') {
|
||||
if (!Object.prototype.hasOwnProperty.call(value, 'values'))
|
||||
return false;
|
||||
|
||||
if (!VALID_TYPES.includes(value.type.substr(0, value.type.length-11)))
|
||||
return false;
|
||||
} else {
|
||||
if (!Object.prototype.hasOwnProperty.call(value, 'id'))
|
||||
return false;
|
||||
|
||||
if (!VALID_TYPES.includes(value.type))
|
||||
return false;
|
||||
|
||||
if (TYPE_DEFINITION[value.type].extras) {
|
||||
if (!TYPE_DEFINITION[value.type].extras.every(extra => Object.prototype.hasOwnProperty.call(value, extra)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getValidTransferData(event, allowedTypes, strict) {
|
||||
let obj = null;
|
||||
|
||||
try {
|
||||
obj = getTransferData(event, strict);
|
||||
if (!obj)
|
||||
return null;
|
||||
|
||||
if (!strict && Array.isArray(obj)) {
|
||||
obj = obj.filter(isValidDragObject);
|
||||
if (!obj.length)
|
||||
return null;
|
||||
} else if (!isValidDragObject(obj))
|
||||
return null;
|
||||
|
||||
if (allowedTypes && allowedTypes.length) {
|
||||
if (Array.isArray(obj)) {
|
||||
if (strict && !obj.every(v => allowedTypes.includes(v.type))) {
|
||||
return null;
|
||||
} else if (!strict) {
|
||||
obj = obj.filter(v => allowedTypes.includes(v.type));
|
||||
if (!obj.length)
|
||||
return null;
|
||||
}
|
||||
} else if (!allowedTypes.includes(obj.type)) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} catch(_error) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj) && obj.length == 1)
|
||||
return obj.find(Boolean);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function isValidTransferData(event, allowedTypes, strict) {
|
||||
return getValidTransferData(event, allowedTypes, strict) ? true : false;
|
||||
}
|
||||
|
||||
function getTransferData(event, strict) {
|
||||
const result = [];
|
||||
|
||||
for (const type of event.dataTransfer.types) {
|
||||
if (type.substr(0, 16) != 'application/fhc-') {
|
||||
if (strict)
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
let base_type = type.substr(16);
|
||||
let collection = false;
|
||||
if (base_type.substr(-11) == '-collection') {
|
||||
base_type = base_type.substr(0, base_type.length-11);
|
||||
collection = true;
|
||||
}
|
||||
if (!VALID_TYPES.includes(base_type)) {
|
||||
if (strict)
|
||||
return null;
|
||||
continue;
|
||||
}
|
||||
let data = JSON.parse(event.dataTransfer.getData(type));
|
||||
if (collection)
|
||||
result.push(...data.values);
|
||||
else
|
||||
result.push(data);
|
||||
}
|
||||
|
||||
if (!result.length)
|
||||
return null;
|
||||
|
||||
if (result.length == 1)
|
||||
return result[0];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function convertToValidDragObject(data, strict) {
|
||||
if (Array.isArray(data)) {
|
||||
const converted = data.map(convertToValidDragObject).filter(Boolean);
|
||||
if (!converted.length)
|
||||
return undefined;
|
||||
if (strict && converted.length != data.length)
|
||||
return undefined;
|
||||
|
||||
const sorted = converted.reduce((res, item) => {
|
||||
if (!res[item.type])
|
||||
res[item.type] = [];
|
||||
res[item.type].push(item);
|
||||
return res;
|
||||
}, {});
|
||||
|
||||
return Object.entries(sorted).map(([type, values]) => {
|
||||
if (values.length > 1) {
|
||||
return {
|
||||
type: type + '-collection',
|
||||
values
|
||||
};
|
||||
}
|
||||
return values[0];
|
||||
});
|
||||
}
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(data, 'type') && isValidDragObject(data)) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const found = Object.entries(TYPE_DEFINITION).find(([ , typedef ]) => {
|
||||
if (!Object.prototype.hasOwnProperty.call(data, typedef.id))
|
||||
return false;
|
||||
if (typedef.extras) {
|
||||
if (!typedef.extras.every(extra => Object.prototype.hasOwnProperty.call(data, extra)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!found) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const [ type, typedef ] = found;
|
||||
|
||||
const newData = {};
|
||||
newData.type = type;
|
||||
newData.id = data[typedef.id];
|
||||
if (typedef.extras)
|
||||
typedef.extras.forEach(extra => newData[extra] = data[extra]);
|
||||
|
||||
return newData;
|
||||
}
|
||||
|
||||
function setTransferData(event, validDragObject, setDragImage = false) {
|
||||
if (setDragImage) {
|
||||
const dragItems = Array.isArray(validDragObject) ? validDragObject : [ validDragObject ];
|
||||
const dragElements = dragItems.map(item => {
|
||||
const icon = document.createElement('i');
|
||||
const label = document.createElement('span');
|
||||
const iconContainer = document.createElement('span');
|
||||
|
||||
iconContainer.className = 'btn btn-outline-dark bg-light';
|
||||
label.className = 'small';
|
||||
|
||||
if (TYPE_DEFINITION[item.type]) {
|
||||
icon.className = TYPE_DEFINITION[item.type].dragIcon || 'fa-solid fa-question';
|
||||
label.textContent = item.id;
|
||||
} else if (item.type.substr(-11) == '-collection' && TYPE_DEFINITION[item.type.substr(0, item.type.length-11)]) {
|
||||
iconContainer.style.boxShadow = '3px 3px var(--bs-btn-border-color)';
|
||||
icon.className = TYPE_DEFINITION[item.type.substr(0, item.type.length-11)].dragIcon || 'fa-solid fa-question';
|
||||
label.textContent = 'x' + item.values.length;
|
||||
} else {
|
||||
icon.className = 'fa-solid fa-question';
|
||||
label.textContent = item.id || '';
|
||||
}
|
||||
|
||||
iconContainer.append(icon);
|
||||
|
||||
const itemContainer = document.createElement('div');
|
||||
itemContainer.className = 'd-flex flex-column align-items-center gap-2 small';
|
||||
itemContainer.append(iconContainer, label);
|
||||
return itemContainer;
|
||||
});
|
||||
|
||||
const container = document.createElement('div');
|
||||
container.className = 'd-flex flex-row gap-2 small';
|
||||
container.append(...dragElements);
|
||||
|
||||
document.body.append(container);
|
||||
event.dataTransfer.setDragImage(container, -25, 0);
|
||||
requestAnimationFrame(() => {
|
||||
document.body.removeChild(container);
|
||||
});
|
||||
}
|
||||
if (Array.isArray(validDragObject)) {
|
||||
return validDragObject.forEach(data => setTransferData(event, data));
|
||||
}
|
||||
|
||||
event.dataTransfer.setData('application/fhc-' + validDragObject.type, JSON.stringify(validDragObject));
|
||||
}
|
||||
|
||||
/**
|
||||
* check if the dataTransfer types are in the allowed types array
|
||||
* if strict is disabled at least one type must be the allowed array
|
||||
* otherwise all types have to be in the allowed array
|
||||
*
|
||||
* @param Event event
|
||||
* @param Array allowedTypes
|
||||
* @param Boolean strict
|
||||
*/
|
||||
function eventHasTypes(event, allowedTypes, strict) {
|
||||
if (!allowedTypes || !allowedTypes.length)
|
||||
allowedTypes = VALID_TYPES;
|
||||
allowedTypes = allowedTypes.map(type => 'application/fhc-' + type);
|
||||
|
||||
const dataTypes = [...event.dataTransfer.types];
|
||||
|
||||
// NOTE(chris): if dragging across browsers the dataTransfer object is
|
||||
// set to a default one without data. Since we do not support dragging
|
||||
// across browsers (yet) we return false which will disallow dropping.
|
||||
if (!dataTypes.length)
|
||||
return false;
|
||||
|
||||
if (!strict)
|
||||
return allowedTypes.some(type => [...event.dataTransfer.types].includes(type));
|
||||
|
||||
return [...event.dataTransfer.types].every(type => allowedTypes.includes(type));
|
||||
}
|
||||
|
||||
function bindDragEnterLeave(el, onEnter, onLeave) {
|
||||
// NOTE(chris): add save dragenter and dragleave events
|
||||
// that won't fire when hovering over child elements
|
||||
|
||||
let skipLeave = false;
|
||||
let skipLeaveParent = true;
|
||||
|
||||
function init(evt) {
|
||||
skipLeave = false;
|
||||
skipLeaveParent = true;
|
||||
// add global listeners
|
||||
window.addEventListener('dragenter', globalDragenter, true);
|
||||
window.addEventListener('dragleave', globalDragleave, true);
|
||||
window.addEventListener('drop', globalDrop, true);
|
||||
// call enter
|
||||
onEnter(evt);
|
||||
// remove self
|
||||
el.removeEventListener('dragenter', init);
|
||||
}
|
||||
|
||||
function cleanup(evt, wasDropped) {
|
||||
// remove global listeners
|
||||
window.removeEventListener('dragenter', globalDragenter, true);
|
||||
window.removeEventListener('dragleave', globalDragleave, true);
|
||||
window.removeEventListener('drop', globalDrop, true);
|
||||
// call leave
|
||||
onLeave(evt, wasDropped);
|
||||
// add init
|
||||
el.addEventListener('dragenter', init);
|
||||
}
|
||||
|
||||
function globalDragenter(evt) {
|
||||
skipLeaveParent = false;
|
||||
if (el != evt.target && !el.contains(evt.target)) {
|
||||
cleanup(evt);
|
||||
} else {
|
||||
skipLeave = true;
|
||||
}
|
||||
}
|
||||
function globalDragleave(evt) {
|
||||
if (el != evt.target && !el.contains(evt.target)) {
|
||||
if (skipLeaveParent) {
|
||||
skipLeaveParent = false;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (skipLeave) {
|
||||
skipLeave = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cleanup(evt);
|
||||
}
|
||||
function globalDrop(evt) {
|
||||
cleanup(evt, true);
|
||||
}
|
||||
|
||||
el.addEventListener('dragenter', init);
|
||||
|
||||
return () => {
|
||||
// cleanup
|
||||
el.removeEventListener('dragenter', init);
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
isValidDragObject,
|
||||
getValidTransferData,
|
||||
isValidTransferData,
|
||||
getTransferData,
|
||||
convertToValidDragObject,
|
||||
setTransferData,
|
||||
eventHasTypes,
|
||||
bindDragEnterLeave
|
||||
};
|
||||
export default {
|
||||
...TYPE_CONSTANTS,
|
||||
isValidDragObject,
|
||||
getValidTransferData,
|
||||
isValidTransferData,
|
||||
getTransferData,
|
||||
convertToValidDragObject,
|
||||
setTransferData,
|
||||
eventHasTypes,
|
||||
bindDragEnterLeave
|
||||
};
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export function capitalize(string) {
|
||||
if (!string) return '';
|
||||
return string[0].toUpperCase() + string.slice(1);
|
||||
}
|
||||
@@ -548,6 +548,9 @@ export default {
|
||||
} else {
|
||||
console.error("FhcApi: method not allowed:", method);
|
||||
}
|
||||
},
|
||||
getErrorHandler(config) {
|
||||
return get_error_handler(config);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -332,6 +332,12 @@ foreach($prestudent_arr as $prest_id)
|
||||
{
|
||||
$studiengangbezeichnung = $studienordnung->__get('studiengangbezeichnung');
|
||||
$studiengangbezeichnung_englisch = $studienordnung->__get('studiengangbezeichnung_englisch');
|
||||
$akadgrad = new akadgrad();
|
||||
if ($akadgrad->load($studienordnung->__get('akadgrad_id')))
|
||||
{
|
||||
$akadgrad_titel_studienordnung = $akadgrad->titel;
|
||||
$akadgrad_kurzbz_studienordnung = $akadgrad->akadgrad_kurzbz;
|
||||
}
|
||||
}
|
||||
}
|
||||
$studiengang_bezeichnung = empty($studiengangbezeichnung) ? $studiengang->bezeichnung : $studiengangbezeichnung;
|
||||
@@ -428,6 +434,8 @@ foreach($prestudent_arr as $prest_id)
|
||||
|
||||
//Wenn Quereinsteiger stimmt studiengang_maxsemester nicht mit der tatsaechlichen Ausbildungsdauer ueberein
|
||||
$student_maxsemester = ($studiengang->max_semester-$ausbildungssemester)+1;
|
||||
|
||||
// TODO: where to get semester duration for master Lehrgaenge?
|
||||
echo "\t\t<student_maxsemester>".$student_maxsemester."</student_maxsemester>\n";
|
||||
echo "\t\t<student_anzahljahre>".($student_maxsemester/2)."</student_anzahljahre>\n";
|
||||
|
||||
@@ -452,6 +460,8 @@ foreach($prestudent_arr as $prest_id)
|
||||
|
||||
echo "\t\t<akadgrad>".$akadgrad_titel."</akadgrad>\n";
|
||||
echo "\t\t<akadgrad_kurzbz>".$akadgrad_kurzbz."</akadgrad_kurzbz>\n";
|
||||
echo "\t\t<akadgrad_studienordnung>".($akadgrad_titel_studienordnung ?? '')."</akadgrad_studienordnung>\n";
|
||||
echo "\t\t<akadgrad_kurzbz_studienordnung>".($akadgrad_kurzbz_studienordnung ?? '')."</akadgrad_kurzbz_studienordnung>\n";
|
||||
|
||||
echo "\t\t<datum_aktuell>".$datum_aktuell."</datum_aktuell>\n";
|
||||
|
||||
|
||||
@@ -1160,12 +1160,13 @@ function checkNote($note_alt, $note_neu)
|
||||
'4' => 'ea',
|
||||
'5' => 'tg',
|
||||
'6' => 'met',
|
||||
'7' => 'ar',
|
||||
'8' => 'nb',
|
||||
'9' => '5',
|
||||
'10' => 'nea');
|
||||
'7' => 'b',
|
||||
'8' => 'ar',
|
||||
'9' => 'nb',
|
||||
'10' => '5',
|
||||
'11' => 'nea');
|
||||
|
||||
for($i = 0; $i<=9; $i++)
|
||||
for($i = 0; $i<=11; $i++)
|
||||
{
|
||||
if($note_alt == $arrayNotenPriority[$i])
|
||||
$priority_alt = $i;
|
||||
|
||||
@@ -335,14 +335,14 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$anrechnung = new anrechnung();
|
||||
$anrechnung->getAnrechnungPrestudent($student->prestudent_id, null, $lehrveranstaltung_id);
|
||||
|
||||
$xml .= "<studienverpflichtung>";
|
||||
$xml .= "<studienverpflichtung><![CDATA[";
|
||||
$lehrveranstaltung_id_kompatibel = "";
|
||||
if(count($anrechnung->result) === 1)
|
||||
{
|
||||
$lehrveranstaltung_id_kompatibel = $anrechnung->result[0]->lehrveranstaltung_id;
|
||||
$xml .= $anrechnung->result[0]->lehrveranstaltung_bez;
|
||||
}
|
||||
$xml .= "</studienverpflichtung>";
|
||||
$xml .= "]]></studienverpflichtung>";
|
||||
|
||||
if($lehrveranstaltung_id_kompatibel != "")
|
||||
{
|
||||
|
||||
@@ -84,6 +84,7 @@ require_once('dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php');
|
||||
require_once('dbupdate_3.4/66982_berufsschule.php');
|
||||
require_once('dbupdate_3.4/40314_electronic_onboarding_anbindung_ida.php');
|
||||
require_once('dbupdate_3.4/47972_pruefungsverwaltung_ects_angabe.php');
|
||||
require_once('dbupdate_3.4/67490_studstatus_suche_abort_controller_haengt.php');
|
||||
|
||||
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
||||
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||
|
||||
// Add index to campus.tbl_studierendenantrag_status.studierendenantrag_id
|
||||
if ($result = $db->db_query("SELECT * FROM pg_class WHERE relname='idx_tbl_studierendenantrag_status_studierendenantrag_id'"))
|
||||
{
|
||||
if ($db->db_num_rows($result) == 0)
|
||||
{
|
||||
$qry = "CREATE INDEX idx_tbl_studierendenantrag_status_studierendenantrag_id ON campus.tbl_studierendenantrag_status USING btree (studierendenantrag_id)";
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>Indizes: ' . $db->db_last_error() . '</strong><br>';
|
||||
else
|
||||
echo 'Index fuer campus.tbl_studierendenantrag_status.studierendenantrag_id hinzugefuegt';
|
||||
}
|
||||
}
|
||||
+1526
-41
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