Merge branch 'master' into feature-18571/EntwicklungsteamBisMeldung

This commit is contained in:
Andreas Österreicher
2024-03-25 13:12:35 +01:00
73 changed files with 10654 additions and 614 deletions
@@ -116,6 +116,96 @@ class Leitung extends FHC_Controller
$this->outputJsonSuccess($studierendenantrag_id);
}
public function pauseAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
[
'isEntitledToPauseAntrag',
[$this->antraglib, 'isEntitledToPauseAntrag']
],
[
'antragCanBeManualPaused',
[$this->antraglib, 'antragCanBeManualPaused']
]
],
[
'isEntitledToPauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'antragCanBeManualPaused' => $this->p->t(
'studierendenantrag',
'error_not_pauseable',
['id' => $this->input->post('studierendenantrag_id')]
)
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->pauseAntrag($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function unpauseAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
[
'isEntitledToUnpauseAntrag',
[$this->antraglib, 'isEntitledToUnpauseAntrag']
],
[
'antragCanBeManualUnpaused',
[$this->antraglib, 'antragCanBeManualUnpaused']
]
],
[
'isEntitledToUnpauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'antragCanBeManualUnpaused' => $this->p->t(
'studierendenantrag',
'error_not_paused',
['id' => $this->input->post('studierendenantrag_id')]
)
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->unpauseAntrag($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function objectAntrag()
{
$this->load->library('form_validation');
@@ -86,7 +86,7 @@ class Unterbrechung extends FHC_Controller
$data = getData($result);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($data->studiensemester_kurzbz);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($prestudent_id, null);
$this->outputJsonSuccess($data);
}
@@ -136,7 +136,7 @@ class Unterbrechung extends FHC_Controller
$datum_wiedereinstieg = $this->input->post('datum_wiedereinstieg');
$dms_id = null;
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id);
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester, $datum_wiedereinstieg);
if (isError($result)) {
return $this->outputJsonError(['db' => getError($result)]);
}
@@ -161,6 +161,18 @@ class Wiederholung extends FHC_Controller
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]);
}
elseif ($result == -1)
{
$result = $this->PrestudentstatusModel->getLastStatus($prestudent_id);
if (isError($result))
return $this->outputJsonError(['db' => getError($result)]);
if (!hasData($result))
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_prestudentstatus', [
'prestudent_id' => $prestudent_id
])]);
if (!in_array(current(getData($result))->status_kurzbz, $this->config->item('antrag_prestudentstatus_whitelist')))
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]);
}
elseif ($result == -2)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]);
@@ -241,7 +253,8 @@ class Wiederholung extends FHC_Controller
if (!hasData($result))
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id]));
$antrag = current(getData($result));
if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED && $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED)
if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED
&& $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED)
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_locked'));
}
+61 -12
View File
@@ -19,6 +19,8 @@ class AntragJob extends JOB_Controller
// Loads SanchoHelper
$this->load->helper('hlp_sancho_helper');
$this->load->library('AntragLib');
// Load Model
$this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel');
$this->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel');
@@ -172,7 +174,16 @@ class AntragJob extends JOB_Controller
$cc = $leitung['Details']->email;
// NOTE(chris): Sancho mail
if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $to, 'Anträge - Aktion(en) erforderlich', DEFAULT_SANCHO_HEADER_IMG, DEFAULT_SANCHO_FOOTER_IMG, '', $cc))
if (sendSanchoMail(
"Sancho_Mail_Antrag_Stgl",
$data,
$to,
'Anträge - Aktion(en) erforderlich',
DEFAULT_SANCHO_HEADER_IMG,
DEFAULT_SANCHO_FOOTER_IMG,
'',
$cc
))
$count++;
}
@@ -316,12 +327,52 @@ class AntragJob extends JOB_Controller
} else {
$deregisterStatus = getData($result);
$result = $this->antraglib->pauseAntrag(
$prestudent->studierendenantrag_id,
Studierendenantragstatus_model::INSERTVON_DEREGISTERED
);
if (isError($result))
$this->logError(getError($result));
$result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, '', $insertvon);
if (isError($result)) {
$this->StudierendenantragstatusModel->delete($deregisterStatus);
$this->logError(getError($result));
} else {
$count++;
$datum_kp = new DateTime($prestudent->datum);
$dataMail = array(
'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname),
'vorname' => $prestudent->vorname,
'nachname' => $prestudent->nachname,
'pers_kz'=> $prestudent->matrikelnr,
'stg' => $prestudent->bezeichnung,
'lvbezeichnung' => $prestudent->lvbezeichnung,
'datum_kp' => $datum_kp->format('d.m.Y'),
'studiensemester'=> $prestudent->studiensemester_kurzbz,
'Orgform'=> $prestudent->orgform,
'prestudent_id' => $prestudent->prestudent_id,
'fristablauf' => $dateDeadline->format('d.m.Y')
);
$email = $this->StudentModel->getEmailFH($this->StudentModel->getUID($prestudent->prestudent_id));
// Mail to Student
if (!sendSanchoMail('Sancho_Mail_Antrag_W_DL_Stud', $dataMail, $email, 'Wiederholung: Frist abgelaufen')) {
$this->logWarning("Failed to send Notification to " . $email);
}
$result = $this->StudiengangModel->load($prestudent->studiengang_kz);
if (!hasData($result)) {
$this->logWarning('No Studiengang found');
continue;
}
$studiengang = current(getData($result));
$email = $studiengang->email;
// Mail to Assistenz
if (!sendSanchoMail('Sancho_Mail_Antrag_W_DL_Assist', $dataMail, $email, 'Wiederholung: Frist abgelaufen')) {
$this->logWarning("Failed to send Notification to " . $email);
}
}
}
}
@@ -339,8 +390,6 @@ class AntragJob extends JOB_Controller
{
$this->logInfo('Start Job handleAbmeldungenStglDeadline');
$this->load->library('AntragLib');
$insertvon = $this->config->item('antrag_job_systemuser');
if (!$insertvon) {
$this->logError('Config "antrag_job_systemuser" nicht gesetzt');
@@ -364,7 +413,10 @@ class AntragJob extends JOB_Controller
$this->StudierendenantragModel->addSelect('s.insertamum');
$this->StudierendenantragModel->addSelect('s.insertvon');
$this->StudierendenantragModel->db->where_in('public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)', $this->config->item('antrag_prestudentstatus_whitelist'));
$this->StudierendenantragModel->db->where_in(
'public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)',
$this->config->item('antrag_prestudentstatus_whitelist')
);
$result = $this->StudierendenantragModel->getWithLastStatusWhere([
'typ' => Studierendenantrag_model::TYP_ABMELDUNG_STGL,
@@ -393,6 +445,10 @@ class AntragJob extends JOB_Controller
else {
$deregisterStatus = getData($result);
$result = $this->antraglib->pauseAntrag($antrag->studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED);
if (isError($result))
$this->logError(getError($result));
$result = $this->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
@@ -438,7 +494,6 @@ class AntragJob extends JOB_Controller
$this->logWarning("Failed to send Notification to " . $email);
}
}
}
}
$this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher");
@@ -569,12 +624,6 @@ class AntragJob extends JOB_Controller
}
}
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$result = $this->PrestudentstatusModel->loadLastWithStgDetails($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz);
if (hasData($result)) {
$ausbildungssemester = current(getData($result))->semester;
}
$dataMail = array(
'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname),
'vorname' => $prestudent->vorname,
@@ -591,7 +640,7 @@ class AntragJob extends JOB_Controller
'fristablauf' => $fristende->format('d.m.Y'),
'pre_wiederholer_sem' => $next_sem,
'wiederholer_sem' => $sem_after_next_sem,
'sem' => $ausbildungssemester
'sem' => $prestudent->ausbildungssemester
);
// NOTE(chris): Sancho mail
@@ -144,7 +144,7 @@ class MigrateSalary extends CLI_Controller
// Zeile zu Ende - Ende Datum setzen wenn nicht für alle Monate ein Eintrag vorhanden ist
if($monat < count($monate) && isset($gehaltsarr[$gehaltsindex]))
$gehaltsarr[$gehaltsindex]['ende'] == $monate[$monat-1];
$gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1];
}
$this->_saveGehalt($lastuser, $gehaltsarr);
@@ -162,6 +162,7 @@ class MigrateSalary extends CLI_Controller
foreach($gehaltsarr as $row_gehalt)
{
//var_dump($row_gehalt);
$auszahlungen = 14;
$dvid = '';
$vbsid = '';
@@ -171,7 +172,9 @@ class MigrateSalary extends CLI_Controller
//DV und VBS Ermitteln
$dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $row_gehalt['beginn']);
if (!hasData($dv))
// Wenn keiner gefunden wird oder mit Monatsersteln nur ein externer gefunden wird, weitersuchen ob im Monat noch ein
// "richtiger" Vertrag startet
if (!hasData($dv) || getData($dv)[0]->vertragsart_kurzbz='externerLehrender')
{
$date = new DateTime($row_gehalt['beginn']);
$date->modify('last day of this month');
@@ -179,7 +182,7 @@ class MigrateSalary extends CLI_Controller
// Wenn mit Monatsersten kein DV gefunden wird, wird stattdessen mit Monatsletzten gesucht um DVs zu finden
// für Personen die erst später im Monat in ihr DV einsteigen
$dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $last_day_this_month);
$dv = $this->DienstverhaeltnisModel->getDVByPersonUIDOverlapping($uid, $this->OE_DEFAULT, $row_gehalt['beginn'], $last_day_this_month);
if (!hasData($dv))
{
@@ -189,21 +192,39 @@ class MigrateSalary extends CLI_Controller
}
else
{
$resultdata = getData($dv);
foreach($resultdata as $dvdata)
{
// Externer DV wird in Monatsmitte zu echten DV - daher weitersuchen bei externenDVs da
// diese sowieso kein Gehalt zugeordnet haben
if($dvdata->vertragsart_kurzbz != 'externerLehrender')
{
$dvid = $dvdata->dienstverhaeltnis_id;
// Gehaltsstart wird auf den Start des DV korrigiert wenn nicht der Monatserste
$row_gehalt['beginn'] = getData($dv)[0]->von;
// nur wenn das Beginndatum vor dem DV-Start liegt da sonst das Datum korrigiert wird
// wenn der Vertragsbestandteil wechselt
if($row_gehalt['beginn'] < $dvdata->von)
$row_gehalt['beginn'] = $dvdata->von;
break;
}
}
}
}
else
{
$resultdata = getData($dv);
if (count($resultdata) == 1)
$dvid = $resultdata[0]->dienstverhaeltnis_id;
}
$resultdata = getData($dv);
if (count($resultdata) !== 1)
if ($dvid == '')
{
echo "Kein oder Mehrere DVs gefunden -> ROLLBACK";
echo "Kein oder mehrere DVs gefunden -> ROLLBACK";
$failed = true;
break;
}
$dvid = $resultdata[0]->dienstverhaeltnis_id;
$allin = $this->_isAllIn($dvid, $row_gehalt['beginn']);
$db = new DB_Model();
@@ -213,10 +234,11 @@ class MigrateSalary extends CLI_Controller
if (hasData($resultVBS))
{
$vbsid = getData($resultVBS)[0]->vertragsbestandteil_id;
$vbsbis = getData($resultVBS)[0]->bis;
}
else
{
echo "Vertragsbestandteil wurde nicht gefunden -> ROLLBACK";
echo "Vertragsbestandteil fuer $uid DV $dvid wurde nicht gefunden mit Beginn ".$row_gehalt['beginn']."-> ROLLBACK";
$failed = true;
break;
}
@@ -356,10 +378,18 @@ class MigrateSalary extends CLI_Controller
$date->modify('last day of this month');
$last_day_this_month = $date->format('Y-m-d');
// TODO: wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist,
// Wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist,
// dann muss hier das Ende Datum des DV stehen bzw das Ende
// oder das Ende des VBS falls die Person in der Monatsmitte Stunden wechselt
$data['bis'] = $last_day_this_month;
// Wenn der Vertragsbestandteil endet bevor das Gehalt endet, dann wir das Gehaltsende auf VBS Ende gesetzt
//echo "Ende des VBS: $vbsbis Ende des Gehalt: ".$data['bis'];
if ($vbsbis != '' && $vbsbis < $data['bis'])
{
$data['bis'] = $vbsbis;
//echo "Gehalt auf vbs ende gesetzt";
}
}
$ret = $this->GehaltsbestandteilModel->insert($data,
+255
View File
@@ -0,0 +1,255 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Controller using JSON
*/
class FHCAPI_Controller extends FHC_Controller
{
/**
* Response status
* @see https://github.com/omniti-labs/jsend
*/
const STATUS_SUCCESS = 'success';
const STATUS_FAIL = 'fail';
const STATUS_ERROR = 'error';
/**
* Error types
*/
const ERROR_TYPE_PHP = 'php'; // TODO(chris): php types from severity?
const ERROR_TYPE_EXCEPTION = 'exception';
const ERROR_TYPE_GENERAL = 'general';
const ERROR_TYPE_404 = '404';
const ERROR_TYPE_DB = 'db';
const ERROR_TYPE_VALIDATION = 'validation';
/**
* Return Object
*
* @var array
*/
private $returnObj = [];
/**
* Constructor
*
* @param array $requiredPermissions
* @return void
*/
public function __construct($requiredPermissions = [])
{
if (is_cli())
show_404();
parent::__construct();
$this->config->set_item('error_views_path', VIEWPATH.'errors'.DIRECTORY_SEPARATOR.'json'.DIRECTORY_SEPARATOR);
global $g_result;
$g_result = $this;
ob_start(function ($content) {
$http_response_code = http_response_code();
// NOTE(chris): For security reasons 404 will be displayed the same everywhere
if ($http_response_code == REST_Controller::HTTP_NOT_FOUND)
return $content;
header('Content-Type: application/json; charset=utf-8');
if (!isset($this->returnObj['meta']) || !isset($this->returnObj['meta']['status'])) {
switch ($http_response_code) {
case 200:
$this->setStatus(self::STATUS_SUCCESS);
break;
case 400:
$this->setStatus(self::STATUS_FAIL);
break;
default:
$this->setStatus(self::STATUS_ERROR);
break;
}
}
#$this->returnObj['test'] = implode('/n', headers_list());
return json_encode($this->returnObj);
});
// Load libraries
$this->load->library('AuthLib');
$this->load->library('PermissionLib');
// Checks if the caller is allowed to access to this content
$this->_isAllowed($requiredPermissions);
// 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 = array_merge($_POST, json_decode($_POST['_jsondata'], true));
unset($_POST['_jsondata']);
}
}
// ---------------------------------------------------------------
// Handle Output object
// ---------------------------------------------------------------
/**
* @param array $data
* @param string $type (optional)
* @return void
*/
public function addError($data, $type = null)
{
if (!isset($this->returnObj['errors']))
$this->returnObj['errors'] = [];
$error = [];
if (is_array($data)) {
if ($type == self::ERROR_TYPE_VALIDATION)
$error['messages'] = $data;
else
$error = $data;
} else {
$error['message'] = $data;
}
if ($type)
$error['type'] = $type;
$this->returnObj['errors'][] = $error;
}
/**
* @param mixed $data
* @return void
*/
public function setData($data)
{
$this->returnObj['data'] = $data;
}
/**
* @param string $status
* @return void
*/
public function setStatus($status)
{
if (!isset($this->returnObj['meta']))
$this->returnObj['meta'] = [];
$this->returnObj['meta']['status'] = $status;
}
// ---------------------------------------------------------------
// Handle Output object - Shortcut functions
// ---------------------------------------------------------------
/**
* @param array $errors
* @return void
*/
protected function terminateWithValidationErrors($errors)
{
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
$this->addError($errors, self::ERROR_TYPE_VALIDATION);
$this->setStatus(self::STATUS_FAIL);
exit(EXIT_ERROR);
}
/**
* @param mixed $data (optional)
* @return void
*/
protected function terminateWithSuccess($data = null)
{
$this->setData($data);
$this->setStatus(self::STATUS_SUCCESS);
exit;
}
/**
* @param array $error
* @param string $type (optional)
* @return void
*/
protected function terminateWithError($error, $type = null)
{
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->addError($error, $type);
$this->setStatus(self::STATUS_ERROR);
exit;
}
/**
* @param stdclass $result
* @param string $errortype
* @return void
*/
protected function checkForErrors($result, $errortype = self::ERROR_TYPE_GENERAL)
{
// TODO(chris): IMPLEMENT!
if (isError($result)) {
$this->terminateWithError(getError($result), $errortype);
}
return $result->retval;
}
// TODO(chris): complete list
// ---------------------------------------------------------------
// Security
// ---------------------------------------------------------------
/**
* Checks if the caller is allowed to access to this content with the given permissions
* If it is not allowed will set the HTTP header with code 401
* Wrapper for permissionlib->isEntitled
*
* @param array $requiredPermissions
* @return void
*/
protected function _isAllowed($requiredPermissions)
{
// Checks if this user is entitled to access to this content
if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method))
{
$this->output->set_status_header(isLogged() ? REST_Controller::HTTP_FORBIDDEN : REST_Controller::HTTP_UNAUTHORIZED);
$this->addError([
'message' => 'You are not allowed to access to this content',
'controller' => $this->router->class,
'method' => $this->router->method,
'required_permissions' => $this->_rpsToString($requiredPermissions, $this->router->method)
]);
exit; // immediately terminate the execution
}
}
/**
* Converts an array of permissions to a string that contains them as a comma separated list
* Ex: "<permission 1>, <permission 2>, <permission 3>"
*
* @param array $requiredPermissions
* @param string $method
* @return void
*/
protected function _rpsToString($requiredPermissions, $method)
{
if (!isset($requiredPermissions[$method]))
return '';
if (!is_array($requiredPermissions[$method]))
return $requiredPermissions[$method];
return implode(', ', $requiredPermissions[$method]);
}
}
+301 -105
View File
@@ -62,9 +62,11 @@ class AntragLib
'insertvon' => $insertvon
]);
// NOTE(chris): remove "preabbrecher" statusgrund for Stgl-Abmeldungen if set
// NOTE(chris): remove "preabbrecher" statusgrund and paused stati for sibling Anträge for Stgl-Abmeldungen if set
$res = $this->_ci->StudierendenantragModel->load($antrag_id);
if (hasData($res) && current(getData($res))->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) {
$this->unpauseAntrag($antrag_id, Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL);
$this->_ci->PrestudentstatusModel->addSelect('tbl_status_grund.statusgrund_kurzbz');
$res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail(current(getData($res))->prestudent_id, '', 'Student');
if (hasData($res) && current(getData($res))->statusgrund_kurzbz == 'preabbrecher') {
@@ -83,6 +85,67 @@ class AntragLib
return $result;
}
/**
* @param integer $antrag_id
* @param string $insertvon
*
* @return stdClass
*/
public function pauseAntrag($antrag_id, $insertvon)
{
switch ($insertvon) {
case Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL:
$result = $this->_ci->StudierendenantragstatusModel->stopAntraegeForAbmeldungStgl($antrag_id);
break;
case Studierendenantragstatus_model::INSERTVON_DEREGISTERED:
$result = $this->_ci->StudierendenantragstatusModel->stopAntraegeForAbbruchBy($antrag_id);
break;
default:
$result = $this->_ci->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE,
'insertvon' => $insertvon
]);
break;
}
return $result;
}
/**
* @param integer $antrag_id
* @param string $insertvon
*
* @return stdClass
*/
public function unpauseAntrag($antrag_id, $insertvon)
{
if ($insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED)
return error($this->p->t('studierendenantrag', 'error_no_right'));
if ($insertvon == Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL) {
return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id);
}
// NOTE(chris): get last status that is not pause
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum');
$this->_ci->StudierendenantragstatusModel->addLimit(1);
$result = $this->_ci->StudierendenantragstatusModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz !=' => Studierendenantragstatus_model::STATUS_PAUSE
]);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_antragstatus', ['id' => $antrag_id]));
$status = current(getData($result));
$result = $this->_ci->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz' => $status->studierendenantrag_statustyp_kurzbz,
'insertvon' => $insertvon
]);
return $result;
}
/**
* NOTE(chris): permissions & verification must be handled outside
*
@@ -190,6 +253,10 @@ class AntragLib
$vorlage ='Sancho_Mail_Antrag_A_Approve';
$subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_A_Approve');
$result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED);
if (isError($result))
$errors[] = getError($result);
$result = $this->_ci->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
@@ -208,7 +275,13 @@ class AntragLib
$data = [
'student' => $this->_ci->p->t('person', 'studentIn'),
'sem' => $antrag->studiensemester_kurzbz,
'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' . $antrag->typ . '.xml.php&xsl=Antrag' . $antrag->typ . '&id=' . $antrag->studierendenantrag_id . '&output=pdf')
'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' .
$antrag->typ .
'.xml.php&xsl=Antrag' .
$antrag->typ .
'&id=' .
$antrag->studierendenantrag_id .
'&output=pdf')
];
if (hasData($result)) {
$person = current(getData($result));
@@ -229,6 +302,10 @@ class AntragLib
sendSanchoMail($vorlage, $data, $prestudent_status->email, $subject);
}
} else { // ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL)
$result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL);
if (isError($result))
$errors[] = getError($result);
$result = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id, '', 'Student');
if (isError($result))
{
@@ -340,6 +417,10 @@ class AntragLib
if (isError($result))
return $result;
else {
$result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED);
// NOTE(chris): here we should have error handling but at the
// moment there is no way to notify the user for "soft" errors
$result = $this->_ci->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
@@ -471,7 +552,6 @@ class AntragLib
'<br>Details:<br>' .
$error_msg;
} else {
$data = getData($data);
$result = $this->_ci->StudierendenantragstatusModel->insert([
@@ -582,7 +662,11 @@ class AntragLib
'nachname' => $data['person']->nachname,
'UID' => $data['UID'],
'sem' => $resultAntrag->studiensemester_kurzbz,
'linkPdf' => base_url('content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' . $studierendenantrag_id . '&output=pdf'),
'linkPdf' => base_url(
'content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' .
$studierendenantrag_id .
'&output=pdf'
),
'insertvon' => $approvedBy
],
$data['prestudent_status']->email,
@@ -699,7 +783,9 @@ class AntragLib
'Orgform' => $data['prestudent_status']->orgform_kurzbz,
'prestudent_id' => $data['prestudent_status']->prestudent_id,
'abmeldungLink' => site_url('lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id),
'abmeldungLinkCIS' => CIS_ROOT . 'index.ci.php/lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id
'abmeldungLinkCIS' => CIS_ROOT .
'index.ci.php/lehre/Studierendenantrag/abmeldung/' .
$data['prestudent_status']->prestudent_id
],
$data['email'],
$this->_ci->p->t('studierendenantrag', 'mail_subject_U_Reject')
@@ -862,7 +948,9 @@ class AntragLib
$result = $this->_ci->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz' => $repeat ? Studierendenantragstatus_model::STATUS_CREATED : Studierendenantragstatus_model::STATUS_PASS,
'studierendenantrag_statustyp_kurzbz' => $repeat
? Studierendenantragstatus_model::STATUS_CREATED
: Studierendenantragstatus_model::STATUS_PASS,
'insertvon' => $insertvon
]);
@@ -878,8 +966,7 @@ class AntragLib
$email = $prestudent_status->email;
// NOTE(chris): Sancho mail
$lvzuweisungLink = site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id);
if( defined('VILESCI_ROOT') )
{
if (defined('VILESCI_ROOT')) {
$lvzuweisungLink = VILESCI_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id;
}
sendSanchoMail(
@@ -1062,7 +1149,11 @@ class AntragLib
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_stdsem', ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz]));
return error($this->_ci->p->t(
'studierendenantrag',
'error_no_stdsem',
['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz]
));
$asem = current(getData($result));
foreach ($stdsems as $sem) {
@@ -1117,7 +1208,6 @@ class AntragLib
$lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung;
$lv->antrag_zugelassen = true;
}
}
} else {
$lvsA = null;
@@ -1252,7 +1342,19 @@ class AntragLib
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist_abmeldung'))) {
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED
], [
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE
], [
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
@@ -1302,7 +1404,7 @@ class AntragLib
* retval -2 means other Antrag pending;
* retval -3 means in blacklist stg
*/
public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null)
public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null, $datum_wiedereinstieg = null)
{
$result = $this->_ci->PrestudentModel->load($prestudent_id);
if (isError($result))
@@ -1320,18 +1422,10 @@ class AntragLib
if (!hasData($result))
return success(0);
$result = current(getData($result));
$prestudent_stdsem = $result->studiensemester_kurzbz;
$datumStatus = $result->datum;
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))) {
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))
&& $result->status_kurzbz != 'Unterbrecher') {
return success(0);
}
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere(['prestudent_id' => $prestudent_id]);
@@ -1339,6 +1433,7 @@ class AntragLib
return $result;
if (!hasData($result))
return success(1);
$result = getData($result);
foreach ($result as $antrag)
{
@@ -1349,11 +1444,11 @@ class AntragLib
elseif($antrag->status == Studierendenantragstatus_model::STATUS_APPROVED && $antrag->datum > $datumStatus)
return success(-2);
}
if ($studiensemester_kurzbz && $antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG)
if ($antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG)
{
// NOTE(chris): check if this is an old or canceled one
if ($antrag->studiensemester_kurzbz == $studiensemester_kurzbz && $antrag->status != Studierendenantragstatus_model::STATUS_CANCELLED)
return success(-1);
// NOTE(chris): Ignore canceled ones
if ($antrag->status == Studierendenantragstatus_model::STATUS_CANCELLED)
continue;
}
if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG)
{
@@ -1362,6 +1457,17 @@ class AntragLib
}
}
if (!$studiensemester_kurzbz) {
$sems = $this->getSemesterForUnterbrechung($prestudent_id, $prestudent_stdsem);
if (!count(array_filter($sems, function ($item) {
return !$item['disabled'];
})))
return success(-1);
} else {
if ($this->_ci->StudierendenantragModel->hasRunningUnterbrechungBetween($prestudent_id, $studiensemester_kurzbz, $datum_wiedereinstieg))
return success(-1);
}
return success(1);
}
@@ -1406,7 +1512,27 @@ class AntragLib
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE
]);
if (isError($result))
return $result;
@@ -1457,15 +1583,16 @@ class AntragLib
return success($result);
}
/**
* Gets details for the latest Antrag of one or more types
*
* @param integer $prestudent_id
* @param array|string $typ
*
* @return \stdClass
*/
public function getDetailsForLastAntrag($prestudent_id, $typ = null)
{
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($prestudent_id);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $prestudent_id]));
$resultDetails = current(getData($result));
$where = [
'prestudent_id' => $prestudent_id
];
@@ -1494,21 +1621,20 @@ class AntragLib
'prestudent_id' => $prestudent_id
]));
$resultDetails->status = $resultAntrag->status;
$resultDetails->statustyp = $resultAntrag->statustyp;
$resultDetails->grund = $resultAntrag->grund;
$resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id;
$resultDetails->typ = $resultAntrag->typ;
$resultDetails->datum = $resultAntrag->datum;
$resultDetails->studiensemester_kurzbz = $resultAntrag->studiensemester_kurzbz;
return success($resultDetails);
return $this->addDetailsToAntrag($resultAntrag);
}
/**
* Gets details for a specific Antrag
*
* @param integer $studierendenantrag_id
*
* @return \stdClass
*/
public function getDetailsForAntrag($studierendenantrag_id)
{
$where = [
'studierendenantrag_id' => $studierendenantrag_id
's.studierendenantrag_id' => $studierendenantrag_id
];
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where);
@@ -1519,76 +1645,99 @@ class AntragLib
return error($this->_ci->p->t('studierendenantrag', "error_no_antrag_found", ['id' => $studierendenantrag_id]));
$resultAntrag = current(getData($result));
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id, $resultAntrag->studiensemester_kurzbz);
return $this->addDetailsToAntrag($resultAntrag);
}
/**
* Helper function for getDetailsForAntrag and getDetailsForLastAntrag
*
* @param \stdClass $antrag
*
* @return \stdClass
*/
protected function addDetailsToAntrag($antrag)
{
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
$antrag->insertamum
);
if (isError($result))
return $result;
if (!hasData($result)) {
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id);
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails(
$antrag->prestudent_id,
null,
$antrag->insertamum
);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', $resultAntrag));
}
$resultDetails = current(getData($result));
$resultDetails->status = $resultAntrag->status;
$resultDetails->statustyp = $resultAntrag->statustyp;
$resultDetails->grund = $resultAntrag->grund;
$resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id;
$resultDetails->typ = $resultAntrag->typ;
$resultDetails->dms_id = $resultAntrag->dms_id;
$resultDetails->datum_wiedereinstieg = $resultAntrag->datum_wiedereinstieg;
return success($resultDetails);
}
public function getSemesterForUnterbrechung($studiensemester_kurzbz)
{
return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', $antrag));
$tmp = current(getData($result));
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$semester = [];
$result = $this->_ci->StudiensemesterModel->getNextFrom($studiensemester_kurzbz);
if (!hasData($result))
return $semester;
$nextSem = current(getData($result));
$semester[0] = [
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'wiedereinstieg' => [$nextSem]
];
$result = $this->_ci->StudiensemesterModel->getNextFrom($nextSem->studiensemester_kurzbz);
if (!hasData($result))
return $semester;
$currSemester = current(getData($result));
$followingSemester = [$currSemester];
$max = $this->_ci->config->item('unterbrecher_semester_max_length');
if(!$max || $max < 1)
$max = 2;
for ($i = 1; $i < $max; $i++) {
$result = $this->_ci->StudiensemesterModel->getNextFrom($currSemester->studiensemester_kurzbz);
if (!hasData($result))
break;
$currSemester = current(getData($result));
$followingSemester[] = $currSemester;
$res = $this->_ci->StudiensemesterModel->load($antrag->studiensemester_kurzbz);
if (hasData($res))
$tmp->studienjahr_kurzbz = current(getData($res))->studienjahr_kurzbz;
else
$tmp->studienjahr_kurzbz = '';
// NOTE(chris): the semester might not be correct on this fallback so we disable it
$tmp->semester = '';
}
$semester[1] = [
'studiensemester_kurzbz' => $nextSem->studiensemester_kurzbz,
'wiedereinstieg' => $followingSemester
$result = current(getData($result));
$result->status = $antrag->status;
$result->statustyp = $antrag->statustyp;
$result->status_insertvon = $antrag->status_insertvon;
$result->grund = $antrag->grund;
$result->studierendenantrag_id = $antrag->studierendenantrag_id;
$result->typ = $antrag->typ;
$result->datum = $antrag->datum;
$result->dms_id = $antrag->dms_id;
$result->datum_wiedereinstieg = $antrag->datum_wiedereinstieg;
return success($result);
}
/**
* Rearrange the free semester slots for a new Unterbrechung
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz
*
* @return array
*/
public function getSemesterForUnterbrechung($prestudent_id, $studiensemester_kurzbz)
{
$result = $this->_ci->StudierendenantragModel->getFreeSlotsForUnterbrechung($prestudent_id, $studiensemester_kurzbz);
if (isError($result))
return [];
$result = getData($result);
if (!$result)
return [];
return array_reduce($result, function ($carry, $item) {
if (!isset($carry[$item->von]))
$carry[$item->von] = [
'studienjahr_kurzbz' => $item->studienjahr_kurzbz,
'studiensemester_kurzbz' => $item->von,
'wiedereinstieg' => [],
'disabled' => true
];
//remove last Semester of the array
array_pop($followingSemester);
$carry[$item->von]['wiedereinstieg'][] = [
'studiensemester_kurzbz' => $item->bis,
'start' => $item->ende,
'disabled' => (boolean)$item->studierendenantrag_id
];
foreach ($followingSemester as $sem)
$semester[0]['wiedereinstieg'][] = $sem;
if ($carry[$item->von]['disabled'] && !$item->studierendenantrag_id) {
$carry[$item->von]['disabled'] = false;
}
return $semester;
return $carry;
}, []);
return $result;
}
public function getAktivePrestudentenInStgs($studiengaenge, $query)
@@ -1664,7 +1813,6 @@ class AntragLib
return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_antrag', ['id' => $antrag_id]));
$stg = current($result);
$studiengang_kz = $stg->studiengang_kz;
$semester = $stg->ausbildungssemester;
$result = $this->_ci->StudierendenantragModel->load($antrag_id);
@@ -1726,9 +1874,7 @@ class AntragLib
$result = $this->getLvsForAntrag($antrag_id);
if (hasData($result)) {
$lvs = getData($result);
$repeat_last = false;
if (isset($lvs['repeat_last'])) {
$repeat_last = true;
unset($lvs['repeat_last']);
$vorlage .= '_Lst';
}
@@ -1895,6 +2041,26 @@ class AntragLib
return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag');
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function isEntitledToPauseAntrag($antrag_id)
{
return ($this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe') || $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag'));
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function isEntitledToUnpauseAntrag($antrag_id)
{
return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag');
}
/**
* @param integer $antrag_id
*
@@ -1935,6 +2101,36 @@ class AntragLib
return $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe');
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function antragCanBeManualPaused($antrag_id)
{
$this->_ci->StudierendenantragModel->db->where_not_in('campus.get_status_studierendenantrag(studierendenantrag_id)', [
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_PAUSE
]);
$result = $this->_ci->StudierendenantragModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG
]);
return hasData($result);
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function antragCanBeManualUnpaused($antrag_id)
{
return $this->_ci->StudierendenantragModel->isManuallyPaused($antrag_id);
}
/**
* @param integer $antrag_id
* @param string|array $status
@@ -267,7 +267,7 @@ class Prestudentstatus_model extends DB_Model
return $this->loadWhere($where);
}
public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null)
public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null, $max_date = null)
{
$this->load->config('studierendenantrag');
@@ -304,7 +304,8 @@ class Prestudentstatus_model extends DB_Model
$this->addLimit(1);
$this->db->where_in($this->dbTable . '.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist'));
if ($max_date)
$this->db->where($this->dbTable . '.insertamum <', $max_date);
$whereArr = [
$this->dbTable . '.prestudent_id' => $prestudent_id,
@@ -87,7 +87,13 @@ class Pruefung_model extends DB_Model
$this->addJoin('public.tbl_person pers', 'person_id');
$this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz');
$this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus pss',
'pss.prestudent_id=ps.prestudent_id
AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz
AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz');
$this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false);
@@ -167,6 +173,7 @@ class Pruefung_model extends DB_Model
$this->addSelect('a.studierendenantrag_id');
$this->addSelect('a.typ');
$this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status');
$this->addSelect('pss.ausbildungssemester');
$this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
@@ -175,12 +182,20 @@ class Pruefung_model extends DB_Model
$this->addJoin('public.tbl_person pers', 'person_id');
$this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz');
$this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus pss',
'pss.prestudent_id=ps.prestudent_id
AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz
AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz');
$this->addJoin('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG), 'LEFT');
$this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist'));
$this->addJoin(
'campus.tbl_studierendenantrag a',
'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG),
'LEFT'
);
$this->db->where("g.aktiv", true);
@@ -238,6 +253,8 @@ class Pruefung_model extends DB_Model
$this->db->where("b.aktiv", true);
$this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist'));
if (is_array($status)) {
if (in_array(null, $status)) {
$status = array_filter($status);
@@ -46,6 +46,8 @@ class Studierendenantrag_model extends DB_Model
$this->addSelect('datum_wiedereinstieg');
$this->addSelect($this->dbTable . '.typ');
$this->addSelect('st.studierendenantrag_statustyp_kurzbz as status');
$this->addSelect('s.insertvon as status_insertvon');
$this->addSelect('s.insertamum as status_insertamum');
$this->addSelect('dms_id');
$this->addSelect('st.bezeichnung[(' . $sql . ')] as statustyp');
@@ -54,7 +56,13 @@ class Studierendenantrag_model extends DB_Model
$this->addJoin('public.tbl_person', 'person_id');
$this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz');
$this->addJoin('public.tbl_studiensemester ss', 'studiensemester_kurzbz');
$this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus ps',
'ps.prestudent_id=p.prestudent_id
AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz
AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)');
$this->addJoin(
@@ -76,7 +84,9 @@ class Studierendenantrag_model extends DB_Model
public function loadActiveForStudiengaenge($studiengaenge)
{
// NOTE(chris): get language before changing things in the global db object because getUserLanguage() might use it and it should not have been tampered with
// NOTE(chris): get language before changing things in the global
// db object because getUserLanguage() might use it and it should
// not have been tampered with
$sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1";
$this->db->group_start();
@@ -85,7 +95,8 @@ class Studierendenantrag_model extends DB_Model
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_REJECTED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED,
Studierendenantragstatus_model::STATUS_DEREGISTERED
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_PAUSE
]);
$this->db->or_group_start();
$this->db->where('s.studierendenantrag_statustyp_kurzbz', Studierendenantragstatus_model::STATUS_APPROVED);
@@ -133,12 +144,18 @@ class Studierendenantrag_model extends DB_Model
$lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage());
$this->addSelect('*');
$this->addSelect('campus.get_status_studierendenantrag(studierendenantrag_id) status');
$this->addSelect($this->dbTable . '.grund AS grund');
$this->addSelect('s.studierendenantrag_statustyp_kurzbz status');
$this->addSelect('s.insertvon status_insertvon');
$this->addSelect('t.bezeichnung[(' . $lang . ')] statustyp');
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id'
);
$this->addJoin(
'campus.tbl_studierendenantrag_statustyp t',
'campus.get_status_studierendenantrag(studierendenantrag_id)=t.studierendenantrag_statustyp_kurzbz'
's.studierendenantrag_statustyp_kurzbz=t.studierendenantrag_statustyp_kurzbz'
);
if ($types && is_array($types)) {
@@ -168,7 +185,11 @@ class Studierendenantrag_model extends DB_Model
$this->addJoin(
'public.tbl_prestudentstatus s',
$this->dbTable . '.prestudent_id=s.prestudent_id AND ' . $this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz'
$this->dbTable . '.prestudent_id=s.prestudent_id
AND ' .
$this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz
AND ' .
$this->dbTable . '.insertamum > s.insertamum'
);
$this->addJoin('public.tbl_prestudent p', $this->dbTable . '.prestudent_id=p.prestudent_id');
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
@@ -180,8 +201,6 @@ class Studierendenantrag_model extends DB_Model
$this->addLimit(1);
$this->db->where_in('s.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist'));
return $this->loadWhere([
$this->pk => $antrag_id
]);
@@ -233,20 +252,45 @@ class Studierendenantrag_model extends DB_Model
$this->addSelect($this->dbTable . '.datum_wiedereinstieg');
$this->addSelect($this->dbTable . '.grund');
$this->addSelect($this->dbTable . '.dms_id');
$this->addSelect("(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " . $this->dbTable . ".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved", false);
$this->addSelect('s.insertvon AS status_insertvon');
$this->addSelect(
"(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " .
$this->dbTable .
".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved",
false
);
$this->addJoin('public.tbl_prestudent p', 'prestudent_id', 'RIGHT');
$this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz');
$this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' . $this->dbTable . '.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' . $this->dbTable . '.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus ps',
'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' .
$this->dbTable .
'.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' .
$this->dbTable .
'.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)');
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id',
'LEFT'
);
$this->addJoin(
'campus.tbl_studierendenantrag_statustyp st',
'campus.get_status_studierendenantrag(studierendenantrag_id)=st.studierendenantrag_statustyp_kurzbz',
's.studierendenantrag_statustyp_kurzbz=st.studierendenantrag_statustyp_kurzbz',
'LEFT'
);
$this->db->where("(SELECT status_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=p.prestudent_id AND status_kurzbz='Student' LIMIT 1) IS NOT NULL", null, false);
$this->db->where("(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus
WHERE prestudent_id=p.prestudent_id
AND status_kurzbz='Student'
LIMIT 1
) IS NOT NULL", null, false);
return $this->loadWhere([
@@ -287,4 +331,144 @@ class Studierendenantrag_model extends DB_Model
return $this->loadWhere($where);
}
/**
* Checks if the Prestudent has an active Unterbrechung between
* the start of the given semester and the given enddate.
* If the enddate is omitted the end of the given semester is used.
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz
* @param string $enddate (optional)
*
* @return boolean
*/
public function hasRunningUnterbrechungBetween($prestudent_id, $studiensemester, $enddate = null)
{
$start = '(SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=' . $this->db->escape($studiensemester) . ')';
$end = $enddate
? $this->db->escape($enddate)
: '(SELECT ende FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=' . $this->db->escape($studiensemester) . ')';
$this->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$this->db->where([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id) !=' => Studierendenantragstatus_model::STATUS_CANCELLED,
'start < ' . $end => null,
'datum_wiedereinstieg > ' . $start => null,
]);
return (boolean)$this->db->count_all_results($this->dbTable);
}
/**
* Gets free semester slots for a new Unterbrechung.
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz (optional)
*
* @return stdClass
*/
public function getFreeSlotsForUnterbrechung($prestudent_id, $studiensemester = null)
{
$max_starters = 2;
$max_length = max(
2,
(integer)$this->config->item('unterbrecher_semester_max_length')
);
$subquery = '';
if ($studiensemester)
$subquery = 'SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=?';
else
$subquery = 'SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=public.get_stdsem_prestudent (?, null)';
$sql = "WITH numbered_sems AS (
SELECT
a.studienjahr_kurzbz AS studienjahr_kurzbz,
a.studiensemester_kurzbz AS von,
b.studiensemester_kurzbz AS bis,
a.start AS start,
b.start AS ende,
ROW_NUMBER() OVER (
PARTITION BY a.studiensemester_kurzbz
ORDER BY b.start
) AS row_number
FROM public.tbl_studiensemester a
LEFT JOIN public.tbl_studiensemester b ON (b.start > a.ende)
),
last_sems AS (
SELECT *
FROM numbered_sems
WHERE numbered_sems.row_number <= ?
)
SELECT s.von, s.bis, s.start, s.ende, studierendenantrag_id, studienjahr_kurzbz
FROM last_sems s
LEFT JOIN (
SELECT studierendenantrag_id, start, datum_wiedereinstieg AS ende
FROM campus.tbl_studierendenantrag
LEFT JOIN public.tbl_studiensemester USING(studiensemester_kurzbz)
WHERE typ=?
AND campus.get_status_studierendenantrag(studierendenantrag_id) != ?
AND prestudent_id=?
) a ON (s.start < a.ende AND s.ende > a.start)
WHERE s.start >= (" . $subquery . ")
ORDER BY s.start, s.ende
LIMIT ?;";
return $this->execQuery($sql, [
$max_length,
self::TYP_UNTERBRECHUNG,
Studierendenantragstatus_model::STATUS_CANCELLED,
$prestudent_id,
$studiensemester ?: $prestudent_id,
$max_length * $max_starters
]);
}
/**
* Returns if an Antrag is manually paused
*
* @param integer $antrag_id
*
* @return boolean
*/
public function isManuallyPaused($antrag_id)
{
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id'
);
$this->db->where([
's.studierendenantrag_id' => $antrag_id,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE
]);
$this->db->group_start();
$this->db->where_not_in('s.insertvon', [
Studierendenantragstatus_model::INSERTVON_DEREGISTERED,
Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL
]);
$this->db->or_group_start();
$this->db->where('s.insertvon', Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL);
$this->db->where('1 !=', '(
SELECT COUNT(*)%2
FROM campus.tbl_studierendenantrag_status i
WHERE i.studierendenantrag_id = s.studierendenantrag_id
AND i.insertamum > (
SELECT ii.insertamum
FROM campus.tbl_studierendenantrag_status ii
WHERE ii.studierendenantrag_id = s.studierendenantrag_id
AND ii.insertvon <> ' . $this->escape(Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL) . '
ORDER BY ii.insertamum DESC
LIMIT 1
)
)', false);
$this->db->group_end();
$this->db->group_end();
return hasData($this->load());
}
}
@@ -15,6 +15,10 @@ class Studierendenantragstatus_model extends DB_Model
const STATUS_OBJECTED = 'Beeinsprucht';
const STATUS_OBJECTION_DENIED = 'EinspruchAbgelehnt';
const STATUS_DEREGISTERED = 'Abgemeldet';
const STATUS_PAUSE = 'Pause';
const INSERTVON_ABMELDUNGSTGL = "AbmeldungStgl";
const INSERTVON_DEREGISTERED = "Studienabbruch";
/**
* Constructor
@@ -49,4 +53,157 @@ class Studierendenantragstatus_model extends DB_Model
return $this->loadWhere($where);
}
public function stopAntraegeForAbmeldungStgl($antrag_id)
{
$sql = 'INSERT INTO campus.tbl_studierendenantrag_status
(studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum)
SELECT studierendenantrag_id, ?, ?, (
SELECT insertamum
FROM campus.tbl_studierendenantrag_status
WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?)
)
FROM campus.tbl_studierendenantrag
WHERE prestudent_id = (
SELECT prestudent_id
FROM campus.tbl_studierendenantrag
WHERE studierendenantrag_id = ?
)
AND studierendenantrag_id <> ?
AND (
(
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ?
)
)';
return $this->execQuery($sql, [
self::STATUS_PAUSE,
self::INSERTVON_ABMELDUNGSTGL,
$antrag_id,
$antrag_id,
$antrag_id,
Studierendenantrag_model::TYP_ABMELDUNG,
[
Studierendenantragstatus_model::STATUS_CREATED
],
Studierendenantrag_model::TYP_UNTERBRECHUNG,
[
Studierendenantragstatus_model::STATUS_CREATED
],
Studierendenantrag_model::TYP_WIEDERHOLUNG,
[
Studierendenantragstatus_model::STATUS_REQUESTSENT_1,
Studierendenantragstatus_model::STATUS_REQUESTSENT_2,
Studierendenantragstatus_model::STATUS_CREATED,
Studierendenantragstatus_model::STATUS_LVSASSIGNED,
Studierendenantragstatus_model::STATUS_PAUSE
],
]);
}
public function resumeAntraegeForAbmeldungStgl($antrag_id)
{
$sql = 'INSERT INTO campus.tbl_studierendenantrag_status
(studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum)
SELECT studierendenantrag_id, (
SELECT studierendenantrag_statustyp_kurzbz
FROM campus.tbl_studierendenantrag_status s
WHERE s.studierendenantrag_id=a.studierendenantrag_id
AND campus.get_status_id_studierendenantrag(a.studierendenantrag_id) <> studierendenantrag_status_id
ORDER BY insertamum DESC
LIMIT 1
), ?, (
SELECT insertamum
FROM campus.tbl_studierendenantrag_status
WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?)
)
FROM campus.tbl_studierendenantrag a
WHERE prestudent_id = (
SELECT prestudent_id
FROM campus.tbl_studierendenantrag
WHERE studierendenantrag_id = ?
)
AND typ <> ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) = ?
';
return $this->execQuery($sql, [
self::INSERTVON_ABMELDUNGSTGL,
$antrag_id,
$antrag_id,
Studierendenantrag_model::TYP_ABMELDUNG_STGL,
Studierendenantragstatus_model::STATUS_PAUSE
]);
}
public function stopAntraegeForAbbruchBy($antrag_id)
{
$sql = 'INSERT INTO campus.tbl_studierendenantrag_status
(studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum)
SELECT studierendenantrag_id, ?, ?, (
SELECT insertamum
FROM campus.tbl_studierendenantrag_status
WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?)
)
FROM campus.tbl_studierendenantrag
WHERE prestudent_id = (
SELECT prestudent_id
FROM campus.tbl_studierendenantrag
WHERE studierendenantrag_id = ?
)
AND studierendenantrag_id <> ?
AND (
(
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
)
)';
return $this->execQuery($sql, [
self::STATUS_PAUSE,
self::INSERTVON_DEREGISTERED,
$antrag_id,
$antrag_id,
$antrag_id,
Studierendenantrag_model::TYP_ABMELDUNG,
[
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_CANCELLED
],
Studierendenantrag_model::TYP_UNTERBRECHUNG,
[
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_CANCELLED,
Studierendenantragstatus_model::STATUS_REMINDERSENT,
Studierendenantragstatus_model::STATUS_REJECTED
],
Studierendenantrag_model::TYP_ABMELDUNG_STGL,
[
Studierendenantragstatus_model::STATUS_CANCELLED,
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED
],
Studierendenantrag_model::TYP_WIEDERHOLUNG,
[
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_APPROVED
],
]);
}
}
@@ -173,4 +173,55 @@ EOSQL;
return false;
}
public function getDVByPersonUIDOverlapping($uid, $oe_kurzbz=null, $beginn=null, $ende=null)
{
$result = null;
$qry = "
SELECT
dv.dienstverhaeltnis_id,
tbl_benutzer.uid,
tbl_mitarbeiter.personalnummer,
tbl_mitarbeiter.kurzbz,
tbl_mitarbeiter.lektor,
tbl_mitarbeiter.fixangestellt,
tbl_person.person_id,
tbl_benutzer.alias,
org.oe_kurzbz,
org.bezeichnung oe_bezeichnung,
dv.von,
dv.bis,
dv.vertragsart_kurzbz,
dv.updateamum,
dv.updatevon
FROM tbl_mitarbeiter
JOIN tbl_benutzer ON tbl_mitarbeiter.mitarbeiter_uid::text = tbl_benutzer.uid::text
JOIN tbl_person USING (person_id)
JOIN hr.tbl_dienstverhaeltnis dv ON(tbl_benutzer.uid::text = dv.mitarbeiter_uid::text)
JOIN public.tbl_organisationseinheit org USING(oe_kurzbz)
WHERE tbl_benutzer.uid=?";
$data = array($uid);
if(!is_null($oe_kurzbz))
{
$qry.=" AND oe_kurzbz=?";
$data[] = $oe_kurzbz;
}
if (!is_null($beginn) && !is_null($ende))
{
$qry.=" AND (?,?) OVERLAPS (dv.von, COALESCE(dv.bis, '2999-12-31'))";
$data[] = $beginn;
$data[] = $ende;
}
$qry .="
ORDER BY dv.von desc
";
return $this->execQuery($qry, $data);
}
}
@@ -0,0 +1,65 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// NOTE(chris): For security reasons 404 will be displayed the same everywhere
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>404 Page Not Found</title>
<style type="text/css">
::selection { background-color: #E13300; color: white; }
::-moz-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
a {
color: #003399;
background-color: transparent;
font-weight: normal;
}
h1 {
color: #444;
background-color: transparent;
border-bottom: 1px solid #D0D0D0;
font-size: 19px;
font-weight: normal;
margin: 0 0 14px 0;
padding: 14px 15px 10px 15px;
}
code {
font-family: Consolas, Monaco, Courier New, Courier, monospace;
font-size: 12px;
background-color: #f9f9f9;
border: 1px solid #D0D0D0;
color: #002166;
display: block;
margin: 14px 0 14px 0;
padding: 12px 10px 12px 10px;
}
#container {
margin: 10px;
border: 1px solid #D0D0D0;
box-shadow: 0 0 8px #D0D0D0;
}
p {
margin: 12px 15px 12px 15px;
}
</style>
</head>
<body>
<div id="container">
<h1><?php echo $heading; ?></h1>
<?php echo $message; ?>
</div>
</body>
</html>
@@ -0,0 +1,49 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
// NOTE(chris): remove p tags from CI_Exceptions::show_error() function
$msg = substr($message, 3);
$msg = substr($msg, 0, -4);
$msg = explode('</p><p>', $msg);
$msgs = [];
$error = [
'heading' => $heading
];
/** NOTE(chris): extract Error Number and SQL
* @see: DB_driver.php:692
*/
if (substr(current($msg), 0, 14) == 'Error Number: ') {
$code = substr(array_shift($msg), 14);
if ($code)
$error['code'] = (int)$code;
$msgs[] = array_shift($msg);
$error['sql'] = array_shift($msg);
}
/** NOTE(chris): extract Line Number and Filename
* @see: DB_driver.php:1782
* @see: DB_driver.php:1783
*/
if (count($msg) >= 2) {
if (substr(end($msg), 0, 13) == 'Line Number: ' && substr(prev($msg), 0, 10) == 'Filename: ') {
$error['line'] = (int)substr(array_pop($msg), 13);
$error['filename'] = substr(array_pop($msg), 10);
}
}
foreach ($msg as $m)
$msgs[] = $m;
if (count($msgs) == 1)
$error['message'] = current($msgs);
else
$error['messages'] = $msgs;
$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_DB);
$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR);
@@ -0,0 +1,27 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
$error = [
'message' => $message,
'class' => get_class($exception),
'filename' => $exception->getFile(),
'line' => $exception->getLine()
];
if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true) {
$error['backtrace'] = [];
foreach (debug_backtrace() as $err) {
if (isset($err['file']) && strpos($err['file'], realpath(BASEPATH)) !== 0) {
$error['backtrace'][] = [
'file' => $err['file'],
'line' => $err['line'],
'function' => $err['function']
];
}
}
}
$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_EXCEPTION);
$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR);
@@ -0,0 +1,20 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
// NOTE(chris): remove p tags from CI_Exceptions::show_error() function
$msg = substr($message, 3);
$msg = substr($msg, 0, -4);
$msg = explode('</p><p>', $msg);
$error = [
'heading' => $heading
];
if (count($msg) == 1)
$error['message'] = current($msg);
else
$error['messages'] = $msg;
$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_GENERAL);
$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR);
@@ -0,0 +1,31 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
$error = [
'message' => $message,
'severity' => $severity,
'filename' => $filepath,
'line' => $line
];
if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true) {
$error['backtrace'] = [];
foreach (debug_backtrace() as $err) {
if (isset($err['file']) && strpos($err['file'], realpath(BASEPATH)) !== 0) {
$error['backtrace'][] = [
'file' => $err['file'],
'line' => $err['line'],
'function' => $err['function']
];
}
}
}
// TODO(chris): change type with severity
$g_result->addError($error, 'php');
if (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity) {
$g_result->setStatus('error');
}
+2 -2
View File
@@ -31,9 +31,9 @@ $this->load->view(
<div class="fhc-container row">
<div class="col-sm-8 mb-3">
<studierendenantrag-antrag
prestudent-id="<?= $prestudent_id; ?>"
:prestudent-id="<?= $prestudent_id; ?>"
antrag-type="<?= $antrag_type; ?>"
studierendenantrag-id="<?= $studierendenantrag_id; ?>"
:studierendenantrag-id="<?= $studierendenantrag_id ?: 'undefined'; ?>"
v-model:info-array="infoArray"
v-model:status-msg="status.msg"
v-model:status-severity="status.severity"
+101 -12
View File
@@ -38,7 +38,10 @@ $this->load->view(
<div class="alert alert-secondary">
<p><?= $this->p->t('studierendenantrag', 'calltoaction_' . $type); ?></p>
<hr>
<a href="<?= site_url('lehre/Studierendenantrag/' . strtolower($type) . '/' . $prestudent_id); ?>" class="btn btn-outline-secondary">
<a
href="<?= site_url('lehre/Studierendenantrag/' . strtolower($type) . '/' . $prestudent_id); ?>"
class="btn btn-outline-secondary"
>
<i class="fa fa-plus"></i> <?= $this->p->t('studierendenantrag', 'antrag_typ_' . $type); ?>
</a>
</div>
@@ -63,7 +66,16 @@ $this->load->view(
<tr>
<td><?= $antrag->studierendenantrag_id; ?></td>
<td><?= $this->p->t('studierendenantrag', 'antrag_typ_' . $antrag->typ); ?></td>
<td><?= $antrag->status_bezeichnung; ?></td>
<td>
<?=
(
$antrag->status == Studierendenantragstatus_model::STATUS_PAUSE
&& $antrag->status_insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED
)
? $this->p->t('studierendenantrag', 'status_stop')
: $antrag->status_bezeichnung;
?>
</td>
<td><?= $antrag->studiensemester_kurzbz; ?></td>
<td><?= (new DateTime($antrag->datum))->format('d.m.Y'); ?></td>
<td><?= $antrag->datum_wiedereinstieg ? (new DateTime($antrag->datum_wiedereinstieg))->format('d.m.Y') : ''; ?></td>
@@ -74,15 +86,32 @@ $this->load->view(
</a>
<!-- Modal -->
<div class="modal fade" id="modalgrund<?= $antrag->studierendenantrag_id; ?>" tabindex="-1" aria-labelledby="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>" aria-hidden="true">
<div
class="modal fade"
id="modalgrund<?= $antrag->studierendenantrag_id; ?>"
tabindex="-1"
aria-labelledby="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>"><?= $this->p->t('studierendenantrag', 'antrag_grund'); ?></h5>
<h5
class="modal-title"
id="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>"
>
<?= $this->p->t('studierendenantrag', 'antrag_grund'); ?>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<textarea class="form-control" style="width: 100%; height: 250px;" readonly><?= $antrag->grund; ?></textarea>
<textarea
class="form-control"
style="width: 100%; height: 250px;"
readonly
>
<?= $antrag->grund; ?>
</textarea>
</div>
</div>
</div>
@@ -100,18 +129,78 @@ $this->load->view(
<?php } ?>
</td>
<td>
<a href="<?= site_url('lehre/Studierendenantrag/' . strtolower($antrag->typ) . '/' . $antrag->prestudent_id . '/' . $antrag->studierendenantrag_id); ?>"><i class="fa-solid fa-pen" title="<?= $this->p->t('studierendenantrag', 'btn_edit'); ?>"></i></a>
<?php if ($antrag->typ != Studierendenantrag_model::TYP_WIEDERHOLUNG && in_array($antrag->status, [
<a
href="<?= site_url('lehre/Studierendenantrag/' .
strtolower($antrag->typ) .
'/' .
$antrag->prestudent_id .
'/' .
$antrag->studierendenantrag_id); ?>"
>
<i class="fa-solid fa-pen" title="<?= $this->p->t('studierendenantrag', 'btn_edit'); ?>"></i>
</a>
<?php
$allowed = [];
switch ($antrag->typ) {
case Studierendenantrag_model::TYP_ABMELDUNG:
$allowed = [
Studierendenantragstatus_model::STATUS_APPROVED
];
break;
case Studierendenantrag_model::TYP_ABMELDUNG_STGL:
$allowed = [
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_OBJECTED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED,
Studierendenantragstatus_model::STATUS_DEREGISTERED
];
break;
case Studierendenantrag_model::TYP_UNTERBRECHUNG:
$allowed = [
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_REMINDERSENT
])) { ?>
<a class="ms-2" target="_blank" href="<?= base_url('cis/private/pdfExport.php?xml=Antrag' . $antrag->typ . '.xml.php&xsl=Antrag' . $antrag->typ . '&id=' . $antrag->studierendenantrag_id . '&uid=' . getAuthUID()); ?>"><i class="fa-solid fa-download" title="<?= $this->p->t('studierendenantrag', 'btn_download_antrag'); ?>"></i></a>
];
break;
case Studierendenantrag_model::TYP_WIEDERHOLUNG:
$allowed = [
Studierendenantragstatus_model::STATUS_DEREGISTERED
];
break;
}
if (in_array($antrag->status, $allowed)) { ?>
<a
class="ms-2"
target="_blank"
href="<?= base_url('cis/private/pdfExport.php?xml=Antrag' .
$antrag->typ .
'.xml.php&xsl=Antrag' .
$antrag->typ .
'&id=' .
$antrag->studierendenantrag_id .
'&uid=' .
getAuthUID()); ?>"
>
<i
class="fa-solid fa-download"
title="<?= $this->p->t('studierendenantrag', 'btn_download_antrag'); ?>"
>
</i>
</a>
<?php } ?>
<?php if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG && $antrag->status == Studierendenantragstatus_model::STATUS_APPROVED) { ?>
<a class="ms-2" href="#modallv<?= $antrag->studierendenantrag_id; ?>" data-bs-toggle="modal"><?= $this->p->t('studierendenantrag', 'btn_show_lvs'); ?></a>
<lv-popup id="modallv<?= $antrag->studierendenantrag_id; ?>" antrag-id = "<?= $antrag->studierendenantrag_id; ?>">
<?php if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG
&& $antrag->status == Studierendenantragstatus_model::STATUS_APPROVED
) { ?>
<a
class="ms-2"
href="#modallv<?= $antrag->studierendenantrag_id; ?>"
data-bs-toggle="modal"
>
<?= $this->p->t('studierendenantrag', 'btn_show_lvs'); ?>
</a>
<lv-popup
id="modallv<?= $antrag->studierendenantrag_id; ?>"
antrag-id = "<?= $antrag->studierendenantrag_id; ?>"
>
<?= $this->p->t('studierendenantrag', 'my_lvs'); ?>
</lv-popup>
<?php } ?>
+14 -5
View File
@@ -114,12 +114,15 @@ else
$format_highlight->setFgColor(15);
$format_highlight->setBorder(1);
$format_highlight->setBorderColor('white');
$format_highlight->setAlign('left');
$format_highlight->setNumFormat(49);
$format_highlightright=& $workbook->addFormat();
$format_highlightright->setFgColor(15);
$format_highlightright->setBorder(1);
$format_highlightright->setBorderColor('white');
$format_highlightright->setAlign('right');
$format_highlightright->setNumFormat(49);
$format_highlightright_date=& $workbook->addFormat();
$format_highlightright_date->setFgColor(15);
@@ -318,17 +321,23 @@ else
$worksheet->write($lines,1,$elem->uid);
$worksheet->write($lines,2,$elem->nachname.$inc);
$worksheet->write($lines,3,$elem->vorname);
if( NULL !== $elem->wahlname )
{
//wenn Wahlname vorhanden überschreibt dieser den Vornamen
$worksheet->write($lines,3,$elem->wahlname);
$worksheet->write($lines,4,'="'.$elem->semester.$elem->verband.$elem->gruppe.'"');
$worksheet->write($lines,5,'="'.trim($elem->matrikelnr).'"',$format_highlight);
}
else
{
$worksheet->write($lines,3,$elem->vorname);
}
$worksheet->write($lines,4,$elem->semester.$elem->verband.$elem->gruppe);
$worksheet->write($lines,5,trim($elem->matrikelnr),$format_highlight);
$worksheet->write($lines,6, $note, $format_highlightright);
// Nachprüfung
if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2)
{
$worksheet->write($lines,8, '="'.trim($elem->matrikelnr).'"', $format_highlight);
$worksheet->write($lines,8, trim($elem->matrikelnr), $format_highlight);
$pr = new Pruefung();
$pr->getPruefungen($elem->uid, "Termin2", $lvid, $sem);
$output2 = $pr->result;
@@ -349,7 +358,7 @@ else
// Nachprüfung
if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3)
{
$worksheet->write($lines,12, '="'.trim($elem->matrikelnr).'"', $format_highlight);
$worksheet->write($lines,12, trim($elem->matrikelnr), $format_highlight);
$pr = new Pruefung();
$pr->getPruefungen($elem->uid, "Termin3", $lvid, $sem);
$output3 = $pr->result;
+10 -1
View File
@@ -283,7 +283,7 @@ define('FAS_DOPPELTE_BUCHUNGSTYPEN_CHECK', serialize(
'StudiengebuehrRestzahlung' => array('StudiengebuehrErhoeht', 'Studiengebuehr', 'StudiengebuehrRestzahlung'),
'OEH' => array('OEH')
))
));
);
// Spezialnoten die am Zeunigs und Diplomasupplement ignoriert werden
define('ZEUGNISNOTE_NICHT_ANZEIGEN',serialize(array('iar', 'nz')));
@@ -295,4 +295,13 @@ define ('DEFAULT_LEHRMODUS','regulaer');
//Echter Dienstvertrag
define ('DEFAULT_ECHTER_DIENSTVERTRAG',[103,110]);
//Buchungstypen die fix auf eine bestimmte Kostenstelle gebucht werden sollen
//Buchungstyp => Studiengang_kz
define('FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE', serialize(
array(
'Test_1' => 0,
'Test_2' => 2
)
));
?>
+16
View File
@@ -141,7 +141,9 @@ foreach($addon_obj->result as $addon)
<command id="menu-dokumente-accountinfoblatt:command" oncommand="PrintAccountInfoBlatt(event);"/>
<command id="menu-dokumente-zutrittskarte:command" oncommand="PrintZutrittskarte();"/>
<command id="menu-dokumente-antrag-abmeldung:command" oncommand="StudentPrintAntragAbmeldung(event);"/>
<command id="menu-dokumente-antrag-abmeldungstgl:command" oncommand="StudentPrintAntragAbmeldungStgl(event);"/>
<command id="menu-dokumente-antrag-unterbrechung:command" oncommand="StudentPrintAntragUnterbrechung(event);"/>
<command id="menu-dokumente-antrag-wiederholung:command" oncommand="StudentPrintAntragWiederholung(event);"/>
<command id="menu-dokumente-studienblatt:command" oncommand="PrintStudienblatt(event);"/>
<command id="menu-dokumente-studienblatt_englisch:command" oncommand="PrintStudienblattEnglisch(event);"/>
<command id="menu-dokumente-pruefungsprotokoll:command" oncommand="StudentAbschlusspruefungPrintPruefungsprotokollMultiple(event,'de');"/>
@@ -518,6 +520,13 @@ foreach($addon_obj->result as $addon)
command = "menu-dokumente-antrag-abmeldung:command"
accesskey = "&menu-dokumente-antrag-abmeldung.accesskey;"
/>
<menuitem
id = "menu-dokumente-antrag-abmeldungstgl"
key = "menu-dokumente-antrag-abmeldungstgl:key"
label = "&menu-dokumente-antrag-abmeldungstgl.label;"
command = "menu-dokumente-antrag-abmeldungstgl:command"
accesskey = "&menu-dokumente-antrag-abmeldungstgl.accesskey;"
/>
<menuitem
id = "menu-dokumente-antrag-unterbrechung"
key = "menu-dokumente-antrag-unterbrechung:key"
@@ -525,6 +534,13 @@ foreach($addon_obj->result as $addon)
command = "menu-dokumente-antrag-unterbrechung:command"
accesskey = "&menu-dokumente-antrag-unterbrechung.accesskey;"
/>
<menuitem
id = "menu-dokumente-antrag-wiederholung"
key = "menu-dokumente-antrag-wiederholung:key"
label = "&menu-dokumente-antrag-wiederholung.label;"
command = "menu-dokumente-antrag-wiederholung:command"
accesskey = "&menu-dokumente-antrag-wiederholung.accesskey;"
/>
</menupopup>
</menu>
<menuseparator/>
+4 -1
View File
@@ -2584,13 +2584,16 @@ if(!$error)
}
else
{
if(defined('FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE') && isset(unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$_POST['buchungstyp_kurzbz']]))
$kostenstelle = unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$_POST['buchungstyp_kurzbz']];
foreach ($person_ids as $person_id)
{
if($person_id!='')
{
$buchung = new konto();
$buchung->person_id = $person_id;
$buchung->studiengang_kz = $_POST['studiengang_kz'];
$buchung->studiengang_kz = isset($kostenstelle) ? $kostenstelle : $_POST['studiengang_kz'];
$buchung->studiensemester_kurzbz = $_POST['studiensemester_kurzbz'];
$buchung->buchungsnr_verweis='';
$buchung->betrag = $_POST['betrag'];
+96
View File
@@ -6225,6 +6225,54 @@ function StudentPrintAntragAbmeldung(event)
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragAbmeldung.xml.php&xsl=AntragAbmeldung&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragAbmeldung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
function StudentPrintAntragAbmeldungStgl(event)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var tree = document.getElementById('student-tree');
if (tree.currentIndex==-1)
return alert('Bitte eine/n Studierende/n auswaehlen');
//Uids aller markierten Studenten holen
var start = new Object();
var end = new Object();
var numRanges = tree.view.selection.getRangeCount();
var prestudent_id= '';
var student_uid= '';
for (var t = 0; t < numRanges; t++)
{
tree.view.selection.getRangeAt(t,start,end);
for (var v = start.value; v <= end.value; v++)
{
var col = tree.columns ? tree.columns["student-treecol-prestudent_id"] : "student-treecol-prestudent_id";
var prestudentId=tree.view.getCellText(v,col);
prestudent_id += ';'+prestudentId;
col = tree.columns ? tree.columns["student-treecol-uid"] : "student-treecol-uid";
var uid=tree.view.getCellText(v,col);
student_uid += ';'+uid;
}
}
if (event.shiftKey)
{
var output='odt';
}
else if (event.ctrlKey)
{
var output='doc';
}
else
{
var output='pdf';
}
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragAbmeldungStgl.xml.php&xsl=AntragAbmeldungStgl&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragAbmeldung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
function StudentPrintAntragUnterbrechung(event)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
@@ -6273,6 +6321,54 @@ function StudentPrintAntragUnterbrechung(event)
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragUnterbrechung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
function StudentPrintAntragWiederholung(event)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var tree = document.getElementById('student-tree');
if (tree.currentIndex==-1)
return alert('Bitte eine/n Studierende/n auswaehlen');
//Uids aller markierten Studenten holen
var start = new Object();
var end = new Object();
var numRanges = tree.view.selection.getRangeCount();
var prestudent_id= '';
var student_uid= '';
for (var t = 0; t < numRanges; t++)
{
tree.view.selection.getRangeAt(t,start,end);
for (var v = start.value; v <= end.value; v++)
{
var col = tree.columns ? tree.columns["student-treecol-prestudent_id"] : "student-treecol-prestudent_id";
var prestudentId=tree.view.getCellText(v,col);
prestudent_id += ';'+prestudentId;
col = tree.columns ? tree.columns["student-treecol-uid"] : "student-treecol-uid";
var uid=tree.view.getCellText(v,col);
student_uid += ';'+uid;
}
}
if (event.shiftKey)
{
var output='odt';
}
else if (event.ctrlKey)
{
var output='doc';
}
else
{
var output='pdf';
}
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragWiederholung.xml.php&xsl=AntragWiederholung&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragUnterbrechung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
// ****
// * Erstellt den Ausbildungsvertrag fuer einen oder mehrere Studenten
// ****
@@ -152,8 +152,8 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
</template>
</tree>
<vbox>
<button id="student-projektarbeit-button-neu" label="Neu" oncommand="StudentProjektarbeitNeu();" disabled="true"/>
<button id="student-projektarbeit-button-loeschen" label="Loeschen" oncommand="StudentProjektarbeitLoeschen();" disabled="true"/>
<button id="student-projektarbeit-button-neu" label="Neue PA" oncommand="StudentProjektarbeitNeu();" disabled="true"/>
<button id="student-projektarbeit-button-loeschen" label="PA Loeschen" oncommand="StudentProjektarbeitLoeschen();" disabled="true"/>
</vbox>
</hbox>
<hbox>
@@ -322,7 +322,7 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
<spacer />
<hbox>
<spacer flex="1" />
<button id="student-projektarbeit-button-speichern" oncommand="StudentProjektarbeitSpeichern()" label="Speichern" disabled="true"/>
<button id="student-projektarbeit-button-speichern" oncommand="StudentProjektarbeitSpeichern()" label="PA Speichern" disabled="true"/>
</hbox>
</row>
</rows>
@@ -428,8 +428,8 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
</template>
</tree>
<vbox>
<button id="student-projektbetreuer-button-neu" label="Neu" oncommand="StudentProjektbetreuerNeu();" disabled="true"/>
<button id="student-projektbetreuer-button-loeschen" label="Loeschen" oncommand="StudentProjektbetreuerLoeschen();" disabled="true"/>
<button id="student-projektbetreuer-button-neu" label="Neue Betreuung" oncommand="StudentProjektbetreuerNeu();" disabled="true"/>
<button id="student-projektbetreuer-button-loeschen" label="Betreuung Loeschen" oncommand="StudentProjektbetreuerLoeschen();" disabled="true"/>
</vbox>
</hbox>
<vbox hidden="true">
@@ -534,7 +534,7 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
<spacer />
<hbox>
<spacer flex="1" />
<button id="student-projektbetreuer-button-speichern" label="Speichern" oncommand="StudentProjektbetreuerSpeichern()" />
<button id="student-projektbetreuer-button-speichern" label="Betreuung Speichern" oncommand="StudentProjektbetreuerSpeichern()" />
</hbox>
</row>
</rows>
+1 -1
View File
@@ -187,7 +187,7 @@ class zgv extends basis_db
public function getAllDoktor($onlyAktiv = false)
{
$sprache = new sprache();
$qry='SELECT *,'.$sprache->getSprachQuery('bezeichnung').' FROM bis.tbl_zgvdoktor;';
$qry='SELECT *,'.$sprache->getSprachQuery('bezeichnung').' FROM bis.tbl_zgvdoktor';
if ($onlyAktiv === true)
{
+8
View File
@@ -219,10 +219,18 @@
<!ENTITY menu-dokumente-antrag-abmeldung.label "Abmeldung">
<!ENTITY menu-dokumente-antrag-abmeldung.accesskey "A">
<!ENTITY menu-dokumente-antrag-abmeldungstgl.key "S">
<!ENTITY menu-dokumente-antrag-abmeldungstgl.label "Abmeldung durch Stgl">
<!ENTITY menu-dokumente-antrag-abmeldungstgl.accesskey "S">
<!ENTITY menu-dokumente-antrag-unterbrechung.key "U">
<!ENTITY menu-dokumente-antrag-unterbrechung.label "Unterbrecher">
<!ENTITY menu-dokumente-antrag-unterbrechung.accesskey "U">
<!ENTITY menu-dokumente-antrag-wiederholung.key "W">
<!ENTITY menu-dokumente-antrag-wiederholung.label "Abmeldung durch Ablauf der Wiederholungsfrist">
<!ENTITY menu-dokumente-antrag-wiederholung.accesskey "W">
<!ENTITY menu-dokumente-ausbildungsvertrag.key "A">
<!ENTITY menu-dokumente-ausbildungsvertrag.label "Ausbildungsvertrag Deutsch">
<!ENTITY menu-dokumente-ausbildungsvertrag.accesskey "A">
+80 -63
View File
@@ -1,83 +1,100 @@
.text-prewrap {
.fhc-header {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: baseline;
margin-bottom: 3rem;
}
.fhc-header > h1:first-child {
font-size: calc(1.325rem + .9vw);
}
.fhc-header > :first-child > small {
color: var(--bs-secondary);
font-size: .65em;
padding-inline-start: 1em;
}
.fhc-alert.p-toast-center {
width: 35rem;
max-width: 100vw;
}
.fhc-alert.p-toast-top-right {
max-width: calc(100vw - 40px);
}
.fhc-alert.p-toast-top-right .p-toast-detail,
.fhc-alert.p-toast-center .p-toast-message-text .card {
white-space: pre-wrap;
}
.text-preline {
white-space: pre-line;
}
.accordion-button-primary {
background-color: #e7f1ff;
color: #0c63e4;
}
.accordion-button-primary:not(.collapsed) {
background-color: #cfe2ff;
color: #0a58ca;
.text-prewrap {
white-space: pre-wrap;
}
.accordion-button-secondary {
background-color: #f0f1f2;
color: #616971;
}
.accordion-button-secondary:not(.collapsed) {
background-color: #e2e3e5;
color: #565e64;
.btn-p-0 {
padding: 0 .375rem;
}
.accordion-button-success {
background-color: #e8f3ee;
color: #177a4c;
}
.accordion-button-success:not(.collapsed) {
background-color: #d1e7dd;
color: #146c43;
.z-1 {
z-index: 1;
}
.accordion-button-info {
background-color: #e7fafe;
color: #0cb6d8;
}
.accordion-button-info:not(.collapsed) {
background-color: #cff4fc;
color: #0aa2c0;
.input-group > .input-group-item {
position: relative;
flex: 1 1 auto;
width: 1%;
min-width: 0;
}
.accordion-button-warning {
background-color: #fff9e6;
color: #e6ae06;
}
.accordion-button-warning:not(.collapsed) {
background-color: #fff3cd;
color: #cc9a06;
.input-group > .input-group-item .form-control:focus,
.input-group > .input-group-item .form-select:focus {
z-index: 3;
position: relative;
}
.accordion-button-danger {
background-color: #fcebec;
color: #c6303e;
}
.accordion-button-danger:not(.collapsed) {
background-color: #f8d7da;
color: #b02a37;
.input-group-lg > .input-group-item .form-control,
.input-group-lg > .input-group-item .form-select {
padding: 0.5rem 1rem;
font-size: 1.25rem;
border-radius: 0.3rem;
}
.accordion-button-light {
background-color: #fefeff;
color: #dfe0e1;
}
.accordion-button-light:not(.collapsed) {
background-color: #fefefe;
color: #c6c7c8;
.input-group-sm > .input-group-item .form-control,
.input-group-sm > .input-group-item .form-select {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
border-radius: 0.2rem;
}
.accordion-button-dark {
background-color: #e9e9ea;
color: #1e2125;
}
.accordion-button-dark:not(.collapsed) {
background-color: #d3d3d4;
color: #1a1e21;
.input-group-lg > .input-group-item .form-select,
.input-group-sm > .input-group-item .form-select {
padding-right: 3rem;
}
.tabulator-edit-list .tabulator-edit-list-item {
background-color: white;
.input-group:not(.has-validation) > .input-group-item:not(:last-child) .form-control,
.input-group:not(.has-validation) > .input-group-item:not(:last-child) .form-select {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.tabulator-edit-list .tabulator-edit-list-item:hover,
.tabulator-edit-list .tabulator-edit-list-item.active {
color: white;
.input-group.has-validation > .input-group-item:nth-last-child(n+3) .form-control,
.input-group.has-validation > .input-group-item:nth-last-child(n+3) .form-select {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group > .input-group-item:not(:first-child) .form-control,
.input-group > .input-group-item:not(:first-child) .form-select {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.form-control-color.is-invalid,
.was-validated .form-control-color:invalid,
.form-control-color.is-valid,
.was-validated .form-control-color:valid {
padding-right: .375rem;
background-image: none;
}
+7 -1
View File
@@ -1,4 +1,4 @@
@import '../../vendor/olifolkerd/tabulator5/dist/css/tabulator_bootstrap5.min.css';
@import '../../vendor/olifolkerd/tabulator5/dist/css/tabulator_simple.min.css';
/* Apply borders and background to Cell instead of the Row
* otherwise frozen columns won't look good (columns behind
@@ -38,3 +38,9 @@
.tabulator .tabulator-col-resize-handle:last-of-type {
z-index: 999999;
}
.tabulator-cell .btn {
padding: 0 .5rem;
max-height: 22px;
min-width: 30px;
}
@@ -64,3 +64,12 @@
margin-top: 20px;
}
.tabulator {
font-size: 1rem;
}
.tabulator-cell .btn {
padding: 0 .375rem;
font-size: .875rem;
border-radius: .2rem;
}
@@ -82,6 +82,7 @@
/*
* To be moved outside
*/
.navbar.navbar-left-side ~ *,
#content {
position: inherit;
margin: 0 0 0 250px;
+16
View File
@@ -0,0 +1,16 @@
.nav-item.nav-link:focus {
box-shadow: 0 0 0 .24rem rgba(13,110,253,.25);
z-index: 1;
outline: 0;
position: relative;
}
.nav-item.nav-link:focus::after {
content: "";
display: block;
position: absolute;
left: -.5rem;
right: -.5rem;
top: calc(100% + 1px);
background: white;
height: .25rem;
}
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
@import '../../../vendor/vuejs/vuedatepicker_css/main.css';
:root {
/*General*/
--dp-font-family: var(--bs-body-font-family);
--dp-border-radius: .25rem;
--dp-cell-border-radius: .25rem; /*Specific border radius for the calendar cell*/
/*Sizing*/
--dp-button-height: 2.1875rem; /*Size for buttons in overlays*/
--dp-month-year-row-height: 2.1875rem; /*Height of the month-year select row*/
--dp-month-year-row-button-size: 2.1875rem; /*Specific height for the next/previous buttons*/
--dp-button-icon-height: 1.25rem; /*Icon sizing in buttons*/
--dp-cell-size: 2.1875rem; /*Width and height of calendar cell*/
--dp-cell-padding: .3125rem; /*Padding in the cell*/
--dp-common-padding: .625rem; /*Common padding used*/
--dp-input-icon-padding: 2.1875rem;
--dp-input-padding: .375rem .75rem;
--dp-action-buttons-padding: .125rem .3125rem; /*Adjust padding for the action buttons in action row*/
--dp-row-margin: .3125rem 0; /*Adjust the spacing between rows in the calendar*/
--dp-calendar-header-cell-padding: 0.5rem; /*Adjust padding in calendar header cells*/
--dp-two-calendars-spacing: .625rem; /*Space between multiple calendars*/
--dp-overlay-col-padding: .1875rem; /*Padding in the overlay column*/
--dp-time-inc-dec-button-size: 2rem; /*Sizing for arrow buttons in the time picker*/
--dp-menu-padding: .375rem .5rem; /*Menu padding*/
}
.dp__theme_light {
--dp-text-color: var(--text-color);
--dp-primary-color: var(--bs-primary);
--dp-primary-disabled-color: rgba(var(--bs-primary-rgb), .65);
--dp-primary-text-color: var(--primary-color-text);
--dp-secondary-color: var(--bs-secondary);
--dp-border-color: var(--bs-gray-400);
--dp-menu-border-color: var(--bs-gray-400);
--dp-border-color-hover: var(--bs-gray-400);
--dp-icon-color: rgba(var(--bs-black-rgb), .5);
--dp-hover-icon-color: rgba(var(--bs-black-rgb), .75);
--dp-range-between-dates-text-color: var(--dp-hover-text-color, var(--text-color));
}
.dp__theme_light .form-control.is-invalid {
--dp-border-color-hover: var(--bs-danger);
}
.dp__theme_light .form-control.is-valid {
--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) }
@@ -24,6 +24,8 @@ import {CoreRESTClient} from '../../RESTClient.js';
import {CoreFetchCmpt} from '../../components/Fetch.js';
import {BismeldestichtagAPIs} from './API.js';
import Phrasen from '../../plugin/Phrasen.js';
const bismeldestichtagApp = Vue.createApp({
data: function() {
return {
@@ -187,4 +189,4 @@ const bismeldestichtagApp = Vue.createApp({
}
});
bismeldestichtagApp.mount('#main');
bismeldestichtagApp.use(Phrasen).mount('#main');
+3 -1
View File
@@ -21,6 +21,8 @@ import {LogsViewerTabulatorEventHandlers} from './TabulatorSetup.js';
import {CoreFilterCmpt} from '../../components/filter/Filter.js';
import {CoreNavigationCmpt} from '../../components/navigation/Navigation.js';
import Phrasen from '../../plugin/Phrasen.js';
const logsViewerApp = Vue.createApp({
data: function() {
return {
@@ -40,5 +42,5 @@ const logsViewerApp = Vue.createApp({
}
});
logsViewerApp.mount('#main');
logsViewerApp.use(Phrasen).mount('#main');
+123
View File
@@ -0,0 +1,123 @@
import FhcFragment from "../Fragment.js";
export default {
components: {
FhcFragment
},
provide() {
return {
$registerToForm: component => {
if (this.inputs.indexOf(component) < 0)
this.inputs.push(component);
},
$clearValidationForName: this.clearValidationForName
};
},
props: {
tag: {
type: String,
default: 'form'
}
},
data() {
return {
inputs: []
}
},
computed: {
sortedInputs() {
return this.inputs.reduce((a,c) => {
let name = c.name || '_default';
if (!a[name])
a[name] = [];
a[name].push(c);
if (c.lcType == 'checkbox' && name.substr(-1) == ']' && name.indexOf('[')) {
name = name.substr(0, name.lastIndexOf('['));
if (!a[name])
a[name] = [];
a[name].push(c);
}
return a;
}, {});
},
factory() {
const factory = Object.create(Object.getPrototypeOf(this.$fhcApi.factory), Object.getOwnPropertyDescriptors(this.$fhcApi.factory));
factory.$fhcApi = {
get: this.get,
post: this.post
};
return factory;
}
},
methods: {
get(...args) {
if (typeof args[0] == 'object' && args[0].clearValidation && args[0].setFeedback)
args[0] = this;
else
args.unshift(this);
return this.$fhcApi.get(...args);
},
post(...args) {
if (typeof args[0] == 'object' && args[0].clearValidation && args[0].setFeedback)
args[0] = this;
else
args.unshift(this);
return this.$fhcApi.post(...args);
},
_sendFeedbackToInput(inputs, feedback, valid) {
if (inputs.length) {
inputs.forEach(input => input.setFeedback(valid, feedback));
return false;
}
if (this.$fhcAlert) {
this.$fhcAlert[valid ? 'alertSuccess' : 'alertError'](feedback);
return false;
}
return true;
},
setFeedback(valid, feedback) {
if (Array.isArray(feedback)) {
let remaining = feedback.filter(fb =>
this._sendFeedbackToInput(
this.sortedInputs['_default'] || [],
fb,
valid
)
);
return remaining.length ? remaining : null;
}
if (typeof feedback === 'object') {
let remaining = Object.entries(feedback).filter(([name, fb]) =>
this._sendFeedbackToInput(
this.sortedInputs[name.split('.')[0] + name.split('.').slice(1).map(p => `[${p}]`).join("")] || this.sortedInputs['_default'] || [],
fb,
valid
)
);
return remaining.length ? Object.fromEntries(remaining) : null;
}
let remaining = this._sendFeedbackToInput(
this.sortedInputs['_default'] || [],
feedback,
valid
);
return remaining ? feedback : null;
},
clearValidation() {
this.inputs.forEach(input => input.clearValidation());
},
clearValidationForName(name) {
(this.sortedInputs[name.split('.')[0] + name.split('.').slice(1).map(p => `[${p}]`).join("")] || this.sortedInputs['_default'] || [])
.forEach(input => input.clearValidation());
}
},
template: `
<component :is="tag || 'FhcFragment'" v-bind="$attrs">
<slot></slot>
</component>`
}
+315
View File
@@ -0,0 +1,315 @@
import FhcFragment from "../Fragment.js";
let _uuid = {};
export default {
inheritAttrs: false,
components: {
FhcFragment
},
inject: {
registerToForm: {
from: '$registerToForm',
default: null
},
clearValidationForName: {
from: '$clearValidationForName',
default: null
}
},
props: {
bsFeedback: Boolean,
noAutoClass: Boolean,
noFeedback: Boolean,
inputGroup: Boolean,
type: String,
name: String,
containerClass: [String, Array, Object]
},
data() {
return {
valid: undefined,
feedback: [],
modelValueDummy: undefined
}
},
computed: {
hasContainer() {
if (!this.bsFeedback)
return true;
if (this.containerClass)
return true;
for (const prop in this.autoContainerClass)
if (Object.hasOwn(this.autoContainerClass, prop))
return true;
return false;
},
acc() {
if (!this.containerClass)
return {};
if (typeof this.containerClass === 'string' || this.containerClass instanceof String)
return this.containerClass.split(' ').reduce((a,c) => {a[c] = true; return a}, {});
if (Array.isArray(this.containerClass))
return this.containerClass.reduce((a,c) => {a[c] = true; return a}, {});
return this.containerClass;
},
autoContainerClass() {
if (this.noAutoClass)
return this.acc;
const acc = {...this.acc};
if (this.inputGroup)
acc['input-group-item'] = true;
if (this.lcType == 'radio' || this.lcType == 'checkbox')
acc['form-check'] = true;
if (this.inputGroup && acc['form-check']) {
acc['input-group-item'] = false;
acc['form-check'] = false;
acc['input-group-text'] = true;
}
return acc;
},
lcType() {
if (!this.type)
return 'text';
return this.type.toLowerCase();
},
tag() {
switch (this.lcType) {
case 'textarea':
case 'select':
return this.lcType;
case 'datepicker':
return 'VueDatePicker';
case 'autocomplete':
return 'PvAutocomplete';
case 'uploadimage':
return 'UploadImage';
case 'uploadfile':
case 'uploaddms':
return 'UploadDms';
default:
return 'input';
}
},
validationClass() {
const classes = [];
if (this.valid)
classes.push('is-valid');
else if (this.valid === false)
classes.push('is-invalid');
if (!this.noAutoClass) {
let c = this.$attrs.class ? this.$attrs.class.split(' ') : [];
switch (this.lcType) {
// TODO(chris): complete list!
case 'select':
if (!c.includes('form-select'))
classes.push('form-select');
break;
case 'range':
if (!c.includes('form-range'))
classes.push('form-range');
break;
case 'radio':
case 'checkbox':
// TODO(chris): maybe different handling?
if (!c.includes('form-check-input') && !c.includes('btn-check'))
classes.push('form-check-input');
break;
case 'color':
if (!c.includes('form-control-color'))
classes.push('form-control-color');
if (!c.includes('form-control'))
classes.push('form-control');
break;
case 'autocomplete':
case 'datepicker':
classes.push('p-0');
classes.push('border-0');
if (!c.includes('form-control'))
classes.push('form-control');
break;
case 'text':
case 'number':
case 'password':
case 'textarea':
if (!c.includes('form-control'))
classes.push('form-control');
break;
}
}
return classes;
},
feedbackClass() {
if (!this.feedback || this.feedback === true)
return '';
if (!this.bsFeedback)
return {
'valid-tooltip': this.valid === true,
'invalid-tooltip': this.valid === false
};
return {
'valid-feedback': this.valid === true,
'invalid-feedback': this.valid === false
};
},
modelValueCmp: {
get() {
if (this.$attrs.modelValue === undefined)
return this.modelValueDummy;
return this.$attrs.modelValue;
},
set(v) {
if (this.$attrs.modelValue === undefined)
this.modelValueDummy = v;
this.$emit('update:modelValue', v);
}
},
idCmp() {
let uuid = this.$attrs.id;
if (this.lcType == 'datepicker')
uuid = this.$attrs.uid;
if (!uuid && this.$attrs.label)
uuid = 'fhc-form-input';
if (!uuid)
return undefined;
if (this.lcType == 'datepicker')
uuid = 'dp-input-' + uuid;
if (_uuid[uuid] === undefined)
_uuid[uuid] = 0;
return uuid + '-' + (_uuid[uuid]++);
}
},
methods: {
clearValidation() {
this.valid = undefined;
this.feedback = [];
},
clearValidationForThisName() {
if (this.valid === undefined)
return;
if (this.clearValidationForName && this.name)
this.clearValidationForName(this.name);
else
this.clearValidation();
},
setFeedback(valid, feedback) {
if (!feedback)
feedback = [];
if (!Array.isArray(feedback))
feedback = [feedback];
this.valid = valid;
// NOTE(chris): On a list of radios/checkboxes only add the feedback message to the last item
if (this.name && (this.lcType == 'radio' || this.lcType == 'checkbox')) {
const selector = 'input[type="' + this.lcType + '"][name="' + this.name + '"]';
if ([...this.$el.parentNode.querySelectorAll(selector)].pop() != this.$refs.input)
return;
}
this.feedback = feedback;
},
_loadComponents() {
if (this.tag == 'VueDatePicker' && !this._.components.VueDatePicker) {
this._.components.VueDatePicker = Vue.defineAsyncComponent(() => import("../vueDatepicker.js.php"));
} else if (this.tag == 'PvAutocomplete' && !this._.components.PvAutocomplete) {
this._.components.PvAutocomplete = Vue.defineAsyncComponent(() => import(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/public/js/components/primevue/autocomplete/autocomplete.esm.min.js"));
} else if (this.tag == 'UploadImage' && !this._.components.UploadImage) {
this._.components.UploadImage = Vue.defineAsyncComponent(() => import("./Upload/Image.js"));
} else if (this.tag == 'UploadDms' && !this._.components.UploadDms) {
this._.components.UploadDms = Vue.defineAsyncComponent(() => import("./Upload/Dms.js"));
}
}
},
beforeMount() {
this._loadComponents();
},
beforeUpdate() {
this._loadComponents();
},
mounted() {
if (this.registerToForm)
this.registerToForm(this);
},
template: `
<component :is="!hasContainer ? 'FhcFragment' : 'div'" class="position-relative" :class="autoContainerClass">
<label v-if="$attrs.label && lcType != 'radio' && lcType != 'checkbox'" :for="idCmp">{{$attrs.label}}</label>
<input v-if="tag == 'input'" :type="lcType" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)">
<textarea v-else-if="tag == 'textarea'" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)"></textarea>
<select v-else-if="tag == 'select'" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)">
<slot></slot>
</select>
<component
v-else-if="tag == 'VueDatePicker'"
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:uid="idCmp ? idCmp.substr(9) : idCmp"
:name="name"
:class="validationClass"
:input-class-name=
"[...Object.entries({'form-control': !noAutoClass, 'is-valid': valid === true, 'is-invalid': valid === false}).reduce((a,[k,v]) => {if(v) a.push(k);return a}, []), ...($attrs['input-class-name'] ? $attrs['input-class-name'].split(' ') : [])].join(' ')"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<component
v-else-if="tag == 'PvAutocomplete'"
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:id="idCmp"
:input-props="{name}"
:class="validationClass"
:input-class="[...Object.entries({'form-control': !noAutoClass, 'is-valid': valid === true, 'is-invalid': valid === false}).reduce((a,[k,v]) => {if(v) a.push(k);return a}, []), ...($attrs['input-class'] ? $attrs['input-class'].split(' ') : [])].join(' ')"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<component
v-else-if="tag == 'UploadDms'"
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:id="idCmp"
:name="name"
:class="validationClass"
:input-class="validationClass"
:no-list="inputGroup"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<component
v-else
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:id="idCmp"
:name="name"
:class="validationClass"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<label v-if="$attrs.label && (lcType == 'radio' || lcType == 'checkbox')" :for="idCmp" :class="!noAutoClass && 'form-check-label'">{{$attrs.label}}</label>
<div v-if="valid !== undefined && feedback.length && !noFeedback" :class="feedbackClass">
<template v-for="(msg, i) in feedback" :key="i">
<hr v-if="i" class="m-0">
{{msg}}
</template>
</div>
</component>
`
}
+87
View File
@@ -0,0 +1,87 @@
export default {
emits: [
'update:modelValue'
],
props: {
modelValue: {
type: [ FileList, Array ],
required: true
},
multiple: Boolean,
id: String,
name: String,
inputClass: [String, Array, Object],
noList: Boolean
},
methods: {
stringifyFile(file) {
return JSON.stringify({
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
name: file.name,
size: file.size,
type: file.type
});
},
addFiles(event) {
if (!this.multiple)
return this.$emit('update:modelValue', event.target.files);
const dt = new DataTransfer();
const doubles = [];
for (var file of this.modelValue) {
dt.items.add(file);
doubles.push(this.stringifyFile(file));
}
for (var file of event.target.files) {
// NOTE(chris): deep check (with FileReader) would require an async function so we only check the basic attributes
if (doubles.indexOf(this.stringifyFile(file)) < 0)
dt.items.add(file);
}
this.$emit('update:modelValue', dt.files);
},
removeFile(id) {
const fileToRemove = Array.from(this.modelValue)[id];
const dt = new DataTransfer();
for (var file of this.modelValue) {
if (file !== fileToRemove)
dt.items.add(file);
}
this.$emit('update:modelValue', dt.files);
}
},
watch: {
modelValue(n) {
if (n instanceof FileList)
return this.$refs.upload.files = n;
const dt = new DataTransfer();
const dms = [];
for (var file of n) {
if (file instanceof File) {
dt.items.add(file);
} else {
const dmsFile = new File([JSON.stringify(file)], file.name, {
type: 'application/x.fhc-dms+json'
});
dt.items.add(dmsFile);
}
}
this.$emit('update:modelValue', dt.files);
}
},
template: `
<div class="form-upload-dms">
<input ref="upload" class="form-control" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
<ul v-if="modelValue.length && multiple && !noList" class="list-unstyled m-0">
<li v-for="(file, index) in modelValue" :key="index" class="d-flex mx-1 mt-1 align-items-start">
<span class="col-auto"><i class="fa fa-file me-1"></i></span>
<span class="col">{{ file.name }}</span>
<button class="col-auto btn btn-outline-secondary btn-p-0" @click="removeFile(index)">
<i class="fa fa-close"></i>
</button>
</li>
</ul>
</div>`
}
+62
View File
@@ -0,0 +1,62 @@
export default {
emits: [
'update:modelValue'
],
props: {
modelValue: String
},
computed: {
valueAsBase64DataString() {
if (!this.modelValue || this.modelValue.substring(0, 10) == 'data:image')
return this.modelValue;
return 'data:image/jpeg;charset=utf-8;base64,' + this.modelValue;
}
},
methods: {
openUploadDialog() {
this.$refs.fileInput.click();
},
pickFile() {
let file = this.$refs.fileInput.files;
if (file && file[0]) {
let reader = new FileReader();
reader.onload = e => {
this.$emit('update:modelValue', e.target.result);
}
reader.readAsDataURL(file[0]);
}
},
deleteImage() {
this.$emit('update:modelValue', '');
}
},
template: `
<div class="form-upload-image">
<template v-if="modelValue">
<img class="img-thumbnail" :src="valueAsBase64DataString" />
<div class="fotobutton">
<div class="d-grid gap-2 d-md-flex">
<button type="button" class="btn btn-outline-dark btn-sm" @click="deleteImage">
<i class="fa fa-close"></i>
</button>
<button type="button" class="btn btn-outline-dark btn-sm" @click="openUploadDialog">
<i class="fa fa-pen"></i>
</button>
</div>
</div>
</template>
<template v-else>
<slot>
<svg class="bd-placeholder-img img-thumbnail" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="A generic square placeholder image with a white border around it, making it resemble a photograph taken with an old instant camera: 200x200" preserveAspectRatio="xMidYMid slice" focusable="false"><title>A generic square placeholder image with a white border around it, making it resemble a photograph taken with an old instant camera</title><rect width="100%" height="100%" fill="#868e96"></rect><text x="50%" y="50%" fill="#dee2e6" dy=".3em"></text></svg>
</slot>
<div class="fotobutton-visible">
<div class="d-grid gap-2 d-md-flex">
<button type="button" class="btn btn-outline-dark btn-sm" @click="openUploadDialog">
<i class="fa fa-pen"></i>
</button>
</div>
</div>
</template>
<input :id="$attrs.id" class="d-none" type="file" ref="fileInput" @input="pickFile" accept="image/*">
</div>`
}
+41
View File
@@ -0,0 +1,41 @@
export default {
inject: [
'$registerToForm'
],
data() {
return {
feedback: {
success: [],
danger: []
}
};
},
methods: {
clearValidation() {
this.feedback = {
success: [],
danger: []
};
},
setFeedback(valid, feedback) {
if (!feedback)
feedback = [];
if (!Array.isArray(feedback))
feedback = [feedback];
const ts = Date.now();
this.feedback[valid ? 'success' : 'danger'] = feedback.map(msg => [msg, ts]);
}
},
mounted() {
if (this.$registerToForm)
this.$registerToForm(this);
},
template: `
<template v-for="(arr, key) in feedback" :key="key">
<div v-for="[msg, ts] in arr" :key="ts + msg" class="alert alert-dismissible fade show" :class="'alert-' + key" role="alert">
{{msg}}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</template>
`
};
+5
View File
@@ -0,0 +1,5 @@
export default {
render() {
return (this.$slots && this.$slots.default) ? this.$slots.default() : null;
}
};
@@ -29,8 +29,10 @@ export default {
switch (this.data.status)
{
case 'Erstellt': return 'info';
case 'Pause':
case 'Zurueckgezogen': return 'danger';
case 'Genehmigt': return 'success';
default: return 'info';
default: return 'warning';
}
},
loadUrl() {
@@ -51,8 +53,12 @@ export default {
result => {
this.data = result.data.retval;
if (this.data.status) {
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
}
@@ -29,9 +29,11 @@ export default {
switch (this.data?.status)
{
case 'Erstellt': return 'info';
case 'Genehmigt':
case 'Pause':
case 'Zurueckgezogen': return 'danger';
case 'EinspruchAbgelehnt':
case 'Abgemeldet': return 'success';
default: return 'info';
default: return 'warning';
}
},
loadUrl() {
@@ -52,8 +54,12 @@ export default {
result => {
this.data = result.data.retval;
if (this.data.status) {
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
}
@@ -37,9 +37,12 @@ export default {
switch (this.data.status)
{
case 'Erstellt': return 'info';
case 'Genehmigt': return 'success';
case 'Zurueckgezogen': return 'danger';
default: return 'info';
case 'Pause':
case 'Zurueckgezogen':
case 'Abgelehnt': return 'danger';
case 'Genehmigt':
case 'EmailVersandt': return 'success';
default: return 'warning';
}
},
loadUrl() {
@@ -62,6 +65,18 @@ export default {
return datumUnformatted;
let datum = new Date(datumUnformatted);
return datum.toLocaleDateString();
},
semesterOffsets() {
if (!this.data || !this.data.studiensemester)
return [];
return Object.values(this.data.studiensemester)
.filter(el => !el.disabled)
.map(el => el.studiensemester_kurzbz);
},
semester() {
if (!this.stsem)
return '';
return this.data.semester + this.semesterOffsets.indexOf(this.stsem);
}
},
methods: {
@@ -74,8 +89,12 @@ export default {
result => {
this.data = result.data.retval;
if (this.data.status) {
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
}
@@ -235,7 +254,7 @@ export default {
<tr>
<th>{{$p.t('lehre', 'semester')}}</th>
<td align="right" v-if="data.studierendenantrag_id">{{data.semester}}</td>
<td align="right" v-else>{{stsem === null ? '' : data.studiensemester[stsem].semester}}</td>
<td align="right" v-else>{{semester}}</td>
</tr>
</table>
</div>
@@ -256,7 +275,7 @@ export default {
:id="'studierendenantrag-form-abmeldung-' + uuid + '-stsem'"
@input="currentWiedereinstieg = ''"
>
<option v-for="(stsem, index) in data.studiensemester" :key="index" :value="index">
<option v-for="(stsem, index) in data.studiensemester" :key="index" :value="index" :disabled="stsem.disabled">
{{stsem.studiensemester_kurzbz}}
</option>
</select>
@@ -280,7 +299,7 @@ export default {
</div>
<div v-else>
<select v-model="currentWiedereinstieg" class="form-select">
<option v-for="sem in data.studiensemester[stsem].wiedereinstieg" :key="sem.studiensemester_kurzbz" :value="sem.start">
<option v-for="sem in data.studiensemester[stsem].wiedereinstieg" :key="sem.studiensemester_kurzbz" :value="sem.start" :disabled="sem.disabled">
{{sem.studiensemester_kurzbz}}
</option>
</select>
@@ -35,11 +35,14 @@ export default {
statusSeverity() {
switch (this.data.status)
{
case 'Erstellt': return 'info';
case 'Offen':
case 'Erstellt':
case 'ErsteAufforderungVersandt': return 'info';
case 'Genehmigt': return 'success';
case 'Pause':
case 'Verzichtet':
case 'Abgemeldet': return 'danger';
default: return 'info';
default: return 'warning';
}
},
loadUrl() {
@@ -67,8 +70,12 @@ export default {
this.data.statustyp = this.$p.t('studierendenantrag', 'status_open');
}
this.$emit('update:status', this.data.status);
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
return result;
@@ -184,6 +184,44 @@ export default {
.then(this.showValidation)
.catch(this.showError);
},
actionPause(evt) {
var antraege = evt || this.selectedData;
this.$refs.loader.show();
axios
.all(
antraege.map(
antrag => axios.post(
FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
'/components/Antrag/Leitung/pauseAntrag/',
{
studierendenantrag_id: antrag.studierendenantrag_id
}
)
)
)
.then(this.showValidation)
.catch(this.showError);
},
actionUnpause(evt) {
var antraege = evt || this.selectedData;
this.$refs.loader.show();
axios
.all(
antraege.map(
antrag => axios.post(
FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
'/components/Antrag/Leitung/unpauseAntrag/',
{
studierendenantrag_id: antrag.studierendenantrag_id
}
)
)
)
.then(this.showValidation)
.catch(this.showError);
},
actionObject(evt) {
var antraege = evt || this.selectedData;
this.$refs.loader.show();
@@ -347,6 +385,8 @@ export default {
@action:objectionDeny="actionoObjectionDeny"
@action:objectionApprove="actionObjectionApprove"
@action:cancel="actionCancel"
@action:pause="actionPause"
@action:unpause="actionUnpause"
@reload="reload"
>
</leitung-table>
@@ -25,7 +25,9 @@ export default {
'action:object',
'action:objectionDeny',
'action:objectionApprove',
'action:cancel'
'action:cancel',
'action:pause',
'action:unpause'
],
data() {
return {
@@ -60,6 +62,29 @@ export default {
this.historyData = res.data.retval.sort((a, b) => a.insertamum > b.insertamum);
});
},
getHistoryStatus(data, index) {
if (data.insertvon == 'Studienabbruch')
return this.$p.t('studierendenantrag/status_stop');
if (index > 0 && this.historyData[index-1].studierendenantrag_statustyp_kurzbz == 'Pause') {
if (index > 1 && this.historyData[index-2].studierendenantrag_statustyp_kurzbz != 'Pause') {
// NOTE(chris): this is a AbmeldungStgl Pause right after a manual Pause
if (data.studierendenantrag_statustyp_kurzbz == 'Pause')
return data.typ;
// NOTE(chris): this is a manual Pause resumed
else
return data.typ + ' (' + this.$p.t('studierendenantrag/status_unpaused') + ')';
}
// NOTE(chris): a series of pause stati always starts with a manual and alternate afterwards
let i = 2;
while (index-i > 0 && this.historyData[index-i].studierendenantrag_statustyp_kurzbz == 'Pause') i++;
if (data.studierendenantrag_statustyp_kurzbz == 'Pause')
i++;
return i%2
? data.typ
: data.typ + ' (' + this.$p.t('studierendenantrag/status_unpaused') + ')';
}
return data.typ;
},
showHistoryGrund(grund) {
this.$refs.modalGrund.$el.addEventListener(
'hidden.bs.modal',
@@ -89,7 +114,7 @@ export default {
this.table = new Tabulator(this.$refs.table, {
placeholder:"Keine zu bearbeitenden Datensätze",
movableColumns: true,
maxHeight: '50vh',
height: '65vh',
layout: "fitDataFill",
ajaxURL: this.ajaxUrl + (this.filter || ''),
persistence: { // NOTE(chris): do not store column titles
@@ -153,9 +178,13 @@ export default {
autocomplete: true,
},
formatter: (cell, formatterParams, onRendered) => {
let data = cell.getData();
let status = cell.getValue();
if (data.status_insertvon == 'Studienabbruch' && data.status == 'Pause')
status = this.$p.t('studierendenantrag/status_stop');
let link = document.createElement('a');
link.href = "#";
link.innerHTML = cell.getValue();
link.innerHTML = status;
link.addEventListener('click', e => {
e.preventDefault();
this.lastHistoryClickedId = cell.getData().studierendenantrag_id;
@@ -234,7 +263,22 @@ export default {
container.className = "d-flex gap-2";
if ((data.typ == 'Abmeldung' || data.typ == 'AbmeldungStgl' || data.typ == 'Unterbrechung') && (data.status == 'Genehmigt' || data.status == 'Beeinsprucht' || data.status == 'EinspruchAbgelehnt' || data.status == 'EmailVersandt')) {
let allowed_status_for_download = [];
switch (data.typ) {
case 'Abmeldung':
allowed_status_for_download = ['Genehmigt'];
break;
case 'AbmeldungStgl':
allowed_status_for_download = ['Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt', 'Abgemeldet'];
break;
case 'Unterbrechung':
allowed_status_for_download = ['Genehmigt', 'EmailVersandt'];
break;
case 'Wiederholung':
allowed_status_for_download = ['Abgemeldet'];
break;
}
if (allowed_status_for_download.includes(data.status)) {
// NOTE(chris): Download PDF
let button = document.createElement('a');
// NOTE(chris): phrasen in attribues don't work if they are not preloaded
@@ -246,6 +290,56 @@ export default {
'content/pdfExport.php?xml=Antrag' + data.typ + '.xml.php&xsl=Antrag' + data.typ + '&id=' + data.studierendenantrag_id + '&output=pdf';
container.append(button);
}
if (data.typ == 'Wiederholung' && (data.status == 'ErsteAufforderungVersandt' || data.status == 'ZweiteAufforderungVersandt')) {
// NOTE(chris): Pause
let button = document.createElement('button');
let icon = document.createElement('i');
let span = document.createElement('span');
icon.className = "fa-solid fa-pause";
icon.setAttribute('aria-hidden', true);
icon.setAttribute('title', this.$p.t('studierendenantrag', 'btn_pause'));
span.className = "fa-sr-only";
span.append(this.$p.t('studierendenantrag', 'btn_pause'));
button.append(icon);
button.append(span);
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:pause', [cell.getData()]));
container.append(button);
}
let canUnpause = data.status == 'Pause' && !['AbmeldungStgl', 'Studienabbruch'].includes(data.status_insertvon);
if (!canUnpause && data.status == 'Pause' && data.status_insertvon == 'AbmeldungStgl') {
canUnpause = cell.getTable().getData().filter(row =>
row.prestudent_id == data.prestudent_id
&& row.typ == 'AbmeldungStgl'
&& row.status == 'Zurueckgezogen'
&& row.status_insertamum == data.status_insertamum
).length;
}
if (canUnpause) {
// NOTE(chris): Unpause
let button = document.createElement('button');
let icon = document.createElement('i');
let span = document.createElement('span');
icon.className = "fa-solid fa-play";
icon.setAttribute('aria-hidden', true);
icon.setAttribute('title', this.$p.t('studierendenantrag', 'btn_unpause'));
span.className = "fa-sr-only";
span.append(this.$p.t('studierendenantrag', 'btn_unpause'));
button.append(icon);
button.append(span);
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:unpause', [cell.getData()]));
container.append(button);
}
if (data.typ == 'AbmeldungStgl' && data.status == 'Genehmigt') {
// NOTE(chris): Object
let button = document.createElement('button');
@@ -377,10 +471,10 @@ export default {
<template #title>{{$p.t('studierendenantrag', 'title_history', {id: lastHistoryClickedId})}}</template>
<core-fetch-cmpt ref="historyLoader" :api-function="getHistory">
<table v-if="historyData.length" class="table">
<tr v-for="status in historyData" :key="status.studierendenantrag_status_id">
<tr v-for="(status, index) in historyData" :key="status.studierendenantrag_status_id">
<td>{{(new Date(status.insertamum)).toLocaleString()}}</td>
<td>{{status.insertvon}}</td>
<td>{{status.typ}}</td>
<td>{{getHistoryStatus(status, index)}}</td>
<td>
<a v-if="status.grund" href="#modal-grund" data-bs-toggle="modal" @click="showHistoryGrund(status.grund)">
{{$p.t('studierendenantrag', 'antrag_grund')}}
+62 -21
View File
@@ -6,12 +6,19 @@ export default {
accessibility
},
emits: [
'update:modelValue'
'update:modelValue',
'change',
'changed'
],
props: {
configUrl: String,
config: {
type: [String, Object],
required: true
},
default: String,
modelValue: [String, Number, Boolean, Array, Object, Date, Function, Symbol]
modelValue: [String, Number, Boolean, Array, Object, Date, Function, Symbol],
vertical: Boolean,
border: Boolean
},
data() {
return {
@@ -35,50 +42,84 @@ export default {
}
}
},
created() {
CoreRESTClient
.get(this.configUrl)
watch: {
config(n) {
this.initConfig(n);
}
},
methods: {
change(key) {
this.$emit("change", key)
this.current = key;
this.$nextTick(() => this.$emit("changed", key));
},
initConfig(config) {
if (!config)
return;
if (typeof config === 'string' || config instanceof String)
return CoreRESTClient.get(config)
.then(result => CoreRESTClient.getData(result.data))
.then(result => {
.then(this.initConfig)
.catch(this.$fhcAlert.handleSystemError);
const tabs = {};
// TODO(chris): check if result is array
Object.entries(result).forEach(([key, config]) => {
if (!config.component)
if (Array.isArray(config)) {
config.forEach((item, key) => {
if (!item.component)
return console.error('Component missing for ' + key);
tabs[key] = {
component: Vue.markRaw(Vue.defineAsyncComponent(() => import(config.component))),
title: config.title || key,
config: config.config,
component: Vue.markRaw(Vue.defineAsyncComponent(() => import(item.component))),
title: item.title || key,
config: item.config,
key
}
});
} else {
Object.entries(config).forEach(([key, item]) => {
if (!item.component)
return console.error('Component missing for ' + key);
tabs[key] = {
component: Vue.markRaw(Vue.defineAsyncComponent(() => import(item.component))),
title: item.title || key,
config: item.config,
key
}
});
}
if (this.current === null || !tabs[this.current]) {
if (tabs[this.default])
this.current = this.default;
else
this.current = Object.keys(tabs)[0];
}
this.tabs = tabs;
})
.catch(this.$fhcAlert.handleSystemError);
}
},
created() {
this.initConfig(this.config);
},
template: `
<div class="fhc-tabs d-flex flex-column">
<div class="nav nav-tabs">
<div class="fhc-tabs d-flex" :class="vertical ? 'align-items-stretch gap-3' : (border ? 'flex-column' : 'flex-column gap-3')" v-if="Object.keys(tabs).length">
<div class="nav" :class="vertical ? 'nav-pills flex-column' : 'nav-tabs'">
<div
v-for="tab in tabs"
:key="tab.key"
class="nav-item nav-link"
:class="{active: tab.key == current}"
@click="current=tab.key"
@click="change(tab.key)"
:aria-current="tab.key == current ? 'page' : ''"
v-accessibility:tab
v-accessibility:tab.[vertical]
>
{{tab.title}}
</div>
</div>
<div style="flex: 1 1 0%; height: 0%" class="border-bottom border-start border-end overflow-auto p-3">
<div :style="vertical ? '' : 'flex: 1 1 0%; height: 0%'" class="overflow-auto flex-grow-1" :class="vertical || !border ? '' : 'p-3 border-bottom border-start border-end'">
<keep-alive>
<component :is="currentTab.component" v-model="value" :config="currentTab.config"></component>
<component ref="current" :is="currentTab.component" v-model="value" :config="currentTab.config"></component>
</keep-alive>
</div>
</div>`
+18 -7
View File
@@ -136,9 +136,9 @@ export const CoreFilterCmpt = {
for (let col of columns)
{
// If the column has to be displayed or not
col.visible = selectedFields.indexOf(col.field) >= 0;
if (col.formatter == 'rowSelection')
col.visible = true;
/* fields.indexOf(col.field) == -1; ensures displaying formatter colums
e.g. column with rowSelection checkboxes or with custom formatted action buttons */
col.visible = selectedFields.indexOf(col.field) >= 0 || fields.indexOf(col.field) == -1;
if (col.hasOwnProperty('resizable'))
col.resizable = col.visible;
@@ -185,13 +185,23 @@ export const CoreFilterCmpt = {
else
this.getFilter();
},
initTabulator() {
async initTabulator() {
let placeholder = '< Phrasen Plugin not loaded! >';
if (this.$p) {
await this.$p.loadCategory('ui');
placeholder = this.$p.t('ui/keineDatenVorhanden');
}
// Define a default tabulator options in case it was not provided
let tabulatorOptions = {...{
height: 500,
layout: "fitColumns",
layout: "fitDataStretch",
movableColumns: true,
reactiveData: true
columnDefaults:{
tooltip: true,
},
placeholder,
reactiveData: true,
persistence: true
}, ...(this.tabulatorOptions || {})};
if (!this.tableOnly) {
@@ -265,6 +275,7 @@ export const CoreFilterCmpt = {
this.filterName = data.filterName;
this.dataset = data.dataset;
this.datasetMetadata = data.datasetMetadata;
this.fields = data.fields;
this.selectedFields = data.selectedFields;
this.notSelectedFields = this.fields.filter(x => this.selectedFields.indexOf(x) === -1);
@@ -435,7 +446,7 @@ export const CoreFilterCmpt = {
*
*/
handlerRemoveCustomFilter: function(event) {
filterId = event.currentTarget.getAttribute("href").substring(1);
let filterId = event.currentTarget.getAttribute("href").substring(1);
if (filterId === this.selectedFilter)
this.selectedFilter = null;
//
+54
View File
@@ -0,0 +1,54 @@
/**
* Copyright (C) 2022 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 {
props: {
title: '',
subtitle: '',
mainCols: {
type: Array,
default: []
},
asideCols: {
type: Array,
default: []
},
},
computed: {
mainGridCols() {
return this.mainCols.length > 0 ? `col-md-${this.mainCols[0]}` : "col-md-12";
},
asideGridCols() {
return this.asideCols.length > 0 ? `col-md-${this.asideCols[0]}` : "";
}
},
template: `
<div class="overflow-hidden">
<header v-if="title">
<h1 class="h2 mb-5">{{ title }}<span class="fhc-subtitle">{{ subtitle }}</span></h1>
</header>
<div class="row gx-5">
<main :class="mainGridCols">
<slot name="main">{{ mainGridCols }}</slot>
</main>
<aside v-if="asideCols.length > 0" :class="asideGridCols">
<slot name="aside">{{ asideGridCols }}</slot>
</aside>
</div>
</div>
`
};
+11 -11
View File
@@ -133,8 +133,8 @@ const helperApp = Vue.createApp({
helperAppContainer.parentElement.removeChild(helperAppContainer);
},
template: `
<pv-toast ref="toast" base-z-index="99999"></pv-toast>
<pv-toast ref="alert" base-z-index="99999" position="center">
<pv-toast ref="toast" class="fhc-alert" :base-z-index="99999"></pv-toast>
<pv-toast ref="alert" class="fhc-alert" :base-z-index="99999" position="center">
<template #message="slotProps">
<i class="fa fa-circle-exclamation fa-2xl mt-3"></i>
<div class="p-toast-message-text">
@@ -161,7 +161,7 @@ const helperApp = Vue.createApp({
</a>
</div>
<div ref="messageCard" :id="'fhcAlertCollapseMessageCard' + slotProps.message.id" class="collapse mt-3">
<div class="card card-body text-body small" style="white-space: pre-wrap">
<div class="card card-body text-body small">
{{slotProps.message.detail}}
</div>
</div>
@@ -237,7 +237,7 @@ export default {
alertMultiple(messageArray, severity = 'info', title = 'Info', sticky = false){
// Check, if array has only string values
if (messageArray.every(message => typeof message === 'string')) {
messageArray.every(message => this.alertDefault(severity, title, message, sticky));
messageArray.forEach(message => this.alertDefault(severity, title, message, sticky));
return true;
}
return false;
@@ -281,21 +281,21 @@ export default {
handleSystemMessage(message) {
// Message is string
if (typeof message === 'string')
return fhcerror.alertWarning(message);
return $fhcAlert.alertWarning(message);
// Message is array of strings
if (Array.isArray(message)) {
// If Array has only Strings
if (message.every(msg => typeof msg === 'string'))
return message.every(fhcerror.alertWarning);
return message.every($fhcAlert.alertWarning);
// If Array has only Objects
if (message.every(msg => typeof msg === 'object') && msg !== null) {
return message.every(msg => {
if (msg.hasOwnProperty('data') && msg.data.hasOwnProperty('retval')) {
fhcerror.alertWarning(JSON.stringify(msg.data.retval));
$fhcAlert.alertWarning(JSON.stringify(msg.data.retval));
} else {
fhcerror.alertSystemError(JSON.stringify(msg));
$fhcAlert.alertSystemError(JSON.stringify(msg));
}
});
}
@@ -305,15 +305,15 @@ export default {
if (typeof message === 'object' && message !== null){
if (message.hasOwnProperty('data') && message.data.hasOwnProperty('retval')) {
// NOTE(chris): changed: alertSystemError => alertWarning
fhcerror.alertWarning(JSON.stringify(message.data.retval));
$fhcAlert.alertWarning(JSON.stringify(message.data.retval));
} else {
fhcerror.alertSystemError(JSON.stringify(message));
$fhcAlert.alertSystemError(JSON.stringify(message));
}
return;
}
// Fallback
fhcerror.alertSystemError('alertSystemError throws Generic Error\r\nError Controller Path: ' + FHC_JS_DATA_STORAGE_OBJECT.called_path + '/' + FHC_JS_DATA_STORAGE_OBJECT.called_method);
$fhcAlert.alertSystemError('alertSystemError throws Generic Error\r\nError Controller Path: ' + FHC_JS_DATA_STORAGE_OBJECT.called_path + '/' + FHC_JS_DATA_STORAGE_OBJECT.called_method);
},
resetFormValidation(form) {
const event = new Event('fhc-form-reset');
+282
View File
@@ -0,0 +1,282 @@
import FhcAlert from './FhcAlert.js';
import FhcApiFactory from '../apps/api/fhcapifactory.js';
export default {
install: (app, options) => {
app.use(FhcAlert);
function _get_config(form, uri, data, config) {
if (typeof form == 'string' && config === undefined) {
[uri, data, config] = [form, uri, data];
form = undefined;
} else if (form) {
if (typeof form != 'object')
throw new TypeError('Parameter 1 of _get_config must be an object or a string');
if (uri === undefined && data === undefined && config === undefined) {
config = form;
form = undefined;
}
}
if (form) {
// NOTE(chris): check if form is fhc-form
if (!form.clearValidation || !form.setFeedback)
throw new TypeError("'form' is not a Form Component");
form = {
clearValidation: form.clearValidation,
setFeedback: form.setFeedback
};
if (config)
config.form = form;
else
config = {form};
}
return [uri, data, config];
}
function _clean_return_value(response) {
const result = response.data;
delete response.data;
if (!result.meta)
result.meta = {response};
else
result.meta.response = response;
return result;
}
const fhcApiAxios = axios.create({
timeout: 5000,
baseURL: FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/"
});
fhcApiAxios.interceptors.request.use(config => {
if (config.method != 'post' || !config.data)
return config;
if (config.data instanceof FormData)
return config;
if (!Object.values(config.data).every(item => {
if (item instanceof FileList)
return false;
if (Array.isArray(item))
return item.every(i => !(i instanceof File));
return true;
})) {
const newData = Object.entries(config.data).reduce((nd, [key, item]) => {
if (item instanceof FileList) {
for (const file of item)
nd.FormData.append(key + (item.length > 1 ? '[]' : ''), file);
} else if (Array.isArray(item)) {
if (item.every(i => !(i instanceof File))) {
nd.jsondata[key] = item;
} else {
item.forEach(file => nd.FormData.append(key + (item.length > 1 ? '[]' : ''), file));
}
} else {
nd.jsondata[key] = item;
}
return nd;
}, {
FormData: new FormData(),
jsondata: {}
});
newData.FormData.append('_jsondata', JSON.stringify(newData.jsondata));
config.data = newData.FormData;
}
return config;
});
fhcApiAxios.interceptors.response.use(response => {
if (response.config?.errorHandling == 'off'
|| response.config?.errorHandling === false
|| response.config?.errorHandling == 'fail')
return _clean_return_value(response);
// NOTE(chris): loop through errors
if (response.data.errors)
response.data.errors = response.data.errors.filter(
err => (response.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, response.config.form)
);
return _clean_return_value(response);
}, error => {
if (error.code == 'ERR_CANCELED')
return new Promise(() => {});
if (error.config?.errorHandling == 'off'
|| error.config?.errorHandling === false
|| error.config?.errorHandling == 'success')
return Promise.reject(error);
if (error.response) {
if (error.response.status == 404) {
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL, true);
return new Promise(() => {});
}
// NOTE(chris): loop through errors
error.response.data.errors = error.response.data.errors.filter(
err => (error.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, error.config.form)
);
if (!error.response.data.errors.length)
return new Promise(() => {});
} else if (error.request) {
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL);
return new Promise(() => {});
} else {
app.config.globalProperties.$fhcAlert.alertError(error.message);
return new Promise(() => {});
}
return Promise.reject(error);
});
app.config.globalProperties.$fhcApi = {
get(form, uri, params, config) {
[uri, params, config] = _get_config(form, uri, params, config);
if (params) {
if (config)
config.params = params;
else
config = {params};
}
return fhcApiAxios.get(uri, config);
},
post(form, uri, data, config) {
[uri, data, config] = _get_config(form, uri, data, config);
return fhcApiAxios.post(uri, data, config);
},
_defaultErrorHandlers: {
validation(error, form) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
if (form) {
form.clearValidation();
form.setFeedback(false, error.messages);
return false;
}
if (Array.isArray(error.messages)) {
error.messages.forEach($fhcAlert.alertError);
return false;
} else if (typeof error.messages == 'object') {
Object.entries(error.messages).forEach(
([key, value]) => $fhcAlert.alertDefault('error', key, value, true)
);
return false;
}
return true;
},
general(error, form) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
if (form)
form.setFeedback(false, error.message);
else
$fhcAlert.alertError(error.message);
},
php(error) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
var message = '';
message += 'Message: ' + error.message + '\n\n';
message += 'Filename: ' + error.filename + '\n';
message += 'Line Number: ' + error.line + '\n';
if (error.backtrace && error.backtrace.length) {
message += '\nBacktrace: ';
error.backtrace.forEach(err => {
message += '\n\tFile: ' + err.file + '\n';
message += '\tLine: ' + err.line + '\n';
message += '\tFunction: ' + err.function + '\n';
});
}
switch (error.severity) {
case 'Warning':
case 'Core Warning':
case 'Compile Warning':
case 'User Warning':
$fhcAlert.alertDefault('warn', 'PHP ' + error.severity, message, true);
break;
case 'Notice':
case 'User Notice':
case 'Runtime Notice':
$fhcAlert.alertDefault('info', 'PHP ' + error.severity, message, true);
break;
default:
message = 'Type: PHP ' + error.severity + '\n\n' + message;
$fhcAlert.alertSystemError(message);
break;
}
},
exception(error) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
var message = '';
message += 'Type: ' + error.class + '\n\n';
message += 'Message: ' + error.message + '\n\n';
message += 'Filename: ' + error.filename + '\n';
message += 'Line Number: ' + error.line + '\n';
if (error.backtrace && error.backtrace.length) {
message += '\nBacktrace: ';
error.backtrace.forEach(err => {
message += '\n\tFile: ' + err.file + '\n';
message += '\tLine: ' + err.line + '\n';
message += '\tFunction: ' + err.function + '\n';
});
}
$fhcAlert.alertSystemError(message);
},
db(error) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
var message = '';
if (error.heading !== undefined)
message += error.heading + '\n\n';
if (error.code !== undefined)
message += 'Code: ' + error.code + '\n\n';
if (error.sql !== undefined)
message += 'SQL: ' + error.sql + '\n\n';
if (error.message !== undefined)
message += 'Message: ' + error.message + '\n\n';
else if (error.messages !== undefined)
message += 'Messages: ' + error.messages.join('\n\t') + '\n\n';
if (error.filename !== undefined)
message += 'Filename: ' + error.filename + '\n';
if (error.line !== undefined)
message += 'Line Number: ' + error.line + '\n';
$fhcAlert.alertSystemError(message);
}
}
};
class FhcApiFactoryWrapper {
constructor(factorypart, root) {
if (root === undefined)
this.$fhcApi = app.config.globalProperties.$fhcApi;
else
Object.defineProperty(this, '$fhcApi', {
get() {
return (root || this).$fhcApi;
}
})
Object.keys(factorypart).forEach(key => {
Object.defineProperty(this, key, {
get() {
if (typeof factorypart[key] == 'function')
return factorypart[key].bind(this);
return new FhcApiFactoryWrapper(factorypart[key], root || this);
}
});
});
}
}
app.config.globalProperties.$fhcApi.factory = new FhcApiFactoryWrapper(FhcApiFactory);
}
};
+1 -1
View File
@@ -36,7 +36,7 @@ else
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, public.get_absem_prestudent(a.prestudent_id, NULL) AS semester, a.grund
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, a.grund
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
+3 -3
View File
@@ -14,7 +14,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
$id = $_GET['id'];
$where = " WHERE studierendenantrag_id = " . $db->db_add_param($id) . "
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt');";
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt', 'Abgemeldet');";
$not_found_error = 'Studierendenantrag not found'. $id;
} elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) {
$uid = $_GET['uid'];
@@ -26,7 +26,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
$prestudent_id = (array_filter($prestudent_id, 'strlen'));
$where = " WHERE a.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ")
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt');";
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt', 'Abgemeldet');";
$not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid);
} else
die('<error>wrong parameters</error>');
@@ -36,7 +36,7 @@ else
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, public.get_absem_prestudent(a.prestudent_id, NULL) AS semester, a.grund
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, a.grund
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
+1 -1
View File
@@ -37,7 +37,7 @@ else
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, public.get_absem_prestudent(a.prestudent_id, NULL) AS semester, a.grund, datum_wiedereinstieg, a.datum
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, a.grund, datum_wiedereinstieg, a.datum
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
+70
View File
@@ -0,0 +1,70 @@
<?php
header("Content-type: application/xhtml+xml");
require_once('../config/vilesci.config.inc.php');
require_once('../include/functions.inc.php');
require_once('../include/basis_db.class.php');
$db = new basis_db();
if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
{
if(isset($_GET['id'])) {
$id = $_GET['id'];
$where = " WHERE studierendenantrag_id = " . $db->db_add_param($id) . "
AND a.typ = 'Wiederholung' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Abgemeldet';";
$not_found_error = 'Studierendenantrag not found'. $id;
} elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) {
$uid = $_GET['uid'];
$uid = explode(';', $uid);
$uid = (array_filter($uid, 'strlen'));
$prestudent_id = $_GET['prestudent_id'];
$prestudent_id = explode(';', $prestudent_id);
$prestudent_id = (array_filter($prestudent_id, 'strlen'));
$where = " WHERE a.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ")
AND a.typ = 'Wiederholung' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Abgemeldet';";
$not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid);
} else
die('<error>wrong parameters</error>');
}
else
die('<error>Format not supported</error>');
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, (SELECT pt.text FROM system.tbl_phrase p JOIN system.tbl_phrasentext pt USING(phrase_id) WHERE p.category=" . $db->db_add_param('studierendenantrag', FHC_STRING) . " AND p.phrase=" . $db->db_add_param('grund_Wiederholung_deadline', FHC_STRING) . " AND pt.sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . " LIMIT 1) AS grund
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
JOIN public.tbl_benutzer ON tbl_student.student_uid=uid
JOIN public.tbl_person USING (person_id)
JOIN public.tbl_studiengang stg USING (studiengang_kz)
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
LEFT JOIN public.tbl_prestudentstatus pss ON (pss.prestudent_id = a.prestudent_id AND pss.studiensemester_kurzbz=a.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(a.prestudent_id, a.studiensemester_kurzbz))
LEFT JOIN lehre.tbl_studienplan plan USING (studienplan_id)
JOIN bis.tbl_orgform ON (tbl_orgform.orgform_kurzbz = COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, stg.orgform_kurzbz))" . $where;
if (!$db->db_query($query) || !$db->db_num_rows())
die('<error>' . $not_found_error . '</error>');
?>
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<antraege>
<?php while($row = $db->db_fetch_object()) { ?>
<antrag>
<name><![CDATA[<?= trim($row->vorname . ' ' . $row->nachname); ?>]]></name>
<studiengang><![CDATA[<?= $row->bezeichnung; ?>]]></studiengang>
<organisationsform><![CDATA[<?= $row->bezeichnung_mehrsprachig; ?>]]></organisationsform>
<personenkz><![CDATA[<?= $row->matrikelnr; ?>]]></personenkz>
<studienjahr><![CDATA[<?= $row->studienjahr_kurzbz; ?>]]></studienjahr>
<studiensemester><![CDATA[<?= $row->studiensemester_kurzbz; ?>]]></studiensemester>
<semester><![CDATA[<?= $row->semester; ?>]]></semester>
<grund><![CDATA[<?= $row->grund; ?>]]></grund>
</antrag>
<?php } ?>
</antraege>
+12
View File
@@ -269,11 +269,23 @@ foreach($uid_arr as $uid)
echo "\t\t<studienplan_sprache><![CDATA[".$studienplan->sprache."]]></studienplan_sprache>\n";
echo "\t\t<regelstudiendauer><![CDATA[".$studienplan->regelstudiendauer."]]></regelstudiendauer>\n";
// Abschlussgrad ermitteln
// Erst aus Studienordnung, wenn nicht gesetzt aus akadgrad-Tabelle
if ($studienordnung->akadgrad_id != '')
{
$akadgrad = new akadgrad($studienordnung->akadgrad_id);
echo "\t\t<akadgrad><![CDATA[".$akadgrad->titel."]]></akadgrad>\n";
echo "\t\t<akadgrad_kurzbz><![CDATA[".$akadgrad->akadgrad_kurzbz."]]></akadgrad_kurzbz>\n";
}
else
{
$akadgrad = new akadgrad();
$akadgrad->getAkadgradStudent($student->uid);
echo "\t\t<akadgrad><![CDATA[".$akadgrad->titel."]]></akadgrad>\n";
echo "\t\t<akadgrad_kurzbz><![CDATA[".$akadgrad->akadgrad_kurzbz."]]></akadgrad_kurzbz>\n";
}
//für ao. Studierende wird die StgKz der Lehrveranstaltungen benötigt, die sie besuchen
$lv_studiengang_kz='';
+2
View File
@@ -50,6 +50,8 @@ require_once('dbupdate_3.4/29835_uhstat1_erfassung_der_uhstat1_daten_ueber_das_b
require_once('dbupdate_3.4/33714_erhoehter_studienbeitrag_fuer_drittsaatenangehoerig.php');
require_once('dbupdate_3.4/36275_zeitaufzeichnung_karenz.php');
require_once('dbupdate_3.4/21620_neues_feld_zum_erfassen_des_ESI.php');
require_once('dbupdate_3.4/36530_bis_internationsalisierung_codextabelle_neuerungen.php');
require_once('dbupdate_3.4/34543_ux_template.php');
require_once('dbupdate_3.4/17513_Entwicklungsteam.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
@@ -7,7 +7,8 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status
$qry = "CREATE TABLE campus.tbl_studierendenantrag_statustyp (
studierendenantrag_statustyp_kurzbz VARCHAR(32) NOT NULL,
bezeichnung VARCHAR(128)[] NOT NULL,
CONSTRAINT tbl_studierendenantrag_statustyp_pk PRIMARY KEY(studierendenantrag_statustyp_kurzbz)
CONSTRAINT tbl_studierendenantrag_statustyp_pk
PRIMARY KEY(studierendenantrag_statustyp_kurzbz)
);
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_statustyp TO vilesci;
@@ -62,6 +63,22 @@ if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statust
}
}
if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp WHERE studierendenantrag_statustyp_kurzbz = 'Pause' "))
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO campus.tbl_studierendenantrag_statustyp
(studierendenantrag_statustyp_kurzbz, bezeichnung)
VALUES
('Pause', '{\"Pausiert\",\"Paused\"}');
";
if (!$db->db_query($qry))
echo '<strong>campus.tbl_studierendenantrag_statustyp (insert): '.$db->db_last_error().'</strong><br>';
else
echo '<br>campus.tbl_studierendenantrag_statustyp: "Pause" added';
}
}
if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag LIMIT 1"))
{
$qry = "CREATE TABLE campus.tbl_studierendenantrag (
@@ -82,7 +99,9 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag LIMIT
NO MAXVALUE
NO MINVALUE
CACHE 1;
ALTER TABLE campus.tbl_studierendenantrag ALTER COLUMN studierendenantrag_id SET DEFAULT nextval('campus.tbl_studierendenantrag_studierendenantrag_id_seq');
ALTER TABLE campus.tbl_studierendenantrag
ALTER COLUMN studierendenantrag_id
SET DEFAULT nextval('campus.tbl_studierendenantrag_studierendenantrag_id_seq');
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO vilesci;
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO web;
@@ -104,16 +123,27 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status
insertamum TIMESTAMP DEFAULT NOW(),
insertvon VARCHAR(32) NOT NULL,
grund TEXT NULL,
CONSTRAINT tbl_studierendenantrag_status_pk PRIMARY KEY(studierendenantrag_status_id),
CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_statustyp_fk FOREIGN KEY (studierendenantrag_statustyp_kurzbz) REFERENCES campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT
CONSTRAINT tbl_studierendenantrag_status_pk
PRIMARY KEY(studierendenantrag_status_id),
CONSTRAINT tbl_studierendenantrag_fk
FOREIGN KEY (studierendenantrag_id)
REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_statustyp_fk
FOREIGN KEY (studierendenantrag_statustyp_kurzbz)
REFERENCES campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE SEQUENCE campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
ALTER TABLE campus.tbl_studierendenantrag_status ALTER COLUMN studierendenantrag_status_id SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq');
ALTER TABLE campus.tbl_studierendenantrag_status
ALTER COLUMN studierendenantrag_status_id
SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq');
GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO vilesci;
GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO web;
@@ -137,17 +167,32 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_lehrve
anmerkung TEXT NULL,
insertamum TIMESTAMP DEFAULT NOW(),
insertvon VARCHAR(32) NOT NULL,
CONSTRAINT tbl_studierendenantrag_lehrveranstaltung_pk PRIMARY KEY(studierendenantrag_lehrveranstaltung_id),
CONSTRAINT tbl_studiensemester_fk FOREIGN KEY (studiensemester_kurzbz) REFERENCES public.tbl_studiensemester(studiensemester_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT tbl_note_fk FOREIGN KEY (note) REFERENCES lehre.tbl_note(note) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT
CONSTRAINT tbl_studierendenantrag_lehrveranstaltung_pk
PRIMARY KEY(studierendenantrag_lehrveranstaltung_id),
CONSTRAINT tbl_studiensemester_fk
FOREIGN KEY (studiensemester_kurzbz)
REFERENCES public.tbl_studiensemester(studiensemester_kurzbz)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT tbl_note_fk
FOREIGN KEY (note)
REFERENCES lehre.tbl_note(note)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_fk
FOREIGN KEY (studierendenantrag_id)
REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE SEQUENCE campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
ALTER TABLE campus.tbl_studierendenantrag_lehrveranstaltung ALTER COLUMN studierendenantrag_lehrveranstaltung_id SET DEFAULT nextval('campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq');
ALTER TABLE campus.tbl_studierendenantrag_lehrveranstaltung
ALTER COLUMN studierendenantrag_lehrveranstaltung_id
SET DEFAULT nextval('campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq');
GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_lehrveranstaltung TO vilesci;
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_lehrveranstaltung TO web;
@@ -164,7 +209,8 @@ if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berecht
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/studierendenantrag', 'Berechtigung für Bearbeiten Studierendenanträge');";
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung)
VALUES ('student/studierendenantrag', 'Berechtigung für Bearbeiten Studierendenanträge');";
if(!$db->db_query($qry))
echo '<strong>system.tbl_berechtigung '.$db->db_last_error().'</strong><br>';
@@ -177,7 +223,8 @@ if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berecht
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/antragfreigabe', 'Berechtigung für Freigabe der Studierendenanträge');";
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung)
VALUES ('student/antragfreigabe', 'Berechtigung für Freigabe der Studierendenanträge');";
if(!$db->db_query($qry))
echo '<strong>system.tbl_berechtigung '.$db->db_last_error().'</strong><br>';
@@ -375,7 +422,8 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusg
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('abbrecherStgl', 'Abbrecher', TRUE, '{\"durch Stgl\", \"by Course Director\"}', '{\"durch Stgl\", \"by Course Director\"}');";
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig)
VALUES ('abbrecherStgl', 'Abbrecher', TRUE, '{\"durch Stgl\", \"by Course Director\"}', '{\"durch Stgl\", \"by Course Director\"}');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_status_grund '.$db->db_last_error().'</strong><br>';
@@ -388,7 +436,8 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusg
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('abbrecherStud', 'Abbrecher', TRUE, '{\"durch Stud\", \"by Student\"}', '{\"durch Stud\", \"by Student\"}');";
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig)
VALUES ('abbrecherStud', 'Abbrecher', TRUE, '{\"durch Stud\", \"by Student\"}', '{\"durch Stud\", \"by Student\"}');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_status_grund '.$db->db_last_error().'</strong><br>';
@@ -401,7 +450,8 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusg
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('preabbrecher', 'Student', TRUE, '{\"Pre-Abbrecher\", \"Pre-Aborted\"}', '{\"Pre-Abbrecher\", \"Pre-Aborted\"}');";
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig)
VALUES ('preabbrecher', 'Student', TRUE, '{\"Pre-Abbrecher\", \"Pre-Aborted\"}', '{\"Pre-Abbrecher\", \"Pre-Aborted\"}');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_status_grund '.$db->db_last_error().'</strong><br>';
+16
View File
@@ -0,0 +1,16 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
// add app fhctemplate
if($result = $db->db_query("SELECT 1 FROM system.tbl_app WHERE app='fhctemplate'"))
{
if($db->db_num_rows($result) === 0)
{
$qry = "INSERT INTO system.tbl_app (app) VALUES('fhctemplate');";
if(!$db->db_query($qry))
echo '<strong>System Tabelle app: '.$db->db_last_error().'</strong><br>';
else
echo '<br>app fhctemplate hinzugefuegt';
}
}
@@ -0,0 +1,30 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
if($result = @$db->db_query("SELECT 1 FROM bis.tbl_mobilitaetsprogramm WHERE mobilitaetsprogramm_code IN (43, 44, 45, 46, 47, 48, 49, 50, 51, 52)"))
{
if($db->db_num_rows($result) < 10)
{
$qry = "
INSERT INTO bis.tbl_mobilitaetsprogramm(mobilitaetsprogramm_code, kurzbz, beschreibung, sichtbar, sichtbar_outgoing) VALUES
(43, 'AMinKunst', 'Auslandsstipendium des Bundesministeriums für Kunst', TRUE, TRUE),
(44, 'BundeslandProg', 'Bundesland-Programm', TRUE, TRUE),
(45, 'ERASMUSSMS', 'ERASMUS+ (SMS) - Studienaufenthalte', TRUE, TRUE),
(46, 'ERASMUSSMT', 'ERASMUS+ (SMT) - Studierendenpraktika', TRUE, TRUE),
(47, 'ERASMUSMundus', 'Erasmus Mundus Joint Master Degrees / Erasmus Mundus Joint Master', FALSE, FALSE),
(48, 'EUGrad', 'Mobilitätsprogramm für Graduierte im EU-Bereich', TRUE, TRUE),
(49, 'ÖStiftung', 'Stipendienstiftung der Republik Österreich', TRUE, FALSE),
(50, 'ÖAkadWiss', 'Stipendienabkommen der Österreichischen Akademie der Wissenschaften', TRUE, TRUE),
(51, 'FondWissForsch', 'Stipendium des Fonds zur Förderung der wissenschaftlichen Forschung', TRUE, TRUE),
(52, 'SEMP', 'Swiss-European Mobility Programme (SEMP)', TRUE, TRUE)
ON CONFLICT (mobilitaetsprogramm_code) DO NOTHING;
";
if(!$db->db_query($qry))
echo '<strong>bis.tbl_mobilitaetsprogramm: '.$db->db_last_error().'</strong><br>';
else
echo ' bis.tbl_mobilitaetsprogramm: Mobilitätsprogramme hinzugefuegt<br>';
}
}
+28 -1
View File
@@ -378,7 +378,8 @@ $filters = array(
{"name" : "FoerderfallId"},
{"name" : "LeistungsdatenId"},
{"name" : "startjahr"},
{"name" : "endjahr"}
{"name" : "endjahr"},
{"name" : "Uebermittelt"}
],
"filters": []
}
@@ -1278,6 +1279,32 @@ $filters = array(
}
',
'oe_kurzbz' => null,
),
array(
'app' => 'fhctemplate',
'dataset_name' => 'exampledata',
'filter_kurzbz' => 'exampledata',
'description' => '{Beispieldaten Filter}',
'sort' => 1,
'default_filter' => true,
'filter' => '
{
"name": "Alle Beispieldaten",
"columns": [
{"name": "uid"},
{"name": "stringval"},
{"name": "integerval"},
{"name": "dateval"},
{"name": "booleanval"},
{"name": "moneyval"},
{"name": "dokument_bezeichnung"},
{"name": "textval"},
{"name": "examplestatus_kurzbz"}
],
"filters": []
}
',
'oe_kurzbz' => null
)
);
+402
View File
@@ -10862,6 +10862,7 @@ Any unusual occurrences
'app' => 'projektarbeitsbeurteilung',
'category' => 'projektarbeitsbeurteilung',
'phrase' => 'kommissionellePruefungHinweis',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
@@ -11395,6 +11396,26 @@ Any unusual occurrences
)
)
),
array(
'app' => 'core',
'category' => 'anrechnung',
'phrase' => 'anrechnung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Anrechnung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Exemption',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'anrechnung',
@@ -20508,6 +20529,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'btn_pause',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Pausieren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Pause',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'btn_unpause',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fortsetzen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Resume',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -21309,6 +21370,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'status_unpaused',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fortgesetzt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Resumed',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'status_stop',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gestoppt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Stopped',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -21509,6 +21610,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'error_no_antragstatus',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kein Status für Bekanntgabe #{id} gefunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'No status found announcement #{id}',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -21729,6 +21850,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'error_not_pausable',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bekanntgabe mit Id {id} kann nicht pausiert werden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Announcement with Id {id} cannot be not paused',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'error_not_paused',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bekanntgabe mit Id {id} ist nicht pausiert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Announcement with Id {id} is not paused',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -22673,6 +22834,7 @@ array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'dropdown_bitteWaehlen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
@@ -22688,6 +22850,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'grund_Wiederholung_deadline',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'negative kommissionelle Beurteilung und keine fristgerechte Bekanntgabe der Wiederholung des Studienjahres',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'negative assessment by the committee and no timely announcement of the repetition of the academic year',
'description' => '',
'insertvon' => 'system'
)
)
),
// Personalverwaltung begin
array(
'app' => 'core',
@@ -24196,6 +24378,226 @@ array(
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'geloescht',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gelöscht',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Deleted',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'aenderungGespeichert',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Änderung gespeichert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Saved changes',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatz',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzGenehmigen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz genehmigen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Approve dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzAblehnen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz ablehnen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reject dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzAnlegen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz anlegen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Add dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzBearbeiten',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz bearbeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Edit dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'alleGenehmigt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alle genehmigt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'All accepted',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'alleAbgelehnt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alle abgelehnt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'All rejected',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'dokument',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Dokument',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Document',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'aktionen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Aktionen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Actions',
'description' => '',
'insertvon' => 'system'
)
)
)
);
Binary file not shown.
+378
View File
@@ -0,0 +1,378 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="antraege">
<office:document-content
xmlns:officeooo="http://openoffice.org/2009/office"
xmlns:css3t="http://www.w3.org/TR/css3-text/"
xmlns:grddl="http://www.w3.org/2003/g/data-view#"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rpt="http://openoffice.org/2005/report"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
xmlns:tableooo="http://openoffice.org/2009/table"
xmlns:drawooo="http://openoffice.org/2010/draw"
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3">
<office:scripts/>
<office:font-face-decls>
<style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Lohit Devanagari" svg:font-family="&apos;Lohit Devanagari&apos;"/>
<style:font-face style:name="Lohit Devanagari1" svg:font-family="&apos;Lohit Devanagari&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Noto Sans CJK SC" svg:font-family="&apos;Noto Sans CJK SC&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Noto Serif CJK SC" svg:font-family="&apos;Noto Serif CJK SC&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Times New Roman" svg:font-family="&apos;Times New Roman&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
</office:font-face-decls>
<office:automatic-styles>
<style:style style:name="Tabelle1" style:family="table">
<style:table-properties style:width="16.245cm" fo:margin-left="-0.191cm" table:align="left" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle1.A" style:family="table-column">
<style:table-column-properties style:column-width="16.245cm"/>
</style:style>
<style:style style:name="Tabelle1.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle1.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border="none" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle2" style:family="table">
<style:table-properties style:width="16.245cm" fo:margin-left="-0.191cm" table:align="left" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle2.A" style:family="table-column">
<style:table-column-properties style:column-width="4.41cm"/>
</style:style>
<style:style style:name="Tabelle2.B" style:family="table-column">
<style:table-column-properties style:column-width="11.836cm"/>
</style:style>
<style:style style:name="Tabelle2.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle2.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border="0.5pt solid #000000" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle2.5" style:family="table-row">
<style:table-row-properties style:min-row-height="8.301cm" fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle3" style:family="table">
<style:table-properties style:width="16.245cm" fo:margin-left="-0.191cm" table:align="left" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle3.A" style:family="table-column">
<style:table-column-properties style:column-width="7.528cm"/>
</style:style>
<style:style style:name="Tabelle3.B" style:family="table-column">
<style:table-column-properties style:column-width="0.416cm"/>
</style:style>
<style:style style:name="Tabelle3.C" style:family="table-column">
<style:table-column-properties style:column-width="8.301cm"/>
</style:style>
<style:style style:name="Tabelle3.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle3.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.5pt solid #000000" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle3.B1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border="none" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle3.A2" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border-left="none" fo:border-right="none" fo:border-top="0.5pt solid #000000" fo:border-bottom="none" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:line-height="150%">
<style:tab-stops>
<style:tab-stop style:position="3.501cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="P2" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:line-height="150%">
<style:tab-stops>
<style:tab-stop style:position="3.501cm"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="P3" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="P4" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.494cm" fo:margin-bottom="0.882cm" style:contextual-spacing="false" fo:line-height="0.776cm">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="14pt" style:font-size-asian="14pt" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="P5" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P6" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" fo:language="none" fo:country="none" style:font-size-asian="9pt" style:language-asian="none" style:country-asian="none" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P7" style:family="paragraph" style:parent-style-name="Header">
<style:text-properties fo:language="none" fo:country="none" style:language-asian="none" style:country-asian="none"/>
</style:style>
<style:style style:name="P8" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false" fo:line-height="0.776cm">
<style:tab-stops>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P9" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false"/>
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P10" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" fo:language="none" fo:country="none" style:font-size-asian="9pt" style:language-asian="none" style:country-asian="none" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P11" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false"/>
</style:style>
<style:style style:name="P12" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false" style:snap-to-layout-grid="false"/>
</style:style>
<style:style style:name="P13" style:family="paragraph" style:parent-style-name="Standard">
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
</style:style>
<style:style style:name="P14" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:break-after="page"/>
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
</style:style>
<style:style style:name="T1" style:family="text">
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt"/>
</style:style>
<style:style style:name="T2" style:family="text">
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
</style:style>
<style:style style:name="T3" style:family="text">
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="T4" style:family="text">
<style:text-properties fo:font-size="9pt" fo:language="none" fo:country="none" style:font-size-asian="9pt" style:language-asian="none" style:country-asian="none" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="T5" style:family="text">
<style:text-properties fo:font-size="8pt" style:font-size-asian="8pt" style:font-size-complex="8pt"/>
</style:style>
<style:style style:name="fr1" style:family="graphic" style:parent-style-name="Graphics">
<style:graphic-properties fo:margin-left="0.319cm" fo:margin-right="0.319cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:run-through="background" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="true" style:wrap-contour-mode="outside" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:background-color="transparent" draw:fill="none" draw:fill-color="#ffffff" fo:padding="0.002cm" fo:border="none" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/>
</style:style>
<style:style style:name="Sect1" style:family="section">
<style:section-properties text:dont-balance-text-columns="true" style:writing-mode="lr-tb" style:editable="false">
<style:columns fo:column-count="1" fo:column-gap="0cm"/>
</style:section-properties>
</style:style>
</office:automatic-styles>
<office:body>
<xsl:apply-templates match="antrag"/>
</office:body>
</office:document-content>
</xsl:template>
<xsl:template match="antrag">
<office:text>
<office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
<text:tracked-changes text:track-changes="true"/>
<text:sequence-decls>
<text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
<text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
</text:sequence-decls>
<text:section text:style-name="Sect1" text:name="Bereich1" text:protected="true">
<table:table table:name="Tabelle1" table:style-name="Tabelle1">
<table:table-column table:style-name="Tabelle1.A"/>
<table:table-row table:style-name="Tabelle1.1">
<table:table-cell table:style-name="Tabelle1.A1" office:value-type="string">
<text:p text:style-name="P1">
<text:span text:style-name="T2">Studiengang:
<text:s text:c="13"/>
</text:span>
<text:span text:style-name="T4"><xsl:value-of select="studiengang"/></text:span>
</text:p>
<text:p text:style-name="P2">
<text:span text:style-name="T2">Organisationsform:
<text:tab/>
</text:span>
<text:span text:style-name="T4"><xsl:value-of select="organisationsform"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="P4">Abmeldung vom Studium durch Studiengang</text:p>
<table:table table:name="Tabelle2" table:style-name="Tabelle2">
<table:table-column table:style-name="Tabelle2.A"/>
<table:table-column table:style-name="Tabelle2.B"/>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P3">
<text:span text:style-name="T3">Name der*des Studierenden</text:span>
</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P6">
<text:span text:style-name="T4"><xsl:value-of select="name"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Personenkennzeichen</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="personenkz"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Studienjahr</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="studienjahr"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Studiensemester</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="studiensemester"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Semester</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="semester"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.5">
<table:table-cell table:style-name="Tabelle2.A1" table:number-columns-spanned="2" office:value-type="string">
<text:p text:style-name="P8">Grund der Abmeldung:</text:p>
<text:p text:style-name="P10">
<text:span text:style-name="T4"><xsl:value-of select="grund"/></text:span>
</text:p>
</table:table-cell>
<table:covered-table-cell/>
</table:table-row>
</table:table>
<text:p text:style-name="Standard"/>
<text:p text:style-name="Standard"/>
<text:p text:style-name="Standard"/>
<text:p text:style-name="Standard"/>
<text:p text:style-name="P13"/>
<text:p text:style-name="Standard">
<text:span text:style-name="T2">Wir weisen Sie darauf hin, dass Ihr FHTW Account noch 21 Tage aktiv ist. Wir bitten Sie, alle benötigte Dateien (Zeugnisse, Studienerfolgsbestätigungen, Studienbestätigungen, etc.) innerhalb dieses Zeitraums herunterzuladen. Für die Ausstellung von Duplikaten fallen nach Inaktivsetzung des CIS-Accounts Kosten an.
<text:line-break/>
</text:span>
<text:span text:style-name="T1">Sie sind gem. Ausbildungsvertrag verpflichtet, unverzüglich alle zur Verfügung gestellten Gerätschaften, Bücher, Schlüssel und sonstige Materialien zurückzugeben.</text:span>
<text:span text:style-name="T2">
<text:line-break/>Bei Abmeldung vor dem 01.09. bzw. 15.02. und bereits eingezahltem Studienbeitrag für das kommende Semester: Wir informieren Sie darüber, dass der Studienbeitrag für das kommende Semester von Ihnen zurückgefordert werden kann. Bitte geben Sie uns dafür innerhalb von 14 Tagen Ihre Bankdaten an folgende E-Mail-Adresse bekannt: billing@technikum-wien.at.
</text:span>
</text:p>
<text:p text:style-name="P14"/>
</text:section>
</office:text>
</xsl:template>
</xsl:stylesheet>
+15 -3
View File
@@ -92,6 +92,18 @@ echo '<!DOCTYPE HTML>
<title>Lehreinheit Vorrueckung</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="../../skin/vilesci.css" type="text/css">
<script type="text/javascript" src="../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
$("#select_studiensemester_kurzbz_from").change(function()
{
var index = $(this).prop("selectedIndex");
index = index-1;
$("#select_studiensemester_kurzbz_to :nth-child("+index+")").prop("selected", true);
});
});
</script>
</head>
<body style="background-color:#eeeeee;">
<h2>Lehreinheiten Vorr&uuml;ckung</h2>
@@ -132,9 +144,9 @@ for ($i = 1;$i <= 10;$i++)
}
echo '</SELECT>';
echo ' Von: <SELECT name="stsem_von">';
echo ' Von: <SELECT id="select_studiensemester_kurzbz_from" name="stsem_von">';
$stsem_obj = new studiensemester();
$stsem_obj->getAll();
$stsem_obj->getAll('desc');
foreach ($stsem_obj->studiensemester as $stsem)
{
@@ -147,7 +159,7 @@ foreach ($stsem_obj->studiensemester as $stsem)
}
echo '</SELECT>';
echo ' Nach: <SELECT name="stsem_nach">';
echo ' Nach: <SELECT id="select_studiensemester_kurzbz_to" name="stsem_nach">';
foreach ($stsem_obj->studiensemester as $stsem)
{
+1 -1
View File
@@ -108,7 +108,7 @@ echo '<form action="studienplan_vorrueckung.php" method="POST">';
echo ' Quelle: <select id="select_studiensemester_kurzbz_from" name="studiensemester_kurzbz_from" />';
$stsem = new studiensemester();
$stsem->getPlusMinus(null,10,'ende ASC');
$stsem->getPlusMinus(null,10,'ende DESC');
foreach($stsem->studiensemester as $row)
{
+1 -1
View File
@@ -56,7 +56,7 @@ $uid_benutzer = get_uid();
$rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($uid_benutzer);
if(!$rechte->isBerechtigt('mitarbeiter', null, 's'))
if(!$rechte->isBerechtigt('mitarbeiter/zeitwuensche', null, 's'))
die($rechte->errormsg);
$datum_obj = new datum();
@@ -38,6 +38,8 @@ require_once('../../include/benutzer.class.php');
require_once('../../include/funktion.class.php');
require_once('../../include/wawi_kostenstelle.class.php');
require_once('../../include/log.class.php');
require_once('../../include/mitarbeiter.class.php');
require_once('../../include/datum.class.php');
/*
* TODOs
@@ -60,6 +62,7 @@ BEschreibungstexte bestehender Rechte
*/
$user = get_uid();
$datum = new datum();
$rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($user);
@@ -68,7 +71,14 @@ if (!$db = new basis_db())
die('Fehler beim öffnen der Datenbankverbindung');
if(!$rechte->isBerechtigt('basis/berechtigung'))
die('Sie haben keine Berechtigung fuer diese Seite');
die($rechte->errormsg);
$mitarbeiter = new mitarbeiter($user);
$userKuerzel = $user;
if ($mitarbeiter->kurzbz != '')
{
$userKuerzel = $mitarbeiter->kurzbz;
}
//$reloadstr = ''; // neuladen der liste im oberen frame
$htmlstr = '';
@@ -104,7 +114,27 @@ if(isset($_POST['delete']) && $_POST['delete'] != '')
$ber = new benutzerberechtigung();
if(!$ber->delete($benutzerberechtigung_id))
{
$errorstr .= 'Datensatz konnte nicht gel&ouml;scht werden!';
}
else
{
//Log schreiben
$log = new log();
$logdata = var_export((array) $ber, true);
$log->new = true;
$log->sql = $logdata;
$log->sqlundo = 'Kein Undo vorhanden';
$log->executetime = date('Y-m-d H:i:s');
$log->mitarbeiter_uid = $user;
$log->beschreibung = 'Berechtigung gelöscht';
if(!$log->save())
{
$errorstr .= "<span style='color: red'><b>Fehler beim schreiben des Log-Eintrags</b></span><br>";
}
}
//$reloadstr .= "<script type='text/javascript'>";
//$reloadstr .= " parent.uebersicht.location.href='benutzerberechtigung_uebersicht.php';";
@@ -172,7 +202,13 @@ if(isset($_POST['uebertragen']) && $_POST['uebertragen_nach'] != '')
//echo '<pre>', var_dump($_POST), '</pre>';exit();
if($rechte->isBerechtigt('basis/berechtigung', null, 'suid'))
{
$mitarbeiter = new mitarbeiter($_POST['uid']);
$uidVon = $_POST['uid'];
if ($mitarbeiter->kurzbz != '')
{
$uidVon = $mitarbeiter->kurzbz;
}
$copyTo = $_POST['uebertragen_nach'];
if (isset($_POST['dataset']))
@@ -215,12 +251,12 @@ if(isset($_POST['uebertragen']) && $_POST['uebertragen_nach'] != '')
$ber->uid = $copyTo;
$ber->funktion_kurzbz = $funktion_kurzbz;
$ber->studiensemester_kurzbz = $studiensemester_kurzbz;
$ber->start = $start;
$ber->start = date('Y-m-d');
$ber->ende = $ende;
$ber->updateamum = date('Y-m-d H:i:s');
$ber->updatevon = $user;
$ber->kostenstelle_id = $kostenstelle_id;
$ber->anmerkung = 'Kopiert von UID '.$uidVon.($anmerkung!=''?'. Anmerkung von UID '.$uidVon.': '.$anmerkung:'');
$ber->anmerkung = 'Kp '.$uidVon.($anmerkung != '' ? ': '.$anmerkung : '');
if(!$ber->save())
{
@@ -317,6 +353,88 @@ if(isset($_POST['setDate_multi']) && $_POST['setDate_multi'] != '')
//$reloadstr .= "<script type='text/javascript'>";
//$reloadstr .= " parent.uebersicht.location.href='benutzerberechtigung_uebersicht.php';";
//$reloadstr .= "</script>";
}
if(isset($_POST['save_anmerkung_multi']) && $_POST['anmerkung_multi'] != '')
{
if(!$rechte->isBerechtigt('basis/berechtigung', null, 'su'))
die($rechte->errormsg);
$anmerkungNeu = $_POST['anmerkung_multi'];
if (isset($_POST['dataset']))
{
$i = 0;
foreach ($_POST['dataset'] AS $benutzerberechtigung_id => $value)
{
// Nur markierte Einträge bearbeiten
if (!isset($value['check']))
{
continue;
}
$ber = new benutzerberechtigung();
if(!$ber->load($benutzerberechtigung_id))
{
die('Fehler beim Laden der Berechtigung');
}
// Bestehende Anmerkungen belassen und neue Ergänzen
if ($ber->anmerkung != '')
{
$ber->anmerkung = $ber->anmerkung.'; '.$anmerkungNeu;
}
else
{
$ber->anmerkung = $anmerkungNeu;
}
// Wenn Anmerkung länger als 256 Zeichen ist (DB-Beschränkung), String kürzen und Warnung ausgeben
if (strlen($ber->anmerkung) > 256)
{
$ber->anmerkung = cutString($ber->anmerkung, 256, '...');
$errorstr .= "<span style='color: red'><b>Die Anmerkung bei der ID ".$benutzerberechtigung_id." übersteigt die maximale Länge von 256 Zeichen und wurde nicht vollständig gespeichert</b></span><br>";
}
$ber->updateamum = date('Y-m-d H:i:s');
$ber->updatevon = $user;
if(!$ber->save())
{
$errorstr .= "Die Anmerkung des Datensatzes mit der ID ".$benutzerberechtigung_id." konnte nicht gespeichert werden!".$ber->errormsg;
}
else
{
$i ++;
//Log schreiben
$log = new log();
$logdata = var_export((array) $ber, true);
$log->new = true;
$log->sql = $logdata;
$log->sqlundo = 'Kein Undo vorhanden';
$log->executetime = date('Y-m-d H:i:s');
$log->mitarbeiter_uid = $user;
$log->beschreibung = 'Anmerkung bearbeitet';
if(!$log->save())
{
$errorstr .= "<span style='color: red'><b>Fehler beim schreiben des Log-Eintrags</b></span><br>";
}
}
}
if ($i > 0)
{
$successstr .= "<span style='color: green'><b>Anmerkung bei ".$i." Einträgen erfolgreich gespeichert</b></span><br>";
}
}
//$reloadstr .= "<script type='text/javascript'>";
//$reloadstr .= " parent.uebersicht.location.href='benutzerberechtigung_uebersicht.php';";
//$reloadstr .= "</script>";
@@ -424,6 +542,10 @@ if(isset($_POST['schick']))
}
}
}
if ($errorstr == '')
{
$successstr .= "<span style='color: green'><b>Änderungen erfolgreich gespeichert</b></span><br>";
}
}
}
else
@@ -503,14 +625,16 @@ $oe = new organisationseinheit();
$oe->getAll();
foreach ($oe->result AS $row)
{
$oe_arr[$row->oe_kurzbz] = $row->organisationseinheittyp_kurzbz.' '.$row->bezeichnung;
$oe_arr[$row->oe_kurzbz]['bezeichnung'] = $row->organisationseinheittyp_kurzbz.' '.$row->bezeichnung;
$oe_arr[$row->oe_kurzbz]['aktiv'] = $row->aktiv;
}
$kostenstelle = new wawi_kostenstelle();
$kostenstelle->getAll();
foreach ($kostenstelle->result AS $row)
{
$kst_arr[$row->kostenstelle_id] = $row->bezeichnung;
$kst_arr[$row->kostenstelle_id]['bezeichnung'] = $row->bezeichnung;
$kst_arr[$row->kostenstelle_id]['aktiv'] = $row->aktiv;
}
if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
@@ -536,23 +660,27 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$name = new benutzer();
$name->load($uid);
$htmlstr .= "Berechtigungen von <b>".$name->nachname." ".$name->vorname." (".$uid.")</b>";
$htmlstr .= "Berechtigungen von <b>".$name->nachname." ".$name->vorname." (".$uid.")</b> <a href='".CIS_ROOT."cis/private/profile/index.php?uid=".$uid."' target='_blank'>Zum CIS-Profil</a>";
$message = '';
$class = '';
$messageString = '';
if ($errorstr != '' || $successstr != '')
{
if ($successstr != '')
{
$class = 'class="alert alert-success"';
$message = $successstr;
$messageString .= ' <div '.$class.'>'.$message.'</div>';
}
elseif ($errorstr != '')
if ($errorstr != '')
{
$class = 'class="alert alert-danger"';
$message = $errorstr;
$messageString .= ' <div '.$class.'>'.$message.'</div>';
}
}
$htmlstr .= ' <div id="msgbox" '.$class.'>'.$message.'</div>';
$htmlstr .= ' <div id="msgbox">'.$messageString.'</div>';
$i = 0;
@@ -643,8 +771,9 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
</tr></thead><tbody>";
$htmlstr .= "<tr id='neu'>";
$htmlstr .= "<form action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST' name='berechtigung_neu'>";
$htmlstr .= "<form id='formNeuesRecht' action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST' name='berechtigung_neu'>";
$htmlstr .= "<input type='hidden' name='neu' value='1'>";
$htmlstr .= "<input type='hidden' name='schick' value='1'>";
$htmlstr .= "<input type='hidden' name='benutzerberechtigung_id' value=''>";
$htmlstr .= "<input type='hidden' name='uid' value='".$uid."'>";
$htmlstr .= "<input type='hidden' name='funktion_kurzbz' value='".$funktion_kurzbz."'>";
@@ -708,7 +837,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$htmlstr .= " <td align='center'><input type='checkbox' name='dataset[0][negativ]'></td>";
//Start
$htmlstr .= " <td nowrap><input class='datepicker_datum' type='text' name='dataset[0][start]' value='' size='10' maxlength='10'></td>";
$htmlstr .= " <td nowrap><input class='datepicker_datum' type='text' name='dataset[0][start]' value='".date('Y-m-d')."' size='10' maxlength='10'></td>";
//Ende
$htmlstr .= " <td nowrap><input class='datepicker_datum' type='text' name='dataset[0][ende]' value='' size='10' maxlength='10'></td>";
@@ -716,7 +845,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
//Anmerkung
$htmlstr .= " <td><input id='anmerkung_neu' type='text' name='dataset[0][anmerkung]' value='' size='100' maxlength='256'></td>";
$htmlstr .= " <td><input type='submit' name='schick' value='Neu anlegen' onclick='return validateNewData()'></td>";
//$htmlstr .= " <td><input type='submit' name='schick' value='Neu anlegen' onclick='return validateNewData()'></td>";
$htmlstr .= "</form>";
$htmlstr .= " </tr></tbody></table>";
@@ -726,8 +855,8 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
// Tabelle für bestehende Berechtigungen
////////////////
$htmlstr .= "<p style='font-size: small' id='anzahl'></p>";
$htmlstr .= "<form action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST'>";
$htmlstr .= "<div class='pull-left' style='font-size: small' id='anzahl'></div><div class='pull-right' style='font-size: smaller'>STRG+ALT+T fügt Datum ein</div>";
$htmlstr .= "<form id='formRechte' action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST'>";
$htmlstr .= "<input type='hidden' name='uid' value='".$uid."'>";
$htmlstr .= "<input type='hidden' name='funktion_kurzbz' value='".$funktion_kurzbz."'>";
@@ -759,6 +888,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
</tr></thead><tbody>";
$countInaktiveUndWawi = 0;
foreach($rights->berechtigungen as $b)
{
switch($filter)
@@ -775,7 +905,6 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
default: break;
}
$htmlstr .= " <tr class='row_berechtigung' id='".$b->benutzerberechtigung_id."'>";
$heute = strtotime(date('Y-m-d'));
if ($b->ende!='' && strtotime($b->ende) < $heute)
{
@@ -798,6 +927,17 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$inaktiv_class = '';
$data = 'gruen';
}
// Inaktive Elemente sowie WaWi-Rechte ausblenden
if ($b->ende!='' && strtotime($b->ende) < $heute || $b->rolle_kurzbz == 'wawi' || substr($b->berechtigung_kurzbz, 0, 4) == 'wawi')
{
$htmlstr .= " <tr class='row_berechtigung ausgeblendet' id='".$b->benutzerberechtigung_id."'>";
$countInaktiveUndWawi++;
}
else
{
$htmlstr .= " <tr class='row_berechtigung' id='".$b->benutzerberechtigung_id."'>";
}
// Auswahlcheckbox
$htmlstr .= " <td $style class='auswahlcheckboxen' name='td_$b->benutzerberechtigung_id' data-".$data."='".$data."'>";
$htmlstr .= " <span style='display: none'>".$titel."</span>";
@@ -862,9 +1002,10 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
else
{
$htmlstr .= " <td class='oe_column'>";
$htmlstr .= " <span style='display: none'>".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz] : '')."</span>";
$htmlstr .= " <span style='display: none'>".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz]['bezeichnung'] : '')."</span>";
$htmlstr .= " <input type='hidden' name='dataset[$b->benutzerberechtigung_id][oe_kurzbz]' value='$b->oe_kurzbz'>";
$htmlstr .= " <input type='text' class='oe_kurzbz_autocomplete $inaktiv_class' value='".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz] : '')."'>";
$style = isset($oe_arr[$b->oe_kurzbz]) && $oe_arr[$b->oe_kurzbz]['aktiv'] == false? 'style="text-decoration: line-through"' : '';
$htmlstr .= " <input $style type='text' class='oe_kurzbz_autocomplete $inaktiv_class' value='".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz]['bezeichnung'] : '')."'>";
$htmlstr .= " </td>";
}
@@ -872,7 +1013,8 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$htmlstr .= " <td class='ks_column'>";
$htmlstr .= " <span style='display: none'>".$b->kostenstelle_id."</span>";
$htmlstr .= " <input type='hidden' name='dataset[$b->benutzerberechtigung_id][kostenstelle_id]' value='$b->kostenstelle_id'>";
$htmlstr .= " <input type='text' class='kostenstelle_autocomplete $inaktiv_class' value='".($b->kostenstelle_id != '' ? $kst_arr[$b->kostenstelle_id] : '')."'>";
$style = isset($kst_arr[$b->kostenstelle_id]) && $kst_arr[$b->kostenstelle_id]['aktiv'] == false ? 'style="text-decoration: line-through"' : '';
$htmlstr .= " <input $style type='text' class='kostenstelle_autocomplete $inaktiv_class' value='".($b->kostenstelle_id != '' ? $kst_arr[$b->kostenstelle_id]['bezeichnung'] : '')."'>";
$htmlstr .= " </td>";
@@ -960,20 +1102,39 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$htmlstr .= " </tr>";
}
$htmlstr .= "</tbody></table>";
//Button zum einblenden ausgeblendeter Zeilen
if ($countInaktiveUndWawi > 0)
{
$htmlstr .= "<button type='button' class='btn btn-default' onclick='show_hidden()'>Inaktive und WaWi anzeigen</button>";
}
// Speichern und Aktions-Bereich
$htmlstr .= '<div id="bottomArea" >
<div class="input-group">
<button type="submit" class="btn btn-default" name="schick" onclick="return validateSpeichern()" style="margin-bottom: 10px">Speichern</button>
<div class="form-inline" style="">
<button id="ButtonNeu" type="button" class="btn btn-default" name="schick" onclick="return submitNeuesRecht()" style="margin-bottom: 10px">Neues Recht speichern</button>
<button id="ButtonSpeichern" type="submit" class="btn btn-default" name="schick" onclick="return validateSpeichern()" style="margin-bottom: 10px">Änderungen Speichern</button>
<div class="form-inline multi-options" style="">
<div class="input-group" style="width: 180px;">
<input type="text" id="input_uebertragen_nach" name="uebertragen_nach" class="form-control benutzer_autocomplete" placeholder="Zu UID übertragen">
<input type="text" id="input_uebertragen_nach" name="uebertragen_nach" class="form-control benutzer_autocomplete" placeholder="Zu UID übertragen" disabled>
<div class="input-group-btn">
<button class="btn btn-default" type="submit" id="button_uebertragen" name="uebertragen" onclick="return validateUebertragen()">
<button class="btn btn-default" type="submit" id="button_uebertragen" name="uebertragen" onclick="return validateUebertragen()" disabled>
<i class="glyphicon glyphicon-transfer" style="line-height: unset"></i>
</button>
</div>
</div>
<button type="submit" id="button_mehrfachbeenden" name="setDate_multi" value="setDate_multi" class="btn btn-default" onclick="return validateBeenden()">Ende setzen</button>
<button type="submit" id="button_mehrfachloeschen" name="delete_multi" value="delete_multi" class="btn btn-warning" onclick="return validateDeleteMulti()">Markierte löschen</button>
<button type="submit" id="button_mehrfachbeenden" name="setDate_multi" value="setDate_multi" class="btn btn-default" onclick="return validateBeenden()" disabled>Ende setzen</button>
<button type="submit" id="button_mehrfachloeschen" name="delete_multi" value="delete_multi" class="btn btn-warning" onclick="return validateDeleteMulti()" disabled>Markierte löschen</button>
</div>
<div class="form-inline multi-options" style="">
<div class="input-group" style="width: 180px;">
<input type="text" id="input_anmerkung_multi" maxlength="256" name="anmerkung_multi" class="form-control" placeholder="Mehrfach-Anmerkung" style="width: 390px;" disabled>
<div class="input-group-btn">
<button class="btn btn-default" type="submit" id="button_anmerkung_multi" name="save_anmerkung_multi" onclick="return validateAnmerkungMulti()" disabled>
<i class="glyphicon glyphicon-ok" style="line-height: unset"></i>
</button>
</div>
</div>
</div>
</div>
</div>';
@@ -992,6 +1153,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
<link href="../../skin/tablesort.css" rel="stylesheet" type="text/css"/>
<link href="../../skin/jquery-ui-1.9.2.custom.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="../../vendor/twbs/bootstrap3/dist/css/bootstrap.min.css">
<script type="text/javascript" src="../../include/tiny_mce/tiny_mce.js"></script>
<script src="../../include/js/mailcheck.js"></script>
<script src="../../include/js/datecheck.js"></script>
<!-- <script type="text/javascript" src="../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>-->
@@ -1268,6 +1430,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
/*border-right: 1px solid #999;*/
margin-left: auto;
display: block ruby;
border-top-left-radius: 4px;
}
#msgbox
{
@@ -1306,8 +1469,35 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
{
background-color: #f3f3f3 !important;
}
.ausgeblendet
{
display: none;
}
/*.multi-options*/
/*{*/
/* display: none;*/
/*}*/
</style>
<script type="text/javascript">
$.tablesorter.addParser({
id: "customDate",
is: function(s) {
//return false;
//use the above line if you don\'t want table sorter to auto detected this parser
// match dd.mm.yyyy e.g. 01.01.2001 as regex
//return /\d{1,4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2} .*/.test(s);
return /\d{1,2}.\d{1,2}.\d{1,4} \d{1,2}:\d{1,2} .*/.test(s);
},
// replace regex-wildcards and return new date
format: function(s) {
s = s.replace(/\-/g," ");
s = s.replace(/:/g," ");
s = s.replace(/\./g," ");
s = s.split(" ");
return $.tablesorter.formatFloat(new Date(s[2], s[1]-1, s[0], s[3], s[4]).getTime());
},
type: "numeric"
});
$(document).ready(function()
{
// $("[data-toggle=\"popover\"]").popover();
@@ -1358,6 +1548,13 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
else return $(node).text();
}
});
$("#t2").tablesorter(
{
sortList: [[0,1]],
widgets: ["filter"],
headers: { 0: { sorter: "customDate"}},
widgetOptions : {}
});
//document.berechtigung_neu.rolle_kurzbz.focus();
// Breite des Autocompletes korrigieren um das Springen zu verhindern
@@ -1499,18 +1696,100 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
var aktiv = $('td.auswahlcheckboxen[data-gruen]').length + $('td.auswahlcheckboxen[data-gelb]').length;
var inaktiv = $('td.auswahlcheckboxen[data-rot]').length;
$("#anzahl").html(aktiv + inaktiv + " Einträge (" + aktiv + " Aktive, " + inaktiv + " Inaktive)");
$("#anzahl").html(aktiv + inaktiv + " Einträge (" + aktiv + " Aktive, " + inaktiv + " Inaktive (ausgeblendet))");
/*$('.checkbox').each(function ()
{
$("#t1").checkboxes('range', true);
});*/
$("#uncheck_t1").on('click', function(e) {
$("#uncheck_t1").on('click', function(e)
{
$(".auswahlcheckboxen").checkboxes('uncheck');
e.preventDefault();
});
// Wenn eine Auswahlcheckbox angeklickt wird, Zusatzoptionen anzeigen
$(".auswahlcheckbox").change(function() {
if ($(".auswahlcheckbox:checked").length > 0)
{
// Aktiviere Inputs, wenn mindestens eine Checkbox ausgewählt ist
$(".multi-options input[type=text]").prop('disabled', false);
$(".multi-options").find("button").prop('disabled', false);
}
else
{
// Deaktiviere Inputs, wenn keine Checkbox ausgewählt ist
$(".multi-options input[type=text]").prop('disabled', true);
$(".multi-options").find("button").prop('disabled', true);
}
});
// Wenn etwas ins Neu-Formular eingegeben wird, nur den Neu-Speicherbutton aktivieren, sonst den anderen
$("#neu :input").on( "input", function() {
var filled = false;
$("#formNeuesRecht :input").each(function() {
if ($(this).val().trim() !== '') {
filled = true;
return false; // Brechen Sie die each-Schleife ab, wenn ein gefülltes Feld gefunden wurde
}
});
// Aktualisieren Sie den Status des Buttons basierend auf den Änderungen in den Feldern
$("#ButtonSpeichern").prop("disabled", !filled);
$("#ButtonNeu").prop("disabled", filled);
// Aktualisieren Sie die Variable, um den Status zu speichern
isButtonDisabled = !filled;
});
// Wenn etwas ins Rechte-Formular eingegeben wird, nur den Speicherbutton aktivieren, sonst den anderen
$("#formRechte :input").on( "input", function() {
var filled = false;
$("#formNeuesRecht :input").each(function() {
if ($(this).val().trim() !== '') {
filled = true;
return false; // Brechen Sie die each-Schleife ab, wenn ein gefülltes Feld gefunden wurde
}
});
// Aktualisieren Sie den Status des Buttons basierend auf den Änderungen in den Feldern
$("#ButtonNeu").prop("disabled", !filled);
$("#ButtonSpeichern").prop("disabled", filled);
// Aktualisieren Sie die Variable, um den Status zu speichern
isButtonDisabled = !filled;
});
$('input[type="text"]').on('keydown', function(e){
if(e.ctrlKey && e.altKey && e.keyCode == 84){ // Wenn Strg + Alt + T gedrückt wird
e.preventDefault();
insertDatumAtCursor(this);
}
});
function insertDatumAtCursor(input){
var startPos = input.selectionStart;
var endPos = input.selectionEnd;
var currentDate = getCurrentDateAndUser();
var text = $(input).val();
var newText = text.substring(0, startPos) + currentDate + text.substring(endPos, text.length);
$(input).val(newText);
$(input).prop('selectionStart', startPos + currentDate.length);
$(input).prop('selectionEnd', startPos + currentDate.length);
}
function getCurrentDateAndUser()
{
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); // Januar ist 0!
var yyyy = today.getFullYear();
return dd + '.' + mm + '.' + yyyy+ ' <?php echo $userKuerzel; ?>: ';
}
//if (typeof $("#filterTableDataset").checkboxes === 'function')
// $("#filterTableDataset").checkboxes("range", true);
//$("input.auswahlcheckbox").checkboxes('range', true); //Wählt ALLE Checkboxen. Funktioniert nicht mit anderem selector
@@ -1539,6 +1818,22 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
return true;
}
function validateAnmerkungMulti()
{
if($('input.auswahlcheckbox:checked').length == 0)
{
alert('Bitte mindestens eine Berechtigung auswählen');
return false;
}
else if($('#input_anmerkung_multi').val() == '')
{
alert('Bitte Text eingeben, der als Anmerkung hinzugefügt werden soll');
return false;
}
else
return true;
}
function validateBeenden()
{
if($('input.auswahlcheckbox:checked').length == 0)
@@ -1584,18 +1879,17 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
}
else if ($('#art_neu').val() != '')
{
var eingabe, c, erlaubt = 'suid', laenge;
eingabe = $('#art_neu').val();
eingabe = eingabe.toLowerCase();
laenge = eingabe.length;
for (c = 0; c < laenge; c++)
var eingabe = $('#art_neu').val().toLowerCase();
var erlaubt = ['s', 'su', 'sui', 'suid'];
if (erlaubt.includes(eingabe))
{
d = eingabe.charAt(c);
if (erlaubt.indexOf(d) == -1)
{
alert ('Erlaubte Werte für Art sind s,u,i,d');
return false;
return true;
}
else
{
alert('Erlaubte Werte für Art sind s, su, sui, suid');
return false;
}
}
else
@@ -1697,7 +1991,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
function validateArt(id)
{
var eingabe, c, erlaubt = 'suid', laenge;
eingabe = document.getElementById(id).value;;
eingabe = document.getElementById(id).value;
eingabe = eingabe.toLowerCase();
laenge = eingabe.length;
if (eingabe == '')
@@ -1718,6 +2012,22 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
document.getElementById(id).style.border = "";
}
}
function show_hidden()
{
$("tr.ausgeblendet:hidden").each(function()
{
$(this).fadeIn(1000);
});
}
function submitNeuesRecht()
{
if (validateNewData())
{
var form = document.getElementById("formNeuesRecht");
form.submit();
}
}
</script>
</head>
<body style="background-color:#eeeeee;">
@@ -29,17 +29,20 @@ require_once('../../include/benutzer.class.php');
require_once('../../include/berechtigung.class.php');
require_once ('../../include/organisationseinheit.class.php');
require_once ('../../include/benutzerfunktion.class.php');
require_once ('../../include/funktion.class.php');
echo '<html>
<head>
<title>Berechtigungen Uebersicht</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../skin/vilesci.css" type="text/css">';
<link rel="stylesheet" href="../../skin/vilesci.css" type="text/css">
<link href="../../skin/jquery-ui-1.9.2.custom.min.css" rel="stylesheet" type="text/css">';
include('../../include/meta/jquery.php');
include('../../include/meta/jquery-tablesorter.php');
echo '
<script type="text/javascript" src="../../vendor/components/jqueryui/jquery-ui.min.js"></script>
<script language="JavaScript" type="text/javascript">
function checkLength()
{
@@ -54,14 +57,14 @@ function checkLength()
}
$(document).ready(function()
{
if ($("#berechtigung_kurzbz").val() == "" && $("#rolle_kurzbz").val() == "")
if ($("#berechtigung_kurzbz").val() == "" && $("#rolle_kurzbz").val() == "" && $("#person_oe_kurzbz").val() == "")
$("#erweitertesuche").hide();
$("#t1").tablesorter(
{
sortList: [[0,0],[1,0],[2,0]],
widgets: ["zebra"],
headers: {4:{sorter:false}}
sortList: [[4,0],[0,0],[1,0],[2,0]],
widgets: ["zebra", "filter", "stickyHeaders"]
//headers: {4:{sorter:false}}
});
$("#t2").tablesorter(
{
@@ -72,11 +75,11 @@ $(document).ready(function()
widgetOptions : { filter_functions:
{
// Add select menu to this column
6 : {
"Ja" : function(e, n, f, i, $r, c, data) { return e == "Ja" || e == "" },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
},
7 : {
"Ja" : function(e, n, f, i, $r, c, data) { return e === "Ja" || /^\s*$/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return e === "Nein" || /^\s*$/.test(e); }
},
8 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
@@ -93,8 +96,8 @@ $(document).ready(function()
{
// Add select menu to this column
6 : {
"Ja" : function(e, n, f, i, $r, c, data) { return /Ja/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
"Ja" : function(e, n, f, i, $r, c, data) { return e === "Ja" || /^\s*$/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return e === "Nein" || /^\s*$/.test(e); }
},
7 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
@@ -123,6 +126,67 @@ $(document).ready(function()
}
}
});
$("#t5").tablesorter(
{
sortList: [[0,0],[1,0],[3,1]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {4:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
4 : {
"Ja" : function(e, n, f, i, $r, c, data) { return /Ja/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
}
}
}
});
// Breite des Autocompletes korrigieren um das Springen zu verhindern
$.extend($.ui.autocomplete.prototype.options, {
open: function(event, ui) {
$(this).autocomplete("widget").css({
"width": ($(".ui-menu-item").width()+ 20 + "px"),
"padding-left": "5px"
});
}
});
$(".oe_kurzbz_autocomplete").autocomplete({
source: "benutzerberechtigung_autocomplete.php?autocomplete=oe_kurzbz",
minLength:2,
response: function(event, ui)
{
if (!ui.content.length)
{
var noResult = { value:"",label:"Keine Ergebnisse" };
ui.content.push(noResult);
}
else
{
//Value und Label fuer die Anzeige setzen
for (i in ui.content) {
ui.content[i].value = ui.content[i].organisationseinheittyp_kurzbz + " " + ui.content[i].bezeichnung;
ui.content[i].label = ui.content[i].organisationseinheittyp_kurzbz + " " + ui.content[i].bezeichnung;
}
}
},
select: function(event, ui)
{
$(this).siblings("input:hidden").val(ui.item.oe_kurzbz);
}
});
$(".oe_kurzbz_autocomplete").on( "input", function() {
if ($(this).val() == "")
{
$(this).siblings("input:hidden").val("");
}
});
$("#person_oe_kurzbz").on( "click", function() {
$(this).select();
});
$("#searchbox").on( "click", function() {
$(this).select();
});
});
</script>
@@ -199,10 +263,11 @@ if(!$rechte->isBerechtigt('basis/berechtigung'))
$htmlstr = "";
$searchstr = (isset($_GET['searchstr'])?$_GET['searchstr']:'');
$benutzerart = (isset($_GET['benutzerart'])?$_GET['benutzerart']:'');
$benutzerart = (isset($_GET['benutzerart'])?$_GET['benutzerart']:'mitarbeiter');
$benutzeraktiv = (isset($_GET['aktiv'])?$_GET['aktiv']:'aktiv');
$berechtigung_kurzbz = (isset($_GET['berechtigung_kurzbz'])?$_GET['berechtigung_kurzbz']:'');
$rolle_kurzbz = (isset($_GET['rolle_kurzbz'])?$_GET['rolle_kurzbz']:'');
$person_oe_kurzbz = (isset($_GET['person_oe_kurzbz'])?$_GET['person_oe_kurzbz']:'');
$userOnly = (isset($_GET['userOnly']) ? true : false);
$htmlstr='
@@ -228,6 +293,13 @@ $htmlstr='
</form>
<div id="erweitertesuche">
<hr>
<form accept-charset="UTF-8" name="searchPersonenOe" method="GET">
Personen in Organisationseinheit:
<input type="hidden" name="person_oe_kurzbz" value="'.$person_oe_kurzbz.'">
<input type="text" id="person_oe_kurzbz" value="'.$person_oe_kurzbz.'" class="oe_kurzbz_autocomplete">
<input type="submit" value="Suchen">
</form>
<hr>
<form accept-charset="UTF-8" name="searchrechte" method="GET">
Rechte:
<select id="berechtigung_kurzbz" name="berechtigung_kurzbz">
@@ -366,6 +438,7 @@ if($berechtigung_kurzbz != '')
<th>Nachname</th>
<th>Vorname</th>
<th>UID</th>
<th>Organisationseinheit</th>
<th>Art</th>
<th data-value='Ja'>Benutzer Aktiv</th>
<th data-value='Aktiv'>Status</th>
@@ -377,6 +450,8 @@ if($berechtigung_kurzbz != '')
$benutzer = new benutzer();
$benutzer->load($row->uid);
$organisationseinheit = new organisationseinheit($row->oe_kurzbz);
$heute = strtotime(date('Y-m-d'));
if ($row->ende!='' && strtotime($row->ende) < $heute)
@@ -398,6 +473,7 @@ if($berechtigung_kurzbz != '')
$htmlstr .= ' <td>'.($benutzer->nachname != ''?$benutzer->nachname:'').'</td>';
$htmlstr .= ' <td>'.($benutzer->vorname != ''?$benutzer->vorname:'').'</td>';
$htmlstr .= ' <td>'.($row->uid != ''?$row->uid:'').'</td>';
$htmlstr .= ' <td style="text-overflow: ellipsis; white-space: nowrap; overflow:hidden;">'.($row->oe_kurzbz != '' ? $organisationseinheit->organisationseinheittyp_kurzbz.' '.$organisationseinheit->bezeichnung:'').'</td>';
$htmlstr .= ' <td>'.$row->art.'</td>';
$htmlstr .= ' <td>'.(isset($row->uid)?$benutzer->bnaktiv?'Ja':'Nein':'').'</td>';
$htmlstr .= ' <td align="center">'.$status.'</td>';
@@ -552,7 +628,7 @@ if($rolle_kurzbz != '')
// Anzahl uniquer UIDs ermitteln
$berechtigungen_array_uids = sizeof(array_column($rollen->result, null, 'uid'));
$htmlstr .= "<h3>".$berechtigung_kurzbz."</h3>\n";
$htmlstr .= "<h3>".$rolle_kurzbz."</h3>\n";
$htmlstr .= "<div style='font-size: 9pt'>".count($rollen->result)." Einträge</div>";
$htmlstr .= "<div style='font-size: 9pt'>".$berechtigungen_array_uids." UIDs</div>";
$htmlstr .= "<table id='t3' class='tablesorter'><thead><tr>\n";
@@ -607,6 +683,76 @@ if($rolle_kurzbz != '')
}
}
//Personen in OEs suchen und Tabelle anzeigen
if($person_oe_kurzbz != '')
{
$childOes = new organisationseinheit();
$oeChilds = $childOes->getChilds($person_oe_kurzbz);
$uids = array();
$countUID = array();
$benutzerfunktion = new benutzerfunktion();
foreach ($oeChilds AS $key => $oe)
{
$benutzerfunktion->getOeFunktionen($oe,'kstzuordnung,fachzuordnung','now()','now()');
foreach($benutzerfunktion->result as $bf)
{
$oeFunktion = new organisationseinheit($bf->oe_kurzbz);
$funktion = new funktion($bf->funktion_kurzbz);
$uids[$bf->uid.$bf->oe_kurzbz] = ["uid" => $bf->uid, "funktion" => $funktion->beschreibung." ".$oeFunktion->bezeichnung];
$countUID[] = $bf->uid;
}
$benutzerfunktion->getOeFunktionen($oe,'Leitung,stvLtg,oezuordnung','now()','now()');
foreach($benutzerfunktion->result as $bf)
{
$oeFunktion = new organisationseinheit($bf->oe_kurzbz);
$funktion = new funktion($bf->funktion_kurzbz);
$uids[$bf->uid.$bf->oe_kurzbz] = ["uid" => $bf->uid, "funktion" => $funktion->beschreibung." ".$oeFunktion->bezeichnung];
$countUID[] = $bf->uid;
}
}
if(count($uids) != 0)
{
// Anzahl uniquer UIDs ermitteln
$berechtigungen_array_uids = count($uids);
$countUID = array_unique($countUID);
$oeName = new organisationseinheit($person_oe_kurzbz);
$htmlstr .= "<h3>".$oeName->organisationseinheittyp_kurzbz." ".$oeName->bezeichnung."</h3>\n";
$htmlstr .= "<div style='font-size: 9pt'>".$berechtigungen_array_uids." Einträge</div>";
$htmlstr .= "<div style='font-size: 9pt'>".count($countUID)." UIDs</div>";
$htmlstr .= "<table id='t5' class='tablesorter'><thead><tr>\n";
$htmlstr .= " <th>Nachname</th>
<th>Vorname</th>
<th>UID</th>
<th>Funktion</th>
<th data-value='Ja'>Benutzer Aktiv</th>
<th>Aktion</th>";
$htmlstr .= "</tr></thead><tbody>\n";
foreach($uids as $key => $uid)
{
$benutzer = new benutzer();
$benutzer->load($uid["uid"]);
$htmlstr .= ' <tr>';
$htmlstr .= ' <td>'.($benutzer->nachname != ''?$benutzer->nachname:'').'</td>';
$htmlstr .= ' <td>'.($benutzer->vorname != ''?$benutzer->vorname:'').'</td>';
$htmlstr .= ' <td>'.$uid["uid"].'</td>';
$htmlstr .= ' <td>'.$uid["funktion"].'</td>';
$htmlstr .= ' <td>'.(isset($uid)?$benutzer->bnaktiv?'Ja':'Nein':'').'</td>';
$htmlstr .= ' <td><a href="benutzerberechtigung_details.php?uid='.$uid["uid"].'" target="vilesci_detail">Rechte bearbeiten</a></td>';
$htmlstr .= ' </tr>';
}
$htmlstr .= '</tbody></table>';
}
else
{
$htmlstr .= "Für diese Berechtigung sind keine Einträge vorhanden";
}
}
echo $htmlstr;
?>
+169 -23
View File
@@ -31,11 +31,12 @@ $rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($user);
if(!$rechte->isBerechtigt('basis/berechtigung'))
die('Sie habe keine Rechte um diese Seite anzuzeigen');
die($rechte->errormsg);
//echo '<pre>', var_dump($_POST), '</pre>';exit();
$rolle_kurzbz = filter_input(INPUT_GET, 'rolle_kurzbz');
$delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN);
$copy = filter_input(INPUT_POST, 'copy');
$saveRecht = isset($_POST['action']) && $_POST['action'] == 'saveRechtAjax' ? true : false;
$vergleich = filter_input(INPUT_GET, 'vergleich');
?>
<html>
@@ -157,13 +158,135 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
else
return true;
}
function saveRecht(rolle_kurzbz, recht, art)
{
data = {
action: 'saveRechtAjax',
rolle_ajax: rolle_kurzbz,
recht_ajax: recht,
art_ajax: art
};
$.ajax({
url: 'berechtigungrolle.php',
data: data,
type: 'POST',
dataType: 'json',
success: function(data)
{
if(data.status!='ok')
{
//error
console.log('error');
}
else
{
//location.reload(true);
window.location.reload(true)
// html = '<td style=""></td><td style="">'+recht+'</td><td style="text-align: right;">'+art+'</td>';
// console.log('#'+rolle_kurzbz+'_'+recht);
// $('#'+rolle_kurzbz+'_'+recht).html(html);
}
},
error: function(data)
{
//error
console.log('AJAX-Fehler in Error-Methode: ' + data.status + ' - ' + data.error);
location.reload(true);
},
stop: function (data)
{
location.reload(true);
}
});
}
</script>
<style>
button
{
line-height: 9pt;
}
table.tablesorter tr:hover td
{
/*pointer-events: none !important;*/
}
table.tablesorter tr.odd:hover td
{
background-color: #d3d3d3 !important;
}
table.tablesorter tr.even:hover td
{
background-color: #efefef !important;
}
table.tablesorter tr.odd:hover td.difference
{
background-color: #b2b2b2 !important;
/*border-top: 1px solid #aaa;*/
/*border-bottom: 1px solid #aaa;*/
}
table.tablesorter tr.even:hover td.difference
{
background-color: #b2b2b2 !important;
/*border-top: 1px solid #aaa;*/
/*border-bottom: 1px solid #aaa;*/
}
.difference
{
background-color: #b2b2b2 !important;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
/*.difference:hover*/
/*{*/
/* background-color: #b2b2b2 !important;*/
/* border-top: 1px solid #aaa;*/
/* border-bottom: 1px solid #aaa;*/
/*}*/
.tablesorter
{
border-collapse: collapse !important;
}
</style>
</head>
<body class="background_main">
<?php
if($saveRecht)
{
$rolle_kurzbz = filter_input(INPUT_POST, 'rolle_ajax');
$recht = filter_input(INPUT_POST, 'recht_ajax');
$art = filter_input(INPUT_POST, 'art_ajax');
$berechtigung = new berechtigung();
$berechtigung->rolle_kurzbz = $rolle_kurzbz;
$berechtigung->berechtigung_kurzbz = $recht;
$berechtigung->art = $art;
$berechtigung->insertamum = date('Y-m-d H:i:s');
$berechtigung->insertvon = $user;
if($berechtigung->saveRolleBerechtigung())
{
echo json_encode(array(
'status' => 'ok',
'msg' => ''
));
exit();
}
else
{
echo json_encode(array(
'status' => 'error',
'msg' => 'Fehler beim Speichern der Rolle'
));
exit();
}
}
if(isset($rolle_kurzbz))
{
echo '<h2>Berechtigungen der Rolle "'.$rolle_kurzbz.'"</h2>';
@@ -335,35 +458,46 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
<tr>
<th>Kurzbz</th>
<th>Art</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>';
foreach ($rollenGesamt AS $recht => $art)
{
if (array_key_exists($recht, $rollen1Arr))
if (array_key_exists($recht, $rollen1Arr) || !array_key_exists($recht, $rollen2Arr))
{
if ($art != $rollen1Arr[$recht])
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid black">'.$rollen1Arr[$recht].'</td>
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td style="">'.$recht.'</td>
<td class="difference">'.$rollen1Arr[$recht].'</td>
<td style="text-align: right;"><button type="button" onclick="saveRecht(\''.$rolle2.'\', \''.$recht.'\', \''.$rollen1Arr[$recht].'\')"> -> </button></td>
</tr>';
}
elseif (!array_key_exists($recht, $rollen2Arr))
{
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
<td style="text-align: right;"><button type="button" onclick="saveRecht(\''.$rolle2.'\', \''.$recht.'\', \''.$rollen1Arr[$recht].'\')"> -> </button></td>
</tr>';
}
else
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid transparent">'.$art.'</td>
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
<td style="text-align: right;"></td>
</tr>';
}
}
else
{
echo ' <tr>
<td style="border: 1px solid black; border-right: 0">&nbsp;</td>
<td style="border: 1px solid black; border-left: 0">&nbsp;</td>
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td class="difference" style="">&nbsp;</td>
<td class="difference"style="">&nbsp;</td>
<td class="difference"style=" text-align: right;"></td>
</tr>';
}
}
@@ -395,6 +529,7 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
echo ' <table id="t4" class="tablesorter">
<thead>
<tr>
<th>&nbsp;</th>
<th>Kurzbz</th>
<th>Art</th>
</tr>
@@ -402,28 +537,39 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
<tbody>';
foreach ($rollenGesamt AS $recht => $art)
{
if (array_key_exists($recht, $rollen2Arr))
if (array_key_exists($recht, $rollen2Arr) || !array_key_exists($recht, $rollen1Arr))
{
if ($art != $rollen2Arr[$recht])
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid black">'.$rollen2Arr[$recht].'</td>
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td style="text-align: left;"><button type="button" onclick="saveRecht(\''.$rolle1.'\', \''.$recht.'\', \''.$rollen2Arr[$recht].'\')"> <- </button></td>
<td style="">'.$recht.'</td>
<td class="difference" style="">'.$rollen2Arr[$recht].'</td>
</tr>';
}
elseif (!array_key_exists($recht, $rollen1Arr))
{
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td style="text-align: left;"><button type="button" onclick="saveRecht(\''.$rolle1.'\', \''.$recht.'\', \''.$rollen2Arr[$recht].'\')"> <- </button></td>
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
</tr>';
}
else
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid transparent">'.$art.'</td>
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td style="">&nbsp;</td>
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
</tr>';
}
}
else
{
echo ' <tr>
<td style="border: 1px solid black; border-right: 0">&nbsp;</td>
<td style="border: 1px solid black; border-left: 0">&nbsp;</td>
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td class="difference" style=""></td>
<td class="difference" style="">&nbsp;</td>
<td class="difference" style="">&nbsp;</td>
</tr>';
}
}
+11 -6
View File
@@ -47,17 +47,23 @@ $tmp_gemeinde_ar = array();
if (isset($_FILES['parsefile']) && $_FILES['parsefile']['error'] == 0)
{
$rows = array_map('str_getcsv', file( $_FILES['parsefile']['tmp_name'] ));
$header = array_shift($rows);
$rows = file( $_FILES['parsefile']['tmp_name'] );
// all entries of csv
$header = explode(";",array_shift($rows)); // first row
$header = array_map('trim',$header);
$data = array();
foreach ($rows as $row)
{
$data[] = array_combine($header, $row);
$data[] = array_combine(preg_replace('/\xEF\xBB\xBF/','',$header), explode(";",$row));
}
foreach ($data as $gemeinde_details)
{
//Wenn nicht gültig dann überspringen
if ($gemeinde_details['Gültig'] == 'Nein') continue;
@@ -66,15 +72,14 @@ if (isset($_FILES['parsefile']) && $_FILES['parsefile']['error'] == 0)
foreach ($plzs as $plz)
{
$tmp_obj_gemeinde = null;
$tmp_obj_gemeinde = new gemeinde();
$tmp_obj_gemeinde->plz = $plz;
$tmp_obj_gemeinde->kennziffer = $gemeinde_details["Gemeindekennziffer"];
$tmp_obj_gemeinde->name = $gemeinde_details['Gemeindename'];
$tmp_obj_gemeinde->ortschaftskennziffer = $gemeinde_details['Ortschaftskennziffer'];
$tmp_obj_gemeinde->ortschaftsname = $gemeinde_details['Ortschaftsname'];
$tmp_obj_gemeinde->bulacode = $gemeinde_details['BULA_Code'];
$tmp_obj_gemeinde->bulabez = $gemeinde_details['BULA_Bez'];
$tmp_obj_gemeinde->kennziffer = $gemeinde_details['Gemeindekennziffer'];
$tmp_obj_gemeinde->save();
$tmp_gemeinde_ar[] = $tmp_obj_gemeinde;