Merge remote-tracking branch 'origin/master' into feature-60873/GesamtnoteneingabeCis4

This commit is contained in:
Johann Hoffmann
2025-07-15 09:51:11 +02:00
42 changed files with 1336 additions and 191 deletions
+11
View File
@@ -0,0 +1,11 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// apps for which issues should be displayed
$config['issues_list_apps'] = array('core', 'dvuh');
// functions which enable users to see issues
$config['issues_list_functions'] = array('ass');
// functions which enable users to see issues
$config['issues_list_status'] = array('Aufgenommener', 'Student', 'Incoming', 'Diplomand', 'Abbrecher', 'Unterbrecher', 'Absolvent');
+3 -1
View File
@@ -4,4 +4,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
// use vuejs dev version
$config['use_vuejs_dev_version'] = false;
// use bundled javascript
$config['use_bundled_javascript'] = false;
$config['use_bundled_javascript'] = false;
// systemerror_mailto use in FHC-Alert Plugin - if empty Link will not be rendered
$config['systemerror_mailto'] = '';
@@ -85,7 +85,10 @@ class Kontakt extends FHCAPI_Controller
|| $this->router->method == 'addNewBankverbindung'
) {
$person_id = current(array_slice($this->uri->rsegments, 2));
if (is_null($person_id) || !ctype_digit((string)$person_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
} elseif ($this->router->method == 'loadAddress'
|| $this->router->method == 'loadContact'
@@ -119,6 +122,9 @@ class Kontakt extends FHCAPI_Controller
$model = 'person/Bankverbindung_model';
}
if (!isset($id) || !ctype_digit((string)$id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model($model, 'TempModel');
$result = $this->TempModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
@@ -387,8 +393,11 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getFirmen($searchString)
public function getFirmen($searchString = null)
{
if (is_null($searchString))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('ressource/firma_model', 'FirmaModel');
$result = $this->FirmaModel->searchFirmen($searchString);
@@ -398,8 +407,11 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithSuccess($result ?: []);
}
public function getStandorte($searchString)
public function getStandorte($searchString = null)
{
if (is_null($searchString))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('organisation/standort_model', 'StandortModel');
$result = $this->StandortModel->searchStandorte($searchString);
@@ -409,8 +421,11 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function getStandorteByFirma($firma_id)
public function getStandorteByFirma($firma_id = null)
{
if (is_null($firma_id) || !ctype_digit((string)$firma_id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('organisation/standort_model', 'StandortModel');
$result = $this->StandortModel->getStandorteByFirma($firma_id);
@@ -652,6 +667,9 @@ class Kontakt extends FHCAPI_Controller
$bic = $this->input->post('bic');
$blz = $this->input->post('blz');
$kontonr = $this->input->post('kontonr');
$iban = $this->input->post('iban');
$typ = $this->input->post('typ');
$verrechnung = $this->input->post('verrechnung');
$result = $this->BankverbindungModel->insert(
[
@@ -659,13 +677,13 @@ class Kontakt extends FHCAPI_Controller
'name' => $name,
'anschrift' => $anschrift,
'bic' => $bic,
'iban' => $_POST['iban'],
'iban' => $iban,
'blz' => $blz,
'kontonr' => $kontonr,
'insertvon' => 'uid',
'insertamum' => date('c'),
'typ' => $_POST['typ'],
'verrechnung' => $_POST['verrechnung'],
'typ' => $typ,
'verrechnung' => $verrechnung,
'ext_id' => $ext_id,
'oe_kurzbz' => $oe_kurzbz,
'orgform_kurzbz' => $orgform_kurzbz
+7 -4
View File
@@ -95,12 +95,15 @@ class AntragJob extends JOB_Controller
continue;
}
$leitung = current(getData($result));
if (!isset($stgLeitungen[$leitung->uid]))
$leitungen = getData($result);
foreach ($leitungen as $leitung)
{
$stgLeitungen[$leitung->uid] = [ 'Details' => $leitung, 'stgs' => [] ];
if (!isset($stgLeitungen[$leitung->uid]))
{
$stgLeitungen[$leitung->uid] = ['Details' => $leitung, 'stgs' => []];
}
$stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz;
}
$stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz;
$result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id);
if (isError($result))
@@ -48,7 +48,9 @@ class IssueResolver extends IssueResolver_Controller
'CORE_PERSON_0001' => 'CORE_PERSON_0001',
'CORE_PERSON_0002' => 'CORE_PERSON_0002',
'CORE_PERSON_0003' => 'CORE_PERSON_0003',
'CORE_PERSON_0004' => 'CORE_PERSON_0004'
'CORE_PERSON_0004' => 'CORE_PERSON_0004',
'CORE_PERSON_0005' => 'CORE_PERSON_0005',
'CORE_PERSON_0006' => 'CORE_PERSON_0006'
);
// fehler which are resolved by the job the same way as they are produced
@@ -2375,16 +2375,50 @@ class InfoCenter extends Auth_Controller
if ($statusgrund === 'null' || $studiengang === 'null' || $abgeschickt === 'null' || empty($personen))
$this->terminateWithJsonError("Bitte füllen Sie alle Felder aus");
foreach($personen as $person)
if ($studiengang === 'all' && $abgeschickt === 'all')
{
$prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt);
foreach($personen as $person)
{
$prestudenten = $this->PrestudentModel->getByPersonWithoutLehrgang($person, $studienSemester);
if (!hasData($prestudent))
continue;
if (!hasData($prestudenten))
continue;
$prestudentData = getData($prestudent);
$prestudentenData = getData($prestudenten);
foreach ($prestudentenData as $prestudent)
{
$this->saveAbsage($prestudent->prestudent_id, $statusgrund);
}
}
}
else
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->StudienplanModel->addSelect('1');
$this->StudienplanModel->addJoin('lehre.tbl_studienordnung so', 'studienordnung_id');
$escaped = $this->StudienplanModel->db->escape(strtoupper($studiengang));
$this->StudienplanModel->db->where("UPPER(so.studiengangkurzbzlang || ':' || tbl_studienplan.orgform_kurzbz) = $escaped");
$this->StudienplanModel->addLimit(1);
$studiengangResult = $this->StudienplanModel->load();
if (hasData($studiengangResult))
{
foreach($personen as $person)
{
$prestudent = $this->PrestudentModel->getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt, $abgeschickt === 'all');
if (!hasData($prestudent))
continue;
$prestudentData = getData($prestudent);
$this->saveAbsage($prestudentData[0]->prestudent_id, $statusgrund);
}
}
else
$this->terminateWithJsonError("Falschen Studiengang übergeben!");
$this->saveAbsage($prestudentData[0]->prestudent_id, $statusgrund);
}
$this->outputJsonSuccess("Success");
@@ -14,7 +14,8 @@ class Rueckstellung extends Auth_Controller
'get' => array('infocenter:r', 'lehre/zgvpruefung:r'),
'set' => array('infocenter:r', 'lehre/zgvpruefung:r'),
'delete' => array('infocenter:r', 'lehre/zgvpruefung:r'),
'getStatus' => array('infocenter:rw', 'lehre/zgvpruefung:rw')
'getStatus' => array('infocenter:rw', 'lehre/zgvpruefung:rw'),
'setForPersonen' => array('infocenter:rw', 'lehre/zgvpruefung:rw'),
)
);
@@ -79,7 +80,34 @@ class Rueckstellung extends Auth_Controller
$this->outputJson($result);
}
public function setForPersonen()
{
$personen = $this->input->post('personen');
$datum_bis = $this->input->post('datum_bis');
$status_kurzbz = $this->input->post('status_kurzbz');
foreach ($personen as $person)
{
$rueckstellung = $this->_ci->RueckstellungModel->loadWhere(array('person_id' => $person));
if (hasData($rueckstellung))
continue;
$result = $this->_ci->RueckstellungModel->insert(
array('person_id' => $person,
'status_kurzbz' => $status_kurzbz,
'datum_bis' => date_format(date_create($datum_bis), 'Y-m-d'),
'insertvon' => $this->_uid
)
);
if (isError($result))
$this->terminateWithJsonError(getError($result));
$this->_log($person, $status_kurzbz);
}
$this->outputJsonSuccess("Erfolgreich gespeichert!");
}
public function delete()
{
$person_id = $this->input->post('person_id');
@@ -6,7 +6,6 @@ class Issues extends Auth_Controller
{
private $_uid;
const FUNKTION_KURZBZ = 'ass'; // user having this funktion can see issues for oes assigned with this funktion
const BERECHTIGUNG_KURZBZ = 'system/issues_verwalten'; // user having this permission can see issues for oes assigned with this permission
public function __construct()
@@ -28,6 +27,9 @@ class Issues extends Auth_Controller
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
// load config
$this->load->config('issueList');
$this->loadPhrases(
array(
'global',
@@ -47,10 +49,12 @@ class Issues extends Auth_Controller
{
$oes_for_issues = $this->_getOesForIssues();
$language_index = $this->_getLanguageIndex();
$apps = $this->config->item('issues_list_apps');
$status = $this->config->item('issues_list_status');
$this->load->view(
'system/issues/issues',
array_merge($oes_for_issues, array('language_index' => $language_index))
array_merge($oes_for_issues, array('language_index' => $language_index, 'apps' => $apps, 'status' => $status))
);
}
@@ -121,6 +125,8 @@ class Issues extends Auth_Controller
$oe_kurzbz_for_funktion = array();
$benutzerfunktionRes = $this->BenutzerfunktionModel->getBenutzerFunktionByUid($this->_uid, null, date('Y-m-d'), date('Y-m-d'));
$functions = $this->config->item('issues_list_functions');
if (isError($benutzerfunktionRes))
show_error(getError($benutzerfunktionRes));
@@ -130,8 +136,8 @@ class Issues extends Auth_Controller
{
$all_funktionen_oe_kurzbz[$benutzerfunktion->oe_kurzbz][] = $benutzerfunktion->funktion_kurzbz;
// separate oes for the additional funktion which enables displaying issues
if ($benutzerfunktion->funktion_kurzbz == self::FUNKTION_KURZBZ)
// separate oes for the additional functions which enables displaying issues
if (in_array($benutzerfunktion->funktion_kurzbz, $functions))
{
$oe_kurzbz_for_funktion[] = $benutzerfunktion->oe_kurzbz;
@@ -95,6 +95,9 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod)
}, $server_language);
$user_language = getUserLanguage();
$ci->load->config('javascript');
$systemerror_mailto = $ci->config->item('systemerror_mailto');
$FHC_JS_DATA_STORAGE_OBJECT = array(
'app_root' => APP_ROOT,
'ci_router' => $indexPage,
@@ -103,6 +106,7 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod)
'server_languages' => $server_language,
'user_language' => $user_language,
'timezone' => date_default_timezone_get(),
'systemerror_mailto' => $systemerror_mailto,
);
$toPrint = "\n";
+7 -2
View File
@@ -77,7 +77,9 @@ class AntragLib
'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz,
'ausbildungssemester'=>$prestudentstatus->ausbildungssemester
], [
'statusgrund_id' => null
'statusgrund_id' => null,
'updateamum' => date('c'),
'updatevon' => $insertvon
]);
}
}
@@ -335,7 +337,10 @@ class AntragLib
'status_kurzbz'=>$prestudentstatus->status_kurzbz,
'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz,
'ausbildungssemester'=>$prestudentstatus->ausbildungssemester
], []);
], [
'updateamum' => $insertam,
'updatevon' => $insertvon
]);
if (isError($result))
{
$errors[] = getError($result);
@@ -13,7 +13,7 @@ class PlausicheckResolverLib
private $_ci; // ci instance
private $_extensionName; // name of extension
private $_codeLibMappings = []; // mappings for issues which explicitly defined resolver
private $_codeProducerLibMappings = []; // mappings for issues which are resolved as produced
private $_codeProducerLibMappings = []; // mappings for issues which are resolved with the same check as they are produced
public function __construct($params = null)
{
@@ -99,10 +99,11 @@ class PlausicheckResolverLib
$issueResolved = getData($issueResolvedRes) === true;
}
}
elseif (isset($this->_codeProducerLibMappings[$issue->fehlercode]))
elseif (isset($this->_codeProducerLibMappings[$issue->fehlercode])) // check if it is an issue without explicit resolver, "self-resolving"
{
$libName = $this->_codeProducerLibMappings[$issue->fehlercode];
// execute same check as used for issue production
$issueResolvedRes = $this->_ci->plausicheckproducerlib->producePlausicheckIssue(
$libName,
$issue->fehler_kurzbz,
@@ -0,0 +1,36 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Geburtsnation missing
*/
class CORE_PERSON_0005 implements IIssueResolvedChecker
{
public function checkIfIssueIsResolved($params)
{
if (!isset($params['issue_person_id']) || !is_numeric($params['issue_person_id']))
return error('Person Id missing, issue_id: '.$params['issue_id']);
$this->_ci =& get_instance(); // get code igniter instance
$this->_ci->load->model('person/Person_model', 'PersonModel');
// load geburtsnation for the given person
$this->_ci->PersonModel->addSelect('geburtsnation');
$personRes = $this->_ci->PersonModel->load($params['issue_person_id']);
if (isError($personRes)) return $personRes;
if (hasData($personRes))
{
// get person data
$personData = getData($personRes)[0];
// if geburtsnation present, issue is resolved
return success(!isEmptyString($personData->geburtsnation));
}
else
return success(false); // if no person found, not resolved
}
}
@@ -0,0 +1,37 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Geburtsnation missing
*/
class CORE_PERSON_0006 implements IIssueResolvedChecker
{
public function checkIfIssueIsResolved($params)
{
if (!isset($params['issue_person_id']) || !is_numeric($params['issue_person_id']))
return error('Person Id missing, issue_id: '.$params['issue_id']);
$this->_ci =& get_instance(); // get code igniter instance
$this->_ci->load->model('codex/Uhstat1daten_model', 'UhstatModel');
$personRes = $this->_ci->UhstatModel->getUHSTAT1PersonData([$params['issue_person_id']]);
if (isError($personRes)) return $personRes;
if (hasData($personRes))
{
// get person data
$personData = getData($personRes)[0];
// if person identification data present, issue is resolved
return success(
!isEmptyString($personData->ersatzkennzeichen)
|| (!isEmptyString($personData->vbpkAs) && !isEmptyString($personData->vbpkBf))
);
}
else
return success(false); // if no person found, not resolved
}
}
@@ -131,6 +131,11 @@ class VertragsbestandteilLib
return $this->VertragsbestandteilModel->getVertragsbestandteil($vertragsbestandteil_id);
}
public function fetchLastVertragsbestandteilStundenBeforeAltersteilzeit($dienstverhaeltnis_id)
{
return $this->VertragsbestandteilModel->getLastVertragsbestanteilStundenBeforeAltersteilzeit($dienstverhaeltnis_id);
}
public function storeDienstverhaeltnis(Dienstverhaeltnis $dv)
{
if( intval($dv->getDienstverhaeltnis_id()) > 0 )
@@ -11,4 +11,44 @@ class Uhstat1daten_model extends DB_Model
$this->dbTable = 'bis.tbl_uhstat1daten';
$this->pk = 'uhstat1daten_id';
}
/**
* Gets person data needed for sending as UHSTAT1 data.
* @param array $person_id_arr
* @param string $studiensemester
* @param array $status_kurzbz
* @return object success with prestudents or error
*/
public function getUHSTAT1PersonData($person_id_arr)
{
if (!isset($person_id_arr) || isEmptyArray($person_id_arr)) return success([]);
$params = array($person_id_arr);
$prstQry = "SELECT
DISTINCT ON (pers.person_id)
pers.person_id, uhstat_daten.uhstat1daten_id, pers.svnr, pers.ersatzkennzeichen, pers.geburtsnation,
uhstat_daten.mutter_geburtsstaat, uhstat_daten.mutter_bildungsstaat, uhstat_daten.mutter_geburtsjahr,
uhstat_daten.mutter_bildungmax, uhstat_daten.vater_geburtsstaat, uhstat_daten.vater_bildungsstaat,
uhstat_daten.vater_geburtsjahr, uhstat_daten.vater_bildungmax,
kzVbpkAs.inhalt AS \"vbpkAs\", kzVbpkBf.inhalt AS \"vbpkBf\"
FROM
public.tbl_person pers
JOIN public.tbl_prestudent ps USING (person_id)
JOIN public.tbl_studiengang stg USING (studiengang_kz)
JOIN bis.tbl_uhstat1daten uhstat_daten USING (person_id)
LEFT JOIN public.tbl_kennzeichen kzVbpkAs ON kzVbpkAs.kennzeichentyp_kurzbz = 'vbpkAs'AND kzVbpkAs.person_id = pers.person_id AND kzVbpkAs.aktiv
LEFT JOIN public.tbl_kennzeichen kzVbpkBf ON kzVbpkBf.kennzeichentyp_kurzbz = 'vbpkBf'AND kzVbpkBf.person_id = pers.person_id AND kzVbpkBf.aktiv
WHERE
ps.bismelden
AND stg.melderelevant
AND pers.person_id IN ?
ORDER BY
pers.person_id";
return $this->execReadOnlyQuery(
$prstQry,
$params
);
}
}
+28 -8
View File
@@ -677,7 +677,7 @@ class Prestudent_model extends DB_Model
));
}
public function getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt)
public function getPrestudentByStudiengangAndPerson($studiengang, $person, $studienSemester, $abgeschickt, $ignoreAbgeschickt = false)
{
$query = "SELECT ps.prestudent_id
FROM public.tbl_prestudentstatus pss
@@ -687,22 +687,42 @@ class Prestudent_model extends DB_Model
JOIN lehre.tbl_studienordnung so USING(studienordnung_id)
WHERE ps.person_id = ?
AND UPPER(so.studiengangkurzbzlang || ':' || sp.orgform_kurzbz) = ?
AND pss.studiensemester_kurzbz = ?
AND";
AND pss.studiensemester_kurzbz = ?";
if ($abgeschickt === 'true')
$query .= " EXISTS";
else
$query .= " NOT EXISTS";
if (!$ignoreAbgeschickt)
{
$query .= "AND";
$query .= " (SELECT 1 FROM public.tbl_prestudentstatus spss
if ($abgeschickt === 'true')
$query .= " EXISTS";
else
$query .= " NOT EXISTS";
$query .= " (SELECT 1 FROM public.tbl_prestudentstatus spss
JOIN public.tbl_prestudent sps USING(prestudent_id)
WHERE sps.prestudent_id = ps.prestudent_id
AND spss.bewerbung_abgeschicktamum IS NOT NULL)";
}
return $this->execQuery($query, array($person, $studiengang, $studienSemester));
}
public function getByPersonWithoutLehrgang($person, $studienSemester)
{
$query = "SELECT DISTINCT(ps.prestudent_id)
FROM public.tbl_prestudentstatus pss
JOIN public.tbl_prestudent ps USING(prestudent_id)
JOIN public.tbl_studiengang sg USING(studiengang_kz)
JOIN lehre.tbl_studienplan sp USING(studienplan_id)
JOIN lehre.tbl_studienordnung so USING(studienordnung_id)
WHERE ps.person_id = ?
AND (sg.typ = 'b' OR sg.typ = 'm')
AND pss.studiensemester_kurzbz = ?";
return $this->execQuery($query, array($person, $studienSemester));
}
/**
* Gets förderrelevant flag for a prestudent, from prestudent, or, if not set on prestudent level, from studiengang
* @param int $prestudent_id
@@ -183,6 +183,46 @@ EOSQL;
return $vbcount[0]->overlappingvbs;
}
public function getLastVertragsbestanteilStundenBeforeAltersteilzeit($dienstverhaeltnis_id)
{
$sql = <<<EOATZSQL
select
*
from
hr.tbl_vertragsbestandteil vb
join
hr.tbl_vertragsbestandteil_stunden vbs USING(vertragsbestandteil_id)
where
vb.dienstverhaeltnis_id = ?
and (
vbs.teilzeittyp_kurzbz != 'altersteilzeit'
or
vbs.teilzeittyp_kurzbz is NULL
)
order by
vb.bis desc
limit 1
EOATZSQL;
$query = $this->execReadOnlyQuery($sql, array($dienstverhaeltnis_id));
$data = getData($query);
if ($data == null)
{
return null;
}
$vertragsbestandteil = null;
try
{
$vertragsbestandteil = VertragsbestandteilFactory::getVertragsbestandteil($data[0], true);
}
catch (Exception $ex)
{
echo $ex->getMessage() . "\n";
}
return $vertragsbestandteil;
}
/**
* Checks if sap sync table exists.
* @return bool
@@ -14,12 +14,13 @@
'navigationwidget' => true,
'dialoglib' => true,
'phrases' => array(
'infocenter' => array('statusAuswahl'),
'person' => array('vorname', 'nachname'),
'global' => array('mailAnXversandt'),
'ui' => array('bitteEintragWaehlen')
),
'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js')
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/rueckstellung.js', 'public/js/infocenter/infocenterPersonDataset.js')
);
$this->load->view('templates/FHC-Header', $includesArray);
@@ -20,7 +20,7 @@
'ui' => array('bitteEintragWaehlen')
),
'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js')
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/rueckstellung.js', 'public/js/infocenter/infocenterPersonDataset.js')
)
);
?>
@@ -20,7 +20,7 @@
'ui' => array('bitteEintragWaehlen')
),
'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js')
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/rueckstellung.js', 'public/js/infocenter/infocenterPersonDataset.js')
)
);
?>
@@ -20,7 +20,7 @@
'ui' => array('bitteEintragWaehlen')
),
'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js')
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/rueckstellung.js', 'public/js/infocenter/infocenterPersonDataset.js')
)
);
?>
@@ -20,7 +20,7 @@
'ui' => array('bitteEintragWaehlen')
),
'customCSSs' => array('public/css/sbadmin2/tablesort_bootstrap.css', 'public/css/infocenter/infocenterPersonDataset.css'),
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/infocenterPersonDataset.js')
'customJSs' => array('public/js/bootstrapper.js', 'public/js/infocenter/rueckstellung.js', 'public/js/infocenter/infocenterPersonDataset.js')
)
);
?>
+48 -34
View File
@@ -1,11 +1,21 @@
<?php
$PERSON_ID = getAuthPersonId();
// all oe kurzbz for which logged user has a funktion
$ALL_FUNKTIONEN_OE_KURZBZ = "('" . implode("','", array_keys($all_funktionen_oe_kurzbz)) . "')";
$ALL_FUNKTIONEN_OE_KURZBZ = isEmptyArray($all_funktionen_oe_kurzbz) ? "(NULL)"
: "(" . implode(",", array_map(function($string) { return $this->db->escape($string); }, array_keys($all_funktionen_oe_kurzbz))) . ")";
// all oes for which logged user has issues permissions, including permissions for "special" issue funktion
$ALL_OE_KURZBZ_BERECHTIGT = "('" . implode("','", $all_oe_kurzbz_berechtigt) . "')";
$RELEVANT_PRESTUDENT_STATUS = "('Aufgenommener', 'Student', 'Incoming', 'Diplomand', 'Abbrecher', 'Unterbrecher', 'Absolvent')";
$ALL_OE_KURZBZ_BERECHTIGT = isEmptyArray($all_oe_kurzbz_berechtigt) ? "(NULL)"
: "(" . implode(",", array_map(function($string) { return $this->db->escape($string); }, $all_oe_kurzbz_berechtigt)) . ")";
// app apps for which issues should be displayed
$APPS = isEmptyArray($apps) ? "" : "(" . implode(",", array_map(function($string) { return $this->db->escape($string); }, $apps)) . ")";
// all prestudent status for which issues should be displayed
$RELEVANT_PRESTUDENT_STATUS = isEmptyArray($status) ? ""
: "(" . implode(",", array_map(function($string) { return $this->db->escape($string); }, $status)) . ")";
// get issues for the oes of the logged user or for the persons (students, oe-zuordnung) of the oes
$query = "WITH zustaendigkeiten AS (
@@ -37,8 +47,8 @@ $query .= "
SELECT
issue_id, fehlercode AS \"Fehlercode\", fehler_kurzbz AS \"Fehler Kurzbezeichnung\", iss.fehlercode_extern AS \"Fehlercode extern\", datum AS \"Datum\",
inhalt AS \"Inhalt\", inhalt_extern AS \"Inhalt extern\", iss.person_id AS \"PersonId\", iss.oe_kurzbz AS \"OE\",
ftyp.bezeichnung_mehrsprachig[".$language_index."] AS \"Fehlertyp\",
stat.bezeichnung_mehrsprachig[".$language_index."] AS \"Fehlerstatus\",
ftyp.bezeichnung_mehrsprachig[".$this->db->escape($language_index)."] AS \"Fehlertyp\",
stat.bezeichnung_mehrsprachig[".$this->db->escape($language_index)."] AS \"Fehlerstatus\",
verarbeitetvon AS \"Verarbeitet von\",verarbeitetamum AS \"Verarbeitet am\", fr.app AS \"Applikation\",
fr.fehlertyp_kurzbz AS \"Fehlertypcode\", iss.status_kurzbz AS \"Statuscode\",
pers.vorname AS \"Vorname\", pers.nachname AS \"Nachname\",
@@ -118,44 +128,48 @@ $query .= "
JOIN system.tbl_issue_status stat USING (status_kurzbz)
LEFT JOIN public.tbl_person pers ON iss.person_id = pers.person_id
WHERE
fr.app IN ('core', 'dvuh')
AND (
(
EXISTS ( /* if oe or person is specified in fehler_zustaendigkeiten */
SELECT 1 FROM zustaendigkeiten
WHERE fehlercode = iss.fehlercode
AND zustaendig = TRUE)";
// show issue if it is assigend to oe of logged in user or to student of oe of logged in user
if (!isEmptyArray($all_oe_kurzbz_berechtigt))
{
$query .= " OR iss.oe_kurzbz IN $ALL_OE_KURZBZ_BERECHTIGT /* if issue is for oe */";
$query .= " OR iss.oe_kurzbz IN $ALL_OE_KURZBZ_BERECHTIGT /* if issue is for oe */";
$query .= " OR (iss.oe_kurzbz IS NULL AND EXISTS ( /* if person_id of issue is a student of studiengang oe */
SELECT 1 FROM public.tbl_prestudent ps
JOIN public.tbl_prestudentstatus pss USING (prestudent_id)
JOIN public.tbl_studiengang stg USING (studiengang_kz)
WHERE person_id = iss.person_id
AND stg.oe_kurzbz IN ".$ALL_OE_KURZBZ_BERECHTIGT;
if (!isEmptyString($RELEVANT_PRESTUDENT_STATUS)) $query .= " AND pss.status_kurzbz IN ".$RELEVANT_PRESTUDENT_STATUS;
$query .= " AND NOT EXISTS (SELECT 1 /* irrelevant if already finished studies and studied a while ago */
FROM public.tbl_prestudentstatus ps_finished
JOIN public.tbl_studiensemester sem_finished USING (studiensemester_kurzbz)
WHERE prestudent_id = ps.prestudent_id
AND status_kurzbz IN ('Absolvent','Abbrecher','Abgewiesener')
AND datum::date + interval '2 months' < NOW()
AND EXISTS (SELECT 1 FROM public.tbl_prestudent /* if more recent prestudent exists, still display the issue */
JOIN public.tbl_prestudentstatus USING (prestudent_id)
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
WHERE person_id = ps.person_id
AND prestudent_id <> ps_finished.prestudent_id
AND tbl_studiensemester.start::date > sem_finished.start::date";
if (!isEmptyString($RELEVANT_PRESTUDENT_STATUS)) $query .= " AND tbl_prestudentstatus.status_kurzbz IN ".$RELEVANT_PRESTUDENT_STATUS;
$query .= ")
)
)
)";
$query .= " OR (iss.oe_kurzbz IS NULL AND EXISTS ( /* if person_id of issue is a student of studiengang oe */
SELECT 1 FROM public.tbl_prestudent ps
JOIN public.tbl_prestudentstatus pss USING (prestudent_id)
JOIN public.tbl_studiengang stg USING (studiengang_kz)
WHERE person_id = iss.person_id
AND stg.oe_kurzbz IN $ALL_OE_KURZBZ_BERECHTIGT
AND pss.status_kurzbz IN $RELEVANT_PRESTUDENT_STATUS
AND NOT EXISTS (SELECT 1 /* irrelevant if already finished studies and studied a while ago */
FROM public.tbl_prestudentstatus ps_finished
JOIN public.tbl_studiensemester sem_finished USING (studiensemester_kurzbz)
WHERE prestudent_id = ps.prestudent_id
AND status_kurzbz IN ('Absolvent','Abbrecher','Abgewiesener')
AND datum::date + interval '2 months' < NOW()
AND EXISTS (SELECT 1 FROM public.tbl_prestudent /* if more recent prestudent exists, still display the issue */
JOIN public.tbl_prestudentstatus USING (prestudent_id)
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
WHERE tbl_prestudentstatus.status_kurzbz IN $RELEVANT_PRESTUDENT_STATUS
AND person_id = ps.person_id
AND prestudent_id <> ps_finished.prestudent_id
AND tbl_studiensemester.start::date > sem_finished.start::date)
)
)
)";
}
$query .= ") ";
if (!isEmptyString($APPS)) $query .= " AND fr.app IN ".$APPS;
$query .= " ORDER BY
CASE
WHEN fehlertyp_kurzbz = '".IssuesLib::ERRORTYPE_CODE."' THEN 0
@@ -384,17 +384,6 @@ for ($i = 0; $i < count($ztaufdata); $i++)
}
}
//worktime with no break greater 6 -> compulsory break of half an hour
if ($pauseSubtracted < 0.5 && !$lehreExternExists)
{
if ($projektlines[$day]->arbeitszeit >= 6.5)
$projektlines[$day]->arbeitszeit -= 0.5;
//ensure that no worktime gets smaller than 6 hours because of compulsory break
elseif ($projektlines[$day]->arbeitszeit > 6)
$projektlines[$day]->arbeitszeit -= $projektlines[$day]->arbeitszeit - 6;
}
$projektlines[$day]->arbeitszeit = round($projektlines[$day]->arbeitszeit, 2);
//calculate sums
+307 -55
View File
@@ -65,7 +65,7 @@ if (isset($_GET['nummer']))
}
else
{
$nummer = '';
$nummer = '0';
}
if (isset($_GET['frage_id']))
@@ -102,29 +102,175 @@ echo '<?xml version="1.0" encoding="UTF-8"?>';
<link href="../../../skin/style.css.php" rel="stylesheet" type="text/css" />
<script language="Javascript">
//Vorschau anzeigen
function preview()
{
document.getElementById('vorschau').innerHTML = document.getElementById('text').value;
function preview(input) {
const xmlText = document.getElementById('text_'+input).value;
const vorschau = document.getElementById('vorschau_'+input);
// Zurücksetzen der Styles
vorschau.style.textAlign = 'center';
vorschau.style.backgroundColor = 'initial';
vorschau.style.color = 'initial';
// Prüfen ob überhaupt Inhalt vorhanden ist
if (!xmlText.trim()) {
vorschau.innerHTML = '';
return;
}
// Prüfe ob HTML/XML-Tags vorhanden sind
const hatTags = xmlText.indexOf('&lt;') != -1 &amp;&amp; xmlText.indexOf('&gt;') != -1;
if (!hatTags) {
// Kein HTML/XML - zeige als normalen Text
vorschau.innerText = xmlText;
return;
}
// Versuche HTML/MathML zu rendern
try {
// Erstelle einen temporären Container für die Validierung
const tempDiv = document.createElement('div');
tempDiv.innerHTML = xmlText;
// Prüfe auf MathML-Elemente und stelle sicher, dass sie korrekt sind
const mathElements = tempDiv.querySelectorAll('math');
let mathmlValid = true;
// Verwende eine while-Schleife statt for-Schleife um XML-Probleme zu vermeiden
let i = 0;
while (i &lt; mathElements.length) {
const mathEl = mathElements[i];
// Prüfe ob das MathML-Element den korrekten Namespace hat
if (!mathEl.hasAttribute('xmlns')) {
mathEl.setAttribute('xmlns', 'http://www.w3.org/1998/Math/MathML');
}
// Grundlegende MathML-Validierung
const mathmlContent = mathEl.innerHTML;
if (mathmlContent.trim() === '') {
mathmlValid = false;
break;
}
i++;
}
if (mathmlValid) {
// Wenn alles ok ist, zeige den Inhalt an
vorschau.innerHTML = xmlText;
// Versuche MathML zu rendern falls MathJax verfügbar ist
if (typeof MathJax != 'undefined' &amp;&amp; MathJax.typesetPromise) {
MathJax.typesetPromise([vorschau]).catch(function (err) {
console.log('MathJax-Fehler:', err.message);
});
}
} else {
throw new Error('Ungültiges MathML');
}
} catch (error) {
// HTML-Parsing fehlgeschlagen - prüfe ob es sich um reines XML handelt
const startetMitTag = xmlText.trim().charAt(0) === '&lt;';
const endetMitTag = xmlText.trim().charAt(xmlText.trim().length - 1) === '&gt;';
const hatNurTags = xmlText.indexOf('&lt;') === 0 &amp;&amp; xmlText.lastIndexOf('&gt;') === xmlText.length - 1;
if (startetMitTag &amp;&amp; endetMitTag &amp;&amp; hatNurTags) {
// Versuche XML-Parsing
try {
const parser = new DOMParser();
const parsed = parser.parseFromString(xmlText, 'application/xml');
const parsererror = parsed.getElementsByTagName('parsererror');
if (parsererror.length &gt; 0) {
let fehlertext = parsererror[0].textContent;
const zeileninfoStart = fehlertext.indexOf("Zeile Nr.");
if (zeileninfoStart != -1) {
const zeileninfo = fehlertext.substring(zeileninfoStart);
fehlertext = 'XML-Verarbeitungsfehler:\n' + zeileninfo;
}
vorschau.innerText = fehlertext;
vorschau.style.textAlign = 'left';
vorschau.style.backgroundColor = 'lightyellow';
vorschau.style.color = 'red';
return;
} else {
// XML ist gültig
vorschau.innerText = xmlText;
return;
}
} catch (xmlError) {
// XML-Parsing fehlgeschlagen
vorschau.innerText = 'XML-Formatfehler: ' + xmlError.message;
vorschau.style.textAlign = 'left';
vorschau.style.backgroundColor = 'lightyellow';
vorschau.style.color = 'red';
return;
}
} else {
// Gemischter Inhalt oder HTML mit Fehlern - zeige Fehlermeldung
vorschau.innerText = 'HTML/MathML-Formatfehler: ' + error.message;
vorschau.style.textAlign = 'left';
vorschau.style.backgroundColor = 'lightyellow';
vorschau.style.color = 'red';
}
}
}
function previewvorschlag()
{
document.getElementById('vorschauvorschlag').innerHTML = document.getElementById('text_vorschlag').value;
function previewvorschlag() {
const xmlText = document.getElementById('text_vorschlag').value;
const vorschau = document.getElementById('vorschauvorschlag');
const parser = new DOMParser();
const parsed = parser.parseFromString(xmlText, 'application/xml');
const parsererror = parsed.getElementsByTagName('parsererror');
if (parsererror.length > 0) {
var fehlertext = parsererror[0].textContent;
const zeileninfoStart = fehlertext.indexOf("Zeile Nr.");
if (zeileninfoStart !== -1) {
const zeileninfo = fehlertext.substring(zeileninfoStart);
fehlertext = 'XML-Verarbeitungsfehler:\n ' + zeileninfo;
} else {
fehlertext = fehlertext; // Fallback
}
vorschau.innerText = fehlertext;
vorschau.style.textAlign = 'left';
vorschau.style.backgroundColor = 'lightyellow';
} else {
// Zeige XML als Text (nicht als HTML rendern!)
vorschau.innerHTML = xmlText;
vorschau.style.textAlign = 'center';
vorschau.style.backgroundColor = 'initial';
}
}
function insertfrage(aTag, eTag)
{
var input = document.forms['formular_frage'].elements['text'];
var input = document.forms['formular_frage'].elements['text_frage'];
input.focus();
/* Einfügen des Formatierungscodes */
var start = input.selectionStart;
var end = input.selectionEnd;
var insText = input.value.substring(start, end);
input.value = input.value.substr(0, start) + aTag + insText + eTag + input.value.substr(end);
if (eTag)
{
input.value = input.value.substr(0, start) + aTag + insText + eTag + input.value.substr(end);
}
else
{
input.value = input.value.substr(0, start) + aTag + input.value.substr(end);
}
/* Anpassen der Cursorposition */
var pos;
if (insText.length == 0) {
pos = start + aTag.length;
} else {
pos = start + aTag.length + insText.length + eTag.length;
} else
{
if (eTag) {
pos = start + aTag.length + insText.length + eTag.length;
}
else {
pos = start + aTag.length + insText.length;
}
}
input.selectionStart = pos;
input.selectionEnd = pos;
@@ -137,13 +283,25 @@ function insertvorschlag(aTag, eTag)
var start = input.selectionStart;
var end = input.selectionEnd;
var insText = input.value.substring(start, end);
input.value = input.value.substr(0, start) + aTag + insText + eTag + input.value.substr(end);
if (eTag)
{
input.value = input.value.substr(0, start) + aTag + insText + eTag + input.value.substr(end);
}
else
{
input.value = input.value.substr(0, start) + aTag + input.value.substr(end);
}
/* Anpassen der Cursorposition */
var pos;
if (insText.length == 0) {
pos = start + aTag.length;
} else {
pos = start + aTag.length + insText.length + eTag.length;
if (eTag) {
pos = start + aTag.length + insText.length + eTag.length;
}
else {
pos = start + aTag.length + insText.length;
}
}
input.selectionStart = pos;
input.selectionEnd = pos;
@@ -153,6 +311,14 @@ function confirmDeleteFrage()
{
return confirm('Wollen Sie diese Frage wirklich löschen?');
}
function increaseMATHML()
{
const mathTags = document.querySelectorAll('math');
mathTags.forEach(tag => {
tag.style.fontSize = '200%';
});
}
</script>
<style type="text/css">
@@ -778,44 +944,83 @@ if (($anzahl !== 0) || ($stg_kz == '-1') && ($stg_kz !== ''))
<a href="'.$PHP_SELF.'?gebiet_id='.$gebiet_id.'&amp;stg_kz='.$stg_kz.'&amp;nummer='.$nummer.'&amp;filter=aktiv">
<input type="checkbox" name="inaktiv" '.$inaktivchecked.' onclick="window.location.assign(\''.$PHP_SELF.'?gebiet_id='.$gebiet_id.'&amp;stg_kz='.$stg_kz.'&amp;nummer='.$nummer.'&amp;filter=aktiv\');"/>inaktiv</a>';
}
echo '<br/><table class="nummern" style="display: inline-table;"><tbody><tr>
<td>Nummer:</td>';
foreach ($resultArray AS $key=>$value)
{
if ($nummer == '')
$nummer = $value['nummer'];
echo '<br/>';
$style = '';
if ($db->db_parse_bool($value['aktiv']) == false)
$style = 'style="color: lightgrey"';
$counter = 0;
$maxPerTable = 50;
$totalItems = count($resultArray);
$styleSelected = '';
if ($nummer == $value['nummer'])
{
$styleSelected = 'style="background-color: lightblue"';
}
// Erste Tabelle öffnen
echo '<table class="nummern" style="display: inline-table; margin-bottom: 10px;"><tbody><tr>
<td>Nummer:</td>';
echo '<td class="nummern" '.$styleSelected.'><a href="'.$PHP_SELF.'?gebiet_id='.$gebiet_id.'&amp;stg_kz='.$stg_kz.'&amp;nummer='.$value['nummer'].'&amp;filter='.$filter.'" '.$style.'>'.$value['nummer'].'</a></td>';
foreach ($resultArray AS $key=>$value) {
// Neue Tabelle starten, wenn 50 Einträge erreicht sind
if ($counter > 0 && $counter % $maxPerTable == 0) {
// Aktuelle Tabelle schließen
echo '</tr><tr><td>Level:</td>';
// Level-Zeile für die vorherigen Einträge
$startIndex = $counter - $maxPerTable;
$endIndex = $counter;
$tempArray = array_slice($resultArray, $startIndex, $maxPerTable, true);
foreach ($tempArray AS $tempKey=>$tempValue) {
$leveltext = '';
if ($tempValue['level'] == '') {
$leveltext = '-';
} else {
$leveltext = $tempValue['level'];
if ($tempValue['demo'] == 't') {
$leveltext .= '*';
}
}
echo '<td class="nummern" style="color: grey">'.$leveltext.'</td>';
}
echo '</tr></tbody></table><br/>';
// Neue Tabelle starten
echo '<table class="nummern" style="display: inline-table; margin-bottom: 10px;"><tbody><tr>
<td>Nummer:</td>';
}
if ($nummer == '')
$nummer = $value['nummer'];
$style = '';
if ($db->db_parse_bool($value['aktiv']) == false)
$style = 'style="color: lightgrey"';
$styleSelected = '';
if ($nummer == $value['nummer']) {
$styleSelected = 'style="background-color: lightblue"';
}
echo '<td class="nummern" '.$styleSelected.'><a href="'.$PHP_SELF.'?gebiet_id='.$gebiet_id.'&amp;stg_kz='.$stg_kz.'&amp;nummer='.$value['nummer'].'&amp;filter='.$filter.'" '.$style.'>'.$value['nummer'].'</a></td>';
$counter++;
}
echo '</tr><tr>
<td>Level:</td>';
$leveltext = '';
foreach ($resultArray AS $key=>$value)
{
if ($value['level'] == '')
{
$leveltext = '-';
}
else
{
$leveltext = $value['level'];
if ($value['demo'] == 't')
{
$leveltext .= '*';
}
}
echo '<td class="nummern" style="color: grey">'.$leveltext.'</td>';
// Letzte Tabelle schließen
echo '</tr><tr><td>Level:</td>';
// Level-Zeile für die letzten Einträge
$remainingItems = $counter % $maxPerTable;
if ($remainingItems == 0) $remainingItems = $maxPerTable;
$startIndex = $counter - $remainingItems;
$tempArray = array_slice($resultArray, $startIndex, $remainingItems, true);
foreach ($tempArray AS $tempKey=>$tempValue) {
$leveltext = '';
if ($tempValue['level'] == '') {
$leveltext = '-';
} else {
$leveltext = $tempValue['level'];
if ($tempValue['demo'] == 't') {
$leveltext .= '*';
}
}
echo '<td class="nummern" style="color: grey">'.$leveltext.'</td>';
}
echo '</tr></tbody></table>';
echo " <a href='$PHP_SELF?gebiet_id=$gebiet_id&amp;stg_kz=$stg_kz&amp;type=neuefrage&amp;filter=$filter' class='Item'>neue Frage hinzufuegen</a>";
$frage_obj = new frage();
@@ -931,7 +1136,7 @@ if ($frage_id != '')
//Bei Aenderungen im Textfeld werden diese sofort in der Vorschau angezeigt
//Wenn beim Speichern der Text kein Gueltiges XML ist, wird der vorige Text erneut angezeigt
echo "<tr valign='top'><td colspan='2'>\n<textarea name='text' id='text' cols='50' rows='27' oninput='preview()' ".($frage->aktiv == false?'disabled="disabled"':'')."><![CDATA[".(isset($frage_error_text)?$frage_error_text:$frage->text)."]]></textarea>\n</td>";
echo "<tr valign='top'><td colspan='2'>\n<textarea name='text' id='text_frage' cols='50' rows='27' oninput='preview(\"frage\")' ".($frage->aktiv == false?'disabled="disabled"':'')."><![CDATA[".(isset($frage_error_text)?$frage_error_text:$frage->text)."]]></textarea>\n</td>";
echo "<table><tr><td><input type='button' value='br' onclick='insertfrage(\"&lt;br/&gt;\", \"\")' />";
echo "<input type='button' value='F' style='font-weight:bold' onclick='insertfrage(\"&lt;strong&gt;\", \"&lt;/strong&gt;\")' />";
echo "<input type='button' value='K' style='font-style:italic' onclick='insertfrage(\"&lt;i&gt;\", \"&lt;/i&gt;\")' /><br/><br/>";
@@ -948,8 +1153,14 @@ if ($frage_id != '')
echo "<input type='button' value='msqrt' onclick='insertfrage(\"&lt;msqrt&gt;\", \"&lt;/msqrt&gt;\")' title='Wurzel' /><br/>";
echo "<input type='button' value='munderover' onclick='insertfrage(\"&lt;munderover&gt;&lt;mo movablelimits=\&quot;false\&quot;&gt;Das steht mittig&lt;/mo&gt;&lt;mo&gt;Das steht unten&lt;/mo&gt;&lt;mo&gt;Das steht oben&lt;/mo&gt;&lt;/munderover&gt;\", \"\")' title='Oben und unten' /><br/>";
echo "<input type='button' value='mtext' onclick='insertfrage(\"&lt;mtext&gt;\", \"&lt;/mtext&gt;\")' title='Text' /><br/>";
echo "Operatoren:<br/>π<br/>·<br/>∑<br/>∫<br/><a href='http://de.selfhtml.org/html/referenz/zeichen.htm#benannte_iso8859_1' target='blank'>Weitere</a>";
echo "</td>";
echo "Operatoren:<p>";
echo "<button type='button' onclick='insertfrage(\"&lt;mo&gt;π&lt;/mo&gt;\")'>π</button>&nbsp;";
echo "<button type='button' onclick='insertfrage(\"&lt;mo&gt;·&lt;/mo&gt;\")'>·</button>&nbsp;";
echo "<button type='button' onclick='insertfrage(\"&lt;mo&gt;∑&lt;/mo&gt;\")'>∑</button>&nbsp;";
echo "<button type='button' onclick='insertfrage(\"&lt;mo&gt;∫&lt;/mo&gt;\")'>∫</button>";
echo "<p><a href='http://de.selfhtml.org/html/referenz/zeichen.htm#benannte_iso8859_1' target='blank'>Weitere</a></p>";
echo "<button type='button' onclick='increaseMATHML()'>MathML größer</button>";
echo "</p></td>";
echo "</tr></table></tr>";
echo "<tr><td>Demo <input type='checkbox' name='demo' ".($frage->demo?'checked="true"':'')." />
Level <input type='text' name='level' value='$frage->level' size='1' />
@@ -960,7 +1171,10 @@ if ($frage_id != '')
echo "</form>";
echo "</td></tr>";
//Vorschau fuer das Text-Feld
echo "<tr><td colspan='2'>Vorschau:<br /><div id='vorschau' style='border: 1px solid black' align='center'>$frage->text</div></td></tr>";
echo "<tr><td style='width: 50%'>Vorschau:<br />
<div id='vorschau_frage' style='border: 1px solid black' align='center'>$frage->text</div></td>
<td style='width: 50%'>Derzeit:<br /><div id='aktuell' style='border: 1px solid black' align='center'>$frage->text</div>
</td></tr>";
echo "</table>";
echo '</td><td style="border-left: 1px solid black" valign="top">';
@@ -1022,7 +1236,7 @@ if ($frage_id != '')
echo "<input type='button' value='+1/2' style='background-color:#C5FFBF' onclick='document.getElementById(\"punkte\").value=\"0.5\";' /></td>";
echo '</tr>';
echo '<tr valign="top">';
echo '<td>Text:</td><td><textarea name="text" id="text_vorschlag" rows="25" cols="45" oninput="previewvorschlag()" '.($vorschlag->aktiv == true || is_null($vorschlag->aktiv)?'':'disabled="disabled"').'><![CDATA['.$vorschlag->text."]]></textarea>\n</td>";
echo '<td>Text:</td><td><textarea name="text" id="text_vorschlag" rows="25" cols="45" oninput="preview(\'vorschlag\')" '.($vorschlag->aktiv == true || is_null($vorschlag->aktiv)?'':'disabled="disabled"').'><![CDATA['.$vorschlag->text."]]></textarea>\n</td>";
echo "<td><input type='button' value='br' onclick='insertvorschlag(\"&lt;br/&gt;\", \"\")' />";
echo "<input type='button' value='F' style='font-weight:bold' onclick='insertvorschlag(\"&lt;strong&gt;\", \"&lt;/strong&gt;\")' />";
echo "<input type='button' value='K' style='font-style:italic' onclick='insertvorschlag(\"&lt;i&gt;\", \"&lt;/i&gt;\")' /><br/><br/>";
@@ -1039,8 +1253,12 @@ if ($frage_id != '')
echo "<input type='button' value='msqrt' onclick='insertvorschlag(\"&lt;msqrt&gt;\", \"&lt;/msqrt&gt;\")' title='Wurzel' /><br/>";
echo "<input type='button' value='munderover' onclick='insertvorschlag(\"&lt;munderover&gt;&lt;mo movablelimits=\&quot;false\&quot;&gt;Das steht mittig&lt;/mo&gt;&lt;mo&gt;Das steht unten&lt;/mo&gt;&lt;mo&gt;Das steht oben&lt;/mo&gt;&lt;/munderover&gt;\", \"\")' title='Oben und unten' /><br/>";
echo "<input type='button' value='mtext' onclick='insertvorschlag(\"&lt;mtext&gt;\", \"&lt;/mtext&gt;\")' title='Text' /><br/>";
echo "Operatoren:<br/>π<br/>·<br/>∑<br/>∫<br/><a href='http://de.selfhtml.org/html/referenz/zeichen.htm#benannte_iso8859_1' target='blank'>Weitere</a>";
echo "</td>";
echo "Operatoren:<p>";
echo "<button type='button' onclick='insertvorschlag(\"&lt;mo&gt;π&lt;/mo&gt;\")'>π</button>&nbsp;";
echo "<button type='button' onclick='insertvorschlag(\"&lt;mo&gt;·&lt;/mo&gt;\")'>·</button>&nbsp;";
echo "<button type='button' onclick='insertvorschlag(\"&lt;mo&gt;∑&lt;/mo&gt;\")'>∑</button>&nbsp;";
echo "<button type='button' onclick='insertvorschlag(\"&lt;mo&gt;∫&lt;/mo&gt;\")'>∫</button>";
echo "</p></td>";
echo '</tr><tr valign="top">';
//Upload Feld fuer Bild
echo "<td>Bild:</td><td><input type='file' name='bild' /></td>";
@@ -1062,10 +1280,10 @@ if ($frage_id != '')
echo "/></td></tr>";
echo "<tr><td colspan='2' align='right'><input type='submit' name='submitvorschlag' value='Speichern' />".($vorschlag_id != ''?"<input type='button' value='Abbrechen' onclick=\"document.location.href='$PHP_SELF?gebiet_id=$gebiet_id&amp;stg_kz=$stg_kz&amp;nummer=$nummer&amp;frage_id=$frage->frage_id'\" />":'')."</td></tr>";
//Vorschau fuer das Text-Feld
echo "<tr><td colspan='2'>Vorschau:<br /><div id='vorschauvorschlag' style='border: 1px solid black' align='center'>$vorschlag->text</div></td></tr>";
echo "<tr><td colspan='2'>Vorschau:<br /><div id='vorschau_vorschlag' style='border: 1px solid black' align='center'>$vorschlag->text</div>
Derzeit:<br /><div id='aktuellvorschlag' style='border: 1px solid black' align='center'>$vorschlag->text</div></td></tr>";
echo "</table>";
echo "</form>";
echo '</td></tr></table>';
$vorschlag = new vorschlag();
@@ -1115,6 +1333,40 @@ if ($frage_id != '')
echo '<tr><td><input type="hidden" name="allevorschlaege" value="'.$allevorschlaege.'" />Summe:</td><td align="left">'.number_format(array_sum($a), 2, ".", "").'&nbsp;&nbsp;</td><td></td><td></td><td></td><td></td><td></td><td><input type="submit" value="Speichern"/></td></tr>';
echo '</table></form><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>';
}
echo "<script>
document.getElementById('text_vorschlag').addEventListener('keydown', function(e)
{
if (e.key === 'Tab') {
e.preventDefault();
const textarea = e.target;
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
// Tabulator-Zeichen einfügen
textarea.value = textarea.value.substring(0, start) + '\t' + textarea.value.substring(end);
// Cursor hinter den Tab setzen
textarea.selectionStart = textarea.selectionEnd = start + 1;
}
});
document.getElementById('text_frage').addEventListener('keydown', function(e)
{
if (e.key === 'Tab') {
e.preventDefault();
const textarea = e.target;
const start = textarea.selectionStart;
const end = textarea.selectionEnd;
// Tabulator-Zeichen einfügen
textarea.value = textarea.value.substring(0, start) + '\t' + textarea.value.substring(end);
// Cursor hinter den Tab setzen
textarea.selectionStart = textarea.selectionEnd = start + 1;
}
});
</script>";
}
@@ -634,6 +634,7 @@ if(!$error)
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE
mitarbeiter_uid=".$db->db_add_param($lem->mitarbeiter_uid)." AND
lower(mitarbeiter_uid) NOT LIKE '_dummy%' AND
studiensemester_kurzbz=".$db->db_add_param($le->studiensemester_kurzbz)." AND
bismelden";
+42
View File
@@ -575,5 +575,47 @@ class ampel extends basis_db
}
}
/**
* Zählt die Anzahl der UIDs, welche mit einer Ampel adressiert werden
* @param $ampel_id integer ID der Ampel, die geladen werden soll
*/
public function getAnzahlUserAmpel($ampel_id)
{
// Ampel laden
$qry_ampel = "SELECT benutzer_select FROM public.tbl_ampel WHERE ampel_id=".$this->db_add_param($ampel_id, FHC_INTEGER);
if($result_ampel = $this->db_query($qry_ampel))
{
// Anzahl User laden
if ($row_ampel = $this->db_fetch_object($result_ampel))
{
$qry_user = "SELECT count(*) AS anzahl FROM (SELECT uid FROM public.tbl_benutzer WHERE uid IN (".$row_ampel->benutzer_select."))subquery";
}
if ($result = $this->db_query($qry_user))
{
if ($row = $this->db_fetch_object($result))
{
return $row->anzahl;
}
else
{
$this->errormsg = 'Anzahl UIDs konnte nicht geladen werden';
return false;
}
}
else
{
$this->errormsg = 'Anzahl UIDs konnte nicht geladen werden';
return false;
}
}
else
{
$this->errormsg = 'Fehler beim Laden der Ampel';
return false;
}
}
}
?>
+18 -6
View File
@@ -200,7 +200,7 @@ class LehreListHelper
//Studierende der LV laden und in ein Array schreiben
$qry = 'SELECT
distinct on(nachname, vorname, person_id) vorname, nachname, wahlname, matrikelnr, public.tbl_student.student_uid,
distinct on(nachname, vorname, public.tbl_benutzer.person_id) vorname, nachname, wahlname, matrikelnr, public.tbl_student.student_uid,
tbl_studentlehrverband.semester, tbl_studentlehrverband.verband, tbl_studentlehrverband.gruppe,
(SELECT status_kurzbz FROM public.tbl_prestudentstatus
WHERE prestudent_id=tbl_student.prestudent_id
@@ -209,7 +209,8 @@ class LehreListHelper
tbl_note.lkt_ueberschreibbar, tbl_note.anmerkung, tbl_mitarbeiter.mitarbeiter_uid, tbl_person.matr_nr, tbl_person.geschlecht, tbl_studiengang.kurzbzlang,
tbl_mobilitaet.mobilitaetstyp_kurzbz, tbl_zeugnisnote.note,
(CASE WHEN bis.tbl_mobilitaet.studiensemester_kurzbz = vw_student_lehrveranstaltung.studiensemester_kurzbz THEN 1 ELSE 0 END) as doubledegree,
(tbl_bisio.bis::timestamp - tbl_bisio.von::timestamp) as daysout
(tbl_bisio.bis::timestamp - tbl_bisio.von::timestamp) as daysout,
public.tbl_prestudent.gsstudientyp_kurzbz as ddtype
FROM
campus.vw_student_lehrveranstaltung
JOIN public.tbl_benutzer USING(uid)
@@ -223,6 +224,7 @@ class LehreListHelper
LEFT JOIN bis.tbl_bisio ON(uid=tbl_bisio.student_uid)
LEFT JOIN public.tbl_studiengang ON(tbl_student.studiengang_kz=tbl_studiengang.studiengang_kz)
LEFT JOIN bis.tbl_mobilitaet USING(prestudent_id)
LEFT JOIN public.tbl_prestudent USING(prestudent_id)
WHERE
vw_student_lehrveranstaltung.lehrveranstaltung_id='.$this->db->db_add_param($this->lvid, FHC_INTEGER).' AND
vw_student_lehrveranstaltung.studiensemester_kurzbz='.$this->db->db_add_param($this->studiensemester);
@@ -231,7 +233,7 @@ class LehreListHelper
if($this->lehreinheit!='')
$qry.=' AND vw_student_lehrveranstaltung.lehreinheit_id='.$this->db->db_add_param($this->lehreinheit, FHC_INTEGER);
$qry.=' ORDER BY nachname, vorname, person_id, daysout DESC, doubledegree DESC';
$qry.=' ORDER BY nachname, vorname, public.tbl_benutzer.person_id, daysout DESC, doubledegree DESC';
$stsem_obj = new studiensemester();
$stsem_obj->load($this->studiensemester);
@@ -263,8 +265,13 @@ class LehreListHelper
//Outgoing
if($row->bisio_id != '' && $row->status != 'Incoming' && ($row->bis > $stsemdatumvon || $row->bis == '')
&& $row->von < $stsemdatumbis && (anzahlTage($row->von, $row->bis) >= 30))
&& $row->von < $stsemdatumbis && (anzahlTage($row->von, $row->bis) >= 30)) {
$zusatz .= '(o)(ab '.$datum->formatDatum($row->von, 'd.m.Y').')';
} else if ($row->bisio_id != '' && $row->status != 'Incoming' && ($row->von > $stsemdatumvon || $row->von == '')) {
// if bis datum is not yet known but von is available already
$zusatz .= '(o)(ab '.$datum->formatDatum($row->von, 'd.m.Y').')';
}
if($row->lkt_ueberschreibbar == 'f') // angerechnet / intern angerechnet / nicht zugelassen
$zusatz.= '('. $row->anmerkung. ')';
@@ -275,8 +282,13 @@ class LehreListHelper
if($row->stg_kz_student==$a_o_kz) //Außerordentliche Studierende
$zusatz.='(a.o.)';
if(($row->mobilitaetstyp_kurzbz != '') && ($row->doubledegree == 1)) //Double Degree Student
$zusatz .= '(d.d.)';
if(($row->mobilitaetstyp_kurzbz != '') && ($row->doubledegree == 1)) {
//Double Degree Student
$zusatz .= '(d.d.';
if($row->ddtype == 'Intern') $zusatz .= 'i.)';
else if ($row->ddtype == 'Extern') $zusatz .='o.)';
else $zusatz .= ')';
}
if(($row->wahlname != ''))
{
+1
View File
@@ -119,6 +119,7 @@ export default {
<div class="modal-content">
<div v-if="$slots.title" class="modal-header">
<h5 class="modal-title"><slot name="title"/></h5>
<slot name="popoutButton"></slot>
<button v-if="!noCloseBtn" type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" :class="bodyClass">
+1 -1
View File
@@ -318,7 +318,7 @@ export default {
>
<slot></slot>
</component>
<label v-if="label && (lcType == 'radio' || lcType == 'checkbox')" :for="idCmp" :class="!noAutoClass && 'form-check-label'">{{label}}</label>
<label v-if="label && (lcType == 'radio' || lcType == 'checkbox')" :for="idCmp" :class="!noAutoClass && 'form-check-label'" v-html="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">
+5 -1
View File
@@ -20,6 +20,10 @@ export default {
accept: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
},
methods: {
@@ -88,7 +92,7 @@ export default {
},
template: `
<div class="form-upload-dms">
<input ref="upload" class="form-control" :accept="accept" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
<input ref="upload" class="form-control" :disabled="disabled" :accept="accept" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
<ul v-if="modelValue.length && multiple && !noList" :accept="accept" class="list-unstyled m-0">
<dms-item
v-for="(file, index) in modelValue"
+11 -6
View File
@@ -75,7 +75,7 @@ export const CoreFilterCmpt = {
newBtnDisabled: Boolean,
newBtnLabel: String,
uniqueId: String,
// TODO soll im master kommen?
idField: String,
parentIdField: String,
countOnly: Boolean
@@ -216,17 +216,22 @@ export const CoreFilterCmpt = {
}
// Define a default tabulator options in case it was not provided
let tabulatorOptions = {...{
height: 500,
layout: "fitDataStretchFrozen",
movableColumns: true,
columnDefaults:{
tooltip: true
},
placeholder,
reactiveData: true,
persistence: this.persistence,
}, ...(this.tabulatorOptions || {})};
// set default height if no height property is set
if (tabulatorOptions.height === undefined &&
tabulatorOptions.minHeight === undefined &&
tabulatorOptions.maxHeight === undefined) {
tabulatorOptions.height = 500;
}
if (!this.tableOnly) {
tabulatorOptions.data = this.filteredData;
tabulatorOptions.columns = this.filteredColumns;
@@ -234,7 +239,7 @@ export const CoreFilterCmpt = {
if (tabulatorOptions.selectable || (tabulatorOptions.columns && tabulatorOptions.columns.filter(el => el.formatter == 'rowSelection').length))
this.tabulatorHasSelector = true;
// TODO check ob im core bleiben soll
if (this.idField) {
// enable nested tabulator if parent Id given
if (this.parentIdField) tabulatorOptions.dataTree = true;
@@ -258,7 +263,7 @@ export const CoreFilterCmpt = {
this.tabulator.on("rowSelectionChanged", data => {
this.selectedData = data;
});
// TODO check ob im core so bleiben soll
// if nested tabulator, restructure data
if (this.parentIdField && this.idField) {
this.tabulator.on("dataLoading", data => {
@@ -575,7 +580,7 @@ export const CoreFilterCmpt = {
this.getFilter
);
},
// TODO check ob im core so bleiben soll
// append child to it's parent
appendChild(data, child) {
// get parent id
@@ -50,12 +50,21 @@ var InfocenterPersonDataset = {
'</select>' +
'<select class="form-control auswahlAbsageAbgeschickt" style="width:auto; float:left;">' +
'<option value="null" selected="selected"> Bewerbung abgeschickt? </option>' +
'<option value="all"> Beide </option>' +
'<option value="true"> Ja </option>' +
'<option value="false"> Nein </option>' +
'</select>' +
'<button class="btn btn-default auswahlAbsageBtn" style="float:left"> Absage </button>';
let rueckstellung = '<br />' +
'<select id="rueckstellungtype" class="form-control" style="width:auto; float:left;">' +
'<option disabled value="null" selected>' + FHC_PhrasesLib.t('infocenter', 'statusAuswahl') + '</option>' +
'</select>' +
'<input id="rueckstellungdate" type="text" class="form-control" style="width:auto; float:left;" placeholder="Parkdatum">' +
'<button class="form-control btn btn-default rueckstellBtn" style="width:auto; float:left"> Zurückstellen </button>';
InfocenterPersonDataset.getAbsageData();
Rueckstellung.getStatus()
var studienSemesterHtml = '<button class="btn btn-default btn-xs decStudiensemester">' +
'<i class="fa fa-chevron-left"></i>' +
@@ -98,10 +107,22 @@ var InfocenterPersonDataset = {
"<div class='row'>"+
"<div class='col-xs-12'>"+auswahlAbsageToggle+"</div>"+
"<div class='col-xs-12' id='absagePunkte' style='display:none'>"+auswahlAbsage+"</div>"+
"<div class='col-xs-12' id='rueckstellung' style='display:none'>"+rueckstellung+"</div>"+
"</div>" +
"<div class='h-divider'></div>" +
"<hr class='studiensemesterline'>"
)
let rueckstelldate = new Date();
rueckstelldate.setDate(rueckstelldate.getDate() + 14);
$('#rueckstellungdate').attr("value", $.datepicker.formatDate("dd.mm.yy", rueckstelldate));
$("#rueckstellungdate").datepicker({
"dateFormat": "dd.mm.yy",
"minDate": 1
});
$("button.incStudiensemester").click(function() {
InfocenterPersonDataset.changeStudiensemesterUservar(1);
});
@@ -123,6 +144,29 @@ var InfocenterPersonDataset = {
$(".absageModalForAll").modal("show");
});
$('button.rueckstellBtn').click(function()
{
let idsel = $("#filterTableDataset input:checked[name=PersonId\\[\\]]");
if(idsel.length <= 0)
return FHC_DialogLib.alertInfo("Bitte wählen Sie die Personen aus.");
let type = $('#rueckstellungtype').val()
if (type === null)
return FHC_DialogLib.alertInfo("Bitte ein Rückstellgrund auswählen.");
let personen = [];
for (let i = 0; i < idsel.length; i++)
{
personen.push($(idsel[i]).val());
}
let date = $("#rueckstellungdate").val();
Rueckstellung.setForPersons(personen, type, date)
});
$('#saveAbsageForAll').click(function()
{
InfocenterPersonDataset.saveAbsageForAll();
@@ -131,6 +175,7 @@ var InfocenterPersonDataset = {
$('a.absageToggle').click(function()
{
$('#absagePunkte').toggle();
$('#rueckstellung').toggle();
})
var personcount = 0;
@@ -356,6 +401,11 @@ var InfocenterPersonDataset = {
text: value.bezeichnung_mehrsprachig[0]
}))
})
$('.auswahlAbsageStg').append($("<option/>", {
value: 'all',
text: 'Alle'
}))
$.each(data.studiengaenge, function(key, value){
$('.auswahlAbsageStg').append($("<option/>", {
value: value.studiengang,
+27
View File
@@ -87,6 +87,33 @@ var Rueckstellung = {
}
);
},
setForPersons: function(personen, type, date)
{
if (type === null)
return false;
FHC_AjaxClient.ajaxCallPost(
CONTROLLER_RUECKSTELLUNG_URL + '/setForPersonen',
{
"personen": personen,
"datum_bis": date,
"status_kurzbz": type,
},
{
successCallback: function(data, textStatus, jqXHR) {
if (FHC_AjaxClient.isError(data))
FHC_DialogLib.alertError(FHC_AjaxClient.getError(data));
if (FHC_AjaxClient.hasData(data))
FHC_DialogLib.alertSuccess("Erfolgreich gespeichert.")
},
errorCallback: function(jqXHR, textStatus, errorThrown) {
FHC_DialogLib.alertError(textStatus);
},
veilTimeout: 0
}
);
},
delete: function(personid, status = null)
{
FHC_AjaxClient.ajaxCallPost(
+7 -1
View File
@@ -117,7 +117,7 @@ const helperApp = Vue.createApp({
},
methods: {
mailToUrl(slotProps) {
let mailTo = 'noreply@technikum-wien.at'; // TODO domain anpassen
let mailTo = FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto;
let subject = 'Meldung%20Systemfehler';
let body = `
Danke, dass Sie uns den Fehler melden. %0D%0A %0D%0A
@@ -141,6 +141,11 @@ const helperApp = Vue.createApp({
unmounted() {
helperAppContainer.parentElement.removeChild(helperAppContainer);
},
computed: {
showmaillink: function() {
return FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto !== '';
}
},
template: `
<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">
@@ -162,6 +167,7 @@ const helperApp = Vue.createApp({
Fehler anzeigen
</a>
<a
v-if="showmaillink"
class="btn btn-primary flex-fill"
target="_blank"
:href="mailToUrl(slotProps)"
+7 -1
View File
@@ -109,7 +109,7 @@ const helperApp = Vue.createApp({
},
methods: {
mailToUrl(slotProps) {
let mailTo = 'noreply@technikum-wien.at'; // TODO domain anpassen
let mailTo = FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto;
let subject = 'Meldung%20Systemfehler';
let body = `
Danke, dass Sie uns den Fehler melden. %0D%0A %0D%0A
@@ -133,6 +133,11 @@ const helperApp = Vue.createApp({
unmounted() {
helperAppContainer.parentElement.removeChild(helperAppContainer);
},
computed: {
showmaillink: function() {
return FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto !== '';
}
},
template: `
<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">
@@ -154,6 +159,7 @@ const helperApp = Vue.createApp({
Fehler anzeigen
</a>
<a
v-if="showmaillink"
class="btn btn-primary flex-fill"
target="_blank"
:href="mailToUrl(slotProps)"
+21 -1
View File
@@ -35,6 +35,7 @@ require_once('../include/studiengang.class.php');
require_once('../include/mitarbeiter.class.php');
require_once('../include/anrechnung.class.php');
require_once('../include/prestudent.class.php');
require_once('../include/nation.class.php');
$datum = new datum();
$db = new basis_db();
@@ -107,7 +108,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
tbl_studiengang.bezeichnung, tbl_studiengang.english, tbl_studentlehrverband.semester,
tbl_person.vorname, tbl_person.vornamen, tbl_person.nachname,tbl_person.gebdatum,tbl_person.titelpre,
tbl_person.titelpost, tbl_person.anrede, tbl_studiensemester.bezeichnung as sembezeichnung,
tbl_studiensemester.studiensemester_kurzbz as stsem, tbl_student.prestudent_id, tbl_studiengang.max_semester
tbl_studiensemester.studiensemester_kurzbz as stsem, tbl_student.prestudent_id, tbl_studiengang.max_semester, tbl_person.gebort, tbl_person.geburtsnation, tbl_person.geschlecht
FROM tbl_person, tbl_student, tbl_studiengang, tbl_benutzer, tbl_studentlehrverband, tbl_studiensemester
WHERE tbl_student.studiengang_kz = tbl_studiengang.studiengang_kz
AND tbl_student.student_uid = tbl_benutzer.uid AND tbl_benutzer.person_id = tbl_person.person_id
@@ -187,6 +188,10 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
else
$studiengang_kz = sprintf("%04s", abs($row->studiengang_kz));
$nation = new nation($row->geburtsnation);
$geburtsnation = $nation->kurztext;
$xml .= " <studiengang_art><![CDATA[".$bezeichnung."]]></studiengang_art>";
$xml .= " <studiengang_kz><![CDATA[".$studiengang_kz."]]></studiengang_kz>";
$xml .= "\n <anrede><![CDATA[".$row->anrede."]]></anrede>";
@@ -195,6 +200,9 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
$xml .= " <name><![CDATA[".trim($row->titelpre.' '.trim($row->vorname.' '.$row->vornamen).' '.$row->nachname.($row->titelpost!=''?', '.$row->titelpost:''))."]]></name>";
$gebdatum = date('d.m.Y',strtotime($row->gebdatum));
$xml .= " <gebdatum><![CDATA[".$gebdatum."]]></gebdatum>";
$xml .= " <gebort><![CDATA[".$row->gebort."]]></gebort>";
$xml .= " <geburtsnation><![CDATA[".$geburtsnation."]]></geburtsnation>";
$xml .= " <geschlecht><![CDATA[".$row->geschlecht."]]></geschlecht>";
$xml .= " <matrikelnr><![CDATA[".trim($row->matrikelnr)."]]></matrikelnr>";
$xml .= " <studiengangsleiter><![CDATA[".$stgl."]]></studiengangsleiter>";
$datum_aktuell = date('d.m.Y');
@@ -267,6 +275,15 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
if ($lastPrestudentStatus)
$showAllNoten = $prestudent->status_kurzbz === 'Incoming';
$lastBenotungsdatum = '';
$dates = array_column($obj->result, 'benotungsdatum');
if (!empty($dates))
{
$lastBenotungsdatum = max($dates);
$xml .= "<last_benotungsdatum><![CDATA[".date('d.m.Y', strtotime($lastBenotungsdatum))."]]></last_benotungsdatum>";
}
foreach ($obj->result as $row)
{
if($showAllNoten || $row->zeugnis)
@@ -390,12 +407,15 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
}
}
$xml .= "\n <unterrichtsfach>";
$xml .= " <benotungsdatum><![CDATA[".date('d.m.Y', strtotime($row->benotungsdatum))."]]></benotungsdatum>";
$xml .= " <bezeichnung><![CDATA[".$bezeichnung."]]></bezeichnung>";
$xml .= " <bezeichnung_englisch><![CDATA[".$bezeichnung_englisch."]]></bezeichnung_englisch>";
$xml .= " <note_positiv><![CDATA[".$row->note_positiv."]]></note_positiv>";
$xml .= " <note><![CDATA[".$note2."]]></note>";
$xml .= " <sws><![CDATA[".($row->semesterstunden==0?'':number_format(sprintf('%.1F',$row->semesterstunden/$wochen),1))."]]></sws>";
$xml .= " <sws_lv><![CDATA[".($row->sws==0?'':number_format(sprintf('%.1F',$row->sws),1))."]]></sws_lv>";
$xml .= " <lv_id><![CDATA[".$row->lehrveranstaltung_id."]]></lv_id>";
$ectspunkte='';
$anrechnung = new anrechnung();
+16
View File
@@ -324,6 +324,22 @@ $fehlerArr = array(
'fehlertext' => 'Es sind mehrere oder keine Zustelladressen eingetragen',
'fehlertyp_kurzbz' => 'error',
'app' => 'core'
),
array(
'fehlercode' => 'CORE_PERSON_0005',
'fehler_kurzbz' => 'geburtsnationFehlt',
'fehlercode_extern' => null,
'fehlertext' => 'Geburtsnation nicht vorhanden',
'fehlertyp_kurzbz' => 'error',
'app' => 'core'
),
array(
'fehlercode' => 'CORE_PERSON_0006',
'fehler_kurzbz' => 'uhstatPersonkennungFehltCore',
'fehlercode_extern' => null,
'fehlertext' => 'Personkennung fehlt (vBpk AS, vBpk BF oder Ersatzkennzeichen fehlt)',
'fehlertyp_kurzbz' => 'error',
'app' => 'core'
)
/** Plausichecks end **/
);
+423 -3
View File
@@ -30084,6 +30084,26 @@ array(
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'entschuldigungStatusUpdateAutoEmailBetreff',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Entschuldigung Status Update.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Excuse note status update.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
@@ -31412,7 +31432,7 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Termine laut Stundenplan',
'text' => 'Unterricht laut Stundenplan',
'description' => '',
'insertvon' => 'system'
),
@@ -31424,6 +31444,26 @@ array(
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'unterrichtDauer',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterricht Dauer',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lesson Duration',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
@@ -31492,13 +31532,13 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Keine zugeteilten Studenten gefunden!',
'text' => 'Keine zugeteilten Studenten gefunden für den gewählten LV-Teil gefunden!',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'No assigned students found!',
'text' => 'No assigned students for the selected teaching unit found!',
'description' => '',
'insertvon' => 'system'
)
@@ -31804,6 +31844,86 @@ array(
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'kontrollDauerUnterMindestwert',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kontrolle muss für eine Unterrichtsdauer von mindestens {0} Minuten gelten.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Attendance check must apply for a lesson duration of at least {0} minutes.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'zeitNichtAusStundenplanBeginn',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterrichtbeginn entspricht keinem Unterrichtstermin laut Stundenplan.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lecture Begin Time does not match a lesson as per timetable.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'zeitNichtAusStundenplanEnde',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterrichtende entspricht keinem Unterrichtstermin laut Stundenplan.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lecture End Time does not match a lesson as per timetable.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'datumNichtAusStundenplan',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datum entspricht keinem Stundenplan Termin.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Date does not match a lesson as per timetable.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
@@ -32000,6 +32120,306 @@ array(
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'anwTimeline',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Digitale Anwesenheiten Timeline',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Digital Attendances Timeline',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'entschuldigungEdit',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Entschuldigung bearbeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Excuse Note Edit',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'excuseUploadNoFile',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Dokument wird nachgereicht',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Document will be submitted later',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'entschuldigungEditieren',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Entschuldigung bearbeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Edit Excuse Note',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'missingEntschuldigungFile',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fehlendes Dokument!',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Missing Document!',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'anwKontrolleVon',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterricht von',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lesson from',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'anwKontrolleBis',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterricht bis',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lesson until',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'termineAusStundenplan',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterricht Termine laut Stundenplan',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lesson dates according to timetable',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'tooltipUnterrichtZeitCustom',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterrichtszeiten werden aus dem Stundenplan geladen, überschreiben Sie diese nur falls Ihre tatsächliche Unterrichtszeiten davon abweichen!',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lesson times are loaded from the timetable, only overwrite them if your actual lesson times differ!',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'tooltipUnterrichtDatumCustom',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterrichtsdaten werden aus dem Stundenplan geladen, überschreiben Sie dieses nur falls Ihr tatsächliches Unterrichtsdatum abweicht!',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Class dates are loaded from the timetable, only overwrite this if your actual class date differs!',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'unterrichtzeit',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Unterrichtszeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Lesson Times',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'statusLegende',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Status Legende',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Status Legend',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'download',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Herunterladen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Download',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'upload',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Hochladen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Upload',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'anwesenheiten',
'category' => 'global',
'phrase' => 'providedDateTooOld',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Angegebenes Datum ist älter als erlaubt.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Provided date is older than allowed date',
'description' => '',
'insertvon' => 'system'
)
)
),
//
// DIGITALE ANWESENHEITEN PHRASEN END
//
+2
View File
@@ -550,6 +550,8 @@ if($orgform_kurzbz != -1)
if($lehrveranstaltung_id != '')
$sql_query.= " AND tbl_lehrveranstaltung.lehrveranstaltung_id=".$db->db_add_param($lehrveranstaltung_id, FHC_INTEGER);
elseif(isset($_GET['delete_lvid']))
$sql_query.= " AND tbl_lehrveranstaltung.lehrveranstaltung_id=".$db->db_add_param(intval($_GET['delete_lvid']), FHC_INTEGER);
if($lehrveranstaltung_name != '')
{
@@ -30,8 +30,6 @@
require_once('../../include/lehrmodus.class.php');
require_once('../../include/benutzerberechtigung.class.php');
require_once('../../include/studienplan.class.php');
require_once('../../include/lehrveranstaltung_faktor.class.php');
require_once('../../include/studiensemester.class.php');
if (!$db = new basis_db())
die('Es konnte keine Verbindung zum Server aufgebaut werden.');
@@ -141,31 +139,6 @@
$reloadstr .= " window.location.href='".$_SERVER['PHP_SELF']."?stg_kz=$lv->studiengang_kz&semester=$lv->semester&neu=true';";
}
$reloadstr .= "</script>\n";
if (in_array($lv->lehrtyp_kurzbz, array('tpl', 'lv')) && $lv->new === true)
{
$lv_faktor = new lehrveranstaltung_faktor();
$studiensemester = new studiensemester();
$studiensemester_von = $studiensemester->getLastOrAktSemester();
if ($lv->lehrtyp_kurzbz === 'lv' && $_POST['lehrveranstaltung_template_id'] !== '')
{
$lv_faktor->getAkt($_POST['lehrveranstaltung_template_id']);
//TODO Faktor in eine Config
if (is_null($lv_faktor->faktor))
$lv_faktor->addFaktor($lv->lehrveranstaltung_id, 2, $studiensemester_von);
else
$lv_faktor->addFaktor($lv->lehrveranstaltung_id, $lv_faktor->faktor, $studiensemester_von);
}
else
{
$lv_faktor->loadByLV($lv->lehrveranstaltung_id);
if (empty($lv_faktor->lv_faktoren))
{
$lv_faktor->addFaktor($lv->lehrveranstaltung_id, 2, $studiensemester_von);
}
}
}
}
}
+14 -2
View File
@@ -192,6 +192,15 @@ $datum_obj = new datum();
die('Invalid Action');
break;
}
if(isset($ampel_id) && $ampel->benutzer_select != '')
{
$anzahlUser = $ampel->getAnzahlUserAmpel($ampel_id);
}
else
{
$anzahlUser = 0;
}
echo '<form action="'.$_SERVER['PHP_SELF'].'?action=save" method="POST">
<input type="hidden" name="new" value="'.htmlspecialchars($new).'">
@@ -207,8 +216,11 @@ $datum_obj = new datum();
<td><input type="text" class="datepicker_datum" name="deadline" size="10" maxlength="10" value="'.htmlspecialchars($datum_obj->formatDatum($ampel->deadline,'Y-m-d')).'" required></td>
</tr>
<tr valign="top">
<td rowspan="3">Benutzer Select</td>
<td rowspan="3"><textarea name="benutzer_select" cols="60" rows="5" required>'.htmlspecialchars($ampel->benutzer_select).'</textarea></td>
<td rowspan="3">Benutzer*innen Select</td>
<td rowspan="3">
<textarea name="benutzer_select" cols="60" rows="5" required>'.htmlspecialchars($ampel->benutzer_select).'</textarea>
<br>Anzahl Benutzer*innen: '.$anzahlUser.'
</td>
<td></td>
<td valign="middle">Vorlaufzeit (in Tagen)&nbsp
<i class="fa fa-info-circle fa-lg" aria-hidden="true" data-toggle="tooltip" data-placement="left" title="Anzahl der Tage VOR der Deadline, an denen die Ampel gezeigt werden soll.&#013Wenn keine Angabe, dann wird die Ampel gleich nach ihrer Erstellung angezeigt."></i>