Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into rc1_FHC4_C4

This commit is contained in:
Harald Bamberger
2025-08-01 15:48:49 +02:00
142 changed files with 16658 additions and 700 deletions
+1 -1
View File
@@ -6,4 +6,4 @@ $config['use_vuejs_dev_version'] = false;
// use bundled javascript
$config['use_bundled_javascript'] = false;
// systemerror_mailto use in FHC-Alert Plugin - if empty Link will not be rendered
$config['systemerror_mailto'] = '';
$config['systemerror_mailto'] = '';
+5 -1
View File
@@ -52,7 +52,11 @@ $config['tabs'] =
],
],
],
]
],
'exemptions' => [
//if true, Anrechnungen can be added and edited in tab Anrechnungen
'editableAnrechnungen' => false,
],
];
// List of fields to show when ZGV_DOKTOR_ANZEIGEN is defined
+30
View File
@@ -0,0 +1,30 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class NeueNachricht extends Auth_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['vertrag/mitarbeiter:r'];
parent::__construct($permissions);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* @return void
*/
public function _remap()
{
//now working
$this->load->view('Nachrichten', [
'permissions' => [
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'),
]
]);
}
}
@@ -43,7 +43,8 @@ class Documents extends FHCAPI_Controller
parent::__construct([
'permissionAlternativeFormat' => self::PERM_LOGGED,
'archive' => ['admin:rw', 'assistenz:rw'],
'archiveSigned' => ['admin:rw', 'assistenz:rw']
'archiveSigned' => ['admin:rw', 'assistenz:rw'],
'download' => ['admin:rw', 'assistenz:rw']
]);
// Load Phrases
@@ -66,7 +67,7 @@ class Documents extends FHCAPI_Controller
}
/**
* Download a not signed document.
* Archive a not signed document.
*
* @param string $xml (optional)
* @param string $xsl (optional)
@@ -79,7 +80,7 @@ class Documents extends FHCAPI_Controller
}
/**
* Download a signed document.
* Archive a signed document.
*
* @param string $xml (optional)
* @param string $xsl (optional)
@@ -91,6 +92,42 @@ class Documents extends FHCAPI_Controller
return $this->_archive($xml, $xsl, getAuthUID());
}
/**
*
* @return void
*/
public function download($xml, $xsl, $sign_user = null)
{
$akteExportData = $this->_getAkteExportData($xml, $xsl, $sign_user);
$akteData = $akteData['akteData'];
$exportData = $akteData['exportData'];
/**
* [
'vorlage' => $vorlage,
'xml_data' => $data,
'oe_kurzbz' => $xsl_oe_kurzbz,
'version' => $version,
'outputformat' => $outputformat,
'sign_user' => $sign_user
]
*/
// Output
$result = $this->documentexportlib->showContent(
$akteData['akteData']['inhalt'],
$exportData['vorlage'],
$exportData['xml_data'],
$exportData['oe_kurzbz'],
$exportData['version'],
$exportData['outputformat'],
$exportData['sign_user']
);
$this->terminateWithSuccess(true);
}
/**
* Helper function for archive() and archiveSigned()
*
@@ -100,16 +137,36 @@ class Documents extends FHCAPI_Controller
*
* @return void
*/
public function _archive($xml, $xsl, $sign_user = null)
private function _archive($xml, $xsl, $sign_user = null)
{
$akteData = $this->_getAkteExportData($xml, $xsl, $sign_user);
$this->load->model('crm/Akte_model', 'AkteModel');
$result = $this->AkteModel->insert($akteData['akteData']);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
/**
* @param string $xml
* @param string $xsl
* @param string $sign_user (optional)
*
* @return array with Akte data and export data
*/
private function _getAkteExportData($xml, $xsl, $sign_user = null)
{
if (!$xml || !$xsl) {
$this->load->library('form_validation');
if (!$xml) {
$xml = $this->input->post_get('xml');
$this->addMeta('xml', $xml);
$this->form_validation->set_rules('xml', 'xml', 'required');
}
if (!$xsl) {
$xsl = $this->input->post_get('xsl');
$this->addMeta('xsl', $xsl);
$this->form_validation->set_rules('xsl', 'xsl', 'required');
}
@@ -151,6 +208,7 @@ class Documents extends FHCAPI_Controller
$this->load->model('system/Vorlage_model', 'VorlageModel');
$result = $this->VorlageModel->load($xsl);
$this->addMeta("ress", $result);
$vorlage = current($this->getDataOrTerminateWithError($result));
if (!$vorlage)
show_404();
@@ -171,6 +229,7 @@ class Documents extends FHCAPI_Controller
$studiengang_kz = null;
if ($akteData['uid']) {
$this->load->model('crm/Student_model', 'StudentModel');
$this->StudentModel->addSelect('tbl_student.*, UPPER(typ || kurzbz) AS kuerzel');
$this->StudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
$result = $this->StudentModel->load([$akteData['uid']]);
$student = current($this->getDataOrTerminateWithError($result));
@@ -318,6 +377,7 @@ class Documents extends FHCAPI_Controller
$result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version);
$access_rights = current($this->getDataOrTerminateWithError($result));
// TODO: was bedeutet wenn keine berechtigung?
if (!$access_rights || !$access_rights->berechtigung)
return show_404();
@@ -413,10 +473,17 @@ class Documents extends FHCAPI_Controller
$akteData['titel'] .= '.pdf';
$akteData['inhalt'] = base64_encode($content);
$this->load->model('crm/Akte_model', 'AkteModel');
$result = $this->AkteModel->insert($akteData);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
return [
'akteData' => $akteData,
'exportData' =>
[
'vorlage' => $vorlage,
'xml_data' => $data,
'oe_kurzbz' => $xsl_oe_kurzbz,
'version' => $version,
'outputformat' => $outputformat,
'sign_user' => $sign_user
]
];
}
}
@@ -75,8 +75,9 @@ class BetriebsmittelP extends FHCAPI_Controller
'required' => $this->p->t('ui', 'error_fieldRequired')
]);
$this->form_validation->set_rules('kaution', 'Kaution', 'numeric|less_than_equal_to[9999.99]', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric')
$this->form_validation->set_rules('kaution', 'Kaution', 'callback_valid_number|callback_not_less_than_equal', [
'valid_number' => $this->p->t('ui', 'error_fieldNoValidNumber'),
'not_less_than_equal' => $this->p->t('ui', 'error_fieldLessThan1000'),
]);
$this->form_validation->set_rules('ausgegebenam', 'Ausgegeben am', 'required|is_valid_date', [
@@ -158,6 +159,7 @@ class BetriebsmittelP extends FHCAPI_Controller
], [
'uid_in_person' => $this->p->t('person', 'error_uidNotInPerson')
]);
$this->validateNewOrUpdate();
$betriebsmitteltyp = $this->input->post('betriebsmitteltyp');
@@ -167,6 +169,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$betriebsmittel_id = $this->input->post('betriebsmittel_id');
$anmerkung = $this->input->post('anmerkung');
$kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
$uid = $this->input->post('uid');
@@ -250,6 +253,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$betriebsmittel_id = $this->input->post('betriebsmittel_id');
$anmerkung = $this->input->post('anmerkung');
$kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
@@ -382,6 +386,26 @@ class BetriebsmittelP extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function valid_number($number)
{
if(is_null($number)) return true;
$number = str_replace(',', '.', $number);
if (!is_numeric($number))
{
return false;
}
return true;
}
public function not_less_than_equal($number)
{
$number = str_replace(',', '.', $number);
if ($number < 1000)
return true;
return false;
}
}
@@ -0,0 +1,328 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Funktionen extends FHCAPI_Controller
{
public function __construct()
{
//TODO(Manu) check permissions
parent::__construct(array(
'getAllFunctions' => ['admin:r', 'assistenz:r'],
'getAllUserFunctions' => ['admin:r', 'assistenz:r'],
'getOrgHeads' => ['admin:r', 'assistenz:r'],
'getOrgetsForCompany' => ['admin:r', 'assistenz:r'],
'getAllOrgUnits' => ['admin:r', 'assistenz:r'],
'loadFunction' => ['admin:r', 'assistenz:r'],
'insertFunction' => ['admin:rw', 'assistenz:rw'],
'updateFunction' => ['admin:rw', 'assistenz:rw'],
'deleteFunction' => ['admin:rw', 'assistenz:rw'],
)
);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
]);
// Load models
$this->load->model('extensions/FHC-Core-Personalverwaltung/Api_model', 'ApiModel');
$this->load->model('ressource/Funktion_model', 'FunktionModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
}
public function getAllFunctions()
{
$this->FunktionModel->addSelect("funktion_kurzbz");
$this->FunktionModel->addSelect("beschreibung");
$this->FunktionModel->addSelect("aktiv");
$this->FunktionModel->addSelect("beschreibung AS label");
$this->FunktionModel->addOrder("beschreibung");
$result = $this->FunktionModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getOrgHeads()
{
$result = $this->OrganisationseinheitModel->getHeads();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllUserFunctions($uid)
{
if(!$uid)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'UID']), self::ERROR_TYPE_GENERAL);
}
$sql = "
SELECT
dv.dienstverhaeltnis_id,
un.bezeichnung || ' (' || TO_CHAR(dv.von, 'DD.MM.YYYY') || CASE WHEN dv.bis IS NOT NULL THEN ' - '
|| TO_CHAR(dv.bis, 'DD.MM.YYYY') ELSE '' END || ')' AS dienstverhaeltnis_unternehmen ,
'[' || oet.bezeichnung || '] ' || oe.bezeichnung AS funktion_oebezeichnung,
f.beschreibung AS funktion_beschreibung,
bf.*,
fb.bezeichnung AS fachbereich_bezeichnung,
CASE
WHEN
bf.datum_bis IS NOT NULL AND bf.datum_bis::date < now()::date
THEN
false
ELSE
true
END aktiv
FROM
public.tbl_benutzerfunktion bf
JOIN
public.tbl_organisationseinheit oe ON oe.oe_kurzbz = bf.oe_kurzbz
JOIN
public.tbl_organisationseinheittyp oet ON oe.organisationseinheittyp_kurzbz = oet.organisationseinheittyp_kurzbz
JOIN
public.tbl_funktion f ON f.funktion_kurzbz = bf.funktion_kurzbz
LEFT JOIN
hr.tbl_vertragsbestandteil_funktion vf ON vf.benutzerfunktion_id = bf.benutzerfunktion_id
LEFT JOIN
hr.tbl_vertragsbestandteil v ON vf.vertragsbestandteil_id = v.vertragsbestandteil_id
LEFT JOIN
hr.tbl_dienstverhaeltnis dv ON v.dienstverhaeltnis_id = dv.dienstverhaeltnis_id
LEFT JOIN
public.tbl_organisationseinheit un ON dv.oe_kurzbz = un.oe_kurzbz
LEFT JOIN
public.tbl_fachbereich fb ON fb.fachbereich_kurzbz = bf.fachbereich_kurzbz
WHERE
bf.uid = ?
ORDER BY
bf.datum_von, bf.datum_von ASC";
$benutzerfunktionen = $this->BenutzerfunktionModel->execReadOnlyQuery($sql, array($uid));
$data = $this->getDataOrTerminateWithError($benutzerfunktionen);
$this->terminateWithSuccess($data);
}
/*
* returns list of all organisation units
* as key value list to be used in select or autocomplete
*/
public function getAllOrgUnits()
{
$sql = "
SELECT
oe.oe_kurzbz, oe.aktiv,
'[' || COALESCE(oet.bezeichnung, oet.organisationseinheittyp_kurzbz) ||
'] ' || COALESCE(oe.bezeichnung, oe.oe_kurzbz) AS label
FROM public.tbl_organisationseinheit oe
JOIN public.tbl_organisationseinheittyp oet ON oe.organisationseinheittyp_kurzbz = oet.organisationseinheittyp_kurzbz
ORDER BY oet.bezeichnung ASC, oe.bezeichnung ASC";
$result = $this->OrganisationseinheitModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/*
* return list of child orgets for a given company orget_kurzbz
* as key value list to be used in select or autocomplete
*/
public function getOrgetsForCompany($companyOrgetkurzbz = null)
{
$sql = "
SELECT
oe.oe_kurzbz, oe.aktiv,
'[' || COALESCE(oet.bezeichnung, oet.organisationseinheittyp_kurzbz) ||
'] ' || COALESCE(oe.bezeichnung, oe.oe_kurzbz) AS label
FROM (
WITH RECURSIVE oes(oe_kurzbz, oe_parent_kurzbz) as
(
SELECT oe_kurzbz, oe_parent_kurzbz FROM public.tbl_organisationseinheit
WHERE oe_kurzbz=?
UNION ALL
SELECT o.oe_kurzbz, o.oe_parent_kurzbz FROM public.tbl_organisationseinheit o, oes
WHERE o.oe_parent_kurzbz=oes.oe_kurzbz
)
SELECT oe_kurzbz
FROM oes
GROUP BY oe_kurzbz
) c
JOIN public.tbl_organisationseinheit oe ON oe.oe_kurzbz = c.oe_kurzbz
JOIN public.tbl_organisationseinheittyp oet ON oe.organisationseinheittyp_kurzbz = oet.organisationseinheittyp_kurzbz
ORDER BY oet.bezeichnung ASC, oe.bezeichnung ASC";
$childorgets = $this->OrganisationseinheitModel->execReadOnlyQuery($sql, array($companyOrgetkurzbz));
$data = $this->getDataOrTerminateWithError($childorgets);
$this->terminateWithSuccess($data);
}
public function loadFunction($benutzerfunktion_id)
{
$this->BenutzerfunktionModel->addSelect("*");
$result = $this->BenutzerfunktionModel->loadWhere(
array('benutzerfunktion_id' => $benutzerfunktion_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function insertFunction()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$uid = $this->input->post('uid');
if(!$uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$datum_von = $formData['datum_von'] ?? null;
$datum_bis = $formData['datum_bis'] ?? null;
$formData['oe_kurzbz'] = is_array($formData['oe_kurzbz']) ? $formData['oe_kurzbz']['oe_kurzbz'] : $formData['oe_kurzbz'];
$formData['funktion_kurzbz'] = is_array($formData['funktion_kurzbz'])
? $formData['funktion_kurzbz']['funktion_kurzbz']
: $formData['funktion_kurzbz'];
$bezeichnung = $formData['bezeichnung'] ?? null;
$wochenstunden = $formData['wochenstunden'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('datum_von', 'VonDatum', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('datum_bis', 'BisDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'BisDatum'])
]);
$this->form_validation->set_rules('oe_kurzbz', 'Organisationseinheit', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Organisationseinheit'])
]);
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Funktion'])
]);
$this->form_validation->set_rules('wochenstunden', 'Wochenstunden', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Wochenstunden'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->BenutzerfunktionModel->insert([
'uid' => $uid,
'datum_von' => $datum_von,
'datum_bis' => $datum_bis ,
'oe_kurzbz' => $formData['oe_kurzbz'],
'funktion_kurzbz' => $formData['funktion_kurzbz'],
'bezeichnung' => $bezeichnung,
'wochenstunden' => $wochenstunden,
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function updateFunction()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$uid = $this->input->post('uid');
if(!$uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'UID']), self::ERROR_TYPE_GENERAL);
}
$benutzerfunktion_id = $this->input->post('benutzerfunktion_id');
if(!$benutzerfunktion_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Benutzerfunktion ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$datum_von = $formData['datum_von'] ?? null;
$datum_bis = $formData['datum_bis'] ?? null;
$formData['oe_kurzbz'] = is_array($formData['oe_kurzbz']) ? $formData['oe_kurzbz']['oe_kurzbz'] : $formData['oe_kurzbz'];
$formData['funktion_kurzbz'] = is_array($formData['funktion_kurzbz'])
? $formData['funktion_kurzbz']['funktion_kurzbz']
: $formData['funktion_kurzbz'];
$bezeichnung = $formData['bezeichnung'] ?? null;
$wochenstunden = $formData['wochenstunden'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('datum_von', 'VonDatum', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('datum_bis', 'BisDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'BisDatum'])
]);
$this->form_validation->set_rules('oe_kurzbz', 'Organisationseinheit', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Organisationseinheit'])
]);
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Funktion'])
]);
$this->form_validation->set_rules('wochenstunden', 'Wochenstunden', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Wochenstunden'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->BenutzerfunktionModel->update(
[
'benutzerfunktion_id' => $benutzerfunktion_id,
],
[
'uid' => $uid,
'datum_von' => $datum_von,
'datum_bis' => $datum_bis ,
'oe_kurzbz' => $formData['oe_kurzbz'],
'funktion_kurzbz' => $formData['funktion_kurzbz'],
'bezeichnung' => $bezeichnung,
'wochenstunden' => $wochenstunden,
'updateamum' => date('c'),
'updatevon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteFunction($benutzerfunktion_id)
{
$result = $this->BenutzerfunktionModel->delete(
array('benutzerfunktion_id' => $benutzerfunktion_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,458 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Messages extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getMessages' => ['admin:r', 'assistenz:r'],
'getVorlagen' => ['admin:r', 'assistenz:r'],
'getMessageVarsPerson' => ['admin:r', 'assistenz:r'],
'getMsgVarsPrestudent' => ['admin:r', 'assistenz:r'],
'getMsgVarsLoggedInUser' => ['admin:r', 'assistenz:r'],
'getNameOfDefaultRecipient' => ['admin:r', 'assistenz:r'],
'sendMessage' => ['admin:r', 'assistenz:r'],
'deleteMessage' => ['admin:r', 'assistenz:r'],
'getVorlagentext' => ['admin:r', 'assistenz:r'],
'getPreviewText' => ['admin:r', 'assistenz:r'],
'getReplyData' => ['admin:r', 'assistenz:r'],
'getPersonId' => ['admin:r', 'assistenz:r'],
'getUid' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('system/Message_model', 'MessageModel');
$this->load->model('CL/Messages_model', 'MessagesModel');
// Additional Permission Checks
//TODO(manu) check permissions
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->load->library('MessageLib');
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getMessages($id, $type_id, $size, $page)
{
if($type_id != 'person_id'){
$id = $this->_getPersonId($id, $type_id);
}
$offset = $size * ($page - 1);
$limit = $size;
$result = $this->MessageModel->getMessagesForTable($id, $offset, $limit);
$data = $this->getDataOrTerminateWithError($result);
$this->addMeta('count', $data['count']);
$this->terminateWithSuccess($data['data']);
}
public function getVorlagen()
{
//get oe of user
$uid = getAuthUID();
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = current($data);
$this->load->model('system/Vorlage_model', 'VorlageModel');
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
//If admin
$this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC');
$result = $this->VorlageModel->loadWhere(
array(
'mimetype' => 'text/html'
));
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getVorlagentext($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');
$result = $this->VorlagestudiengangModel->loadWhere(
[
'vorlage_kurzbz' =>$vorlage_kurzbz,
'studiengang_kz' => $studiengang_kz
]);
$data = $this->getDataOrTerminateWithError($result);
//not correct with Vorlage
$vorlage = current($data);
//$this->terminateWithSuccess($data);
$this->terminateWithSuccess($vorlage->text);
}
public function getMessageVarsPerson($id, $typeId)
{
$person_id = ($typeId == 'mitarbeiter_uid') ? $this->_getPersonId($id, $typeId) : $id;
$result = $this->MessageModel->getMsgVarsDataByPersonId($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getMsgVarsPrestudent($id, $typeId)
{
$prestudent_id = ($typeId == 'uid') ? $this->_getPrestudentIdFromUid($id) : $id;
$result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getMsgVarsLoggedInUser()
{
$result = $this->MessageModel->getMsgVarsLoggedInUser();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getNameOfDefaultRecipient($id, $type_id)
{
$id = ($type_id != 'person_id') ? $this->_getPersonId($id, $type_id) : $id;
$this->load->model('person/Person_model', 'PersonModel');
$result = $this->PersonModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
$name = current($data);
$this->terminateWithSuccess($name->vorname . " " . $name->nachname );
}
public function sendMessage($recipient_id)
{
//has to be uid
// $this->terminateWithError("uid", $recipient_id, self::ERROR_TYPE_GENERAL);
//default setting
$receiversPersonId = $this->_getPersonId($recipient_id, 'uid');
$uid = getAuthUID();
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['uid' => $uid]
);
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$this->load->library('form_validation');
$this->form_validation->set_rules('subject', 'Betreff', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betreff'])
]);
$this->form_validation->set_rules('body', 'Text', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Text'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$subject = $this->input->post('subject');
$body = $this->input->post('body');
$relationmessage_id = $this->input->post('relationmessage_id');
$typeId = $this->input->post('type_id');
$id = $this->input->post('id');
if($typeId == 'uid')
{
$prestudent_id = $this-> _getPrestudentIdFromUid($id);
//parseMessagetext for variables Prestudent
$result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
if($typeId == 'mitarbeiter_uid')
{
$person_id = $this->_getPersonId($id, $typeId);
$result = $this->MessagesModel->parseMessageTextPerson($person_id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
$this->terminateWithError($bodyParsed, self::ERROR_TYPE_GENERAL);
}
elseif($typeId == 'person_id')
{
$result = $this->MessagesModel->parseMessageTextPerson($id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
elseif($typeId == 'prestudent_id')
{
// $this->terminateWithError("prestudent_id ", self::ERROR_TYPE_GENERAL);
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
else
{
$this->terminateWithError("type_id " . $typeId . " not valid", self::ERROR_TYPE_GENERAL);
}
$result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id, null, $relationmessage_id);
$this->terminateWithSuccess($result);
}
public function getPreviewText($id, $type_id)
{
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
}
else
$this->terminateWithError("Textbody missing ", self::ERROR_TYPE_GENERAL);
switch($type_id)
{
case 'uid':
$prestudent_id = $this->_getPrestudentIdFromUid($id);
$result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $data);
break;
case 'prestudent_id':
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $data);
break;
case 'person_id':
$result = $this->MessagesModel->parseMessageTextPerson($id, $data);
break;
case 'mitarbeiter_uid':
{
$person_id = $this->_getPersonId($id, $type_id);
$result = $this->MessagesModel->parseMessageTextPerson($person_id, $data);
}
break;
default:
$this->terminateWithError("MESSAGES::getPreviewText logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL);
break;
}
$bodyParsed = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($bodyParsed);
}
public function getReplyData($messageId)
{
//TODO(Manu) validation of messageId: if number
$this->MessageModel->addSelect('public.tbl_msg_message.*');
$this->MessageModel->addSelect('r.*');
$this->MessageModel->addSelect('p.nachname');
$this->MessageModel->addSelect('p.vorname');
$this->MessageModel->addJoin('public.tbl_msg_recipient r', 'ON (r.message_id = public.tbl_msg_message.message_id)');
$this->MessageModel->addJoin('public.tbl_person p', 'ON (p.person_id = public.tbl_msg_message.person_id)');
$result = $this->MessageModel->loadWhere(
array('r.message_id' => $messageId)
);
$dataMessage = $this->getDataOrTerminateWithError($result);
$prefix = "Re: "; // reply subject prefix
$subject = $dataMessage[0]->subject;
$body = $dataMessage[0]->body;
$replyBody = $this->_getReplyBody($body, $dataMessage[0]->nachname, $dataMessage[0]->vorname, $dataMessage[0]->insertamum);
$dataMessage[0]->replyBody = $replyBody;
$dataMessage[0]->rest = "Help Manu";
$dataMessage[0]->replySubject = $prefix . $subject;
$this->terminateWithSuccess($dataMessage);
}
public function deleteMessage($messageId)
{
// Start DB transaction
$this->db->trans_begin();
$result = $this->MessageModel->deleteMessageRecipient($messageId);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$result = $this->MessageModel->deleteMessageStatus($messageId);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$result = $this->MessageModel->deleteMessage($messageId);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->db->trans_commit();
$this->terminateWithSuccess($result);
}
public function getPersonId($id, $typeId)
{
if ($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['uid' => $id]
);
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
}
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
$this->terminateWithSuccess($person->person_id);
}
public function getUid($id, $typeId)
{
if (!$typeId)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Type ID']), self::ERROR_TYPE_GENERAL);
}
elseif ($typeId == 'person_id')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['person_id' => $id]
);
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
$person_id = $person->person_id;
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['person_id' => $person_id]
);
}
elseif($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->terminateWithSuccess($id);
}
else
{
$this->terminateWithError("MESSAGES::getUID logic for type_id " . $typeId . " not defined yet", self::ERROR_TYPE_GENERAL);
}
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
$this->terminateWithSuccess($benutzer->uid);
}
private function _getPersonId($id, $typeId)
{
if ($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['uid' => $id]
);
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
}
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
return $person->person_id;
}
private function _getPrestudentIdFromUid($uid)
{
// $this->terminateWithError($uid, self::ERROR_TYPE_GENERAL);
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(
['student_uid' => $uid]
);
$data = $this->getDataOrTerminateWithError($result);
$student = current($data);
// $this->terminateWithError($student->prestudent_id, self::ERROR_TYPE_GENERAL);
return $student->prestudent_id;
}
private function _getReplyBody($body, $receiverName, $receiverSurname, $sentDate)
{
// To quote a reply body message
$bodyFormat = "<br>
<br>
<blockquote>
<i>
On %s %s %s wrote:
</i>
</blockquote>
<blockquote style='border-left:2px solid; padding-left: 8px'>
%s
</blockquote>";
return sprintf(
$bodyFormat,
date_format(date_create($sentDate), 'd.m.Y H:i'), $receiverName, $receiverSurname, $body
);
}
}
@@ -20,6 +20,8 @@ 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'],
@@ -38,6 +40,51 @@ class Abschlusspruefung extends FHCAPI_Controller
// Load models
$this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel');
//Permission checks for Studiengangsarray
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'insertAbschlusspruefung' || $this->router->method == 'updateAbschlusspruefung')
{
$student_uid = $this->input->post('uid') ?: ($this->input->post('formData')['student_uid'] ?? null);
if(!$student_uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
if ($this->router->method == 'deleteAbschlusspruefung')
{
$abschlusspruefung_id = $this->input->post('id');
if(!$abschlusspruefung_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Abschlusspruefung ID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->AbschlusspruefungModel->load(
array('abschlusspruefung_id' => $abschlusspruefung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$student_uid = current($data)->student_uid;
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
}
private function _checkAllowedStgsFromUid($student_uid, $allowedStgs)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
public function getAbschlusspruefung($student_uid)
@@ -149,16 +196,16 @@ class Abschlusspruefung extends FHCAPI_Controller
{
$studiengang_kz= $this->input->post('studiengang_kz');
/* if (!$studiengang_kzs || !is_array($studiengang_kzs)) {
$this->load->library('form_validation');
/* if (!$studiengang_kzs || !is_array($studiengang_kzs)) {
$this->load->library('form_validation');
$this->form_validation->set_rules('studiengang_kzs', '', 'required|is_null', [
'is_null' => $this->p->t('ui', 'error_fieldMustBeArray')
]);
$this->form_validation->set_rules('studiengang_kzs', '', 'required|is_null', [
'is_null' => $this->p->t('ui', 'error_fieldMustBeArray')
]);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}*/
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}*/
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
@@ -224,19 +271,7 @@ class Abschlusspruefung extends FHCAPI_Controller
$formData = $this->input->post('formData');
$_POST['pruefungstyp_kurzbz'] = $formData['pruefungstyp_kurzbz'];
$_POST['akadgrad_id']= $formData['akadgrad_id'];
$_POST['vorsitz'] = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz'];
$_POST['pruefer1'] = isset($formData['pruefer1']['person_id']) ? $formData['pruefer1']['person_id'] : $formData['pruefer1'];
$_POST['pruefer2'] = isset($formData['pruefer2']['person_id']) ? $formData['pruefer2']['person_id'] : $formData['pruefer2'];
$_POST['pruefer3'] = isset($formData['pruefer3']['person_id']) ? $formData['pruefer3']['person_id'] : $formData['pruefer3'];
$_POST['pruefungsantritt_kurzbz'] = $formData['pruefungsantritt_kurzbz'];
$_POST['abschlussbeurteilung_kurzbz'] = $formData['abschlussbeurteilung_kurzbz'];
$_POST['datum']= $formData['datum'];
$_POST['sponsion']= $formData['sponsion'];
$_POST['anmerkung'] = $formData['anmerkung'];
$_POST['protokoll']= $formData['protokoll'];
$_POST['note'] = $formData['note'];
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('pruefungstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
@@ -261,19 +296,19 @@ class Abschlusspruefung extends FHCAPI_Controller
$result = $this->AbschlusspruefungModel->insert([
'student_uid' => $student_uid,
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'akadgrad_id' => $this->input->post('akadgrad_id'),
'vorsitz' => $this->input->post('vorsitz'),
'pruefungsantritt_kurzbz' => $this->input->post('pruefungsantritt_kurzbz'),
'abschlussbeurteilung_kurzbz' => $this->input->post('abschlussbeurteilung_kurzbz'),
'datum' => $this->input->post('datum'), //TODO(Manu) check if minute format like FAS
'sponsion' => $this->input->post('sponsion'),
'pruefer1' => $this->input->post('pruefer1'),
'pruefer2' => $this->input->post('pruefer2'),
'pruefer3' => $this->input->post('pruefer3'),
'protokoll' => $this->input->post('protokoll'),
'note' => $this->input->post('note'),
'anmerkung' => $this->input->post('anmerkung'),
'pruefungstyp_kurzbz' => $formData['pruefungstyp_kurzbz'],
'akadgrad_id' => $formData['akadgrad_id'],
'vorsitz' => $formData['vorsitz'],
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $formData['datum'], //TODO(Manu) check if minute format like FAS
'sponsion' => $formData['sponsion'],
'pruefer1' => $formData['pruefer1'],
'pruefer2' => $formData['pruefer2'],
'pruefer3' => $formData['pruefer3'],
'protokoll' => $formData['protokoll'],
'note' => $formData['note'],
'anmerkung' => $formData['anmerkung'],
'insertamum' => date('c'),
'insertvon' => getAuthUID()
]);
@@ -295,25 +330,17 @@ class Abschlusspruefung extends FHCAPI_Controller
}
$formData = $this->input->post('formData');
$_POST['student_uid'] = $formData['student_uid'];
$_POST['pruefungstyp_kurzbz'] = $formData['pruefungstyp_kurzbz'];
$_POST['akadgrad_id']= $formData['akadgrad_id'];
$_POST['vorsitz'] = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz'];
$_POST['pruefer1'] = isset($formData['pruefer1']['person_id']) ? $formData['pruefer1']['person_id'] : $formData['pruefer1'];
$_POST['pruefer2'] = isset($formData['pruefer2']['person_id']) ? $formData['pruefer2']['person_id'] : $formData['pruefer2'];
$_POST['pruefer3'] = isset($formData['pruefer3']['person_id']) ? $formData['pruefer3']['person_id'] : $formData['pruefer3'];
$_POST['pruefungsantritt_kurzbz'] = $formData['pruefungsantritt_kurzbz'];
$_POST['abschlussbeurteilung_kurzbz'] = $formData['abschlussbeurteilung_kurzbz'];
$_POST['datum']= $formData['datum'];
$_POST['sponsion']= $formData['sponsion'];
$_POST['anmerkung'] = $formData['anmerkung'];
$_POST['protokoll']= $formData['protokoll'];
$_POST['note'] = $formData['note'];
$vorsitz = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz'];
$pruefer1 = isset($formData['pruefer1']['person_id']) ? $formData['pruefer1']['person_id'] : $formData['pruefer1'];
$pruefer2 = isset($formData['pruefer2']['person_id']) ? $formData['pruefer2']['person_id'] : $formData['pruefer2'];
$pruefer3 = isset($formData['pruefer3']['person_id']) ? $formData['pruefer3']['person_id'] : $formData['pruefer3'];
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('pruefungstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('akadgrad_id', 'AkadGrad', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'AkadGrad'])
]);
@@ -334,25 +361,25 @@ class Abschlusspruefung extends FHCAPI_Controller
$result = $this->AbschlusspruefungModel->update(
[
'abschlusspruefung_id' => $abschlusspruefung_id
'abschlusspruefung_id' => $abschlusspruefung_id
],
[
'student_uid' => $this->input->post('student_uid'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'akadgrad_id' => $this->input->post('akadgrad_id'),
'vorsitz' => $this->input->post('vorsitz'),
'pruefungsantritt_kurzbz' => $this->input->post('pruefungsantritt_kurzbz'),
'abschlussbeurteilung_kurzbz' => $this->input->post('abschlussbeurteilung_kurzbz'),
'datum' => $this->input->post('datum'),
'sponsion' => $this->input->post('sponsion'),
'pruefer1' => $this->input->post('pruefer1'),
'pruefer2' => $this->input->post('pruefer2'),
'pruefer3' => $this->input->post('pruefer3'),
'protokoll' => $this->input->post('protokoll'),
'note' => $this->input->post('note'),
'anmerkung' => $this->input->post('anmerkung'),
'insertamum' => date('c'),
'insertvon' => getAuthUID()
'student_uid' => $formData['student_uid'],
'pruefungstyp_kurzbz' => $formData['pruefungstyp_kurzbz'],
'akadgrad_id' => $formData['akadgrad_id'],
'vorsitz' => $vorsitz,
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $formData['datum'],
'sponsion' => $formData['sponsion'],
'pruefer1' => $pruefer1,
'pruefer2' => $pruefer2,
'pruefer3' => $pruefer3,
'protokoll' => $formData['protokoll'],
'note' => $formData['note'],
'anmerkung' => $formData['anmerkung'],
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
@@ -417,4 +444,58 @@ 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);
}
}
@@ -31,6 +31,11 @@ class Address extends FHCAPI_Controller
'getNations' => self::PERM_LOGGED,
'getPlaces' => self::PERM_LOGGED
]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getNations()
@@ -53,7 +58,11 @@ class Address extends FHCAPI_Controller
$this->form_validation->set_data(['address.plz' => $plz]);
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]');
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']),
'less_than' => $this->p->t('ui', 'error_fieldLessThan10000', ['field' => 'PLZ'])
]);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
@@ -0,0 +1,70 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Controller for downloading Akte
*/
class Akte extends Auth_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'download' => ['admin:w', 'assistenz:w'],
]);
// Load models
$this->load->model('crm/Akte_model', 'AkteModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*
* Downloads an Akte
*/
public function download()
{
$akte_id = $this->input->get('akte_id');
if (!is_numeric($akte_id)) $this->terminateWithError('akte Id missing');
$result = $this->AkteModel->load($akte_id);
if (!hasData($result)) $this->terminateWithError('Akte not found');
$data = getData($result)[0];
if (isset($data->inhalt) && $data->inhalt != '')
{
header('Content-Description: File Transfer');
header('Content-Type: '. $data->mimetype);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Disposition: attachment; filename="'.$data->titel.'"');
echo base64_decode($data->inhalt);
die();
}
}
}
@@ -0,0 +1,256 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Anrechnungen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAnrechnungen' => ['admin:r', 'assistenz:r'],
'deleteAnrechnung' => ['admin:rw', 'assistenz:rw'],
'getLehrveranstaltungen' => ['admin:r', 'assistenz:r'],
'getBegruendungen' => ['admin:r', 'assistenz:r'],
'getLektoren' => ['admin:r', 'assistenz:r'],
'getLvsKompatibel' => ['admin:r', 'assistenz:r'],
'insertAnrechnung' => ['admin:rw', 'assistenz:rw'],
'loadAnrechnung' => ['admin:rw', 'assistenz:rw'],
'updateAnrechnung' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui', 'lehre'
]);
// Load models
$this->load->model('education/Anrechnung_model', 'AnrechnungsModel');
}
public function getAnrechnungen($prestudent_id)
{
$result = $this->AnrechnungsModel->getAnrechnungsData($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getBegruendungen()
{
$this->load->model('education/Anrechnungbegruendung_model', 'AnrechnungbegrueundungsModel');
$result = $this->AnrechnungbegrueundungsModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getLehrveranstaltungen($prestudent_id)
{
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$result = $this->PrestudentstatusModel->getLastStatus($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$studienplan_id = current($data)->studienplan_id;
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudienplanId($studienplan_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLvsKompatibel($lehrveranstaltung_id)
{
$this->AnrechnungsModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'ON (lv.lehrveranstaltung_id = lehre.tbl_anrechnung.lehrveranstaltung_id)');
$result = $this->AnrechnungsModel->loadWhere(
['lehrveranstaltung_id_kompatibel' => $lehrveranstaltung_id]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLektoren($studiengang_kz)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->getLektoren($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function insertAnrechnung()
{
$this->load->library('form_validation');
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$_POST['lehrveranstaltung_id'] =
(isset($formData['lehrveranstaltung_id']) && !empty($formData['lehrveranstaltung_id']))
? $formData['lehrveranstaltung_id']
: null;
$_POST['lehrveranstaltung_id_kompatibel'] =
(isset($formData['lehrveranstaltung_id_kompatibel']) && !empty($formData['lehrveranstaltung_id_kompatibel']))
? $formData['lehrveranstaltung_id_kompatibel']
: null;
$_POST['begruendung'] =
(isset($formData['begruendung_id']) && !empty($formData['begruendung_id']))
? $formData['begruendung_id']
: null;
$_POST['genehmigtVon'] = (isset($formData['genehmigt_von']) && !empty($formData['genehmigt_von']))
? $formData['genehmigt_von']
: null;
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung'])
]);
$this->form_validation->set_rules('begruendung', 'Begruendung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Begruendung'])
]);
if($_POST['begruendung'] == 2)
{
$this->form_validation->set_rules('lehrveranstaltung_id_kompatibel', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung Kompatibel'])
]);
}
$this->form_validation->set_rules('genehmigtVon', 'GenehmigtVon', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'GenehmigtVon'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AnrechnungsModel->insert(
[
'prestudent_id' => $prestudent_id,
'lehrveranstaltung_id' => $_POST['lehrveranstaltung_id'],
'lehrveranstaltung_id_kompatibel' => $_POST['lehrveranstaltung_id_kompatibel'],
'begruendung_id' => $_POST['begruendung'],
'genehmigt_von' => $_POST['genehmigtVon']
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAnrechnung($anrechnung_id)
{
$this->AnrechnungsModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'ON (lv.lehrveranstaltung_id = lehre.tbl_anrechnung.lehrveranstaltung_id)');
$result = $this->AnrechnungsModel->loadWhere(
array('anrechnung_id' => $anrechnung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function updateAnrechnung()
{
$this->load->library('form_validation');
$anrechnung_id = $this->input->post('anrechnung_id');
if(!$anrechnung_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Anrechnung UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$_POST['lehrveranstaltung_id'] =
(isset($formData['lehrveranstaltung_id']) && !empty($formData['lehrveranstaltung_id']))
? $formData['lehrveranstaltung_id']
: null;
$_POST['lehrveranstaltung_id_kompatibel'] =
(isset($formData['lehrveranstaltung_id_kompatibel']) && !empty($formData['lehrveranstaltung_id_kompatibel']))
? $formData['lehrveranstaltung_id_kompatibel']
: null;
$_POST['begruendung'] = (isset($formData['begruendung_id']) && !empty($formData['begruendung_id'])) ? $formData['begruendung_id'] : null;
$_POST['genehmigtVon'] = (isset($formData['genehmigt_von']) && !empty($formData['genehmigt_von'])) ? $formData['genehmigt_von'] : null;
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung'])
]);
$this->form_validation->set_rules('begruendung', 'Begruendung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Begruendung'])
]);
if($_POST['begruendung'] == 2)
{
$this->form_validation->set_rules('lehrveranstaltung_id_kompatibel', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung Kompatibel'])
]);
}
$this->form_validation->set_rules('genehmigtVon', 'GenehmigtVon', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'GenehmigtVon'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AnrechnungsModel->update(
[
'anrechnung_id' => $anrechnung_id,
],
[
'lehrveranstaltung_id' => $_POST['lehrveranstaltung_id'],
'lehrveranstaltung_id_kompatibel' => $_POST['lehrveranstaltung_id_kompatibel'],
'begruendung_id' => $_POST['begruendung'],
'genehmigt_von' => $_POST['genehmigtVon']
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAnrechnung($anrechnung_id)
{
// Start DB transaction
$this->db->trans_begin();
//delete anrechnung_id of table tbl_anrechnung_anrechnungstatus
$this->load->model('education/Anrechnunganrechnungstatus_model','AnrechnungAnrechnungstatusModel');
$result = $this->AnrechnungAnrechnungstatusModel->delete(
array('anrechnung_id' => $anrechnung_id)
);
$this->getDataOrTerminateWithError($result);
//delete anrechnung_id of table tbl_anrechnung
$result = $this->AnrechnungsModel->delete(
array('anrechnung_id' => $anrechnung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->db->trans_commit();
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,272 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
use CI3_Events as Events;
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about archive documents
* Listens to ajax post calls to change the archive documents
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Archiv extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'get' => ['admin:r', 'assistenz:r'],
'getArchivVorlagen' => ['admin:r', 'assistenz:r'],
'archive' => ['admin:w', 'assistenz:w'],
'download' => ['admin:w', 'assistenz:w'],
'update' => ['admin:w'],
'delete' => ['admin:w', 'assistenz:w']
]);
// Load models
$this->load->model('crm/Akte_model', 'AkteModel');
$this->load->model('system/Vorlage_model', 'VorlageModel');
// Load language phrases
$this->loadPhrases([
'archiv'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Get archive documents for a person
* @return void
*/
public function get()
{
$person_id = $this->input->post('person_id');
$this->load->library('form_validation');
if (!$person_id || !is_array($person_id))
{
$this->form_validation->set_rules('person_id', 'Person ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AkteModel->getArchiv($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* Get Vorlagen for archiving documents
* @return void
*/
public function getArchivVorlagen()
{
$result = $this->VorlageModel->getArchivVorlagen();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
*
* @param
* @return object success or error
*/
public function download()
{
$akte_id = $this->input->get('akte_id');
if (!is_numeric($akte_id)) $this->terminateWithError('akte Id missing');
$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 != '')
{
// Define handle to output stream
$tmpFilePointer = fopen("php://output", 'w');
$meta_data = stream_get_meta_data($tmpFilePointer);
$filename = $meta_data["uri"];
fwrite($tmpFilePointer, $data->inhalt);
header('Content-Description: File Transfer');
header('Content-Type: '. $data->mimetype);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: ' . filesize($fileObj->file));
//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
{
$this->load->library('AkteLib');
$result = $this->aktelib->get($akte_id);
}
/* $fileObj->filename
* $fileObj->file
* $fileObj->name
* $fileObj->mimetype
* $fileObj->disposition*/
}
/**
* Updating an Akte
* @return void
*/
public function update()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('akte_id', 'Akte Id', 'required');
$this->form_validation->set_rules('signiert', 'Signiert', 'is_bool');
$this->form_validation->set_rules('stud_selfservice', 'Self-Service', 'is_bool');
//Events::trigger('konto_update_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = $this->input->post('akte_id');
// get the akte
$result = $this->AkteModel->load($id);
if (!hasData($result)) $this->terminateWithError("Akte not found!");
$akte = getData($result)[0];
$allowed = [
'signiert',
'stud_selfservice'
];
$data = [
'updateamum' => date('c'),
'updatevon' => getAuthUID()
];
// if Akte has Inhalt directly in Akte table
if (isset($_FILES['datei']['tmp_name']))
{
$this->addMeta('read', "read");
// update inhalt directly
// get tmp file
$filename = $_FILES['datei']['tmp_name'];
// open it
$fp = fopen($filename,'r');
// read it
$content = fread($fp, filesize($filename));
fclose($fp);
// encode it
$data['inhalt'] = base64_encode($content);
$this->addMeta('content', base64_encode($content));
}
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field);
$this->addMeta("data", $data);
$result = $this->AkteModel->update($id, $data);
$this->getDataOrTerminateWithError($result);
$result = null;
$this->terminateWithSuccess($result);
}
/**
* Delete archived Akte
*
* @return void
*/
public function delete()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('akte_id', 'Akte ID', 'required');
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'has_permissions_for_stg[admin:rw,assistenz:rw]');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$akte_id = $this->input->post('akte_id');
$result = $this->AkteModel->load($akte_id);
if (!hasData($result))
{
$this->terminateWithError($this->p->t('archiv', 'error_missing', [
'akte_id' => $akte_id
]));
}
$result = getData($result)[0];
if ($result->dokument_kurzbz == 'Ausbvert'
&& isset($result->akzeptiertamum)
&& !isEmptyString($result->akzeptiertamum)
&& !has_permissions_for_stg($this->input->post('studiengang_kz'), 'admin:rw')
)
{
$this->terminateWithError($this->p->t('archiv', 'nur_admins_loschen_ausbildungsvertraege', [
'akte_id' => $akte_id
]));
}
$result = $this->AkteModel->delete($akte_id);
if (isError($result)) $this->terminateWithError(getError($result));
$this->terminateWithSuccess();
}
}
@@ -0,0 +1,413 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Aufnahmetermine extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAufnahmetermine' => ['admin:r', 'assistenz:r'],
'loadAufnahmetermin' => ['admin:r', 'assistenz:r'],
'insertAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
'updateAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
'deleteAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
'getListPlacementTests' => ['admin:r', 'assistenz:r'],
'getListStudyPlans' => ['admin:r', 'assistenz:r'],
'loadDataRtPrestudent' => ['admin:r', 'assistenz:r'],
'insertOrUpdateDataRtPrestudent' => ['admin:r', 'assistenz:r'],
'loadAufnahmegruppen' => ['admin:r', 'assistenz:r'],
'getResultReihungstest' => ['admin:r', 'assistenz:r'],
'getZukuenftigeReihungstestStg' => ['admin:r', 'assistenz:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'admission'
]);
// Load models
$this->load->model('crm/Reihungstest_model', 'ReihungstestModel');
$this->load->model('crm/RtPerson_model', 'RtPersonModel');
}
public function getAufnahmetermine($person_id)
{
$result = $this->ReihungstestModel->getReihungstestPerson($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function insertAufnahmetermin()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$formData = $this->input->post('formData');
$person_id = $this->input->post('person_id');
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
$rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null;
$anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null;
$teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false;
$studienplan_id = (isset($formData['studienplan_id']) && !empty($formData['studienplan_id'])) ? $formData['studienplan_id'] : null;
$punkte = (isset($formData['punkte']) && !empty($formData['punkte'])) ? $formData['punkte'] : null;
//validation if there is already an RT with chosen data existing
$result = $this->RtPersonModel->loadWhere(
array(
'rt_id' => $rt_id,
'person_id' => $person_id,
'studienplan_id' => $studienplan_id,
)
);
$data = getData($result);
if($data)
return $this->terminateWithError("Error", self::ERROR_TYPE_GENERAL);
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('punkte', 'Punkte', 'numeric', [
'required' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Punkte'])
]);
$this->form_validation->set_rules('studienplan_id', 'studienplan_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studienplan'])
]);
$this->form_validation->set_rules('rt_id', 'Reihungstest_id', 'required', [
'is_valid_date' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Reihungstest'])
]);
$this->form_validation->set_rules('anmeldedatum', 'AnmeldeDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Anmeldedatum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->RtPersonModel->insert([
'person_id' => $person_id,
'rt_id' => $rt_id,
'anmeldedatum' => $anmeldedatum,
'teilgenommen' => $teilgenommen,
'studienplan_id' => $studienplan_id,
'punkte' => $punkte,
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAufnahmetermin($rt_person_id)
{
$result = $this->RtPersonModel->loadWhere(
array('rt_person_id' => $rt_person_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function updateAufnahmetermin()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$formData = $this->input->post('formData');
$rt_person_id = $this->input->post('rt_person_id');
$person_id = (isset($formData['person_id']) && !empty($formData['person_id'])) ? $formData['person_id'] : null;
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
if(!$rt_person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'RT_Person ID']), self::ERROR_TYPE_GENERAL);
}
$rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null;
$anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null;
$teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false;
$studienplan_id = (isset($formData['studienplan_id']) && !empty($formData['studienplan_id'])) ? $formData['studienplan_id'] : null;
$punkte = (isset($formData['punkte']) && !empty($formData['punkte'])) ? $formData['punkte'] : null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('punkte', 'Punkte', 'numeric', [
'required' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Punkte'])
]);
$this->form_validation->set_rules('studienplan_id', 'studienplan_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studienplan'])
]);
$this->form_validation->set_rules('rt_id', 'Reihungstest_id', 'required', [
'is_valid_date' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Reihungstest'])
]);
$this->form_validation->set_rules('anmeldedatum', 'AnmeldeDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Anmeldedatum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->RtPersonModel->update(
[
'rt_person_id' => $rt_person_id,
],
[
'rt_id' => $rt_id,
'anmeldedatum' => $anmeldedatum,
'teilgenommen' => $teilgenommen,
'studienplan_id' => $studienplan_id,
'punkte' => $punkte,
'insertamum' => date('c'),
'insertvon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAufnahmetermin($rt_person_id)
{
$result = $this->RtPersonModel->delete(
array('rt_person_id' => $rt_person_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getListPlacementTests($prestudent_id)
{
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
//get studienplan array
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->PrestudentstatusModel->addSelect('*');
$this->PrestudentstatusModel->addSelect('sp.studienplan_id');
$this->PrestudentstatusModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
$result = $this->PrestudentstatusModel->loadWhere(
array(
'prestudent_id' => $prestudent_id,
'status_kurzbz' => 'Interessent'
)
);
$data = $this->getDataOrTerminateWithError($result);
$studienplan_arr = [];
$include_ids = [];
foreach ($data as $item)
{
if($item->studienplan_id != null)
$studienplan_arr[] = $item->studienplan_id;
}
//get Placementtests Person
$person_id = $this->_getPersonId($prestudent_id);
$resultRt = $this->ReihungstestModel->getReihungstestPerson($person_id);
$dataRt = $this->getDataOrTerminateWithError($resultRt);
foreach ($dataRt as $item)
{
if(!in_array($item->studienplan_id, $studienplan_arr))
$studienplan_arr[] = $item->studienplan_id;
if(!in_array($item->rt_id, $include_ids) && ($item->rt_id != null))
$include_ids[] = $item->rt_id;
}
$result = $this->ReihungstestModel->getReihungstestByStudyPlanAndIds($studienplan_arr, $include_ids);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getListStudyPlans($person_id)
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$result = $this->StudienplanModel->getStudienplaeneForPerson($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadDataRtPrestudent($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addSelect(["reihungstestangetreten"]);
$this->PrestudentModel->addSelect(["rt_gesamtpunkte"]);
$this->PrestudentModel->addSelect(["aufnahmegruppe_kurzbz"]);
$result = $this->PrestudentModel->loadWhere(
array('prestudent_id' => $prestudent_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function insertOrUpdateDataRtPrestudent()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$formData = $this->input->post('formData');
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$rt_gesamtpunkte =
(isset($formData['rt_gesamtpunkte']) && !empty($formData['rt_gesamtpunkte']))
? $formData['rt_gesamtpunkte']
: null;
$reihungstestangetreten =
(isset($formData['reihungstestangetreten']) && !empty($formData['reihungstestangetreten']))
? $formData['reihungstestangetreten']
: null;
$aufnahmegruppe_kurzbz =
(isset($formData['aufnahmegruppe_kurzbz']) && !empty($formData['aufnahmegruppe_kurzbz']))
? $formData['aufnahmegruppe_kurzbz']
: null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('rt_gesamtpunkte', 'Rt_gesamtpunkte', 'numeric', [
'required' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Rt_gesamtpunkte'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->update(
[
'prestudent_id' => $prestudent_id,
],
[
'reihungstestangetreten' => $reihungstestangetreten,
'rt_gesamtpunkte' => $rt_gesamtpunkte,
'aufnahmegruppe_kurzbz' => $aufnahmegruppe_kurzbz,
'updateamum' => date('c'),
'updatevon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAufnahmegruppen()
{
$uid = $this->input->get('uid');
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$result = $this->BenutzergruppeModel->loadAufnahmegruppen($uid, $studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(($data));
}
public function getResultReihungstest()
{
$person_id = $this->input->get('person_id');
$punkte = $this->input->get('punkte');
$reihungstest_id = $this->input->get('reihungstest_id');
if(!$reihungstest_id)
{
$this->terminateWithSuccess(null);
}
//for gewichtung
$studiengang_kz = $this->input->get('studiengang_kz');
$this->load->model('testtool/Ablauf_model', 'AblaufModel');
$result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$weightedArray = [];
foreach ($data as $abl)
{
$weightedArray[$abl->gebiet_id] = $abl->gewicht;
}
$result = $this->ReihungstestModel->getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray);
/* if (isError($result))
{
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}*/
$this->terminateWithSuccess($result);
}
public function getZukuenftigeReihungstestStg()
{
$studiengang_kz = $this->input->get('studiengang_kz');
if(!$studiengang_kz)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
}
$result = $this->ReihungstestModel->getZukuenftigeReihungstestStg($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
private function _getPersonId($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $prestudent_id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
return $person->person_id;
}
}
@@ -83,6 +83,10 @@ class Config extends FHCAPI_Controller
'title' => 'Status',
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js'
];
$result['documents'] = [
'title' => $this->p->t('stv', 'tab_documents'),
'component' => './Stv/Studentenverwaltung/Details/Dokumente.js'
];
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
@@ -99,6 +103,15 @@ class Config extends FHCAPI_Controller
'title' => $this->p->t('stv', 'tab_resources'),
'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js'
];
$result['groups'] = [
'title' => $this->p->t('stv', 'tab_groups'),
'component' => './Stv/Studentenverwaltung/Details/Gruppen.js'
];
$result['messages'] = [
'title' => $this->p->t('stv', 'tab_messages'),
'component' => './Stv/Studentenverwaltung/Details/Messages.js'
];
$result['grades'] = [
'title' => $this->p->t('stv', 'tab_grades'),
'component' => './Stv/Studentenverwaltung/Details/Noten.js',
@@ -117,6 +130,12 @@ class Config extends FHCAPI_Controller
'component' => './Stv/Studentenverwaltung/Details/Pruefung.js'
];
$result['exemptions'] = [
'title' => $this->p->t('lehre', 'anrechnungen'),
'component' => './Stv/Studentenverwaltung/Details/Anrechnungen.js',
'config' => $config['exemptions']
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
@@ -128,6 +147,34 @@ class Config extends FHCAPI_Controller
'component' => './Stv/Studentenverwaltung/Details/Mobility.js'
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
$result['jointstudies'] = [
'title' => $this->p->t('stv', 'tab_jointstudies'),
'component' => './Stv/Studentenverwaltung/Details/JointStudies.js'
];
$result['coursedates'] = [
'title' => $this->p->t('stv', 'tab_courseDates'),
'component' => './Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine.js'
];
$result['admissionDates'] = [
'title' => $this->p->t('stv', 'tab_admissionDates'),
'component' => './Stv/Studentenverwaltung/Details/Aufnahmetermine.js'
];
$result['functions'] = [
'title' => $this->p->t('stv', 'tab_functions'),
'component' => './Stv/Studentenverwaltung/Details/Funktionen.js'
];
Events::trigger('stv_conf_student', function & () use (&$result) {
return $result;
});
@@ -163,10 +210,17 @@ class Config extends FHCAPI_Controller
]
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'config' => $config['finalexam']
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
Events::trigger('stv_conf_students', function & () use (&$result) {
return $result;
@@ -303,7 +357,7 @@ class Config extends FHCAPI_Controller
$title_eng = $this->p->t("global", "englisch");
$title_ff = $this->p->t("stv", "document_certificate");
$title_lv = $this->p->t("stv", "document_coursecertificate");
$link_ff = "documents/export/" .
"zertifikat.rdf.php/" .
"Zertifikat" .
@@ -0,0 +1,569 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Dokumente extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getDocumentsUnaccepted' => ['admin:r', 'assistenz:r'],
'getDocumentsAccepted' => ['admin:r', 'assistenz:r'],
'deleteZuordnung' => ['admin:rw', 'assistenz:rw'],
'createZuordnung' => ['admin:rw', 'assistenz:rw'],
'loadAkte' => ['admin:rw', 'assistenz:rw'],
'deleteAkte' => ['admin:rw', 'assistenz:rw'],
'updateAkte' => ['admin:rw', 'assistenz:rw'],
'getDoktypen' => ['admin:r', 'assistenz:r'],
'uploadDokument' => ['admin:rw', 'assistenz:rw'],
'download' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->load->library('DmsLib', array('who' => getAuthUID()));
// Load language phrases
$this->loadPhrases([
'ui',
'dokumente'
]);
// Load models
$this->load->model('crm/Akte_model', 'AkteModel');
$this->load->model('crm/Dokument_model', 'DokumentModel');
$this->load->model('crm/Dokumentprestudent_model', 'DokumentprestudentModel');
//TODO(Manu) check additional Berechtigungen
//TODO(Manu) check if using dokument lib instead of dokument model?
}
public function getDocumentsUnaccepted($prestudent_id, $studiengang_kz)
{
if(!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($prestudent_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$studiengang_kz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
$person_id = $this->_getPersonId($prestudent_id);
$result = $this->DokumentModel->getUnacceptedDocuments($prestudent_id, $person_id);
$dataAkteUnaccepted = $this->getDataOrTerminateWithError($result);
$resultMd = $this->_getMissingDocuments($studiengang_kz, $prestudent_id);
$data = $this->_mergeDocuments($dataAkteUnaccepted, $resultMd);
$this->terminateWithSuccess($data);
}
public function getDocumentsAccepted($prestudent_id, $studiengang_kz)
{
if(!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($prestudent_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$studiengang_kz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
$resultPreDoc = $this->_getPrestudentDokumente($prestudent_id);
$arrayAccepted = [];
$person_id = $this->_getPersonId($prestudent_id);
$docNames = array_map(function ($item) {
return $item->dokument_kurzbz;
}, $resultPreDoc);
foreach($docNames as $doc)
{
$result = $this->AkteModel->getAktenFAS($person_id, $doc, $studiengang_kz, $prestudent_id, true);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (hasData($result))
{
$data = getData($result);
foreach ($data as $value)
{
array_push($arrayAccepted, $value);
}
}
}
//Mapping with document_kurzbz
$preDocMap = [];
foreach ($resultPreDoc as $pre) {
$preDocMap[$pre->dokument_kurzbz] = $pre;
}
$mergedArray = [];
foreach ($arrayAccepted as $doc) {
$merged = clone $doc;
if (isset($preDocMap[$doc->dokument_kurzbz])) {
$merged->docdatum = $preDocMap[$doc->dokument_kurzbz]->docdatum;
$merged->insertvonma = $preDocMap[$doc->dokument_kurzbz]->insertvonma;
$merged->bezeichnung = $preDocMap[$doc->dokument_kurzbz]->bezeichnung;
} else {
$merged->akzeptiertdatum = null;
$merged->akzeptiertvon = null;
}
$mergedArray[] = $merged;
}
$this->terminateWithSuccess($mergedArray);
}
public function deleteZuordnung($prestudent_id, $dokument_kurzbz)
{
if(!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($prestudent_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$dokument_kurzbz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Dokument_kurzbz']), self::ERROR_TYPE_GENERAL);
$result = $this->DokumentprestudentModel->delete(
[
'prestudent_id' => $prestudent_id,
'dokument_kurzbz' => $dokument_kurzbz
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAkte($akte_id)
{
if (!$akte_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
$this->AkteModel->addSelect('public.tbl_akte.*');
$this->AkteModel->addSelect("CONCAT(public.tbl_person.vorname, ' ' , public.tbl_person.nachname) AS namePerson");
$this->AkteModel->addJoin('public.tbl_person', 'person_id');
$result = $this->AkteModel->loadWhere(
[
'akte_id' => $akte_id,
]
);
$data = $this->getDataOrTerminateWithError($result);
$data = current($data);
$this->terminateWithSuccess($data);
}
public function updateAkte()
{
$this->form_validation->set_rules('akte_id', 'Akte ID', 'required', [
'required' => $this->p->t('dokumente', 'err_updateNotAllowed')
]);
$this->form_validation->set_rules('dokument_kurzbz', 'Dokumenttyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Dokumenttyp'])
]);
$this->form_validation->set_rules('nachreichung_am', 'Nachreichung am', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Nachreichung am'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$uid = getAuthUID();
$result = $this->AkteModel->update(
[
'akte_id' => $this->input->post('akte_id'),
],
[
'dokument_kurzbz' => $this->input->post('dokument_kurzbz'),
'anmerkung_intern' => $this->input->post('anmerkung_intern'),
'titel_intern' => $this->input->post('titel_intern'),
'nachgereicht_am' => $this->input->post('nachgereicht_am'),
'updateamum' => date('c'),
'updatevon' => $uid,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function createZuordnung($prestudent_id, $dokument_kurzbz)
{
if (!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$dokument_kurzbz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Dokument_kurzbz']), self::ERROR_TYPE_GENERAL);
$uid = getAuthUid();
//check if more than 1 dokumentkurzbz
//if()
$result = $this->DokumentprestudentModel->insert(
[
'prestudent_id' => $prestudent_id,
'dokument_kurzbz' => $dokument_kurzbz,
'mitarbeiter_uid' => $uid,
'datum' => date('c'),
'insertamum' => date('c'),
'insertvon' => $uid,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAkte($akte_id)
{
if (!$akte_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
$result = $this->AkteModel->load($akte_id);
$dataAkte = $this->getDataOrTerminateWithError($result);
$logdata_akte = var_export($dataAkte, true);
$dms_id = current($dataAkte)->dms_id;
$nachgereicht = current($dataAkte)->nachgereicht;
$inhalt = current($dataAkte)->inhalt;
$inhaltVorhanden = $inhalt != '';
$uid = getAuthUid();
$this->db->trans_start();
if($dms_id)
{
$this->load->model('content/Dms_model', 'DmsModel');
$result = $this->DmsModel->load($dms_id);
$data = $this->getDataOrTerminateWithError($result);
$logdata_dms = (array)$data;
$logdata_dms = "Logdata: " . var_export($logdata_dms, true);
//delete from dmsLib
$this->load->library('DmsLib');
$person_id = current($dataAkte)->person_id;
$result = $this->dmslib->delete($person_id, $dms_id);
$this->getDataOrTerminateWithError($result);
//LOGGING Dms ID
$this->load->model('system/Log_model', 'LogModel');
$result = $this->LogModel->insert([
'executetime' => date('c'),
'mitarbeiter_uid' => $uid,
'beschreibung' => "Löschen der DMS_ID ". $dms_id,
'sql' => $logdata_dms
]);
$this->getDataOrTerminateWithError($result);
//delete akte
$result = $this->AkteModel->delete(
[
'akte_id' => $akte_id
]
);
$data = $this->getDataOrTerminateWithError($result);
//Logging Deletion Akte
$result = $this->LogModel->insert([
'executetime' => date('c'),
'mitarbeiter_uid' => $uid,
'beschreibung' => "Löschen der Akte ". $akte_id,
'sql' => "DELETE FROM public.tbl_akte WHERE akte_id=" .$akte_id. " LogData: ". $logdata_akte
]);
$this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
elseif (!!$dms_id || ($nachgereicht && !$inhaltVorhanden))
{
$result = $this->AkteModel->delete(
[
'akte_id' => $akte_id
]
);
$data = $this->getDataOrTerminateWithError($result);
$result = $this->LogModel->insert([
'executetime' => date('c'),
'mitarbeiter_uid' => $uid,
'beschreibung' => "Löschen der Akte ". $akte_id,
'sql' => "DELETE FROM public.tbl_akte WHERE akte_id=" .$akte_id. " LogData: ". $logdata_akte
]);
$this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
else
$this->terminateWithError($this->p->t('dokumente', 'err_deleteDokHere'), self::ERROR_TYPE_GENERAL);
}
public function uploadDokument()
{
$this->load->library('DmsLib');
$prestudent_id = $this->input->post('prestudent_id');
$anmerkung_intern = $this->input->post('anmerkung_intern');
$titel_intern = $this->input->post('titel_intern');
$dokument_kurzbz = $this->input->post('dokument_kurzbz');
$this->form_validation->set_rules('prestudent_id', 'Prestudent_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Prestudent ID'])
]);
$this->form_validation->set_rules('dokument_kurzbz', 'Dokumenttyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Dokumenttyp'])
]);
//validation if attachment was added
$this->form_validation->set_rules('anhang', 'Attachment', 'callback_file_check');
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->db->trans_start();
$uid = getAuthUID();
$dms = array(
'kategorie_kurzbz' => 'Akte',
'version' => 0,
'name' => $_FILES['anhang']['name'],
'mimetype' => $_FILES['anhang']['type'],
'insertamum' => date('c'),
'insertvon' => $uid
);
$result = $this->dmslib->upload($dms, 'anhang', array("jpg", "png", "pdf"));
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$dms_id = $result->retval['dms_id'];
$person_id = $this->_getPersonId($prestudent_id);
$result = $this->DokumentModel->load($dokument_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$bezeichnung = current($data)->bezeichnung;
//save entry in akte
if($dms_id)
{
$result = $this->AkteModel->insert([
'person_id' => $person_id,
'dms_id' => $dms_id,
'dokument_kurzbz' => $dokument_kurzbz,
'mimetype' => $_FILES['anhang']['type'],
'insertamum' => date('c'),
'erstelltam' => date('c'),
'insertvon' => $uid,
'anmerkung_intern' => $anmerkung_intern,
'titel_intern' => $titel_intern,
'bezeichnung' => $bezeichnung,
'titel' => $_FILES['anhang']['name']
]);
$data = $this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
public function getDoktypen()
{
$this->DokumentModel->addSelect('dokument_kurzbz');
$this->DokumentModel->addSelect('bezeichnung');
$this->DokumentModel->addOrder('dokument_kurzbz', 'ASC');
$result = $this->DokumentModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function download()
{
//TODO(Manu) check filetype, Decoding
$akte_id = $this->input->get('akte_id');
if(!$akte_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($akte_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
$result = $this->AkteModel->load($akte_id);
if (!hasData($result)) $this->terminateWithError('Akte not found');
$data = getData($result)[0];
$mimetype = $data->mimetype;
$filecontentbase64 = $data->inhalt;
$filename = $data->titel;
if(intval($data->dms_id) > 0)
{
$dmsdokres = $this->dmslib->read($data->dms_id);
if (!hasData($dmsdokres)) $this->terminateWithError('DMS File not found');
$dmsdok = getData($dmsdokres)[0];
$mimetype = $dmsdok->mimetype;
$filecontentbase64 = $dmsdok->file_content;
$filename = $dmsdok->name;
}
$filecontent = '';
if (!empty($filecontentbase64)) {
$filecontent = base64_decode($filecontentbase64, true);
if ($filecontent === false) {
$this->terminateWithError('Base64-Dekodierung failed.');
}
}
$this->terminateWithFileOutput($mimetype, $filecontent, $filename);
}
private function _getMissingDocuments($studiengang_kz, $prestudent_id)
{
$result = $this->DokumentModel->getMissingDocuments($studiengang_kz, $prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
private function _getUnacceptedDocuments($prestudent_id)
{
$person_id = $this->_getPersonId($prestudent_id);
$result = $this->DokumentModel->getUnacceptedDocuments($prestudent_id, $person_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
/**
* helper function for merging objects
* sorts object after merging according to dokument_kurzbz
* @param $original object of documents of akte
* @param object $toMerge documents to merge (of dokumentprestudent, dokumentstudiengang)
* @return Array mergedObject
*/
private function _mergeDocuments($original, $toMerge)
{
$existingKurzbez = [];
foreach ($original as $doc) {
$existingKurzbez[$doc->dokument_kurzbz] = true;
}
foreach ($toMerge as $doc) {
if (!isset($existingKurzbez[$doc->dokument_kurzbz])) {
$original[] = $doc;
$existingKurzbez[$doc->dokument_kurzbz] = true;
}
else
{
foreach($original as $docOriginal)
{
if ($docOriginal->dokument_kurzbz == $doc->dokument_kurzbz)
{
$docOriginal->pflicht = $doc->pflicht;
$docOriginal->onlinebewerbung = $doc->onlinebewerbung;
}
}
}
}
usort($original, function ($a, $b) {
return strcmp($a->dokument_kurzbz, $b->dokument_kurzbz);
});
return $original;
}
private function _getDocumentsOfAkte($person_id)
{
$result = $this->AkteModel->getAktenFAS($person_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
private function _getPrestudentDokumente($prestudent_id)
{
$result = $this->DokumentprestudentModel->getPrestudentDokumente($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
private function _getPersonId($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $prestudent_id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
return $person->person_id;
}
public function file_check($str)
{
if (isset($_FILES['anhang']) && $_FILES['anhang']['size'] > 0)
{
$allowed_mime_types = ['image/jpeg', 'image/png', 'application/pdf'];
$mime = mime_content_type($_FILES['anhang']['tmp_name']);
if (in_array($mime, $allowed_mime_types))
{
return true;
} else
{
$this->form_validation->set_message('file_check', $this->p->t('dokumente', 'error_fileType'));
return false;
}
}
else
{
$this->form_validation->set_message('file_check', $this->p->t('dokumente', 'error_fileMissing'));
return false;
}
}
}
@@ -0,0 +1,287 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class GemeinsameStudien extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getStudien' => ['admin:r', 'assistenz:r'],
'loadStudie' => ['admin:r', 'assistenz:r'],
'insertStudie' => ['admin:rw', 'assistenz:rw'],
'updateStudie' => ['admin:rw', 'assistenz:rw'],
'deleteStudie' => ['admin:rw', 'assistenz:rw'],
'getProgramsStudien' => ['admin:r', 'assistenz:r'],
'getTypenMobility' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getStudienprogramme' => ['admin:r', 'assistenz:r'],
'getPartnerfirmen' => ['admin:r', 'assistenz:r'],
'getStatiPrestudent' => ['admin:r', 'assistenz:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'jointstudies'
]);
// Load models
$this->load->model('codex/Mobilitaet_model', 'MobilitaetModel');
//TODO(check if additional Permissions necessary): 'student/stammdaten'
}
public function getStudien($prestudent_id)
{
$this->MobilitaetModel->addSelect('mobilitaet_id');
$this->MobilitaetModel->addSelect('mobilitaetstyp_kurzbz');
$this->MobilitaetModel->addSelect('prestudent_id');
$this->MobilitaetModel->addSelect('studiensemester_kurzbz');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.mobilitaetsprogramm_code');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.gsprogramm_id');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.firma_id');
$this->MobilitaetModel->addSelect('status_kurzbz');
$this->MobilitaetModel->addSelect('ausbildungssemester');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.insertvon');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.insertamum');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.updatevon');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.updateamum');
$this->MobilitaetModel->addSelect('mp.kurzbz');
$this->MobilitaetModel->addSelect('gp.gsprogrammtyp_kurzbz');
$this->MobilitaetModel->addSelect('gp.bezeichnung as studienprogramm');
$this->MobilitaetModel->addSelect('f.name as partner');
$this->MobilitaetModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_mobilitaet.mobilitaetsprogramm_code)', 'LEFT');
$this->MobilitaetModel->addJoin('bis.tbl_gsprogramm gp', 'ON (gp.gsprogramm_id = bis.tbl_mobilitaet.gsprogramm_id)', 'LEFT');
$this->MobilitaetModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = bis.tbl_mobilitaet.firma_id)', 'LEFT');
$result = $this->MobilitaetModel->loadWhere([
'prestudent_id' => $prestudent_id,
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getTypenMobility()
{
$this->load->model('codex/Mobilitaetstyp_model', 'MobilitaetstypModel');
$result = $this->MobilitaetstypModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStudiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('studienjahr_kurzbz', 'DESC');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStudienprogramme()
{
$this->load->model('codex/Gsprogramm_model', 'GsprogrammModel');
$result = $this->GsprogrammModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getPartnerfirmen()
{
$this->load->model('ressource/Firma_model', 'FirmaModel');
$result = $this->FirmaModel->loadWhere(
['partner_code !=' => null]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStatiPrestudent()
{
$this->load->model('crm/Status_model', 'StatusModel');
$result = $this->StatusModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadStudie($mobilitaet_id)
{
$result = $this->MobilitaetModel->load($mobilitaet_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function insertStudie()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$ausbildungssemester = (isset($formData['ausbildungssemester']) && !empty($formData['ausbildungssemester']))
? $formData['ausbildungssemester']
: null;
$mobilitaetstyp_kurzbz = (isset($formData['mobilitaetstyp_kurzbz']) && !empty($formData['mobilitaetstyp_kurzbz']))
? $formData['mobilitaetstyp_kurzbz']
: null;
$studiensemester_kurzbz = (isset($formData['studiensemester_kurzbz']) && !empty($formData['studiensemester_kurzbz']))
? $formData['studiensemester_kurzbz'] : null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('mobilitaetstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester'])
]);
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Ausbildungssemester']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ausbildungssemester']),
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$status_kurzbz = (isset($formData['status_kurzbz']) && !empty($formData['status_kurzbz']))
? $formData['status_kurzbz']
: null;
$mobilitaetsprogramm_code = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code']))
? $formData['mobilitaetsprogramm_code']
: null;
$gsprogramm_id = (isset($formData['gsprogramm_id']) && !empty($formData['gsprogramm_id']))
? $formData['gsprogramm_id']
: null;
$firma_id= (isset($formData['firma_id']) && !empty($formData['firma_id'])) ? $formData['firma_id'] : null;
$result = $this->MobilitaetModel->insert([
'prestudent_id' => $prestudent_id,
'mobilitaetstyp_kurzbz' =>$mobilitaetstyp_kurzbz,
'status_kurzbz' => $status_kurzbz,
'studiensemester_kurzbz' =>$studiensemester_kurzbz,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'gsprogramm_id' => $gsprogramm_id,
'firma_id' => $firma_id,
'ausbildungssemester' =>$ausbildungssemester,
'insertvon' => $authUID,
'insertamum' => date('c'),
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function updateStudie()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$mobilitaet_id = (isset($formData['mobilitaet_id']) && !empty($formData['mobilitaet_id']))
? $formData['mobilitaet_id'] :
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Mobilitaet ID']), self::ERROR_TYPE_GENERAL);
$ausbildungssemester = (isset($formData['ausbildungssemester']) && !empty($formData['ausbildungssemester']))
? $formData['ausbildungssemester']
: null;
$mobilitaetstyp_kurzbz = (isset($formData['mobilitaetstyp_kurzbz']) && !empty($formData['mobilitaetstyp_kurzbz']))
? $formData['mobilitaetstyp_kurzbz']
: null;
$studiensemester_kurzbz = (isset($formData['studiensemester_kurzbz']) && !empty($formData['studiensemester_kurzbz']))
? $formData['studiensemester_kurzbz']
: null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('mobilitaetstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester'])
]);
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Ausbildungssemester']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ausbildungssemester']),
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$status_kurzbz = (isset($formData['status_kurzbz']) && !empty($formData['status_kurzbz'])) ? $formData['status_kurzbz'] : null;
$mobilitaetsprogramm_code = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code']))
? $formData['mobilitaetsprogramm_code']
: null;
$gsprogramm_id = (isset($formData['gsprogramm_id']) && !empty($formData['gsprogramm_id']))
? $formData['gsprogramm_id']
: null;
$firma_id= (isset($formData['firma_id']) && !empty($formData['firma_id'])) ? $formData['firma_id'] : null;
$result = $this->MobilitaetModel->update(
[
'mobilitaet_id' => $mobilitaet_id,
],
[
'prestudent_id' => $prestudent_id,
'mobilitaetstyp_kurzbz' => $mobilitaetstyp_kurzbz,
'status_kurzbz' => $status_kurzbz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'gsprogramm_id' => $gsprogramm_id,
'firma_id' => $firma_id,
'ausbildungssemester' => $ausbildungssemester,
'updatevon' => $authUID,
'updateamum' => date('c'),
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteStudie($mobilitaet_id)
{
if(!$mobilitaet_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Mobilität ID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->MobilitaetModel->delete(
array('mobilitaet_id' => $mobilitaet_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,80 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Gruppen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getGruppen' => ['admin:r', 'assistenz:r'],
'deleteGruppe' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui', 'gruppenmanagement'
]);
// Load models
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
}
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');
$result = $this->BenutzergruppeModel->loadWhere(
array(
'uid' => $student_uid
)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteGruppe()
{
$student_uid = $this->input->post('id');
$gruppe_kurzbz = $this->input->post('gruppe_kurzbz');
//Validate if automatic group generation
$result = $this->GruppeModel-> loadWhere(
array(
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
$data = $this->getDataOrTerminateWithError($result);
$generation = current($data);
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
)
);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($data);
}
}
@@ -28,7 +28,8 @@ class Kontakt extends FHCAPI_Controller
'getStandorte' => ['admin:r', 'assistenz:r'],
'getStandorteByFirma' => ['admin:r', 'assistenz:r'],
'getKontakte' => ['admin:r', 'assistenz:r'],
'getBankverbindung' => ['mitarbeiter/bankdaten:r', 'student/bankdaten:r']
'getBankverbindung' => ['mitarbeiter/bankdaten:r', 'student/bankdaten:r'],
'getAllFirmen' => ['admin:r', 'assistenz:r']
]);
// Load Libraries
@@ -46,6 +47,7 @@ class Kontakt extends FHCAPI_Controller
$this->load->model('organisation/standort_model', 'StandortModel');
$this->load->model('ressource/firma_model', 'FirmaModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Kontakttyp_model', 'KontakttypModel');
// Extra Permissionchecks
$permsMa = [];
@@ -196,13 +198,7 @@ class Kontakt extends FHCAPI_Controller
$name = isset($_POST['name']) ? $_POST['name'] : null;
$typ = isset($_POST['typ']) ? $_POST['typ'] : null;
$anmerkung = isset($_POST['anmerkung']) ? $_POST['anmerkung'] : null;
if(isset($_POST['firma']))
{
$firma_id = $_POST['firma']['firma_id'];
}
else
$firma_id = null;
$firma_id = isset($_POST['firma_id']) ? $_POST['firma_id'] : null;
$result = $this->AdresseModel->insert(
[
@@ -269,17 +265,6 @@ class Kontakt extends FHCAPI_Controller
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Adresse_id']), self::ERROR_TYPE_GENERAL);
}
if(isset($_POST['firma']))
{
$firma_id = $_POST['firma']['firma_id'];
}
elseif(isset($_POST['firma_id']))
{
$firma_id = $_POST['firma_id'];
}
else
$firma_id = null;
$person_id = isset($_POST['person_id']) ? $_POST['person_id'] : null;
$co_name = isset($_POST['co_name']) ? $_POST['co_name'] : null;
$strasse = isset($_POST['strasse']) ? $_POST['strasse'] : null;
@@ -289,6 +274,7 @@ class Kontakt extends FHCAPI_Controller
$name = isset($_POST['name']) ? $_POST['name'] : null;
$typ = isset($_POST['typ']) ? $_POST['typ'] : null;
$anmerkung = isset($_POST['anmerkung']) ? $_POST['anmerkung'] : null;
$firma_id = isset($_POST['firma_id']) ? $_POST['firma_id'] : null;
$result = $this->AdresseModel->update(
[
@@ -443,8 +429,10 @@ class Kontakt extends FHCAPI_Controller
THEN public.tbl_kontakt.updateamum
ELSE public.tbl_kontakt.insertamum
END) AS lastUpdate, st.bezeichnung, f.name");
$this->KontakttypModel->addSelect("kt.beschreibung as kontakttypbeschreibung");
$this->StandortModel->addJoin('public.tbl_standort st', 'ON (public.tbl_kontakt.standort_id = st.standort_id)', 'LEFT');
$this->FirmaModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = st.firma_id)', 'LEFT');
$this->KontakttypModel->addJoin('public.tbl_kontakttyp kt', 'ON (public.tbl_kontakt.kontakttyp = kt.kontakttyp)');
$result = $this->KontaktModel->loadWhere(
array('person_id' => $person_id)
);
@@ -594,8 +582,8 @@ class Kontakt extends FHCAPI_Controller
'anmerkung' => $anmerkung,
'kontakt' => $kontakt,
'zustellung' => $_POST['zustellung'],
'insertvon' => $uid,
'insertamum' => date('c'),
'updatevon' => $uid,
'updateamum' => date('c'),
'standort_id' => $standort_id,
'ext_id' => $ext_id
]
@@ -670,6 +658,7 @@ class Kontakt extends FHCAPI_Controller
$iban = $this->input->post('iban');
$typ = $this->input->post('typ');
$verrechnung = $this->input->post('verrechnung');
$uid = getAuthUID();
$result = $this->BankverbindungModel->insert(
[
@@ -680,7 +669,7 @@ class Kontakt extends FHCAPI_Controller
'iban' => $iban,
'blz' => $blz,
'kontonr' => $kontonr,
'insertvon' => 'uid',
'insertvon' => $uid,
'insertamum' => date('c'),
'typ' => $typ,
'verrechnung' => $verrechnung,
@@ -797,4 +786,25 @@ class Kontakt extends FHCAPI_Controller
return $this->GemeindeModel->checkLocation($_POST['plz'], $_POST['gemeinde'], $_POST['ort']);
}
/*
* returns list of all companies
* as key value list to be used in select or autocomplete
*/
public function getAllFirmen()
{
$sql = "
SELECT
f.firma_id, f.name,
f.name AS label
FROM public.tbl_firma f
ORDER BY f.name ASC";
$result = $this->FirmaModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -116,6 +116,8 @@ class Konto extends FHCAPI_Controller
{
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
$this->BuchungstypModel->addOrder('beschreibung');
$result = $this->BuchungstypModel->load();
$data = $this->getDataOrTerminateWithError($result);
@@ -0,0 +1,408 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class LvTermine extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getStundenplan' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
]);
// Load models
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
//query verwenden wie im Cis endpoint
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
}
//TODO Build own lib or combine with Controller Stundenplan.php
//here use of logic of Stundenplan.php, extended with parameters uid, grouping, and used dbTable
public function getStundenplan($uid, $start_date = null, $end_date = null, $groupConsecutiveHours = false, $dbStundenplanTable = "stundenplan")
{
$student_uid = $uid;
$semester_range = $this->studienSemesterErmitteln($start_date, $end_date);
$this->sortStudienSemester($semester_range);
$this->applyLoadUeberSemesterHaelfte($semester_range);
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range, $student_uid);
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range, $student_uid);
if(!$groupConsecutiveHours)
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery(
$start_date,
$end_date,
$semester_range,
$benutzer_gruppen,
$student_lehrverband
);
else
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery(
$start_date,
$end_date,
$semester_range,
$benutzer_gruppen,
$student_lehrverband,
true,
$dbStundenplanTable
);
if(!$stundenplan_query)
{
$this->terminateWithSuccess([]);
}
if($groupConsecutiveHours)
{
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierungConsecutive($stundenplan_query);
}
else
{
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query);
}
$stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? [];
$this->terminateWithSuccess($stundenplan_data);
$this->expand_object_information($stundenplan_data);
$this->returnObj['$stundenplan_query'] = $stundenplan_query;
$this->returnObj['$student_lehrverband'] = $student_lehrverband;
$this->returnObj['$benutzer_gruppen'] = $benutzer_gruppen;
$this->terminateWithSuccess($stundenplan_data);
}
public function getStudiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('studienjahr_kurzbz', 'DESC');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
//copied from Stundenplan.php
private function studienSemesterErmitteln($start_date, $end_date)
{
// gets all studiensemester from the student from start_date to end_date
$semester_range = $this->StudiensemesterModel->getByDateRange($start_date, $end_date);
$semester_range = array_map(
function ($sem) {
return $sem->studiensemester_kurzbz;
},
$this->getDataOrTerminateWithError($semester_range)
);
// if no studiensemester is found for the given timespan, get the nearest studiensemester
if(count($semester_range) == 0)
{
$aktuelle_studiensemester = $this->StudiensemesterModel->getNearest();
$aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester);
if (count($aktuelle_studiensemester) == 0) {
$this->terminateWithError("No aktuelles semester");
}
$aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz;
// push aktuelles semester in active semester array
array_push($semester_range, $aktuelle_studiensemester);
}
return $semester_range;
}
//copied from Stundenplan.php
private function sortStudienSemester(&$semester_range)
{
usort(
$semester_range,
function ($first, $second) {
$sem_first = null;
$year_first = null;
$match_first = null;
$sem_second = null;
$year_second = null;
$match_second = null;
preg_match('/([WS]+)([0-9]+)/', $first, $match_first);
preg_match('/([WS]+)([0-9]+)/', $second, $match_second);
$sem_first = $match_first[1];
$year_first = intval($match_first[2]);
$sem_second = $match_second[1];
$year_second = intval($match_second[2]);
if($year_first < $year_second)
{
return -1;
}
elseif($year_first > $year_second)
{
return 1;
}
elseif($year_first == $year_second && $sem_first > $sem_second)
{
return 1;
}
elseif($year_first == $year_second && $sem_first < $sem_second)
{
return -1;
}
return 0;
}
);
}
//copied from Stundenplan.php
private function applyLoadUeberSemesterHaelfte(&$semester_range)
{
/*
@var($semester_collection)
convert the array of studiensemester into an associative array with the studiensemester as the key
and the values of each key are the studiensemester needed for the query associated to that studiensemester
example:
#INPUT:
['WS2023','SS2024','WS2024']
#OUTPUT:
[
'WS2023' => ['SS2023','WS2023']
'SS2024' => ['WS2023','SS2024']
'WS2024' => ['SS2024','WS2024']
]
*/
$semester_collection = [];
foreach($semester_range as $studiensemester)
{
$previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($studiensemester);
$previous_studiensemester = $this->getDataOrTerminateWithError($previous_studiensemester);
if (count($previous_studiensemester) == 0) {
$this->terminateWithError("No previous semester");
}
$previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz;
$semester_collection[$studiensemester] = [$previous_studiensemester, $studiensemester];
}
/*
@var($studienSemesterDateRanges)
fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak
based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range
or the semester with the full date range and the previous semester with the half date range:
#INPUT:
[
'WS2023' => ['SS2023','WS2023']
'SS2024' => ['WS2023','SS2024']
'WS2024' => ['SS2024','WS2024']
]
#OUTPUT: depends whether LVPLAN_LOAD_UEBER_SEMESTERHAELFTE is true or false
~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == true
[
"SS2024": [
"WS2023": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
],
"SS2024": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
]
]
]
~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == false
[
"SS2024": [
"WS2023": [
"start"=> "2024-02-03",
"ende"=> "2024-05-17"
],
"SS2024": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
]
]
]
*/
$studienSemesterDateRanges=[];
foreach($semester_collection as $semester_original => $semester_adjoint)
{
$semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original);
$semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende));
// initialize empty arrays to add key value pairs
$studienSemesterDateRanges[$semester_original] = [];
// check if the studiensemester is a summer semester and add 1 month to bridge the school summer break
$match = null;
preg_match("/^(SS)([0-9]+)/", $semester_original, $match);
if(count($match) >0)
{
$one_month = new DateInterval('P1M');
$one_day = DateInterval::createFromDateString('1 days');
$summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d', $semester_start_ende->ende);
$summer_studiensemester_end_date->add($one_month);
$summer_studiensemester_end_date->sub($one_day);
$semester_start_ende->ende = date_format($summer_studiensemester_end_date, 'Y-m-d');
}
if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true)
{
foreach($semester_adjoint as $adjoint)
{
$studienSemesterDateRanges[$semester_original][$adjoint]=$semester_start_ende;
}
}
else
{
//TODO: half of a DateInterval might not be correctly calculated
// calculate the half of the studiensemester
$studiensemester_start_date = DateTime::createFromFormat('Y-m-d', $semester_start_ende->start);
$studiensemester_end_date = DateTime::createFromFormat('Y-m-d', $semester_start_ende->ende);
$studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date);
$half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2);
$half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D');
$studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval), 'Y-m-d');
$first_half = new stdClass();
$first_half->start = $semester_start_ende->start;
$first_half->ende = $studiensemester_half;
$studienSemesterDateRanges[$semester_original][$semester_adjoint[0]] = $first_half;
$studienSemesterDateRanges[$semester_original][$semester_adjoint[1]] = $semester_start_ende;
}
$semester_range = $studienSemesterDateRanges;
}
}
//copied from Stundenplan.php, extended with $student_uid
private function fetchBenutzerGruppenFromStudiensemester($semester_range, $student_uid)
{
//$student_uid = getAuthUID();
$benutzer_gruppen = [];
// for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array
/*
[
['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']],
['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']],
['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$benutzer_gruppen[$semester_key] = [];
// each semester could have ajoint semesters that need to be checked
foreach($semester_array as $semester => $semester_date_range)
{
// for each active semester query the benutzer_gruppen associated to the semester
$benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query);
array_push(
$benutzer_gruppen[$semester_key],
array_map(
function ($item) {
return "'".$item->gruppe_kurzbz. "'";
},
$benutzer_query_result
)
);
}
}
// merge the gruppen of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'],
['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'],
['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'],
]
*/
$benutzer_gruppen = array_map(
function ($gruppe) {
$merged_gruppe = [];
foreach($gruppe as $gruppen_array)
{
$merged_gruppe = array_merge($merged_gruppe, $gruppen_array);
}
return $merged_gruppe;
},
$benutzer_gruppen
);
return $benutzer_gruppen;
}
//copied from Stundenplan.php, extended with $student_uid
private function fetchStudentlehrverbandFromStudiensemester($semester_range, $student_uid)
{
//$student_uid = getAuthUID();
$student_lehrverband = [];
// for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array
/*
[
['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ],
['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ],
['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$student_lehrverband[$semester_key] = [];
foreach($semester_array as $semester => $semester_date_range)
{
// for each active semester query the student_lehrverband associated to the semester
$lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query);
array_push($student_lehrverband[$semester_key], array_map(
function ($item) {
$result = new stdClass();
$result->studiengang_kz = $item->studiengang_kz;
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
return $result;
},
$lehrverband_query_result));
}
}
// merge the studentlehrverband of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ],
['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ],
['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ],
]
*/
$student_lehrverband = array_map(
function ($studentlehrverband) {
$merged_studentlehrverband = [];
foreach($studentlehrverband as $studentlehrverband_array)
{
$merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array);
}
return $merged_studentlehrverband;
},
$student_lehrverband
);
return $student_lehrverband;
}
}
@@ -3,6 +3,7 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
use CI3_Events as Events;
class Mobility extends FHCAPI_Controller
{
@@ -40,13 +41,54 @@ class Mobility extends FHCAPI_Controller
// Load models
$this->load->model('codex/Bisio_model', 'BisioModel');
//Permission checks for Studiengangsarray
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'insertMobility' || $this->router->method == 'updateMobility')
{
$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);
}
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
if ($this->router->method == 'deleteMobility') {
$bisio_id = $this->input->post('bisio_id');
if(!$bisio_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Bisio ID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->BisioModel->load(
array('bisio_id' => $bisio_id)
);
$data = $this->getDataOrTerminateWithError($result);
$student_uid = current($data)->student_uid;
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
}
private function _checkAllowedStgsFromUid($student_uid, $allowedStgs)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
public function getMobilitaeten($student_uid)
{
$this->BisioModel->addSelect("*");
$this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT');
$this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)','LEFT');
$this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)', 'LEFT');
$this->BisioModel->addOrder('von', 'DESC');
$this->BisioModel->addOrder('bis', 'DESC');
$this->BisioModel->addOrder('bisio_id', 'DESC');
@@ -83,14 +125,20 @@ class Mobility extends FHCAPI_Controller
$formData = $this->input->post('formData');
$_POST['von'] = (isset($formData['von']) && !empty($formData['von'])) ? $formData['von'] : null;
$_POST['bis'] = (isset($formData['bis']) && !empty($formData['bis'])) ? $formData['bis'] : null;
$_POST['nation_code'] = (isset($formData['nation_code']) && !empty($formData['nation_code'])) ? $formData['nation_code'] : 'A';
$_POST['mobilitaetsprogramm_code'] = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code'])) ? $formData['mobilitaetsprogramm_code'] : null;
$_POST['herkunftsland_code'] = (isset($formData['herkunftsland_code']) && !empty($formData['herkunftsland_code'])) ? $formData['herkunftsland_code'] : 'A';
$_POST['ects_erworben'] = (isset($formData['ects_erworben']) && !empty($formData['ects_erworben'])) ? $formData['ects_erworben'] : null;
$_POST['ects_angerechnet'] = (isset($formData['ects_angerechnet']) && !empty($formData['ects_angerechnet'])) ? $formData['ects_angerechnet'] : null;
$_POST['lehreinheit_id'] = (isset($formData['lehreinheit_id']) && !empty($formData['lehreinheit_id'])) ? $formData['lehreinheit_id'] : null;
$von = $formData['von'] ?? null;
$bis = $formData['bis'] ?? null;
$nation_code = $formData['nation_code'] ?? null;
$mobilitaetsprogramm_code = $formData['mobilitaetsprogramm_code'] ?? null;
$herkunftsland_code = $formData['herkunftsland_code'] ?? null;
$ects_erworben = $formData['ects_erworben'] ?? null;
$ects_angerechnet = $formData['ects_angerechnet'] ?? null;
$lehreinheit_id = $formData['lehreinheit_id'] ?? null;
$ort = $formData['ort'] ?? null;
$universitaet = $formData['universitaet'] ?? null;
$localPurposes = $formData['localPurposes'] ?? null;
$localSupports = $formData['localSupports'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code'])
@@ -126,23 +174,18 @@ class Mobility extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$ort = (isset($formData['ort']) && !empty($formData['ort'])) ? $formData['ort'] : null;
$universitaet = (isset($formData['universitaet']) && !empty($formData['universitaet'])) ? $formData['universitaet'] : null;
$localPurposes = (isset($formData['localPurposes']) && !empty($formData['localPurposes'])) ? $formData['localPurposes'] : null;
$localSupports = (isset($formData['localSupports']) && !empty($formData['localSupports'])) ? $formData['localSupports'] : null;
$result = $this->BisioModel->insert([
'student_uid' => $student_uid,
'von' => $_POST['von'],
'bis' => $_POST['bis'],
'mobilitaetsprogramm_code' => $_POST['mobilitaetsprogramm_code'],
'nation_code' => $_POST['nation_code'],
'herkunftsland_code' => $_POST['herkunftsland_code'],
'lehreinheit_id' => $_POST['lehreinheit_id'],
'von' => $von,
'bis' => $bis,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'nation_code' => $nation_code,
'herkunftsland_code' => $herkunftsland_code,
'lehreinheit_id' => $lehreinheit_id,
'ort' => $ort,
'universitaet' => $universitaet,
'ects_erworben' => $_POST['ects_erworben'] ,
'ects_angerechnet' => $_POST['ects_angerechnet'],
'ects_erworben' => $ects_erworben ,
'ects_angerechnet' => $ects_angerechnet,
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
@@ -171,7 +214,7 @@ class Mobility extends FHCAPI_Controller
{
$this->BisioModel->addSelect("*");
$this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT');
$this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)','LEFT');
$this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)', 'LEFT');
$result = $this->BisioModel->loadWhere(
array('bisio_id' => $bisio_id)
);
@@ -194,14 +237,18 @@ class Mobility extends FHCAPI_Controller
}
$formData = $this->input->post('formData');
$_POST['von'] = (isset($formData['von']) && !empty($formData['von'])) ? $formData['von'] : null;
$_POST['bis'] = (isset($formData['bis']) && !empty($formData['bis'])) ? $formData['bis'] : null;
$_POST['nation_code'] = (isset($formData['nation_code']) && !empty($formData['nation_code'])) ? $formData['nation_code'] : 'A';
$_POST['mobilitaetsprogramm_code'] = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code'])) ? $formData['mobilitaetsprogramm_code'] : null;
$_POST['herkunftsland_code'] = (isset($formData['herkunftsland_code']) && !empty($formData['herkunftsland_code'])) ? $formData['herkunftsland_code'] : 'A';
$_POST['ects_erworben'] = (isset($formData['ects_erworben']) && !empty($formData['ects_erworben'])) ? $formData['ects_erworben'] : null;
$_POST['ects_angerechnet'] = (isset($formData['ects_angerechnet']) && !empty($formData['ects_angerechnet'])) ? $formData['ects_angerechnet'] : null;
$_POST['lehreinheit_id'] = (isset($formData['lehreinheit_id']) && !empty($formData['lehreinheit_id'])) ? $formData['lehreinheit_id'] : null;
$von = $formData['von'] ?? null;
$bis = $formData['bis'] ?? null;
$nation_code = $formData['nation_code'] ?? null;
$mobilitaetsprogramm_code = $formData['mobilitaetsprogramm_code'] ?? null;
$herkunftsland_code = $formData['herkunftsland_code'] ?? null;
$ects_erworben = $formData['ects_erworben'] ?? null;
$ects_angerechnet = $formData['ects_angerechnet'] ?? null;
$lehreinheit_id = $formData['lehreinheit_id'] ?? null;
$ort = $formData['ort'] ?? null;
$universitaet = $formData['universitaet'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code'])
@@ -209,6 +256,7 @@ class Mobility extends FHCAPI_Controller
$this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code'])
]);
$this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code'])
]);
@@ -243,16 +291,17 @@ class Mobility extends FHCAPI_Controller
],
[
'student_uid' => $student_uid,
'von' => $_POST['von'],
'bis' => $_POST['bis'],
'mobilitaetsprogramm_code' => $_POST['mobilitaetsprogramm_code'],
'nation_code' => $_POST['nation_code'],
'herkunftsland_code' => $_POST['herkunftsland_code'],
'lehreinheit_id' => $_POST['lehreinheit_id'],
'ort' => $formData['ort'],
'universitaet' => $formData['universitaet'],
'ects_erworben' => $_POST['ects_erworben'] ,
'ects_angerechnet' => $_POST['ects_angerechnet'],
'von' => $von,
'bis' => $bis,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'nation_code' => $nation_code,
'herkunftsland_code' => $herkunftsland_code,
'lehreinheit_id' => $lehreinheit_id,
'ort' => $ort,
'universitaet' => $universitaet,
'ects_erworben' => $ects_erworben ,
'ects_angerechnet' => $ects_angerechnet,
'updateamum' => date('c'),
'updatevon' => $authUID,
]
@@ -263,30 +312,12 @@ class Mobility extends FHCAPI_Controller
$this->terminateWithSuccess(current($data));
}
public function deleteMobility($bisio_id)
public function deleteMobility()
{
//check if extension table exists
$result = $this->BisioModel->tableExists('extension', 'tbl_mo_bisioidzuordnung');
$data = $this->getDataOrTerminateWithError($result);
$bisio_id = $this->input->post('bisio_id');
//if table exists check if existing entry
if(!empty($data))
{
$this->BisioModel->addSelect("count(*)");
$this->BisioModel->addJoin('extension.tbl_mo_bisioidzuordnung mo', 'ON (mo.bisio_id = bis.tbl_bisio.bisio_id)', 'LEFT');
$resultCheckMo = $this->BisioModel->loadWhere(
array('mo.bisio_id' => $bisio_id)
);
$resultCheckMo = $this->getDataOrTerminateWithError($resultCheckMo);
$count = current($resultCheckMo)->count;
$existsInExtension = $count > 0 ? true : false;
if($existsInExtension)
$this->terminateWithError($this->p->t('mobility', 'error_existingEntryInExtension'), self::ERROR_TYPE_GENERAL);
}
//check if entry in MobilityOnline extension exists
Events::trigger('mobility_delete', $bisio_id);
$result = $this->BisioModel->delete(
array('bisio_id' => $bisio_id)
@@ -294,6 +325,7 @@ class Mobility extends FHCAPI_Controller
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLVList($studiengang_kz)
@@ -475,7 +507,6 @@ class Mobility extends FHCAPI_Controller
if($local_support){
$aufenthaltfoerderung_code = $local_support;
}
$this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
if(!$local_support)
@@ -136,10 +136,21 @@ class Prestudent extends FHCAPI_Controller
$update_prestudent = array();
foreach ($array_allowed_props_prestudent as $prop)
{
$val = $this->input->post($prop);
if ($val !== null || $prop == 'foerderrelevant') {
$val = $this->input->post($prop, true);
if ($val !== null || $prop === 'foerderrelevant') {
$update_prestudent[$prop] = $val;
}
// allowed to be null, but has to be in postparameter
if (
in_array($prop, ['zgvdatum', 'zgvmadatum', 'zgvdoktordatum', 'zgv_code', 'zgvmas_code', 'zgvdoktor_code'])
&& !isset($update_prestudent[$prop])
&& array_key_exists($prop, $_POST)
)
{
$update_prestudent[$prop] = null;
}
}
$update_prestudent['updateamum'] = date('c');
@@ -174,7 +185,11 @@ class Prestudent extends FHCAPI_Controller
{
$this->load->model('codex/Zgv_model', 'ZgvModel');
$this->ZgvModel->addOrder('zgv_code');
$this->ZgvModel->addSelect('zgv_code');
$this->ZgvModel->addSelect('zgv_bez');
$this->ZgvModel->addSelect('aktiv');
$this->ZgvModel->addSelect('zgv_bez as label');
$this->ZgvModel->addOrder('zgv_bez');
$result = $this->ZgvModel->load();
if (isError($result))
@@ -188,7 +203,11 @@ class Prestudent extends FHCAPI_Controller
{
$this->load->model('codex/Zgvdoktor_model', 'ZgvdoktorModel');
$this->ZgvdoktorModel->addOrder('zgvdoktor_code');
$this->ZgvdoktorModel->addSelect('zgvdoktor_code');
$this->ZgvdoktorModel->addSelect('zgvdoktor_bez');
$this->ZgvdoktorModel->addSelect('aktiv');
$this->ZgvdoktorModel->addSelect('zgvdoktor_bez as label');
$this->ZgvdoktorModel->addOrder('zgvdoktor_bez');
$result = $this->ZgvdoktorModel->load();
if (isError($result))
@@ -202,7 +221,11 @@ class Prestudent extends FHCAPI_Controller
{
$this->load->model('codex/Zgvmaster_model', 'ZgvmasterModel');
$this->ZgvmasterModel->addOrder('zgvmas_code');
$this->ZgvmasterModel->addSelect('zgvmas_code');
$this->ZgvmasterModel->addSelect('zgvmas_bez');
$this->ZgvmasterModel->addSelect('aktiv');
$this->ZgvmasterModel->addSelect('zgvmas_bez as label');
$this->ZgvmasterModel->addOrder('zgvmas_bez');
$result = $this->ZgvmasterModel->load();
if (isError($result))
@@ -739,8 +739,12 @@ class Status extends FHCAPI_Controller
// Start DB transaction
$this->db->trans_begin();
//Delete Studentlehrverband if no Status left in this semester
$cilsresult = $this->PrestudentstatusModel->checkIfLastStatusEntry($prestudent_id, $studiensemester_kurzbz);
$isLastPrestudentStatusForSemester = $this->getDataOrTerminateWithError($cilsresult);
//Delete Status
$result = $this->PrestudentstatusModel->delete(
$delpsresult = $this->PrestudentstatusModel->delete(
[
'prestudent_id' => $prestudent_id,
'status_kurzbz' => $status_kurzbz,
@@ -748,14 +752,9 @@ class Status extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz
]
);
$this->getDataOrTerminateWithError($delpsresult);
$this->getDataOrTerminateWithError($result);
//Delete Studentlehrverband if no Status left in this semester
$result = $this->PrestudentstatusModel->checkIfLastStatusEntry($prestudent_id, $studiensemester_kurzbz);
$result = $this->getDataOrTerminateWithError($result);
if ($result)
if ($isLastPrestudentStatusForSemester)
{
//get student_uid
$this->load->model('crm/Student_model', 'StudentModel');
@@ -1529,9 +1528,32 @@ class Status extends FHCAPI_Controller
$newStudentlvb['semester'] = $ausbildungssemester;
} // If there is no lehrverband just use the same as in the previous studiensemester
//add studentlehrverband
$result = $this->StudentlehrverbandModel->insert($newStudentlvb);
$checkres = $this->StudentlehrverbandModel->load(array(
'student_uid' => $studentlvb->student_uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz
));
if(hasData($checkres))
{
$result = $this->StudentlehrverbandModel->update(
array(
'student_uid' => $studentlvb->student_uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz
),
array(
'studiengang_kz' => $studentlvb->studiengang_kz,
'semester' => $studentlvb->semester,
'verband' => $studentlvb->verband,
'gruppe' => $studentlvb->gruppe,
'updateamum' => $now,
'updatevon' => $authUID
)
);
}
else
{
//add studentlehrverband
$result = $this->StudentlehrverbandModel->insert($newStudentlvb);
}
$this->getDataOrTerminateWithError($result);
@@ -72,9 +72,22 @@ class Student extends FHCAPI_Controller
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addSelect('p.*');
$this->PrestudentModel->addSelect('p.person_id');
$this->PrestudentModel->addSelect('p.titelpre');
$this->PrestudentModel->addSelect('p.nachname');
$this->PrestudentModel->addSelect('p.vorname');
$this->PrestudentModel->addSelect('p.wahlname');
$this->PrestudentModel->addSelect('p.vornamen');
$this->PrestudentModel->addSelect('p.titelpost');
$this->PrestudentModel->addSelect('p.svnr');
$this->PrestudentModel->addSelect('p.ersatzkennzeichen');
$this->PrestudentModel->addSelect('p.gebdatum');
$this->PrestudentModel->addSelect('p.geschlecht');
$this->PrestudentModel->addSelect('p.foto');
$this->PrestudentModel->addSelect('p.foto_sperre');
$this->PrestudentModel->addSelect('s.student_uid');
$this->PrestudentModel->addSelect('matrikelnr');
$this->PrestudentModel->addSelect('b.aktiv');
@@ -82,6 +95,15 @@ class Student extends FHCAPI_Controller
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
$this->PrestudentModel->addSelect('b.alias');
$this->PrestudentModel->addSelect('p.geburtsnation');
$this->PrestudentModel->addSelect('p.sprache');
$this->PrestudentModel->addSelect('p.gebort');
$this->PrestudentModel->addSelect('p.homepage');
$this->PrestudentModel->addSelect('p.anmerkung');
$this->PrestudentModel->addSelect('p.familienstand');
$this->PrestudentModel->addSelect('p.staatsbuergerschaft');
$this->PrestudentModel->addSelect('p.matr_nr');
$this->PrestudentModel->addSelect('p.anrede');
if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) {
$this->PrestudentModel->addSelect(
@@ -97,6 +119,16 @@ class Student extends FHCAPI_Controller
false
);
}
$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->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT');
@@ -106,17 +138,34 @@ class Student extends FHCAPI_Controller
'LEFT'
);
$this->PrestudentModel->addJoin('public.tbl_person p', 'p.person_id = tbl_prestudent.person_id');
/* $this->PrestudentModel->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id = tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = ' . $this->PrestudentModel->escape($studiensemester_kurzbz),
'LEFT');*/
$result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
$result = $this->PrestudentModel->loadWhere(['tbl_prestudent.prestudent_id' => $prestudent_id]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
return show_404();
$this->terminateWithSuccess(current($student));
}
protected function isLaufendesSemester($selectedSemester)
{
$laufendesStudiensemester = '';
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->getNearest();
if(hasData($result)) {
$laufendesStudiensemester = (getData($result))[0]->studiensemester_kurzbz;
}
$islaufendesSemester = $selectedSemester === $laufendesStudiensemester;
return $islaufendesSemester;
}
/**
* Saves data to a prestudent
*
@@ -125,24 +174,36 @@ class Student extends FHCAPI_Controller
*/
public function save($prestudent_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->load->library('form_validation');
$authuid = getAuthUID();
$now = date('c');
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date');
$this->form_validation->set_rules('semester', 'Semester', 'integer');
$this->form_validation->set_rules('semester', 'Semester', 'integer', [
'integer' => $this->p->t('ui', 'error_fieldNotInteger')
]
);
$this->form_validation->set_rules('alias', 'Alias', 'regex_match[/^[-a-z0-9\_\.]*[a-z0-9]{1,}\.[-a-z0-9\_]{1,}$/]',
[
'regex_match' => $this->p->t('ui', 'error_fieldInvalidAlias')
]);
$this->load->library('UDFLib');
$result = $this->udflib->getCiValidations($this->PersonModel, $this->input->post());
//TODO(Manu) check with Chris: input number not allowed
$udf_field_validations = $this->getDataOrTerminateWithError($result);
$this->form_validation->set_rules($udf_field_validations);
@@ -197,7 +258,7 @@ class Student extends FHCAPI_Controller
'anmerkung',
'homepage'
];
// add UDFs
$result = $this->udflib->getDefinitionForModel($this->PersonModel);
@@ -215,6 +276,10 @@ class Student extends FHCAPI_Controller
}
$array_allowed_props_student = ['matrikelnr'];
if($this->isLaufendesSemester($studiensemester_kurzbz))
{
$array_allowed_props_student = ['matrikelnr', 'verband', 'semester', 'gruppe'];
}
$update_student = array();
foreach ($array_allowed_props_student as $prop) {
$val = $this->input->post($prop);
@@ -223,6 +288,15 @@ class Student extends FHCAPI_Controller
}
}
$array_allowed_props_benutzer = ['aktiv', 'alias'];
$update_benutzer = array();
foreach ($array_allowed_props_benutzer as $prop) {
$val = $this->input->post($prop);
if ($val !== null) {
$update_benutzer[$prop] = $val;
}
}
// Check PKs
if (count($update_lehrverband) + count($update_student) && $uid === null) {
$this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_student')]);
@@ -230,16 +304,47 @@ class Student extends FHCAPI_Controller
if (count($update_person) && $person_id === null) {
$this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_person')]);
}
if (count($update_benutzer) && $uid === null) {
$this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_student')]);
}
// Do Updates
if (count($update_lehrverband)) {
$curstudlvb = $this->StudentlehrverbandModel->load([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid
]);
$data = $this->getDataOrTerminateWithError($curstudlvb);
$data = current($data);
$verbandCurrent = $data->verband;
$studiengang_kz = $data->studiengang_kz;
$semesterCurrent = $data->semester;
$gruppeCurrent = $data->gruppe;
$verband = isset($update_lehrverband['verband']) ? $update_lehrverband['verband'] : $verbandCurrent;
$gruppe = isset($update_lehrverband['gruppe']) ? $update_lehrverband['gruppe'] : $gruppeCurrent;
$semester = isset($update_lehrverband['semester']) ? $update_lehrverband['semester'] : $semesterCurrent;
//check if existing Lehrverband of new data to avoid Error
$result = $this->LehrverbandModel->loadWhere([
'verband' => $verband,
'gruppe' => $gruppe,
'semester' => $semester,
'studiengang_kz' => $studiengang_kz,
]);
if(!hasData($result))
{
$this->terminateWithError($this->p->t('lehre', 'error_noLehrverband'), self::ERROR_TYPE_GENERAL);
}
if(hasData($curstudlvb) && count(getData($curstudlvb)) > 0 )
{
$update_lehrverband['updatevon'] = $authuid;
$update_lehrverband['updateamum'] = $now;
$result = $this->StudentlehrverbandModel->update([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid
@@ -247,6 +352,8 @@ class Student extends FHCAPI_Controller
}
else
{
$update_lehrverband['insertvon'] = $authuid;
$update_lehrverband['insertamum'] = $now;
$result = $this->StudentlehrverbandModel->insert(array_merge([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid,
@@ -258,6 +365,8 @@ class Student extends FHCAPI_Controller
}
if (count($update_person)) {
$update_person['updatevon'] = $authuid;
$update_person['updateamum'] = $now;
$result = $this->PersonModel->update(
$person_id,
$update_person
@@ -267,6 +376,8 @@ class Student extends FHCAPI_Controller
if (count($update_student)) {
$update_student['updatevon'] = $authuid;
$update_student['updateamum'] = $now;
$result = $this->StudentModel->update(
[$uid],
$update_student
@@ -274,10 +385,26 @@ class Student extends FHCAPI_Controller
$this->getDataOrTerminateWithError($result);
}
if (count($update_benutzer)) {
$update_benutzer['updatevon'] = $authuid;
$update_benutzer['updateamum'] = $now;
if (array_key_exists("aktiv", $update_benutzer))
{
$update_benutzer['updateaktivvon'] = $authuid;
$update_benutzer['updateaktivam'] = $now;
}
$result = $this->BenutzerModel->update(
[$uid],
$update_benutzer
);
$this->getDataOrTerminateWithError($result);
}
$this->terminateWithSuccess(array_fill_keys(array_merge(
array_keys($update_lehrverband),
array_keys($update_person),
array_keys($update_student)
array_keys($update_student),
array_keys($update_benutzer)
), ''));
}
@@ -70,7 +70,7 @@ class Students extends FHCAPI_Controller
* /(studiengang_kz)/(org_form)/(semester)/(verband) => getStudents
* /(studiengang_kz)/(org_form)/(semester)/(verband)/(gruppe)
* => getStudents
* /uid/(student_uid) => getStudent
* /student/(student_uid) => getStudent
* /prestudent/(prestudent_id) => getPrestudent
* /person/(person_id) => getPerson
*
@@ -223,25 +223,25 @@ class Students extends FHCAPI_Controller
break;
case "bewerbungnichtabgeschickt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bewerbung_abgeschicktamum'] = null;
$where['ps.bewerbung_abgeschicktamum'] = null;
break;
case "bewerbungabgeschickt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bewerbung_abgeschicktamum IS NOT NULL'] = null;
$where['bestaetigtam'] = null;
$where['ps.bewerbung_abgeschicktamum IS NOT NULL'] = null;
$where['ps.bestaetigtam'] = null;
break;
case "statusbestaetigt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$where['ps.bestaetigtam IS NOT NULL'] = null;
break;
case "statusbestaetigtrtnichtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$where['ps.bestaetigtam IS NOT NULL'] = null;
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
break;
case "statusbestaetigtrtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$where['ps.bestaetigtam IS NOT NULL'] = null;
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
break;
case "zgv":
@@ -358,6 +358,18 @@ class Students extends FHCAPI_Controller
$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);
@@ -380,7 +392,6 @@ class Students extends FHCAPI_Controller
protected function getStudents($studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
@@ -406,6 +417,18 @@ 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 = [];
@@ -482,6 +505,19 @@ class Students extends FHCAPI_Controller
$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->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
@@ -527,8 +563,23 @@ class Students extends FHCAPI_Controller
$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);
$result = $this->PrestudentModel->loadWhere([
@@ -565,6 +616,19 @@ class Students extends FHCAPI_Controller
$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);
@@ -622,6 +686,8 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('ersatzkennzeichen');
$this->PrestudentModel->addSelect('gebdatum');
$this->PrestudentModel->addSelect('geschlecht');
$this->PrestudentModel->addSelect('foto');
$this->PrestudentModel->addSelect('foto_sperre');
// semester
// verband
@@ -629,6 +695,7 @@ class Students extends FHCAPI_Controller
$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');
$this->PrestudentModel->addSelect("s.matrikelnr");
$this->PrestudentModel->addSelect('p.person_id');
$this->PrestudentModel->addSelect('pls.status_kurzbz AS status');
@@ -640,7 +707,7 @@ class Students extends FHCAPI_Controller
);
$this->PrestudentModel->addSelect("
CASE WHEN b.uid IS NOT NULL AND b.uid<>''
THEN b.uid || " . $this->PrestudentModel->escape(DOMAIN) . "
THEN CONCAT(b.uid, '@', " . $this->PrestudentModel->escape(DOMAIN) . ")
ELSE '' END AS mail_intern", false);
$this->PrestudentModel->addSelect('p.anmerkung AS anmerkungen');
$this->PrestudentModel->addSelect('tbl_prestudent.anmerkung');
@@ -709,7 +776,12 @@ class Students extends FHCAPI_Controller
*/
protected function addFilter($studiensemester_kurzbz)
{
$filter = $this->input->get('filter');
$filter = json_decode($this->input->get('filter'), true);
if (!is_array($filter))
{
$this->addMeta('addfilter', 'invalid filter: ' . $this->input->get('filter'));
return;
}
if (isset($filter['konto_count_0'])) {
$bt = $this->PrestudentModel->escape($filter['konto_count_0']);
$stdsem = $this->PrestudentModel->escape($studiensemester_kurzbz);
@@ -0,0 +1,720 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Vertraege extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAllVertraege' => ['vertrag/mitarbeiter:r'],
'getAllContractsNotAssigned' => ['vertrag/mitarbeiter:r'],
'getAllContractsAssigned' => ['vertrag/mitarbeiter:r'],
'getAllContractTypes' => ['vertrag/mitarbeiter:r'],
'getAllContractStati' => ['vertrag/mitarbeiter:r'],
'getStatiOfContract' => ['vertrag/mitarbeiter:r'],
'loadContract' => ['vertrag/mitarbeiter:r'],
'loadContractStatus' => ['vertrag/mitarbeiter:r'],
'updateContract' =>['vertrag/mitarbeiter:w'],
'addNewContract' =>['vertrag/mitarbeiter:w'],
'deleteContract' =>['vertrag/mitarbeiter:w'],
'insertContractStatus' =>['vertrag/mitarbeiter:w'],
'deleteContractStatus' =>['vertrag/mitarbeiter:w'],
'updateContractStatus' =>['vertrag/mitarbeiter:w'],
'deleteLehrauftrag' =>['vertrag/mitarbeiter:w'],
'deleteBetreuung' =>['vertrag/mitarbeiter:w'],
'getMitarbeiter' => ['vertrag/mitarbeiter:r'],
'getHeader' => ['vertrag/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
]);
//Load Models and Libraries
$this->load->model('accounting/Vertrag_model', 'VertragModel');
$this->load->model('accounting/Vertragsstatus_model', 'VertragsstatusModel');
$this->load->model('accounting/Vertragstyp_model', 'VertragstypModel');
$this->load->model('accounting/Vertragvertragsstatus_model', 'VertragvertragsstatusModel');
// Load language phrases
$this->loadPhrases([
'ui',
'vertrag'
]);
}
public function getAllVertraege($person_id)
{
$result = $this->VertragModel->loadContractsOfPerson($person_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getAllContractsNotAssigned($person_id)
{
$result = $this->VertragModel->loadContractsOfPersonNotAssigned($person_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getAllContractsAssigned($person_id, $vertrag_id)
{
$result = $this->VertragModel->loadContractsOfPersonAssigned($person_id, $vertrag_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getStatiOfContract($person_id, $vertrag_id)
{
//check if vertrag_id corresponds with person_id and return null if not
$result = $this->VertragModel->loadWhere(
array(
'vertrag_id' => $vertrag_id,
'person_id' => $person_id
)
);
if(!hasData($result))
{
$this->terminateWithSuccess([]);
}
$result = $this->VertragModel->getStatiOfContract($vertrag_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getAllContractTypes()
{
$result = $this->VertragstypModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getAllContractStati()
{
$result = $this->VertragsstatusModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function addNewContract()
{
$this->load->library('form_validation');
$person_id = $this->input->post('person_id');
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$vertragstyp_kurzbz = $formData['vertragstyp_kurzbz'] ?? null;
$vertragsdatum = $formData['vertragsdatum'] ?? null;
$bezeichnung = $formData['bezeichnung'] ?? null;
$betrag = $formData['betrag'] ?? null;
$vertragsstunden = $formData['vertragsstunden'] ?? null;
$vertragsstunden_studiensemester_kurzbz = $formData['vertragsstunden_studiensemester_kurzbz'] ?? null;
$anmerkung = $formData['anmerkung'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('bezeichnung', 'Bezeichnung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Bezeichnung'])
]);
$this->form_validation->set_rules('vertragstyp_kurzbz', 'Vertragstyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragstyp'])
]);
$this->form_validation->set_rules('vertragsdatum', 'Vertragsdatum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Vertragsdatum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragsdatum'])
]);
$this->form_validation->set_rules('betrag', 'Betrag', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betrag']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Betrag'])
]);
$this->form_validation->set_rules('vertragsstunden', 'Stunden(Vertrags-Urfassung)', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Stunden(Vertrags-Urfassung)'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$lehrauftraege = $this->input->post('clickedRows');
$this->db->trans_start();
$result = $this->VertragModel->insert([
'person_id' => $person_id,
'vertragsdatum' => $vertragsdatum,
'bezeichnung' => $bezeichnung,
'vertragstyp_kurzbz' => $vertragstyp_kurzbz,
'betrag' => $betrag,
'vertragsstunden' => $vertragsstunden,
'vertragsstunden_studiensemester_kurzbz' => $vertragsstunden_studiensemester_kurzbz,
'anmerkung' => $anmerkung,
'insertamum' => date('c'),
'insertvon' => getAuthUID()
]);
$this->getDataOrTerminateWithError($result);
$vertrag_id = $result->retval;
$status_result = $this->VertragvertragsstatusModel->insert([
'vertrag_id' => $vertrag_id,
'uid' => getAuthUID(),
'vertragsstatus_kurzbz' => 'neu',
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'datum' => date('c')
]);
if (!$status_result) {
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_insertOrUpdateStatusVertrag'), self::ERROR_TYPE_GENERAL);
}
//Hinzufügen der Lehraufträge
foreach ($lehrauftraege as $row)
{
if ($row['type'] == 'Lehrauftrag')
{
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$result_lehrauftrag = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $row['lehreinheit_id'],
'mitarbeiter_uid' => $row['mitarbeiter_uid']
],
[
'vertrag_id' => $vertrag_id
]
);
if (!$result_lehrauftrag) {
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
if ($row['type'] == 'Betreuung')
{
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
$result_projektbetreuer = $this->Projektbetreuermodel->update(
[
'person_id' => $person_id,
'projektarbeit_id' => $row['projektarbeit_id'],
'betreuerart_kurzbz' => $row['betreuerart_kurzbz']
],
[
'vertrag_id' => $vertrag_id
]
);
if (!$result_projektbetreuer)
{
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
}
$this->db->trans_complete();
$this->terminateWithSuccess(true);
}
public function updateContract()
{
$this->load->library('form_validation');
$vertrag_id = $this->input->post('vertrag_id');
$person_id = $this->input->post('person_id');
$formData = $this->input->post('formData');
$lehrauftraege = $this->input->post('clickedRows');
$vertragstyp_kurzbz = $formData['vertragstyp_kurzbz'] ?? null;
$vertragsdatum = $formData['vertragsdatum'] ?? null;
$bezeichnung = $formData['bezeichnung'] ?? null;
$betrag = $formData['betrag'] ?? null;
$vertragsstunden = $formData['vertragsstunden'] ?? null;
$vertragsstunden_studiensemester_kurzbz = $formData['vertragsstunden_studiensemester_kurzbz'] ?? null;
$anmerkung = $formData['anmerkung'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('bezeichnung', 'Bezeichnung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Bezeichnung'])
]);
$this->form_validation->set_rules('vertragstyp_kurzbz', 'Vertragstyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragstyp'])
]);
$this->form_validation->set_rules('vertragsdatum', 'Vertragsdatum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Vertragsdatum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragsdatum'])
]);
$this->form_validation->set_rules('betrag', 'Betrag', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betrag']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Betrag'])
]);
$this->form_validation->set_rules('vertragsstunden', 'Stunden(Vertrags-Urfassung)', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Stunden(Vertrags-Urfassung)'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->db->trans_start();
$result = $this->VertragModel->update(
$vertrag_id,
[
'person_id' => $person_id,
'vertragsdatum' => $vertragsdatum,
'bezeichnung' => $bezeichnung,
'vertragstyp_kurzbz' => $vertragstyp_kurzbz,
'betrag' => $betrag,
'vertragsstunden' => $vertragsstunden,
'vertragsstunden_studiensemester_kurzbz' => $vertragsstunden_studiensemester_kurzbz,
'anmerkung' => $anmerkung,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$this->getDataOrTerminateWithError($result);
//Adding of Lehraufträge
foreach ($lehrauftraege as $row)
{
if ($row['type'] == 'Lehrauftrag')
{
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$result_lehrauftrag = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $row['lehreinheit_id'],
'mitarbeiter_uid' => $row['mitarbeiter_uid']
],
[
'vertrag_id' => $vertrag_id,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (!$result_lehrauftrag) {
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
if ($row['type'] == 'Betreuung')
{
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
$result_projektbetreuer = $this->Projektbetreuermodel->update(
[
'person_id' => $person_id,
'projektarbeit_id' => $row['projektarbeit_id'],
'betreuerart_kurzbz' => $row['betreuerart_kurzbz']
],
[
'vertrag_id' => $vertrag_id,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (!$result_projektbetreuer)
{
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
}
$this->db->trans_complete();
$this->terminateWithSuccess(true);
}
public function loadContract($vertrag_id)
{
$result = $this->VertragModel->load($vertrag_id);
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) {
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Vertrag_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)));
}
public function deleteContract($vertrag_id)
{
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
//check if attached Lehrauftrag
$resultLehrauftrag = $this->LehreinheitmitarbeiterModel->load([
'vertrag_id' => $vertrag_id
]);
if(hasData($resultLehrauftrag))
{
$resultLehrauftrag = getData($resultLehrauftrag);
foreach($resultLehrauftrag as $lehrauftrag)
{
$result = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $lehrauftrag->lehreinheit_id,
'mitarbeiter_uid' => $lehrauftrag->mitarbeiter_uid,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$this->getDataOrTerminateWithError($result);
}
}
//if attached Betreuung
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
//if attached Betreuung
$resultBetreuung = $this->Projektbetreuermodel->load([
'vertrag_id' => $vertrag_id
]);
if(hasData($resultBetreuung))
{
$resultBetreuung = getData($resultBetreuung);
foreach($resultBetreuung as $betreuung)
{
$result = $this->Projektbetreuermodel->update(
[
'person_id' => $betreuung->person_id,
'projektarbeit_id' => $betreuung->projektarbeit_id,
'betreuerart_kurzbz' => $betreuung->betreuerart_kurzbz,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$this->getDataOrTerminateWithError($result);
}
}
$result = $this->VertragvertragsstatusModel->load([
'vertrag_id' => $vertrag_id
]);
if(hasData($result))
{
$data = getData($result);
foreach ($data as $item)
{
//delete all entries in lehre.tbl_vertrag_vertragsstatus
$result = $this->VertragvertragsstatusModel->delete([
'vertrag_id' => $vertrag_id,
'vertragsstatus_kurzbz' => $item->vertragsstatus_kurzbz,
'uid' => $item->uid
]);
if(isError($result))
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
}
//delete Contract
$result = $this->VertragModel->delete(
array('vertrag_id' => $vertrag_id,
)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) {
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Vertrag_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function insertContractStatus()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('vertragsstatus_kurzbz', 'vertragsstatus_kurzbz', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'vertragsstatus_kurzbz'])
]);
$this->form_validation->set_rules('datum', 'Datum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Datum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->VertragvertragsstatusModel->loadWhere(
array(
'vertrag_id' => $this->input->post('vertrag_id'),
'vertragsstatus_kurzbz' => $this->input->post('vertragsstatus_kurzbz')
)
);
if (hasData($result))
{
$this->terminateWithError($this->p->t('vertrag', 'error_statusVorhanden'), self::ERROR_TYPE_GENERAL);
}
$status_result = $this->VertragvertragsstatusModel->insert([
'vertrag_id' => $this->input->post('vertrag_id'),
'uid' => getAuthUID(),
'vertragsstatus_kurzbz' => $this->input->post('vertragsstatus_kurzbz'),
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'datum' => $this->input->post('datum')
]);
if (!$status_result) {
$this->terminateWithError('Fehler beim Hinzufügen des Vertragsstatus.');
}
return $this->terminateWithSuccess(current(getData($status_result)));
}
public function deleteContractStatus()
{
$status = $this->input->post('vertragsstatus_kurzbz');
$vertrag_id = $this->input->post('vertrag_id');
$result = $this->VertragvertragsstatusModel->delete(
array(
'vertrag_id' => $vertrag_id,
'vertragsstatus_kurzbz' => $status
)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'vertragsstatus_kurzb']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function loadContractStatus()
{
$status = $this->input->get('vertragsstatus_kurzbz');
$vertrag_id = $this->input->get('vertrag_id');
$result = $this->VertragvertragsstatusModel->loadWhere(
array(
'vertrag_id' => $vertrag_id,
'vertragsstatus_kurzbz' => $status
)
);
if (!$result) {
$this->terminateWithError('Status not existing');
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function updateContractStatus()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('vertragsstatus_kurzbz', 'vertragsstatus_kurzbz', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'vertragsstatus_kurzbz'])
]);
$this->form_validation->set_rules('datum', 'Datum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Datum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$status_result = $this->VertragvertragsstatusModel->update(
[
'vertrag_id' => $this->input->post('vertrag_id'),
'vertragsstatus_kurzbz' => $this->input->post('vertragsstatus_kurzbz')
],
[
'uid' => getAuthUID(),
'updateamum' => date('c'),
'updatevon' => getAuthUID(),
'datum' => $this->input->post('datum')
]
);
if (!$status_result) {
$this->terminateWithError('Fehler beim Updaten des Vertragsstatus.');
}
return $this->terminateWithSuccess(current(getData($status_result)));
}
public function deleteLehrauftrag()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$vertrag_id = $this->input->post('vertrag_id');
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
//kein delete: ein update, bei dem die vertrag_id auf null gesetzt wird
$result = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $lehreinheit_id,
'mitarbeiter_uid' => $mitarbeiter_uid,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Id_Lehrauftrag']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function deleteBetreuung()
{
$person_id= $this->input->post('person_id');
$projektarbeit_id = $this->input->post('projektarbeit_id');
$betreuerart_kurzbz = $this->input->post('betreuerart_kurzbz');
$vertrag_id = $this->input->post('vertrag_id');
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
$result = $this->Projektbetreuermodel->update(
[
'person_id' => $person_id,
'projektarbeit_id' => $projektarbeit_id,
'betreuerart_kurzbz' => $betreuerart_kurzbz,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Id_Projektbetreuung']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function getMitarbeiter()
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getPersonenWithContractDetails();
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
//return data before PV21 (with filter fix angestellt, active and with bisverwendung)
$result = $this->Mitarbeitermodel->getPersonal(true, true, true);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
}
return $this->terminateWithSuccess(getData($result));
}
public function getPersonAbteilung($mitarbeiter_uid)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getLeitungOrg($oekurzbz)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getHeader($person_id)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getHeader($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
}
@@ -0,0 +1,63 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Vorlagen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getVorlagen' => ['admin:r', 'assistenz:r'],
'getVorlagenByLoggedInUser' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('system/Vorlage_model', 'VorlageModel');
// Additional Permission Checks
//TODO(manu) check permissions
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->load->library('VorlageLib');
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getVorlagen()
{
$this->load->model('system/Vorlage_model', 'VorlageModel');
$this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC');
$result = $this->VorlageModel->loadWhere(
array(
'mimetype' => 'text/html'
));
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getVorlagenByLoggedInUser()
{
//get oe of user
$uid = getAuthUID();
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = current($data);
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
+38 -2
View File
@@ -81,8 +81,11 @@ class FHCAPI_Controller extends Auth_Controller
// For JSON Requests (as opposed to multipart/form-data) get the $_POST variable from the input stream instead
if ($this->input->get_request_header('Content-Type', true) == 'application/json')
$_POST = json_decode($this->security->xss_clean($this->input->raw_input_stream), true);
elseif (isset($_POST['_jsondata'])) {
{
$_POST = json_decode($this->input->raw_input_stream, true);
}
elseif (isset($_POST['_jsondata']))
{
$_POST = array_merge($_POST, json_decode($_POST['_jsondata'], true));
unset($_POST['_jsondata']);
}
@@ -223,6 +226,39 @@ class FHCAPI_Controller extends Auth_Controller
return $result->retval;
}
protected function terminateWithFileOutput($contenttype, $content, $filename=null)
{
$this->clearOutputBuffering();
$this->output->set_status_header(200)
->set_content_type($contenttype)
->set_header('Expires: 0')
->set_header('Cache-Control: no-store, no-cache, must-revalidate')
->set_header('Pragma: public')
->set_header('Content-Length: ' . strlen($content));
if($filename)
{
$cleanedfilename = preg_replace('/[^a-zA-Z0-9\-_.]/', '_', $filename);
$this->output->set_header('Content-Disposition: attachment; filename="'
. $cleanedfilename . '"');
}
else
{
$this->output->set_header('Content-Disposition: inline');
}
$this->output->set_output($content)
->_display();
exit();
}
private function clearOutputBuffering()
{
while(ob_get_level() > 0)
{
ob_end_clean();
}
}
// ---------------------------------------------------------------
// Security
-23
View File
@@ -44,27 +44,4 @@ class Bisio_model extends DB_Model
else
return success("Bisio not found");
}
/**
* checks, if an (extension) table exists to avoid later errors
* @param String $schema like 'extension'
* @param String $table like 'tbl_mo_bisiozuordnung'
* @return boolean
*/
public function tableExists($schema, $table)
{
$params = array($schema, $table);
$qry = "SELECT
1
FROM
information_schema.role_table_grants
WHERE
table_schema = ?
AND table_name = ?";
$result = $this->execQuery($qry, $params);
return $result;
}
}
@@ -0,0 +1,14 @@
<?php
class Mobilitaetstyp_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'bis.tbl_mobilitaetstyp';
$this->pk = 'mobilitaetstyp_kurzbz';
}
}
+63 -4
View File
@@ -92,7 +92,7 @@ class Akte_model extends DB_Model
a.anmerkung,
a.nachgereicht,
a.nachgereicht_am,
CASE WHEN MAX(dp.dokument_kurzbz) IS NOT NULL THEN TRUE ELSE FALSE END AS accepted
CASE WHEN MAX(dp.dokument_kurzbz) IS NOT NULL THEN TRUE ELSE FALSE END AS accepted,
FROM public.tbl_akte a
INNER JOIN public.tbl_prestudent p USING(person_id)
LEFT JOIN public.tbl_dokumentprestudent dp USING(prestudent_id, dokument_kurzbz)
@@ -111,6 +111,61 @@ class Akte_model extends DB_Model
return $this->execQuery($query, $parametersArray);
}
/**
* getAktenAccepted FAS
*/
public function getAktenFAS($person_id, $dokument_kurzbz = null, $stg_kz = null, $prestudent_id = null, $returnInhalt = false)
{
$query = 'SELECT
a.akte_id,
a.bezeichnung,
a.dokument_kurzbz,
a.titel_intern,
a.anmerkung_intern,
a.insertamum as hochgeladenamum,
a.updatevon, a.insertvon, a.uid,
a.dms_id, a.anmerkung as infotext,
a.nachgereicht,
CASE
WHEN inhalt IS NOT NULL OR a.dms_id IS NOT NULL
THEN true
ELSE false
END AS vorhanden,
a.nachgereicht_am,
ausstellungsnation, formal_geprueft_amum, archiv,
signiert, stud_selfservice, akzeptiertamum, inhalt
FROM public.tbl_akte a
WHERE a.person_id = ?';
$parametersArray = array($person_id);
if (!isEmptyString($dokument_kurzbz))
{
$query .= " AND dokument_kurzbz = ?
AND dokument_kurzbz NOT IN ('Zeugnis','DiplSupp','Bescheid')";
array_push($parametersArray, $dokument_kurzbz);
}
if($stg_kz != null && $prestudent_id != null)
{
$query.= " AND dokument_kurzbz not in (
SELECT dokument_kurzbz
FROM public.tbl_dokument
JOIN public.tbl_dokumentstudiengang USING(dokument_kurzbz)
WHERE studiengang_kz= ?
AND dokument_kurzbz NOT IN(
SELECT dokument_kurzbz FROM public.tbl_dokumentprestudent
JOIN public.tbl_dokument USING(dokument_kurzbz)
WHERE prestudent_id=?))";
array_push($parametersArray, $stg_kz);
array_push($parametersArray, $prestudent_id);
}
$query .= ' ORDER BY erstelltam';
return $this->execQuery($query, $parametersArray);
}
/**
* getAktenAcceptedDms
*/
@@ -195,9 +250,9 @@ class Akte_model extends DB_Model
}
/**
* Liefert die Archivdokumente einer Person
* Liefert die Archivdokumente einer Person/mehrerer Personen
*
* @param integer $person_id
* @param integer/array $person_id
* @param boolean|null $signiert Wenn true werden nur Dokumente geliefert die digital signiert wurden.
* @param boolean|null $stud_selfservice Wenn true werden nur Dokumente geliefert die Studierende selbst herunterladen duerfen.
*
@@ -237,10 +292,14 @@ class Akte_model extends DB_Model
if ($stud_selfservice !== null)
$this->db->where('stud_selfservice', (boolean)$stud_selfservice);
if (is_array($person_id))
$this->db->where_in('person_id', $person_id);
else
$this->db->where('person_id', $person_id);
$this->addOrder('erstelltam', 'DESC');
return $this->loadWhere([
'person_id' => $person_id,
'archiv' => true
]);
}
+87
View File
@@ -11,4 +11,91 @@ class Dokument_model extends DB_Model
$this->dbTable = 'public.tbl_dokument';
$this->pk = 'dokument_kurzbz';
}
/**
* Loads all missing Documents of a Studiengang
* a Prestudent has not submitted
* @param integer studiengang_kz
* @param integer prestudent_id
* @param boolean archivdokumente
* Default: true.
* If false, documents that are archivable (tbl_vorlage.archivierbar e.g. certificate, notice, ...) not retrieved
* @return Array of Documents || error
*/
public function getMissingDocuments($studiengang_kz, $prestudent_id = null, $archivdokumente = false, $person_id = null)
{
$parametersArray = array($studiengang_kz);
$qry = "SELECT
tbl_dokument.* ,
tbl_dokumentstudiengang.*
FROM public.tbl_dokument
JOIN public.tbl_dokumentstudiengang USING(dokument_kurzbz)
LEFT JOIN public.tbl_vorlage ON (tbl_dokument.dokument_kurzbz = tbl_vorlage.vorlage_kurzbz)
WHERE studiengang_kz = ? ";
if($prestudent_id)
{
array_push($parametersArray, $prestudent_id);
$qry.=" AND tbl_dokument.dokument_kurzbz NOT IN (
SELECT dokument_kurzbz FROM public.tbl_dokumentprestudent WHERE prestudent_id= ?)";
}
if(!$archivdokumente)
{
$qry.=" AND (tbl_vorlage.archivierbar = FALSE OR tbl_vorlage.archivierbar IS NULL)";
}
$qry.=" ORDER BY tbl_dokument.dokument_kurzbz;";
return $this->execQuery($qry, $parametersArray);
}
public function getUnacceptedDocuments($prestudent_id, $person_id)
{
$parametersArray = array($person_id, $prestudent_id);
$qry = " SELECT
a.akte_id,
a.bezeichnung,
a.dokument_kurzbz,
a.titel_intern,
a.anmerkung_intern,
a.insertamum as hochgeladenamum,
a.updatevon,
a.insertvon,
a.uid,
a.dms_id,
a.anmerkung as infotext,
a.nachgereicht,
CASE
WHEN inhalt IS NOT NULL
OR a.dms_id IS NOT NULL THEN true
ELSE false
END AS vorhanden,
a.nachgereicht_am,
ausstellungsnation,
formal_geprueft_amum,
archiv,
signiert,
stud_selfservice,
akzeptiertamum,
inhalt
FROM
public.tbl_akte a
WHERE
a.person_id = ?
AND a.dokument_kurzbz NOT IN (
SELECT
dokument_kurzbz
FROM
public.tbl_dokumentprestudent
WHERE
prestudent_id = ?
)
AND a.dokument_kurzbz NOT IN ('Zeugnis','DiplSupp','Bescheid')
ORDER BY a.dokument_kurzbz;";
return $this->execQuery($qry, $parametersArray);
}
}
@@ -69,4 +69,41 @@ class Dokumentprestudent_model extends DB_Model
return $result;
}
/**
* Loads all Documents of Prestudent, already submitted
* @param integer prestudent_id
* @param boolean archivdokumente Default true. if false, archivable Documents (tbl_vorlage.archivierbar zB Zeugnis, Bescheid, ...) not retrieved
* @return Array of Documents || error
*/
public function getPrestudentDokumente($prestudent_id, $archivdokumente = true)
{
$parametersArray = array($prestudent_id);
$qry = "SELECT
d.bezeichnung,
d.dokument_kurzbz,
dp.datum as Docdatum,
dp.mitarbeiter_uid as DocMitarbeiter_uid,
dp.insertamum as Docinsertamum,
dp.prestudent_id,
CONCAT(p.vorname, ' ', p.nachname) as insertvonma
FROM
public.tbl_dokumentprestudent dp
JOIN public.tbl_dokument d USING(dokument_kurzbz)
LEFT JOIN public.tbl_vorlage v ON (d.dokument_kurzbz = v.vorlage_kurzbz)
LEFT JOIN public.tbl_benutzer bn ON (bn.uid = dp.mitarbeiter_uid)
LEFT JOIN public.tbl_person p ON (p.person_id = bn.person_id)
WHERE
prestudent_id = ?";
if(!$archivdokumente)
{
$qry.=" AND (v.archivierbar = FALSE OR v.archivierbar IS NULL)";
}
$qry.=" ORDER BY d.bezeichnung ASC";
return $this->execQuery($qry, $parametersArray);
}
}
+247 -1
View File
@@ -511,4 +511,250 @@ class Reihungstest_model extends DB_Model
return $this->execQuery($query, array($date, $studiengang_kz));
}
}
/**
* Loads all placement tests of a given person
* @param integer $person_id
* @return array Returns object array with data of placement tests
*/
public function getReihungstestPerson($person_id)
{
$query = '
SELECT
tbl_rt_person.*,
tbl_reihungstest.studiengang_kz,
tbl_reihungstest.anmerkung,
tbl_reihungstest.datum,
tbl_reihungstest.uhrzeit,
tbl_reihungstest.ext_id,
tbl_reihungstest.max_teilnehmer,
tbl_reihungstest.oeffentlich,
tbl_reihungstest.freigeschaltet,
tbl_reihungstest.studiensemester_kurzbz as studiensemester,
tbl_reihungstest.stufe,
tbl_reihungstest.anmeldefrist,
tbl_reihungstest.aufnahmegruppe_kurzbz,
tbl_studiengang.typ,
UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel,
so.studiengangbezeichnung,
so.studiengangbezeichnung_englisch,
so.studiengangkurzbzlang
FROM
public.tbl_rt_person
JOIN public.tbl_reihungstest ON (rt_id=reihungstest_id)
JOIN public.tbl_studiengang ON tbl_reihungstest.studiengang_kz = tbl_studiengang.studiengang_kz
JOIN lehre.tbl_studienplan sp USING(studienplan_id)
JOIN lehre.tbl_studienordnung so USING(studienordnung_id)
WHERE
tbl_rt_person.person_id = ?
ORDER BY datum, uhrzeit ASC';
return $this->execQuery($query, array($person_id));
}
/**
* Calculates Result of Placement Test for a given Person and given placementtest
* and with taking account of weighting per area
*
* @param $person_id ID of Person
* @param $punkte if true result is points else result is percentage of sum
* @param $reihungstest_id ID of Placementtest
* @param $weightedArray array of weighting per area (gewicht per gebiet_id)
* @return float result
*/
public function getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray = null)
{
$parametersArray = array($reihungstest_id);
$qry = "
SELECT DISTINCT ON (vw_auswertung_ablauf.gebiet_id) gebiet_id,
vw_auswertung_ablauf.*,
tbl_studiengang.typ
FROM
testtool.vw_auswertung_ablauf
JOIN
public.tbl_studiengang USING (studiengang_kz)
WHERE
reihungstest_id = ? ";
//using prestudent Status to avoid to get the sum of more than 1 placement tests
$qry .= "
AND prestudent_id = (
SELECT
prestudent_id
FROM
public.tbl_rt_person
JOIN
public.tbl_prestudent USING(person_id)
JOIN
public.tbl_prestudentstatus USING (prestudent_id, studienplan_id)
JOIN
tbl_reihungstest ON (
tbl_rt_person.rt_id = tbl_reihungstest.reihungstest_id
)
WHERE
tbl_rt_person.person_id = ?
AND
tbl_rt_person.rt_id = ?
AND
tbl_prestudentstatus.status_kurzbz = 'Interessent'
AND
tbl_prestudentstatus.studiensemester_kurzbz = tbl_reihungstest.studiensemester_kurzbz
ORDER BY tbl_reihungstest.datum DESC, tbl_prestudent.priorisierung ASC LIMIT 1
)
";
array_push($parametersArray, $person_id);
array_push($parametersArray, $reihungstest_id);
$resultRtPerson = $this->execQuery($qry, $parametersArray);
$ergebnis = 0;
$summeGewicht = 0;
foreach ($resultRtPerson->retval as $row)
{
$prozent = 0;
if($row->punkte>=$row->maxpunkte)
{
$prozent = 100;
$row->punkte = $row->maxpunkte;
}
else
$prozent = (($row->punkte + $row->offsetpunkte)/($row->maxpunkte + $row->offsetpunkte))*100;
if($punkte == 'true')
{
if($row->punkte)
{
$ergebnis += $row->punkte;
}
}
else
{
if ($row->punkte)
{
$gew = isset($weightedArray[$row->gebiet_id]) ? $weightedArray[$row->gebiet_id] : 1;
$ergebnis += $prozent * $gew;
$summeGewicht += $gew;
}
}
}
$return = $summeGewicht > 0
? number_format($ergebnis/$summeGewicht, 4, '.', '')
: number_format($ergebnis, 4, '.', '');
return $return;
}
/**
* returns Reihungstests for given studyplans and include_ids
*
* @param Array $studienplan_arr array of studienplaene
* @param Array $include_ids array of include_ids
* @return Array List of Reihungstests
*/
public function getReihungstestByStudyPlanAndIds($studienplan_arr, $include_ids = null)
{
$studienplan_ids_string = implode(',', $studienplan_arr);
$studienplan_arr = explode(',', $studienplan_ids_string);
$parametersArray = array($studienplan_arr);
$qry = "
SELECT
distinct a.*,
CASE EXTRACT(DOW FROM a.datum)
WHEN 0 THEN 'So'
WHEN 1 THEN 'Mo'
WHEN 2 THEN 'Di'
WHEN 3 THEN 'Mi'
WHEN 4 THEN 'Do'
WHEN 5 THEN 'Fr'
WHEN 6 THEN 'Sa'
END AS wochentag,
sg.kurzbzlang as stg,
(
SELECT count(*) FROM public.tbl_rt_person
WHERE rt_id = a.reihungstest_id
) as angemeldete_teilnehmer
FROM
public.tbl_reihungstest a
JOIN public.tbl_rt_studienplan USING(reihungstest_id)
JOIN public.tbl_studiengang sg USING(studiengang_kz)
WHERE studienplan_id IN ?";
if($include_ids && is_array($include_ids) && count($include_ids) > 0)
{
$include_ids_string = implode(',', $include_ids);
$include_ids = explode(',', $include_ids_string);
array_push($parametersArray, $include_ids);
$qry .= "OR reihungstest_id in ?";
}
$qry .= "ORDER BY a.datum DESC";
return $this->execQuery($qry, $parametersArray);
}
/**
* returns Reihungstests for given studyplans and include_ids
*
* @param Integer $studiengang_kz
* @param $include_id optional (here null)
* @return Array List of Reihungstests
*/
public function getZukuenftigeReihungstestStg($studiengang_kz, $include_id = null)
{
$parametersArray = array($studiengang_kz, $studiengang_kz, $include_id);
$qry = "
SELECT *,
CASE EXTRACT(DOW FROM a.datum)
WHEN 0 THEN 'So'
WHEN 1 THEN 'Mo'
WHEN 2 THEN 'Di'
WHEN 3 THEN 'Mi'
WHEN 4 THEN 'Do'
WHEN 5 THEN 'Fr'
WHEN 6 THEN 'Sa'
END AS wochentag,
(
SELECT count(*) FROM public.tbl_prestudent
WHERE reihungstest_id=a.reihungstest_id
) as angemeldete_teilnehmer
FROM
(
SELECT *, '1' as sortierung,
(
SELECT upper(typ || kurzbz) FROM public.tbl_studiengang
WHERE studiengang_kz=tbl_reihungstest.studiengang_kz
) as stg
FROM
public.tbl_reihungstest
WHERE
datum>=now()-'1 days'::interval AND studiengang_kz=?
UNION
SELECT *, '2' as sortierung,
(
SELECT upper(typ || kurzbz) FROM public.tbl_studiengang
WHERE studiengang_kz=tbl_reihungstest.studiengang_kz
) as stg
FROM
public.tbl_reihungstest
WHERE datum>=now()-'1 days'::interval AND studiengang_kz!=?
UNION
SELECT *, '0' as sortierung,
(
SELECT upper(typ || kurzbz) FROM public.tbl_studiengang
WHERE studiengang_kz=tbl_reihungstest.studiengang_kz
) as stg
FROM
public.tbl_reihungstest
WHERE reihungstest_id=?
ORDER BY sortierung, stg, datum
) a
";
return $this->execQuery($qry, $parametersArray);
}
}
@@ -202,4 +202,66 @@ class Anrechnung_model extends DB_Model
return success();
}
/**
* Get Anrechnungsdata for Table Anrechnungen
*
* @param $prestudent_id
* @return array
*/
public function getAnrechnungsData($prestudent_id)
{
$qry = '
SELECT
lehre.tbl_anrechnung.anrechnung_id,
lehre.tbl_anrechnung.prestudent_id,
lehre.tbl_anrechnung.lehrveranstaltung_id,
lehre.tbl_lehrveranstaltung.bezeichnung AS bez_lehrveranstaltung,
lehre.tbl_anrechnung_begruendung.bezeichnung AS begruendung,
lehre.tbl_anrechnung_anrechnungstatus.status_kurzbz AS status,
genehmigt_von,
lehre.tbl_anrechnung.insertamum,
lehre.tbl_anrechnung.insertvon,
lehre.tbl_anrechnung.updateamum,
lehre.tbl_anrechnung.updatevon,
lehrveranstaltung_id_kompatibel,
lv_comp.bezeichnung as lehrveranstaltung_bez_kompatibel,
count(nz.notizzuordnung_id) AS notizen_anzahl
FROM
lehre.tbl_anrechnung
JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN lehre.tbl_lehrveranstaltung lv_comp ON (lehre.tbl_anrechnung.lehrveranstaltung_id_kompatibel = lv_comp.lehrveranstaltung_id)
JOIN lehre.tbl_anrechnung_begruendung USING (begruendung_id)
LEFT JOIN lehre.tbl_anrechnung_anrechnungstatus ON (lehre.tbl_anrechnung_anrechnungstatus.anrechnung_id = lehre.tbl_anrechnung.anrechnung_id)
AND lehre.tbl_anrechnung_anrechnungstatus.insertamum = (
SELECT MAX(insertamum)
FROM lehre.tbl_anrechnung_anrechnungstatus
WHERE anrechnung_id = lehre.tbl_anrechnung.anrechnung_id
)
LEFT JOIN lehre.tbl_anrechnungstatus USING (status_kurzbz)
LEFT JOIN public.tbl_notizzuordnung nz ON (nz.anrechnung_id = lehre.tbl_anrechnung.anrechnung_id)
WHERE
lehre.tbl_anrechnung.prestudent_id = ?
GROUP BY
nz.anrechnung_id,
lehre.tbl_anrechnung.anrechnung_id,
lehre.tbl_anrechnung.prestudent_id,
lehre.tbl_anrechnung.lehrveranstaltung_id,
bez_lehrveranstaltung,
begruendung,
status,
genehmigt_von,
lehre.tbl_anrechnung.insertamum,
lehre.tbl_anrechnung.insertvon,
lehre.tbl_anrechnung.updateamum,
lehre.tbl_anrechnung.updatevon,
lehrveranstaltung_id_kompatibel,
lehrveranstaltung_bez_kompatibel
ORDER BY
lehre.tbl_anrechnung.updateamum ASC
';
return $this->execQuery($qry, array($prestudent_id));
}
}
@@ -0,0 +1,14 @@
<?php
class Anrechnunganrechnungstatus_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'lehre.tbl_anrechnung_anrechnungstatus';
$this->pk = 'anrechnungstatus_id';
}
}
@@ -988,4 +988,41 @@ class Lehrveranstaltung_model extends DB_Model
return $this->execQuery($qry, $params);
}
/**
* Gets lehrveranstaltungen of Studienplan
* @param $studienplan_id ID des Studienplans
* @param $semester Semester optional
* @return array|null
*/
public function getLvsByStudienplanId($studienplan_id, $semester = null)
{
$params = array($studienplan_id);
$qry = "SELECT tbl_lehrveranstaltung.*,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id,
tbl_studienplan_lehrveranstaltung.semester as stpllv_semester,
tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht,
tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent,
tbl_studienplan_lehrveranstaltung.sort stpllv_sort,
tbl_studienplan_lehrveranstaltung.curriculum,
tbl_studienplan_lehrveranstaltung.export,
tbl_studienplan_lehrveranstaltung.genehmigung
FROM lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung
USING(lehrveranstaltung_id)
WHERE tbl_studienplan_lehrveranstaltung.studienplan_id = ?
";
if ($semester !== null)
{
$qry.= " AND tbl_studienplan_lehrveranstaltung.semester = ?";
$params[] = $semester;
}
$qry .= " ORDER BY stpllv_sort, semester, sort";
return $this->execQuery($qry, $params);
}
}
@@ -191,7 +191,7 @@ class Organisationseinheit_model extends DB_Model
/**
* @param string $oe_kurzbz
*
*
* @return stdClass
*/
public function getWithType($oe_kurzbz)
@@ -203,18 +203,14 @@ class Organisationseinheit_model extends DB_Model
}
/**
* Get OEs by eventQuery string. Use with autocomplete event queries.
* @param $eventQuery String
* @return array
* get highest organisation units
*/
public function getAutocompleteSuggestions($eventQuery)
public function getHeads()
{
$this->addSelect('oe_kurzbz');
$this->addSelect('organisationseinheittyp_kurzbz, oe_kurzbz, bezeichnung, aktiv, lehre');
$this->addOrder('organisationseinheittyp_kurzbz, bezeichnung');
$this->addSelect('*');
$this->addSelect('oe_kurzbz as head');
$result = $this->loadWhere(array('oe_parent_kurzbz' => null, 'aktiv' => true));
return $this->loadWhere("
oe_kurzbz ILIKE '%". $this->escapeLike($eventQuery). "%'
");
return $result;
}
}
@@ -134,4 +134,17 @@ class Studienplan_model extends DB_Model
'prestudent_id' => $prestudent_id
]);
}
public function getStudienplaeneForPerson($person_id)
{
$this->addDistinct();
$this->addSelect($this->dbTable . '.*');
$this->addSelect('ps.*');
$this->addJoin('public.tbl_prestudentstatus pss', 'studienplan_id');
$this->addJoin('public.tbl_prestudent ps', 'prestudent_id');
return $this->loadWhere([
'person_id' => $person_id
]);
}
}
@@ -33,4 +33,16 @@ class Benutzergruppe_model extends DB_Model
$uids = (hasData($res)) ? getData($res) : array();
return $uids;
}
/**
* Laedt die Aufnahmegruppe(n) in Abhängigkeit von User und Studiensemester
* @param uid, gruppe_kurzbz, studiensemester_kurzbz
* @return array
*/
public function loadAufnahmegruppen($uid, $stsem)
{
$query = "
SELECT * FROM tbl_gruppe WHERE aufnahmegruppe=true;";
return $this->execReadOnlyQuery($query);
}
}
+26 -3
View File
@@ -154,8 +154,21 @@ class Notiz_model extends DB_Model
public function getNotizWithDocEntries($id, $type)
{
$qry = "
SELECT
n.*, count(dms_id) as countDoc, z.notizzuordnung_id,
SELECT
n.*,
CASE
WHEN person_verfasser.vorname IS NOT NULL AND person_verfasser.vorname != ''
OR person_verfasser.nachname IS NOT NULL AND person_verfasser.nachname != ''
THEN CONCAT(person_verfasser.vorname, ' ', person_verfasser.nachname)
ELSE NULL
END AS verfasser,
CASE
WHEN person_bearbeiter.vorname IS NOT NULL AND person_bearbeiter.vorname != ''
OR person_bearbeiter.nachname IS NOT NULL AND person_bearbeiter.nachname != ''
THEN CONCAT(person_bearbeiter.vorname, ' ', person_bearbeiter.nachname)
ELSE NULL
END AS bearbeiter,
count(dms_id) as countDoc, z.notizzuordnung_id,
(CASE
WHEN n.updateamum >= n.insertamum THEN n.updateamum
ELSE n.insertamum
@@ -173,10 +186,20 @@ class Notiz_model extends DB_Model
public.tbl_notiz_dokument dok USING (notiz_id)
LEFT JOIN
campus.tbl_dms_version USING (dms_id)
LEFT JOIN
public.tbl_benutzer p_verfasser ON (p_verfasser.uid = n.verfasser_uid)
LEFT JOIN
public.tbl_person person_verfasser ON (person_verfasser.person_id = p_verfasser.person_id)
LEFT JOIN
public.tbl_benutzer p_bearbeiter ON (p_bearbeiter.uid = n.bearbeiter_uid)
LEFT JOIN
public.tbl_person person_bearbeiter ON (person_bearbeiter.person_id = p_bearbeiter.person_id)
WHERE
z.$type = ?
GROUP BY
notiz_id, z.notizzuordnung_id
notiz_id, z.notizzuordnung_id,
person_verfasser.vorname, person_verfasser.nachname,
person_bearbeiter.vorname, person_bearbeiter.nachname
";
return $this->execQuery($qry, array($type, $id));
@@ -12,34 +12,34 @@ class Mitarbeiter_model extends DB_Model
$this->pk = 'mitarbeiter_uid';
}
/**
* Checks if the user is a Mitarbeiter.
* @param string $uid
* @param boolean null $fixangestellt
* @return array
*/
public function isMitarbeiter($uid, $fixangestellt = null)
{
$this->addSelect('1');
/**
* Checks if the user is a Mitarbeiter.
* @param string $uid
* @param boolean null $fixangestellt
* @return array
*/
public function isMitarbeiter($uid, $fixangestellt = null)
{
$this->addSelect('1');
if (is_bool($fixangestellt))
{
$result = $this->loadWhere(array('mitarbeiter_uid' => $uid, 'fixangestellt' => $fixangestellt));
}
else // default
{
$result = $this->loadWhere(array('mitarbeiter_uid' => $uid));
}
if (is_bool($fixangestellt))
{
$result = $this->loadWhere(array('mitarbeiter_uid' => $uid, 'fixangestellt' => $fixangestellt));
}
else // default
{
$result = $this->loadWhere(array('mitarbeiter_uid' => $uid));
}
if(hasData($result))
{
return success(true);
}
else
{
return success(false);
}
}
if(hasData($result))
{
return success(true);
}
else
{
return success(false);
}
}
/**
* Laedt das Personal
@@ -98,6 +98,129 @@ class Mitarbeiter_model extends DB_Model
return $this->execQuery($qry, $params);
}
/**
* gibt Personen mit Übersicht von Vertragsdaten aus
*
* @return array
*/
public function getPersonenWithContractDetails($person_id = null)
{
$qry = "
SELECT
b.uid , p.person_id,
p.vorname, p.nachname,
gebdatum,
COALESCE(b.alias, b.uid) AS email,
STRING_AGG(DISTINCT va.bezeichnung, ', ') AS Vertragsarten,
STRING_AGG(DISTINCT u.bezeichnung, ', ') AS Unternehmen,
STRING_AGG(d.dienstverhaeltnis_id::TEXT, ', ') AS ids,
b.aktiv
FROM
hr.tbl_dienstverhaeltnis d
JOIN
public.tbl_benutzer b ON d.mitarbeiter_uid = b.uid
JOIN
public.tbl_person p ON p.person_id = b.person_id
JOIN
public.tbl_organisationseinheit u ON d.oe_kurzbz = u.oe_kurzbz
JOIN
hr.tbl_vertragsart va ON d.vertragsart_kurzbz = va.vertragsart_kurzbz
";
if($person_id)
{
$qry .= " WHERE p.person_id = ?";
}
$qry.= "
GROUP BY
b.uid, p.person_id, p.vorname, p.nachname, b.alias
ORDER BY
p.nachname, p.vorname;
";
$params = array($person_id);
return $this->execQuery($qry, $params);
}
/**
* get current disciplinary Abteilung of person
*
* @param $person_id
*
* @return Array benutzerfunktionsdata
*/
public function getPersonAbteilung($uid)
{
$qry = "
SELECT
bf.benutzerfunktion_id, bf.fachbereich_kurzbz, bf.uid, bf.funktion_kurzbz, bf.updateamum,
bf.updatevon, bf.insertamum, bf.insertvon, bf.ext_id, bf.semester, bf.oe_kurzbz,
bf.datum_von, bf.datum_bis, bf.bezeichnung, bf.wochenstunden,
oe.oe_kurzbz, oe.oe_parent_kurzbz, oe.bezeichnung,
oe.organisationseinheittyp_kurzbz, oe.aktiv, oe.mailverteiler,
oe.freigabegrenze, oe.kurzzeichen, oe.lehre, oe.standort,
oe.warn_semesterstunden_frei, oe.warn_semesterstunden_fix, oe.standort_id
FROM tbl_benutzerfunktion bf
JOIN public.tbl_organisationseinheit oe USING(oe_kurzbz)
WHERE uid = ?
AND funktion_kurzbz = 'oezuordnung'
AND datum_von <= NOW()
AND (datum_bis IS NULL OR datum_bis >= NOW())
";
$result = $this->execQuery($qry, [$uid]);
return $result;
}
/**
* get Leitung / Vorgesetzten of current OE
*
* @param $oe_kurzbz
*
* @return Array persondata / benutzerfunktionsdata
*/
public function getLeitungOrg($oe_kurzbz)
{
$qry = "
SELECT bf.benutzerfunktion_id,bf.fachbereich_kurzbz,bf.uid,bf.funktion_kurzbz,
bf.updateamum,bf.updatevon,bf.insertamum,bf.insertvon,bf.ext_id,bf.semester,
bf.oe_kurzbz,bf.datum_von,bf.datum_bis,bf.bezeichnung,bf.wochenstunden,
p.person_id, p.vorname,p.nachname,p.titelpre,p.titelpost
FROM public.tbl_benutzerfunktion bf JOIN public.tbl_organisationseinheit oe USING(oe_kurzbz)
JOIN public.tbl_benutzer b USING (uid) JOIN public.tbl_mitarbeiter ma ON(b.uid=ma.mitarbeiter_uid)
JOIN public.tbl_person p USING(person_id)
WHERE funktion_kurzbz='Leitung' AND oe.oe_kurzbz = ?
AND datum_von<=now() AND (datum_bis is null OR datum_bis>=now());
";
return $this->execQuery($qry, array($oe_kurzbz));
}
/**
* get persondata for person_id
*
* @param $oe_kurzbz
*
* @return Array persondata
*/
public function getHeader($person_id)
{
$qry = "
SELECT
titelpre, vorname, nachname, titelpost, foto, foto_sperre, person_id, alias, telefonklappe
FROM
public.tbl_person
JOIN public.tbl_benutzer b USING(person_id)
JOIN public.tbl_mitarbeiter ma ON (ma.mitarbeiter_uid = b.uid)
WHERE
person_id = ?
";
return $this->execQuery($qry, array($person_id));
}
/**
* Gibt ein Array mit den UIDs der Vorgesetzten zurück
* @return object
@@ -213,7 +336,7 @@ class Mitarbeiter_model extends DB_Model
if (hasData($kurzbzexists) && getData($kurzbzexists)[0])
return error('No Kurzbezeichnung could be generated');
return success($kurzbz);
}
@@ -240,13 +363,13 @@ class Mitarbeiter_model extends DB_Model
$qry = "
SELECT " . $returnwert . "
FROM
public.tbl_mitarbeiter ma
public.tbl_mitarbeiter ma
JOIN
public.tbl_benutzer b on (ma.mitarbeiter_uid = b.uid)
public.tbl_benutzer b on (ma.mitarbeiter_uid = b.uid)
JOIN
public.tbl_person p on (p.person_id = b.person_id)
public.tbl_person p on (p.person_id = b.person_id)
WHERE
lower (p.nachname) LIKE '%". $this->db->escape_like_str($filter)."%'
lower (p.nachname) LIKE '%". $this->db->escape_like_str($filter)."%'
OR
lower (p.vorname) LIKE '%". $this->db->escape_like_str($filter)."%'
OR
@@ -261,14 +384,14 @@ class Mitarbeiter_model extends DB_Model
* @param $lehrveranstaltung_id
* @return array with Mitarbeiter and their Lehreinheiten
*/
public function getMitarbeiterFromLV($lehrveranstaltung_id){
//TODO(manu) maybe filter that in pruefungslist.js ?
$qry = "SELECT DISTINCT
lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid
public function getMitarbeiterFromLV($lehrveranstaltung_id)
{
$qry = "SELECT DISTINCT
lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid
FROM
lehre.tbl_lehreinheitmitarbeiter, campus.vw_mitarbeiter, lehre.tbl_lehreinheit
lehre.tbl_lehreinheitmitarbeiter, campus.vw_mitarbeiter, lehre.tbl_lehreinheit
WHERE
lehrveranstaltung_id= ?
lehrveranstaltung_id= ?
AND
mitarbeiter_uid=uid
AND
@@ -278,4 +401,33 @@ class Mitarbeiter_model extends DB_Model
return $this->execQuery($qry, $parametersArray);
}
/**
* Get Lektoren by studiengang_kz
*
* @param $studiengang_kz
* @return array with Mitarbeiter
*/
public function getLektoren($studiengang_kz)
{
$qry = "
SELECT DISTINCT
campus.vw_mitarbeiter.uid,
campus.vw_mitarbeiter.vorname,
campus.vw_mitarbeiter.nachname,
studiengang_kz,
tbl_studiengang.typ,
tbl_studiengang.kurzbz AS stg_kurzbz
FROM
campus.vw_mitarbeiter
JOIN public.tbl_benutzerfunktion USING (uid)
JOIN public.tbl_studiengang USING(oe_kurzbz)
WHERE studiengang_kz = ?
AND lektor is true
ORDER BY campus.vw_mitarbeiter.nachname";
$parametersArray = array($studiengang_kz);
return $this->execQuery($qry, $parametersArray);
}
}
@@ -50,7 +50,6 @@ class Stundenplan_model extends DB_Model
*/
public function groupedCalendarEvents($ort_kurzbz,$start_date,$end_date){
$gruppierteEvents= $this->execReadOnlyQuery("
SELECT
@@ -186,6 +185,99 @@ class Stundenplan_model extends DB_Model
return $query_result;
}
/**
* groups rows of a subquery that fetches data from the lehre.vw_stundenplan table or lehre.vw_stundenplandev
* @param string $stundenplanViewQuery the subquery used to group the result regarding consecutive hours (Tab LV Termine)
*
* @return stdClass
*/
public function stundenplanGruppierungConsecutive($stundenplanViewQuery)
{
$query_result = $this->execReadOnlyQuery("
SELECT
distinct lehrveranstaltung_id,
datum,
MIN(beginn) as beginn,
MAX(ende) as ende,
type,
topic,
gruppe,
ort_kurzbz,
lehreinheit_id,
lehrfach_bez,
lektor,
lektorname,
gruppen_kuerzel,
farbe
FROM
(
SELECT
'lehreinheit' as type, beginn, ende, datum,
CONCAT(lehrfach,'-',lehrform) as topic,
array_agg(DISTINCT lektor) as lektor,
array_agg(DISTINCT lektorname) as lektorname,
array_agg(DISTINCT (gruppe,verband,semester,studiengang_kz,gruppen_kuerzel)) as gruppe,
array_agg(DISTINCT (gruppen_kuerzel)) as gruppen_kuerzel,
string_agg(DISTINCT ort_kurzbz, '/') as ort_kurzbz,
array_agg(DISTINCT lehreinheit_id) as lehreinheit_id,
titel, lehrfach, lehrform, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id
FROM
(
SELECT unr,datum,beginn, ende,
CASE
WHEN sp.mitarbeiter_kurzbz IS NOT NULL THEN sp.mitarbeiter_kurzbz
ELSE lektor
END as lektor,
CASE
WHEN gruppe_kurzbz IS NOT NULL THEN gruppe_kurzbz
ELSE (SELECT UPPER(typ || kurzbz)
FROM public.tbl_studiengang
WHERE studiengang_kz=sp.studiengang_kz) || COALESCE(sp.semester,'0') || COALESCE(sp.verband,'') || COALESCE(sp.gruppe,'')
END as gruppen_kuerzel,
(SELECT bezeichnung
FROM public.tbl_organisationseinheit
WHERE oe_kurzbz IN(
SELECT oe_kurzbz
FROM lehre.tbl_lehrveranstaltung
WHERE lehrveranstaltung_id = sp.lehrveranstaltung_id
)) as organisationseinheit,
ort_kurzbz, studiengang_kz, titel,lehreinheit_id,lehrfach_id,sp.anmerkung,fix,lehrveranstaltung_id,
stg_kurzbzlang,stg_bezeichnung,stg_typ,fachbereich_kurzbz,lehrfach,lehrfach_bez,farbe,lehrform,
anmerkung_lehreinheit,gruppe, verband, semester,stg_kurzbz,
CONCAT(p.nachname, ' ', p.vorname) as lektorname
FROM (".$stundenplanViewQuery.") sp
JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = sp.stunde
LEFT JOIN public.tbl_benutzer bn ON bn.uid = sp.uid
LEFT JOIN public.tbl_person p ON p.person_id = bn.person_id
) as subquery
GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit,
farbe, lehrveranstaltung_id
ORDER BY datum, beginn) t
GROUP BY
lehrveranstaltung_id,
type,
datum,
topic,
lektor,
lehrfach_bez,
gruppe,
ort_kurzbz,
lehreinheit_id,
lektorname,
gruppen_kuerzel,
farbe
ORDER BY
datum, beginn
"
);
return $query_result;
}
/**
* queries Stundenplan but for a whole lva, irrespective of who is requesting it
*
@@ -300,10 +392,13 @@ class Stundenplan_model extends DB_Model
/**
* NO STANDALONE FUNCTION - Generates a SQL query string to fetch 'stundenplan' events for a specific student within the current semester.
*
* @param isLvList if condition needed for Tab LV Termine is given
* @param db_stpl_table enables switch to db 'stundenplandev'
*
* @return mixed
*/
public function getStundenplanQuery($start_date, $end_date,$semester,$gruppen,$studentlehrverbaende){
public function getStundenplanQuery($start_date, $end_date, $semester, $gruppen, $studentlehrverbaende, $isLvList=false, $db_stpl_table='stundenplan'){
// helper function to check if either $gruppen or $studentlehrverbaende are empty for each semester
$emptyCheck = function($toBeCheckedArray) use ($semester){
$result = true;
@@ -325,7 +420,7 @@ class Stundenplan_model extends DB_Model
$query =
"select sp.*
from lehre.vw_stundenplan sp
from lehre.vw_".$db_stpl_table." sp
WHERE
sp.datum >= ".$this->escape($start_date)."
AND sp.datum <= ".$this->escape($end_date);
@@ -335,10 +430,10 @@ class Stundenplan_model extends DB_Model
{
$query .= " AND ( ";
}
foreach($semester as $sem => $semester_date_range)
{
foreach($semester_date_range as $sem_date => $sem_date_range)
{
// if there are not groups for the semester skip the iteration step
@@ -358,7 +453,13 @@ class Stundenplan_model extends DB_Model
{
$query = substr($query, 0, -2);
}
//Condition for showLVList FHC4
if(!$isLvList)
$stringGroupLv = "AND gruppe_kurzbz is null";
else
$stringGroupLv ="";
foreach($semester as $sem=>$semester_date_range)
{
foreach($semester_date_range as $sem_date => $sem_date_range)
@@ -373,10 +474,10 @@ class Stundenplan_model extends DB_Model
// Eintraege fuer den ganzen Verband
$query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")";
// Eintraege fuer das ganze Semester
$query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).") AND gruppe_kurzbz is null)";
$query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)
." AND ".$this->escape($sem_date_range->ende).")". $stringGroupLv. ")";
$query .="OR";
}
}
}
@@ -434,5 +535,4 @@ class Stundenplan_model extends DB_Model
return $this->execQuery($query, [$uid, $uid]);
}
}
+133 -2
View File
@@ -85,7 +85,7 @@ class Message_model extends DB_Model
*/
public function getMessagesOfPerson($person_id, $status = null)
{
$sql = 'SELECT m.message_id,
$sql = "SELECT m.message_id,
m.person_id,
m.subject,
m.body,
@@ -122,7 +122,7 @@ class Message_model extends DB_Model
) s ON (m.message_id = s.message_id AND re.person_id = s.person_id)
WHERE se.person_id = ?
OR re.person_id = ?
';
";
if (is_numeric($status))
{
@@ -230,4 +230,135 @@ class Message_model extends DB_Model
return $this->execQuery($query, $params);
}
/**
* Gets messages for a person for tableMessages.
* @param $person_id
* paginationInitialPage: 1,
* @param $offset number to skip, calculated by tabulatorParam paginationInitialPage and paginationSize, refers to specified numer of skipped items
* and page
* @param $limit refers to tabulatorParam paginationSize
* @return array|null
*/
public function getMessagesForTable($person_id, $offset, $limit)
{
$sql_base = "
SELECT
m.message_id AS message_id,
m.subject AS subject,
m.body AS body,
m.insertamum AS insertamum,
m.relationmessage_id AS relationmessage_id,
(SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = m.person_id) as sender,
(SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = r.person_id) as recipient,
m.person_id as sender_id,
r.person_id as recipient_id,
MAX(ss.status) as status,
MAX(ss.insertamum) as statusdatum
FROM public.tbl_msg_message m
JOIN public.tbl_msg_recipient r USING(message_id)
JOIN public.tbl_msg_status ss ON(r.message_id = ss.message_id AND ss.person_id = r.person_id)
WHERE m.person_id = ?
GROUP BY m.message_id, m.subject, m.body, m.insertamum, m.relationmessage_id, sender, recipient, sender_id, recipient_id
UNION ALL
SELECT
m.message_id AS message_id,
m.subject AS subject,
m.body AS body,
m.insertamum AS insertamum,
m.relationmessage_id AS relationmessage_id,
(SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = m.person_id) as sender,
(SELECT COALESCE(titelpre,'') || ' ' || COALESCE(vorname,'') || ' ' || COALESCE(nachname,'') || ' ' || COALESCE(titelpost,'') FROM public.tbl_person WHERE person_id = r.person_id) as recipient,
m.person_id as sender_id,
r.person_id as recipient_id,
MAX(ss.status) as status,
MAX(ss.insertamum) as statusdatum
FROM public.tbl_msg_recipient r
JOIN public.tbl_msg_status ss USING(message_id, person_id)
JOIN public.tbl_msg_message m USING(message_id)
WHERE r.person_id = ?
GROUP BY m.message_id, m.subject, m.body, m.insertamum, m.relationmessage_id, sender, recipient, sender_id, recipient_id
";
$sql = "
SELECT COUNT(*) AS count FROM (
" . $sql_base . "
) a
";
$parametersArray = array($person_id, $person_id);
$count = $this->execQuery($sql, $parametersArray);
if (isError($count))
return $count;
$count = ceil(current(getData($count))->count/$limit);
$sql = "
SELECT * FROM (
" . $sql_base . "
) a
ORDER BY insertamum DESC
LIMIT ?
OFFSET ?
";
$parametersArray = array($person_id, $person_id, $limit, $offset);
$data = $this->execQuery($sql, $parametersArray);
if (isError($data))
return $data;
$data = getData($data);
return success(['data' => $data, 'count' => $count]);
}
/**
* Deletes entry in dependency table tbl_msg_recipient
*
* @param $message_id
* @return boolean success
*/
public function deleteMessageRecipient($message_id)
{
$sql = "
DELETE FROM public.tbl_msg_recipient
WHERE message_id = ?;
";
return $this->execQuery($sql, array($message_id));
}
/**
* Deletes entry in dependency table tbl_msg_status
*
* @param $message_id
* @return boolean success
*/
public function deleteMessageStatus($message_id)
{
$sql = "
DELETE FROM public.tbl_msg_status
WHERE message_id = ?;
";
return $this->execQuery($sql, array($message_id));
}
/**
* Deletes entry in dependency table tbl_msg_message
*
* @param $message_id
* @return boolean success
*/
public function deleteMessage($message_id)
{
$sql = "
DELETE FROM public.tbl_msg_message
WHERE message_id = ?;
";
return $this->execQuery($sql, array($message_id));
}
}
+127 -1
View File
@@ -13,7 +13,7 @@ class Vorlage_model extends DB_Model
}
/**
* Returns mume types
* Returns mime types
*/
public function getMimeTypes()
{
@@ -21,4 +21,130 @@ class Vorlage_model extends DB_Model
return $this->execQuery($query);
}
/**
* Returns all Vorlagen for archive
*/
public function getArchivVorlagen()
{
$query ="SELECT * FROM public.tbl_vorlage WHERE archivierbar=true ORDER BY bezeichnung";
return $this->execQuery($query);
}
/**
* Returns all Vorlagen
* that belongs to the organisation units of the user
* and the parents of those organisation units until the root of the
* @param Array Array of $oe_kurzbz
* @return object Array of Vorlagen
*/
public function getAllVorlagenByOe($oe_kurzbz)
{
// Loads library OrganisationseinheitLib
$this->load->library('OrganisationseinheitLib');
$vorlage = success(array()); // Default value
$table = '(
SELECT v.vorlage_kurzbz,
v.bezeichnung,
vs.version,
vs.oe_kurzbz,
vs.aktiv,
vs.subject,
vs.text,
v.mimetype
FROM tbl_vorlagestudiengang vs
JOIN tbl_vorlage v USING(vorlage_kurzbz)
) templates';
$alias = 'templates';
$fields = array(
'templates.vorlage_kurzbz AS id',
'templates.bezeichnung || \' (\' || UPPER(templates.oe_kurzbz) || \')\' AS description'
);
$where = 'templates.aktiv = TRUE
AND templates.subject IS NOT NULL
AND templates.text IS NOT NULL
AND templates.mimetype = \'text/html\'
GROUP BY 1, 2, 3';
$order_by = 'description ASC';
if (!is_array($oe_kurzbz))
{
$vorlage = $this->organisationseinheitlib->treeSearchEntire(
$table,
$alias,
$fields,
$where,
$order_by,
$oe_kurzbz
);
}
else // is an array
{
// Get the vorlage for each organisation unit
foreach($oe_kurzbz as $val)
{
$tmpVorlage = $this->organisationseinheitlib->treeSearchEntire(
$table,
$alias,
$fields,
$where,
$order_by,
$val
);
// Everything is ok and data are inside
if (hasData($tmpVorlage))
{
// If it's the first vorlage copy it
if (!hasData($vorlage))
{
for ($j = 0; $j < count(getData($tmpVorlage)); $j++)
{
if (getData($tmpVorlage)[$j]->id != '')
{
array_push($vorlage->retval, getData($tmpVorlage)[$j]);
}
}
}
else // checks for duplicates, if it's not already present push it into the array getData($vorlage)
{
for ($j = 0; $j < count(getData($tmpVorlage)); $j++)
{
$found = false;
$currentTmpVorlageData = null;
for ($i = 0; $i < count(getData($vorlage)); $i++)
{
$currentTmpVorlageData = getData($tmpVorlage)[$j];
if (getData($vorlage)[$i]->id == getData($tmpVorlage)[$j]->id
&& getData($vorlage)[$i]->_pk == getData($tmpVorlage)[$j]->_pk
&& getData($vorlage)[$i]->_ppk == getData($tmpVorlage)[$j]->_ppk
&& getData($vorlage)[$i]->_jtpk == getData($tmpVorlage)[$j]->_jtpk)
{
$found = true;
break;
}
}
if (!$found && $currentTmpVorlageData->id != '')
{
array_push($vorlage->retval, $currentTmpVorlageData);
}
}
}
}
}
}
return $vorlage;
}
}
@@ -11,4 +11,31 @@ class Ablauf_model extends DB_Model
$this->dbTable = 'testtool.tbl_ablauf';
$this->pk = 'ablauf_id';
}
/**
* Returns Weighting of the respective ranking test areas
* @param $studiengang_kz Studiengang_kz
* @param $semester Integer optional
* @return array of weightings per ranking test areas of given studiengang
*/
public function getAblaufGebieteAndGewichte($studiengang_kz, $semester = null)
{
$parametersArray = array($studiengang_kz);
$qry = "
SELECT
tbl_ablauf.gebiet_id, tbl_ablauf.gewicht
FROM
testtool.tbl_ablauf
WHERE
tbl_ablauf.studiengang_kz= ?";
if($semester)
{
$qry .= " AND semester = ?";
array_push($parametersArray, $semester);
}
return $this->execQuery($qry, $parametersArray);
}
}
+48
View File
@@ -0,0 +1,48 @@
<?php
$includesArray = array(
'title' => 'Nachrichten',
'axios027' => true,
'bootstrap5' => true,
'fontawesome6' => true,
'vue3' => true,
'primevue3' => true,
#'filtercomponent' => true,
'tabulator5' => true,
'tinymce5' => true,
'phrases' => array(
'global',
'ui',
),
'customCSSs' => [
'public/css/components/vue-datepicker.css',
'public/css/components/primevue.css',
],
'customJSs' => [
#'vendor/npm-asset/primevue/tree/tree.min.js',
#'vendor/npm-asset/primevue/toast/toast.min.js'
],
'customJSModules' => [
'public/js/apps/Nachrichten.js'
]
);
$this->load->view('templates/FHC-Header', $includesArray);
?>
<?php
$configArray = [
'domain' => !defined('DOMAIN') ? 'notDefined' : DOMAIN,
];
?>
<div id="main">
<router-view
cis-root="<?= CIS_ROOT; ?>"
:permissions="<?= htmlspecialchars(json_encode($permissions)); ?>"
:config="<?= htmlspecialchars(json_encode($configArray)); ?>"
>
</router-view>
</div>
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
+8 -2
View File
@@ -15,11 +15,14 @@
'notiz',
),
'customCSSs' => [
#datepicker fuer component functions
'public/css/components/vue-datepicker.css',
'public/css/components/primevue.css',
'public/css/Studentenverwaltung.css'
'public/css/Studentenverwaltung.css',
'public/css/components/function.css'
],
'customJSs' => [
'vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js'
#'vendor/npm-asset/primevue/tree/tree.min.js',
#'vendor/npm-asset/primevue/toast/toast.min.js'
],
@@ -37,7 +40,10 @@ $configArray = [
//replaced by possibility to hide each formular field via config stv.php
#'showZgvDoktor' => !defined('ZGV_DOKTOR_ANZEIGEN') ? false : ZGV_DOKTOR_ANZEIGEN,
#'showZgvErfuellt' => !defined('ZGV_ERFUELLT_ANZEIGEN') ? false : ZGV_ERFUELLT_ANZEIGEN
'showHintKommPrfg' => !defined('FAS_STUDSTATUS_SHOW_KOMM_PRFG_HINT') ? false : FAS_STUDSTATUS_SHOW_KOMM_PRFG_HINT
'showHintKommPrfg' => !defined('FAS_STUDSTATUS_SHOW_KOMM_PRFG_HINT') ? false : FAS_STUDSTATUS_SHOW_KOMM_PRFG_HINT,
'showAufnahmegruppen' => !defined('FAS_REIHUNGSTEST_AUFNAHMEGRUPPEN') ? false : FAS_REIHUNGSTEST_AUFNAHMEGRUPPEN,
'allowUebernahmePunkte' => !defined('FAS_REIHUNGSTEST_PUNKTEUEBERNAHME') ? true : FAS_REIHUNGSTEST_PUNKTEUEBERNAHME,
'useReihungstestPunkte' => !defined('FAS_REIHUNGSTEST_PUNKTE') ? true : FAS_REIHUNGSTEST_PUNKTE,
];
?>
+7
View File
@@ -98,3 +98,10 @@
padding-right: .375rem;
background-image: none;
}
.modal-msg {
max-width: 1378px;
}
.modal-msg .modal-content {
height: 95vh;
}
+20 -2
View File
@@ -4,6 +4,7 @@
@import './components/FilterComponent.css';
@import './components/Tabs.css';
@import './components/Notiz.css';
@import './components/Messages.css';
html {
font-size: .875em;
@@ -53,11 +54,12 @@ html {
}
/* Dropdown AbschlusspruefungList.js */
.tabulator-row {
.stv-details-abschlusspruefung .tabulator-row {
overflow: visible !important;
}
.tabulator-cell {
/* to avoid interference with Notiz.css and overflow for textfield */
.stv-details-abschlusspruefung .tabulator-cell {
overflow: visible !important;
}
@@ -77,6 +79,10 @@ html {
overflow: visible !important;
}
.highlight-row {
background-color: #e5aeae !important;
}
@media (min-width: 768px) {
#sidebarMenu {
visibility: visible!important;
@@ -140,4 +146,16 @@ html {
}
.override_filtercmpt_actions_style div.d-flex.align-items-baseline {
align-items: end !important;
}
.stv-details-details-foto img {
max-width: 150px;
}
.msg_preview {
margin-bottom: -1px;
}
.tiny-90 div.tox.tox-tinymce {
height: 90% !important;
}
+4
View File
@@ -0,0 +1,4 @@
.twoColumns {
height: 400px;
overflow-y: auto;
}
+21 -1
View File
@@ -3,4 +3,24 @@
}
.notizText {
color: darkblue;
}
}
/* Enforce content clipping in the scrollable section */
.tabulator .tabulator-tableHolder {
overflow-x: hidden;
position: relative;
}
.tabulator .tabulator-table {
overflow-x: hidden;
table-layout: fixed;
width: 100%;
}
.tabulator .tabulator-cell {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
+3
View File
@@ -0,0 +1,3 @@
.item-inactive {
text-decoration: line-through;
}
+11
View File
@@ -5249,6 +5249,8 @@
}
.p-toast .p-toast-message .p-toast-message-content .p-toast-message-text {
margin: 0 0 0 1rem;
flex: 1 0 0%;
word-break: break-word;
}
.p-toast .p-toast-message .p-toast-message-content .p-toast-message-icon {
font-size: 2rem;
@@ -5314,6 +5316,15 @@
.p-toast .p-toast-message.p-toast-message-error .p-toast-icon-close {
color: #721c24;
}
.p-toast.p-component.p-toast-top-right.fhc-alert {
max-height: calc(100vh - 20px - 1rem);
overflow: auto;
}
.p-toast-message-text .alertCollapseText {
overflow: auto;
max-height: 30rem;
}
.p-galleria .p-galleria-close {
margin: 0.5rem;
+9 -1
View File
@@ -43,4 +43,12 @@
--dp-border-color-hover: var(--bs-success);
}
.form-control.is-invalid ~ .dp__clear_icon,
.was-validated .form-control:invalid ~ .dp__clear_icon { margin-right: calc(1.5em + .75rem - 12px) }
.was-validated .form-control:invalid ~ .dp__clear_icon {
margin-right: calc(1.5em + .75rem - 12px);
}
.p-component .dp__input_icons {
box-sizing: content-box !important;
}
.input-group .dp__input_icons {
z-index: 3;
}
+37
View File
@@ -0,0 +1,37 @@
/**
* 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 {
getHeader(person_id){
return {
method: 'get',
url: 'api/frontend/v1/vertraege/vertraege/getHeader/' + person_id,
};
},
getPersonAbteilung(mitarbeiter_uid){
return {
method: 'get',
url: 'api/frontend/v1/vertraege/vertraege/getPersonAbteilung/' + mitarbeiter_uid,
};
},
getLeitungOrg(oekurzbz){
return {
method: 'get',
url: 'api/frontend/v1/vertraege/vertraege/getLeitungOrg/' + oekurzbz,
};
},
}
+89
View File
@@ -0,0 +1,89 @@
/**
* 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 {
getOrgHeads() {
var url = 'api/frontend/v1/funktionen/Funktionen/getOrgHeads';
return {
method: 'get',
url,
};
},
getOrgetsForCompany(unternehmen) {
var url = 'api/frontend/v1/funktionen/Funktionen/getOrgetsForCompany'
+ '/' + unternehmen;
return {
method: 'get',
url,
};
},
getAllOrgUnits(filterStudent) {
var url = 'api/frontend/v1/funktionen/Funktionen/getAllOrgUnits';
return {
method: 'get',
url,
};
},
getAllUserFunctions(mitarbeiter_uid) {
var url = 'api/frontend/v1/funktionen/Funktionen/getAllUserFunctions'
+ '/' + mitarbeiter_uid;
return {
method: 'get',
url,
};
},
getAllFunctions() {
var url = 'api/frontend/v1/funktionen/Funktionen/getAllFunctions';
return {
method: 'get',
url,
};
},
addFunction(params) {
return {
method: 'post',
url: 'api/frontend/v1/funktionen/Funktionen/insertFunction/',
params
};
},
loadFunction(benutzerfunktion_id) {
var url = 'api/frontend/v1/funktionen/Funktionen/loadFunction'
+ '/' + benutzerfunktion_id;
return {
method: 'get',
url,
};
},
updateFunction(params) {
return {
method: 'post',
url: 'api/frontend/v1/funktionen/Funktionen/updateFunction/',
params
};
},
deleteFunction(benutzerfunktion_id) {
return {
method: 'post',
url: 'api/frontend/v1/funktionen/Funktionen/deleteFunction/' + benutzerfunktion_id
};
},
getOes(head, searchString) {
return {
method: 'get',
url: 'api/frontend/v1/funktionen/Funktionen/searchOes/' + head + '/' + searchString
};
},
};
+110
View File
@@ -0,0 +1,110 @@
/**
* 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 {
getMessages(params) {
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getMessages/'
+ params.id + '/'
+ params.type + '/'
+ params.size + '/'
+ params.page
};
},
getVorlagen(){
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getVorlagen/'
};
},
getMsgVarsLoggedInUser(){
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/'
};
},
getMessageVarsPerson(userParams){
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/getMessageVarsPerson/' + userParams.id + '/' + userParams.type_id
};
},
getMsgVarsPrestudent(userParams){
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + userParams.id + '/' + userParams.type_id
};
},
getPersonId(params){
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/getPersonId/' + params.id + '/' + params.type_id
};
},
getUid(userParams){
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getUid/' + userParams.id + '/' + userParams.type_id
};
},
getVorlagentext(vorlage_kurzbz){
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getVorlagentext/' + vorlage_kurzbz
};
},
getNameOfDefaultRecipient(params){
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id
};
},
getPreviewText(userParams, params){
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/getPreviewText/' + userParams.id + '/' + userParams.type_id,
params
};
},
getReplyData(messageId){
return {
method: 'get',
url: 'api/frontend/v1/messages/messages/getReplyData/' + messageId
};
},
sendMessageFromModalContext(id, params) {
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/sendMessage/' + id,
params
};
},
sendMessage(id, params) {
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/sendMessage/' + id,
params
};
},
deleteMessage(messageId){
return {
method: 'post',
url: 'api/frontend/v1/messages/messages/deleteMessage/' + messageId
};
}
}
+3 -1
View File
@@ -29,6 +29,7 @@ import exam from './stv/exam.js';
import abschlusspruefung from './stv/abschlusspruefung.js';
import grades from './stv/grades.js';
import mobility from './stv/mobility.js';
import admissionDates from './stv/admissionDates.js';
export default {
app,
@@ -44,5 +45,6 @@ export default {
exam,
abschlusspruefung,
grades,
mobility
mobility,
admissionDates
};
+13 -1
View File
@@ -105,7 +105,19 @@ export default {
return {
method: 'post',
url: 'api/frontend/v1/stv/abschlusspruefung/checkForExistingExams/',
params: { uid }
params: { uids }
};
},
getAllMitarbeiter(){
return {
method: 'get',
url: 'api/frontend/v1/stv/abschlusspruefung/getAllMitarbeiter/'
};
},
getAllPersons(){
return {
method: 'get',
url: 'api/frontend/v1/stv/abschlusspruefung/getAllPersons/'
};
}
};
@@ -0,0 +1,99 @@
/**
* 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 {
getAufnahmetermine(person_id) {
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/getAufnahmetermine/' + person_id,
};
},
getListPlacementTests(prestudent_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/getListPlacementTests/' + prestudent_id,
};
},
getListStudyPlans(person_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/getListStudyPlans/' + person_id,
};
},
addNewPlacementTest(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/aufnahmetermine/insertAufnahmetermin/',
params
};
},
loadPlacementTest(rt_person_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/loadAufnahmetermin/' + rt_person_id,
};
},
updatePlacementTest(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/aufnahmetermine/updateAufnahmetermin/',
params
};
},
deletePlacementTest(rt_person_id){
return {
method: 'post',
url: 'api/frontend/v1/stv/aufnahmetermine/deleteAufnahmetermin/' + rt_person_id
};
},
loadDataRtPrestudent(prestudent_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/loadDataRtPrestudent/' + prestudent_id,
};
},
saveDataRtPrestudent(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/aufnahmetermine/insertOrUpdateDataRtPrestudent/',
params
};
},
loadAufnahmegruppen(params){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/loadAufnahmegruppen/',
params
};
},
getResultReihungstest(params){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/getResultReihungstest/',
params
};
},
loadFutureReihungstests(params){
return {
method: 'get',
url: 'api/frontend/v1/stv/aufnahmetermine/getZukuenftigeReihungstestStg/',
params
};
},
}
+35
View File
@@ -0,0 +1,35 @@
/**
* 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 {
getCourselist(params) {
return {
method: 'get',
url: 'api/frontend/v1/stv/LvTermine/getStundenplan/' + params.student_uid + '/'
+ params.start_date + '/'
+ params.end_date + '/'
+ params.group_consecutiveHours + '/'
+ params.dbStundenplanTable
};
},
getStudiensemester(){
return {
method: 'get',
url: 'api/frontend/v1/stv/LvTermine/getStudiensemester/'
};
},
}
+76
View File
@@ -0,0 +1,76 @@
/**
* 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 {
getDocumentsUnaccepted(params) {
return {
method: 'get',
url: 'api/frontend/v1/stv/dokumente/getDocumentsUnaccepted/' + params.id + '/' + params.studiengang_kz
};
},
getDocumentsAccepted(params) {
return {
method: 'get',
url: 'api/frontend/v1/stv/dokumente/getDocumentsAccepted/' + params.id + '/' + params.studiengang_kz
};
},
deleteZuordnung(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/dokumente/deleteZuordnung/' + params.prestudent_id + '/' + params.dokument_kurzbz
};
},
createZuordnung(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/dokumente/createZuordnung/' + params.prestudent_id + '/' + params.dokument_kurzbz
};
},
loadAkte(akte_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/dokumente/loadAkte/' + akte_id
};
},
getDoktypen(){
return {
method: 'get',
url: 'api/frontend/v1/stv/dokumente/getDoktypen/'
};
},
updateFile(akte_id, params){
return {
method: 'post',
url: 'api/frontend/v1/stv/dokumente/updateAkte/' + akte_id,
params
};
},
deleteFile(akte_id){
console.log("in deleteFile " + akte_id);
return {
method: 'post',
url: 'api/frontend/v1/stv/dokumente/deleteAkte/' + akte_id,
};
},
uploadFile(prestudent_id, params){
return {
method: 'post',
url: 'api/frontend/v1/stv/dokumente/uploadDokument/' + prestudent_id,
params
};
},
}
+75
View File
@@ -0,0 +1,75 @@
/**
* 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 {
getAnrechnungen(id) {
return {
method: 'get',
url: 'api/frontend/v1/stv/anrechnungen/getAnrechnungen/' + id
};
},
getLehrveranstaltungen(prestudent_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/anrechnungen/getLehrveranstaltungen/' + prestudent_id
};
},
getBegruendungen(){
return {
method: 'get',
url: 'api/frontend/v1/stv/anrechnungen/getBegruendungen/'
};
},
getLvsKompatibel(lv_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/anrechnungen/getLvsKompatibel/' + lv_id
};
},
getLektoren(studiengang_kz){
return {
method: 'get',
url: 'api/frontend/v1/stv/anrechnungen/getLektoren/' + studiengang_kz
};
},
addNewAnrechnung(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/anrechnungen/insertAnrechnung/',
params
};
},
loadAnrechnung(anrechnung_id){
return {
method: 'get',
url: 'api/frontend/v1/stv/anrechnungen/loadAnrechnung/' + anrechnung_id
};
},
editAnrechnung(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/anrechnungen/updateAnrechnung/',
params
};
},
deleteAnrechnung(anrechnung_id){
return {
method: 'post',
url: 'api/frontend/v1/stv/anrechnungen/deleteAnrechnung/' + anrechnung_id
};
},
}
+33
View File
@@ -0,0 +1,33 @@
/**
* 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 {
getGruppen(id) {
return {
method: 'get',
url: 'api/frontend/v1/stv/Gruppen/getGruppen/' + id
};
},
deleteGroup(params) {
return {
method: 'post',
url: 'api/frontend/v1/stv/Gruppen/deleteGruppe/',
params
};
}
}
+81
View File
@@ -0,0 +1,81 @@
/**
* 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 {
getStudies(uid) {
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/getStudien/' + uid
};
},
getTypenMobility(){
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/getTypenMobility/'
};
},
getStudiensemester(){
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/getStudiensemester/'
};
},
getStudyprograms(){
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/getStudienprogramme/'
};
},
getListPartner(){
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/getPartnerfirmen/'
};
},
getStatiPrestudent(){
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/getStatiPrestudent/'
};
},
loadStudy(id){
return {
method: 'get',
url: 'api/frontend/v1/stv/GemeinsameStudien/loadStudie/' + id
};
},
insertStudy(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/GemeinsameStudien/insertStudie/',
params
};
},
updateStudy(params){
return {
method: 'post',
url: 'api/frontend/v1/stv/GemeinsameStudien/updateStudie/',
params
};
},
deleteStudy(id){
return {
method: 'post',
url: 'api/frontend/v1/stv/GemeinsameStudien/deleteStudie/' + id
};
},
}
@@ -67,5 +67,11 @@ export default {
method: 'get',
url: 'api/frontend/v1/stv/address/getNations/'
};
},
getAllFirmen(){
return {
method: 'get',
url: 'api/frontend/v1/stv/kontakt/getAllFirmen/'
}
}
};
+4 -3
View File
@@ -51,7 +51,8 @@ export default {
deleteMobility(bisio_id) {
return {
method: 'post',
url: 'api/frontend/v1/stv/mobility/deleteMobility/' + bisio_id
url: 'api/frontend/v1/stv/mobility/deleteMobility/',
params: { bisio_id }
};
},
getLVList(studiengang_kz) {
@@ -100,7 +101,7 @@ export default {
deleteMobilityPurpose(params) {
return {
method: 'post',
url: 'api/frontend/v1/stv/mobility/deleteMobilityPurpose/' + params.bisio_id,
url: 'api/frontend/v1/stv/mobility/deleteMobilityPurpose/',
params
};
},
@@ -108,7 +109,7 @@ export default {
return {
method: 'post',
url: 'api/frontend/v1/stv/mobility/addMobilityPurpose/' + params.bisio_id,
params
params: params
};
},
deleteMobilitySupport(params) {
+32
View File
@@ -0,0 +1,32 @@
/**
* 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 {
getVorlagen() {
return {
method: 'get',
url: 'api/frontend/v1/vorlagen/vorlagen/getVorlagen/'
};
},
getVorlagenByLoggedInUser() {
return {
method: 'get',
url: 'api/frontend/v1/vorlagen/vorlagen/getVorlagenByLoggedInUser/'
};
},
};
+5
View File
@@ -33,6 +33,8 @@ import ort from "./ort.js";
import cms from "./cms.js";
import lehre from "./lehre.js";
import addons from "./addons.js";
import messages from "./messages.js";
import vorlagen from "./vorlagen.js";
import studiengang from "./studiengang.js";
import menu from "./menu.js";
import dashboard from "./dashboard.js";
@@ -57,6 +59,9 @@ export default {
ort,
cms,
lehre,
addons,
messages,
vorlagen,
addons,
studiengang,
menu,
+5
View File
@@ -0,0 +1,5 @@
import person from "./messages/person.js";
export default {
person
}
+47
View File
@@ -0,0 +1,47 @@
export default {
getMessages(url, config, params) {
return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessages/' + params.id + '/' + params.type + '/' + params.size + '/' + params.page);
},
getVorlagen(){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getVorlagen/');
},
getMsgVarsLoggedInUser(){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsLoggedInUser/');
},
getMessageVarsPerson(params){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getMessageVarsPerson/' + params.id + '/' + params.type_id);
},
getMsgVarsPrestudent(params){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getMsgVarsPrestudent/' + params.id + '/' + params.type_id);
},
getPersonId(params){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getPersonId/'+ params.id + '/' + params.type_id);
},
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);
},
getNameOfDefaultRecipient(params){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getNameOfDefaultRecipient/' + params.id + '/' + params.type_id);
},
getPreviewText(params, data){
return this.$fhcApi.post('api/frontend/v1/messages/messages/getPreviewText/' + params.id + '/' + params.type_id,
data);
},
getReplyData(messageId){
return this.$fhcApi.get('api/frontend/v1/messages/messages/getReplyData/' + messageId);
},
sendMessageFromModalContext(form, id, data) {
return this.$fhcApi.post(form,'api/frontend/v1/messages/messages/sendMessage/' + id,
data);
},
sendMessage(id, data) {
return this.$fhcApi.post('api/frontend/v1/messages/messages/sendMessage/' + id,
data);
},
deleteMessage(messageId){
return this.$fhcApi.post('api/frontend/v1/messages/messages/deleteMessage/' + messageId);
}
}
+12
View File
@@ -2,6 +2,7 @@ import verband from './stv/verband.js';
import students from './stv/students.js';
import filter from './stv/filter.js';
import konto from './stv/konto.js';
import group from './stv/group.js';
import kontakt from './stv/kontakt.js';
import prestudent from './stv/prestudent.js';
import status from './stv/status.js';
@@ -10,12 +11,18 @@ import exam from './stv/exam.js';
import abschlusspruefung from './stv/abschlusspruefung.js';
import grades from './stv/grades.js';
import mobility from './stv/mobility.js';
import archiv from './stv/archiv.js';
import documents from './stv/documents.js';
import exemptions from './stv/exemptions.js';
import jointstudies from "./stv/jointstudies.js";
import courselist from './stv/courselist.js';
export default {
verband,
students,
filter,
konto,
group,
kontakt,
prestudent,
status,
@@ -24,6 +31,11 @@ export default {
abschlusspruefung,
grades,
mobility,
archiv,
documents,
exemptions,
jointstudies,
courselist,
configStudent() {
return this.$fhcApi.get('api/frontend/v1/stv/config/student');
},
+36
View File
@@ -0,0 +1,36 @@
export default {
tabulatorConfig(config, self) {
config.ajaxURL = 'api/frontend/v1/stv/archiv/get';
config.ajaxParams = () => {
const params = {
person_id: self.modelValue.person_id || self.modelValue.map(e => e.person_id)
};
return params;
};
config.ajaxRequestFunc = (url, config, params) => this.$fhcApi.post(url, params, config);
config.ajaxResponse = (url, params, response) => response.data;
return config;
},
getArchivVorlagen() {
return this.$fhcApi.post('api/frontend/v1/stv/archiv/getArchivVorlagen');
},
archive(data) {
return this.$fhcApi.post(
'api/frontend/v1/documents/archive',
data
);
},
archiveSigned(data) {
return this.$fhcApi.post(
'api/frontend/v1/documents/archiveSigned',
data
);
},
update(data) {
return this.$fhcApi.post('api/frontend/v1/stv/archiv/update', data);
},
delete({akte_id, studiengang_kz}) {
return this.$fhcApi.post('api/frontend/v1/stv/archiv/delete', {akte_id, studiengang_kz});
}
};
+15
View File
@@ -0,0 +1,15 @@
export default {
getCourselist(url, config, params) {
//corresponding logic controller Stundenplan.php
return this.$fhcApi.get('api/frontend/v1/stv/LvTermine/getStundenplan/'
+ params.student_uid + '/'
+ params.start_date + '/'
+ params.end_date + '/'
+ params.group_consecutiveHours + '/'
+ params.dbStundenplanTable
);
},
getStudiensemester(){
return this.$fhcApi.get('api/frontend/v1/stv/LvTermine/getStudiensemester/');
},
}
+33
View File
@@ -0,0 +1,33 @@
export default {
getDocumentsUnaccepted(url, config, params) {
return this.$fhcApi.get('api/frontend/v1/stv/dokumente/getDocumentsUnaccepted/' + params.id + '/' + params.studiengang_kz);
},
getDocumentsAccepted(url, config, params) {
return this.$fhcApi.get('api/frontend/v1/stv/dokumente/getDocumentsAccepted/' + params.id + '/' + params.studiengang_kz);
},
deleteZuordnung(params){
return this.$fhcApi.post('api/frontend/v1/stv/dokumente/deleteZuordnung/' + params.prestudent_id + '/' + params.dokument_kurzbz);
},
createZuordnung(params){
return this.$fhcApi.post('api/frontend/v1/stv/dokumente/createZuordnung/'
+ params.prestudent_id + '/'
+ params.dokument_kurzbz);
},
loadAkte(akte_id){
return this.$fhcApi.get('api/frontend/v1/stv/dokumente/loadAkte/' + akte_id);
},
getDoktypen(){
return this.$fhcApi.get('api/frontend/v1/stv/dokumente/getDoktypen/');
},
updateFile(akte_id, data){
return this.$fhcApi.post('api/frontend/v1/stv/dokumente/updateAkte/' + akte_id,
data);
},
deleteFile(akte_id){
return this.$fhcApi.post('api/frontend/v1/stv/dokumente/deleteAkte/' + akte_id);
},
uploadFile(prestudent_id, data){
return this.$fhcApi.post('api/frontend/v1/stv/dokumente/uploadDokument/' + prestudent_id,
data);
},
}
+29
View File
@@ -0,0 +1,29 @@
export default {
getAnrechnungen(url, config, params) {
return this.$fhcApi.get('api/frontend/v1/stv/anrechnungen/getAnrechnungen/' + params.id);
},
getLehrveranstaltungen(prestudent_id){
return this.$fhcApi.get('api/frontend/v1/stv/anrechnungen/getLehrveranstaltungen/' + prestudent_id);
},
getBegruendungen(){
return this.$fhcApi.get('api/frontend/v1/stv/anrechnungen/getBegruendungen/');
},
getLvsKompatibel(lv_id){
return this.$fhcApi.get('api/frontend/v1/stv/anrechnungen/getLvsKompatibel/' + lv_id);
},
getLektoren(studiengang_kz){
return this.$fhcApi.get('api/frontend/v1/stv/anrechnungen/getLektoren/' + studiengang_kz);
},
addNewAnrechnung(form, data){
return this.$fhcApi.post(form, 'api/frontend/v1/stv/anrechnungen/insertAnrechnung/', data);
},
loadAnrechnung(anrechnung_id){
return this.$fhcApi.get('api/frontend/v1/stv/anrechnungen/loadAnrechnung/' + anrechnung_id);
},
editAnrechnung(form, data){
return this.$fhcApi.post(form, 'api/frontend/v1/stv/anrechnungen/updateAnrechnung/', data);
},
deleteAnrechnung(anrechnung_id){
return this.$fhcApi.post('api/frontend/v1/stv/anrechnungen/deleteAnrechnung/' + anrechnung_id);
},
}
+8
View File
@@ -0,0 +1,8 @@
export default {
getGruppen(url, config, params) {
return this.$fhcApi.get('api/frontend/v1/stv/Gruppen/getGruppen/' + params.id);
},
deleteGroup(params) {
return this.$fhcApi.post('api/frontend/v1/stv/Gruppen/deleteGruppe/', params);
}
}
+33
View File
@@ -0,0 +1,33 @@
export default {
getStudies(url, config, params) {
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/getStudien/' + params.id);
},
getTypenMobility(){
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/getTypenMobility/');
},
getStudiensemester(){
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/getStudiensemester/');
},
getStudyprograms(){
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/getStudienprogramme/');
},
getListPartner(){
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/getPartnerfirmen/');
},
getStatiPrestudent(){
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/getStatiPrestudent/');
},
loadStudy(id){
return this.$fhcApi.get('api/frontend/v1/stv/GemeinsameStudien/loadStudie/' + id);
},
insertStudy(form, data){
return this.$fhcApi.post(form,'api/frontend/v1/stv/GemeinsameStudien/insertStudie/', data);
},
updateStudy(form, data){
return this.$fhcApi.post(form,'api/frontend/v1/stv/GemeinsameStudien/updateStudie/', data);
},
deleteStudy(id){
return this.$fhcApi.post('api/frontend/v1/stv/GemeinsameStudien/deleteStudie/' + id);
},
}
+8
View File
@@ -0,0 +1,8 @@
export default {
getVorlagen() {
return this.$fhcApi.get('api/frontend/v1/vorlagen/vorlagen/getVorlagen/');
},
getVorlagenByLoggedInUser() {
return this.$fhcApi.get('api/frontend/v1/vorlagen/vorlagen/getVorlagenByLoggedInUser/');
}
}
+27
View File
@@ -0,0 +1,27 @@
//TODO Manu
//use this instead of Nachrichten.js
import NewMessage from "../../components/Messages/Details/NewMessage/NewDiv.js";
import Phrasen from "../../plugin/Phrasen.js";
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes: [
{ path: `/${ciPath}/NeueNachricht`, component: NewMessage },
{ path: `/${ciPath}/NeueNachricht/:id`, component: NewMessage },
{ path: `/${ciPath}/NeueNachricht/:id/:typeId`, component: NewMessage },
]
});
const app = Vue.createApp();
app
.use(router)
.use(primevue.config.default, {
zIndex: {
overlay: 1100
}
})
.use(Phrasen)
.mount('#main');
+26
View File
@@ -0,0 +1,26 @@
import NewMessage from "../components/Messages/Details/NewMessage/NewDiv.js";
import Phrasen from "../plugin/Phrasen.js";
const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
const router = VueRouter.createRouter({
history: VueRouter.createWebHistory(),
routes: [
{ path: `/${ciPath}/NeueNachricht/:id/:typeId`, component: NewMessage },
{ path: `/${ciPath}/NeueNachricht/:id/:typeId/:messageId`, component: NewMessage },
]
});
const app = Vue.createApp();
app
.use(router)
.use(primevue.config.default, {
zIndex: {
overlay: 1100
}
})
.use(Phrasen)
.mount('#main');
@@ -137,8 +137,6 @@ export default {
layout: 'fitColumns',
layoutColumnsOnNewData: false,
height: '550',
selectableRangeMode: 'click',
selectable: true,
persistenceID: 'core-betriebsmittel'
},
tabulatorEvents: [
@@ -311,6 +309,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('ui', 'betriebsmittel')"
@click:new="actionNewBetriebsmittel"
@@ -427,6 +426,7 @@ export default {
v-model="formData.ausgegebenam"
auto-apply
:enable-time-picker="false"
text-input
format="dd.MM.yyyy"
preview-format="dd.MM.yyyy"
:teleport="true"
@@ -442,6 +442,7 @@ export default {
v-model="formData.retouram"
auto-apply
:enable-time-picker="false"
text-input
format="dd.MM.yyyy"
preview-format="dd.MM.yyyy"
:teleport="true"
+11 -2
View File
@@ -23,9 +23,17 @@ export default {
},
noCloseBtn: Boolean,
dialogClass: [String,Array,Object],
headerClass: {
type: [String,Array,Object],
default: ''
},
bodyClass: {
type: [String,Array,Object],
default: 'px-4 py-5'
},
footerClass: {
type: [String,Array,Object],
default: ''
}
},
emits: [
@@ -117,15 +125,16 @@ export default {
template: `<div ref="modal" class="bootstrap-modal modal" tabindex="-1" @[\`hide.bs.modal\`]="$emit('hideBsModal')" @[\`hidden.bs.modal\`]="$emit('hiddenBsModal')" @[\`hidePrevented.bs.modal\`]="$emit('hidePreventedBsModal')" @[\`show.bs.modal\`]="$emit('showBsModal')" >
<div class="modal-dialog" :class="dialogClass">
<div class="modal-content">
<div v-if="$slots.title" class="modal-header">
<div v-if="$slots.title" class="modal-header" :class="headerClass">
<h5 class="modal-title"><slot name="title"/></h5>
<slot name="popoutButton"></slot>
<button v-if="!noCloseBtn" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
<slot name="modal-header-content"></slot>
</div>
<div class="modal-body" :class="bodyClass">
<slot></slot>
</div>
<div v-if="$slots.footer" class="modal-footer">
<div v-if="$slots.footer" class="modal-footer" :class="footerClass">
<slot name="footer"/>
</div>
</div>
@@ -0,0 +1,209 @@
import ApiDetailHeader from "../../api/factory/detailHeader.js";
export default {
name: 'DetailHeader',
inject: {
domain: {
from: 'configDomain',
default: 'technikum-wien.at'
},
},
props: {
headerData: {
type: Object,
required: false
},
person_id: {
type: Number,
required: false
},
typeHeader: {
type: String,
default: 'student',
validator(value) {
return [
'student',
'mitarbeiter',
].includes(value)
}
}
},
computed: {
appRoot() {
return FHC_JS_DATA_STORAGE_OBJECT.app_root;
},
validatedHeaderData() {
if (this.typeHeader === 'student') return this.headerData;
if (this.typeHeader === 'mitarbeiter') return this.person_id;
return null;
}
},
created(){
if(this.person_id) {
this.getHeader(this.person_id);
this.loadDepartmentData(this.mitarbeiter_uid)
.then(() => {
// Call getLeitungOrg only after departmentData is loaded
this.getLeitungOrg(this.departmentData.oe_kurzbz);
})
.catch((error) => {
console.error("Error loading department data:", error);
});
}
},
watch: {
person_id: {
handler(newVal) {
if (newVal) {
this.getHeader(this.person_id);
this.loadDepartmentData(this.person_id).
then(() => {
this.getLeitungOrg(this.departmentData.oe_kurzbz);
});
}
},
deep: true,
},
},
data(){
return{
headerDataMa: {},
departmentData: {},
leitungData: {},
};
},
methods: {
getHeader(person_id) {
return this.$api
.call(ApiDetailHeader.getHeader(person_id))
.then(result => {
this.headerDataMa = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
loadDepartmentData(mitarbeiter_uid) {
return this.$api
.call(ApiDetailHeader.getPersonAbteilung(mitarbeiter_uid))
.then(result => {
this.departmentData = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
getLeitungOrg(oekurzbz){
return this.$api
.call(ApiDetailHeader.getLeitungOrg(oekurzbz))
.then(result => {
this.leitungData = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
redirectToLeitung(){
this.$emit('redirectToLeitung', {
person_id: this.leitungData.person_id});
}
},
template: `
<div class="core-header d-flex justify-content-start align-items-center w-100 overflow-auto pb-3 gap-3" style="max-height:9rem; min-width: 37.5rem;">
<template v-if="typeHeader==='student'">
<div
v-for="person in headerData"
:key="person.person_id"
class="d-flex flex-column align-items-center h-100 position-relative d-inline-block"
>
<img
class="d-block h-100 rounded"
alt="Profilbild"
:src="'data:image/jpeg;base64,' + person.foto"
/>
<template v-if="person.foto_sperre">
<i
class=" fa fa-lock text-secondary bg-light rounded d-flex justify-content-center align-items-center position-absolute top-0 end-0"
style="z-index: 1; font-size: 1rem; width: 1.25rem; height: 1.25rem;"
></i>
</template>
<small class="text-muted">{{person.uid}}</small>
</div>
<div v-if="headerData.length == 1">
<h2 class="h4">
{{headerData[0].titelpre}}
{{headerData[0].vorname}}
{{headerData[0].nachname}}<span v-if="headerData[0].titelpost">, </span>
{{headerData[0].titelpost}}
</h2>
<h5 class="h6">
<strong class="text-muted">Person ID </strong>
{{headerData[0].person_id}}
<strong class="text-muted">| {{$p.t('lehre', 'studiengang')}} </strong>
{{headerData[0].stg_bezeichnung}} ({{headerData[0].studiengang}})
<strong v-if="headerData[0].semester" class="text-muted"> | {{$p.t('lehre', 'semester')}} </strong>
{{headerData[0].semester}}
<strong v-if="headerData[0].verband" class="text-muted"> | {{$p.t('lehre', 'verband')}}</strong>
{{headerData[0].verband}}
<strong v-if="headerData[0].gruppe" class="text-muted"> | {{$p.t('lehre', 'gruppe')}} </strong>
{{headerData[0].gruppe}}
</h5>
<h5 class="h6">
<strong class="text-muted">Email </strong>
<span>
<a :href="'mailto:'+headerData[0]?.mail_intern">{{headerData[0].mail_intern}}</a>
</span>
<strong v-if="headerData[0].statusofsemester" class="text-muted"> | Status </strong>
{{headerData[0].statusofsemester}}
<strong class="text-muted"> | {{$p.t('person', 'matrikelnummer')}} </strong>
{{headerData[0].matr_nr}}
</h5>
</div>
</template>
<template v-if="typeHeader==='mitarbeiter'">
<div class="row">
<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"
alt="Profilbild"
:src="'data:image/jpeg;base64,' + headerDataMa.foto"
/>
<template v-if="headerDataMa.foto_sperre">
<i
class=" fa fa-lock text-secondary bg-light rounded d-flex justify-content-center align-items-center position-absolute top-0 end-0"
style="z-index: 1; font-size: 1rem; width: 1.25rem; height: 1.25rem;"
></i>
</template>
</div>
<!--show Ma-Details-->
<div class="col-md-10">
<h5>{{headerDataMa.titelpre}} {{headerDataMa.vorname}} {{headerDataMa.nachname}}<span v-if="headerDataMa?.titelpost">, </span> {{headerDataMa.titelpost}}
</h5>
<strong class="text-muted">{{departmentData.organisationseinheittyp_kurzbz}}</strong>
{{departmentData.bezeichnung}}
<span v-if="leitungData.uid"> | </span>
<strong v-if="leitungData.uid" class="text-muted">Vorgesetzte*r </strong>
<a href="#" @click.prevent="redirectToLeitung">
{{leitungData.titelpre}} {{leitungData.vorname}} {{leitungData.nachname}}
</a>
<p>
<strong class="text-muted">Email </strong>
<span v-if="!headerDataMa?.alias">
<a :href="'mailto:'+headerDataMa?.uid+'@'+domain">{{headerDataMa.uid}}@{{domain}}</a>
</span>
<span v-if="headerDataMa?.alias">
<a :href="'mailto:'+headerDataMa?.alias+'@'+domain">{{headerDataMa.alias}}@{{domain}}</a>
</span>
<span v-if="headerDataMa?.telefonklappe" class="mb-2"> | <strong class="text-muted">DW </strong>{{headerDataMa?.telefonklappe}}</span>
</p>
</div>
</div>
</template>
</div>
`
}
@@ -0,0 +1,592 @@
import {CoreFilterCmpt} from "../filter/Filter.js";
import FormInput from "../Form/Input.js";
import FormForm from "../Form/Form.js";
import BsModal from "../Bootstrap/Modal.js";
import PvAutoComplete from "../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
import ApiCoreFunktion from '../../api/factory/functions.js';
export default {
name: 'FunctionComponent',
components: {
CoreFilterCmpt,
FormInput,
FormForm,
BsModal,
PvAutoComplete
},
props: {
modelValue: {
type: Object,
default: () => ({}),
required: false
},
config: {type: Object, default: () => ({}), required: false},
readonlyMode: {type: Boolean, required: false, default: false},
personID: {type: Number, required: true},
personUID: {type: String, required: true},
writePermission: {type: Boolean, required: false},
showDvCompany: {type: Boolean, required: false, default: true},
saveFunctionAsCopy: {type: Boolean, required: false, default: false},
stylePv21: {type: Boolean, required: false, default: false},
companyLinkFormatter: {type: Function || null, default: null}
},
data(){
return {
tabulatorOptions: {
ajaxURL: 'dummy',
ajaxRequestFunc: () => this.$api.call(
ApiCoreFunktion.getAllUserFunctions(this.personUID)
),
ajaxResponse: (url, params, response) => response.data,
columns: [
{
title: "dienstverhaeltnis_unternehmen",
field: "dienstverhaeltnis_unternehmen",
headerFilter: "list",
headerFilterParams: {valuesLookup: true, autocomplete: true, sort: "asc"},
},
{
title: "funktion_beschreibung", field: "funktion_beschreibung", headerFilter: "list",
headerFilterParams: {valuesLookup: true, autocomplete: true, sort: "asc"},
},
{
title: "funktion_oebezeichnung", field: "funktion_oebezeichnung", headerFilter: "list",
headerFilterParams: {valuesLookup: true, autocomplete: true, sort: "asc"}
},
{title: "wochenstunden", field: "wochenstunden", headerFilter: true},
{
title: "Von",
field: "datum_von",
headerFilter: true,
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",
});
},
},
{
title: "Bis",
field: "datum_bis",
headerFilter: true,
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",
});
},
},
{title: "bezeichnung", field: "bezeichnung", headerFilter: true},
{title: "aktiv", field: "aktiv", visible: false},
{title: "benutzerfunktion_id", field: "benutzerfunktion_id", visible: false},
{title: "uid", field: "uid", visible: false},
{
//title: 'Aktionen', field: 'actions',
minWidth: 150, // Ensures Action-buttons will be always fully displayed
headerSort:false,
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
container.className = "d-flex gap-2";
if( cell.getRow().getData().dienstverhaeltnis_unternehmen === null ) {
let button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
if(this.stylePv21)
button.innerHTML = '<i class="fa fa-pen"></i>';
else
button.innerHTML = '<i class="fa fa-edit"></i>';
button.title = this.$p.t('ui', 'bearbeiten');
button.addEventListener('click', (event) =>
this.actionEditFunction(cell.getData().benutzerfunktion_id)
);
if(this.readonlyMode === true) button.disabled = true;
container.append(button);
}
if( cell.getRow().getData().dienstverhaeltnis_unternehmen === null ) {
let 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.actionDeleteFunction(cell.getData().benutzerfunktion_id)
);
if(this.readonlyMode === true) button.disabled = true;
container.append(button);
}
if (cell.getRow().getData().dienstverhaeltnis_unternehmen === null && this.saveFunctionAsCopy) {
let button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-copy"></i>';
button.title = this.$p.t('ui', 'saveAsCopy');
button.addEventListener('click', () =>
this.actionCopyFunction(cell.getData().benutzerfunktion_id)
);
if(this.readonlyMode === true) button.disabled = true;
container.append(button);
}
return container;
},
frozen: true
}
],
layout: 'fitDataFill',
layoutColumnsOnNewData: false,
height: '300',
persistenceID: 'core-functions',
},
tabulatorEvents: [
{
event: 'tableBuilt',
handler: async () => {
await this.$p.loadCategory(['global', 'lehre', 'person', 'ui']);
let cm = this.$refs.table.tabulator.columnManager;
//Field Company: if visible show link to dv
const column = cm.getColumnByField('dienstverhaeltnis_unternehmen');
const companyDv = {
title: this.$p.t('person', 'dv_unternehmen'),
width: 140,
visible: this.showDvCompany,
formatter: this.companyLinkFormatter
};
column.component.updateDefinition(companyDv);
cm.getColumnByField('funktion_beschreibung').component.updateDefinition({
title: this.$p.t('person', 'zuordnung_taetigkeit'),
width: 140
});
cm.getColumnByField('funktion_oebezeichnung').component.updateDefinition({
title: this.$p.t('lehre', 'organisationseinheit'),
width: 140
});
cm.getColumnByField('wochenstunden').component.updateDefinition({
title: this.$p.t('person', 'wochenstunden')
});
const columnDatumVon = cm.getColumnByField('datum_von');
const fieldVonDatum = {
title: this.$p.t('ui', 'from')
};
columnDatumVon.component.updateDefinition(fieldVonDatum);
const columnDatumBis = cm.getColumnByField('datum_bis');
const fieldBisDatum = {
title: this.$p.t('global', 'bis'),
};
columnDatumBis.component.updateDefinition(fieldBisDatum);
cm.getColumnByField('bezeichnung').component.updateDefinition({
title: this.$p.t('ui', 'bezeichnung'),
width: 140
});
}
}
],
isFilterSet: true,
listOrgHeads: [],
listOrgUnits: [], //Old
listAllOrgUnits: [],
listOrgUnits_GST: [],
listOrgUnits_GMBH: [],
formData: {
head: 'gst',
oe_kurzbz: '',
funktion_kurzbz: null,
label:'',
//funktion_label: '',
funktion: null,
},
statusNew: true,
listAllFunctions: [],
abortController: {
oes: null,
functions: null
},
filteredOes: [],
filteredFunctions: [],
newBtnStyle: '',
selectedFunction: null,
selectedOe: null
}
},
watch: {
selectedFunction(newVal) {
this.formData.funktion_kurzbz = newVal?.funktion_kurzbz || '';
},
selectedOe(newVal) {
this.formData.oe_kurzbz = newVal?.oe_kurzbz || '';
}
},
methods: {
onSwitchChange() {
if (this.isFilterSet) {
this.$refs.table.tabulator.setFilter("aktiv", "=", true);
}
else {
this.$refs.table.tabulator.clearFilter();
this.isFilterSet = false;
}
},
actionNewFunction(){
this.resetModal();
this.statusNew = true;
this.formData.datum_von = new Date();
this.$refs.functionModal.show();
},
actionCopyFunction(benutzerfunktion_id) {
this.statusNew = true;
this.loadFunction(benutzerfunktion_id).then(() => {
this.$refs.functionModal.show();
});
},
actionDeleteFunction(benutzerfunktion_id) {
this.$fhcAlert
.confirmDelete()
.then(result => result
? benutzerfunktion_id
: Promise.reject({handled: true}))
.then(this.deleteFunction)
.catch(this.$fhcAlert.handleSystemError);
},
actionEditFunction(benutzerfunktion_id) {
this.resetModal();
this.statusNew = false;
this.loadFunction(benutzerfunktion_id).then(() => {
//set selectedFunction and selectedOd to enable viewing label in primevue autocomplete fields
this.selectedFunction = this.listAllFunctions.find(
item => item.funktion_kurzbz === this.formData.funktion_kurzbz
);
this.selectedOe = this.listAllOrgUnits.find(
item => item.oe_kurzbz === this.formData.oe_kurzbz
);
});
this.$refs.functionModal.show();
},
addFunction() {
const dataToSend = {
uid: this.personUID,
formData: this.formData
};
return this.$refs.functionData
.call(ApiCoreFunktion.addFunction(dataToSend))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.hideModal('functionModal');
this.resetModal();
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.reload();
});
},
loadFunction(benutzerfunktion_id) {
return this.$api
.call(ApiCoreFunktion.loadFunction(benutzerfunktion_id))
.then(result => {
this.formData = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
updateFunction(benutzerfunktion_id){
const dataToSend = {
uid: this.personUID,
formData: this.formData,
benutzerfunktion_id: benutzerfunktion_id
};
return this.$refs.functionData
.call(ApiCoreFunktion.updateFunction(dataToSend))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.hideModal('functionModal');
this.resetModal();
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.reload();
});
},
deleteFunction(benutzerfunktion_id) {
return this.$api
.call(ApiCoreFunktion.deleteFunction(benutzerfunktion_id))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.reload();
});
},
hideModal(modalRef) {
this.$refs[modalRef].hide();
},
reload() {
this.$refs.table.reloadTable();
},
resetModal(){
this.formData = {};
this.formData.head = 'gst';
this.formData.oe_kurzbz = '';
this.formData.funktion_kurzbz = '';
},
filterFunctions(event) {
const query = event.query.toLowerCase();
this.filteredFunctions = this.listAllFunctions.filter(item =>
item.label.toLowerCase().includes(query)
)
},
filterOes(event) {
const query = event.query.toLowerCase();
if(!this.formData.head)
this.$fhcAlert.alertError(this.$p.t('ui', 'bitteUnternehmenWaehlen'));
if(this.formData.head == 'gst') {
this.filteredOes = this.listOrgUnits_GST.filter(item =>
item.label.toLowerCase().includes(query)
);
}
if(this.formData.head == 'gmbh') {
this.filteredOes = this.listOrgUnits_GMBH.filter(item =>
item.label.toLowerCase().includes(query)
);
}
},
styleNewButton(){
if(this.stylePv21) {
this.newBtnStyle = "btn-sm";
}
},
//helper function: workaround to trigger validation if input is not a number
normalizeStunden() {
if (this.formData.wochenstunden === null || this.formData.wochenstunden === '') {
this.formData.wochenstunden = 'xxx'
}
}
},
created() {
this.$api
.call(ApiCoreFunktion.getOrgHeads())
.then(result => {
this.listOrgHeads = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiCoreFunktion.getAllFunctions())
.then(result => {
this.listAllFunctions = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiCoreFunktion.getAllOrgUnits())
.then(result => {
this.listAllOrgUnits = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiCoreFunktion.getOrgetsForCompany('gst'))
.then(result => {
this.listOrgUnits_GST = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiCoreFunktion.getOrgetsForCompany('gmbh'))
.then(result => {
this.listOrgUnits_GMBH = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.styleNewButton();
},
template: `
<div class="core-functions h-100 pb-3">
<div class="d-flex justify-content-end" v-if="stylePv21">
<form-input
container-class="form-check"
type="checkbox"
:label="$p.t('funktion/filter_active')"
v-model="isFilterSet"
@change="onSwitchChange"
>
</form-input>
</div>
<div v-else class="py-3">
<form-input
container-class="form-switch"
type="checkbox"
:label="$p.t('funktion/filter_active')"
v-model="isFilterSet"
@change="onSwitchChange"
>
</form-input>
</div>
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
:reload= "!this.stylePv21"
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-class="this.newBtnStyle"
:new-btn-label="this.$p.t('person', 'funktion')"
@click:new="actionNewFunction"
>
</core-filter-cmpt>
<!--Modal: functionModal-->
<bs-modal ref="functionModal" dialog-class="modal-lg">
<template #title>
<p v-if="statusNew" class="fw-bold mt-3">{{ $p.t('funktion', 'addFunktion') }}</p>
<p v-else class="fw-bold mt-3">{{ $p.t('funktion', 'editFunktion') }}</p>
</template>
<form-form class="row pt-3" ref="functionData">
<form-input
container-class="mb-3 col-8"
type="select"
name="companies"
:label="$p.t('core/unternehmen')"
v-model="formData.head"
@change="getOrgetsForCompanyOld"
>
<option
v-for="org in listOrgHeads"
:key="org.head"
:value="org.head"
>
{{ org.bezeichnung }}
</option>
</form-input>
<!--DropDown Autocomplete Funktion -->
<form-input
container-class="mb-3 col-8"
type="autocomplete"
:label="$p.t('person/funktion') + ' *' "
name="funktion_kurzbz"
v-model="selectedFunction"
forceSelection
optionLabel="label"
optionValue="funktion_kurzbz"
:suggestions="filteredFunctions"
dropdown
@complete="filterFunctions"
>
<template #option="slotProps">
<div
:class="!slotProps.option.aktiv
? 'item-inactive'
: ''"
>
{{ slotProps.option.label}}
</div>
</template>
</form-input>
<!--DropDown Autocomplete Organisationseinheit-->
<form-input
container-class="mb-3 col-8"
type="autocomplete"
:label="$p.t('lehre/organisationseinheit') + ' *'"
name="oe_kurzbz"
v-model="selectedOe"
forceSelection
optionLabel="label"
optionValue="oe_kurzbz"
:suggestions="filteredOes"
dropdown
@complete="filterOes"
>
<template #option="slotProps">
<div
:class="!slotProps.option.aktiv
? 'item-inactive'
: ''"
>
{{slotProps.option.label}}
</div>
</template>
</form-input>
<form-input
container-class="mb-3 col-8"
type="text"
name="bezeichnung"
:label="$p.t('global/bezeichnung')"
v-model="formData.bezeichnung"
>
</form-input>
<div class="row mb-3">
<form-input
container-class="mb-3 col-2"
type="number"
name="wochenstunden"
@blur="normalizeStunden"
:label="$p.t('person/wochenstunden')"
v-model="formData.wochenstunden"
>
</form-input>
<form-input
container-class="mb-3 col-3"
type="DatePicker"
v-model="formData.datum_von"
name="datum_von"
:label="$p.t('ui/from') + ' *'"
auto-apply
:enable-time-picker="false"
text-input
format="dd.MM.yyyy"
preview-format="dd.MM.yyyy"
:teleport="true"
>
</form-input>
<form-input
container-class="mb-3 col-3"
type="DatePicker"
v-model="formData.datum_bis"
name="datum_bis"
:label="$p.t('global/bis')"
auto-apply
:enable-time-picker="false"
text-input
format="dd.MM.yyyy"
preview-format="dd.MM.yyyy"
:teleport="true"
>
</form-input>
</div>
</form-form>
<template #footer>
<button type="button" class="btn btn-primary" @click="statusNew ? addFunction() : updateFunction(formData.benutzerfunktion_id)">{{$p.t('ui', 'speichern')}}</button>
</template>
</bs-modal>
</div>
`
}
@@ -0,0 +1,551 @@
import BsModal from "../../../Bootstrap/Modal.js";
import FormForm from "../../../Form/Form.js";
import FormInput from '../../../Form/Input.js';
import ListBox from "../../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js";
import DropdownComponent from "../../../VorlagenDropdown/VorlagenDropdown.js";
export default {
name: "ModalNewMessages",
components: {
BsModal,
FormForm,
DropdownComponent,
FormInput,
ListBox
},
props: {
endpoint: {
type: Object,
required: true
},
typeId: String,
id: {
type: [Number, String],
required: true
},
messageId: {
type: Number,
required: false,
},
openMode: String,
},
data(){
return {
formData: {
recipient: null,
subject: null,
body: null,
vorlage_kurzbz: null,
selectedValue: '',
relationmessage_id: null
},
statusNew: true,
vorlagen: [],
recipientsArray: [],
defaultRecipient: null,
editor: null,
fieldsUser: [],
fieldsPerson: [],
fieldsPrestudent: [],
selectedFieldPrestudent: null,
selectedFieldUser: null,
selectedFieldPerson: null,
itemsPrestudent: [],
itemsPerson: [],
itemsUser: [],
previewText: null,
previewBody: "",
replyData: null,
uid: null,
}
},
methods: {
initTinyMCE() {
const vm = this;
tinymce.init({
target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component
//height: 800,
//plugins: ['lists'],
toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify | link',
plugins: 'link',
link_context_toolbar: true,
automatic_uploads: true,
default_link_target: "_blank",
link_title: true,
target_list: [
{ title: 'New tab', value: '_blank' },
{ title: 'Same tab', value: '_self' }
],
style_formats: [
{title: 'Blocks', block: 'div'},
{title: 'Paragraph', block: 'p'},
{title: 'Heading 1', block: 'h1'},
{title: 'Heading 2', block: 'h2'},
{title: 'Heading 3', block: 'h3'},
{title: 'Heading 4', block: 'h4'},
{title: 'Heading 5', block: 'h5'},
{title: 'Heading 6', block: 'h6'},
],
autoresize_bottom_margin: 16,
setup: (editor) => {
vm.editor = editor;
editor.on('input', () => {
const newContent = editor.getContent();
vm.formData.body = newContent;
});
// Prevent Bootstrap dialog from blocking focusin
document.addEventListener('focusin', (e) => {
if (e.target.closest(".tox-tinymce-aux, .moxman-window, .tam-assetmanager-root") !== null) {
e.stopImmediatePropagation();
}
});
},
});
},
updateText(value) {
this.formData.body = value;
},
sendMessage() {
const data = new FormData();
const params = {
id: this.id,
type_id: this.typeId
};
const merged = {
...this.formData,
...params
};
data.append('data', JSON.stringify(merged));
return this.$refs.formMessage
.call(this.endpoint.sendMessageFromModalContext(this.uid, data))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent'));
this.hideModal('modalNewMessage');
this.resetForm();
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
//this.resetForm();
//closeModal
//closewindwo
this.$emit('reloadTable');
}
);
},
getVorlagentext(vorlage_kurzbz){
return this.$api
.call(this.endpoint.getVorlagentext(vorlage_kurzbz))
.then(response => {
this.formData.body = response.data;
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
//this.resetForm();
//closeModal
//closewindwo
});
},
getPreviewText(){
const data = new FormData();
data.append('data', JSON.stringify(this.formData.body));
return this.$api
.call(this.endpoint.getPreviewText({
id: this.id,
type_id: this.typeId}, data))
.then(response => {
this.previewText = response.data;
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
//this.resetForm();
//closeModal
//closewindwo
});
},
insertVariable(selectedItem){
if (this.editor) {
this.editor.insertContent(selectedItem.value + " ");
this.editor.fire('input');
this.editor.fire('change');
this.editor.setDirty(true);
this.editor.save();
} else {
console.error("Editor instance is not available.");
}
},
resetForm(){
this.formData = {
vorlage_kurzbz: null,
body: null,
subject: null,
};
this.$emit('resetMessageId');
if (this.editor) {
this.editor.setContent("");
}
this.$refs.dropdownComp.setValue(null);
this.previewBody = null;
},
handleSelectedVorlage(vorlage_kurzbz) {
if (typeof vorlage_kurzbz === "string") {
this.getVorlagentext(vorlage_kurzbz);
this.formData.subject = vorlage_kurzbz;
}
},
showPreview(){
this.getPreviewText().then(() => {
this.previewBody = this.previewText;
});
},
getUid(id, typeId){
const params = {
id: id,
type_id: typeId
};
this.$api
.call(this.endpoint.getUid(params))
.then(result => {
this.uid = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
show(){
this.$refs.modalNewMessage.show();
},
hideModal(modalRef){
this.$refs[modalRef].hide();
},
},
watch: {
'formData.body': {
handler(newVal) {
const tinymcsVal = this.editor.getContent();
if (newVal && tinymcsVal != newVal) {
//Inhalt des Editors aktualisieren
this.editor.setContent(newVal);
}
}
},
'formData.vorlage_kurzbz': {
handler(newVal){
if (newVal && newVal != null) {
this.formData.subject = newVal;
return this.getVorlagentext(newVal);
}
}
},
messageId: {
immediate: true,
handler: async function (newMessageId) {
if (!newMessageId) return;
try {
const result = await this.$api.call(this.endpoint.getReplyData(newMessageId));
this.replyData = result.data;
if (this.replyData.length > 0) {
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = newMessageId;
}
} catch (error) {
this.$fhcAlert.handleSystemError(error);
}
}
}
},
created(){
this.getUid(this.id, this.typeId);
if(this.typeId == 'person_id' || this.typeId == 'mitarbeiter_uid'){
const params = {
id: this.id,
type_id: this.typeId
};
this.$api
.call(this.endpoint.getMessageVarsPerson(params))
.then(result => {
this.fieldsPerson = result.data;
const person = this.fieldsPerson[0];
this.itemsPerson = Object.entries(person).map(([key, value]) => ({
label: key.toLowerCase(),
value: '{' + key.toLowerCase() + '}'
}));
})
.catch(this.$fhcAlert.handleSystemError);
}
if(this.typeId == 'prestudent_id' || this.typeId == 'uid'){
const params = {
id: this.id,
type_id: this.typeId
};
this.$api
.call(this.endpoint.getMsgVarsPrestudent(params))
.then(result => {
this.fieldsPrestudent = result.data;
const prestudent = this.fieldsPrestudent[0];
this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({
label: key.toLowerCase(),
value: '{' + key.toLowerCase() + '}'
}));
})
.catch(this.$fhcAlert.handleSystemError);
}
this.$api
.call(this.endpoint.getMsgVarsLoggedInUser())
.then(result => {
this.fieldsUser = result.data;
const user = this.fieldsUser;
this.itemsUser = Object.entries(user).map(([key, value]) => ({
label: value,
value: '{' + value + '}'
}));
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(this.endpoint.getNameOfDefaultRecipient({
id: this.id,
type_id: this.typeId}))
.then(result => {
this.defaultRecipient = result.data;
this.recipientsArray.push({
'uid': this.uid,
'details': this.defaultRecipient});
})
.catch(this.$fhcAlert.handleSystemError);
//case of reply
if(this.messageId) {
this.$api
.call(this.endpoint.getReplyData(this.messageId))
.then(result => {
this.replyData = result.data;
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = this.messageId;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
async mounted() {
this.initTinyMCE();
},
beforeDestroy() {
this.editor.destroy();
},
template: `
<bs-modal
class="messages-detail-newmessage-modal"
ref="modalNewMessage"
dialog-class=" modal-dialog-scrollable modal-xl modal-msg"
header-class="flex-wrap pb-0"
body-class="px-3 py-2"
@hidden.bs.modal="resetForm"
>
<template #title>
{{ $p.t('messages', 'neueNachricht') }}
</template>
<template #modal-header-content>
<ul class="nav nav-tabs w-100 mt-3 msg_preview" id="msg_preview" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="msg-tab" data-bs-toggle="tab" data-bs-target="#msg" type="button" role="tab" aria-controls="msg" aria-selected="true">Nachricht</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="preview-tab" data-bs-toggle="tab" data-bs-target="#preview" type="button" role="tab" aria-controls="preview" aria-selected="false">Vorschau</button>
</li>
</ul>
</template>
<form-form ref="formNewMassage">
<div class="tab-content" id="msg_preview_content">
<div class="tab-pane fade show active" id="msg" role="tabpanel" aria-labelledby="msg-tab">
<div class="row">
<div class="col-sm-8">
<form-form class="row g-3 mt-2 h-100" ref="formMessage">
<div class="row mb-3">
<form-input
type="text"
name="recipient"
:label="$p.t('messages/recipient')"
v-model="defaultRecipient"
disabled
>
</form-input>
</div>
<div class="row mb-3">
<form-input
type="text"
name="subject"
:label="$p.t('global/betreff') + ' *'"
v-model="formData.subject"
>
</form-input>
</div>
<!--Tiny MCE-->
<div class="row mb-3 h-100 tiny-90">
<form-input
ref="editor"
:label="$p.t('global','nachricht') + ' *'"
type="textarea"
v-model="formData.body"
name="body"
rows="35"
cols="75"
>
</form-input>
</div>
</form-form>
</div>
<div class="col-sm-4">
<div class="row">
<dropdown-component
ref="dropdownComp"
:label="$p.t('global/vorlage')"
@change="handleSelectedVorlage"
useLoggedInUserOe
>
</dropdown-component>
</div>
<div v-if="this.fieldsPrestudent.length > 0">
<div class="mt-2"><strong>{{$p.t('ui', 'felder')}} {{$p.t('lehre', 'prestudent')}}</strong></div>
<list-box
v-model="selectedFieldPrestudent"
:options="itemsPrestudent"
optionLabel="label"
listStyle="max-height:200px; overscroll-behavior: none;"
>
<template #option="slotProps">
<div @dblclick="insertVariable(slotProps.option)">
{{ slotProps.option.label }}
</div>
</template>
</list-box>
</div>
<div v-if="this.fieldsPerson.length > 0">
<div class="mt-2"><strong>Felder Person</strong></div>
<list-box
v-model="selectedFieldPerson"
:options="itemsPerson"
optionLabel="label"
listStyle="max-height:200px; overscroll-behavior: none;"
>
<template #option="slotProps">
<div @dblclick="insertVariable(slotProps.option)">
{{ slotProps.option.label }}
</div>
</template>
</list-box>
</div>
<div>
<div class="mt-2"><strong>{{$p.t('messages', 'meineFelder')}}</strong></div>
<list-box
v-model="selectedFieldUser"
:options="itemsUser"
optionLabel="label"
listStyle="max-height:200px; overscroll-behavior: none;"
>
<template #option="slotProps">
<div @dblclick="insertVariable(slotProps.option)">
{{ slotProps.option.label }}
</div>
</template>
</list-box>
</div>
</div>
</div>
</div>
<div class="tab-pane fade" id="preview" role="tabpanel" aria-labelledby="preview-tab">
<div class="row mt-4">
<h4>{{ $p.t('global', 'vorschau') }}:</h4>
<div>
<form-form class="row g-3 mt-2" ref="formPreview">
<div class="col-sm-2 mb-3">
<form-input
type="select"
name="recipient"
:label="$p.t('messages/recipient')"
v-model="defaultRecipient"
>
<option :value="null">{{ $p.t('messages', 'recipient') }}...</option>
<option
v-for="recipient in recipientsArray"
:key="recipient.uid"
:value="recipient.uid"
>{{recipient.details}}
</option>
</form-input>
</div>
<div class="col-md-2 mt-4">
<br>
<button type="button" class="btn btn-secondary" @click="showPreview()">{{ $p.t('ui', 'btnAktualisieren') }}</button>
</div>
</form-form>
<div class="col-sm-12 overflow-scroll">
<div ref="preview">
<div v-html="previewBody" class="p-3 border rounded overflow-scroll twoColumns"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</form-form>
<template #footer>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<button class="btn btn-secondary" @click="resetForm">{{$p.t('ui', 'reset')}}</button>
<button v-if="statusNew" type="button" class="btn btn-primary" @click="sendMessage()">{{$p.t('ui', 'nachrichtSenden')}}</button>
<button v-else type="button" class="btn btn-primary" @click="replyMessage(formData.message_id)">{{$p.t('global', 'reply')}}</button>
</div>
</template>
</bs-modal>
`,
}
@@ -0,0 +1,554 @@
import FormForm from '../../../Form/Form.js';
import FormInput from '../../../Form/Input.js';
import ListBox from "../../../../../../index.ci.php/public/js/components/primevue/listbox/listbox.esm.min.js";
import DropdownComponent from '../../../VorlagenDropdown/VorlagenDropdown.js';
export default {
name: "ComponentNewMessages",
components: {
FormForm,
FormInput,
ListBox,
DropdownComponent,
},
props: {
endpoint: {
type: Object,
required: true
},
openMode: String,
tempTypeId: String,
tempId: {
type: [Number, String],
required: false
},
tempMessageId: {
type: Number,
required: false,
}
},
computed: {
//params with routes for new tab and new window AND props for inSamePage
id(){
return this.$props.tempId || this.$route.params.id;
},
typeId(){
return this.$props.tempTypeId || this.$route.params.typeId;
},
messageId(){
return this.$props.tempMessageId ||this.$route.params.messageId;
}
},
data(){
return {
formData: {
recipient: null,
subject: null,
body: null,
vorlage_kurzbz: null,
selectedValue: '',
relationmessage_id: null
},
statusNew: true,
vorlagen: [],
recipientsArray: [],
defaultRecipient: null,
editor: null,
isVisible: false,
fieldsUser: [],
fieldsPerson: [],
fieldsPrestudent: [],
selectedFieldPrestudent: null,
selectedFieldUser: null,
selectedFieldPerson: null,
itemsPrestudent: [],
itemsPerson: [],
itemsUser: [],
previewText: null,
previewBody: "",
replyData: null,
uid: null,
messageSent: false
}
},
methods: {
initTinyMCE() {
const vm = this;
tinymce.init({
target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component
//height: 800,
//plugins: ['lists'],
toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify',
style_formats: [
{title: 'Blocks', block: 'div'},
{title: 'Paragraph', block: 'p'},
{title: 'Heading 1', block: 'h1'},
{title: 'Heading 2', block: 'h2'},
{title: 'Heading 3', block: 'h3'},
{title: 'Heading 4', block: 'h4'},
{title: 'Heading 5', block: 'h5'},
{title: 'Heading 6', block: 'h6'},
],
autoresize_bottom_margin: 16,
setup: (editor) => {
vm.editor = editor;
editor.on('input', () => {
const newContent = editor.getContent();
vm.formData.body = newContent;
});
},
});
},
updateText(value) {
this.formData.body = value;
},
sendMessage() {
const data = new FormData();
const params = {
id: this.id,
type_id: this.typeId
};
const merged = {
...this.formData,
...params
};
data.append('data', JSON.stringify(merged));
return this.$api
.call(this.endpoint.sendMessage(this.uid, data))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSent'));
this.hideTemplate();
this.resetForm();
this.messageSent = true;
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
//TODO(Manu) hier route definieren für openmode in Tab, Page?
// ist kein child sondern mit route aufgerufen
//würde allerdings neues fenster aktualisiert öffnen, altes bleibt ohne reload gleich
//Reload vorheriges tab???
if(this.openMode == "inSamePage"){
this.$emit('reloadTable');
}
}
);
},
getVorlagentext(vorlage_kurzbz){
return this.$api
.call(this.endpoint.getVorlagentext(vorlage_kurzbz))
.then(response => {
this.formData.body = response.data;
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
//this.resetForm();
});
},
getPreviewText(id, typeId){
const data = new FormData();
data.append('data', JSON.stringify(this.formData.body));
return this.$api
.call(this.endpoint.getPreviewText({
id: this.id,
type_id: this.typeId}, data))
.then(response => {
this.previewText = response.data;
}).catch(this.$fhcAlert.handleSystemError)
.finally(() => {
//this.resetForm();
});
},
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}&nbsp;</span>`);
//this.editor.selection.setCursorLocation(this.editor.getBody(), 1);
} else {
console.error("Editor instance is not available.");
}
},
resetForm(){
this.formData = {
vorlage_kurzbz: null,
body: null,
subject: null,
};
if (this.editor) {
this.editor.setContent("");
}
this.$refs.dropdownComp.setValue(null);
this.previewBody = null;
},
toggleDivNewMessage(){
this.isVisible = !this.isVisible;
},
handleSelectedVorlage(vorlage_kurzbz) {
if (typeof vorlage_kurzbz === "string") {
this.getVorlagentext(vorlage_kurzbz);
this.formData.subject = vorlage_kurzbz;
}
},
hideTemplate(){
if (this.openMode == "inSamePage")
this.isVisible = false;
},
showTemplate(){
if (this.openMode == "inSamePage")
this.isVisible = true;
},
showPreview(id, typeId){
this.getPreviewText(id, typeId).then(() => {
this.previewBody = this.previewText;
});
},
getUid(id, typeId){
const params = {
id: id,
type_id: typeId
};
this.$api
.call(this.endpoint.getUid(params))
.then(result => {
this.uid = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
watch: {
'formData.body': {
handler(newVal) {
const tinymcsVal = this.editor.getContent();
if (newVal && tinymcsVal != newVal) {
//Inhalt des Editors aktualisieren
this.editor.setContent(newVal);
}
}
},
'formData.vorlage_kurzbz': {
handler(newVal){
if (newVal && newVal != null) {
this.formData.subject = newVal;
return this.getVorlagentext(newVal);
}
}
},
},
created(){
this.getUid(this.id, this.typeId);
if (['person_id', 'mitarbeiter_uid'].includes(this.typeId)){
const params = {
id: this.id,
type_id: this.typeId
};
this.$api
.call(this.endpoint.getMessageVarsPerson(params))
.then(result => {
this.fieldsPerson = result.data;
const person = this.fieldsPerson[0];
this.itemsPerson = Object.entries(person).map(([key, value]) => ({
label: key.toLowerCase(),
value: '{' + key.toLowerCase() + '}'
}));
})
.catch(this.$fhcAlert.handleSystemError);
}
if (['prestudent_id', 'uid'].includes(this.typeId)){
const params = {
id: this.id,
type_id: this.typeId
};
this.$api
.call(this.endpoint.getMsgVarsPrestudent(params))
.then(result => {
this.fieldsPrestudent = result.data;
const prestudent = this.fieldsPrestudent[0];
this.itemsPrestudent = Object.entries(prestudent).map(([key, value]) => ({
label: key.toLowerCase(),
value: '{' + key.toLowerCase() + '}'
}));
})
.catch(this.$fhcAlert.handleSystemError);
}
this.$api
.call(this.endpoint.getMsgVarsLoggedInUser())
.then(result => {
this.fieldsUser = result.data;
const user = this.fieldsUser;
this.itemsUser = Object.entries(user).map(([key, value]) => ({
label: value,
value: '{' + value + '}'
}));
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(this.endpoint.getNameOfDefaultRecipient({
id: this.id,
type_id: this.typeId}))
.then(result => {
this.defaultRecipient = result.data;
this.recipientsArray.push({
'uid': this.uid,
'details': this.defaultRecipient});
})
.catch(this.$fhcAlert.handleSystemError);
//case of reply
if(this.messageId != null) {
this.$api
.call(this.endpoint.getReplyData(this.messageId))
.then(result => {
this.replyData = result.data;
this.formData.subject = this.replyData[0].replySubject;
this.formData.body = this.replyData[0].replyBody;
this.formData.relationmessage_id = this.messageId;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
async mounted() {
this.initTinyMCE();
},
beforeDestroy() {
this.editor.destroy();
},
template: `
<div class="messages-detail-newmessage-newdiv">
<!--new page-->
<div v-if="!messageSent" class="overflow-auto m-3">
<h4>{{ $p.t('messages', 'neueNachricht') }}</h4>
<div class="row">
<div class="col-sm-8">
<form-form class="row g-3 mt-2" ref="formMessage">
<div class="row mb-3">
<form-input
type="text"
name="recipient"
:label="$p.t('messages/recipient')"
v-model="defaultRecipient"
disabled
>
</form-input>
</div>
<div class="row mb-3">
<form-input
type="text"
name="subject"
:label="$p.t('global/betreff') + ' *'"
v-model="formData.subject"
>
</form-input>
</div>
<!--Tiny MCE-->
<div class="row mb-3">
<form-input
ref="editor"
:label="$p.t('global','nachricht') + ' *'"
type="textarea"
v-model="formData.body"
name="text"
rows="15"
cols="75"
>
</form-input>
</div>
<div class="row">
<DropdownComponent
ref="dropdownComp"
:label="$p.t('global/vorlage')"
@change="handleSelectedVorlage"
useLoggedInUserOe
>
</DropdownComponent>
</div>
</form-form>
</div>
<div class="col-sm-4">
<div v-if="this.fieldsPrestudent.length > 0" class="mt-3">
<strong>{{$p.t('ui', 'felder')}} {{$p.t('lehre', 'prestudent')}}</strong>
<list-box
v-model="selectedFieldPrestudent"
:options="itemsPrestudent"
optionLabel="label"
listStyle="max-height:250px"
>
<template #option="slotProps">
<div @dblclick="insertVariable(slotProps.option)">
{{ slotProps.option.label }}
</div>
</template>
</list-box>
</div>
<br>
<div v-if="this.fieldsPerson.length > 0" class="mt-3">
<strong>Felder Person</strong>
<list-box
v-model="selectedFieldPerson"
:options="itemsPerson"
optionLabel="label"
listStyle="max-height:250px"
>
<template #option="slotProps">
<div @dblclick="insertVariable(slotProps.option)">
{{ slotProps.option.label }}
</div>
</template>
</list-box>
</div>
<div>
<strong>{{$p.t('messages', 'meineFelder')}}</strong>
<list-box
v-model="selectedFieldUser"
:options="itemsUser"
optionLabel="label"
listStyle="max-height:200px"
>
<template #option="slotProps">
<div @dblclick="insertVariable(slotProps.option)">
{{ slotProps.option.label }}
</div>
</template>
</list-box>
</div>
<br>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<button class="btn btn-secondary" @click="resetForm">{{$p.t('ui', 'reset')}}</button>
<button v-if="statusNew" type="button" class="btn btn-primary" @click="sendMessage()">{{$p.t('ui', 'nachrichtSenden')}}</button>
<button v-else type="button" class="btn btn-primary" @click="replyMessage(formData.message_id)">{{$p.t('global', 'reply')}}</button>
</div>
</div>
</div>
<div class="row mt-4">
<h4>{{ $p.t('global', 'vorschau') }}:</h4>
<div>
<form-form class="row g-3 mt-2" ref="formPreview">
<div class="col-sm-2 mb-3">
<form-input
type="select"
name="recipient"
:label="$p.t('messages/recipient')"
v-model="defaultRecipient"
>
<option :value="null">{{ $p.t('messages', 'recipient') }}...</option>
<option
v-for="recipient in recipientsArray"
:key="recipient.uid"
:value="recipient.uid"
>{{recipient.details}}
</option>
</form-input>
</div>
<div class="col-md-2 mt-4">
<br>
<button type="button" class="btn btn-secondary" @click="showPreview(id, typeId)">{{ $p.t('ui', 'btnAktualisieren') }}</button>
</div>
</form-form>
<div class="col-sm-12 overflow-scroll">
<div ref="preview">
<div v-html="previewBody" class="p-3 border rounded overflow-scroll" style="height: 300px;"></div>
</div>
</div>
</div>
</div>
</div>
<div v-if="messageSent && openMode!='inSamePage'" class="container d-flex justify-content-center align-items-center m-3">
<div class="card" style="width: 80%">
<div class="card-body alert alert-success text-dar p-5 rounded">
<div class="row">
<div class="col-6">
Message sent successfully!
</div>
<div class="col-6">
Nachricht erfolgreich versandt!
</div>
</div>
<div class="row">
<div class="col-6" style="border-right: 1px">
You can safely close this window.
</div>
<div class="col-6">
Sie können dieses Fenster schließen.
</div>
</div>
</div>
<div class="text-center">
<p class="signatureblock">
Fachhochschule Technikum Wien | University of Applied Sciences Technikum Wien
<br>Hoechstaedtplatz 6, 1200 Wien, AUSTRIA
<br><a class="signatureblocklink" href="https://www.technikum-wien.at">www.technikum-wien.at</a>
</p>
</div>
</div>
</div>
</div>
`
}
@@ -0,0 +1,425 @@
import {CoreFilterCmpt} from "../../filter/Filter.js";
import FormForm from '../../Form/Form.js';
export default {
name: "TableMessages",
components: {
CoreFilterCmpt,
FormForm,
},
inject: {
cisRoot: {
from: 'cisRoot'
},
},
props: {
endpoint: {
type: Object,
required: true
},
typeId: String,
id: {
type: [Number, String],
required: true
},
messageLayout: String,
openMode: String
},
data(){
return {
tabulatorOptions: {
ajaxURL: 'dummy',
ajaxRequestFunc: this.loadAjaxCall,
ajaxParams: () => {
return {
id: this.id,
type: this.typeId
};
},
ajaxResponse: (url, params, response) => this.buildTreemap(response),
columns: [
{title: "subject", field: "subject"},
{title: "body", field: "body", formatter: "html", visible: false},
{title: "message_id", field: "message_id", visible: false},
{
title: "Datum",
field: "insertamum",
formatter: function (cell) {
const dateStr = cell.getValue();
const date = new Date(dateStr); // Convert to Date object
return date.toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: false
});
}
},
{title: "sender", field: "sender"},
{title: "recipient", field: "recipient"},
{title: "senderId", field: "sender_id"},
{title: "recipientId", field: "recipient_id"},
{title: "Relationmessage ID", field: "relationmessage_id"},
{
title: "Status",
field: "status",
formatterParams: [
"unread",
"read",
"archived",
"deleted"
],
formatter: (cell, formatterParams) => {
return formatterParams[cell.getValue()];
}
},
{
title: "letzte Änderung",
field: "statusdatum",
formatter: function (cell) {
const dateStr = cell.getValue();
const date = new Date(dateStr); // Convert to Date object
return date.toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
hour: "2-digit",
minute: "2-digit",
hour12: false
});
}
},
{
title: 'Aktionen', field: 'actions',
width: 100,
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
container.className = "d-flex gap-2";
let button = document.createElement('button');
if (this.personId != cell.getData().sender_id) {
button.disabled = true;
button.style = "visibility: hidden";
button.ariaHidden = true;
}
button.className = 'btn btn-outline-secondary btn-action';
button.title = this.$p.t('global', 'reply');
button.innerHTML = '<i class="fa fa-reply"></i>';
button.addEventListener(
'click',
(event) =>
this.actionReplyToMessage(cell.getData().message_id)
);
container.append(button);
button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.title = this.$p.t('ui', 'loeschen');
button.innerHTML = '<i class="fa fa-xmark"></i>';
button.addEventListener(
'click',
() =>
this.actionDeleteMessage(cell.getData().message_id)
);
container.append(button);
return container;
},
frozen: true
}
],
layout: 'fitDataFill',
layoutColumnsOnNewData: false,
height: '400',
selectableRangeMode: 'click',
index: 'message_id',
pagination: true,
paginationMode: "remote",
paginationSize: 15,
paginationInitialPage: 1,
dataTree: true,
headerSort: true,
dataTreeChildField: "children",
dataTreeCollapseElement:"<i class='fas fa-minus-square'></i>",
dataTreeChildIndent: 15,
dataTreeStartExpanded: false,
persistenceID: 'core-message',
locale: 'de',
"langs": {
"de":{ //German language definition
"data":{
"loading":"Lädt", //data loader text
"error":"Fehler", //data error text
},
"pagination":{
"first":"Erste",
"first_title":"Erste Seite",
"last":"Letzte",
"last_title":"Letzte Seite",
"prev":"Vorige",
"prev_title":"Vorige Seite",
"next":"Nächste",
"next_title":"Nächste Seite",
"all":"Alle"
},
},
}
},
tabulatorEvents: [
{
event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global', 'person', 'stv', 'messages', 'ui', 'notiz']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('subject').component.updateDefinition({
title: this.$p.t('global', 'betreff')
});
cm.getColumnByField('body').component.updateDefinition({
title: this.$p.t('messages', 'body')
});
cm.getColumnByField('message_id').component.updateDefinition({
title: this.$p.t('messages', 'message_id')
});
cm.getColumnByField('insertamum').component.updateDefinition({
title: this.$p.t('global', 'datum')
});
cm.getColumnByField('sender').component.updateDefinition({
title: this.$p.t('messages', 'sender')
});
cm.getColumnByField('recipient').component.updateDefinition({
title: this.$p.t('messages', 'recipient')
});
cm.getColumnByField('sender_id').component.updateDefinition({
title: this.$p.t('messages', 'senderId')
});
cm.getColumnByField('recipient_id').component.updateDefinition({
title: this.$p.t('messages', 'recipientId')
});
cm.getColumnByField('statusdatum').component.updateDefinition({
title: this.$p.t('notiz', 'letzte_aenderung')
});
cm.getColumnByField('status').component.updateDefinition({
formatterParams: [
this.$p.t('messages/unread'),
this.$p.t('messages/read'),
this.$p.t('messages/archived'),
this.$p.t('messages/deleted')
]
});
this.$refs.table.tabulator.rowManager.getDisplayRows();
/*
cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'aktionen')
});
*/
}
},
{
event: 'rowClick',
handler: (e, row) => {
const selectedMessage = row.getData().message_id;
const body = row.getData().body;
this.previewBody = body;
}
},
/*
{
event: 'pageLoaded',
handler: (pageno) => {
this.pageNo = pageno+1;
}
}
*/
],
previewBody: "",
open: false,
personId: null,
}
},
methods: {
actionDeleteMessage(message_id){
this.$fhcAlert
.confirmDelete()
.then(result => result
? message_id
: Promise.reject({handled: true}))
.then(this.deleteMessage)
.catch(this.$fhcAlert.handleSystemError);
},
deleteMessage(message_id){
return this.$api
.call(this.endpoint.deleteMessage(message_id))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
}).catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
window.scrollTo(0, 0);
this.reload();
});
},
actionNewMessage(){
this.$emit('newMessage', this.id, this.typeId);
},
actionReplyToMessage(message_id){
this.$emit('replyToMessage', this.id, this.typeId, message_id);
},
reload() {
this.$refs.table.reloadTable();
},
buildTreemap(messages) {
const last_page = messages.meta.count;
messages = messages.data;
const messageMap = new Map();
const messageNested = [];
const remainingMessages = new Set(messages);
//save all Data in Map
messages.forEach(msg => messageMap.set(msg.message_id, msg));
let iteration = 0;
let changes = true;
// do until each relationmessage_id finds message_id (not sensitive to order)
while (changes) {
changes = false;
iteration++;
remainingMessages.forEach(msg => {
if (msg.relationmessage_id === null) {
messageNested.push(messageMap.get(msg.message_id));
remainingMessages.delete(msg);
changes = true;
} else if (messageMap.has(msg.relationmessage_id)) {
const parent = messageMap.get(msg.relationmessage_id);
if (!parent.children) {
parent.children = [];
}
parent.children.push(messageMap.get(msg.message_id));
remainingMessages.delete(msg);
changes = true;
}
});
// to avoid endless loop
if (iteration > messages.length) break;
}
return {data: messageNested, last_page: last_page};
},
loadAjaxCall(url, config, params){
return this.$api.call(
this.endpoint.getMessages(params)
);
}
},
computed: {
statusText(){
return {
0: this.$p.t('messsages', 'unread'),
1: this.$p.t('messsages', 'read'),
2: this.$p.t('messsages', 'archived'),
3: this.$p.t('messsages', 'deleted')
}
},
},
mounted() {
// change to target="_blank"
/* this.$nextTick(() => {
const links = document.querySelectorAll('.preview a');
links.forEach(link => {
link.setAttribute('target', '_blank');
link.setAttribute('rel', 'noopener noreferrer'); // Sicherheitsmaßnahme
});
});*/
},
created(){
if(this.typeId != 'person_id') {
const params = {
id: this.id,
type_id: this.typeId
};
this.$api
.call(this.endpoint.getPersonId(params))
.then(result => {
this.personId = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
template: `
<div class="messages-detail-table">
<!--View Studierendenverwaltung-->
<div v-if="messageLayout=='twoColumnsTableLeft'">
<div class="row">
<!--table-->
<div class="col-sm-6 pt-6">
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
reload
new-btn-show
:new-btn-label="this.$p.t('global', 'nachricht')"
@click:new="actionNewMessage"
>
</core-filter-cmpt>
</div>
<!--preview wysiwyg-window-->
<div class="col-sm-6 pt-6">
<br><br><br><br>
<div ref="preview">
<div v-html="previewBody" class="p-3 border rounded overflow-scroll twoColumns"></div>
</div>
</div>
</div>
</div>
<!--View Infocenter-->
<div v-if="messageLayout=='listTableTop'">
<!--table-->
<div class="col-sm-12 pt-6">
<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')"
new-btn-show
:new-btn-label="this.$p.t('global', 'nachricht')"
@click:new="actionNewMessage"
>
</core-filter-cmpt>
</div>
<!--preview wysiwyg-window-->
<div class="col-sm-12">
<div ref="preview">
<div v-html="previewBody" class="p-3 border rounded overflow-scroll twoColumns"></div>
</div>
</div>
</div>
</div>
`
}
+177
View File
@@ -0,0 +1,177 @@
import TableMessages from "./Details/TableMessages.js";
import FormOnly from "./Details/NewMessage/NewDiv.js";
import MessageModal from "../Messages/Details/NewMessage/Modal.js";
export default {
name: "MessagesComponent",
components: {
TableMessages,
FormOnly,
MessageModal
},
inject: {
cisRoot: {
from: 'cisRoot'
}
},
props: {
endpoint: {
type: Object,
required: true
},
typeId: {
type: String,
required: true,
validator(value) {
return [
'prestudent_id',
'uid',
'person_id',
'mitarbeiter_uid'
].includes(value)
}
},
id: {
type: [Number, String],
required: true
},
showTable: Boolean,
messageLayout: {
type: String,
default: 'twoColumnsTableLeft',
validator(value) {
return [
'twoColumnsTableLeft',
'listTableTop'
].includes(value)
}
},
openMode: {
type: String,
default: 'modal',
validator(value) {
return [
'window',
'newTab',
'modal',
'inSamePage'
].includes(value)
}
}
},
data() {
return {
isVisibleDiv: false,
messageId: null
}
},
methods: {
reloadTable(){
this.$refs.templateTableMessage.reload();
},
handleMessage(id, typeId, messageId){
this.messageId = messageId;
if (this.openMode == "window") {
this.openInNewWindow(id, typeId, messageId);
}
else if (this.openMode == "newTab"){
this.openInNewTab(id, typeId, messageId);
}
else if (this.openMode == "modal"){
this.$refs.modalMsg.show();
}
else if (this.openMode == "inSamePage"){
this.isVisibleDiv = true;
}
else
console.log("no valid openMode");
},
openInNewTab(id, typeId, messageId= null){
let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
if (messageId){
path += "/NeueNachricht/" + id + "/" + typeId + "/" + messageId;
}
else {
path += "/NeueNachricht/" + id + "/" + typeId;
}
const newTab = window.open(path, "_blank");
},
openInNewWindow(id, typeId, messageId){
let path = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router;
if (messageId){
path += "/NeueNachricht/" + id + "/" + typeId + "/" + messageId;
}
else {
path += "/NeueNachricht/" + id + "/" + typeId;
}
const width = Math.round(window.innerWidth * 0.75);
const height = Math.round(window.innerHeight * 0.75);
const left = Math.round((window.innerWidth - width) / 2);
const top = Math.round((window.innerHeight - height) / 2);
const newWindow = window.open(path, "_blank", `width=${width},height=${height},left=${left},top=${top}`);
},
resetMessageId(){
this.messageId = null;
}
},
template: `
<div class="core-messages h-100 pb-3">
<message-modal
ref="modalMsg"
:type-id="typeId"
:id="id"
:message-id="messageId"
:endpoint="endpoint"
:openMode="openMode"
@reloadTable="reloadTable"
@resetMessageId="resetMessageId"
>
</message-modal>
<!--in same page-->
<div v-if="isVisibleDiv" class="overflow-auto m-3" style="max-height: 500px; border: 1px solid #ccc;">
<form-only
ref="templateNewMessage"
:temp-type-id="typeId"
:temp-id="id"
:temp-message-id="messageId"
:endpoint="endpoint"
:openMode="openMode"
@reloadTable="reloadTable"
>
</form-only>
</div>
<div v-if="showTable">
<table-messages
ref="templateTableMessage"
:type-id="typeId"
:id="id"
:endpoint="endpoint"
:messageLayout="messageLayout"
:openMode="openMode"
@newMessage="handleMessage"
@replyToMessage="handleMessage"
>
</table-messages>
</div>
<div v-else>
<div class="col-md-2 mt-4">
<br>
<button type="button" class="btn btn-primary" @click="handleMessage(id, typeId)">{{ $p.t('messages', 'neueNachricht') }}</button>
</div>
</div>
</div>
`
}
+46 -26
View File
@@ -81,6 +81,8 @@ export default {
title: "Text",
field: "text_stripped",
width: 250,
formatter: "html",
//clipContents: true,
tooltip:function(e, cell, onRendered){
var el = document.createElement("div");
el.style.backgroundColor = "white";
@@ -95,8 +97,10 @@ export default {
return el;
},
},
{title: "VerfasserIn", field: "verfasser_uid", width: 124, visible: false},
{title: "BearbeiterIn", field: "bearbeiter_uid", width: 126, visible: false},
{title: "VerfasserIn", field: "verfasser", width: 124},
{title: "BearbeiterIn", field: "bearbeiter", width: 126},
{title: "Verfasser UID", field: "verfasser_uid", width: 124, visible: false},
{title: "Bearbeiter UID", field: "bearbeiter_uid", width: 126, visible: false},
{title: "Start", field: "start_format", width: 86, visible: false},
{title: "Ende", field: "ende_format", width: 86, visible: false},
{title: "Dokumente", field: "countdoc", width: 100, visible: false},
@@ -170,11 +174,10 @@ export default {
},
frozen: true
}],
layout: 'fitColumns',
layout: 'fitDataStretchFrozen',
layoutColumnsOnNewData: false,
height: '250',
selectableRangeMode: 'click',
selectable: true,
//responsiveLayout: "collapse",
maxHeight: '200px',
index: 'notiz_id',
persistenceID: 'core-notiz'
},
@@ -187,22 +190,24 @@ export default {
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('verfasser_uid').component.updateDefinition({
cm.getColumnByField('verfasser').component.updateDefinition({
title: this.$p.t('notiz', 'verfasser'),
visible: this.showVariables.showVerfasser
});
cm.getColumnByField('verfasser_uid').component.updateDefinition({
title: this.$p.t('ui', 'verfasser_uid'),
});
cm.getColumnByField('titel').component.updateDefinition({
title: this.$p.t('global', 'titel'),
//visible: this.showVariables.showTitel
});
cm.getColumnByField('text_stripped').component.updateDefinition({
title: this.$p.t('global', 'text'),
//visible: this.showVariables.showText
});
cm.getColumnByField('bearbeiter_uid').component.updateDefinition({
cm.getColumnByField('bearbeiter').component.updateDefinition({
title: this.$p.t('notiz', 'bearbeiter'),
visible: this.showVariables.showBearbeiter
});
cm.getColumnByField('bearbeiter_uid').component.updateDefinition({
title: this.$p.t('ui', 'bearbeiter_uid'),
});
cm.getColumnByField('start_format').component.updateDefinition({
title: this.$p.t('global', 'gueltigVon'),
visible: this.showVariables.showVon
@@ -242,6 +247,16 @@ export default {
cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'aktionen')
});
cm.getColumnByField('text_stripped').component.updateDefinition({
title: this.$p.t('global', 'text'),
width: 250,
tooltip: true,
//clipContents: true,
});
// Force layout recalculation for handling overflow text
this.$refs.table.tabulator.redraw(true);
}
}
],
@@ -347,6 +362,7 @@ export default {
this.$refs.NotizModal.hide();
}
this.reload();
this.$emit('reload');
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
@@ -359,6 +375,7 @@ export default {
.then(result => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
this.reload();
this.$emit('reload');
this.resetFormData();
})
.catch(this.$fhcAlert.handleSystemError)
@@ -402,6 +419,7 @@ export default {
this.$refs.NotizModal.hide();
}
this.reload();
this.$emit('reload');
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
@@ -553,21 +571,18 @@ export default {
>
</core-filter-cmpt>
<br>
<form-form ref="formNotiz" @submit.prevent class="row pt-3">
<br><br>
<form-form ref="formNotiz" @submit.prevent class="row">
<div class="pt-2">
<div class="row mb-3">
<div class="col-sm-7">
<span class="small">[{{notizData.typeId}}]</span>
</div>
</div>
<div class="row mb-3">
<div class="row mt-4 mb-1">
<div class="col-sm-7">
<p v-if="notizData.statusNew" class="fw-bold"> {{$p.t('notiz','notiz_new')}}</p>
<p v-else class="fw-bold">{{$p.t('notiz','notiz_edit')}}</p>
<p>
<span v-if="notizData.statusNew" class="fw-bold">{{$p.t('notiz','notiz_new')}}</span>
<span v-else class="fw-bold">{{$p.t('notiz','notiz_edit')}}</span>
<span class="small"> [{{notizData.typeId}}]</span>
</p>
</div>
</div>
@@ -689,9 +704,13 @@ export default {
<p class="small">{{notizData.lastupdate}}</p>
</div>
</div>
<button v-if="notizData.statusNew" type="button" class="btn btn-primary" @click="addNewNotiz()"> {{$p.t('studierendenantrag', 'btn_new')}}</button>
<button v-else type="button" class="btn btn-primary" @click="updateNotiz(notizData.notiz_id)"> {{$p.t('ui', 'speichern')}}</button>
<div class="row">
<div class="text-end">
<button v-if="notizData.statusNew" type="button" class="btn btn-primary" @click="addNewNotiz()"> {{$p.t('studierendenantrag', 'btn_new')}}</button>
<button v-else type="button" class="btn btn-primary" @click="updateNotiz(notizData.notiz_id)"> {{$p.t('ui', 'speichern')}}</button>
</div>
</div>
</form-form>
</div>
@@ -1247,6 +1266,7 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('global', 'notiz')"
@click:new="actionNewNotiz"
@@ -65,7 +65,10 @@ export default {
defaultSemester: this.defaultSemester,
$reloadList: () => {
this.$refs.stvList.reload();
}
},
configShowAufnahmegruppen: this.config.showAufnahmegruppen,
configAllowUebernahmePunkte: this.config.allowUebernahmePunkte,
configUseReihungstestPunkte: this.config.useReihungstestPunkte
}
},
data() {
@@ -189,6 +192,8 @@ export default {
.catch(this.$fhcAlert.handleSystemError);
},
mounted() {
//Test manu Systemerror
//FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto = 'ma0068@technikum-wien.at';this.$fhcAlert.handleSystemError(1);
if (this.$route.params.id) {
this.$refs.stvList.updateUrl(
ApiStv.students.uid(this.$route.params.id),
@@ -1,4 +1,5 @@
import FhcTabs from "../../Tabs.js";
import FhcHeader from "../../DetailHeader/DetailHeader.js";
import ApiStvApp from '../../../api/factory/stv/app.js';
@@ -8,7 +9,8 @@ import ApiStvApp from '../../../api/factory/stv/app.js';
export default {
name: "DetailsPrestudent",
components: {
FhcTabs
FhcTabs,
FhcHeader
},
data() {
return {
@@ -58,20 +60,29 @@ export default {
template: `
<div class="stv-details h-100 pb-3 d-flex flex-column">
<div v-if="!students?.length" class="justify-content-center d-flex h-100 align-items-center">
Bitte StudentIn auswählen!
{{$p.t('ui', 'chooseStudent')}}
</div>
<div v-else-if="configStudent && configStudents" class="d-flex flex-column h-100 pb-3">
<div class="d-flex justify-content-start align-items-center w-100 pb-3 gap-3" style="max-height:8rem">
<img v-for="student in students" :key="student.person_id" class="d-block h-100 rounded" alt="profilbild" :src="appRoot + 'cis/public/bild.php?src=person&person_id=' + student.person_id">
<div v-if="students.length == 1">
<h2 class="h4">{{students[0].titlepre}} {{students[0].vorname}} {{students[0].nachname}} {{students[0].titlepost}}</h2>
</div>
</div>
<fhc-tabs v-if="students.length == 1" ref="tabs" :modelValue="students[0]" :config="config" :default="$route.params.tab" style="flex: 1 1 0%; height: 0%" @changed="reload"></fhc-tabs>
<fhc-tabs v-else ref="tabs" :modelValue="students" :config="config" :default="$route.params.tab" style="flex: 1 1 0%; height: 0%" @changed="reload"></fhc-tabs>
<fhc-header
:headerData="students"
typeHeader="student"
>
</fhc-header>
<fhc-tabs
v-if="students.length == 1"
ref="tabs"
:useprimevue="true"
:modelValue="students[0]"
:config="config"
:default="$route.params.tab"
style="flex: 1 1 0%; height: 0%"
@changed="reload"
>
</fhc-tabs>
<fhc-tabs v-else ref="tabs" :useprimevue="true" :modelValue="students" :config="config" :default="$route.params.tab" style="flex: 1 1 0%; height: 0%" @changed="reload"></fhc-tabs>
</div>
<div v-else>
Loading...
</div>
</div>`
};
};
@@ -7,6 +7,7 @@ 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: {
@@ -78,7 +79,7 @@ export default {
{title: "prueferIn2", field: "p2_nachname", visible: false},
{title: "prueferIn3", field: "p3_nachname", visible: false},
{
title: "datum",
title: "datum",
field: "datum",
formatter: function (cell) {
const dateStr = cell.getValue();
@@ -95,7 +96,7 @@ export default {
},
{title: "uhrzeit", field: "uhrzeit"},
{
title: "freigabe",
title: "freigabe",
field: "freigabedatum",
formatter: function (cell) {
const dateStr = cell.getValue();
@@ -112,7 +113,7 @@ export default {
},
{title: "pruefungsantritt", field: "antritt_bezeichnung"},
{
title: "sponsion",
title: "sponsion",
field: "sponsion",
formatter: function (cell) {
const dateStr = cell.getValue();
@@ -167,7 +168,6 @@ export default {
layoutColumnsOnNewData: false,
height: 'auto',
minHeight: '200',
selectable: true,
index: 'abschlusspruefung_id',
persistenceID: 'stv-details-finalexam'
},
@@ -224,7 +224,7 @@ export default {
title: this.$p.t('global', 'typ')
});
cm.getColumnByField('abschlusspruefung_id').component.updateDefinition({
title: this.$p.t('ui', 'abschlusspruefung_id')
title: this.$p.t('abschlusspruefung', 'abschlusspruefung_id')
});
/*
cm.getColumnByField('actions').component.updateDefinition({
@@ -259,12 +259,14 @@ export default {
arrBeurteilungen: [],
arrAkadGrad: [],
arrNoten: [],
filteredMitarbeiter: [],
filteredPruefer: [],
abortController: {
mitarbeiter: null,
pruefer: null
},
selectedVorsitz: null,
listeFilteredMitarbeiter: [],
listeAllMitarbeiter: [],
listeAllPersons: [],
selectedPruefer1: null,
selectedPruefer2: null,
selectedPruefer3: null,
listeFilteredPersons: [],
stgInfo: { typ: '', oe_kurzbz: '' }
}
},
@@ -274,6 +276,18 @@ export default {
this.$refs.table.reloadTable();
}
this.getStudiengangByKz();
},
selectedVorsitz(newVal) {
this.formData.vorsitz = newVal?.mitarbeiter_uid || null;
},
selectedPruefer1(newVal) {
this.formData.pruefer1 = newVal?.person_id || null;
},
selectedPruefer2(newVal) {
this.formData.pruefer2 = newVal?.person_id || null;
},
selectedPruefer3(newVal) {
this.formData.pruefer3 = newVal?.person_id || null;
}
},
methods: {
@@ -293,8 +307,22 @@ export default {
actionEditAbschlusspruefung(abschlusspruefung_id) {
this.resetForm();
this.statusNew = false;
this.loadAbschlusspruefung(abschlusspruefung_id).then(() => {
//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
);
});
this.$refs.finalexamModal.show();
this.loadAbschlusspruefung(abschlusspruefung_id);
},
actionDeleteAbschlusspruefung(abschlusspruefung_id) {
this.$fhcAlert
@@ -374,7 +402,7 @@ export default {
this.formData.vorsitz = null;
this.formData.pruefungsantritt_kurzbz = null;
this.formData.abschlussbeurteilung_kurzbz = null;
this.formData.datum = null; //oder new Date();
this.formData.datum = null;
this.formData.sponsion = null;
this.formData.pruefer1 = null;
this.formData.pruefer2 = null;
@@ -382,34 +410,11 @@ export default {
this.formData.anmerkung = null;
this.formData.protokoll = null;
this.formData.note = null;
this.formData.p1 = null;
this.formData.p2 = null;
this.formData.p3 = null;
this.formData.pv = null;
},
search(event) {
if (this.abortController.mitarbeiter) {
this.abortController.mitarbeiter.abort();
}
this.abortController.mitarbeiter = new AbortController();
this.selectedVorsitz = null;
this.selectedPruefer1 = null;
this.selectedPruefer2 = null;
this.selectedPruefer3 = null;
return this.$api
.call(ApiStvAbschlusspruefung.getMitarbeiter(event.query))
.then(result => {
this.filteredMitarbeiter = result.data.retval;
});
},
searchNotAkad(event) {
if (this.abortController.pruefer) {
this.abortController.pruefer.abort();
}
this.abortController.pruefer = new AbortController();
return this.$api
.call(ApiStvAbschlusspruefung.getPruefer(event.query))
.then(result => {
this.filteredPruefer = result.data.retval;
});
},
setDefaultFormData() {
@@ -434,6 +439,22 @@ export default {
printDocument(link) {
window.open(link, '_blank');
},
filterMitarbeiter(event){
const query = event?.query?.toLowerCase()?.trim() || "";
this.listeFilteredMitarbeiter = this.listeAllMitarbeiter.filter(item => {
const label = (item.label || "").toLowerCase();
return label.includes(query);
});
},
filterPersons(event){
const query = event?.query?.toLowerCase()?.trim() || "";
this.listeFilteredPersons = this.listeAllPersons.filter(item => {
const label = (item.label || "").toLowerCase();
return label.includes(query);
});
}
},
created() {
this.$api
@@ -470,6 +491,21 @@ export default {
this.arrAkadGrad = result.data;
})
.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))
@@ -484,7 +520,7 @@ export default {
template: `
<div class="stv-details-abschlusspruefung h-100 pb-3">
<h4>{{this.$p.t('stv','tab_finalexam')}}</h4>
<div v-if="this.student.length">
<abschlusspruefung-dropdown
:showAllFormats="showAllFormats"
@@ -505,12 +541,13 @@ export default {
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
new-btn-show
:new-btn-label="this.$p.t('stv', 'tab_finalexam')"
@click:new="actionNewAbschlusspruefung"
>
</core-filter-cmpt>
<!--Modal: finalexamModal-->
<bs-modal ref="finalexamModal" dialog-class="modal-xl modal-dialog-scrollable">
<template #title>
@@ -576,87 +613,38 @@ export default {
</div>
<div class="row mb-3">
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
:label="$p.t('abschlusspruefung', 'vorsitz_header')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.vorsitz"
name="vorsitz"
:suggestions="filteredMitarbeiter"
@complete="search"
:min-length="3"
>
</form-input>
</template>
<template v-else >
<form-input
v-if= "formData.pv"
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
type="text"
name="name"
:label="$p.t('abschlusspruefung', 'vorsitz_header')"
v-model="formData.pv"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
:label="$p.t('abschlusspruefung', 'vorsitz_header')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.vorsitz"
name="vorsitz"
:suggestions="filteredMitarbeiter"
@complete="search"
:min-length="3"
>
</form-input>
</template>
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
:label="$p.t('abschlusspruefung', 'pruefer1')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer1"
name="pruefer1"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<template v-else >
<form-input
v-if= "formData.p1"
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
type="text"
name="name"
:label="$p.t('abschlusspruefung', 'pruefer1')"
v-model="formData.p1"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
:label="$p.t('abschlusspruefung', 'pruefer1')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer1"
name="pruefer1"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<form-input
type="autocomplete"
container-class="col-6 stv-details-abschlusspruefung-vorsitz"
:label="$p.t('abschlusspruefung', 'vorsitz')"
name="vorsitz"
v-model="selectedVorsitz"
optionLabel="label"
optionValue="mitarbeiter_uid"
dropdown
forceSelection
:suggestions="listeFilteredMitarbeiter"
@complete="filterMitarbeiter"
:min-length="3"
>
</form-input>
<form-input
type="autocomplete"
container-class="col-6 stv-details-abschlusspruefung-pruefer1"
:label="$p.t('abschlusspruefung', 'pruefer1')"
name="pruefer1"
v-model="selectedPruefer1"
optionLabel="label"
optionValue="person_id"
forceSelection
:suggestions="listeFilteredPersons"
@complete="filterPersons"
:min-length="3"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
container-class="col-6 stv-details-abschlusspruefung-abschlussbeurteilung_kurzbz"
:label="$p.t('abschlusspruefung', 'abschlussbeurteilung')"
@@ -673,44 +661,20 @@ export default {
{{beurteilung.bezeichnung}}
</option>
</form-input>
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
:label="$p.t('abschlusspruefung', 'pruefer2')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer2"
name="pruefer2"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<template v-else >
<form-input
v-if= "formData.p2"
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
type="text"
name="name"
:label="$p.t('abschlusspruefung', 'pruefer2')"
v-model="formData.p2"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
:label="$p.t('abschlusspruefung', 'pruefer2')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer2"
name="pruefer2"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<form-input
type="autocomplete"
container-class="col-6 stv-details-abschlusspruefung-pruefer2"
:label="$p.t('abschlusspruefung', 'pruefer2')"
name="pruefer2"
v-model="selectedPruefer2"
optionLabel="label"
optionValue="person_id"
forceSelection
:suggestions="listeFilteredPersons"
@complete="filterPersons"
:min-length="3"
>
</form-input>
</div>
<div class="row mb-3">
@@ -729,44 +693,20 @@ export default {
{{grad.titel}}
</option>
</form-input>
<template v-if="statusNew">
<form-input
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
:label="$p.t('abschlusspruefung', 'pruefer3')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer3"
name="pruefer3"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<template v-else >
<form-input
v-if= "formData.p3"
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
type="text"
name="name"
:label="$p.t('abschlusspruefung', 'pruefer3')"
v-model="formData.p3"
>
</form-input>
<form-input
v-else
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
:label="$p.t('abschlusspruefung', 'pruefer3')"
type="autocomplete"
optionLabel="mitarbeiter"
v-model="formData.pruefer3"
name="pruefer3"
:suggestions="filteredPruefer"
@complete="searchNotAkad"
:min-length="3"
>
</form-input>
</template>
<form-input
type="autocomplete"
container-class="col-6 stv-details-abschlusspruefung-pruefer3"
:label="$p.t('abschlusspruefung', 'pruefer3')"
name="pruefer3"
v-model="selectedPruefer3"
optionLabel="label"
optionValue="person_id"
forceSelection
:suggestions="listeFilteredPersons"
@complete="filterPersons"
:min-length="3"
>
</form-input>
</div>
<div class="row mb-3">
@@ -777,6 +717,7 @@ export default {
v-model="formData.datum"
auto-apply
:enable-time-picker="false"
text-input
format="dd.MM.yyyy"
name="datum"
:teleport="true"
@@ -800,6 +741,7 @@ export default {
v-model="formData.sponsion"
auto-apply
:enable-time-picker="false"
text-input
format="dd.MM.yyyy"
name="sponsion"
:teleport="true"
@@ -812,6 +754,7 @@ export default {
v-model="formData.protokoll"
name="protokoll"
:rows= 10
readonly
>
</form-input>
</div>
@@ -0,0 +1,26 @@
import AnrechnungenList from './Anrechnungen/Anrechnungen.js';
export default {
name: "TabExemptions",
components: {
AnrechnungenList
},
provide() {
return {
config: this.config
};
},
props: {
modelValue: Object,
config: Object
},
methods: {
reload() {
this.$refs.anrechnungen.$refs.table.reloadTable();
}
},
template: `
<div class="stv-details-anrechnungen h-100 d-flex flex-column">
<anrechnungen-list ref="anrechnungen" :student="modelValue"></anrechnungen-list>
</div>`
};
@@ -0,0 +1,452 @@
import {CoreFilterCmpt} from "../../../../filter/Filter.js";
import BsModal from "../../../../Bootstrap/Modal.js";
import CoreForm from "../../../../Form/Form.js";
import FormInput from "../../../../Form/Input.js";
import CoreNotiz from "../../../../Notiz/Notiz.js";
import ApiStvExemptions from "../../../../../api/factory/stv/exemptions.js";
import ApiNotizPerson from '../../../../../api/factory/notiz/person.js';
export default {
name: "ExemptionComponent",
components: {
CoreFilterCmpt,
BsModal,
CoreForm,
FormInput,
CoreNotiz
},
inject: {
$reloadList: {
from: '$reloadList',
required: true
},
config: {
from: 'config',
required: true
},
},
props: {
student: Object
},
data() {
return {
tabulatorOptions: {
ajaxURL: 'dummy',
ajaxRequestFunc: () => this.$api.call(
ApiStvExemptions.getAnrechnungen(this.student.prestudent_id)
),
ajaxResponse: (url, params, response) => response.data,
columns: [
{title: "anrechnung_id", field: "anrechnung_id", visible: false},
{title: "lehrveranstaltung_id", field: "lehrveranstaltung_id", visible: false},
{title: "Lehrveranstaltung", field: "bez_lehrveranstaltung"},
{title: "Begründung", field: "begruendung"},
{title: "lehrveranstaltung_id_kompatibel", field: "lehrveranstaltung_id_kompatibel", visible: false},
{title: "lehrveranstaltung_bez_kompatibel", field: "lehrveranstaltung_bez_kompatibel"},
{title: "status", field: "status"},
{title: "genehmigt_von", field: "genehmigt_von"},
{title: "notizen_anzahl", field: "notizen_anzahl", visible: false},
{title: "Datum", field: "insertamum",
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",
});
}
},
{
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";
if(this.config.editableAnrechnungen){
let buttonEdit = document.createElement('button');
buttonEdit.className = 'btn btn-outline-secondary btn-action';
buttonEdit.innerHTML = '<i class="fa fa-edit"></i>';
buttonEdit.title = this.$p.t('ui', 'bearbeiten');
buttonEdit.addEventListener('click', (event) =>
this.actionEditAnrechnung(cell.getData().anrechnung_id)
);
container.append(buttonEdit);
}
let 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.actionDeleteAnrechnung(cell.getData().anrechnung_id)
);
container.append(button);
let countNotizen = cell.getData().notizen_anzahl;
let buttonNotes = document.createElement('button');
buttonNotes.className = 'btn btn-outline-secondary btn-action';
if (countNotizen > 0){
buttonNotes.innerHTML = countNotizen + this.$p.t('anrechnung', 'existingNotes');
}
else {
buttonNotes.innerHTML = '+' + this.$p.t('global', 'notiz');
}
buttonNotes.title = this.$p.t('ui', 'notizHinzufuegen');
buttonNotes.addEventListener('click', (event) =>
this.addNote(cell.getData().anrechnung_id)
);
container.append(buttonNotes);
return container;
},
frozen: true
},
],
layout: 'fitDataFill',
height: '500',
index: 'anrechnung_id',
persistenceID: 'stv-details-anrechnungen'
},
tabulatorEvents: [
{
event: 'tableBuilt',
handler: async () => {
await this.$p.loadCategory(['anrechnungen', 'global', 'ui', 'lehre']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('anrechnung_id').component.updateDefinition({
title: this.$p.t('ui', 'anrechnung_id'),
});
cm.getColumnByField('lehrveranstaltung_id').component.updateDefinition({
title: this.$p.t('lehre', 'lehrveranstaltung_id'),
});
cm.getColumnByField('bez_lehrveranstaltung').component.updateDefinition({
title: this.$p.t('lehre', 'lehrveranstaltung'),
});
cm.getColumnByField('begruendung').component.updateDefinition({
title: this.$p.t('global', 'begruendung'),
});
cm.getColumnByField('lehrveranstaltung_id_kompatibel').component.updateDefinition({
title: this.$p.t('anrechnung', 'lehrveranstaltung_id_kompatibel'),
});
cm.getColumnByField('lehrveranstaltung_bez_kompatibel').component.updateDefinition({
title: this.$p.t('anrechnung', 'lehrveranstaltung_bez_kompatibel'),
});
cm.getColumnByField('status').component.updateDefinition({
title: this.$p.t('global', 'status'),
});
cm.getColumnByField('genehmigt_von').component.updateDefinition({
title: this.$p.t('anrechnung', 'genehmigtVon'),
});
cm.getColumnByField('notizen_anzahl').component.updateDefinition({
title: this.$p.t('anrechnung', 'existingNotes'),
});
cm.getColumnByField('insertamum').component.updateDefinition({
title: this.$p.t('global', 'datum'),
});
}
}
],
formData: {},
listBegruendungen: [],
listNewLehrveranstaltungen: [],
listLektoren: [],
listKompatibleLehrveranstaltungen: [],
statusNew: true,
showNotizen: false,
currentAnrechnung_id: null,
endpoint: ApiNotizPerson
}
},
watch: {
student(){
if (this.$refs.table) {
this.$refs.table.reloadTable();
}
},
},
methods: {
actionNewAnrechnung(){
this.statusNew = true;
this.$refs.anrechnungsModal.show();
},
actionEditAnrechnung(anrechnung_id){
this.resetForm();
this.statusNew = false;
this.loadAnrechnung(anrechnung_id);
this.$refs.anrechnungsModal.show();
},
addNote(anrechnung_id){
this.currentAnrechnung_id = anrechnung_id;
this.loadAnrechnung(this.currentAnrechnung_id);
this.showNotizen = true;
this.$refs.anrechnungsnotizModal.show();
},
addNewAnrechnung(){
const dataToSend = {
prestudent_id: this.student.prestudent_id,
formData: this.formData
};
return this.$refs.formExemptions
.call(ApiStvExemptions.addNewAnrechnung(dataToSend))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.$refs.anrechnungsModal.hide();
this.resetForm();
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.reload();
});
},
editAnrechnung(anrechnung_id){
const dataToSend = {
anrechnung_id: anrechnung_id,
formData: this.formData
};
return this.$refs.formExemptions
.call(ApiStvExemptions.editAnrechnung(dataToSend))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.$refs.anrechnungsModal.hide();
this.resetForm();
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.reload();
});
},
actionDeleteAnrechnung(anrechnung_id) {
this.$fhcAlert
.confirmDelete()
.then(result => result
? anrechnung_id
: Promise.reject({handled: true}))
.then(this.deleteAnrechnung)
.catch(this.$fhcAlert.handleSystemError);
},
deleteAnrechnung(anrechnung_id){
return this.$api
.call(ApiStvExemptions.deleteAnrechnung(anrechnung_id))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(() => {
this.reload();
});
},
getLvsKompatibel(){
if(this.formData.lehrveranstaltung_id) {
this.$api
.call(ApiStvExemptions.getLvsKompatibel(this.formData.lehrveranstaltung_id))
.then(result => {
this.listKompatibleLehrveranstaltungen = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
handleInput(){
if(this.formData.begruendung == 2) {
this.getLvsKompatibel();
}
},
loadAnrechnung(anrechnung_id){
return this.$api
.call(ApiStvExemptions.loadAnrechnung(anrechnung_id))
.then(result => {
this.formData = result.data;
this.getLvsKompatibel();
})
.catch(this.$fhcAlert.handleSystemError);
},
reload() {
this.$refs.table.reloadTable();
},
handleReload(){
this.reload();
},
resetForm(){
this.formData = {};
this.statusNew = true;
},
resetLvKompatibel(){
this.formData.lehrveranstaltung_id_kompatibel = null;
this.handleInput();
}
},
created() {
this.$api
.call(ApiStvExemptions.getLehrveranstaltungen(this.student.prestudent_id))
.then(result => {
this.listNewLehrveranstaltungen = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiStvExemptions.getBegruendungen())
.then(result => {
this.listBegruendungen = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiStvExemptions.getLektoren(this.student.studiengang_kz))
.then(result => {
this.listLektoren = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
template: `
<div class="stv-details-tab_exemptions h-100 pb-3">
<bs-modal ref="anrechnungsnotizModal" dialog-class="modal-dialog-scrollable modal-xl" body-class="p-0">
<template #title>
<h5>
<strong>LV {{formData.lehrveranstaltung_id}}: {{formData.bezeichnung}} | {{formData.bezeichnung_english}}
</strong>
</h5>
</template>
<div v-if="showNotizen" class="border p-3 overflow-auto" style="height: 825px;">
<core-notiz
:endpoint="endpoint"
ref="formNotes"
notiz-layout="classicFas"
typeId="anrechnung_id"
:id="currentAnrechnung_id"
show-document
show-tiny-mce
:visibleColumns="['titel','text','verfasser','bearbeiter','dokumente']"
@reload="handleReload"
>
</core-notiz>
</div>
</bs-modal>
<template v-if="config.editableAnrechnungen" >
<core-filter-cmpt
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
reload
new-btn-show
:new-btn-label="this.$p.t('lehre', 'anrechnung')"
@click:new="actionNewAnrechnung"
>
</core-filter-cmpt>
</template>
<template v-else>
<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>
</template>
<bs-modal ref="anrechnungsModal" dialog-class="modal-dialog-scrollable" >
<template #title>
<p v-if="statusNew" class="fw-bold mt-3">{{$p.t('anrechnung', 'neueAnrechnung')}}</p>
<p v-else class="fw-bold mt-3">{{$p.t('anrechnung', 'editAnrechnung')}}</p>
</template>
<core-form ref="formExemptions">
<div class="row mb-3">
<form-input
type="select"
:label="$p.t('lehre/lehrveranstaltung')"
name="lehrveranstaltung"
v-model="formData.lehrveranstaltung_id"
@change="resetLvKompatibel"
>
<option
v-for="entry in listNewLehrveranstaltungen"
:key="entry.lehrveranstaltung_id"
:value="entry.lehrveranstaltung_id"
>
{{entry.bezeichnung}} Semester {{entry.semester}} {{entry.lehrform_kurzbz}}
</option>
</form-input>
</div>
<div class="row mb-3">
<form-input
type="select"
:label="$p.t('anrechnung/begruendung')"
name="begruendung"
v-model="formData.begruendung_id"
@change="handleInput"
>
<option
v-for="entry in listBegruendungen"
:key="entry.begruendung_id"
:value="entry.begruendung_id"
>
{{entry.bezeichnung}}
</option>
</form-input>
</div>
<!--is shown when typ == kompatible LV-->
<div v-if="formData.begruendung_id == '2'" class="row mb-3">
<form-input
type="select"
label="Lehrveranstaltung Kompatibel"
name="lehrveranstaltung_id_kompatibel"
v-model="formData.lehrveranstaltung_id_kompatibel"
>
<option
v-for="entry in listKompatibleLehrveranstaltungen"
:key="entry.lehrveranstaltung_id"
:value="entry.lehrveranstaltung_id"
>
{{entry.bezeichnung}} Semester {{entry.semester}} {{entry.lehrform_kurzbz}}
</option>
</form-input>
</div>
<div class="row mb-3">
<form-input
type="select"
:label="$p.t('anrechnung/genehmigtVon')"
name="genehmigtVon"
v-model="formData.genehmigt_von"
>
<option
v-for="entry in listLektoren"
:key="entry.uid"
:value="entry.uid"
>
{{entry.nachname}} {{entry.vorname}}
</option>
</form-input>
</div>
</core-form>
<template #footer>
<button v-if="statusNew" type="button" class="btn btn-primary" @click="addNewAnrechnung">{{$p.t('ui', 'speichern')}}</button>
<button v-else type="button" class="btn btn-primary" @click="editAnrechnung(formData.anrechnung_id)">{{$p.t('ui', 'speichern')}}</button>
</template>
</bs-modal>
</div>
`
}
@@ -0,0 +1,289 @@
import {CoreFilterCmpt} from "../../../filter/Filter.js";
import FormInput from "../../../Form/Input.js";
import AkteEdit from "./Archiv/Edit.js";
export default {
components: {
CoreFilterCmpt,
FormInput,
AkteEdit
},
inject: {
defaultSemester: {
from: 'defaultSemester'
}
},
props: {
modelValue: Object,
config: {
type: Object,
default: {}
}
},
data() {
return {
loading: false,
selectedVorlage: {},
vorlagenArchiv: [],
vorlageXmlXslMappings: {
'zeugnis.rdf.php': [
'Zeugnis',
'ZeugnisEng'
],
'abschlusspruefung.rdf.php': [
'PrProtokollBakk',
'PrProtBakkEng',
'PrProtBA',
'PrProtBAEng',
'PrProtokollDipl',
'PrProtDiplEng',
'PrProtMA',
'PrProtMAEng',
'Bescheid',
'BescheidEng',
'Bakkurkunde',
'BakkurkundeEng',
'Diplomurkunde',
'DiplomurkundeEng',
],
'diplomasupplement.xml.php': [
'DiplSupplement',
'SZeugnis'
],
'studienblatt.xml.php': [
'Studienblatt',
'StudienblattEng'
],
'ausbildungsvertrag.xml.php': [
'Ausbildungsver',
'AusbVerEng'
],
'abschlussdokument_lehrgaenge.xml.php': [
'AbschlussdokumentLehrgaenge'
]
}
//studiengang_kz: false
};
},
computed: {
//~ personIds() {
//~ if (this.modelValue.person_id)
//~ return [this.modelValue.person_id];
//~ return this.modelValue.map(e => e.person_id);
//~ },
tabulatorColumns() {
const columns = [
{title: "Akte Id", field: "akte_id", visible: false},
{title: this.$p.t('stv', 'archiv_title'), field: "titel"},
{title: this.$p.t('stv', 'archiv_description'), field: "bezeichnung"},
{title: this.$p.t('stv', 'archiv_creation_date'), field: "erstelltam"},
{
title: this.$p.t('stv', 'archiv_signiert'),
field: "signiert",
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
}
},
{
title: "Selfservice",
field: "stud_selfservice",
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('stv', 'archiv_accepted_on_at'), field: "akzeptiertamum"},
{
title: this.$p.t('stv', 'archiv_gedruckt'),
field: "gedruckt",
visible: false,
formatter:"tickCross",
hozAlign:"center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>'
}
},
{
title: 'Aktionen', field: 'actions',
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
container.className = "d-flex gap-2";
let downloadButton = document.createElement('button');
downloadButton.className = 'btn btn-outline-secondary';
downloadButton.innerHTML = '<i class="fa fa-download"></i>';
downloadButton.title = this.$p.t('ui', 'downloadDok');
downloadButton.addEventListener('click', evt => {
evt.stopPropagation();
this.actionDownload(cell.getData().akte_id);
});
container.append(downloadButton);
if (this.config.showEdit)
{
let editButton = document.createElement('button');
editButton.className = 'btn btn-outline-secondary';
editButton.innerHTML = '<i class="fa fa-edit"></i>';
editButton.title = this.$p.t('ui', 'bearbeiten');
editButton.addEventListener('click', () =>
this.$refs.edit.open(cell.getData())
);
container.append(editButton);
}
let deleteButton = document.createElement('button');
deleteButton.className = 'btn btn-outline-secondary';
deleteButton.innerHTML = '<i class="fa fa-trash"></i>';
deleteButton.title = this.$p.t('ui', 'loeschen');
deleteButton.addEventListener('click', evt => {
evt.stopPropagation();
this.$fhcAlert
.confirmDelete()
.then(result => result ? {akte_id: cell.getData().akte_id, studiengang_kz: this.modelValue.studiengang_kz} : Promise.reject({handled:true}))
.then(this.$fhcApi.factory.stv.archiv.delete)
.then(() => {
//cell.getRow().delete();
this.reload();
})
.catch(this.$fhcAlert.handleSystemError);
});
container.append(deleteButton);
return container;
},
minWidth: 150, // Ensures Action-buttons will be always fully displayed
maxWidth: 150,
frozen: true
}
];
return Object.values(columns);
},
tabulatorOptions() {
return this.$fhcApi.factory.stv.archiv.tabulatorConfig({
layout:"fitDataTable",
columns: this.tabulatorColumns,
//selectable: true,
//selectableRangeMode: 'click',
index: 'akte_id',
persistenceID: 'stv-details-archiv'
}, this);
},
tabulatorEvents() {
const events = [
{
event: "rowDblClick",
handler: (e, row) => {
this.actionDownload(row.getData().akte_id);
}
}
];
return events;
}
},
watch: {
modelValue() {
this.$refs.table.reloadTable();
}
},
methods: {
reload() {
this.$refs.table.reloadTable();
},
updateData(data) {
if (!data)
return this.reload();
this.$refs.table.tabulator.updateOrAddData(data);
},
actionArchive() {
let archiveDataArr = Array.isArray(this.modelValue) ? this.modelValue : [this.modelValue];
for (let archiveData of archiveDataArr)
{
this.loading = true;
let archiveFunction =
this.selectedVorlage.signierbar
? this.$fhcApi.factory.stv.archiv.archiveSigned
: this.$fhcApi.factory.stv.archiv.archive;
archiveFunction({
xml: this.getXmlByXsl(this.selectedVorlage.vorlage_kurzbz),
xsl: this.selectedVorlage.vorlage_kurzbz,
ss: this.defaultSemester,
uid: archiveData.uid,
prestudent_id: archiveData.prestudent_id
})
.then(result => result.data)
.then(() => {
this.reload();
this.loading = false;
})
.then(() => this.$p.t('ui/gespeichert'))
.then(this.$fhcAlert.alertSuccess)
.catch(error => {
this.$fhcAlert.handleSystemError(error);
this.loading = false;
});
}
},
actionDownload(akte_id) {
window.open(
FHC_JS_DATA_STORAGE_OBJECT.app_root
+ FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/api/frontend/v1/stv/akte/download?akte_id=' + encodeURIComponent(akte_id),
'_blank'
);
},
getXmlByXsl(xsl) {
for (let xml in this.vorlageXmlXslMappings) {
let xslArr = this.vorlageXmlXslMappings[xml];
if (xslArr.includes(xsl)) return xml;
}
return null;
}
},
created() {
this.$fhcApi
.factory.stv.archiv.getArchivVorlagen()
.then(result => {this.vorlagenArchiv = result.data; this.selectedVorlage = result.data.filter(o => o.vorlage_kurzbz == 'Zeugnis')[0];})
.catch(this.$fhcAlert.handleSystemError);
},
template: `
<div class="stv-details-konto h-100 d-flex flex-column">
<core-filter-cmpt
ref="table"
table-only
:side-menu="false"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
reload
: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">
{{ vorlage.bezeichnung }}
</option>
</select>
<button
class="btn btn-primary"
@click="actionArchive()"
:disabled="loading"
>
<i v-if="loading" class="fa fa-spinner fa-spin"></i>
{{ $p.t('stv/archiv_dokument_archivieren') }}
</button>
</div>
</template>
</core-filter-cmpt>
<akte-edit ref="edit" :config="config" @saved="updateData"></akte-edit>
</div>`
};
@@ -0,0 +1,118 @@
import BsModal from "../../../../Bootstrap/Modal.js";
import CoreForm from "../../../../Form/Form.js";
import FormValidation from "../../../../Form/Validation.js";
import FormInput from "../../../../Form/Input.js";
import FormUploadDms from '../../../../Form/Upload/Dms.js';
export default {
components: {
BsModal,
CoreForm,
FormValidation,
FormInput,
FormUploadDms
},
inject: {
lists: {
from: 'lists'
}
},
props: {
config: {
type: Object,
default: {}
}
},
data() {
return {
loading: false,
//file: [],
data: {
datei: []
}
};
},
methods: {
save() {
this.$refs.form.clearValidation();
this.loading = true;
//~ const formData = new FormData();
//~ formData.append('data', JSON.stringify(this.data));
//Object.entries(this.data.anhang).forEach(([k, v]) => formData.append(k, v));
this.$refs.form
.factory.stv.archiv.update(this.data)
.then(result => {
this.$emit('saved', result.data);
this.loading = false;
this.$refs.modal.hide();
this.$fhcAlert.alertSuccess(this.$p.t('ui/gespeichert'));
})
.catch(error => {
this.$fhcAlert.handleSystemError(error);
this.loading = false;
});
},
open(data) {
this.data.datei = [];
this.data = {...this.data, ...data};
this.$refs.modal.show();
},
preventCloseOnLoading(ev) {
if (this.loading)
ev.returnValue = false;
}
},
template: `
<core-form ref="form" class="stv-details-archiv-edit" @submit.prevent="save">
<bs-modal ref="modal" @hide-bs-modal="preventCloseOnLoading">
<form-validation></form-validation>
<fieldset :disabled="loading">
<div class="mb-3">
{{ data.titel }} ({{ data.bezeichnung }})
</div>
<form-input
v-model="data.akte_id"
name="akte_id"
:label="$p.t('stv/archiv_akte_id')"
disabled
>
</form-input>
<div class="position-relative">
<label for="text" class="form-label col-sm-2">{{ $p.t('stv/archiv_new_file') }}</label>
<!--Upload Component-->
<FormUploadDms ref="upload" id="inhalt" v-model="data.datei"></FormUploadDms>
</div>
<div class="mt-3">
<form-input
container-class="form-check"
type="checkbox"
name="signiert"
:label="$p.t('stv/archiv_signiert')"
v-model="data.signiert"
>
</form-input>
<form-input
container-class="form-check"
type="checkbox"
name="stud_selfservice"
:label="'Selfservice'"
v-model="data.stud_selfservice"
>
</form-input>
</div>
</fieldset>
<template #title>
{{ $p.t('stv/archiv_title_edit', data) }}
</template>
<template #footer>
<button type="submit" class="btn btn-primary" :disabled="loading">
<i v-if="loading" class="fa fa-spinner fa-spin"></i>
{{ $p.t('ui/speichern') }}
</button>
</template>
</bs-modal>
</core-form>`
};
@@ -0,0 +1,26 @@
import AdmissionDates from "./Aufnahmetermine/Aufnahmetermine.js";
import HeaderPlacement from "./Aufnahmetermine/HeaderReihungstest.js";
export default {
name: "TabAdmissionDates",
components: {
AdmissionDates,
HeaderPlacement
},
provide() {
return {
config: this.config
};
},
props: {
modelValue: Object,
},
data(){
return {}
},
template: `
<div class="stv-details-mobility h-30 d-flex flex-column">
<header-placement :student="modelValue"></header-placement>
<admission-dates ref="tbl_admission_dates" :student="modelValue"></admission-dates>
</div>`
};

Some files were not shown because too many files have changed in this diff Show More