mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-01 20:29:29 +00:00
Merge remote-tracking branch 'origin/feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter' into feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter
This commit is contained in:
@@ -110,11 +110,10 @@ $config['abmeldung_job_deadline_date_modifier'] = '+2 weeks';
|
||||
|
||||
/**
|
||||
* System User - uid of a user that is allowed to set prestudentstatus
|
||||
* TODO(chris): DEBUG! CHANGE THIS!
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
$config['antrag_job_systemuser'] = 'ma0168';
|
||||
$config['antrag_job_systemuser'] = '';
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,9 @@ class Filter extends FHC_Controller
|
||||
// Loads authentication library and starts authentication
|
||||
$this->load->library('AuthLib');
|
||||
|
||||
// Loads the FiltersModel
|
||||
$this->load->model('system/Filters_model', 'FiltersModel');
|
||||
|
||||
// Loads the FilterCmptLib with HTTP GET/POST parameters
|
||||
$this->_startFilterCmptLib();
|
||||
}
|
||||
|
||||
@@ -165,9 +165,14 @@ class AntragJob extends JOB_Controller
|
||||
}
|
||||
|
||||
$data['table'] = $data['table_' . DEFAULT_LANGUAGE];
|
||||
$data['leitungLink'] = APP_ROOT. 'index.ci.php/lehre/Studierendenantrag/leitung';
|
||||
|
||||
//Mail an Stgl und Assistenz
|
||||
$to = $leitung['Details']->uid . '@' . DOMAIN;
|
||||
$cc = $leitung['Details']->email;
|
||||
|
||||
// NOTE(chris): Sancho mail
|
||||
if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $leitung['Details']->uid . '@' . DOMAIN, 'Anträge - Aktion(en) erforderlich'))
|
||||
if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $to, 'Anträge - Aktion(en) erforderlich', DEFAULT_SANCHO_HEADER_IMG, DEFAULT_SANCHO_FOOTER_IMG, '', $cc))
|
||||
$count++;
|
||||
}
|
||||
|
||||
@@ -426,40 +431,56 @@ class AntragJob extends JOB_Controller
|
||||
$modifier_request_2 = $this->config->item('wiederholung_job_request_2_date_modifier');
|
||||
$modifier_deadline = $this->config->item('wiederholung_job_deadline_date_modifier');
|
||||
|
||||
if ($modifier_deadline)
|
||||
{
|
||||
$digi_start = $this->config->item('digitalization_start');
|
||||
if ($digi_start) {
|
||||
try {
|
||||
$digi_start = new DateTime($digi_start);
|
||||
} catch(Exception $e) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($modifier_deadline) {
|
||||
$dateDeadline = new DateTime();
|
||||
$dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline));
|
||||
|
||||
if ($digi_start)
|
||||
$dateDeadline = max($digi_start, $dateDeadline);
|
||||
} else {
|
||||
$dateDeadline = $digi_start ?: null;
|
||||
}
|
||||
else
|
||||
$dateDeadline = null;
|
||||
|
||||
//first request
|
||||
if ($modifier_request_1)
|
||||
$this->sendReminder(
|
||||
'Request1',
|
||||
null,
|
||||
Studierendenantragstatus_model::STATUS_REQUESTSENT_1,
|
||||
$dateDeadline,
|
||||
$modifier_request_1,
|
||||
$modifier_deadline,
|
||||
'Aufforderung: Bekanntgabe Wiederholung'
|
||||
);
|
||||
else
|
||||
if ($modifier_request_1) {
|
||||
$dateStichtag = new DateTime();
|
||||
$dateStichtag->sub(DateInterval::createFromDateString($modifier_request_1));
|
||||
if (!$dateDeadline || $dateStichtag > $dateDeadline)
|
||||
$this->sendReminder(
|
||||
'Request1',
|
||||
null,
|
||||
Studierendenantragstatus_model::STATUS_REQUESTSENT_1,
|
||||
$dateDeadline,
|
||||
$dateStichtag,
|
||||
$modifier_deadline,
|
||||
'Aufforderung: Bekanntgabe Wiederholung'
|
||||
);
|
||||
} else
|
||||
$this->logError('Config "wiederholung_job_request_1_date_modifier" nicht gesetzt');
|
||||
|
||||
//second request
|
||||
if ($modifier_request_2)
|
||||
$this->sendReminder(
|
||||
'Request2',
|
||||
Studierendenantragstatus_model::STATUS_REQUESTSENT_1,
|
||||
Studierendenantragstatus_model::STATUS_REQUESTSENT_2,
|
||||
$dateDeadline,
|
||||
$modifier_request_2,
|
||||
$modifier_deadline,
|
||||
'Reminder Aufforderung: Bekanntgabe Wiederholung'
|
||||
);
|
||||
else
|
||||
if ($modifier_request_2) {
|
||||
$dateStichtag = new DateTime();
|
||||
$dateStichtag->sub(DateInterval::createFromDateString($modifier_request_2));
|
||||
if (!$dateDeadline || $dateStichtag > $dateDeadline)
|
||||
$this->sendReminder(
|
||||
'Request2',
|
||||
Studierendenantragstatus_model::STATUS_REQUESTSENT_1,
|
||||
Studierendenantragstatus_model::STATUS_REQUESTSENT_2,
|
||||
$dateDeadline,
|
||||
$dateStichtag,
|
||||
$modifier_deadline,
|
||||
'Reminder Aufforderung: Bekanntgabe Wiederholung'
|
||||
);
|
||||
} else
|
||||
$this->logError('Config "wiederholung_job_request_2_date_modifier" nicht gesetzt');
|
||||
|
||||
$this->logInfo('Ende Job sendAufforderungWiederholer');
|
||||
@@ -479,14 +500,11 @@ class AntragJob extends JOB_Controller
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function sendReminder($name, $status_from, $status_to, $deadline, $date_modifier, $modifier_deadline, $subject)
|
||||
protected function sendReminder($name, $status_from, $status_to, $deadline, $date_stichtag, $modifier_deadline, $subject)
|
||||
{
|
||||
$this->logInfo('Start Job sendAufforderungWiederholer ' . $name);
|
||||
|
||||
$dateStichtag = new DateTime();
|
||||
$dateStichtag->sub(DateInterval::createFromDateString($date_modifier));
|
||||
|
||||
$result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed($status_from, $dateStichtag, $deadline);
|
||||
$result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed($status_from, $date_stichtag, $deadline);
|
||||
|
||||
if(isError($result))
|
||||
{
|
||||
|
||||
@@ -20,7 +20,8 @@ class Dienstverhaeltnis extends AbstractBestandteil {
|
||||
protected $dienstverhaeltnis_id;
|
||||
protected $mitarbeiter_uid;
|
||||
protected $vertragsart_kurzbz;
|
||||
protected $oe_kurzbz;
|
||||
protected $oe_kurzbz;
|
||||
protected $checkoverlap;
|
||||
protected $von;
|
||||
protected $bis;
|
||||
protected $insertamum;
|
||||
@@ -31,6 +32,7 @@ class Dienstverhaeltnis extends AbstractBestandteil {
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->checkoverlap = true;
|
||||
}
|
||||
|
||||
public function hydrateByStdClass($data, $fromdb=false)
|
||||
@@ -39,6 +41,7 @@ class Dienstverhaeltnis extends AbstractBestandteil {
|
||||
isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id);
|
||||
isset($data->mitarbeiter_uid) && $this->setMitarbeiter_uid($data->mitarbeiter_uid);
|
||||
isset($data->vertragsart_kurzbz) && $this->setVertragsart_kurzbz($data->vertragsart_kurzbz);
|
||||
isset($data->checkoverlap) && $this->setCheckoverlap($data->checkoverlap);
|
||||
isset($data->oe_kurzbz) && $this->setOe_kurzbz($data->oe_kurzbz);
|
||||
isset($data->von) && $this->setVon($data->von);
|
||||
isset($data->bis) && $this->setBis($data->bis);
|
||||
@@ -157,6 +160,11 @@ EOTXT;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCheckoverlap(bool $checkoverlap)
|
||||
{
|
||||
$this->checkoverlap = $checkoverlap;
|
||||
}
|
||||
|
||||
public function setOe_kurzbz($oe_kurzbz)
|
||||
{
|
||||
$this->markDirty('oe_kurzbz', $this->oe_kurzbz, $oe_kurzbz);
|
||||
@@ -239,8 +247,7 @@ EOTXT;
|
||||
$this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.';
|
||||
}
|
||||
|
||||
// TODO check for overlapping DVs
|
||||
if( $ci->VertragsbestandteilLib->isOverlappingExistingDV($this) )
|
||||
if( $this->checkoverlap && $ci->VertragsbestandteilLib->isOverlappingExistingDV($this) )
|
||||
{
|
||||
$this->validationerrors[] = 'Es existiert bereits ein überlappendes Dienstverhältnis';
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ class GehaltsbestandteilLib
|
||||
$this->CI = get_instance();
|
||||
$this->CI->load->model('vertragsbestandteil/Gehaltsbestandteil_model',
|
||||
'GehaltsbestandteilModel');
|
||||
$this->CI->load->library('extensions/FHC-Core-Personalverwaltung/abrechnung/GehaltsLib');
|
||||
$this->GehaltsbestandteilModel = $this->CI->GehaltsbestandteilModel;
|
||||
}
|
||||
|
||||
@@ -111,6 +112,11 @@ class GehaltsbestandteilLib
|
||||
public function deleteGehaltsbestandteil(Gehaltsbestandteil $gehaltsbestandteil)
|
||||
{
|
||||
$this->setUIDtoPGSQL();
|
||||
|
||||
// delete Gehaltsabrechnung
|
||||
$ret = $this->CI->gehaltslib->deleteAbrechnung($gehaltsbestandteil);
|
||||
|
||||
//
|
||||
$ret = $this->GehaltsbestandteilModel->delete($gehaltsbestandteil->getGehaltsbestandteil_id());
|
||||
|
||||
if (isError($ret))
|
||||
|
||||
@@ -42,18 +42,30 @@ class VertragsbestandteilFunktion extends Vertragsbestandteil
|
||||
}
|
||||
|
||||
protected function beforePersitExisting() {
|
||||
$data = (object) array(
|
||||
'datum_bis' => $this->getBis(),
|
||||
'updateamum' => strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'updatevon' => getAuthUID()
|
||||
);
|
||||
$data = array();
|
||||
|
||||
$curbfres = $this->CI->BenutzerfunktionModel->load($this->getBenutzerfunktion_id());
|
||||
$curbf = (getData($curbfres))[0];
|
||||
if( $curbf && ($this->getVon() < $curbf->datum_von) )
|
||||
if(hasData($curbfres))
|
||||
{
|
||||
$data->datum_von = $this->getVon();
|
||||
$curbf = (getData($curbfres))[0];
|
||||
if($this->getVon() < $curbf->datum_von)
|
||||
{
|
||||
$data['datum_von'] = $this->getVon();
|
||||
}
|
||||
if($this->getBis() === null
|
||||
|| ($curbf->datum_bis !== null && ($this->getBis() < $curbf->datum_bis)))
|
||||
{
|
||||
$data['datum_bis'] = $this->getBis();
|
||||
}
|
||||
}
|
||||
|
||||
if( count($data) === 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$data['updateamum'] = strftime('%Y-%m-%d %H:%M:%S');
|
||||
$data['updatevon'] = getAuthUID();
|
||||
|
||||
$ret = $this->CI->BenutzerfunktionModel->update($this->getBenutzerfunktion_id(), $data);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class Rueckstellung_model extends DB_Model
|
||||
$this->addLimit(1);
|
||||
$this->addJoin('tbl_rueckstellung_status', 'status_kurzbz');
|
||||
$this->addSelect('*,
|
||||
array_to_json(bezeichnung_mehrsprachig::varchar[])->>'.$language_index . 'as bezeichnung');
|
||||
array_to_json(bezeichnung_mehrsprachig::varchar[])->>'.$language_index . ' as bezeichnung');
|
||||
$this->addOrder('datum_bis', 'DESC');
|
||||
|
||||
$where['person_id'] = $person_id;
|
||||
|
||||
@@ -117,8 +117,74 @@ class Pruefung_model extends DB_Model
|
||||
return $this->db->get_compiled_select($this->dbTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return stdClass
|
||||
*/
|
||||
public function loadWhereCommitteeExamsFailed()
|
||||
{
|
||||
$this->dbTable = 'lehre.tbl_pruefung p';
|
||||
|
||||
$this->addSelect('p.datum');
|
||||
|
||||
$this->addJoin('lehre.tbl_note n', 'note');
|
||||
|
||||
$this->db->where("n.positiv", false);
|
||||
$this->db->where_in("p.pruefungstyp_kurzbz", ['kommPruef','zusKommPruef']);
|
||||
|
||||
return $this->load();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function withDetailsForStudierendenAntrag()
|
||||
{
|
||||
$this->load->config('studierendenantrag');
|
||||
|
||||
$sprache_index = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1";
|
||||
|
||||
$this->addSelect('pers.vorname');
|
||||
$this->addSelect('pers.nachname');
|
||||
$this->addSelect('pers.person_id');
|
||||
$this->addSelect('s.matrikelnr');
|
||||
$this->addSelect('g.bezeichnung');
|
||||
$this->addSelect('g.studiengang_kz');
|
||||
$this->addSelect('o.bezeichnung_mehrsprachig[(' . $sprache_index . ')] AS orgform', false);
|
||||
$this->addSelect('ps.prestudent_id');
|
||||
$this->addSelect('lv.bezeichnung as lvbezeichnung');
|
||||
$this->addSelect('le.studiensemester_kurzbz');
|
||||
$this->addSelect('a.typ');
|
||||
$this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status');
|
||||
|
||||
$this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
|
||||
$this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
|
||||
$this->addJoin('public.tbl_student s', 'student_uid');
|
||||
$this->addJoin('public.tbl_prestudent ps', 'prestudent_id');
|
||||
$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('bis.tbl_orgform o', '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->db->where("g.aktiv", true);
|
||||
|
||||
$statusgruende = $this->config->item('status_gruende_wiederholer');
|
||||
if (is_array($statusgruende) && !isEmptyArray($statusgruende)) {
|
||||
foreach ($statusgruende as $k => $v) {
|
||||
$statusgruende[$k] = $this->db->escape($v);
|
||||
}
|
||||
$this->db->where('lv.studiengang_kz NOT IN(
|
||||
SELECT ps1.studiengang_kz
|
||||
FROM
|
||||
public.tbl_prestudent ps1
|
||||
JOIN public.tbl_prestudentstatus pss USING (prestudent_id)
|
||||
WHERE pss.statusgrund_id in (' . implode(',', $statusgruende) . ')
|
||||
AND ps.prestudent_id = ps1.prestudent_id)', null, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $prestudent_id student_uid
|
||||
@@ -127,23 +193,23 @@ class Pruefung_model extends DB_Model
|
||||
*/
|
||||
public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id)
|
||||
{
|
||||
$this->withDetailsForStudierendenAntrag();
|
||||
|
||||
$sql = $this->loadWhereThreeExamsFailed();
|
||||
$this->db->where('ps.prestudent_id', $prestudent_id);
|
||||
|
||||
$statusgruende = $this->config->item('status_gruende_wiederholer');
|
||||
if (!is_array($statusgruende))
|
||||
$statusgruende = [];
|
||||
|
||||
return $this->execQuery('select * from ( ' . $sql . ') temp where count >= 3 AND prestudent_id = ?', [
|
||||
Studierendenantrag_model::TYP_WIEDERHOLUNG,
|
||||
$statusgruende,
|
||||
$prestudent_id
|
||||
]);
|
||||
return $this->loadWhereCommitteeExamsFailed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $status
|
||||
* @param \DateTime $maxDate
|
||||
* @param \DateTime $minDate
|
||||
*
|
||||
* @return stdClass
|
||||
*/
|
||||
public function getAllPrestudentsWhereCommitteeExamFailed($status, $maxDate, $minDate)
|
||||
{
|
||||
$this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel');
|
||||
$this->withDetailsForStudierendenAntrag();
|
||||
|
||||
if ($maxDate)
|
||||
$this->db->where("p.datum < ", $maxDate->format('c'));
|
||||
@@ -170,12 +236,6 @@ class Pruefung_model extends DB_Model
|
||||
$this->db->where('campus.get_status_studierendenantrag(a.studierendenantrag_id)', $status);
|
||||
}
|
||||
|
||||
$sql = $this->loadWhereThreeExamsFailed();
|
||||
|
||||
$statusgruende = $this->config->item('status_gruende_wiederholer');
|
||||
if (!is_array($statusgruende))
|
||||
$statusgruende = [];
|
||||
|
||||
return $this->execQuery('select * from ( ' . $sql . ') temp where count >= 3', [Studierendenantrag_model::TYP_WIEDERHOLUNG, $statusgruende]);
|
||||
return $this->loadWhereCommitteeExamsFailed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ $sitesettings = array(
|
||||
'primevue3' => true,
|
||||
'phrases' => array(
|
||||
'global',
|
||||
'ui',
|
||||
'studierendenantrag',
|
||||
'lehre',
|
||||
'person',
|
||||
|
||||
@@ -142,7 +142,7 @@ FROM
|
||||
WHEN oe.organisationseinheittyp_kurzbz = \'Department\' THEN (\'DEP \' || oe.bezeichnung)
|
||||
ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung)
|
||||
END AS "lv_oe_kurzbz",
|
||||
TRUNC(lema.semesterstunden, 1) AS "stunden",
|
||||
TRUNC(lema.semesterstunden, 2) AS "stunden",
|
||||
TRUNC((lema.semesterstunden * lema.stundensatz), 2) AS "betrag",
|
||||
vertrag_id,
|
||||
vertragsstunden AS "vertrag_stunden",
|
||||
@@ -232,7 +232,7 @@ FROM
|
||||
SELECT
|
||||
pa.lehreinheit_id,
|
||||
lv.lehrveranstaltung_id,
|
||||
pa.projektarbeit_id AS "projektarbeit_id",
|
||||
pa.projektarbeit_id::text AS "projektarbeit_id",
|
||||
le.studiensemester_kurzbz,
|
||||
stg.studiengang_kz,
|
||||
upper(stg.typ || stg.kurzbz) AS "stg_typ_kurzbz",
|
||||
@@ -375,9 +375,9 @@ $filterWidgetArray = array(
|
||||
orgform_kurzbz: {visible: false, headerFilter:"input"},
|
||||
person_id: {visible: false, headerFilter:"input"},
|
||||
lv_oe_kurzbz: {visible: false, headerFilter:"input"},
|
||||
stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1},
|
||||
stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:2},
|
||||
headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator,
|
||||
bottomCalc:"sum", bottomCalcParams:{precision:1}
|
||||
bottomCalc:"sum", bottomCalcParams:{precision:2}
|
||||
},
|
||||
betrag: {align:"right", formatter: form_formatNulltoStringNumber,
|
||||
headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator,
|
||||
|
||||
@@ -149,7 +149,7 @@ FROM
|
||||
ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung)
|
||||
END AS "lv_oe_kurzbz",
|
||||
(person.nachname || \' \' || person.vorname) AS "lektor",
|
||||
TRUNC(lema.semesterstunden, 1) AS "stunden",
|
||||
TRUNC(lema.semesterstunden, 2) AS "stunden",
|
||||
lema.stundensatz,
|
||||
TRUNC((lema.semesterstunden * lema.stundensatz), 2) AS "betrag",
|
||||
vertrag_id,
|
||||
@@ -400,9 +400,9 @@ $filterWidgetArray = array(
|
||||
person_id: {visible: false, headerFilter:"input"},
|
||||
lv_oe_kurzbz: {visible: false, headerFilter:"input"},
|
||||
lektor: {headerFilter:"input", widthGrow: 2},
|
||||
stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1},
|
||||
stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:2},
|
||||
headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator,
|
||||
bottomCalc:"sum", bottomCalcParams:{precision:1}},
|
||||
bottomCalc:"sum", bottomCalcParams:{precision:2}},
|
||||
stundensatz: {visible: true, align:"right", formatter: form_formatNulltoStringNumber,
|
||||
headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator},
|
||||
betrag: {align:"right", formatter: form_formatNulltoStringNumber,
|
||||
|
||||
@@ -159,7 +159,7 @@ FROM
|
||||
(
|
||||
SELECT
|
||||
/* lehrauftraege also planned with dummies, therefore personalnummer is needed */
|
||||
ma.personalnummer,
|
||||
ma.personalnummer::text,
|
||||
lema.lehreinheit_id,
|
||||
lv.lehrveranstaltung_id,
|
||||
lv.bezeichnung AS "lv_bezeichnung",
|
||||
@@ -179,7 +179,7 @@ FROM
|
||||
ELSE (oe.organisationseinheittyp_kurzbz || \' \' || oe.bezeichnung)
|
||||
END AS "lv_oe_kurzbz",
|
||||
(person.nachname || \' \' || person.vorname) AS "lektor",
|
||||
TRUNC(lema.semesterstunden, 1) AS "stunden",
|
||||
TRUNC(lema.semesterstunden, 2) AS "stunden",
|
||||
lema.stundensatz,
|
||||
TRUNC((lema.semesterstunden * lema.stundensatz), 2) AS "betrag",
|
||||
vertrag_id,
|
||||
@@ -219,7 +219,7 @@ FROM
|
||||
(SELECT
|
||||
uid
|
||||
FROM
|
||||
public.tbl_benutzer JOIN public.tbl_mitarbeiter ma
|
||||
public.tbl_benutzer JOIN public.tbl_mitarbeiter ma
|
||||
ON tbl_benutzer.uid = ma.mitarbeiter_uid
|
||||
WHERE
|
||||
person_id = tmp_projektbetreuung.person_id
|
||||
@@ -272,7 +272,7 @@ FROM
|
||||
pa.lehreinheit_id,
|
||||
lv.lehrveranstaltung_id,
|
||||
lv.bezeichnung AS "lv_bezeichnung",
|
||||
pa.projektarbeit_id AS "projektarbeit_id",
|
||||
pa.projektarbeit_id::text AS "projektarbeit_id",
|
||||
le.studiensemester_kurzbz,
|
||||
stg.studiengang_kz,
|
||||
upper(stg.typ || stg.kurzbz) AS "stg_typ_kurzbz",
|
||||
@@ -414,7 +414,7 @@ $filterWidgetArray = array(
|
||||
row_index: {visible: false},
|
||||
personalnummer: {visible: false, headerFilter:"input"},
|
||||
auftrag: {
|
||||
headerFilter:"input", widthGrow: 2,
|
||||
headerFilter:"input", widthGrow: 2,
|
||||
bottomCalc:"count", bottomCalcFormatter:function(cell){return "'. ucfirst($this->p->t('global', 'anzahl')). ': " + cell.getValue();}
|
||||
},
|
||||
stg_typ_kurzbz: {headerFilter:"input"},
|
||||
@@ -432,9 +432,9 @@ $filterWidgetArray = array(
|
||||
person_id: {visible: false, headerFilter:"input"},
|
||||
lv_oe_kurzbz: {headerFilter:"input"},
|
||||
lektor: {headerFilter:"input", widthGrow: 2},
|
||||
stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:1},
|
||||
stunden: {align:"right", formatter: form_formatNulltoStringNumber, formatterParams:{precision:2},
|
||||
headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator,
|
||||
bottomCalc:"sum", bottomCalcParams:{precision:1}},
|
||||
bottomCalc:"sum", bottomCalcParams:{precision:2}},
|
||||
stundensatz: {visible: true, align:"right", formatter: form_formatNulltoStringNumber,
|
||||
headerFilter:"input", headerFilterFunc: hf_filterStringnumberWithOperator},
|
||||
betrag: {align:"right", formatter: form_formatNulltoStringNumber,
|
||||
|
||||
@@ -123,6 +123,7 @@
|
||||
generateJSsInclude('vendor/npm-asset/primevue/calendar/calendar.min.js');
|
||||
generateJSsInclude('vendor/npm-asset/primevue/skeleton/skeleton.min.js');
|
||||
generateJSsInclude('vendor/npm-asset/primevue/timeline/timeline.min.js');
|
||||
generateJSsInclude('vendor/npm-asset/primevue/multiselect/multiselect.min.js');
|
||||
generateJSsInclude('vendor/npm-asset/primevue/autocomplete/autocomplete.min.js');
|
||||
generateJSsInclude('vendor/npm-asset/primevue/overlaypanel/overlaypanel.min.js');
|
||||
generateJSsInclude('vendor/npm-asset/primevue/datatable/datatable.min.js');
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
}
|
||||
|
||||
// Tabulator 5 CSS
|
||||
if ($tabulator5 === true) generateCSSsInclude('vendor/olifolkerd/tabulator5/dist/css/tabulator_bootstrap5.min.css');
|
||||
if ($tabulator5 === true) generateCSSsInclude('public/css/Tabulator5.css');
|
||||
|
||||
// Tinymce 4 CSS
|
||||
if ($tinymce4 === true) generateCSSsInclude('public/css/TinyMCE4.css');
|
||||
|
||||
@@ -79,7 +79,12 @@ else if (defined('CIS_ZEITAUFZEICHNUNG_GESPERRT_BIS') && CIS_ZEITAUFZEICHNUNG_GE
|
||||
else
|
||||
$gesperrt_bis = '2015-08-31';
|
||||
|
||||
//echo $gesperrt_bis;
|
||||
//Default-Wert für Max-Intervall in Tagen für Zeitsperre, über Config veränderbar
|
||||
$maxDauerZS = 730;
|
||||
|
||||
if (defined('CIS_ZEITSPERREN_MAX_DAUER') && CIS_ZEITSPERREN_MAX_DAUER != '') {
|
||||
$maxDauerZS = CIS_ZEITSPERREN_MAX_DAUER;
|
||||
}
|
||||
|
||||
//Stundentabelleholen
|
||||
if(! $result_stunde=$db->db_query("SELECT * FROM lehre.tbl_stunde ORDER BY stunde"))
|
||||
@@ -204,66 +209,72 @@ function berechnen()
|
||||
|
||||
function checkdatum()
|
||||
{
|
||||
if(document.getElementById('vondatum').value.length<10)
|
||||
if (document.getElementById('vondatum').value.length < 10)
|
||||
{
|
||||
alert('<?php echo $p->t('zeitsperre/vonDatumIstUngueltigNullenAngeben');?>');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(document.getElementById('bisdatum').value.length<10)
|
||||
if (document.getElementById('bisdatum').value.length < 10)
|
||||
{
|
||||
alert('<?php echo $p->t('zeitsperre/bisDatumIstUngueltigNullenAngeben');?>');
|
||||
return false;
|
||||
}
|
||||
|
||||
var Datum, Tag, Monat,Jahr,vonDatum,bisDatum, diff;
|
||||
var Datum, Tag, Monat, Jahr, vonDatum, bisDatum, vonDatumDate, bisDatumDate, diff, diffTime, diffmax;
|
||||
|
||||
Datum=document.getElementById('vondatum').value;
|
||||
Tag=Datum.substring(0,2);
|
||||
Monat=Datum.substring(3,5);
|
||||
if (parseInt(Monat,10)<1 || parseInt(Monat,10)>12)
|
||||
{
|
||||
alert('<?php echo $p->t('zeitsperre/vonDatumMonat');?>'+ document.getElementById('vondatum').value+ ' <?php echo $p->t('zeitsperre/istNichtRichtig');?>.');
|
||||
Datum = document.getElementById('vondatum').value;
|
||||
Tag = Datum.substring(0, 2);
|
||||
Monat = Datum.substring(3, 5);
|
||||
if (parseInt(Monat, 10) < 1 || parseInt(Monat, 10) > 12)
|
||||
{
|
||||
alert('<?php echo $p->t('zeitsperre/vonDatumMonat');?>' + document.getElementById('vondatum').value + ' <?php echo $p->t('zeitsperre/istNichtRichtig');?>.');
|
||||
document.getElementById('vondatum').focus();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Jahr=Datum.substring(6,10);
|
||||
Jahr = Datum.substring(6, 10);
|
||||
|
||||
vonDatum=Jahr+''+Monat+''+Tag;
|
||||
vonDatum = Jahr + '' + Monat + '' + Tag;
|
||||
vonDatumDate = Jahr + '-' + Monat + '-' + Tag;
|
||||
|
||||
Datum=document.getElementById('bisdatum').value;
|
||||
Tag=Datum.substring(0,2);
|
||||
Monat=Datum.substring(3,5);
|
||||
if (parseInt(Monat,10)<1 || parseInt(Monat,10)>12)
|
||||
{
|
||||
alert('<?php echo $p->t('zeitsperre/bisDatumMonat');?>'+ document.getElementById('bisdatum').value+ ' <?php echo $p->t('zeitsperre/istNichtRichtig');?>.');
|
||||
Datum = document.getElementById('bisdatum').value;
|
||||
Tag = Datum.substring(0, 2);
|
||||
Monat = Datum.substring(3, 5);
|
||||
if (parseInt(Monat, 10) < 1 || parseInt(Monat, 10) > 12) {
|
||||
alert('<?php echo $p->t('zeitsperre/bisDatumMonat');?>' + document.getElementById('bisdatum').value + ' <?php echo $p->t('zeitsperre/istNichtRichtig');?>.');
|
||||
document.getElementById('bisdatum').focus();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Jahr=Datum.substring(6,10);
|
||||
Jahr = Datum.substring(6, 10);
|
||||
bisDatum = Jahr + '' + Monat + '' + Tag;
|
||||
bisDatumDate = Jahr + '-' + Monat + '-' + Tag;
|
||||
|
||||
bisDatum=Jahr+''+Monat+''+Tag;
|
||||
bisDatumDate = new Date(bisDatumDate);
|
||||
vonDatumDate = new Date(vonDatumDate);
|
||||
|
||||
diff=bisDatum-vonDatum;
|
||||
diffTime = bisDatumDate.getTime() - vonDatumDate.getTime();
|
||||
diff = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
|
||||
diffmax = <?php echo $maxDauerZS ;?>
|
||||
|
||||
if (vonDatum>bisDatum)
|
||||
{
|
||||
alert('<?php echo $p->t('zeitsperre/vonDatum');?> '+ document.getElementById('vondatum').value+ ' <?php echo $p->t('zeitsperre/istGroesserAlsBisDatum');?> '+document.getElementById('bisdatum').value);
|
||||
if (vonDatum > bisDatum) {
|
||||
alert('<?php echo $p->t('zeitsperre/vonDatum');?> ' + document.getElementById('vondatum').value + ' <?php echo $p->t('zeitsperre/istGroesserAlsBisDatum');?> ' + document.getElementById('bisdatum').value);
|
||||
document.getElementById('vondatum').focus();
|
||||
return false;
|
||||
}
|
||||
else if (diff>14)
|
||||
{
|
||||
Check = confirm('<?php echo $p->t('zeitaufzeichnung/zeitraumAuffallendHoch');?>');
|
||||
return false;
|
||||
}
|
||||
else if (diff > 14 && diff < diffmax) {
|
||||
Check = confirm('<?php echo $p->t('zeitaufzeichnung/zeitraumAuffallendHoch');?>');
|
||||
document.getElementById('bisdatum').focus();
|
||||
if (Check == false)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Check == false)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
} else if (diff >= diffmax) {
|
||||
alert('<?php echo $p->t('zeitsperre/bisDatumGroesserMax');?> ');
|
||||
document.getElementById('bisdatum').focus();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -445,7 +456,8 @@ if(isset($_GET['type']) && ($_GET['type']=='edit_sperre' || $_GET['type']=='new_
|
||||
$date=explode('.',$_POST['bisdatum']);
|
||||
if (@checkdate($date[1], $date[0], $date[2]))
|
||||
{
|
||||
$bisdatum=$date[2].$date[1].$date[0];
|
||||
$bisdatum=$date[2].$date[1].$date[0];
|
||||
$bisdatum_iso = $date[2].'-'.$date[1].'-'.$date[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -464,6 +476,17 @@ if(isset($_GET['type']) && ($_GET['type']=='edit_sperre' || $_GET['type']=='new_
|
||||
$error_msg .= $p->t('zeitsperre/vonDatumGroesserAlsBisDatum').'! ';
|
||||
}
|
||||
|
||||
//check if bis-Datum zu weit in der Zukunft
|
||||
$bis = new DateTime($bisdatum);
|
||||
$von = new DateTime($vondatum);
|
||||
|
||||
$intervall = $bis->diff($von);
|
||||
if ($intervall->days >= $maxDauerZS)
|
||||
{
|
||||
$error=true;
|
||||
$error_msg = $p->t('zeitsperre/bisDatumGroesserMax');
|
||||
}
|
||||
|
||||
//von-datum pruefen TODO
|
||||
if($vondatum_iso < $gesperrt_bis && in_array($_POST['zeitsperretyp_kurzbz'],$typen_arr))
|
||||
{
|
||||
|
||||
+48
-45
@@ -571,7 +571,7 @@ if (isset($_GET['resend']))
|
||||
|
||||
echo "<div id='coodle_content' >
|
||||
<form action='' method='POST'>
|
||||
|
||||
|
||||
<table class='table-bordered'>
|
||||
<tr><td></td>";
|
||||
// Für Colspan bei Datum
|
||||
@@ -675,7 +675,6 @@ if (isset($_GET['resend']))
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
// Ort-Ressourcen ueberspringen
|
||||
if ($ressource->ort_kurzbz != '')
|
||||
{
|
||||
@@ -761,8 +760,8 @@ if (isset($_GET['resend']))
|
||||
echo ' <td class="'.$class.'" align="center" '.$style.'>
|
||||
<div class="checkbox">
|
||||
<label style="font-size: 1.5em; padding-left: 10px">
|
||||
<input type="checkbox"
|
||||
value=""
|
||||
<input type="checkbox"
|
||||
value=""
|
||||
'.($checked ? 'checked="checked"' : '').'
|
||||
'.($termin->datum == '1900-01-01' ? 'id="disableCheckboxes"' : '').'
|
||||
name="check_'.$ressource->coodle_ressource_id.'_'.$termin->coodle_termin_id.'"
|
||||
@@ -867,8 +866,8 @@ if (isset($_GET['resend']))
|
||||
<span class="glyphicon glyphicon-info-sign"></span>
|
||||
Sie können ihre vorläufigen Terminzusagen in ihr Kalendersystem einbinden.<br>
|
||||
Importieren Sie dazu die .ics-Datei des folgenden Links in ihren Kalender:<br>
|
||||
<a href="'.APP_ROOT.'cis/public/ical_coodle.php/cipher_encryption/'.encryptData($uid,LVPLAN_CYPHER_KEY).'" target="_blank">
|
||||
'.APP_ROOT.'cis/public/ical_coodle.php/cipher_encryption/'.encryptData($uid,LVPLAN_CYPHER_KEY).'
|
||||
<a href="'.APP_ROOT.'cis/public/ical_coodle.php/cipher_encryption/'.encryptData($uid, LVPLAN_CYPHER_KEY).'" target="_blank">
|
||||
'.APP_ROOT.'cis/public/ical_coodle.php/cipher_encryption/'.encryptData($uid, LVPLAN_CYPHER_KEY).'
|
||||
</a>
|
||||
<br><br>
|
||||
Die Datei enthält ihre Terminzusagen aus <b>allen laufenden Umfragen</b> .
|
||||
@@ -999,7 +998,7 @@ function sendEmail($coodle_id)
|
||||
else
|
||||
$partstat = 'TENTATIVE';
|
||||
|
||||
$teilnehmer .= 'ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT='.$partstat.';CN='.$name."\n :MAILTO:".$mail."\n";
|
||||
$teilnehmer .= $coodle->foldContentLine('ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT='.$partstat.';CN='.$name.":MAILTO:".$mail) . "\r\n";
|
||||
}
|
||||
}
|
||||
$date = new DateTime($coodle_help->datum.' '.$coodle_help->uhrzeit);
|
||||
@@ -1015,44 +1014,48 @@ function sendEmail($coodle_id)
|
||||
$benutzer = new benutzer();
|
||||
$benutzer->load($coodle->ersteller_uid);
|
||||
$erstellername = trim($benutzer->titelpre.' '.$benutzer->vorname.' '.$benutzer->nachname.' '.$benutzer->titelpost);
|
||||
|
||||
$beschreibung = "DESCRIPTION:" . strip_tags(html_entity_decode($coodle->beschreibung, ENT_QUOTES, 'UTF-8'), '<br>');
|
||||
$terminbeschreibung= $coodle->foldContentLine($beschreibung);
|
||||
|
||||
// Ical File erstellen
|
||||
$ical = "BEGIN:VCALENDAR
|
||||
PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN
|
||||
VERSION:2.0
|
||||
METHOD:PUBLISH
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Europe/Vienna
|
||||
BEGIN:DAYLIGHT
|
||||
TZOFFSETFROM:+0100
|
||||
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
|
||||
DTSTART:19810329T020000
|
||||
TZNAME:GMT+02:00
|
||||
TZOFFSETTO:+0200
|
||||
END:DAYLIGHT
|
||||
BEGIN:STANDARD
|
||||
TZOFFSETFROM:+0200
|
||||
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
|
||||
DTSTART:19961027T030000
|
||||
TZNAME:GMT+01:00
|
||||
TZOFFSETTO:+0100
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
ORGANIZER:MAILTO:".$erstellername." <".$coodle->ersteller_uid."@".DOMAIN."
|
||||
".$teilnehmer."
|
||||
DTSTART;TZID=Europe/Vienna:".$dtstart."
|
||||
DTEND;TZID=Europe/Vienna:".$dtend."
|
||||
LOCATION:".$ort."
|
||||
TRANSP:OPAQUE
|
||||
SEQUENCE:0
|
||||
UID:FHCompleteCoodle".$coodle_id."
|
||||
DTSTAMP;TZID=Europe/Vienna:".$dtstamp."
|
||||
DESCRIPTION:".strip_tags(html_entity_decode($coodle->beschreibung, ENT_QUOTES, 'UTF-8'))."
|
||||
SUMMARY:".strip_tags($coodle->titel)."
|
||||
PRIORITY:5
|
||||
CLASS:PUBLIC
|
||||
END:VEVENT
|
||||
END:VCALENDAR";
|
||||
$ical = "BEGIN:VCALENDAR\r\n"
|
||||
."PRODID:-//Microsoft Corporation//Outlook 11.0 MIMEDIR//EN\r\n"
|
||||
."VERSION:2.0\r\n"
|
||||
."METHOD:PUBLISH\r\n"
|
||||
."BEGIN:VTIMEZONE\r\n"
|
||||
."TZID:Europe/Vienna\r\n"
|
||||
."BEGIN:DAYLIGHT\r\n"
|
||||
."TZOFFSETFROM:+0100\r\n"
|
||||
."RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\n"
|
||||
."DTSTART:19810329T020000\r\n"
|
||||
."TZNAME:GMT+02:00\r\n"
|
||||
."TZOFFSETTO:+0200\r\n"
|
||||
."END:DAYLIGHT\r\n"
|
||||
."BEGIN:STANDARD\r\n"
|
||||
."TZOFFSETFROM:+0200\r\n"
|
||||
."RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\n"
|
||||
."DTSTART:19961027T030000\r\n"
|
||||
."TZNAME:GMT+01:00\r\n"
|
||||
."TZOFFSETTO:+0100\r\n"
|
||||
."END:STANDARD\r\n"
|
||||
."END:VTIMEZONE\r\n"
|
||||
."BEGIN:VEVENT\r\n"
|
||||
.$coodle->foldContentLine("ORGANIZER:MAILTO:".$erstellername." <".$coodle->ersteller_uid."@".DOMAIN)."\r\n"
|
||||
.rtrim($teilnehmer)."\r\n"
|
||||
."DTSTART;TZID=Europe/Vienna:".$dtstart."\r\n"
|
||||
."DTEND;TZID=Europe/Vienna:".$dtend."\r\n"
|
||||
."LOCATION:".$ort."\r\n"
|
||||
."TRANSP:OPAQUE\r\n"
|
||||
."SEQUENCE:0\r\n"
|
||||
."UID:FHCompleteCoodle".$coodle_id."\r\n"
|
||||
."DTSTAMP;TZID=Europe/Vienna:".$dtstamp."\r\n"
|
||||
.$terminbeschreibung."\r\n"
|
||||
."SUMMARY:".strip_tags($coodle->titel)."\r\n"
|
||||
."PRIORITY:5\r\n"
|
||||
."CLASS:PUBLIC\r\n"
|
||||
."END:VEVENT\r\n"
|
||||
."END:VCALENDAR\r\n";
|
||||
|
||||
if (count($coodle_ressource->result) > 0)
|
||||
{
|
||||
@@ -1173,4 +1176,4 @@ function RaumBelegt($ort_kurzbz, $datum, $stunden)
|
||||
return false;
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
||||
|
||||
+6
-28
@@ -26,28 +26,6 @@
|
||||
"wiki": "https://wiki.fhcomplete.info/doku.php"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "package",
|
||||
"package": {
|
||||
"name": "vuepic/vue-datepicker-js",
|
||||
"version": "4.0.0",
|
||||
"dist": {
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@4.0.0/dist/vue-datepicker.iife.js",
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "package",
|
||||
"package": {
|
||||
"name": "vuepic/vue-datepicker-css",
|
||||
"version": "4.0.0",
|
||||
"dist": {
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@4.0.0/dist/main.css",
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "package",
|
||||
"package": {
|
||||
@@ -374,9 +352,9 @@
|
||||
"type": "package",
|
||||
"package": {
|
||||
"name": "vuejs/vuedatepicker_js",
|
||||
"version": "5.4.0",
|
||||
"version": "7.2.0",
|
||||
"dist": {
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@5.4.0/dist/vue-datepicker.iife.js",
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@7.2.0/dist/vue-datepicker.iife.js",
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
@@ -385,9 +363,9 @@
|
||||
"type": "package",
|
||||
"package": {
|
||||
"name": "vuejs/vuedatepicker_css",
|
||||
"version": "5.4.0",
|
||||
"version": "7.2.0",
|
||||
"dist": {
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@5.4.0/dist/main.css",
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@7.2.0/dist/main.css",
|
||||
"type": "file"
|
||||
}
|
||||
}
|
||||
@@ -465,8 +443,8 @@
|
||||
|
||||
"vuejs/vuejs3": "3.2.33",
|
||||
"vuejs/vuerouter4": "4.1.3",
|
||||
"vuejs/vuedatepicker_js": "5.4.0",
|
||||
"vuejs/vuedatepicker_css": "5.4.0"
|
||||
"vuejs/vuedatepicker_js": "7.2.0",
|
||||
"vuejs/vuedatepicker_css": "7.2.0"
|
||||
},
|
||||
"config": {
|
||||
"bin-dir": "vendor/bin"
|
||||
|
||||
Generated
+6
-6
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "67e5823946d817dac0c89156a2f0fcf0",
|
||||
"content-hash": "3ac7bea74aadb85ee412b61e393f8188",
|
||||
"packages": [
|
||||
{
|
||||
"name": "afarkas/html5shiv",
|
||||
@@ -1850,19 +1850,19 @@
|
||||
},
|
||||
{
|
||||
"name": "vuejs/vuedatepicker_css",
|
||||
"version": "5.4.0",
|
||||
"version": "7.2.0",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@5.4.0/dist/main.css"
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@7.2.0/dist/main.css"
|
||||
},
|
||||
"type": "library"
|
||||
},
|
||||
{
|
||||
"name": "vuejs/vuedatepicker_js",
|
||||
"version": "5.4.0",
|
||||
"version": "7.2.0",
|
||||
"dist": {
|
||||
"type": "file",
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@5.4.0/dist/vue-datepicker.iife.js"
|
||||
"url": "https://unpkg.com/@vuepic/vue-datepicker@7.2.0/dist/vue-datepicker.iife.js"
|
||||
},
|
||||
"type": "library"
|
||||
},
|
||||
@@ -4739,5 +4739,5 @@
|
||||
"php": ">=5.6.40"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
||||
|
||||
@@ -294,5 +294,4 @@ define ('DEFAULT_ALLIN_DIENSTVERTRAG',[111]);
|
||||
//Echter Dienstvertrag
|
||||
define ('DEFAULT_ECHTER_DIENSTVERTRAG',[103,111]);
|
||||
|
||||
|
||||
?>
|
||||
|
||||
@@ -47,6 +47,9 @@ define('CIS_PROFIL_STUDIENINFORMATION_ANZEIGEN',true);
|
||||
// Zeitaufzeichnung gesperrt_bis Datum YYYY-MM-DD
|
||||
define('CIS_ZEITAUFZEICHNUNG_GESPERRT_BIS','');
|
||||
|
||||
// maximale Dauer einer Zeitsperre in Tagen
|
||||
define('CIS_ZEITSPERREN_MAX_DAUER', 730);
|
||||
|
||||
// Anzeige des Links zur Noteneingabe in der LVA Uebersicht
|
||||
define('CIS_LVALISTE_NOTENEINGABE_ANZEIGEN',true);
|
||||
|
||||
|
||||
+372
-350
File diff suppressed because it is too large
Load Diff
@@ -212,7 +212,7 @@
|
||||
<!ENTITY menu-dokumente-diplsupplement.accesskey "S">
|
||||
|
||||
<!ENTITY menu-dokumente-antrag.key "N">
|
||||
<!ENTITY menu-dokumente-antrag.label "Antrag">
|
||||
<!ENTITY menu-dokumente-antrag.label "Verwaltung des Studierendenstatus">
|
||||
<!ENTITY menu-dokumente-antrag.accesskey "N">
|
||||
|
||||
<!ENTITY menu-dokumente-antrag-abmeldung.key "A">
|
||||
|
||||
@@ -26,6 +26,7 @@ $this->phrasen['zeitsperre/vonDatumMonat']='Von-Datum Monat';
|
||||
$this->phrasen['zeitsperre/bisDatumMonat']='Bis-Datum Monat';
|
||||
$this->phrasen['zeitsperre/istGroesserAlsBisDatum']='ist größer als das Bis-Datum';
|
||||
$this->phrasen['zeitsperre/vonDatum']='Von-Datum';
|
||||
$this->phrasen['zeitsperre/bisDatumGroesserMax']='BisDatum liegt zu weit in der Zukunft, nicht zulässig!';
|
||||
|
||||
$this->phrasen['zeitsperre/resturlaubstage']='Resturlaubstage';
|
||||
$this->phrasen['zeitsperre/aktuellerStand']='aktueller Stand';
|
||||
|
||||
@@ -26,6 +26,7 @@ $this->phrasen['zeitsperre/vonDatumMonat']='From-date month';
|
||||
$this->phrasen['zeitsperre/bisDatumMonat']='To-date month';
|
||||
$this->phrasen['zeitsperre/istGroesserAlsBisDatum']='is later than To-date';
|
||||
$this->phrasen['zeitsperre/vonDatum']='From-date';
|
||||
$this->phrasen['zeitsperre/bisDatumGroesserMax']='TO-Date value is too far in the future, action not permitted';
|
||||
|
||||
$this->phrasen['zeitsperre/resturlaubstage']='Carry-over days';
|
||||
$this->phrasen['zeitsperre/aktuellerStand']='Available vacation';
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
@import '../../vendor/olifolkerd/tabulator5/dist/css/tabulator_bootstrap5.min.css';
|
||||
|
||||
/* Apply borders and background to Cell instead of the Row
|
||||
* otherwise frozen columns won't look good (columns behind
|
||||
* will be partial visible)
|
||||
*/
|
||||
.tabulator-row {
|
||||
border-bottom: none;
|
||||
}
|
||||
.tabulator-row .tabulator-frozen,
|
||||
.tabulator-row .tabulator-cell {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
.tabulator-row.tabulator-row-even {
|
||||
background-color: transparent;
|
||||
}
|
||||
.tabulator-headers .tabulator-frozen,
|
||||
.tabulator-row.tabulator-row-odd .tabulator-frozen,
|
||||
.tabulator-row.tabulator-row-odd .tabulator-cell {
|
||||
background-color: #fff;
|
||||
}
|
||||
.tabulator-row.tabulator-row-even .tabulator-frozen,
|
||||
.tabulator-row.tabulator-row-even .tabulator-cell {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.tabulator-row.tabulator-selectable:hover .tabulator-frozen,
|
||||
.tabulator-row.tabulator-selectable:hover .tabulator-cell {
|
||||
background-color: #ececec;
|
||||
}
|
||||
.tabulator-row.tabulator-selected .tabulator-frozen,
|
||||
.tabulator-row.tabulator-selected .tabulator-cell {
|
||||
background-color: #9abcea;
|
||||
}
|
||||
.tabulator-row.tabulator-selected:hover .tabulator-frozen,
|
||||
.tabulator-row.tabulator-selected:hover .tabulator-cell {
|
||||
background-color: #769bcc;
|
||||
}
|
||||
@@ -59,8 +59,41 @@ h6, .h6 {
|
||||
|
||||
.fhc-container {
|
||||
padding: 0 15px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.tabulator {
|
||||
font-size: var(--bs-body-font-size);
|
||||
}
|
||||
|
||||
.fhc-container .tabulator {
|
||||
border-left: 1px solid #dee2e6;
|
||||
}
|
||||
.fhc-container .tabulator .tabulator-row {
|
||||
border-bottom: none;
|
||||
}
|
||||
.fhc-container .tabulator .tabulator-row .tabulator-frozen,
|
||||
.fhc-container .tabulator .tabulator-row .tabulator-cell {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-row-even {
|
||||
background-color: transparent;
|
||||
}
|
||||
.fhc-container .tabulator .tabulator-headers .tabulator-frozen,
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-row-odd .tabulator-frozen,
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-row-odd .tabulator-cell {
|
||||
background-color: #fff;
|
||||
}
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-row-even .tabulator-frozen,
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-row-even .tabulator-cell {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-selectable:hover .tabulator-frozen,
|
||||
.fhc-container .tabulator .tabulator-row.tabulator-selectable:hover .tabulator-cell {
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
.fhc-container .tabulator .tabulator-col,
|
||||
.fhc-container .tabulator .tabulator-cell {
|
||||
border-right: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
const DEBUG = false;
|
||||
|
||||
// Default veil timeout (milliseconds)
|
||||
const VEIL_TIMEOUT = 1000;
|
||||
const VEIL_TIMEOUT = 5000;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// Constants
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
const CORE_REST_CLIENT_DEBUG = false;
|
||||
|
||||
// Default timeout (milliseconds)
|
||||
const CORE_REST_CLIENT_TIMEOUT = 1000;
|
||||
const CORE_REST_CLIENT_TIMEOUT = 5000;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// Constants
|
||||
|
||||
@@ -347,6 +347,7 @@ export default {
|
||||
@action:objectionDeny="actionoObjectionDeny"
|
||||
@action:objectionApprove="actionObjectionApprove"
|
||||
@action:cancel="actionCancel"
|
||||
@reload="reload"
|
||||
>
|
||||
</leitung-table>
|
||||
|
||||
|
||||
@@ -44,7 +44,10 @@ export default {
|
||||
this.table.replaceData(this.ajaxUrl + (stg || ''));
|
||||
},
|
||||
download() {
|
||||
this.table.download("csv", "data.csv");
|
||||
this.table.download("csv", "data.csv", {
|
||||
delimiter: ';',
|
||||
bom: true
|
||||
});
|
||||
},
|
||||
getHistory() {
|
||||
if (this.lastHistoryClickedId === null)
|
||||
@@ -86,8 +89,8 @@ export default {
|
||||
this.table = new Tabulator(this.$refs.table, {
|
||||
placeholder:"Keine zu bearbeitenden Datensätze",
|
||||
movableColumns: true,
|
||||
height: '50vh',
|
||||
layout: "fitDataStretch", // TODO(chris): wont work when changed
|
||||
maxHeight: '50vh',
|
||||
layout: "fitDataFill",
|
||||
ajaxURL: this.ajaxUrl,
|
||||
persistence: { // NOTE(chris): do not store column titles
|
||||
sort: true, //persist column sorting
|
||||
@@ -214,6 +217,10 @@ export default {
|
||||
}
|
||||
}, {
|
||||
field: 'actions',
|
||||
frozen: true,
|
||||
title: this.p.t('ui', 'aktion'),
|
||||
headerFilter: false,
|
||||
headerSort: false,
|
||||
formatter: (cell, formatterParams, onRendered) => {
|
||||
let container = document.createElement('div'),
|
||||
data = cell.getData();
|
||||
@@ -324,11 +331,6 @@ export default {
|
||||
container.append(button);
|
||||
}
|
||||
|
||||
// TODO(chris): not yet perfect
|
||||
onRendered(() => {
|
||||
cell.getColumn().setWidth(true);
|
||||
});
|
||||
|
||||
return container;
|
||||
}
|
||||
}]
|
||||
@@ -338,7 +340,7 @@ export default {
|
||||
let columnData = [];
|
||||
for (let col of columns) {
|
||||
let def = col.getDefinition();
|
||||
if (def.title) {
|
||||
if (def.title && !def.frozen) {
|
||||
columnData.push({
|
||||
title: def.title,
|
||||
visible: col.isVisible(),
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
import {CoreFilterAPIs} from './API.js';
|
||||
import {CoreRESTClient} from '../../RESTClient.js';
|
||||
import {CoreFetchCmpt} from '../../components/Fetch.js';
|
||||
import FilterConfig from './Filter/Config.js';
|
||||
import FilterColumns from './Filter/Columns.js';
|
||||
import TableDownload from './Table/Download.js';
|
||||
|
||||
//
|
||||
const FILTER_COMPONENT_NEW_FILTER = 'Filter Component New Filter';
|
||||
@@ -29,11 +32,18 @@ var _uuid = 0;
|
||||
*
|
||||
*/
|
||||
export const CoreFilterCmpt = {
|
||||
emits: ['nwNewEntry'],
|
||||
components: {
|
||||
CoreFetchCmpt
|
||||
CoreFetchCmpt,
|
||||
FilterConfig,
|
||||
FilterColumns,
|
||||
TableDownload
|
||||
},
|
||||
emits: [
|
||||
'nwNewEntry',
|
||||
'click:new'
|
||||
],
|
||||
props: {
|
||||
onNwNewEntry: Function, // NOTE(chris): Hack to get the nwNewEntry listener into $props
|
||||
title: String,
|
||||
sideMenu: {
|
||||
type: Boolean,
|
||||
@@ -45,7 +55,16 @@ export const CoreFilterCmpt = {
|
||||
},
|
||||
tabulatorOptions: Object,
|
||||
tabulatorEvents: Array,
|
||||
tableOnly: Boolean
|
||||
tableOnly: Boolean,
|
||||
reload: Boolean,
|
||||
download: {
|
||||
type: [Boolean, String, Function, Array, Object],
|
||||
default: false
|
||||
},
|
||||
newBtnShow: Boolean,
|
||||
newBtnClass: [String, Array, Object],
|
||||
newBtnDisabled: Boolean,
|
||||
newBtnLabel: String
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
@@ -60,6 +79,7 @@ export const CoreFilterCmpt = {
|
||||
filterFields: null,
|
||||
|
||||
availableFilters: null,
|
||||
selectedFilter: null,
|
||||
|
||||
// FetchCmpt binded properties
|
||||
fetchCmptRefresh: false,
|
||||
@@ -68,7 +88,9 @@ export const CoreFilterCmpt = {
|
||||
fetchCmptDataFetched: null,
|
||||
|
||||
tabulator: null,
|
||||
tableBuilt: false
|
||||
tableBuilt: false,
|
||||
tabulatorHasSelector: false,
|
||||
selectedData: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -115,6 +137,8 @@ export const CoreFilterCmpt = {
|
||||
{
|
||||
// If the column has to be displayed or not
|
||||
col.visible = selectedFields.indexOf(col.field) >= 0;
|
||||
if (col.formatter == 'rowSelection')
|
||||
col.visible = true;
|
||||
|
||||
if (col.hasOwnProperty('resizable'))
|
||||
col.resizable = col.visible;
|
||||
@@ -123,6 +147,14 @@ export const CoreFilterCmpt = {
|
||||
|
||||
return columns;
|
||||
},
|
||||
fieldIdsForVisibilty() {
|
||||
if (!this.tableBuilt)
|
||||
return [];
|
||||
return this.tabulator.getColumns().filter(col => {
|
||||
let def = col.getDefinition();
|
||||
return !def.frozen && def.title;
|
||||
}).map(col => col.getField());
|
||||
},
|
||||
fieldNames() {
|
||||
if (!this.tableBuilt)
|
||||
return {};
|
||||
@@ -135,21 +167,24 @@ export const CoreFilterCmpt = {
|
||||
if (!this.uuid)
|
||||
return '';
|
||||
return '-' + this.uuid;
|
||||
},
|
||||
columnsForFilter() {
|
||||
if (!this.filteredColumns || !this.datasetMetadata)
|
||||
return [];
|
||||
const filterTitles = this.filteredColumns.reduce((a,c) => {
|
||||
a[c.field] = c.title;
|
||||
return a;
|
||||
}, {});
|
||||
return this.datasetMetadata.map(el => ({...el, ...{title: filterTitles[el.name]}}));
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
if (!this.tableOnly == !this.filterType)
|
||||
alert('You can not have a filter-type in table-only mode!');
|
||||
},
|
||||
created() {
|
||||
this.uuid = _uuid++;
|
||||
if (!this.tableOnly)
|
||||
this.getFilter(); // get the filter data
|
||||
},
|
||||
mounted() {
|
||||
this.initTabulator();
|
||||
},
|
||||
methods: {
|
||||
reloadTable() {
|
||||
if (this.tableOnly)
|
||||
this.tabulator.setData();
|
||||
else
|
||||
this.getFilter();
|
||||
},
|
||||
initTabulator() {
|
||||
// Define a default tabulator options in case it was not provided
|
||||
let tabulatorOptions = {...{
|
||||
@@ -164,6 +199,9 @@ export const CoreFilterCmpt = {
|
||||
tabulatorOptions.columns = this.filteredColumns;
|
||||
}
|
||||
|
||||
if (tabulatorOptions.columns && tabulatorOptions.columns.filter(el => el.formatter == 'rowSelection').length)
|
||||
this.tabulatorHasSelector = true;
|
||||
|
||||
// Start the tabulator with the build options
|
||||
this.tabulator = new Tabulator(
|
||||
this.$refs.table,
|
||||
@@ -177,6 +215,9 @@ export const CoreFilterCmpt = {
|
||||
this.tabulator.on(evt.event, evt.handler);
|
||||
}
|
||||
this.tabulator.on('tableBuilt', () => this.tableBuilt = true);
|
||||
this.tabulator.on("rowSelectionChanged", data => {
|
||||
this.selectedData = data;
|
||||
});
|
||||
if (this.tableOnly) {
|
||||
this.tabulator.on('tableBuilt', () => {
|
||||
const cols = this.tabulator.getColumns();
|
||||
@@ -194,15 +235,24 @@ export const CoreFilterCmpt = {
|
||||
}
|
||||
},
|
||||
_updateTabulator() {
|
||||
this.tabulator.setData(this.filteredData);
|
||||
this.tabulatorHasSelector = this.filteredColumns.filter(el => el.formatter == 'rowSelection').length;
|
||||
this.tabulator.setColumns(this.filteredColumns);
|
||||
this.tabulator.setData(this.filteredData);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
getFilter: function() {
|
||||
//
|
||||
this.startFetchCmpt(CoreFilterAPIs.getFilter, null, this.render);
|
||||
if (this.selectedFilter === null)
|
||||
this.startFetchCmpt(CoreFilterAPIs.getFilter, null, this.render);
|
||||
else
|
||||
this.startFetchCmpt(
|
||||
CoreFilterAPIs.getFilterById,
|
||||
{
|
||||
filterId: this.selectedFilter
|
||||
},
|
||||
this.render
|
||||
);
|
||||
},
|
||||
/**
|
||||
*
|
||||
@@ -230,7 +280,7 @@ export const CoreFilterCmpt = {
|
||||
filter.type = data.datasetMetadata[i].type;
|
||||
|
||||
this.filterFields.push(filter);
|
||||
break;
|
||||
//break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,6 +316,7 @@ export const CoreFilterCmpt = {
|
||||
if (link == null) link = '#';
|
||||
|
||||
filtersArray[filtersArray.length] = {
|
||||
id: filters[filtersCount].filter_id,
|
||||
link: link + filters[filtersCount].filter_id,
|
||||
description: filters[filtersCount].desc,
|
||||
sort: filtersCount,
|
||||
@@ -280,6 +331,7 @@ export const CoreFilterCmpt = {
|
||||
if (link == null) link = '#';
|
||||
|
||||
filtersArray[filtersArray.length] = {
|
||||
id: personalFilters[filtersCount].filter_id,
|
||||
link: link + personalFilters[filtersCount].filter_id,
|
||||
description: personalFilters[filtersCount].desc,
|
||||
subscriptDescription: personalFilters[filtersCount].subscriptDescription,
|
||||
@@ -318,6 +370,7 @@ export const CoreFilterCmpt = {
|
||||
if (link == null) link = '#';
|
||||
|
||||
filtersArray[filtersArray.length] = {
|
||||
id: filters[filtersCount].filter_id,
|
||||
option: filters[filtersCount].filter_id,
|
||||
description: filters[filtersCount].desc
|
||||
};
|
||||
@@ -330,6 +383,7 @@ export const CoreFilterCmpt = {
|
||||
if (link == null) link = '#';
|
||||
|
||||
filtersArray[filtersArray.length] = {
|
||||
id: personalFilters[filtersCount].filter_id,
|
||||
option: personalFilters[filtersCount].filter_id,
|
||||
description: personalFilters[filtersCount].desc
|
||||
};
|
||||
@@ -366,12 +420,13 @@ export const CoreFilterCmpt = {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
handlerSaveCustomFilter: function(event) {
|
||||
handlerSaveCustomFilter: function(customFilterName) {
|
||||
this.selectedFilter = null;
|
||||
//
|
||||
this.startFetchCmpt(
|
||||
CoreFilterAPIs.saveCustomFilter,
|
||||
{
|
||||
customFilterName: this.$refscustomFilterName.value
|
||||
customFilterName
|
||||
},
|
||||
this.getFilter
|
||||
);
|
||||
@@ -380,159 +435,22 @@ export const CoreFilterCmpt = {
|
||||
*
|
||||
*/
|
||||
handlerRemoveCustomFilter: function(event) {
|
||||
filterId = event.currentTarget.getAttribute("href").substring(1);
|
||||
if (filterId === this.selectedFilter)
|
||||
this.selectedFilter = null;
|
||||
//
|
||||
this.startFetchCmpt(
|
||||
CoreFilterAPIs.removeCustomFilter,
|
||||
{
|
||||
filterId: event.currentTarget.getAttribute("href").substring(1)
|
||||
filterId: filterId
|
||||
},
|
||||
this.getFilter
|
||||
);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
handlerApplyFilterFields: function(event) {
|
||||
let filterFields = [];
|
||||
let filterFieldDivRows = document.getElementById('filterFields').getElementsByClassName('row');
|
||||
|
||||
for (let i = 0; i< filterFieldDivRows.length; i++)
|
||||
{
|
||||
let filterField = {};
|
||||
|
||||
for (let j = 0; j< filterFieldDivRows[i].children.length; j++)
|
||||
{
|
||||
let filterColumn = filterFieldDivRows[i].children[j];
|
||||
let filterColumnElement = filterColumn.children[0];
|
||||
|
||||
// If the first column then search for the fields dropdown
|
||||
if (j == 0) filterColumnElement = filterColumnElement.querySelector('select[name=fieldName]');
|
||||
|
||||
// If the filter name is _not_ null and it is _not_ a new filter
|
||||
if (filterColumnElement.name != null && filterColumnElement.name != FILTER_COMPONENT_NEW_FILTER)
|
||||
{
|
||||
// Condition
|
||||
if (filterColumnElement.name == 'condition' && filterColumnElement.value == "")
|
||||
{
|
||||
alert("Please fill all the filter options");
|
||||
return;
|
||||
}
|
||||
|
||||
// Name
|
||||
if (filterColumnElement.name == 'fieldName')
|
||||
{
|
||||
filterField.name = filterColumnElement.value;
|
||||
}
|
||||
// Operation
|
||||
if (filterColumnElement.name == 'operation')
|
||||
{
|
||||
filterField.operation = filterColumnElement.value;
|
||||
}
|
||||
// Condition
|
||||
if (filterColumnElement.name == 'condition')
|
||||
{
|
||||
filterField.condition = filterColumnElement.value;
|
||||
}
|
||||
// Option
|
||||
if (filterColumnElement.name == 'option')
|
||||
{
|
||||
filterField.option = filterColumnElement.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.entries(filterField).length > 0) filterFields.push(filterField);
|
||||
}
|
||||
|
||||
//
|
||||
this.startFetchCmpt(
|
||||
CoreFilterAPIs.applyFilterFields,
|
||||
{
|
||||
filterFields: filterFields
|
||||
},
|
||||
this.getFilter
|
||||
);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
handlerChangeFilterField: function(oldValue, newValue) {
|
||||
|
||||
// If an old filter has been changed
|
||||
if (oldValue != "")
|
||||
{
|
||||
for (let i = 0; i < this.filterFields.length; i++)
|
||||
{
|
||||
if (this.filterFields[i].name == oldValue)
|
||||
{
|
||||
this.filterFields.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Then add the new filter
|
||||
for (let i = 0; i < this.datasetMetadata.length; i++)
|
||||
{
|
||||
if (this.datasetMetadata[i].name == newValue)
|
||||
{
|
||||
let filter = {
|
||||
name: this.datasetMetadata[i].name,
|
||||
type: this.datasetMetadata[i].type
|
||||
};
|
||||
|
||||
this.filterFields.push(filter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
handlerAddNewFilter: function(event) {
|
||||
// Adds a new empty filter
|
||||
this.filterFields.push({
|
||||
name: FILTER_COMPONENT_NEW_FILTER,
|
||||
type: FILTER_COMPONENT_NEW_FILTER_TYPE
|
||||
});
|
||||
},
|
||||
/*
|
||||
*
|
||||
*/
|
||||
handlerToggleSelectedField(field) {
|
||||
|
||||
// If it is a selected field
|
||||
if (this.selectedFields.indexOf(field) != -1)
|
||||
{
|
||||
// then hide it
|
||||
this.tabulator.hideColumn(field);
|
||||
// and remove it from the this.selectedFields property
|
||||
this.selectedFields.splice(this.selectedFields.indexOf(field), 1);
|
||||
}
|
||||
else // otherwise
|
||||
{
|
||||
// show it
|
||||
this.tabulator.showColumn(field);
|
||||
// and add it to the this.selectedFields property
|
||||
this.selectedFields.push(field);
|
||||
}
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
handlerRemoveFilterField: function(event) {
|
||||
//
|
||||
this.startFetchCmpt(
|
||||
CoreFilterAPIs.removeFilterField,
|
||||
{
|
||||
filterField: event.currentTarget.getAttribute('field-to-remove')
|
||||
},
|
||||
this.getFilter
|
||||
);
|
||||
},
|
||||
/**
|
||||
*
|
||||
*/
|
||||
handlerGetFilterById: function(event) {
|
||||
|
||||
let filterId = null;
|
||||
@@ -550,16 +468,37 @@ export const CoreFilterCmpt = {
|
||||
filterId = attr.substring(1);
|
||||
}
|
||||
|
||||
// Ajax call
|
||||
this.switchFilter(filterId);
|
||||
},
|
||||
switchFilter(filterId) {
|
||||
this.selectedFilter = filterId;
|
||||
this.getFilter();
|
||||
},
|
||||
applyFilterConfig(filterFields) {
|
||||
this.selectedFilter = null;
|
||||
this.startFetchCmpt(
|
||||
CoreFilterAPIs.getFilterById,
|
||||
CoreFilterAPIs.applyFilterFields,
|
||||
{
|
||||
filterId: filterId
|
||||
filterFields
|
||||
},
|
||||
this.render
|
||||
this.getFilter
|
||||
);
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
if (!this.tableOnly == !this.filterType)
|
||||
alert('You can not have a filter-type in table-only mode!');
|
||||
},
|
||||
created() {
|
||||
if (this.sideMenu && (!this.$props.onNwNewEntry || !(this.$props.onNwNewEntry instanceof Function)))
|
||||
alert('"nwNewEntry" listener is mandatory when sideMenu is true');
|
||||
this.uuid = _uuid++;
|
||||
if (!this.tableOnly)
|
||||
this.getFilter(); // get the filter data
|
||||
},
|
||||
mounted() {
|
||||
this.initTabulator();
|
||||
},
|
||||
template: `
|
||||
<!-- Load filter data -->
|
||||
<core-fetch-cmpt
|
||||
@@ -580,178 +519,53 @@ export const CoreFilterCmpt = {
|
||||
|
||||
<div :id="'filterCollapsables' + idExtra">
|
||||
|
||||
<div class="filter-header-title">
|
||||
<span v-if="!tableOnly" class="filter-header-title-span-filter">[ {{ filterName }} ]</span>
|
||||
<span v-if="!tableOnly" data-bs-toggle="collapse" :data-bs-target="'#collapseFilters' + idExtra" class="filter-header-title-span-icon fa-solid fa-filter fa-xl"></span>
|
||||
<span data-bs-toggle="collapse" :data-bs-target="'#collapseColumns' + idExtra" class="filter-header-title-span-icon fa-solid fa-table-columns fa-xl"></span>
|
||||
</div>
|
||||
|
||||
<div :id="'collapseColumns' + idExtra" class="card-body collapse" :data-bs-parent="'#filterCollapsables' + idExtra">
|
||||
<div class="card">
|
||||
<!-- Filter fields options -->
|
||||
<div class="row card-body filter-options-div">
|
||||
<div class="filter-fields-area">
|
||||
<template v-for="fieldToDisplay in fields">
|
||||
<div
|
||||
class="filter-fields-field"
|
||||
v-bind:class="selectedFields.indexOf(fieldToDisplay) != -1 ? 'text-light bg-dark' : '' "
|
||||
@click="handlerToggleSelectedField(fieldToDisplay)"
|
||||
>
|
||||
{{ fieldNames[fieldToDisplay] || fieldToDisplay }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-row justify-content-between flex-wrap">
|
||||
<div v-if="newBtnShow || reload || $slots.actions" class="d-flex gap-2 align-items-baseline flex-wrap">
|
||||
<button v-if="newBtnShow" class="btn btn-outline-secondary" :class="newBtnClass" :title="newBtnLabel ? undefined : 'New'" :aria-label="newBtnLabel ? undefined : 'New'" @click="$emit('click:new', $event)" :disabled="newBtnDisabled">
|
||||
<span class="fa-solid fa-plus" aria-hidden="true"></span>
|
||||
{{ newBtnLabel }}
|
||||
</button>
|
||||
<button v-if="reload" class="btn btn-outline-secondary" aria-label="Reload" @click="reloadTable">
|
||||
<span class="fa-solid fa-rotate-right" aria-hidden="true"></span>
|
||||
</button>
|
||||
<span v-if="$slots.actions && tabulatorHasSelector">Mit {{selectedData.length}} ausgewählten: </span>
|
||||
<slot name="actions" v-bind="tabulatorHasSelector ? selectedData : []"></slot>
|
||||
</div>
|
||||
<div class="d-flex gap-1 align-items-baseline flex-grow-1 justify-content-end">
|
||||
<span v-if="!tableOnly">[ {{ filterName }} ]</span>
|
||||
<a v-if="!tableOnly" href="#" class="btn btn-link px-0 text-dark" data-bs-toggle="collapse" :data-bs-target="'#collapseFilters' + idExtra">
|
||||
<span class="fa-solid fa-xl fa-filter"></span>
|
||||
</a>
|
||||
<a href="#" class="btn btn-link px-0 text-dark" data-bs-toggle="collapse" :data-bs-target="'#collapseColumns' + idExtra">
|
||||
<span class="fa-solid fa-xl fa-table-columns"></span>
|
||||
</a>
|
||||
<table-download class="btn btn-link px-0 text-dark" :tabulator="tabulator" :config="download"></table-download>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!tableOnly" :id="'collapseFilters' + idExtra" class="card-body collapse" :data-bs-parent="'#filterCollapsables' + idExtra">
|
||||
<div class="card">
|
||||
<!-- Filter options -->
|
||||
<div class="card-body" v-if="!sideMenu">
|
||||
<select
|
||||
class="form-select"
|
||||
@change="handlerGetFilterById"
|
||||
>
|
||||
<option value="">Bitte auswählen...</option>
|
||||
<template v-for="availableFilter in availableFilters">
|
||||
<option v-bind:value="availableFilter.option">{{ availableFilter.description }}</option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div class="card-body filter-options-div">
|
||||
<div>
|
||||
<span>
|
||||
Neuer Filter
|
||||
</span>
|
||||
<span>
|
||||
<button class="btn btn-outline-dark" type="button" @click=handlerAddNewFilter>+</button>
|
||||
</span>
|
||||
</div>
|
||||
<div :id="'filterFields' + idExtra" class="filter-filter-fields">
|
||||
<template v-for="(filterField, index) in filterFields">
|
||||
<div class="row">
|
||||
<filter-columns
|
||||
:id="'collapseColumns' + idExtra"
|
||||
class="card-body collapse"
|
||||
:data-bs-parent="'#filterCollapsables' + idExtra"
|
||||
:fields="fieldIdsForVisibilty"
|
||||
:selected="selectedFields"
|
||||
:names="fieldNames"
|
||||
@hide="tabulator.hideColumn($event)"
|
||||
@show="tabulator.showColumn($event)"
|
||||
></filter-columns>
|
||||
|
||||
<div class="col-5">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Filter {{ index + 1 }}</span>
|
||||
<select
|
||||
class="form-select"
|
||||
name="fieldName"
|
||||
v-bind:value="filterField.name"
|
||||
@change="handlerChangeFilterField(filterField.name, $event.target.value)"
|
||||
>
|
||||
<option value="">Feld zum Filter hinzufügen...</option>
|
||||
<template v-for="columnAlias in filteredColumns">
|
||||
<option v-bind:value="columnAlias.field">{{ columnAlias.title }}</option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Numeric -->
|
||||
<template
|
||||
v-if="filterField.type.toLowerCase().indexOf('int') >= 0">
|
||||
<div class="col-2">
|
||||
<select class="form-select" name="operation" v-model="filterField.operation">
|
||||
<option value="equal">Gleich</option>
|
||||
<option value="nequal">Nicht gleich</option>
|
||||
<option value="gt">Größer als</option>
|
||||
<option value="lt">Weniger als</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input type="number" class="form-control" v-bind:value="filterField.condition" name="condition">
|
||||
</div>
|
||||
<div class="col">
|
||||
<button
|
||||
class="btn btn-outline-dark"
|
||||
type="button"
|
||||
v-bind:field-to-remove="filterField.name"
|
||||
@click=handlerRemoveFilterField>
|
||||
 X 
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Text -->
|
||||
<template
|
||||
v-if="filterField.type.toLowerCase().indexOf('varchar') >= 0
|
||||
|| filterField.type.toLowerCase().indexOf('text') >= 0
|
||||
|| filterField.type.toLowerCase().indexOf('bpchar') >= 0">
|
||||
<div class="col-2">
|
||||
<select class="form-select" name="operation" v-model="filterField.operation">
|
||||
<option value="equal">Gleich</option>
|
||||
<option value="nequal">Nicht gleich</option>
|
||||
<option value="contains">Enthält</option>
|
||||
<option value="ncontains">Enthält nicht</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input type="text" class="form-control" v-bind:value="filterField.condition" name="condition">
|
||||
</div>
|
||||
<div class="col">
|
||||
<button
|
||||
class="btn btn-outline-dark"
|
||||
type="button"
|
||||
v-bind:field-to-remove="filterField.name"
|
||||
@click=handlerRemoveFilterField>
|
||||
 X 
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Timestamp and date -->
|
||||
<template
|
||||
v-if="filterField.type.toLowerCase().indexOf('timestamp') >= 0
|
||||
|| filterField.type.toLowerCase().indexOf('date') >= 0">
|
||||
<div class="col-2">
|
||||
<select class="form-select" name="operation" v-model="filterField.operation">
|
||||
<option value="gt">Größer als</option>
|
||||
<option value="lt">Weniger als</option>
|
||||
<option value="set">Eingestellt ist</option>
|
||||
<option value="nset">Eingestellt nicht ist</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<input type="number" class="form-control" v-bind:value="filterField.condition" name="condition">
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<select class="form-select" name="option" v-model="filterField.option">
|
||||
<option value="minutes">Minuten</option>
|
||||
<option value="hours">Stunden</option>
|
||||
<option value="days">Tage</option>
|
||||
<option value="months">Monate</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button
|
||||
class="btn btn-outline-dark"
|
||||
type="button"
|
||||
v-bind:field-to-remove="filterField.name"
|
||||
@click=handlerRemoveFilterField
|
||||
> - </button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<!-- Filter save options -->
|
||||
<div class="row">
|
||||
<div class="col-7">
|
||||
<div class="input-group">
|
||||
<input ref="customFilterName" type="text" class="form-control" placeholder="Filternamen eingeben..." :id="'customFilterName' + idExtra">
|
||||
<button type="button" class="btn btn-outline-secondary" @click=handlerSaveCustomFilter>Filter speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-outline-dark" @click=handlerApplyFilterFields>Filter anwenden</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<filter-config
|
||||
v-if="!tableOnly"
|
||||
:id="'collapseFilters' + idExtra"
|
||||
class="card-body collapse"
|
||||
:data-bs-parent="'#filterCollapsables' + idExtra"
|
||||
:filters="!sideMenu ? (availableFilters || []) : []"
|
||||
:columns="columnsForFilter"
|
||||
:fields="filterFields || []"
|
||||
@switch-filter="switchFilter"
|
||||
@apply-filter-config="applyFilterConfig"
|
||||
@save-custom-filter="handlerSaveCustomFilter"
|
||||
></filter-config>
|
||||
</div>
|
||||
|
||||
<!-- Tabulator -->
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 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: {
|
||||
fields: Array,
|
||||
selected: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
names: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
hide: ['fieldName'],
|
||||
show: ['fieldName']
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
selectedFields: []
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
selected(n) {
|
||||
this.selectedFields = n;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggle(field) {
|
||||
if (this.selectedFields.indexOf(field) != -1)
|
||||
{
|
||||
this.selectedFields.splice(this.selectedFields.indexOf(field), 1);
|
||||
this.$emit('hide', field);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.selectedFields.push(field);
|
||||
this.$emit('show', field);
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="filter-columns">
|
||||
<div class="card">
|
||||
<div class="d-flex flex-wrap gap-2 p-3 justify-content-center">
|
||||
<div
|
||||
v-for="fieldToDisplay in fields"
|
||||
class="btn"
|
||||
:class="selectedFields.indexOf(fieldToDisplay) != -1 ? 'btn-dark' : 'btn-outline-dark' "
|
||||
@click="toggle(fieldToDisplay)"
|
||||
>
|
||||
{{ names[fieldToDisplay] || fieldToDisplay }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
const FILTER_COMPONENT_NEW_FILTER = 'Filter Component New Filter';
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
props: {
|
||||
filters: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
fields: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
emits: {
|
||||
switchFilter: ['filterId'],
|
||||
applyFilterConfig: ['filterFields'],
|
||||
saveCustomFilter: ['customFilterName']
|
||||
},
|
||||
data: function() {
|
||||
return {
|
||||
currentFields: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
types() {
|
||||
return this.columns.reduce((a,c) => {
|
||||
let type = c.type.toLowerCase();
|
||||
if (type.indexOf('int') >= 0)
|
||||
a[c.name] = 'Numeric';
|
||||
else if (
|
||||
type.indexOf('varchar') >= 0 ||
|
||||
type.indexOf('text') >= 0 ||
|
||||
type.indexOf('bpchar') >= 0
|
||||
)
|
||||
a[c.name] = 'Text';
|
||||
else if (
|
||||
type.indexOf('timestamp') >= 0 ||
|
||||
type.indexOf('date') >= 0
|
||||
)
|
||||
a[c.name] = 'Date';
|
||||
else
|
||||
a[c.name] = '';
|
||||
return a;
|
||||
}, {});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
fields(n) {
|
||||
this.currentFields = n;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
switchFilter(evt) {
|
||||
this.$emit('switchFilter', evt.currentTarget.value);
|
||||
},
|
||||
applyFilterConfig() {
|
||||
const filteredFields = this.currentFields.filter(el => el.name != FILTER_COMPONENT_NEW_FILTER);
|
||||
if (filteredFields.filter(el => el.condition == "").length)
|
||||
alert("Please fill all the filter options");
|
||||
else
|
||||
this.$emit('applyFilterConfig', filteredFields);
|
||||
},
|
||||
addField(evt) {
|
||||
this.currentFields.push({
|
||||
name: FILTER_COMPONENT_NEW_FILTER
|
||||
});
|
||||
},
|
||||
removeField(index) {
|
||||
this.currentFields.splice(index, 1);
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div class="filter-config">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div v-if="filters.length" class="mb-4">
|
||||
<select class="form-select" @change="switchFilter">
|
||||
<option value="">Bitte auswählen...</option>
|
||||
<option v-for="filter in filters" :value="filter.id">
|
||||
{{ filter.description }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-outline-dark" type="button" @click=addField>
|
||||
<span class="fa-solid fa-plus" aria-hidden="true"></span> Neuer Filter
|
||||
</button>
|
||||
</div>
|
||||
<div class="filter-config-fields my-3">
|
||||
<div v-for="(filterField, index) in currentFields" class="filter-config-field row">
|
||||
|
||||
<div class="col-5">
|
||||
<div class="input-group">
|
||||
<span class="input-group-text">Filter {{ index + 1 }}</span>
|
||||
<select
|
||||
class="form-select"
|
||||
v-model="filterField.name"
|
||||
>
|
||||
<option value="">Feld zum Filter hinzufügen...</option>
|
||||
<option v-for="col in columns" :value="col.name">
|
||||
{{ col.title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Numeric -->
|
||||
<template v-if="types[filterField.name] == 'Numeric'">
|
||||
<div class="col-2">
|
||||
<select class="form-select" v-model="filterField.operation">
|
||||
<option value="equal">Gleich</option>
|
||||
<option value="nequal">Nicht gleich</option>
|
||||
<option value="gt">Größer als</option>
|
||||
<option value="lt">Weniger als</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input type="number" class="form-control" v-model="filterField.condition">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Text -->
|
||||
<template v-if="types[filterField.name] == 'Text'">
|
||||
<div class="col-2">
|
||||
<select class="form-select" v-model="filterField.operation">
|
||||
<option value="equal">Gleich</option>
|
||||
<option value="nequal">Nicht gleich</option>
|
||||
<option value="contains">Enthält</option>
|
||||
<option value="ncontains">Enthält nicht</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<input type="text" class="form-control" v-model="filterField.condition">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Timestamp and date -->
|
||||
<template v-if="types[filterField.name] == 'Date'">
|
||||
<div class="col-2">
|
||||
<select class="form-select" v-model="filterField.operation">
|
||||
<option value="gt">Größer als</option>
|
||||
<option value="lt">Weniger als</option>
|
||||
<option value="set">Eingestellt ist</option>
|
||||
<option value="nset">Eingestellt nicht ist</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-1">
|
||||
<input type="number" class="form-control" v-model="filterField.condition">
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<select class="form-select" v-model="filterField.option">
|
||||
<option value="minutes">Minuten</option>
|
||||
<option value="hours">Stunden</option>
|
||||
<option value="days">Tage</option>
|
||||
<option value="months">Monate</option>
|
||||
</select>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="col text-end">
|
||||
<button
|
||||
class="btn btn-outline-dark"
|
||||
type="button"
|
||||
@click="removeField(index)"
|
||||
title="Filter entfernen"
|
||||
aria-title="Filter entfernen"
|
||||
>
|
||||
<span class="fa-solid fa-minus" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filter save options -->
|
||||
<div class="row">
|
||||
<div class="col-7">
|
||||
<div class="input-group">
|
||||
<input ref="filterName" type="text" class="form-control" placeholder="Filternamen eingeben...">
|
||||
<button type="button" class="btn btn-outline-secondary" @click="$emit('saveCustomFilter', $refs.filterName.value)">Filter speichern</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<button type="button" class="btn btn-outline-dark" @click="applyFilterConfig">Filter anwenden</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
};
|
||||
|
||||
@@ -0,0 +1,247 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
const DEFAULT_ICONS = {
|
||||
jsonLines: 'fa-file-lines',
|
||||
xlsx: 'fa-file-excel',
|
||||
pdf: 'fa-file-pdf',
|
||||
html: 'fa-file-code',
|
||||
json: 'fa-file',
|
||||
csv: 'fa-file-csv'
|
||||
};
|
||||
const DEFAULT_LABELS = {
|
||||
jsonLines: 'Download as JSONLINES',
|
||||
xlsx: 'Download as XLSX',
|
||||
pdf: 'Download as PDF',
|
||||
html: 'Download as HTML',
|
||||
json: 'Download as JSON',
|
||||
csv: 'Download as CSV '
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export default {
|
||||
props: {
|
||||
tabulator: Object,
|
||||
config: {
|
||||
type: [Boolean, String, Function, Array, Object],
|
||||
default: false
|
||||
},
|
||||
iconClass: [String, Array, Object]
|
||||
},
|
||||
computed: {
|
||||
currentConfig() {
|
||||
if (!this.config)
|
||||
return false;
|
||||
|
||||
let config = this.config;
|
||||
|
||||
if (config instanceof Function)
|
||||
return [config];
|
||||
|
||||
if (config === null)
|
||||
return [];
|
||||
|
||||
if (this.config === true)
|
||||
config = ['csv'];
|
||||
|
||||
if (Object.prototype.toString.call(config) === "[object String]")
|
||||
config = config.split(',');
|
||||
|
||||
if (typeof config === 'object' && !Array.isArray(config)) {
|
||||
let newConfig = [];
|
||||
for (var k in config) {
|
||||
var v = config[k], type;
|
||||
|
||||
if (!v)
|
||||
continue;
|
||||
|
||||
if (Object.prototype.toString.call(v) === "[object String]") {
|
||||
type = this.stringToFileFormatter(v);
|
||||
if (type !== null) {
|
||||
newConfig.push({
|
||||
icon: 'fa-solid ' + DEFAULT_ICONS[type],
|
||||
label: v === k ? DEFAULT_LABELS[type] : k,
|
||||
formatter: type
|
||||
});
|
||||
} else {
|
||||
type = this.stringToFileFormatter(k);
|
||||
if(type !== null) {
|
||||
newConfig.push({
|
||||
icon: 'fa-solid ' + DEFAULT_ICONS[type],
|
||||
label: v,
|
||||
formatter: type
|
||||
});
|
||||
} else {
|
||||
alert('neither ' + k + ' nor ' + v + ' are supported download file types');
|
||||
}
|
||||
}
|
||||
} else if (typeof v === 'object' && !Array.isArray(v)) {
|
||||
type = this.stringToFileFormatter(k);
|
||||
if (type !== null) {
|
||||
if (v.formatter === undefined)
|
||||
v.formatter = type;
|
||||
if (v.label === undefined)
|
||||
v.label = DEFAULT_LABELS[type];
|
||||
if (v.icon === undefined)
|
||||
v.icon = DEFAULT_ICONS[type];
|
||||
newConfig.push(v);
|
||||
} else {
|
||||
if (v.label === undefined)
|
||||
v.label = k;
|
||||
newConfig.push(v);
|
||||
}
|
||||
} else {
|
||||
type = this.stringToFileFormatter(k);
|
||||
if (type !== null) {
|
||||
newConfig.push({
|
||||
icon: 'fa-solid ' + DEFAULT_ICONS[type],
|
||||
label: DEFAULT_LABELS[type],
|
||||
formatter: type
|
||||
});
|
||||
} else {
|
||||
alert(k + ' is not a supported download file type');
|
||||
}
|
||||
}
|
||||
}
|
||||
config = newConfig;
|
||||
}
|
||||
|
||||
if (Array.isArray(config))
|
||||
{
|
||||
config = config.map(el => {
|
||||
if (Object.prototype.toString.call(el) === "[object String]") {
|
||||
let formatter = this.stringToFileFormatter(el);
|
||||
if (formatter === null)
|
||||
return null;
|
||||
return {
|
||||
icon: 'fa-solid ' + DEFAULT_ICONS[formatter],
|
||||
label: DEFAULT_LABELS[formatter],
|
||||
formatter
|
||||
};
|
||||
}
|
||||
|
||||
if (el instanceof Function)
|
||||
return {
|
||||
formatter: el
|
||||
}
|
||||
|
||||
if (typeof el === 'object' && !Array.isArray(el) && el !== null) {
|
||||
if (el.formatter instanceof Function)
|
||||
return el;
|
||||
if (this.validateFileFormatter(el.formatter))
|
||||
return el;
|
||||
}
|
||||
|
||||
return null;
|
||||
}).filter(el => el !== null);
|
||||
|
||||
if (config.length < 2)
|
||||
return config;
|
||||
|
||||
if (config.filter(el => el.label || el.icon).length == config.length)
|
||||
return config;
|
||||
|
||||
alert('Config not valid');
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
stringToFileFormatter(input) {
|
||||
let lcInput = input.toLowerCase();
|
||||
|
||||
if (lcInput == 'jsonlines')
|
||||
return 'jsonLines';
|
||||
|
||||
if (['xlsx', 'pdf', 'html', 'json', 'csv'].includes(lcInput))
|
||||
return lcInput;
|
||||
|
||||
return null;
|
||||
},
|
||||
validateFileFormatter(input) {
|
||||
let formatter = this.stringToFileFormatter(input);
|
||||
if (!formatter) {
|
||||
alert(input + ' is not a supported file formatter');
|
||||
return false;
|
||||
}
|
||||
if (formatter == 'xlsx') {
|
||||
if (!window.XLSX) {
|
||||
alert('XLSX Library not loaded');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (formatter == 'pdf') {
|
||||
if (!window.jspdf) {
|
||||
alert('jsPDF Library not loaded');
|
||||
return false;
|
||||
}
|
||||
var doc = new jspdf.jsPDF({});
|
||||
if (!doc.autoTable) {
|
||||
alert('jsPDF-AutoTable Plugin not loaded');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
download(config) {
|
||||
this.tabulator.download(config.formatter, config.file, config.options)
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<template v-if="currentConfig">
|
||||
<template v-if="currentConfig.length == 1">
|
||||
<a
|
||||
href="#"
|
||||
class="table-download"
|
||||
v-bind="$attrs"
|
||||
title="Download"
|
||||
aria-title="Download"
|
||||
@click.prevent="download(currentConfig[0])"
|
||||
>
|
||||
<span :class="iconClass || 'fa-solid fa-xl fa-download'" aria-hidden="true"></span>
|
||||
</a>
|
||||
</template>
|
||||
<div v-else class="dropdown d-inline">
|
||||
<a
|
||||
href="#"
|
||||
class="table-download"
|
||||
v-bind="$attrs"
|
||||
title="Download"
|
||||
aria-title="Download"
|
||||
role="button"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
<span :class="iconClass || 'fa-solid fa-xl fa-download'" aria-hidden="true"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li v-for="(conf, i) in currentConfig" :key="i">
|
||||
<a class="dropdown-item" href="#" @click.prevent="download(conf)">
|
||||
<span v-if="conf.icon" :class="conf.icon" aria-hidden="true"></span>
|
||||
{{conf.label}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
`
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import {CoreRESTClient} from '../../RESTClient.js';
|
||||
|
||||
//
|
||||
const CORE_NAVIGATION_CMPT_TIMEOUT = 2000;
|
||||
const CORE_NAVIGATION_CMPT_TIMEOUT = 5000;
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -59,13 +59,18 @@ const phrasen = {
|
||||
return '';
|
||||
}
|
||||
if (!categories[category]) {
|
||||
|
||||
//if (window.FHC_JS_PHRASES_STORAGE_OBJECT !== undefined)
|
||||
// categories[category] = extractCategory(FHC_JS_PHRASES_STORAGE_OBJECT, category);
|
||||
|
||||
var initialval = '';
|
||||
if (window.FHC_JS_PHRASES_STORAGE_OBJECT !== undefined) {
|
||||
var tmp_category = extractCategory(FHC_JS_PHRASES_STORAGE_OBJECT, category);
|
||||
if(tmp_category[phrase] !== undefined ) {
|
||||
initialval = tmp_category[phrase];
|
||||
}
|
||||
}
|
||||
|
||||
if (!categories[category] || Object.keys(categories[category]).length === 0) {
|
||||
categories[category] = undefined;
|
||||
let val = Vue.ref('');
|
||||
let val = Vue.ref(initialval);
|
||||
loadLazy(category, val, phrase, params);
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ function breaktext($text, $zeichen)
|
||||
$arr = explode(' ',$text);
|
||||
$ret = '';
|
||||
$teilstring='';
|
||||
|
||||
|
||||
foreach($arr as $elem)
|
||||
{
|
||||
if(strlen($teilstring.$elem)>$zeichen)
|
||||
@@ -60,7 +60,7 @@ function breaktext($text, $zeichen)
|
||||
$ret.=' '.$teilstring.'\n';
|
||||
$teilstring=$elem;
|
||||
}
|
||||
else
|
||||
else
|
||||
$teilstring .=' '.$elem;
|
||||
}
|
||||
$ret.=$teilstring;
|
||||
@@ -72,9 +72,9 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
|
||||
if(isset($_GET['uid']))
|
||||
$uid = $_GET['uid'];
|
||||
else
|
||||
else
|
||||
$uid = null;
|
||||
|
||||
|
||||
$uid_arr = explode(";",$uid);
|
||||
|
||||
if ($uid_arr[0] == "")
|
||||
@@ -82,61 +82,61 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
unset($uid_arr[0]);
|
||||
$uid_arr = array_values($uid_arr);
|
||||
}
|
||||
|
||||
|
||||
$note_arr = array();
|
||||
$note = new note();
|
||||
$note->getAll($offiziell = true);
|
||||
foreach ($note->result as $n){
|
||||
$note_arr[$n->note] = $n->anmerkung;
|
||||
$note_bezeichnung_arr[$n->note] = $n->bezeichnung;
|
||||
|
||||
$note_bezeichnung_arr[$n->note] = $n->bezeichnung;
|
||||
|
||||
}
|
||||
if(isset($_GET['ss']))
|
||||
$studiensemester_kurzbz = $_GET['ss'];
|
||||
else
|
||||
else
|
||||
die('Studiensemester muss uebergeben werden');
|
||||
|
||||
if(isset($_GET['lvid']))
|
||||
$lehrveranstaltung_id = $_GET['lvid'];
|
||||
else
|
||||
else
|
||||
$lehrveranstaltung_id = 0;
|
||||
|
||||
|
||||
//Daten holen
|
||||
|
||||
$lqry = "SELECT
|
||||
tbl_person.titelpre, tbl_person.vorname, tbl_person.nachname, tbl_person.titelpost
|
||||
FROM
|
||||
public.tbl_benutzer JOIN public.tbl_person using (person_id)
|
||||
WHERE
|
||||
tbl_benutzer.uid = (SELECT
|
||||
tbl_lehreinheitmitarbeiter.mitarbeiter_uid
|
||||
FROM
|
||||
lehre.tbl_lehreinheitmitarbeiter JOIN lehre.tbl_lehrfunktion USING(lehrfunktion_kurzbz),
|
||||
lehre.tbl_lehreinheit JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
$lqry = "SELECT
|
||||
tbl_person.titelpre, tbl_person.vorname, tbl_person.nachname, tbl_person.titelpost
|
||||
FROM
|
||||
public.tbl_benutzer JOIN public.tbl_person using (person_id)
|
||||
WHERE
|
||||
tbl_benutzer.uid = (SELECT
|
||||
tbl_lehreinheitmitarbeiter.mitarbeiter_uid
|
||||
FROM
|
||||
lehre.tbl_lehreinheitmitarbeiter JOIN lehre.tbl_lehrfunktion USING(lehrfunktion_kurzbz),
|
||||
lehre.tbl_lehreinheit JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
tbl_lehreinheitmitarbeiter.lehreinheit_id = tbl_lehreinheit.lehreinheit_id AND
|
||||
tbl_lehrveranstaltung.lehrveranstaltung_id = ".$db->db_add_param($lehrveranstaltung_id)." AND
|
||||
tbl_lehreinheit.studiensemester_kurzbz=".$db->db_add_param($studiensemester_kurzbz)."
|
||||
ORDER BY tbl_lehrfunktion.standardfaktor desc limit 1)";
|
||||
|
||||
|
||||
$leiter_titel = '';
|
||||
$leiter_vorname = '';
|
||||
$leiter_nachname = '';
|
||||
$leiter_titelpost = '';
|
||||
|
||||
|
||||
if($db->db_query($lqry))
|
||||
{
|
||||
if ($lrow = $db->db_fetch_object())
|
||||
{
|
||||
$leiter_titel = $lrow->titelpre;
|
||||
$leiter_titel = $lrow->titelpre;
|
||||
$leiter_vorname = $lrow->vorname;
|
||||
$leiter_nachname = $lrow->nachname;
|
||||
$leiter_titelpost = $lrow->titelpost;
|
||||
}
|
||||
$leiter_nachname = $lrow->nachname;
|
||||
$leiter_titelpost = $lrow->titelpost;
|
||||
}
|
||||
}
|
||||
|
||||
$qry = "SELECT wochen FROM public.tbl_semesterwochen
|
||||
WHERE (studiengang_kz, semester) in (SELECT studiengang_kz, semester
|
||||
|
||||
$qry = "SELECT wochen FROM public.tbl_semesterwochen
|
||||
WHERE (studiengang_kz, semester) in (SELECT studiengang_kz, semester
|
||||
FROM lehre.tbl_lehrveranstaltung WHERE lehrveranstaltung_id=".$db->db_add_param($lehrveranstaltung_id, FHC_INTEGER).")";
|
||||
$wochen = 15;
|
||||
if($result_wochen = $db->db_query($qry))
|
||||
@@ -146,7 +146,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$wochen = $row_wochen->wochen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$lehrveranstaltung=new lehrveranstaltung();
|
||||
$lehrveranstaltung->load($lehrveranstaltung_id);
|
||||
$sws=$lehrveranstaltung->semesterstunden/$wochen;
|
||||
@@ -157,7 +157,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$lehrform = new lehrform($lehrform_kurzbz);
|
||||
$lehrform_bezeichnung = $lehrform->bezeichnung;
|
||||
$organisationseinheit = new organisationseinheit($lehrveranstaltung->oe_kurzbz);
|
||||
|
||||
|
||||
$lehreinheit=new lehreinheit();
|
||||
$lehreinheit->load_lehreinheiten($lehrveranstaltung_id, $studiensemester_kurzbz);
|
||||
if(count($lehreinheit->lehreinheiten)>=1)
|
||||
@@ -169,11 +169,11 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$lehrfach_id='';
|
||||
die('keine Lehreinheiten gefunden!');
|
||||
}
|
||||
|
||||
|
||||
$lv_lehrfach=new lehrveranstaltung();
|
||||
$lv_lehrfach->load($lehrfach_id);
|
||||
$lehrfach_bezeichnung=$lv_lehrfach->bezeichnung;
|
||||
|
||||
|
||||
/* $lvqry = "SELECT * from lehre.tbl_lehrveranstaltung where lehrveranstaltung_id = ".$db->db_add_param($lehrveranstaltung_id, FHC_INTEGER);
|
||||
if($db->db_query($lvqry))
|
||||
{
|
||||
@@ -182,43 +182,43 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$sws = $lvrow->semesterstunden/$wochen;
|
||||
$ects = $lvrow->ects;
|
||||
$lvbezeichnung = $lvrow->bezeichnung;
|
||||
$lvstg = $lvrow->studiengang_kz;
|
||||
}
|
||||
$lvstg = $lvrow->studiengang_kz;
|
||||
}
|
||||
} */
|
||||
|
||||
|
||||
$lehrinhalte = '';
|
||||
$infoqry = "SELECT * FROM campus.tbl_lvinfo WHERE sprache='German' AND lehrveranstaltung_id = ".$db->db_add_param($lehrveranstaltung_id, FHC_INTEGER);
|
||||
if($db->db_query($infoqry))
|
||||
{
|
||||
if ($inforow = $db->db_fetch_object())
|
||||
{
|
||||
$lehrinhalte_arr = explode("<br>",$inforow->lehrinhalte);
|
||||
$lehrinhalte_arr = explode("<br>",$inforow->lehrinhalte);
|
||||
for ($i = 0; $i < sizeof($lehrinhalte_arr); $i++)
|
||||
{
|
||||
$lehrinhalte .= $lehrinhalte_arr[$i].'\n';
|
||||
$lehrinhalte .= $lehrinhalte_arr[$i].'\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$xml = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>";
|
||||
$xml .= "<zertifikate>";
|
||||
|
||||
|
||||
$studiensemester = new studiensemester();
|
||||
$studiensemester->load($studiensemester_kurzbz);
|
||||
|
||||
|
||||
for ($i = 0; $i < sizeof($uid_arr); $i++)
|
||||
{
|
||||
$anzahl_fussnoten=0;
|
||||
$studiengang_typ='';
|
||||
$xml_fussnote='';
|
||||
|
||||
|
||||
$query = "SELECT mitarbeiter_uid FROM lehre.tbl_lehreinheit as le
|
||||
JOIN lehre.tbl_pruefung as p USING(lehreinheit_id)
|
||||
JOIN lehre.tbl_lehrveranstaltung as lv USING(lehrveranstaltung_id)
|
||||
WHERE p.student_uid = ".$db->db_add_param($uid_arr[$i])."
|
||||
AND le.studiensemester_kurzbz = ".$db->db_add_param($studiensemester_kurzbz)."
|
||||
AND lv.lehrveranstaltung_id = ".$db->db_add_param($lehrveranstaltung_id, FHC_INTEGER);
|
||||
|
||||
|
||||
$pruefer_uid='';
|
||||
$pruefer_name='';
|
||||
if($db->db_query($query))
|
||||
@@ -231,7 +231,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
if($pruefer_uid!='')
|
||||
{
|
||||
$pruefer = new mitarbeiter($pruefer_uid);
|
||||
$pruefer_name = trim($pruefer->titelpre.' '.$pruefer->vorname.' '.$pruefer->nachname.' '.$pruefer->titelpost);
|
||||
$pruefer_name = trim($pruefer->titelpre.' '.$pruefer->vorname.' '.$pruefer->nachname.' '.$pruefer->titelpost);
|
||||
}
|
||||
|
||||
$query = "SELECT tbl_student.matrikelnr, tbl_student.studiengang_kz, tbl_studiengang.typ, tbl_studiengang.bezeichnung, tbl_person.vorname, tbl_person.nachname,tbl_person.gebdatum,tbl_person.titelpre, tbl_person.titelpost, tbl_person.geschlecht, tbl_person.matr_nr FROM tbl_person, tbl_student, tbl_studiengang, tbl_benutzer 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 and tbl_student.student_uid = '".$uid_arr[$i]."'";
|
||||
@@ -251,7 +251,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$stgl_ma = new mitarbeiter($stgleiter_uid);
|
||||
$stgl .= trim($stgl_ma->titelpre.' '.$stgl_ma->vorname.' '.$stgl_ma->nachname.' '.$stgl_ma->titelpost);
|
||||
}
|
||||
|
||||
|
||||
$student=new student();
|
||||
$student->load($uid_arr[$i]);
|
||||
$prestudent=new prestudent();
|
||||
@@ -261,11 +261,11 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
{
|
||||
if($status->studienplan_bezeichnung != '')
|
||||
$studienplan_bezeichnung=$status->studienplan_bezeichnung;
|
||||
|
||||
|
||||
if($status->studienplan_id != NULL)
|
||||
$studienplan_id = $status->studienplan_id;
|
||||
}
|
||||
|
||||
|
||||
$xml .= "\n <zertifikat>";
|
||||
$xml .= "\n <studiensemester>".$studiensemester_kurzbz."</studiensemester>";
|
||||
$xml .= "\n <vorname>".$row->vorname."</vorname>";
|
||||
@@ -279,8 +279,8 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$xml .= "\n <studiengangsleiter>".$stgl."</studiengangsleiter>";
|
||||
$datum_aktuell = date('d.m.Y');
|
||||
$xml .= "\n <ort_datum>Wien, am ".$datum_aktuell."</ort_datum>";
|
||||
|
||||
|
||||
|
||||
|
||||
$obj = new zeugnisnote();
|
||||
$obj->load($lehrveranstaltung_id, $uid_arr[$i], $studiensemester_kurzbz);
|
||||
|
||||
@@ -298,10 +298,10 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$uebernahmedatum = "";
|
||||
$benotungsdatum = "";
|
||||
}
|
||||
|
||||
|
||||
$stg = new studiengang();
|
||||
$stg->load($lvstg);
|
||||
|
||||
|
||||
$xml .= " <stg_studiengang_bezeichnung>".$stg_oe_obj->bezeichnung."</stg_studiengang_bezeichnung>";
|
||||
$xml .= " <lv_studiengang_bezeichnung>".$stg->bezeichnung."</lv_studiengang_bezeichnung>";
|
||||
$xml .= " <lv_studiengang_typ>".$stg->typ."</lv_studiengang_typ>";
|
||||
@@ -318,20 +318,20 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$xml .= " <lehrform_kurzbz>".$lehrform_kurzbz."</lehrform_kurzbz>";
|
||||
$xml .= " <lehrform_bezeichnung>".$lehrform_bezeichnung."</lehrform_bezeichnung>";
|
||||
$xml .= " <sws>".($sws==0?'':number_format(sprintf('%.1F',$sws),1))."</sws>";
|
||||
|
||||
|
||||
$xml .= " <lvleiter>".$leiter_titel." ".$leiter_vorname." ".$leiter_nachname.($leiter_titelpost!=''?', '.$leiter_titelpost:'')."</lvleiter>";
|
||||
$xml .= " <lehrinhalte><![CDATA[".clearHtmlTags($lehrinhalte)."]]></lehrinhalte>";
|
||||
$xml .= " <kompatible_lvs>";
|
||||
|
||||
|
||||
$lehrveranstaltung->getLVkompatibel($lehrveranstaltung_id);
|
||||
foreach($lehrveranstaltung->lehrveranstaltungen as $lv_kompatibel)
|
||||
{
|
||||
$xml .= "<lv>".$lv_kompatibel->bezeichnung."</lv>";
|
||||
$xml .= "<lv><![CDATA[".$lv_kompatibel->bezeichnung."]]></lv>";
|
||||
}
|
||||
|
||||
$xml .= " </kompatible_lvs>";
|
||||
|
||||
|
||||
|
||||
|
||||
$anrechnung = new anrechnung();
|
||||
$anrechnung->getAnrechnungPrestudent($student->prestudent_id, null, $lehrveranstaltung_id);
|
||||
|
||||
@@ -343,7 +343,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$xml .= $anrechnung->result[0]->lehrveranstaltung_bez;
|
||||
}
|
||||
$xml .= "</studienverpflichtung>";
|
||||
|
||||
|
||||
if($lehrveranstaltung_id_kompatibel != "")
|
||||
{
|
||||
$lv = new lehrveranstaltung($lehrveranstaltung_id_kompatibel);
|
||||
@@ -352,11 +352,11 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$ects = $lv->ects;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$xml .= " <ects>".number_format($ects,1)."</ects>";
|
||||
|
||||
$lehrveranstaltung->loadLehrveranstaltungStudienplan($studienplan_id);
|
||||
|
||||
|
||||
$studienplan_lehrveranstaltung_id = "";
|
||||
foreach($lehrveranstaltung->lehrveranstaltungen as $lv)
|
||||
{
|
||||
@@ -366,7 +366,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$studienplan = new studienplan();
|
||||
if($studienplan_lehrveranstaltung_id != "")
|
||||
{
|
||||
@@ -384,11 +384,11 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
{
|
||||
$lehrveranstaltung->lehrveranstaltungen = array();
|
||||
}
|
||||
|
||||
|
||||
// $return = $lehrveranstaltung->getLVFromStudienplanByLehrtyp($studienplan_id, "modul");
|
||||
|
||||
$xml .= " <module>";
|
||||
|
||||
|
||||
//Variable wird zur korrekten Darstellung im Dokument benötigt
|
||||
$count=0;
|
||||
foreach($lehrveranstaltung->lehrveranstaltungen as $modul)
|
||||
@@ -411,4 +411,4 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
$xml .= "</zertifikate>";
|
||||
echo $xml;
|
||||
}
|
||||
?>
|
||||
?>
|
||||
|
||||
@@ -18976,6 +18976,9 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
/*
|
||||
// es kann fuer jede Kombination Typ und Status eine Phrase der Form info_<Typ>_<Status
|
||||
// erstellt werden, die dann in der Studierendenansicht in einer infobox angezeigt werden
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'studierendenantrag',
|
||||
@@ -18996,6 +18999,7 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
*/
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'studierendenantrag',
|
||||
@@ -21467,7 +21471,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Die Abmeldung vom Studium kann hier durchführt werden.',
|
||||
'text' => 'Die Abmeldung vom Studium kann hier durchgeführt werden.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
|
||||
@@ -806,7 +806,12 @@ if (isset($_POST['save']))
|
||||
$stg_obj = new studiengang();
|
||||
$stg_obj->load(ltrim($stg,'0'));
|
||||
|
||||
$uid = generateUID($stg_obj->kurzbz,$jahr, $stg_obj->typ, $matrikelnr);
|
||||
$nachname_clean = mb_strtolower(convertProblemChars($person->nachname));
|
||||
$vorname_clean = mb_strtolower(convertProblemChars($person->vorname));
|
||||
$nachname_clean = str_replace(' ','_', $nachname_clean);
|
||||
$vorname_clean = str_replace(' ','_', $vorname_clean);
|
||||
|
||||
$uid = generateUID($stg_obj->kurzbz,$jahr, $stg_obj->typ, $matrikelnr, $vorname_clean, $nachname_clean);
|
||||
|
||||
//Benutzerdatensatz anlegen
|
||||
$benutzer = new benutzer();
|
||||
@@ -815,10 +820,6 @@ if (isset($_POST['save']))
|
||||
$benutzer->aktiv = true;
|
||||
$benutzer->aktivierungscode = generateActivationKey();
|
||||
|
||||
$nachname_clean = mb_strtolower(convertProblemChars($person->nachname));
|
||||
$vorname_clean = mb_strtolower(convertProblemChars($person->vorname));
|
||||
$nachname_clean = str_replace(' ','_', $nachname_clean);
|
||||
$vorname_clean = str_replace(' ','_', $vorname_clean);
|
||||
|
||||
if (!defined('GENERATE_ALIAS_STUDENT') || GENERATE_ALIAS_STUDENT === true)
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@ require_once('../../include/datum.class.php');
|
||||
require_once('../../include/benutzerberechtigung.class.php');
|
||||
require_once('../../include/addon.class.php');
|
||||
require_once('../../include/benutzerfunktion.class.php');
|
||||
require_once('../../include/phrasen.class.php');
|
||||
|
||||
if (!$db = new basis_db())
|
||||
die('Es konnte keine Verbindung zum Server aufgebaut werden.');
|
||||
@@ -63,6 +64,16 @@ $message='';
|
||||
$error=false;
|
||||
$mlAbgeschickt = '';
|
||||
|
||||
//Phrasen
|
||||
$sprache = getSprache();
|
||||
$p = new phrasen($sprache);
|
||||
|
||||
//Default-Wert für Max-Intervall in Tagen für Zeitsperre, über Config veränderbar
|
||||
$maxDauerZS = 730;
|
||||
|
||||
if (defined('CIS_ZEITSPERREN_MAX_DAUER') && CIS_ZEITSPERREN_MAX_DAUER != '') {
|
||||
$maxDauerZS = CIS_ZEITSPERREN_MAX_DAUER;
|
||||
}
|
||||
//prüfen, ob addon casetime aktiviert ist
|
||||
$addon_obj = new addon();
|
||||
$addoncasetime = $addon_obj->checkActiveAddon("casetime");
|
||||
@@ -205,6 +216,24 @@ if(isset($_POST['save']))
|
||||
if(!$berechtigt)
|
||||
die('Sie haben keine Berechtigung für diese Aktion');
|
||||
|
||||
//Validierungen Felder Bis-Datum und Von-Datum
|
||||
if($vondatum > $bisdatum)
|
||||
{
|
||||
$errormsg = $p->t('zeitsperre/vonDatumGroesserAlsBisDatum').'! ';
|
||||
$error=true;
|
||||
}
|
||||
|
||||
//Check if Bisdatum zu weit in der Zukunft
|
||||
$von = new DateTime($vondatum);
|
||||
$bis = new DateTime($bisdatum);
|
||||
|
||||
$intervall = $bis->diff($von);
|
||||
if ($intervall->days > $maxDauerZS)
|
||||
{
|
||||
$error=true;
|
||||
$errormsg = $p->t('zeitsperre/bisDatumGroesserMax');
|
||||
}
|
||||
|
||||
//Speichern der Daten
|
||||
$zeitsperre = new zeitsperre();
|
||||
|
||||
@@ -225,6 +254,8 @@ if(isset($_POST['save']))
|
||||
$zeitsperre->mitarbeiter_uid=$uid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!$error)
|
||||
{
|
||||
$zeitsperre->zeitsperretyp_kurzbz=$zeitsperretyp_kurzbz;
|
||||
|
||||
Reference in New Issue
Block a user