Merge branch 'feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter' of https://github.com/FH-Complete/FHC-Core into feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter

This commit is contained in:
Cris
2023-12-04 17:34:19 +01:00
45 changed files with 841 additions and 473 deletions
+6 -3
View File
@@ -349,6 +349,7 @@ class AntragJob extends JOB_Controller
$this->StudierendenantragModel->addSelect('prestudent_id');
$this->StudierendenantragModel->addSelect('studiensemester_kurzbz');
$this->StudierendenantragModel->addSelect('s.insertamum');
$this->StudierendenantragModel->addSelect('s.insertvon');
$this->StudierendenantragModel->db->where_in('public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)', $this->config->item('antrag_prestudentstatus_whitelist'));
@@ -372,9 +373,11 @@ class AntragJob extends JOB_Controller
$result = $this->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
$insertvon,
'AntragJob',
'abbrecherStgl',
$antrag->insertamum
$antrag->insertamum,
null,
$antrag->insertvon ?: $insertvon
);
if (isError($result))
$this->logError(getError($result));
@@ -413,7 +416,7 @@ class AntragJob extends JOB_Controller
}
}
}
$this->logInfo($count . " Students set to Abbrecher");
$this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher");
}
$this->logInfo('Ende Job handleAbmeldungenStglDeadline');
}
@@ -35,6 +35,7 @@ class LehrauftragAkzeptieren extends Auth_Controller
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('codex/Bisverwendung_model', 'BisverwendungModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('vertragsbestandteil/Dienstverhaeltnis_model', 'DienstverhaeltnisModel');
// Load libraries
$this->load->library('WidgetLib');
@@ -94,9 +95,9 @@ class LehrauftragAkzeptieren extends Auth_Controller
'lektor' => true,
'aktiv' => true
));
$is_external_lector = hasData($result) ? true : false;
$view_data = array(
'studiensemester_selected' => $studiensemester_kurzbz,
'is_external_lector' => $is_external_lector
@@ -207,15 +208,41 @@ class LehrauftragAkzeptieren extends Auth_Controller
*/
public function checkInkludierteLehre()
{
$result = $this->BisverwendungModel->getLast($this->_uid, false);
if (hasData($result))
if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT)
{
$this->outputJsonSuccess(!is_null($result->retval[0]->inkludierte_lehre) && $result->retval[0]->inkludierte_lehre != 0);
// Bei neuer Vertragsstruktur wird nur anhand des echten DVs entschieden ob eine Anzeige
// des Stundensatzes erfolgt oder nicht.
$result = $this->DienstverhaeltnisModel->getDVByPersonUID($this->_uid, null, date('Y-m-d'));
if (hasData($result))
{
$data = getData($result);
foreach($data as $row)
{
if($row->vertragsart_kurzbz == 'echterdv')
$this->outputJsonSuccess(true);
else
$this->outputJsonSuccess(false);
}
}
else
{
$this->outputJsonError(getError($result));
}
}
else
{
$this->outputJsonError(getError($result));
// DEPRECATED
$result = $this->BisverwendungModel->getLast($this->_uid, false);
if (hasData($result))
{
$this->outputJsonSuccess(!is_null($result->retval[0]->inkludierte_lehre) && $result->retval[0]->inkludierte_lehre != 0);
}
else
{
$this->outputJsonError(getError($result));
}
}
}
+6 -2
View File
@@ -854,14 +854,18 @@ class AntragLib
$prestudent_status = current($res);
$email = $prestudent_status->email;
// NOTE(chris): Sancho mail
$lvzuweisungLink = site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id);
if( defined('VILESCI_ROOT') )
{
$lvzuweisungLink = VILESCI_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id;
}
sendSanchoMail(
'Sancho_Mail_Antrag_W_New',
[
'antrag_id' => $antrag_id,
'stg' => $prestudent_status->stg_bezeichnung,
'Orgform' => $prestudent_status->orgform,
'lvzuweisungLink' => site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id),
'lvzuweisungLinkCIS' => CIS_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id
'lvzuweisungLink' => $lvzuweisungLink
],
$email,
$this->_ci->p->t('studierendenantrag', 'mail_subject_W_New')
+4 -2
View File
@@ -35,10 +35,12 @@ class PrestudentLib
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null, $statusgrund_kurzbz = null, $datum = null, $bestaetigtam = null)
public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null, $statusgrund_kurzbz = null, $datum = null, $bestaetigtam = null, $bestaetigtvon = null)
{
if (!$insertvon)
$insertvon = getAuthUID();
if (!$bestaetigtvon)
$bestaetigtvon = $insertvon;
$result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id, $studiensemester_kurzbz);
if (isError($result))
@@ -79,7 +81,7 @@ class PrestudentLib
'insertamum' => date('c'),
'orgform_kurzbz'=> $prestudent_status->orgform_kurzbz,
'studienplan_id'=> $prestudent_status->studienplan_id,
'bestaetigtvon' => $insertvon,
'bestaetigtvon' => $bestaetigtvon,
'bestaetigtam' => $bestaetigtam
]);
@@ -1,6 +1,7 @@
<?php
namespace vertragsbestandteil;
use Exception;
use vertragsbestandteil\Vertragsbestandteil;
use vertragsbestandteil\VertragsbestandteilFactory;
@@ -27,10 +28,25 @@ class VertragsbestandteilFunktion extends Vertragsbestandteil
$this->CI = get_instance();
$this->CI->load->model('person/Benutzerfunktion_model',
'BenutzerfunktionModel');
$this->CI->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model',
'VertragsbestandteilFunktionModel');
$this->CI->load->library('vertragsbestandteil/VertragsbestandteilLib',
null, 'VertragsbestandteilLib');
}
public function isDirty()
{
$isdirty = parent::isDirty();
if( !$isdirty ) {
$bf = $this->loadBenutzerfunktion($this->getBenutzerfunktion_id());
if( !$this->areVbAndBfInSync($bf) )
{
$isdirty = true;
}
}
return $isdirty;
}
public function beforePersist()
{
if( isset($this->benutzerfunktion_id) && intval($this->benutzerfunktion_id) > 0 )
@@ -83,10 +99,10 @@ class VertragsbestandteilFunktion extends Vertragsbestandteil
protected function isBefore($a, $b)
{
if($b === null) {
if($a === null) {
return false;
}
elseif($a === null) {
elseif($b === null) {
return true;
}
else {
@@ -121,10 +137,17 @@ class VertragsbestandteilFunktion extends Vertragsbestandteil
new \DateTimeZone('Europe/Vienna'));
$daybeforevon->sub(new \DateInterval('P1D'));
if( $this->isBefore($this->getVon(), $bf->datum_von) &&
$this->isAfter($this->getBis(), $bf->datum_bis) )
if( $this->isBefore($bf->datum_von, $this->getVon()) &&
$this->isBefore($bf->datum_von, $this->getBis()) )
{
$this->updateBenutzerfunktion($bf, $this->getVon(), $this->getBis());
$data = (object) array(
'mitarbeiter_uid' => $bf->uid,
'funktion' => $bf->funktion_kurzbz,
'orget' => $bf->oe_kurzbz
);
$this->createBenutzerfunktionData($data);
$bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert());
$this->setBenutzerfunktion_id($bfid);
}
elseif( $this->isBefore($bf->datum_von, $this->getVon()) &&
$this->isAfter($this->getBis(), $bf->datum_von) )
@@ -136,20 +159,12 @@ class VertragsbestandteilFunktion extends Vertragsbestandteil
'orget' => $bf->oe_kurzbz
);
$this->createBenutzerfunktionData($data);
$bfid = $this->insertBenutzerfunktion($this->benutzerfunktiondata);
$bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert());
$this->setBenutzerfunktion_id($bfid);
}
elseif( $this->isBefore($bf->datum_von, $this->getVon()) &&
$this->isBefore($bf->datum_von, $this->getBis()) )
else
{
$data = (object) array(
'mitarbeiter_uid' => $bf->uid,
'funktion' => $bf->funktion_kurzbz,
'orget' => $bf->oe_kurzbz
);
$this->createBenutzerfunktionData($data);
$bfid = $this->insertBenutzerfunktion($this->benutzerfunktiondata);
$this->setBenutzerfunktion_id($bfid);
$this->updateBenutzerfunktion($bf, $this->getVon(), $this->getBis());
}
}
}
@@ -211,7 +226,7 @@ class VertragsbestandteilFunktion extends Vertragsbestandteil
return;
}
$bfid = $this->insertBenutzerfunktion($this->benutzerfunktiondata);
$bfid = $this->insertBenutzerfunktion($this->getBenutzerfunktionData4Insert());
$this->setBenutzerfunktion_id($bfid);
}
@@ -275,6 +290,25 @@ EOTXT;
return $this;
}
protected function getBenutzerfunktionData4Insert()
{
if( null === $this->benutzerfunktiondata ) {
return null;
}
$benutzerfunktiondata = (object) array(
'funktion_kurzbz' => $this->benutzerfunktiondata->funktion_kurzbz,
'oe_kurzbz' => $this->benutzerfunktiondata->oe_kurzbz,
'uid' => $this->benutzerfunktiondata->uid,
'datum_von' => $this->getVon(),
'datum_bis' => $this->getBis(),
'insertamum' => strftime('%Y-%m-%d %H:%M:%S'),
'insertvon' => getAuthUID()
);
return $benutzerfunktiondata;
}
protected function createBenutzerfunktionData($data)
{
if( empty($data->funktion) || empty($data->orget) )
@@ -285,11 +319,7 @@ EOTXT;
$this->benutzerfunktiondata = (object) array(
'funktion_kurzbz' => $data->funktion,
'oe_kurzbz' => $data->orget,
'uid' => $data->mitarbeiter_uid,
'datum_von' => $this->getVon(),
'datum_bis' => $this->getBis(),
'insertamum' => strftime('%Y-%m-%d %H:%M:%S'),
'insertvon' => getAuthUID()
'uid' => $data->mitarbeiter_uid
);
}
@@ -307,7 +337,8 @@ EOTXT;
'oe_bezeichnung' => $data->oe_bezeichnung,
'oe_kurzbz_sap' => $data->oe_kurzbz_sap,
'oe_typ_kurzbz' => $data->oe_typ_kurzbz,
'oe_typ_bezeichnung' => $data->oe_typ_bezeichnung
'oe_typ_bezeichnung' => $data->oe_typ_bezeichnung,
'uid' => $data->mitarbeiter_uid
);
}
@@ -319,6 +350,20 @@ EOTXT;
. 'Funktion und eine Organisationseinheit müssen ausgewählt sein.';
}
// TODO check if Benutzerfunktion is assigned to another vb
if( intval($this->benutzerfunktion_id) > 0 )
{
if ( $this->CI->VertragsbestandteilFunktionModel
->isBenutzerfunktionAlreadyAttachedToAnotherVB(
$this->benutzerfunktion_id,
$this->getVertragsbestandteil_id()) )
{
$this->validationerrors[] = 'Die Benutzerfunktion ist bereits '
. 'mit einem anderen Vertragsbestandteil verknüpft und kann '
. 'nicht mehrfach verknüft werden.';
}
}
return parent::validate();
}
}
@@ -86,16 +86,24 @@ EOTXT;
public function validate()
{
if( !(filter_var($this->wochenstunden, FILTER_VALIDATE_FLOAT,
if( false === filter_var($this->wochenstunden, FILTER_VALIDATE_FLOAT,
array(
'options' => array(
'min_range' => 0,
'max_range' => 100
)
)
)) ) {
) ) {
$this->validationerrors[] = 'Stunden muss eine Kommazahl im Bereich 0 bis 100 sein.';
}
else
{
if( floatval($this->wochenstunden) < floatval('0.01') &&
$this->teilzeittyp_kurzbz !== 'altersteilzeit' )
{
$this->validationerrors[] = '0 Wochenstunden ist nur in Kombination mit Altersteilzeit zulässig.';
}
}
return parent::validate();
}
@@ -222,9 +222,9 @@ class Pruefung_model extends DB_Model
$this->withDetailsForStudierendenAntrag();
if ($maxDate)
$this->db->where("p.datum < ", $maxDate->format('c'));
$this->db->where("p.datum <= ", $maxDate->format('Y-m-d'));
if ($minDate)
$this->db->where("p.datum > ", $minDate->format('c'));
$this->db->where("p.datum > ", $minDate->format('Y-m-d'));
$this->db->where("b.aktiv", true);
@@ -144,10 +144,15 @@ class Mitarbeiter_model extends DB_Model
* Checks if alias exists
* @param $kurzbz
*/
public function kurzbzExists($kurzbz)
public function kurzbzExists($kurzbz, $uid=null)
{
$this->addSelect('1');
$result = $this->loadWhere(array('kurzbz' => $kurzbz));
$where = array('kurzbz' => $kurzbz);
if ($uid != null)
{
$where['mitarbeiter_uid<>'] = $uid;
}
$result = $this->loadWhere($where);
if (isSuccess($result))
{
@@ -171,7 +176,6 @@ class Mitarbeiter_model extends DB_Model
*/
public function generateKurzbz($uid)
{
$kurzbz = '';
$this->addLimit(1);
$this->addSelect('vorname, nachname');
$this->addJoin('public.tbl_benutzer', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid');
@@ -181,25 +185,35 @@ class Mitarbeiter_model extends DB_Model
if (hasData($nameresult))
{
$kurzbzdata = getData($nameresult);
$nachname_clean = sanitizeProblemChars($kurzbzdata[0]->nachname);
$vorname_clean = sanitizeProblemChars($kurzbzdata[0]->vorname);
$genKurzbz = $this->generateKurzbzHelper($kurzbzdata[0]->vorname, $kurzbzdata[0]->nachname);
for ($nn = 6, $vn = 2; $nn != 0; $nn--, $vn++)
{
$kurzbz = mb_substr($nachname_clean, 0, $nn);
$kurzbz .= mb_substr($vorname_clean, 0, $vn);
return $genKurzbz;
}
return error('No Kurzbezeichnung could be generated');
}
$kurzbzexists = $this->kurzbzExists($kurzbz);
public function generateKurzbzHelper($vorname, $nachname)
{
$nachname_clean = sanitizeProblemChars($nachname);
$vorname_clean = sanitizeProblemChars($vorname);
$kurzbz = '';
if (hasData($kurzbzexists) && !getData($kurzbzexists)[0])
break;
}
for ($nn = 6, $vn = 2; $nn != 0; $nn--, $vn++)
{
$kurzbz = mb_substr($nachname_clean, 0, $nn);
$kurzbz .= mb_substr($vorname_clean, 0, $vn);
$kurzbzexists = $this->kurzbzExists($kurzbz);
if (hasData($kurzbzexists) && getData($kurzbzexists)[0])
return error('No Kurzbezeichnung could be generated');
if (hasData($kurzbzexists) && !getData($kurzbzexists)[0])
break;
}
$kurzbzexists = $this->kurzbzExists($kurzbz);
if (hasData($kurzbzexists) && getData($kurzbzexists)[0])
return error('No Kurzbezeichnung could be generated');
return success($kurzbz);
}
}
@@ -108,7 +108,30 @@ class Dienstverhaeltnis_model extends DB_Model
public function isOverlappingExistingDV($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $dvid=null)
{
$dvidclause = (intval($dvid) > 0) ? 'AND dv.dienstverhaeltnis_id != ' . $dvid : '';
$params = array($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $von, $bis);
$dvidclause = '';
if (intval($dvid) > 0)
{
$params = array_merge($params, array($dvid, $dvid));
$dvidclause = <<<EODVIDC
AND (
SELECT
COUNT(*) AS karenzen
FROM
hr.tbl_vertragsbestandteil vb
WHERE
vb.dienstverhaeltnis_id = ?
AND
vb.vertragsbestandteiltyp_kurzbz = 'karenz'
AND
dv.von::date >= COALESCE(vb.von, '1970-01-01'::date)
AND
COALESCE(dv.bis::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31')
) = 0
AND dv.dienstverhaeltnis_id != ?
EODVIDC;
}
$query = <<<EOSQL
SELECT
@@ -131,7 +154,7 @@ class Dienstverhaeltnis_model extends DB_Model
FROM
hr.tbl_vertragsbestandteil vb
WHERE
vb.dienstverhaeltnis_id = dv.dienstverhaeltnis_id
vb.dienstverhaeltnis_id = dv.dienstverhaeltnis_id
AND
vb.vertragsbestandteiltyp_kurzbz = 'karenz'
AND
@@ -142,8 +165,7 @@ class Dienstverhaeltnis_model extends DB_Model
{$dvidclause}
EOSQL;
$ret = $this->execReadOnlyQuery($query,
array($mitarbeiter_uid, $oe_kurzbz, $von, $bis, $von, $bis));
$ret = $this->execReadOnlyQuery($query, $params);
if( ($dvcount = getData($ret)) && ($dvcount[0]->dvcount > 0) ) {
return true;
@@ -15,4 +15,21 @@ class VertragsbestandteilFunktion_model extends DB_Model
$this->dbTable = 'hr.tbl_vertragsbestandteil_funktion';
$this->pk = 'vertragsbestandteil_id';
}
public function isBenutzerfunktionAlreadyAttachedToAnotherVB($benutzerfunktion_id, $vertragsbestandteil_id)
{
$where = array('benutzerfunktion_id' => $benutzerfunktion_id);
if( intval($vertragsbestandteil_id) > 0 )
{
$where['vertragsbestandteil_id != '] = $vertragsbestandteil_id;
}
$this->addSelect('count(*) AS vbscount');
$res = $this->loadWhere($where);
if(isError($res))
{
throw new Exception('failed to check if benutzerfunktionid is already attached to another vertragsbestanteil');
}
$count = (getData($res))[0]->vbscount;
return $count > 0;
}
}
@@ -22,8 +22,9 @@ class Vertragsbestandteil_model extends DB_Model
$sql = <<<EOSQL
SELECT
v.*,
bf.funktion_kurzbz, funktion.beschreibung funktion_bezeichnung,
oe.oe_kurzbz, oe.bezeichnung oe_bezeichnung, sap.oe_kurzbz_sap,
bf.funktion_kurzbz, bf.uid AS mitarbeiter_uid,
funktion.beschreibung AS funktion_bezeichnung,
oe.oe_kurzbz, oe.bezeichnung AS oe_bezeichnung, sap.oe_kurzbz_sap,
oet.organisationseinheittyp_kurzbz AS oe_typ_kurzbz, oet.bezeichnung AS oe_typ_bezeichnung,
ft.freitexttyp_kurzbz, ft.titel, ft.anmerkung,
f.benutzerfunktion_id,
+3 -3
View File
@@ -35,13 +35,13 @@ $this->load->view(
antrag-type="<?= $antrag_type; ?>"
studierendenantrag-id="<?= $studierendenantrag_id; ?>"
v-model:info-array="infoArray"
v-model:status-msg="statusMsg"
v-model:status-severity="statusSeverity"
v-model:status-msg="status.msg"
v-model:status-severity="status.severity"
>
</studierendenantrag-antrag>
</div>
<div class="col-sm-4 mb-3">
<studierendenantrag-status :msg="statusMsg" :severity="statusSeverity"></studierendenantrag-status>
<studierendenantrag-status :msg="status.msg" :severity="status.severity"></studierendenantrag-status>
<studierendenantrag-infoblock :infos="infoArray"></studierendenantrag-infoblock>
</div>
</div>
@@ -82,7 +82,7 @@ $this->load->view(
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<pre><?= $antrag->grund; ?></pre>
<textarea class="form-control" style="width: 100%; height: 250px;" readonly><?= $antrag->grund; ?></textarea>
</div>
</div>
</div>
+3 -3
View File
@@ -121,15 +121,15 @@ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<td><input type="text" name="sprache" id="sprache" value="'.$db->convert_html_chars($row_zd->sprache).'" size="10" maxlength="8" readonly="readonly"></td>
</tr>
<tr>
<td width="30%"><b>'.$p->t('abgabetool/kontrollierteSchlagwoerter').':*</b></td>
<td width="30%"><b>'.$p->t('abgabetool/kontrollierteSchlagwoerter').':</b></td>
<td width="40%"><input type="text" name="kontrollschlagwoerter" id="kontrollschlagwoerter" value="'.$db->convert_html_chars($row_zd->kontrollschlagwoerter).'" size="60" maxlength="150" readonly="readonly"></td>
</tr>
<tr>
<td><b>'.$p->t('abgabetool/deutscheSchlagwoerter').': </b></td>
<td><b>'.$p->t('abgabetool/deutscheSchlagwoerter').':* </b></td>
<td><input type="text" name="schlagwoerter" value="'.$db->convert_html_chars($row_zd->schlagwoerter).'" size="60" maxlength="150" readonly="readonly"></td>
</tr>
<tr>
<td><b>'.$p->t('abgabetool/englischeSchlagwoerter').': </b></td>
<td><b>'.$p->t('abgabetool/englischeSchlagwoerter').':* </b></td>
<td><input type="text" name="schlagwoerter_en" value="'.$db->convert_html_chars($row_zd->schlagwoerter_en).'" size="60" maxlength="150" readonly="readonly"></td>
</tr>
<tr>
+3 -26
View File
@@ -64,7 +64,6 @@ if(!isset($_POST['uid']))
$fixtermin = false;
$datum = '01.01.1980';
$kurzbz = '';
$kontrollschlagwoerter = '';
$schlagwoerter = '';
$schlagwoerter_en = '';
$abstract = '';
@@ -88,7 +87,6 @@ else
$kurzbz = (isset($_POST['kurzbz'])?$_POST['kurzbz']:'');
$betreuer = (isset($_POST['betreuer'])?$_POST['betreuer']:'-1');
$sprache = (isset($_POST['sprache'])?$_POST['sprache']:'German');
$kontrollschlagwoerter = (isset($_POST['kontrollschlagwoerter'])?$_POST['kontrollschlagwoerter']:'-1');
$schlagwoerter = (isset($_POST['schlagwoerter'])?$_POST['schlagwoerter']:'-1');
$schlagwoerter_en = (isset($_POST['schlagwoerter_en'])?$_POST['schlagwoerter_en']:'-1');
$abstract = (isset($_POST['abstract'])?$_POST['abstract']:'-1');
@@ -211,23 +209,7 @@ if($command=='add')
{
//zusätzliche Daten bearbeiten
//Check der Eingabedaten
if(strlen($kontrollschlagwoerter)<1)
{
$error=true;
}
if(mb_strlen($kontrollschlagwoerter)>=150)
{
$kontrollschlagwoerter = mb_substr($kontrollschlagwoerter, 0, 146).'...';
}
if(strlen($abstract)<1)
{
$error=true;
}
if(strlen($abstract_en)<1)
{
$error=true;
}
if($seitenanzahl<1)
if((strlen($schlagwoerter) < 1) || (strlen($schlagwoerter_en) < 1) || (strlen($abstract) < 1) || (strlen($abstract_en) < 1) || ($seitenanzahl < 1))
{
$error=true;
}
@@ -237,7 +219,6 @@ if($command=='add')
seitenanzahl = ".$db->db_add_param($seitenanzahl).",
abgabedatum = now(),
sprache = ".$db->db_add_param($sprache).",
kontrollschlagwoerter = ".$db->db_add_param($kontrollschlagwoerter).",
schlagwoerter_en = ".$db->db_add_param($schlagwoerter_en).",
schlagwoerter = ".$db->db_add_param($schlagwoerter).",
abstract = ".$db->db_add_param($abstract).",
@@ -413,12 +394,9 @@ if($command=="update" && $error!=true)
$htmlstr .= "</SELECT> \n";
}
$htmlstr .= "</td></tr>\n";
$htmlstr .= '<tr><td width="30%"><b>'.$p->t('abgabetool/kontrollierteSchlagwoerter').':*</b></td>
<td width="40%"><input type="text" name="kontrollschlagwoerter" id="kontrollschlagwoerter" value="'.$db->convert_html_chars($kontrollschlagwoerter).'" size="60" maxlength="150"></td>
<td width="30%" align="left"><input type="button" name="SWD" value=" SWD " onclick="window.open(\'swd.php\')"></td></tr>'."\n";
$htmlstr .= '<tr><td><b>'.$p->t('abgabetool/deutscheSchlagwoerter').':</b></td>
$htmlstr .= '<tr><td><b>'.$p->t('abgabetool/deutscheSchlagwoerter').':*</b></td>
<td><input type="text" name="schlagwoerter" value="'.$db->convert_html_chars($schlagwoerter).'" size="60" maxlength="150"></td></tr>'."\n";
$htmlstr .= '<tr><td><b>'.$p->t('abgabetool/englischeSchlagwoerter').':</b></td>
$htmlstr .= '<tr><td><b>'.$p->t('abgabetool/englischeSchlagwoerter').':*</b></td>
<td><input type="text" name="schlagwoerter_en" value="'.$db->convert_html_chars($schlagwoerter_en).'" size="60" maxlength="150"></td></tr>'."\n";
$htmlstr .= '<tr><td valign="top"><b>'.$p->t('abgabetool/abstract').' </b>'.$p->t('abgabetool/maxZeichen').':*</td>
<td><textarea name="abstract" cols="46" rows="7">'.$db->convert_html_chars($abstract).'</textarea></td></tr>'."\n";
@@ -657,7 +635,6 @@ if($command!="add")
$htmlstr .= '<input type="hidden" name="uid" value="'.$db->convert_html_chars($uid).'">'."\n";
$htmlstr .= '<input type="hidden" name="betreuer" value="'.$db->convert_html_chars($betreuer).'">'."\n";
$htmlstr .= '<input type="hidden" name="command" value="update">'."\n";
$htmlstr .= '<input type="hidden" name="kontrollschlagwoerter" value="'.$db->convert_html_chars($kontrollschlagwoerter).'">'."\n";
$htmlstr .= '<input type="hidden" name="schlagwoerter" value="'.$db->convert_html_chars($schlagwoerter).'">'."\n";
$htmlstr .= '<input type="hidden" name="schlagwoerter_en" value="'.$db->convert_html_chars($schlagwoerter_en).'">'."\n";
$htmlstr .= '<input type="hidden" name="abstract" value="'.$db->convert_html_chars($abstract).'">'."\n";
-11
View File
@@ -1,11 +0,0 @@
<?php
$url = "https://ognd.bsz-bw.de/";
$zielfeld = "kontrollschlagwoerter";
$url = $url."?zielfeld=".$zielfeld;
header('Content-Type: text/html; charset=utf-8');
$content = file_get_contents($url);
if($content)
print $content;
else
echo "Der Schlagwortdienst ist derzeit nicht erreichbar. Bitte füllen Sie die Schlagwörter manuell aus um den Upload abzuschließen";
?>
+44 -8
View File
@@ -172,9 +172,6 @@ function searchPerson($searchItems)
';
foreach($bn->result as $row)
{
$bisverwendung = new bisverwendung();
$bisverwendung->getLastAktVerwendung($row->uid);
echo '<tr>';
//echo '<td>',$row->titelpre,'</td>';
echo '<td>',$row->anrede,'</td>';
@@ -199,7 +196,7 @@ function searchPerson($searchItems)
echo '<a href="../profile/index.php?uid=',$row->uid,'" title="',$row->titelpre,' ',$row->vorname,' ',$row->wahlname,' ',$row->nachname,' ',$row->titelpost,'">',$row->nachname,'</a>';
if($row->aktiv==false)
echo '<span style="color: red"> (ausgeschieden)</span>';
elseif($bisverwendung->beschausmasscode=='5')
elseif(isKarenziert($row->uid))
echo '<span style="color: orange"> (karenziert)</span>';
echo '</td>';
//echo '<td>',$row->titelpost,'</td>';
@@ -262,6 +259,47 @@ function searchPerson($searchItems)
else
return false;
}
function isKarenziert($uid)
{
global $db;
if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT)
{
$qry ="
SELECT
1
FROM
hr.tbl_dienstverhaeltnis
JOIN hr.tbl_vertragsbestandteil USING(dienstverhaeltnis_id)
JOIN hr.tbl_vertragsbestandteil_karenz USING(vertragsbestandteil_id)
WHERE
tbl_dienstverhaeltnis.mitarbeiter_uid=".$db->db_add_param($uid)."
AND tbl_vertragsbestandteil.von<=now() AND tbl_vertragsbestandteil.bis>=now()
";
if($result = $db->db_query($qry))
{
if($db->db_num_rows($result)>0)
return true;
else
return false;
}
else
return false;
}
else
{
$bisverwendung = new bisverwendung();
$bisverwendung->getLastAktVerwendung($uid);
if($bisverwendung->beschausmasscode=='5')
return true;
else
return false;
}
}
function searchOE($searchItems)
{
global $db, $p, $noalias;
@@ -332,8 +370,6 @@ function searchOE($searchItems)
$mitarbeiter->load($bf->uid);
$kontakt = new kontakt();
$kontakt->loadFirmaKontakttyp($mitarbeiter->standort_id,'telefon');
$bisverwendung = new bisverwendung();
$bisverwendung->getLastAktVerwendung($bf->uid);
$benutzer = new benutzer($bf->uid);
if ($benutzer->bnaktiv)
{
@@ -341,8 +377,8 @@ function searchOE($searchItems)
echo '<td>'.$person->vorname.'</td>';
echo '<td><a href="../profile/index.php?uid=',$person->uid,'" title="',$person->titelpre,' ',$person->vorname,' ',$person->nachname,' ',$person->titelpost,'">',$person->nachname,'</a></td>';
echo '<td>'.$bf->bezeichnung;
if($bisverwendung->beschausmasscode=='5')
echo '<span style="color: orange"> (karenziert)</span>';
if( isKarenziert($bf->uid))
echo '<span style="color: orange"> (karenziert)</span>';
echo '</td>';
// Display phone number
+5
View File
@@ -322,4 +322,9 @@ define ('ZAHLUNGSBESTAETIGUNG_ZAHLUNGSREFERENZ_ANZEIGEN', false);
define('DOCSBOX_ENABLED', false);
// Aktiviert Abfragen auf die Dienstverhaeltnisse im HR Schema anstatt auf die BIS-Verwendung
// Uebergangsphase bis zur entfernung der BIS-Verwendungen
// (true | false)
define('DIENSTVERHAELTNIS_SUPPORT', false);
?>
@@ -26,7 +26,6 @@ require_once('../../include/lehreinheitmitarbeiter.class.php');
require_once('../../include/lehreinheit.class.php');
require_once('../../include/projektbetreuer.class.php');
require_once('../../include/projektarbeit.class.php');
require_once('../../include/bisverwendung.class.php');
require_once('../../include/studiensemester.class.php');
require_once('../../include/phrasen.class.php');
require_once('../../include/benutzerberechtigung.class.php');
+8 -3
View File
@@ -2,6 +2,7 @@ import StudierendenantragAntrag from "../../components/Studierendenantrag/Antrag
import StudierendenantragStatus from "../../components/Studierendenantrag/Status.js";
import StudierendenantragInfoblock from "../../components/Studierendenantrag/Infoblock.js";
import VueDatePicker from "../../components/vueDatepicker.js.php";
import Phrasen from '../../plugin/Phrasen.js';
const app = Vue.createApp({
components: {
@@ -12,10 +13,14 @@ const app = Vue.createApp({
},
data() {
return {
statusMsg: "",
statusSeverity: "",
status: {
msg: '',
severity: ''
},
infoArray: []
};
}
});
app.mount('#wrapper');
app
.use(Phrasen)
.mount('#wrapper');
+5 -1
View File
@@ -1,8 +1,12 @@
import StudierendenantragLeitung from '../../../components/Studierendenantrag/Leitung.js';
import Phrasen from '../../../plugin/Phrasen.js';
const app = Vue.createApp({
components: {
StudierendenantragLeitung
}
});
app.use(primevue.config.default,{zIndex: {overlay: 9999}}).mount('#wrapper');
app
.use(Phrasen)
.use(primevue.config.default,{zIndex: {overlay: 9999}})
.mount('#wrapper');
+4 -1
View File
@@ -1,4 +1,5 @@
import LvZuweisung from '../../../components/Studierendenantrag/Lvzuweisung.js';
import Phrasen from '../../../plugin/Phrasen.js';
const app = Vue.createApp({
components: {
@@ -10,4 +11,6 @@ const app = Vue.createApp({
}
}
});
app.mount('#wrapper');
app
.use(Phrasen)
.mount('#wrapper');
+4 -1
View File
@@ -1,8 +1,11 @@
import LvPopup from '../../../components/Studierendenantrag/Leitung/LvPopup.js';
import Phrasen from '../../../plugin/Phrasen.js';
const app = Vue.createApp({
components: {
LvPopup
}
});
app.mount('#wrapper');
app
.use(Phrasen)
.mount('#wrapper');
+3
View File
@@ -1,3 +1,5 @@
import Phrasen from '../../plugin/Phrasen.js';
export default {
data: () => ({
modal: null
@@ -86,6 +88,7 @@ export default {
}
});
const wrapper = document.createElement("div");
instance.use(Phrasen); // TODO(chris): find a more dynamic way
instance.mount(wrapper);
document.body.appendChild(wrapper);
});
@@ -2,7 +2,6 @@ import StudierendenantragAbmeldung from './Form/Abmeldung.js';
import StudierendenantragAbmeldungStgl from './Form/AbmeldungStgl.js';
import StudierendenantragUnterbrechung from './Form/Unterbrechung.js';
import StudierendenantragWiederholung from './Form/Wiederholung.js';
import Phrasen from '../../mixins/Phrasen.js';
export default {
components: {
@@ -11,9 +10,6 @@ export default {
StudierendenantragUnterbrechung,
StudierendenantragWiederholung
},
mixins: [
Phrasen
],
emits: [
'update:infoArray',
'update:statusMsg',
@@ -37,13 +33,13 @@ export default {
return 'Studierendenantrag' + this.antragType;
},
infoText() {
return this.p.t('studierendenantrag/info_' + this.antragType + '_' + this.status);
return this.$p.t('studierendenantrag/info_' + this.antragType + '_' + this.status);
}
},
template: `
<div class="studierendenantrag-antrag card">
<div class="card-header">
{{p.t('studierendenantrag', 'title_' + antragType)}}
{{$p.t('studierendenantrag', 'title_' + antragType)}}
</div>
<div v-if="infoText && infoText.substr(0, 9) != '<< PHRASE'" class="alert alert-primary m-3" role="alert" v-html="infoText">
</div>
@@ -1,5 +1,4 @@
import {CoreFetchCmpt} from '../../Fetch.js';
import Phrasen from '../../../mixins/Phrasen.js';
var _uuid = 0;
@@ -7,9 +6,6 @@ export default {
components: {
CoreFetchCmpt
},
mixins: [
Phrasen
],
emits: [
'setInfos',
'setStatus'
@@ -56,7 +52,7 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
@@ -67,7 +63,7 @@ export default {
createAntrag() {
bootstrap.Modal.getOrCreateInstance(this.$refs.modal).hide();
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_saving')})),
severity: 'warning'
});
this.saving = true;
@@ -93,7 +89,7 @@ export default {
this.errors.default.push(result.data.retval[k]);
}
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_error')})),
severity: 'danger'
});
}
@@ -104,13 +100,13 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
else
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_open')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_open')})),
severity:'success'
});
}
@@ -120,7 +116,7 @@ export default {
},
cancelAntrag() {
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelling')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_cancelling')})),
severity: 'warning'
});
this.saving = true;
@@ -144,7 +140,7 @@ export default {
this.errors.default.push(result.data.retval[k]);
}
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_error')})),
severity:'danger'
});
}
@@ -156,13 +152,13 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
else
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelled')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_cancelled')})),
severity: 'danger'
});
}
@@ -183,37 +179,37 @@ export default {
</div>
<table class="table">
<tr>
<th>{{p.t('lehre', 'studiengang')}}</th>
<th>{{$p.t('lehre', 'studiengang')}}</th>
<td align="right">{{data.bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'organisationsform')}}</th>
<th>{{$p.t('lehre', 'organisationsform')}}</th>
<td align="right">{{data.orgform_bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<th>{{$p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<td align="right">{{data.name}}</td>
</tr>
<tr>
<th>{{p.t('person', 'personenkennzeichen')}}</th>
<th>{{$p.t('person', 'personenkennzeichen')}}</th>
<td align="right">{{data.matrikelnr}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'studienjahr')}}</th>
<th>{{$p.t('lehre', 'studienjahr')}}</th>
<td align="right">{{data.studienjahr_kurzbz}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'studiensemester')}}</th>
<th>{{$p.t('lehre', 'studiensemester')}}</th>
<td align="right">{{data.studiensemester_kurzbz}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'semester')}}</th>
<th>{{$p.t('lehre', 'semester')}}</th>
<td align="right">{{data.semester}}</td>
</tr>
</table>
</div>
<div v-if="data.grund" class="mb-3">
<h5>{{p.t('studierendenantrag', 'antrag_grund')}}:</h5>
<h5>{{$p.t('studierendenantrag', 'antrag_grund')}}:</h5>
<pre>{{data.grund}}</pre>
</div>
<div v-else class="col-sm-6 mb-3">
@@ -239,7 +235,7 @@ export default {
@click="cancelAntrag"
:disabled="saving"
>
{{p.t('studierendenantrag', 'btn_cancel')}}
{{$p.t('studierendenantrag', 'btn_cancel')}}
</button>
<button
v-else-if="!data.studierendenantrag_id"
@@ -249,7 +245,7 @@ export default {
:data-bs-target="'#studierendenantrag-form-abmeldung-' + uuid + '-modal'"
:disabled="saving"
>
{{p.t('studierendenantrag', 'btn_create_Abmeldung')}}
{{$p.t('studierendenantrag', 'btn_create_Abmeldung')}}
</button>
<div
@@ -266,18 +262,18 @@ export default {
class="modal-title"
:id="'studierendenantrag-form-abmeldung-' + uuid + '-modal-label'"
>
{{p.t('studierendenantrag', 'title_Abmeldung')}}
{{$p.t('studierendenantrag', 'title_Abmeldung')}}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="p.t('ui', 'schliessen')"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="$p.t('ui', 'schliessen')"></button>
</div>
<div class="modal-body" v-html="p.t('studierendenantrag', 'warning_Abmeldung')">
<div class="modal-body" v-html="$p.t('studierendenantrag', 'warning_Abmeldung')">
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-primary"
@click="createAntrag">
{{p.t('studierendenantrag', 'btn_create_Abmeldung')}}
{{$p.t('studierendenantrag', 'btn_create_Abmeldung')}}
</button>
</div>
</div>
@@ -1,5 +1,4 @@
import {CoreFetchCmpt} from '../../Fetch.js';
import Phrasen from '../../../mixins/Phrasen.js';
var _uuid = 0;
@@ -7,9 +6,6 @@ export default {
components: {
CoreFetchCmpt
},
mixins: [
Phrasen
],
emits: [
'setInfos',
'setStatus'
@@ -30,7 +26,7 @@ export default {
},
computed: {
statusSeverity() {
switch (this.data.status)
switch (this.data?.status)
{
case 'Erstellt': return 'info';
case 'Genehmigt': return 'success';
@@ -56,7 +52,7 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
@@ -67,7 +63,7 @@ export default {
createAntrag() {
bootstrap.Modal.getOrCreateInstance(this.$refs.modal).hide();
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_saving')})),
severity: 'warning'
});
this.saving = true;
@@ -93,7 +89,7 @@ export default {
this.errors.default.push(result.data.retval[k]);
}
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_error')})),
severity: 'danger'
});
}
@@ -104,13 +100,13 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
else
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_open')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_open')})),
severity:'success'
});
}
@@ -123,7 +119,7 @@ export default {
if(event.target.value)
{
let templateT= this.p.t('studierendenantrag', event.target.value);
let templateT= this.$p.t('studierendenantrag', event.target.value);
templateText.value = templateT;
}
else
@@ -140,40 +136,40 @@ export default {
<div class="col-12">
<table class="table">
<tr>
<th>{{p.t('lehre', 'studiengang')}}</th>
<th>{{$p.t('lehre', 'studiengang')}}</th>
<td align="right">{{data.bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'organisationsform')}}</th>
<th>{{$p.t('lehre', 'organisationsform')}}</th>
<td align="right">{{data.orgform_bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<th>{{$p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<td align="right">{{data.name}}</td>
</tr>
<tr>
<th>{{p.t('person', 'personenkennzeichen')}}</th>
<th>{{$p.t('person', 'personenkennzeichen')}}</th>
<td align="right">{{data.matrikelnr}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'studienjahr')}}</th>
<th>{{$p.t('lehre', 'studienjahr')}}</th>
<td align="right">{{data.studienjahr_kurzbz}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'studiensemester')}}</th>
<th>{{$p.t('lehre', 'studiensemester')}}</th>
<td align="right">{{data.studiensemester_kurzbz}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'semester')}}</th>
<th>{{$p.t('lehre', 'semester')}}</th>
<td align="right">{{data.semester}}</td>
</tr>
</table>
</div>
<div v-if="data.grund" class="mb-3">
<h5>{{p.t('studierendenantrag', 'antrag_grund')}}:</h5>
<h5>{{$p.t('studierendenantrag', 'antrag_grund')}}:</h5>
<pre class="text-prewrap">{{data.grund}}</pre>
<pre class="text-prewrap">{{data?.grund}}</pre>
</div>
<div v-else class="col-sm-6 mb-3">
<label :for="'studierendenantrag-form-abmeldung-' + uuid + '-grund'" class="form-label">Grund:</label>
@@ -181,18 +177,20 @@ export default {
<select name="grundAv" @change="appendDropDownText
($event)">
<option value="" > --- bitte auswählen, sofern zutreffend ---- </option>
<option value="textLong_NichtantrittStudium">{{p.t('studierendenantrag', 'dropdown_NichtantrittStudium')}}
<option value="textLong_NichtantrittStudium">{{$p.t('studierendenantrag', 'dropdown_NichtantrittStudium')}}
</option>
<option value="textLong_ungenuegendeLeistung">{{p.t('studierendenantrag', 'dropdown_ungenuegendeLeistung')}}
<option value="textLong_ungenuegendeLeistung">{{$p.t('studierendenantrag', 'dropdown_ungenuegendeLeistung')}}
</option>
<option value="textLong_studentNichtAnwesend">{{p.t('studierendenantrag', 'dropdown_nichtAnwesend')}}
<option value="textLong_studentNichtAnwesend">{{$p.t('studierendenantrag', 'dropdown_nichtAnwesend')}}
</option>
<option value="textLong_PruefunstermineNichtEingehalten">{{p.t('studierendenantrag', 'dropdown_PruefunstermineNichtEingehalten')}}
<option value="textLong_PruefunstermineNichtEingehalten">{{$p.t('studierendenantrag', 'dropdown_PruefunstermineNichtEingehalten')}}
</option>
<option value="textLong_studentNichtGezahlt">{{p.t('studierendenantrag', 'dropdown_nichtGezahlt')}}
<option value="textLong_studentNichtGezahlt">{{$p.t('studierendenantrag', 'dropdown_nichtGezahlt')}}
</option>
<option value="textLong_plageat">{{p.t('studierendenantrag', 'dropdown_plageat')}}
<option value="textLong_plageat">{{$p.t('studierendenantrag', 'dropdown_plageat')}}
</option>
<option value="textLong_MissingZgv">{{$p.t('studierendenantrag', 'dropdown_MissingZgv')}}
</option>
</select>
</div>
<textarea
@@ -211,14 +209,14 @@ export default {
<div class="col-12 text-end">
<button
v-if="!data.studierendenantrag_id"
v-if="!data?.studierendenantrag_id"
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
:data-bs-target="'#studierendenantrag-form-abmeldung-' + uuid + '-modal'"
:disabled="saving"
>
{{p.t('studierendenantrag', 'btn_create_Abmeldung')}}
{{$p.t('studierendenantrag', 'btn_create_Abmeldung')}}
</button>
<div
ref="modal"
@@ -234,18 +232,18 @@ export default {
class="modal-title"
:id="'studierendenantrag-form-abmeldung-' + uuid + '-modal-label'"
>
{{p.t('studierendenantrag', 'title_Abmeldung')}}
{{$p.t('studierendenantrag', 'title_Abmeldung')}}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="p.t('ui', 'schliessen')"></button>
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="$p.t('ui', 'schliessen')"></button>
</div>
<div class="modal-body" v-html="p.t('studierendenantrag', 'warning_AbmeldungStgl')">
<div class="modal-body" v-html="$p.t('studierendenantrag', 'warning_AbmeldungStgl')">
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-primary"
@click="createAntrag">
{{p.t('studierendenantrag', 'btn_create_Abmeldung')}}
{{$p.t('studierendenantrag', 'btn_create_Abmeldung')}}
</button>
</div>
</div>
@@ -1,6 +1,5 @@
import {CoreFetchCmpt} from '../../Fetch.js';
import VueDatepicker from '../../vueDatepicker.js.php';
import Phrasen from '../../../mixins/Phrasen.js';
var _uuid = 0;
@@ -9,9 +8,6 @@ export default {
CoreFetchCmpt,
VueDatepicker
},
mixins: [
Phrasen
],
emits: [
'setInfos',
'setStatus'
@@ -79,7 +75,7 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
@@ -89,7 +85,7 @@ export default {
},
createAntrag() {
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_saving')})),
severity: 'warning'
});
this.saving = true;
@@ -126,7 +122,7 @@ export default {
this.errors.default.push(result.data.retval[k]);
}
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_error')})),
severity: 'danger'
});
}
@@ -137,13 +133,13 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
else
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_created')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_created')})),
severity: 'info'
});
}
@@ -153,7 +149,7 @@ export default {
},
cancelAntrag() {
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelling')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_cancelling')})),
severity: 'warning'
});
this.saving = true;
@@ -177,7 +173,7 @@ export default {
this.errors.default.push(result.data.retval[k]);
}
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_error')})),
severity: 'danger'
});
}
@@ -189,13 +185,13 @@ export default {
this.data = result.data.retval;
if (this.data.status) {
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
else
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_cancelled')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_cancelled')})),
severity: 'danger'
});
}
@@ -216,28 +212,28 @@ export default {
</div>
<table class="table">
<tr>
<th>{{p.t('lehre', 'studiengang')}}</th>
<th>{{$p.t('lehre', 'studiengang')}}</th>
<td align="right">{{data.bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'organisationsform')}}</th>
<th>{{$p.t('lehre', 'organisationsform')}}</th>
<td align="right">{{data.orgform_bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<th>{{$p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<td align="right">{{data.name}}</td>
</tr>
<tr>
<th>{{p.t('person', 'personenkennzeichen')}}</th>
<th>{{$p.t('person', 'personenkennzeichen')}}</th>
<td align="right">{{data.matrikelnr}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'studienjahr')}}</th>
<th>{{$p.t('lehre', 'studienjahr')}}</th>
<td align="right" v-if="data.studierendenantrag_id">{{data.studienjahr_kurzbz}}</td>
<td align="right" v-else>{{stsem === null ? '' : data.studiensemester[stsem].studienjahr_kurzbz}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'semester')}}</th>
<th>{{$p.t('lehre', 'semester')}}</th>
<td align="right" v-if="data.studierendenantrag_id">{{data.semester}}</td>
<td align="right" v-else>{{stsem === null ? '' : data.studiensemester[stsem].semester}}</td>
</tr>
@@ -246,7 +242,7 @@ export default {
<div class="col-sm-6 mb-3">
<label :for="'studierendenantrag-form-abmeldung-' + uuid + '-stsem'" class="form-label">
{{p.t('lehre', 'studiensemester')}}
{{$p.t('lehre', 'studiensemester')}}
</label>
<div v-if="data.studierendenantrag_id">
{{data.studiensemester_kurzbz}}
@@ -271,7 +267,7 @@ export default {
</div>
<div class="col-sm-6 mb-3">
<label class="form-label">
{{p.t('studierendenantrag', 'antrag_datum_wiedereinstieg')}}
{{$p.t('studierendenantrag', 'antrag_datum_wiedereinstieg')}}
</label>
<div v-if="data.studierendenantrag_id">
@@ -279,7 +275,7 @@ export default {
</div>
<div v-else-if="stsem === null">
<select class="form-select" disabled>
<option selected>{{p.t('ui/select_studiensemester')}}</option>
<option selected>{{$p.t('ui/select_studiensemester')}}</option>
</select>
</div>
<div v-else>
@@ -295,8 +291,8 @@ export default {
</div>
</div>
<div v-if="data.studierendenantrag_id" class="mb-3">
<h5>{{p.t('studierendenantrag', 'antrag_grund')}}:</h5>
<pre>{{data.grund}}</pre>
<h5>{{$p.t('studierendenantrag', 'antrag_grund')}}:</h5>
<textarea class="form-control" rows="5" readonly>{{data.grund}}</textarea>
</div>
<div v-else class="col-sm-6 mb-3">
<label :for="'studierendenantrag-form-abmeldung-' + uuid + '-grund'" class="form-label">Grund:</label>
@@ -316,14 +312,14 @@ export default {
<div class="col-12 mb-3">
<div v-if="data.studierendenantrag_id">
<a v-if="data.dms_id" target="_blank" :href="siteUrl + '/lehre/Antrag/Attachment/Show/' + data.dms_id"> {{p.t('studierendenantrag', 'antrag_dateianhaenge')}} </a>
<span v-else>{{p.t('studierendenantrag', 'no_attachments')}}</span>
<a v-if="data.dms_id" target="_blank" :href="siteUrl + '/lehre/Antrag/Attachment/Show/' + data.dms_id"> {{$p.t('studierendenantrag', 'antrag_dateianhaenge')}} </a>
<span v-else>{{$p.t('studierendenantrag', 'no_attachments')}}</span>
</div>
<div v-else>
<label
:for="'studierendenantrag-form-abmeldung-' + uuid + '-attachment'"
class="form-label">
{{p.t('studierendenantrag', 'antrag_dateianhaenge')}}
{{$p.t('studierendenantrag', 'antrag_dateianhaenge')}}
</label>
<input
class="form-control"
@@ -341,7 +337,7 @@ export default {
@click="createAntrag"
:disabled="saving"
>
{{p.t('studierendenantrag', 'btn_create_Unterbrechung')}}
{{$p.t('studierendenantrag', 'btn_create_Unterbrechung')}}
</button>
<button
v-else-if="data.status == 'Erstellt'"
@@ -350,7 +346,7 @@ export default {
@click="cancelAntrag"
:disabled="saving"
>
{{p.t('studierendenantrag', 'btn_cancel')}}
{{$p.t('studierendenantrag', 'btn_cancel')}}
</button>
</div>
</div>
@@ -1,6 +1,5 @@
import {CoreFetchCmpt} from '../../Fetch.js';
import VueDatepicker from '../../vueDatepicker.js.php';
import Phrasen from '../../../mixins/Phrasen.js';
var _uuid = 0;
@@ -9,9 +8,6 @@ export default {
CoreFetchCmpt,
VueDatepicker
},
mixins: [
Phrasen
],
emits: [
'setInfos',
'setStatus',
@@ -67,11 +63,11 @@ export default {
this.data = result.data.retval;
if (!this.data.status || this.data.status == 'ErsteAufforderungVersandt' || this.data.status == 'ZweiteAufforderungVersandt') {
this.data.status = 'Offen';
this.data.statustyp = this.p.t('studierendenantrag', 'status_open');
this.data.statustyp = this.$p.t('studierendenantrag', 'status_open');
}
this.$emit('update:status', this.data.status);
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
return result;
@@ -89,7 +85,7 @@ export default {
let nextState = repeat ? 'Erstellt' : 'Verzichtet';
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_saving')})),
severity: 'warning'
});
this.saving = true;
@@ -116,7 +112,7 @@ export default {
this.errors.default.push(result.data.retval[k]);
}
this.$emit('setStatus', {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.$p.t('studierendenantrag', 'status_error')})),
severity: 'danger'
});
}
@@ -129,7 +125,7 @@ export default {
this.data.status = nextState;
this.$emit('update:status', this.data.status);
this.$emit("setStatus", {
msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}),
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
severity: this.statusSeverity
});
}
@@ -143,7 +139,7 @@ export default {
},
mounted() {
this.infos = [...Array(5).keys()].map(n => ({
body: this.p.t_ref('studierendenantrag', 'infotext_Wiederholung_' + n)
body: Vue.computed(() => this.$p.t('studierendenantrag', 'infotext_Wiederholung_' + n))
}));
this.$emit('setInfos', this.infos);
},
@@ -156,27 +152,27 @@ export default {
</div>
<table class="table">
<tr>
<th>{{p.t('lehre', 'studiengang')}}</th>
<th>{{$p.t('lehre', 'studiengang')}}</th>
<td align="right">{{data.bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('lehre', 'organisationsform')}}</th>
<th>{{$p.t('lehre', 'organisationsform')}}</th>
<td align="right">{{data.orgform_bezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<th>{{$p.t('projektarbeitsbeurteilung', 'nameStudierende')}}</th>
<td align="right">{{data.name}}</td>
</tr>
<tr>
<th>{{p.t('person', 'personenkennzeichen')}}</th>
<th>{{$p.t('person', 'personenkennzeichen')}}</th>
<td align="right">{{data.matrikelnr}}</td>
</tr>
<tr>
<th>{{p.t('studierendenantrag', 'antrag_Wiederholung_pruefung')}}</th>
<th>{{$p.t('studierendenantrag', 'antrag_Wiederholung_pruefung')}}</th>
<td align="right">{{data.lvbezeichnung}}</td>
</tr>
<tr>
<th>{{p.t('studierendenantrag', 'antrag_Wiederholung_pruefung_date')}}</th>
<th>{{$p.t('studierendenantrag', 'antrag_Wiederholung_pruefung_date')}}</th>
<td align="right">{{datumPruefungFormatted}}</td>
</tr>
</table>
@@ -190,7 +186,7 @@ export default {
@click="createAntrag"
:disabled="saving"
>
{{p.t('studierendenantrag/antrag_Wiederholung_button_yes')}}
{{$p.t('studierendenantrag/antrag_Wiederholung_button_yes')}}
</button>
<!-- <button
v-if="!data.studierendenantrag_id || data.status == 'Offen'"
@@ -199,7 +195,7 @@ export default {
@click="cancelAntrag"
:disabled="saving"
>
{{p.t('studierendenantrag/antrag_Wiederholung_button_no')}}
{{$p.t('studierendenantrag/antrag_Wiederholung_button_no')}}
</button>-->
</div>
</div>
@@ -5,7 +5,6 @@ import GrundPopup from './Leitung/GrundPopup.js';
import LvPopup from './Leitung/LvPopup.js';
import BsAlert from '../Bootstrap/Alert.js';
import FhcLoader from '../Loader.js';
import Phrasen from '../../mixins/Phrasen.js';
export default {
components: {
@@ -14,7 +13,6 @@ export default {
LeitungActions,
FhcLoader
},
mixins: [Phrasen],
props: {
stgL: Array,
stgA: Array
@@ -79,7 +77,7 @@ export default {
{
let countAntrage = 0;
LvPopup
.popup(this.p.t('studierendenantrag','title_show_lvs', currentAntrag), {
.popup(this.$p.t('studierendenantrag','title_show_lvs', currentAntrag), {
antragId: currentAntrag.studierendenantrag_id,
footer: true,
dialogClass: 'modal-lg',
@@ -128,7 +126,7 @@ export default {
var currentAntrag = antraege.pop();
if (currentAntrag) {
GrundPopup
.popup(this.p.t('studierendenantrag', 'title_grund', {id: currentAntrag.studierendenantrag_id}), {
.popup(this.$p.t('studierendenantrag', 'title_grund', {id: currentAntrag.studierendenantrag_id}), {
countRemaining: antraege.length
})
.then(result => {
@@ -211,7 +209,7 @@ export default {
var currentAntrag = antraege.pop();
if (currentAntrag) {
GrundPopup
.popup(this.p.t('studierendenantrag', 'title_grund', {id: currentAntrag.studierendenantrag_id}), {
.popup(this.$p.t('studierendenantrag', 'title_grund', {id: currentAntrag.studierendenantrag_id}), {
countRemaining : antraege.length,
optional: true
})
@@ -1,13 +1,11 @@
import ActionsNew from './Actions/New.js';
import ActionsColumns from './Actions/Columns.js';
import Phrasen from '../../../mixins/Phrasen.js';
export default {
components: {
ActionsNew,
ActionsColumns
},
mixins: [Phrasen],
props: {
selectedData: Array,
columns: Array,
@@ -67,17 +65,17 @@ export default {
<div class="studierendenantrag-leitung-actions fhc-table-actions d-flex flex-wrap justify-content-between mb-2">
<div class="d-flex align-items-center gap-2">
<actions-new @reload="$emit('reload')"></actions-new>
<button type="button" class="btn btn-outline-secondary" @click="$emit('reload')" :title="p.t('table','reload')">
<button type="button" class="btn btn-outline-secondary" @click="$emit('reload')" :title="$p.t('table','reload')">
<i class="fa-solid fa-rotate-right"></i>
</button>
<span>{{p.t('table', 'with_selected', {count: selectedData.length})}}</span>
<button v-if="stgL.length" :disabled="!selectedCanBeApproved" type="button" class="btn btn-outline-secondary" @click="$emit('action:approve')">{{p.t('studierendenantrag', 'btn_approve')}}</button>
<button v-if="stgL.length" :disabled="!selectedCanBeRejected" type="button" class="btn btn-outline-secondary" @click="$emit('action:reject')">{{p.t('studierendenantrag', 'btn_reject')}}</button>
<button v-if="stgA.length" :disabled="!selectedCanBeReopened" type="button" class="btn btn-outline-secondary" @click="$emit('action:reopen')">{{p.t('studierendenantrag', 'btn_reopen')}}</button>
<span>{{$p.t('table', 'with_selected', {count: selectedData.length})}}</span>
<button v-if="stgL.length" :disabled="!selectedCanBeApproved" type="button" class="btn btn-outline-secondary" @click="$emit('action:approve')">{{$p.t('studierendenantrag', 'btn_approve')}}</button>
<button v-if="stgL.length" :disabled="!selectedCanBeRejected" type="button" class="btn btn-outline-secondary" @click="$emit('action:reject')">{{$p.t('studierendenantrag', 'btn_reject')}}</button>
<button v-if="stgA.length" :disabled="!selectedCanBeReopened" type="button" class="btn btn-outline-secondary" @click="$emit('action:reopen')">{{$p.t('studierendenantrag', 'btn_reopen')}}</button>
</div>
<div>
<button type="button" class="btn btn-link" data-bs-toggle="collapse" href="#columns" :title="p.t('table','spaltenEinAusblenden')"><i class="fa fa-table-columns"></i></button>
<button type="button" class="btn btn-link" @click="$emit('download')" :title="p.t('table','download')"><i class="fa fa-download"></i></button>
<button type="button" class="btn btn-link" data-bs-toggle="collapse" href="#columns" :title="$p.t('table','spaltenEinAusblenden')"><i class="fa fa-table-columns"></i></button>
<button type="button" class="btn btn-link" @click="$emit('download')" :title="$p.t('table','download')"><i class="fa fa-download"></i></button>
</div>
<div class="col-12">
<actions-columns id="columns" class="collapse" :columns="columns"></actions-columns>
@@ -6,9 +6,6 @@ export default {
toggleColumn(col) {
col.visible = !col.visible;
col.original.toggle()
},
show() {
}
},
template: `
@@ -1,15 +1,11 @@
import BsAlert from '../../../Bootstrap/Alert.js';
import BsModal from '../../../Bootstrap/Modal.js';
import Phrasen from '../../../../mixins/Phrasen.js';
export default {
components: {
BsModal,
AutoComplete: primevue.autocomplete
},
mixins: [
Phrasen
],
emits: [
'reload'
],
@@ -33,7 +29,7 @@ export default {
class: 'position-absolute top-0 start-0 w-100 h-100'
}), {
dialogClass: 'modal-fullscreen'
}, this.p.t('studierendenantrag', 'antrag_header')).then(() => {
}, this.$p.t('studierendenantrag', 'antrag_header')).then(() => {
this.$emit('reload');
this.student = '';
});
@@ -67,17 +63,17 @@ export default {
<div class="studierendenantrag-leitung-actions-new" v-if="data">
<button type="button" class="btn btn-outline-secondary" data-bs-toggle="modal" data-bs-target="#newAntragModal">
<i class="fa fa-plus"></i>
{{p.t('studierendenantrag','btn_new')}}
{{$p.t('studierendenantrag','btn_new')}}
</button>
<div ref="modal" class="modal fade" id="newAntragModal" tabindex="-1" aria-labelledby="newAntragModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="newAntragModalLabel">{{p.t('studierendenantrag','title_new_Abmeldung')}}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="p.t('ui','schliessen')"></button>
<h5 class="modal-title" id="newAntragModalLabel">{{$p.t('studierendenantrag','title_new_Abmeldung')}}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" :aria-label="$p.t('ui','schliessen')"></button>
</div>
<div class="modal-body">
<label for="newAntragModalAutoComplete">{{p.t('person','studentIn')}}</label>
<label for="newAntragModalAutoComplete">{{$p.t('person','studentIn')}}</label>
<div>
<auto-complete
class="w-100"
@@ -102,7 +98,7 @@ export default {
class="btn btn-primary"
:disabled="!this.student"
@click.prevent="openForm">
{{p.t('studierendenantrag','btn_create')}}
{{$p.t('studierendenantrag','btn_create')}}
</button>
</div>
</div>
@@ -1,11 +1,8 @@
import BsAlert from '../../Bootstrap/Alert.js';
import Phrasen from '../../../mixins/Phrasen.js';
export default {
mixins: [
BsAlert,
Phrasen
],
props: {
placeholder: String,
@@ -46,17 +43,17 @@ export default {
<div>
<textarea ref="input" class="form-control" :class="{'is-invalid' : isInvalid}" v-model="value"></textarea>
<div v-if="isInvalid" class="invalid-feedback">
{{p.t('kvp','new.error.required')}}
{{$p.t('kvp','new.error.required')}}
</div>
</div>
</template>
<template v-slot:footer>
<div v-if="countRemaining > 0" class="form-check flex-grow-1">
<input ref="check" type="checkbox" class="form-check-input" id="cbid" v-model="check">
<label class="form-check-label" for="cbid">{{p.t('studierendenantrag','fuer_alle_uebernehmen')}}</label>
<label class="form-check-label" for="cbid">{{$p.t('studierendenantrag','fuer_alle_uebernehmen')}}</label>
</div>
<button type="button" class="btn btn-primary" @click="submit">{{p.t('ui','ok')}}</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{p.t('ui','cancel')}}</button>
<button type="button" class="btn btn-primary" @click="submit">{{$p.t('ui','ok')}}</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{$p.t('ui','cancel')}}</button>
</template>
</bs-modal>`
}
@@ -1,7 +1,4 @@
import Phrasen from '../../../mixins/Phrasen.js';
export default {
mixins: [Phrasen],
props: {
stgs: Array
},
@@ -10,10 +7,10 @@ export default {
],
template: `
<div class="studierendenantrag-leitung-header fhc-table-header d-flex align-items-center mb-2 gap-2">
<h3 class="h5 col m-0">{{p.t('studierendenantrag', 'studierendenantraege')}}</h3>
<h3 class="h5 col m-0">{{$p.t('studierendenantrag', 'studierendenantraege')}}</h3>
<div v-if="stgs.length > 1" class="col-auto">
<select ref="stg_select" class="form-select" @input="$emit('input', $event)">
<option value="">{{p.t('global', 'alle')}}</option>
<option value="">{{$p.t('global', 'alle')}}</option>
<option v-for="stg in stgs" :key="stg.studiengang_kz" :value="stg.studiengang_kz">
{{stg.bezeichnung}} ({{stg.orgform}})
</option>
@@ -1,14 +1,12 @@
import BsAlert from '../../Bootstrap/Alert.js';
import {CoreFetchCmpt} from "../../Fetch.js";
import Phrasen from '../../../mixins/Phrasen.js';
export default {
components: {
CoreFetchCmpt
},
mixins: [
BsAlert,
Phrasen
BsAlert
],
props: {
footer: Boolean,
@@ -79,29 +77,29 @@ export default {
@data-fetched="setlvs">
<template #default>
<div v-if="lvzugelassenLength == 0">
{{p.t('studierendenantrag','error_no_lvs')}}
{{$p.t('studierendenantrag','error_no_lvs')}}
</div>
<table v-else class="table caption-top" v-for="(lv_arr, sem) in lvzugelassen" :key="sem">
<caption>
<span class="d-flex justify-content-between">
<span>{{ p.t('studierendenantrag',['title_lv_nicht_zugelassen', 'title_lv_wiederholen'][sem.substr(0,1)-1]) }}</span>
<span>{{ $p.t('studierendenantrag',['title_lv_nicht_zugelassen', 'title_lv_wiederholen'][sem.substr(0,1)-1]) }}</span>
<span>{{sem.substr(1)}}</span>
</span>
</caption>
<thead v-if="lv_arr !== null">
<tr>
<th scope="col">{{p.t('ui','bezeichnung')}}</th>
<th scope="col">{{p.t('lehre','lehrform')}}</th>
<th scope="col">{{$p.t('ui','bezeichnung')}}</th>
<th scope="col">{{$p.t('lehre','lehrform')}}</th>
<th scope="col">ECTS</th>
<th scope="col">{{p.t('lehre','note')}}</th>
<th scope="col">{{$p.t('lehre','note')}}</th>
<th scope="col">
{{p.t('global','anmerkung')}}
{{$p.t('global','anmerkung')}}
</th>
</tr>
</thead>
<tbody>
<tr v-if="lv_arr === null" class="table-warning">
<td colspan="5">{{p.t('studierendenantrag/error_stg_last_semester')}}</td>
<td colspan="5">{{$p.t('studierendenantrag/error_stg_last_semester')}}</td>
</tr>
<template v-else>
<tr v-for="lv in lv_arr">
@@ -140,10 +138,10 @@ export default {
<template v-if="footer" v-slot:footer>
<div v-if="countRemaining > 0" class="form-check flex-grow-1">
<input ref="check" type="checkbox" class="form-check-input" id="cbid" v-model="check">
<label class="form-check-label" for="cbid">{{p.t('studierendenantrag','fuer_x_uebernehmen', {count: countRemaining})}}</label>
<label class="form-check-label" for="cbid">{{$p.t('studierendenantrag','fuer_x_uebernehmen', {count: countRemaining})}}</label>
</div>
<button type="button" class="btn btn-primary" @click="submit(true)">{{p.t('studierendenantrag','btn_approve')}}</button>
<button v-if="countRemaining > 0" type="button" class="btn btn-secondary" @click="submit(false)">{{p.t('ui','skip')}}</button>
<button type="button" class="btn btn-primary" @click="submit(true)">{{$p.t('studierendenantrag','btn_approve')}}</button>
<button v-if="countRemaining > 0" type="button" class="btn btn-secondary" @click="submit(false)">{{$p.t('ui','skip')}}</button>
</template>
</bs-modal>`
}
@@ -1,7 +1,6 @@
import BsModal from '../../Bootstrap/Modal.js';
import {CoreFetchCmpt} from '../../Fetch.js';
import LvPopup from './LvPopup.js';
import Phrasen from '../../../mixins/Phrasen.js';
import { dateFilter } from '../../../tabulator/filters/Dates.js';
export default {
@@ -10,7 +9,6 @@ export default {
CoreFetchCmpt,
LvPopup
},
mixins: [Phrasen],
props: {
selectedData: Array,
columnData: Array,
@@ -76,7 +74,8 @@ export default {
this.$refs.lvList.show();
}
},
mounted() {
async mounted() {
await this.$p.loadCategory(['lehre', 'studierendenantrag', 'person', 'global', 'ui']);
function dateFormatter(cell)
{
let val = cell.getValue();
@@ -100,7 +99,7 @@ export default {
page: true, //persist page
columns: ["width", "visible"], //persist columns
},
persistenceID: 'studierendenantrag_leitung',
persistenceID: 'studierendenantrag_leitung_2023-11-14',
columns: [{
formatter: 'rowSelection',
titleFormatter: 'rowSelection',
@@ -114,7 +113,7 @@ export default {
title: '#'
}, {
field: 'bezeichnung',
title: this.p.t('lehre', 'studiengang'),
title: this.$p.t('lehre', 'studiengang'),
headerFilter: 'list',
headerFilterParams: {
valuesLookup: true,
@@ -123,7 +122,7 @@ export default {
}
}, {
field: 'orgform',
title: this.p.t('lehre', 'organisationsform'),
title: this.$p.t('lehre', 'organisationsform'),
headerFilter: 'list',
headerFilterParams: {
valuesLookup: true,
@@ -132,7 +131,7 @@ export default {
}
}, {
field: 'typ',
title: this.p.t('studierendenantrag', 'antrag_typ'),
title: this.$p.t('studierendenantrag', 'antrag_typ'),
headerFilter: 'list',
headerFilterParams: {
valuesLookup: true,
@@ -140,11 +139,11 @@ export default {
autocomplete: true,
},
formatter: (cell, formatterParams, onRendered) => {
return this.p.t('studierendenantrag','antrag_typ_' + cell.getValue());
return this.$p.t('studierendenantrag','antrag_typ_' + cell.getValue());
}
}, {
field: 'statustyp',
title: this.p.t('studierendenantrag', 'antrag_status'),
title: this.$p.t('studierendenantrag', 'antrag_status'),
headerFilter: 'list',
headerFilterParams: {
valuesLookup: true,
@@ -166,38 +165,38 @@ export default {
}
}, {
field: 'matrikelnr',
title: this.p.t('person', 'personenkennzeichen'),
title: this.$p.t('person', 'personenkennzeichen'),
headerFilter: 'input'
}, {
field: 'prestudent_id',
title: this.p.t('lehre', 'prestudent'),
title: this.$p.t('lehre', 'prestudent'),
headerFilter: 'input'
}, {
field: 'name',
title: this.p.t('global', 'name'),
title: this.$p.t('global', 'name'),
mutator: (value, data) => (data.vorname + ' ' + data.nachname).replace(/^\s*(.*)\s*$/, '$1'),
headerFilter: 'input'
}, {
field: 'datum',
title: this.p.t('global', 'datum'),
title: this.$p.t('global', 'datum'),
formatter: dateFormatter,
headerFilterFunc: 'dates',
headerFilter: dateFilter
}, {
field: 'datum_wiedereinstieg',
title: this.p.t('studierendenantrag', 'antrag_datum_wiedereinstieg'),
title: this.$p.t('studierendenantrag', 'antrag_datum_wiedereinstieg'),
formatter: dateFormatter,
headerFilterFunc: 'dates',
headerFilter: dateFilter
}, {
field: 'grund',
title: this.p.t('studierendenantrag', 'antrag_grund'),
title: this.$p.t('studierendenantrag', 'antrag_grund'),
formatter: (cell, formatterParams, onRendered) => {
let link = document.createElement('a'),
val = cell.getValue();
link.href = "#modal-grund";
link.setAttribute('data-bs-toggle', 'modal');
link.innerHTML = this.p.t('studierendenantrag', 'antrag_grund');
link.innerHTML = this.$p.t('studierendenantrag', 'antrag_grund');
link.addEventListener('click', () => {
this.$refs.modalGrundPre.innerHTML = val;
});
@@ -206,19 +205,25 @@ export default {
}
}, {
field: 'dms_id',
title: this.p.t('studierendenantrag', 'antrag_dateianhaenge'),
title: this.$p.t('studierendenantrag', 'antrag_dateianhaenge'),
formatter: (cell, formatterParams, onRendered) => {
let val = cell.getValue();
if (!val)
return '';
return '<a href="' + FHC_JS_DATA_STORAGE_OBJECT.app_root +
let link = document.createElement('a');
link.href = FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
'/lehre/Antrag/Attachment/show/' + val + '" target="_blank"><i class="fa fa-paperclip" aria-hidden="true"></i> ' + this.p.t('studierendenantrag', 'antrag_anhang') + '</a>';
'/lehre/Antrag/Attachment/show/' +
val;
link.setAttribute('target', '_blank');
link.innerHTML = '<i class="fa fa-paperclip" aria-hidden="true"></i>';
link.append(this.$p.t('studierendenantrag/antrag_anhang'));
return link;
}
}, {
field: 'actions',
frozen: true,
title: this.p.t('ui', 'aktion'),
title: this.$p.t('ui', 'aktion'),
headerFilter: false,
headerSort: false,
formatter: (cell, formatterParams, onRendered) => {
@@ -230,7 +235,9 @@ export default {
if ((data.typ == 'Abmeldung' || data.typ == 'AbmeldungStgl' || data.typ == 'Unterbrechung') && (data.status == 'Genehmigt' || data.status == 'Beeinsprucht' || data.status == 'EinspruchAbgelehnt' || data.status == 'EmailVersandt')) {
// NOTE(chris): Download PDF
let button = document.createElement('a');
button.innerHTML = '<i class="fa-solid fa-download" title="' + this.p.t('studierendenantrag', 'btn_download_antrag') + '"></i>';
// NOTE(chris): phrasen in attribues don't work if they are not preloaded
// it work in this case because the category has already been loaded before
button.innerHTML = '<i class="fa-solid fa-download" title="' + this.$p.t('studierendenantrag', 'btn_download_antrag') + '"></i>';
button.className = "btn btn-outline-secondary";
button.target = "_blank";
button.href = FHC_JS_DATA_STORAGE_OBJECT.app_root +
@@ -240,7 +247,7 @@ export default {
if (data.typ == 'AbmeldungStgl' && data.status == 'Genehmigt') {
// NOTE(chris): Object
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_object');
button.append(this.$p.t('studierendenantrag', 'btn_object'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:object', [cell.getData()]));
container.append(button);
@@ -249,14 +256,14 @@ export default {
if (data.typ == 'AbmeldungStgl' && data.status == 'Beeinsprucht') {
// NOTE(chris): Deny Objection
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_objection_deny');
button.append(this.$p.t('studierendenantrag', 'btn_objection_deny'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:objectionDeny', [cell.getData()]));
container.append(button);
// NOTE(chris): Approve Objection
button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_objection_approve');
button.append(this.$p.t('studierendenantrag', 'btn_objection_approve'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:objectionApprove', [cell.getData()]));
container.append(button);
@@ -266,7 +273,7 @@ export default {
// NOTE(chris): Reopen
if (data.typ == 'Wiederholung' && data.status == 'Verzichtet') {
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_reopen');
button.append(this.$p.t('studierendenantrag', 'btn_reopen'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:reopen', [cell.getData()]));
container.append(button);
@@ -274,7 +281,7 @@ export default {
// NOTE(chris): Lv Zuweisen
if (data.typ == 'Wiederholung' && (data.status == 'Erstellt' || data.status == 'Lvszugewiesen')) {
let button = document.createElement('a');
button.innerHTML = this.p.t('studierendenantrag', 'btn_lvzuweisen');
button.append(this.$p.t('studierendenantrag', 'btn_lvzuweisen'));
button.className = "btn btn-outline-secondary";
button.href = FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
@@ -287,7 +294,7 @@ export default {
class: 'position-absolute top-0 start-0 w-100 h-100'
}), {
dialogClass: 'modal-fullscreen'
}, this.p.t('studierendenantrag', 'title_lvzuweisen', cell.getData())).then(() => {
}, this.$p.t('studierendenantrag', 'title_lvzuweisen', cell.getData())).then(() => {
this.$emit('reload');
});
};
@@ -296,7 +303,7 @@ export default {
// NOTE(chris): Cancel
if (data.typ == 'AbmeldungStgl' && (data.status == 'Erstellt' || data.status == 'Genehmigt' )) {
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_cancel');
button.append(this.$p.t('studierendenantrag', 'btn_cancel'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click',() => this.$emit('action:cancel', [cell.getData()]));
container.append(button);
@@ -307,7 +314,7 @@ export default {
// NOTE(chris): Approve
if ((data.typ == 'Wiederholung' && data.status == 'Lvszugewiesen') || (data.typ != 'Wiederholung' && data.status == 'Erstellt')) {
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_approve');
button.append(this.$p.t('studierendenantrag', 'btn_approve'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:approve', [cell.getData()]));
container.append(button);
@@ -315,7 +322,7 @@ export default {
// NOTE(chris): Reject (Unterbrechung braucht grund)
if (data.status == 'Erstellt' && data.typ == 'Unterbrechung') {
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_reject');
button.append(this.$p.t('studierendenantrag', 'btn_reject'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:reject', [cell.getData()]));
container.append(button);
@@ -325,7 +332,7 @@ export default {
// NOTE(chris): Show LVs
if (data.typ == 'Wiederholung' && (data.status == 'Lvszugewiesen' || data.status == 'Genehmigt')) {
let button = document.createElement('button');
button.innerHTML = this.p.t('studierendenantrag', 'btn_show_lvs');
button.append(this.$p.t('studierendenantrag', 'btn_show_lvs'));
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.showLVs(cell.getData()));
container.append(button);
@@ -358,11 +365,11 @@ export default {
<div class="studierendenantrag-leitung-table">
<div ref="table"></div>
<bs-modal ref="modalGrund" id="modal-grund" class="fade">
<template #title>{{p.t('studierendenantrag', 'antrag_grund')}}</template>
<pre ref="modalGrundPre"></pre>
<template #title>{{$p.t('studierendenantrag', 'antrag_grund')}}</template>
<textarea class="form-control" ref="modalGrundPre" style="width: 100%; height: 250px;" readonly></textarea>
</bs-modal>
<bs-modal ref="history" class="fade">
<template #title>{{p.t('studierendenantrag', 'title_history', {id: lastHistoryClickedId})}}</template>
<template #title>{{$p.t('studierendenantrag', 'title_history', {id: lastHistoryClickedId})}}</template>
<core-fetch-cmpt ref="historyLoader" :api-function="getHistory">
<table v-if="historyData.length" class="table">
<tr v-for="status in historyData" :key="status.studierendenantrag_status_id">
@@ -371,7 +378,7 @@ export default {
<td>{{status.typ}}</td>
<td>
<a v-if="status.grund" href="#modal-grund" data-bs-toggle="modal" @click="showHistoryGrund(status.grund)">
{{p.t('studierendenantrag', 'antrag_grund')}}
{{$p.t('studierendenantrag', 'antrag_grund')}}
</a>
</td>
</tr>
@@ -379,7 +386,7 @@ export default {
</core-fetch-cmpt>
</bs-modal>
<lv-popup ref="lvList" class="fade" :antrag-id="lvsData ? lvsData.studierendenantrag_id : null">
{{p.t('studierendenantrag', 'title_show_lvs', lvsData ? lvsData : {name: ''}) }}
{{$p.t('studierendenantrag', 'title_show_lvs', lvsData ? lvsData : {name: ''}) }}
</lv-popup>
</div>
`
@@ -1,11 +1,9 @@
import StudierendenantragStatus from './Status.js';
import Phrasen from '../../mixins/Phrasen.js';
export default {
components: {
StudierendenantragStatus
},
mixins: [Phrasen],
props: {
antragId: Number,
initialStatusCode: String,
@@ -64,7 +62,7 @@ export default {
this.statusCode = response.data.retval[0].studierendenantrag_statustyp_kurzbz;
this.statusMsg = response.data.retval[0].typ;
} else {
this.addAlert(response.data.retval, 'alert-danger');
this.addAlert(response.data.retval.message || response.data.retval, 'alert-danger');
this.statusCode = 0;
this.statusMsg = 'Error';
}
@@ -107,119 +105,125 @@ export default {
else
{
let res = {};
for (var k in result.data.retval) {
if (result.data.retval[k] === null) {
const alert = document.createElement('div');
alert.innerHTML = this.p.t('studierendenantrag', 'error_stg_last_semester');
alert.className = 'alert alert-warning';
alert.role = 'alert';
this.$refs["lvtable" + k.substr(0,1)].append(alert);
continue;
}
let lvs = result.data.retval[k].reduce((obj,lv) => {
obj[lv.studienplan_lehrveranstaltung_id] = lv;
return obj;
}, {});
for (var lv of Object.values(lvs)) {
if (!lv.studienplan_lehrveranstaltung_id_parent)
continue;
if (!lvs[lv.studienplan_lehrveranstaltung_id_parent])
console.error('parent not available');
else {
if (!lvs[lv.studienplan_lehrveranstaltung_id_parent]._children)
lvs[lv.studienplan_lehrveranstaltung_id_parent]._children = [];
lvs[lv.studienplan_lehrveranstaltung_id_parent]._children.push(lv);
}
}
res[k] = Object.values(lvs).filter(lv => !lv.studienplan_lehrveranstaltung_id_parent);
let current = res[k];
let index = k.substr(0,1);
var table = new Tabulator(this.$refs["lvtable" + k.substr(0,1)], {
data: current,
dataTree: true,
dataTreeStartExpanded: true, //start with an expanded tree
dataTreeChildIndent: 15,
layout: "fitDataStretch",
columns: [
{title: this.p.t('ui','bezeichnung'), field: "bezeichnung"},
{title: this.p.t('lehre','lehrform'), field: "lehrform_kurzbz"},
{title: "ECTS", field: "ects"},
{title: this.p.t('lehre','note'), field: "note", formatter:(cell, formatterParams, onRendered)=>cell.getValue() || "---"},
{title: (index==1) ? this.p.t('studierendenantrag','lv_nicht_zulassen') : this.p.t('studierendenantrag','lv_wiederholen'), field: "antrag_zugelassen", formatter: (cell, formatterParams, onRendered) => {
let data = cell.getData();
if(data._children || !data.zeugnis)
return "";
let input = document.createElement('input');
input.className = "form-check-input";
input.type = "checkbox";
input.role = "switch";
input.checked = cell.getValue();
input.addEventListener('input', () => {
lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.checked;
cell.getRow().reformat();
});
if (this.disabled) {
input.disabled = true;
}
let div = document.createElement('div');
div.className = 'form-check form-switch';
div.append(input);
return div;
}},
{
title: this.p.t('global','anmerkung'),
field: "antrag_anmerkung",
headerSort:false,
titleFormatter:(cell, formatterParams, onRendered)=>{
let link = document.createElement('a');
link.addEventListener('click', (e) => {
e.preventDefault();
});
link.href ="#";
link.title = this.p.t('studierendenantrag','anmerkung_tooltip');
new bootstrap.Tooltip(link);
let tooltip = document.createElement('span');
tooltip.innerHTML = this.p.t('global','anmerkung') + " ";
tooltip.append(link);
let icon = document.createElement('i');
link.append(icon);
icon.className = "fa fa-info-circle";
icon.setAttribute("aria-hidden", "true");
icon.style.minWidth = '1em';
return tooltip;
},
formatter: (cell, formatterParams, onRendered) => {
if (this.disabled) {
return cell.getValue() || "";
}
var data = cell.getData();
if (lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen)
{
let input = document.createElement('input');
input.className = "form-control";
input.type = "text";
input.value = cell.getValue() || "";
input.addEventListener('input', () => {
lvs[data.studienplan_lehrveranstaltung_id].antrag_anmerkung = input.value;
});
return input;
}
else
{
return "";
}
this.$p
.loadCategory(['ui', 'lehre', 'studierendenantrag', 'global'])
.then(() => {
for (var k in result.data.retval) {
if (result.data.retval[k] === null) {
const alert = document.createElement('div');
alert.innerHTML = this.$p.t('studierendenantrag', 'error_stg_last_semester');
alert.className = 'alert alert-warning';
alert.role = 'alert';
this.$refs["lvtable" + k.substr(0,1)].append(alert);
continue;
}
let lvs = result.data.retval[k].reduce((obj,lv) => {
obj[lv.studienplan_lehrveranstaltung_id] = lv;
return obj;
}, {});
for (var lv of Object.values(lvs)) {
if (!lv.studienplan_lehrveranstaltung_id_parent)
continue;
if (!lvs[lv.studienplan_lehrveranstaltung_id_parent])
console.error('parent not available');
else {
if (!lvs[lv.studienplan_lehrveranstaltung_id_parent]._children)
lvs[lv.studienplan_lehrveranstaltung_id_parent]._children = [];
lvs[lv.studienplan_lehrveranstaltung_id_parent]._children.push(lv);
}
}
]
res[k] = Object.values(lvs).filter(lv => !lv.studienplan_lehrveranstaltung_id_parent);
let current = res[k];
let index = k.substr(0,1);
const options = {
data: current,
dataTree: true,
dataTreeStartExpanded: true, //start with an expanded tree
dataTreeChildIndent: 15,
layout: "fitDataStretch",
columns: [
{title: this.$p.t('ui', 'bezeichnung'), field: "bezeichnung"},
{title: this.$p.t('lehre','lehrform'), field: "lehrform_kurzbz"},
{title: "ECTS", field: "ects"},
{title: this.$p.t('lehre','note'), field: "note", formatter:(cell, formatterParams, onRendered)=>cell.getValue() || "---"},
{title: (index==1) ? this.$p.t('studierendenantrag','lv_nicht_zulassen') : this.$p.t('studierendenantrag','lv_wiederholen'), field: "antrag_zugelassen", formatter: (cell, formatterParams, onRendered) => {
let data = cell.getData();
if(data._children || !data.zeugnis)
return "";
let input = document.createElement('input');
input.className = "form-check-input";
input.type = "checkbox";
input.role = "switch";
input.checked = cell.getValue();
input.addEventListener('input', () => {
lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.checked;
cell.getRow().reformat();
});
if (this.disabled) {
input.disabled = true;
}
let div = document.createElement('div');
div.className = 'form-check form-switch';
div.append(input);
return div;
}},
{
title: this.$p.t('global','anmerkung'),
field: "antrag_anmerkung",
headerSort:false,
titleFormatter:(cell, formatterParams, onRendered)=>{
let link = document.createElement('a');
link.addEventListener('click', (e) => {
e.preventDefault();
});
link.href ="#";
link.title = this.$p.t('studierendenantrag','anmerkung_tooltip');
new bootstrap.Tooltip(link);
let tooltip = document.createElement('span');
tooltip.innerHTML = this.$p.t('global','anmerkung') + " ";
tooltip.append(link);
let icon = document.createElement('i');
link.append(icon);
icon.className = "fa fa-info-circle";
icon.setAttribute("aria-hidden", "true");
icon.style.minWidth = '1em';
return tooltip;
},
formatter: (cell, formatterParams, onRendered) => {
if (this.disabled) {
return cell.getValue() || "";
}
var data = cell.getData();
if (lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen)
{
let input = document.createElement('input');
input.className = "form-control";
input.type = "text";
input.value = cell.getValue() || "";
input.addEventListener('input', () => {
lvs[data.studienplan_lehrveranstaltung_id].antrag_anmerkung = input.value;
});
return input;
}
else
{
return "";
}
}
}
]
};
var table = new Tabulator(this.$refs["lvtable" + k.substr(0,1)], options);
}
this.lvs = result.data.retval;
});
}
this.lvs = result.data.retval;
}
}
);
@@ -229,20 +233,20 @@ export default {
<div ref="alertbox"></div>
<span class="d-flex justify-content-between h4">
<span>{{p.t('studierendenantrag', 'title_lv_nicht_zugelassen')}}</span>
<span>{{$p.t('studierendenantrag', 'title_lv_nicht_zugelassen')}}</span>
<span>{{lvs1sem}}</span>
</span>
<div ref="lvtable1" class="mb-3">
</div>
<span class="d-flex justify-content-between h4">
<span>{{p.t('studierendenantrag', 'title_lv_wiederholen')}}</span>
<span>{{$p.t('studierendenantrag', 'title_lv_wiederholen')}}</span>
<span>{{lvs2sem}}</span>
</span>
<div ref="lvtable2">
</div>
<button type="button" @click="save" :disabled="isloading || disabled" class="btn btn-primary my-3">{{p.t('studierendenantrag', 'btn_save_lvs')}}</button>
<button type="button" @click="save" :disabled="isloading || disabled" class="btn btn-primary my-3">{{$p.t('studierendenantrag', 'btn_save_lvs')}}</button>
</div>
<div class="col-sm-2">
<studierendenantrag-status :msg="statusMsg" :severity="statusSeverity"></studierendenantrag-status>
+67
View File
@@ -0,0 +1,67 @@
const categories = Vue.reactive({});
const loadingModules = {};
function extractCategory(obj, category) {
return obj.filter(e => e.category == category).reduce((res, elem) => {
if (!res[elem.phrase])
res[elem.phrase] = elem.text;
return res;
}, {});
}
function getValueForLoadedPhrase(category, phrase, params) {
let result = categories[category][phrase];
if (!result)
return '<< PHRASE ' + phrase + '>>';
if (params)
result = result.replace(/\{([^}]*)\}/g, (match, p1) => params[p1] === undefined ? match : params[p1]);
return result;
}
const phrasen = {
loadCategory(category) {
if (Array.isArray(category))
return Promise.all(category.map(cat => this.loadCategory(cat)));
if (!loadingModules[category])
loadingModules[category] = axios
.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Phrasen/loadModule/' + category)
.then(res => {
if (res.data.retval)
categories[category] = extractCategory(res.data.retval, category);
else
categories[category] = {};
});
return loadingModules[category];
},
t_ref(category, phrase, params) {
console.warn('depricated');
return Vue.computed(() => this.t(category, phrase, params));
},
t(category, phrase, params) {
if (params === undefined && (
(Array.isArray(category) && category.length == 2) ||
(category.split && category.split('/').length == 2))
) {
params = phrase;
[category, phrase] = category.split ? category.split('/') : category;
}
if (phrase === undefined) {
console.error('invalid input', category, phrase, params);
return '';
}
let val = Vue.computed(() => {
if (!categories[category])
return '';
return getValueForLoadedPhrase(category, phrase, params);
});
if (!categories[category])
this.loadCategory(category);
return val.value;
}
};
export default {
install(app, options) {
app.config.globalProperties.$p = phrasen;
}
}
+26 -4
View File
@@ -242,9 +242,31 @@ function drawLehrauftrag($uid)
$name_gesamt = trim($row->titelpre.' '.$row->vorname.' '.$row->nachname.' '.$row->titelpost);
$zuhanden='';
}
// Lädt die letzte (aktuellste) Verwendungen eines Mitarbeiters um die inkludierte Lehre auslesen zu können
$bis = new bisverwendung();
$bis->getLastAktVerwendung($uid);
$show_betrag = true;
if (defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT)
{
$qry = "
SELECT
1
FROM
hr.tbl_dienstverhaeltnis
WHERE
mitarbeiter_uid=".$db->db_add_param($uid)."
AND vertragsart_kurzbz = 'echterdv'
AND von <= (SELECT ende FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=".$db->db_add_param($ss).")
AND COALESCE(bis,'2999-12-31') >= (SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=".$db->db_add_param($ss).")
";
if($result = $db->db_query($qry))
{
if($db->db_num_rows($result)>0)
{
$show_betrag = false;
}
}
}
$xml .= '
<mitarbeiter>
@@ -259,7 +281,7 @@ function drawLehrauftrag($uid)
<ort><![CDATA['.$ort.']]></ort>
<svnr><![CDATA['.$row->svnr.']]></svnr>
<personalnummer><![CDATA['.$row->personalnummer.']]></personalnummer>
<inkludierte_lehre><![CDATA['.$bis->inkludierte_lehre.']]></inkludierte_lehre>
<show_betrag><![CDATA['.($show_betrag?'true':'false').']]></show_betrag>
</mitarbeiter>';
}
}
+28 -4
View File
@@ -24,6 +24,7 @@
* Erstellt ein XML File fuer den Lehrauftrag
*/
require_once('../config/vilesci.config.inc.php');
require_once('../config/global.config.inc.php');
require_once('../include/functions.inc.php');
require_once('../include/benutzerberechtigung.class.php');
require_once('../include/studiengang.class.php');
@@ -246,9 +247,32 @@ function drawLehrauftrag($uid)
$name_gesamt = trim($row->titelpre.' '.$row->vorname.' '.$row->nachname.' '.$row->titelpost);
$zuhanden='';
}
// Lädt die letzte (aktuellste) Verwendungen eines Mitarbeiters um die inkludierte Lehre auslesen zu können
$bis = new bisverwendung();
$bis->getLastAktVerwendung($uid);
$show_betrag = true;
if (defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT)
{
$qry = "
SELECT
1
FROM
hr.tbl_dienstverhaeltnis
WHERE
mitarbeiter_uid=".$db->db_add_param($uid)."
AND vertragsart_kurzbz = 'echterdv'
AND von <= (SELECT ende FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=".$db->db_add_param($ss).")
AND COALESCE(bis,'2999-12-31') >= (SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=".$db->db_add_param($ss).")
";
if($result = $db->db_query($qry))
{
if($db->db_num_rows($result)>0)
{
$show_betrag = false;
}
}
}
$xml .= '
<mitarbeiter>
@@ -263,7 +287,7 @@ function drawLehrauftrag($uid)
<ort><![CDATA['.$ort.']]></ort>
<svnr><![CDATA['.$row->svnr.']]></svnr>
<personalnummer><![CDATA['.$row->personalnummer.']]></personalnummer>
<inkludierte_lehre><![CDATA['.$bis->inkludierte_lehre.']]></inkludierte_lehre>
<show_betrag><![CDATA['.($show_betrag?'true':'false').']]></show_betrag>
</mitarbeiter>';
}
}
+3 -1
View File
@@ -350,6 +350,7 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_vertragsbestandteil_urlaubsanspruch TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_vertragsbestandteil_kuendigungsfrist TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_vertragsbestandteil_karenz TO vilesci;
GRANT SELECT ON hr.tbl_vertragsbestandteil_karenz TO web;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_karenztyp TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_teilzeittyp TO vilesci;
@@ -359,12 +360,13 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
GRANT SELECT ON hr.tbl_vertragsbestandteiltyp TO web;
GRANT SELECT ON hr.tbl_vertragsbestandteil_stunden TO web;
GRANT SELECT ON hr.tbl_vertragsbestandteil_zeitaufzeichnung TO web;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_gehaltsbestandteil TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_gehaltshistorie TO vilesci;
GRANT SELECT, UPDATE, INSERT, DELETE ON hr.tbl_gehaltstyp TO vilesci;
GRANT USAGE ON SCHEMA hr TO vilesci;
GRANT USAGE ON SCHEMA hr TO web;
INSERT INTO hr.tbl_karenztyp(karenztyp_kurzbz, bezeichnung) VALUES('elternkarenz','Elternkarenz');
INSERT INTO hr.tbl_karenztyp(karenztyp_kurzbz, bezeichnung) VALUES('bildungskarenz','Bildungskarenz');
+52 -12
View File
@@ -21531,13 +21531,13 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): \nNichterfüllung finanzieller Verpflichtungen trotz Mahnung (Studienbeitrag)',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): Nichterfüllung finanzieller Verpflichtungen trotz Mahnung (Studienbeitrag)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reason for exclusion according to the training contract (point 7.4): \nFailure to meet financial obligations despite a reminder (tuition fees)',
'text' => 'Reason for exclusion according to the training contract (point 7.4): Failure to meet financial obligations despite a reminder (tuition fees)',
'description' => '',
'insertvon' => 'system'
)
@@ -21551,13 +21551,13 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): \nmehrmalig unentschuldigtes Verletzen der Anwesenheitspflicht',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): mehrmalig unentschuldigtes Verletzen der Anwesenheitspflicht',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reason for exclusion according to the training contract (point 7.4): \nmultiple unexcused breaches of attendance requirements',
'text' => 'Reason for exclusion according to the training contract (point 7.4): multiple unexcused breaches of attendance requirements',
'description' => '',
'insertvon' => 'system'
)
@@ -21571,13 +21571,13 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): \nwiederholtes Nichteinhalten von Prüfungsterminen bzw Abgabeterminen für Seminararbeiten bzw. Projektarbeiten',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): wiederholtes Nichteinhalten von Prüfungsterminen bzw Abgabeterminen für Seminararbeiten bzw. Projektarbeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reason for exclusion according to the training contract (point 7.4): \nrepeated non-compliance with examination dates or deadlines for seminar papers or project work',
'text' => 'Reason for exclusion according to the training contract (point 7.4): repeated non-compliance with examination dates or deadlines for seminar papers or project work',
'description' => '',
'insertvon' => 'system'
)
@@ -21591,13 +21591,13 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): \nPlagiieren im Rahmen wissenschaftlicher Arbeiten bzw. unerlaubte Verwendung KI generierter Hilfsmittel bzw. Quellen',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): Plagiieren im Rahmen wissenschaftlicher Arbeiten bzw. unerlaubte Verwendung KI generierter Hilfsmittel bzw. Quellen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reason for exclusion according to the training contract (point 7.4): \nPlagiarism in the context of scientific work or unauthorized use of AI-generated tools or sources',
'text' => 'Reason for exclusion according to the training contract (point 7.4): Plagiarism in the context of scientific work or unauthorized use of AI-generated tools or sources',
'description' => '',
'insertvon' => 'system'
)
@@ -21611,13 +21611,13 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): \nnicht genügende Leistung im Sinne der Prüfungsordnung',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): nicht genügende Leistung im Sinne der Prüfungsordnung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reason for exclusion according to the training contract (point 7.4): \ninsufficient performance in terms of the examination regulations',
'text' => 'Reason for exclusion according to the training contract (point 7.4): insufficient performance in terms of the examination regulations',
'description' => '',
'insertvon' => 'system'
)
@@ -21631,13 +21631,33 @@ array(
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): \nNichtantritt des Studiums zu Beginn des Studienjahres (=Unbegründetes Nichterscheinen zur ersten Studienveranstaltung)',
'text' => 'Ausschlußgrund gemäß Ausbildungsvertrag (Punkt 7.4): Nichtantritt des Studiums zu Beginn des Studienjahres (=Unbegründetes Nichterscheinen zur ersten Studienveranstaltung)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reason for exclusion according to the training contract (point 7.4): \nFailure to start the course at the beginning of the academic year (= unjustified non-attendance to the first course event)',
'text' => 'Reason for exclusion according to the training contract (point 7.4): Failure to start the course at the beginning of the academic year (= unjustified non-attendance to the first course event)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'textLong_MissingZgv',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zugangsvoraussetzung BA (bzw. MA) nicht erfüllt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Entry requirements BA (resp. MA) not fulfilled)',
'description' => '',
'insertvon' => 'system'
)
@@ -21763,6 +21783,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'dropdown_MissingZgv',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zugangsvoraussetzung BA (bzw. MA) nicht erfüllt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Entry requirements BA (resp. MA) not fulfilled',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
+3 -3
View File
@@ -120,15 +120,15 @@ echo '<div>Student: <b>'.$uid.'</b><br>Titel: <b>'.
<td><input type="text" name="sprache" id="sprache" value="'.(isset($row_zd->sprache)?$db->convert_html_chars($row_zd->sprache):'').'" size="10" maxlength="8" readonly="readonly"></td>
</tr>
<tr>
<td width="30%"><b>Kontrollierte Schlagw&ouml;rter:*</b></td>
<td width="30%"><b>Kontrollierte Schlagw&ouml;rter:</b></td>
<td width="40%"><input type="text" name="kontrollschlagwoerter" id="kontrollschlagwoerter" value="'.(isset($row_zd->kontrollschlagwoerter)?$db->convert_html_chars($row_zd->kontrollschlagwoerter):'').'" size="60" maxlength="150" readonly="readonly"></td>
</tr>
<tr>
<td><b>Dt. Schlagw&ouml;rter:</b></td>
<td><b>Dt. Schlagw&ouml;rter:*</b></td>
<td><input type="text" name="schlagwoerter" value="'.(isset($row_zd->schlagwoerter)?$db->convert_html_chars($row_zd->schlagwoerter):'').'" size="60" maxlength="150" readonly="readonly"></td>
</tr>
<tr>
<td><b>Engl. Schlagw&ouml;rter:</b></td>
<td><b>Engl. Schlagw&ouml;rter:*</b></td>
<td><input type="text" name="schlagwoerter_en" value="'.(isset($row_zd->schlagwoerter_en)?$db->convert_html_chars($row_zd->schlagwoerter_en):'').'" size="60" maxlength="150" readonly="readonly"></td>
</tr>
<tr>
+84 -12
View File
@@ -341,6 +341,31 @@ if ($studiengang_kz != '' && $stsem_von != '' && $stsem_nach != '')
{
$stundensatz = new mitarbeiter($row_lem->mitarbeiter_uid);
$lem_obj->stundensatz = $stundensatz->stundensatz;
if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT)
{
$qry = "
SELECT
stundensatz
FROM
hr.tbl_stundensatz
WHERE
uid=".$db->db_add_param($row_lem->mitarbeiter_uid)."
AND gueltig_von <= ".$db->db_add_param($stsem_nach_obj->ende)."
AND COALESCE(gueltig_bis, '2999-12-31') >= ".$db->db_add_param($stsem_nach_obj->start)."
AND stundensatztyp = 'lehre'
ORDER BY gueltig_von desc
LIMIT 1
";
if($result_stundensatz = $db->db_query($qry))
{
if($row_stundensatz = $db->db_fetch_object($result_stundensatz))
{
$lem_obj->stundensatz = $row_stundensatz->stundensatz;
}
}
}
}
// Wenn VILESCI_STUNDENSATZ_VORRUECKUNG nachbeschaeftigungsart ist, wird
// bei echten Dienstvertraegen mit voller inkludierter Lehre (-1) der Stundensatz auf null gesetzt
@@ -355,21 +380,68 @@ if ($studiengang_kz != '' && $stsem_von != '' && $stsem_nach != '')
$stundensatz = new mitarbeiter($row_lem->mitarbeiter_uid);
$lem_obj->stundensatz = $stundensatz->stundensatz;
$bisverwendung = new bisverwendung();
if(!$bisverwendung->getVerwendungRange($row_lem->mitarbeiter_uid, $stsem_nach_obj->start, $stsem_nach_obj->ende))
if(defined('DIENSTVERHAELTNIS_SUPPORT') && DIENSTVERHAELTNIS_SUPPORT)
{
$bisverwendung->getLastAktVerwendung($row_lem->mitarbeiter_uid);
$bisverwendung->result[] = $bisverwendung;
}
$qry = "
SELECT
stundensatz
FROM
hr.tbl_stundensatz
WHERE
uid=".$db->db_add_param($row_lem->mitarbeiter_uid)."
AND gueltig_von <= ".$db->db_add_param($stsem_nach_obj->ende)."
AND COALESCE(gueltig_bis, '2999-12-31') >= ".$db->db_add_param($stsem_nach_obj->start)."
AND stundensatztyp = 'lehre'
ORDER BY gueltig_von desc
LIMIT 1
";
foreach($bisverwendung->result as $row_verwendung)
{
// Bei echten Dienstvertraegen mit voller inkludierter Lehre wird kein Stundensatz
// geliefert da dies im Vertrag inkludiert ist.
if ((in_array($row_verwendung->ba1code, $arrEchterDV)) && $row_verwendung->inkludierte_lehre == -1)
if($result_stundensatz = $db->db_query($qry))
{
$lem_obj->stundensatz = '';
break;
if($row_stundensatz = $db->db_fetch_object($result_stundensatz))
{
$lem_obj->stundensatz = $row_stundensatz->stundensatz;
}
}
$qry = "
SELECT
1
FROM
hr.tbl_dienstverhaeltnis dv
WHERE
dv.mitarbeiter_uid=".$db->db_add_param($row_lem->mitarbeiter_uid)."
AND dv.von <= ".$db->db_add_param($stsem_nach_obj->ende)."
AND COALESCE(dv.bis, '2999-12-31') >= ".$db->db_add_param($stsem_nach_obj->start)."
AND vertragsart_kurzbz='echterdv'
";
if($result_dienstverhaeltnis = $db->db_query($qry))
{
if($db->db_num_rows($result_dienstverhaeltnis)>0)
{
$lem_obj->stundensatz = '';
}
}
}
else
{
$bisverwendung = new bisverwendung();
if(!$bisverwendung->getVerwendungRange($row_lem->mitarbeiter_uid, $stsem_nach_obj->start, $stsem_nach_obj->ende))
{
$bisverwendung->getLastAktVerwendung($row_lem->mitarbeiter_uid);
$bisverwendung->result[] = $bisverwendung;
}
foreach($bisverwendung->result as $row_verwendung)
{
// Bei echten Dienstvertraegen mit voller inkludierter Lehre wird kein Stundensatz
// geliefert da dies im Vertrag inkludiert ist.
if ((in_array($row_verwendung->ba1code, $arrEchterDV)) && $row_verwendung->inkludierte_lehre == -1)
{
$lem_obj->stundensatz = '';
break;
}
}
}
}