Compare commits

..
Author SHA1 Message Date
ma0068 e876b9e4ab Zeitsperren Mitarbeiter - add component to Vertragsverwaltung 2026-07-24 13:11:40 +02:00
35 changed files with 969 additions and 115 deletions
@@ -0,0 +1,115 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class MaZeitsperren extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAllActiveZeitsperren' => self::PERM_LOGGED,
'getAllZeitsperrenFixeMa' => self::PERM_LOGGED,
'getAllZeitsperrenLector' => self::PERM_LOGGED,
'getAllZeitsperrenOes' => self::PERM_LOGGED,
'getZeitsperrenAss' => self::PERM_LOGGED,
'getStgLectors' => self::PERM_LOGGED,
'loadZeitsperrenLectorStg' => self::PERM_LOGGED,
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'zeitsperren'
]);
// Load models
$this->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel');
}
//only user with zeitsperren
public function getAllActiveZeitsperren($days)
{
$result = $this->ZeitsperreModel->getZeitsperrenForNextDays($days);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
//TODO: check query: more results after join with hr-table
//all fixe Ma
public function getAllZeitsperrenFixeMa($days)
{
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($days, true, false, null, false);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllZeitsperrenLector($days)
{
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($days, false, true, null, false);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getZeitsperrenAss($days)
{
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($days, false, false, null, true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllZeitsperrenOes($days, $oe)
{
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($days, false, false, $oe, false);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadZeitsperrenLectorStg($days, $stg)
{
$result = $this->ZeitsperreModel->getMitarbeiterWithZeitsperren($days, false, true, false, false, $stg);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStgLectors()
{
$sql = "
select
studiengang_kz,
kurzbz,
kurzbzlang,
typ,
bezeichnung,
kurzbzlang || ' (' || bezeichnung || ')' AS label
from
public.tbl_studiengang
where
typ in ('b','m')
order by typ asc, kurzbz Asc
";
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -259,7 +259,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram') == "" ? null : $this->input->post('retouram');
$retouram = $this->input->post('retouram');
// NOTE(chris): transform_kartennummer
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer)
@@ -9,9 +9,9 @@ class Detailheader extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'getHeader' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r'],
'getHeader' => ['vertrag/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
]);
}
@@ -294,10 +294,6 @@ class Funktionen extends FHCAPI_Controller
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if($datum_von == '')
$datum_von = null;
if($datum_bis == '')
$datum_bis = null;
$result = $this->BenutzerfunktionModel->update(
[
@@ -371,9 +371,6 @@ class Abschlusspruefung extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$datum = $formData['datum'] == '' ? null : $formData['datum'];
$sponsion = $formData['sponsion'] == '' ? null : $formData['sponsion'];
$result = $this->AbschlusspruefungModel->update(
[
'abschlusspruefung_id' => $abschlusspruefung_id
@@ -385,8 +382,8 @@ class Abschlusspruefung extends FHCAPI_Controller
'vorsitz' => $vorsitz,
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $datum,
'sponsion' => $sponsion,
'datum' => $formData['datum'],
'sponsion' => $formData['sponsion'],
'pruefer1' => $pruefer1,
'pruefer2' => $pruefer2,
'pruefer3' => $pruefer3,
@@ -170,8 +170,6 @@ class Dokumente extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$nachgereicht_am = $this->input->post('nachgereicht_am') == '' ? null : $this->input->post('nachgereicht_am');
$uid = getAuthUID();
$result = $this->AkteModel->update(
@@ -182,7 +180,7 @@ class Dokumente extends FHCAPI_Controller
'dokument_kurzbz' => $this->input->post('dokument_kurzbz'),
'anmerkung_intern' => $this->input->post('anmerkung_intern'),
'titel_intern' => $this->input->post('titel_intern'),
'nachgereicht_am' => $nachgereicht_am,
'nachgereicht_am' => $this->input->post('nachgereicht_am'),
'updateamum' => date('c'),
'updatevon' => $uid,
]
@@ -429,12 +429,9 @@ class Konto extends FHCAPI_Controller
'updateamum' => date('c'),
'updatevon' => getAuthUID()
];
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field);
if($data['buchungsdatum'] == '')
$data['buchungsdatum'] = null;
$result = $this->KontoModel->update($id, $data);
@@ -237,8 +237,8 @@ class Mobility extends FHCAPI_Controller
}
$formData = $this->input->post('formData');
$von = ($formData['von'] ?? '') ?: null;
$bis = ($formData['bis'] ?? '') ?: null;
$von = $formData['von'] ?? null;
$bis = $formData['bis'] ?? null;
$nation_code = $formData['nation_code'] ?? null;
$mobilitaetsprogramm_code = $formData['mobilitaetsprogramm_code'] ?? null;
$herkunftsland_code = $formData['herkunftsland_code'] ?? null;
@@ -193,7 +193,7 @@ class Prestudent extends FHCAPI_Controller
}
elseif (
$val === ''
&& in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode', 'zgvdatum', 'zgvmadatum'])
&& in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode'])
)
{
$val = null;
@@ -448,10 +448,8 @@ class Pruefung extends FHCAPI_Controller
}
}
$datum = $this->input->post('datum') == '' ? null : $this->input->post('datum');
if(intval($pruefung_id) > 0)
{
$result = $this->PruefungModel->update(
[
'pruefung_id' => $pruefung_id
@@ -461,7 +459,7 @@ class Pruefung extends FHCAPI_Controller
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'note' => $this->input->post('note'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'datum' => $datum,
'datum' => $this->input->post('datum'),
'anmerkung' => $this->input->post('anmerkung'),
'updatevon' => $authUID,
'updateamum' => date('c'),
@@ -474,7 +472,7 @@ class Pruefung extends FHCAPI_Controller
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'),
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'datum' => $datum,
'datum' => $this->input->post('datum'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'note' => $this->input->post('note'),
'anmerkung' => $this->input->post('anmerkung'),
@@ -522,7 +520,7 @@ class Pruefung extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'),
'benotungsdatum' => $datum,
'benotungsdatum' => $this->input->post('datum'),
'insertamum' => date('c'),
'insertvon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
@@ -557,7 +555,7 @@ class Pruefung extends FHCAPI_Controller
], [
'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'),
'benotungsdatum' => $datum,
'benotungsdatum' => $this->input->post('datum'),
'updateamum' => date('c'),
'updatevon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
@@ -296,10 +296,6 @@ class Student extends FHCAPI_Controller
$fotoval = ($val == '') ? null : str_replace('data:image/jpeg;base64,', '', $val);
$update_person[$prop] = $fotoval;
}
else if ($prop == 'gebdatum')
{
$update_person[$prop] = ($val == '') ? null : $val;
}
else
{
$update_person[$prop] = $val;
@@ -122,47 +122,6 @@ class Studiensemester_model extends DB_Model
return $this->execQuery($query, array($studiensemester_kurzbz, $limit));
}
/**
* Returns the current study semester and the previous semesters of the same type (SS/WS).
*
* Example:
* - SS2026, limit 3: SS2026, SS2025, SS2024
* - WS2025, limit 2: WS2025, WS2024
*
* @param $studiensemester_kurzbz
* @param $limit
*/
public function getPreviousSameSemesterFrom($studiensemester_kurzbz, $limit = 1)
{
$qry = '
SELECT
studiensemester_kurzbz,
start,
ende
FROM
public.tbl_studiensemester
WHERE
SUBSTRING(studiensemester_kurzbz FROM 1 FOR 2) = SUBSTRING(? FROM 1 FOR 2)
AND start <= (
SELECT start
FROM public.tbl_studiensemester
WHERE studiensemester_kurzbz = ?
)
ORDER BY
start DESC
LIMIT ?
';
return $this->execQuery($qry,
[
$studiensemester_kurzbz,
$studiensemester_kurzbz,
$limit
]
);
}
/**
* getNearest
*/
@@ -260,6 +260,7 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parameters_array);
}
/**
* Get active Kompetenzfeldleitung bei UID.
*
@@ -295,6 +296,7 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parameters_array);
}
public function insertBenutzerfunktion($Json)
{
unset($Json['benutzerfunktion_id']);
@@ -61,4 +61,195 @@ class Zeitsperre_model extends DB_Model
return $this->execQuery($qry);
}
/**
* getZeitsperren of Mitarbeiter for the next days
* @ days: count of the intervall of the next days
* @return array
*/
public function getZeitsperrenForNextDays($days, $type=null)
{
//TODO(Manu) von und bis im controller berechnen und hier übergeben
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
//version with campus.vw_mitarbeiter
$paramsArray = [$von, $bis, $bis, $von];
$qry = "select
nachname,
vorname,
uid,
vondatum,
bisdatum,
vertretung_uid,
erreichbarkeit_kurzbz
--lektor,
-- fixangestellt
from
campus.vw_mitarbeiter
join campus.tbl_zeitsperre on
(uid = mitarbeiter_uid)
where
((? <= bisdatum
and ? >= bisdatum)
or (?>= vondatum
and ? <= vondatum))
";
//fix, lektor etc just with all ma
if($type=="fix") {
$qry.= "AND fixangestellt = true";
}
if($type=="lector") {
$qry.= "AND lektor = true";
}
//wenn lektor= WAHR und fixangestellt = Falsch: --> externer Lektor
$qry .= " order by nachname";
//version with hr.dienstverhaeltnis
/* $paramsArray = [$bis, $von];
$qry = "
SELECT
ps.nachname,
ps.vorname,
zs.mitarbeiter_uid,
zs.vondatum,
zs.bisdatum,
zs.vertretung_uid,
zs.erreichbarkeit_kurzbz
FROM campus.tbl_zeitsperre zs
JOIN public.tbl_benutzer bn
ON bn.uid = zs.mitarbeiter_uid
JOIN public.tbl_person ps
ON ps.person_id = bn.person_id ";
if ($type != null) {
$qry.= " JOIN hr.tbl_dienstverhaeltnis dv on bn.uid = dv.mitarbeiter_uid ";
}
$qry.="
WHERE
zs.vondatum <= ?
AND zs.bisdatum >= ?";
if($type=="fix") {
$qry.= " and dv.vertragsart_kurzbz = 'echterdv'";
}
if($type=="lector") {
$qry.= " and dv.vertragsart_kurzbz in ('externerlehrender', 'gastlektor')";
}
$qry .= "
ORDER BY
ps.nachname,
ps.vorname,
zs.vondatum;";*/
$result = $this->execQuery($qry, $paramsArray);
return $result;
}
public function getMitarbeiterWithZeitsperren($days, $fix=false, $lector=false, $oe=null, $ass=false, $stg=false)
{
//TODO(Manu) von und bis im controller berechnen und hier übergeben
$von = date('Y-m-d');
$bis = date('Y-m-d', strtotime("+{$days} days"));
//version with campus.vw_mitarbeiter
$paramsArray = [$von, $bis, $bis, $von];
if($oe)
{
$paramsArray[] = $oe;
}
if($stg)
{
$paramsArray[] = $stg;
}
$qry = "
SELECT
m.nachname,
m.vorname,
m.uid,
z.vondatum,
z.bisdatum,
z.vertretung_uid,
z.erreichbarkeit_kurzbz,
m.lektor,
m.fixangestellt,
mv.kurzbz
FROM campus.vw_mitarbeiter m
join public.tbl_benutzer bn on bn.uid = m.uid";
if($oe || $ass || $stg)
{
$qry .= " JOIN public.tbl_benutzerfunktion bf on bf.uid = bn.uid";
}
if($stg)
{
$qry .= " JOIN public.tbl_studiengang stg using (oe_kurzbz)";
}
$qry.= "
LEFT JOIN campus.tbl_zeitsperre z
ON m.uid = z.mitarbeiter_uid
AND (
(? <= z.bisdatum AND ? >= z.bisdatum)
OR
(? >= z.vondatum AND ? <= z.vondatum)
)
left join public.tbl_mitarbeiter mv on z.vertretung_uid = mv.mitarbeiter_uid
where bn.aktiv = true
";
if($fix) {
$qry.= " AND m.fixangestellt = true";
}
if($lector) {
$qry.= " AND m.lektor = true";
}
if ($oe)
{
$qry.= "
AND bf.funktion_kurzbz ='oezuordnung'
AND bf.oe_kurzbz= ?
AND (bf.datum_von is null or bf.datum_von <=now())
AND (bf.datum_bis is null or bf.datum_bis >= now())
";
}
if ($ass)
{
$qry.= "
AND bf.funktion_kurzbz ='ass'
AND (bf.datum_von is null or bf.datum_von <=now())
AND (bf.datum_bis is null or bf.datum_bis >= now())
";
}
if ($stg)
{
$qry.= "
AND stg.studiengang_kz = ?
";
}
$qry .= " order by nachname, vorname, uid";
$result = $this->execQuery($qry, $paramsArray);
return $result;
}
}
+68
View File
@@ -0,0 +1,68 @@
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export default {
loadAllActiveZeitsperren(days) {
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/getAllActiveZeitsperren/' + days
};
},
loadAllZeitsperrenFixeMa(days) {
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/getAllZeitsperrenFixeMa/' + days
};
},
loadAllZeitsperrenLector(days) {
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/getAllZeitsperrenLector/' + days
};
},
getAllOes(){
return {
method: 'get',
url:'api/frontend/v1/funktionen/Funktionen/getAllOrgUnits'
};
},
loadAllZeitsperrenOE(days, oe) {
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/getAllZeitsperrenOes/' + days + '/' + oe,
};
},
loadZeitsperrenAss(days) {
console.log("url: loadZeitsperrenAss");
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/getZeitsperrenAss/' + days
};
},
getAllStg(){
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/getStgLectors'
};
},
loadZeitsperrenLectorStg(days,stg) {
console.log("url: loadZeitsperrenLectorStg");
return {
method: 'get',
url:'api/frontend/v1/MaZeitsperren/loadZeitsperrenLectorStg/' + days + '/' + stg,
};
},
}
+7
View File
@@ -19,6 +19,7 @@ import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.j
import Studium from "../../components/Cis/Studium/Studium.js";
import StgOrgLvPlan from "../../components/Cis/LvPlan/StgOrg.js";
import OtherLvPlan from "../../components/Cis/LvPlan/OtherLvPlan.js";
import ZeitsperrenMa from "../../components/Cis/ZeitsperrenMitarbeiter/ZeitsperrenMa.js";
import ApiRouteInfo from '../../api/factory/routeinfo.js';
import {capitalize} from "../../helpers/StringHelpers.js";
@@ -245,6 +246,12 @@ const router = VueRouter.createRouter({
};
},
},
{
path: `/Cis/ZeitsperrenMa`,
name: 'ZeitsperrenMa',
component: ZeitsperrenMa,
props: true
},
]
})
@@ -433,7 +433,6 @@ export default {
:label="$p.t('wawi/ausgegebenam')"
name="ausgegebenam"
v-model="formData.ausgegebenam"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -450,7 +449,6 @@ export default {
:label="$p.t('wawi/retouram')"
name="retouram"
v-model="formData.retouram"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -0,0 +1,441 @@
import {CoreFilterCmpt} from "../../../filter/Filter.js";
import ApiMaTimelocks from "../../../../api/factory/zeitsperren.js";
import FormForm from "../../../Form/Form.js";
import FormInput from "../../../Form/Input.js";
import PvAutoComplete from "../../../../../../index.ci.php/public/js/components/primevue/autocomplete/autocomplete.esm.min.js";
export default {
name: "aktuelleZeitsperren",
components: {
FormForm,
FormInput,
PvAutoComplete,
CoreFilterCmpt
},
props: {
type: {
type: String,
default: 'all',
validator(value) {
return [
'fix',
'lector',
'oe',
'ass',
'lecStg'
].includes(value)
}
}
},
data(){
return {
interval: 14,
days: {},
arrayMaTimelocks: [],
listOes: [],
filteredOes: [],
selectedOe: null,
oe_kurzbz: null,
listStg: [],
filteredStg: [],
selectedStg: null,
studiengang_kz: null
}
},
methods: {
loadAllActiveZeitsperren(days){
this.$api
.call(ApiMaTimelocks.loadAllActiveZeitsperren(days))
.then(result => {
this.arrayMaTimelocks = result.data;
})
},
loadZeitsperrenFixeMa(days){
this.$api
.call(ApiMaTimelocks.loadAllZeitsperrenFixeMa(days))
.then(result => {
this.arrayMaTimelocks = result.data;
})
},
loadZeitsperrenLector(days){
this.$api
.call(ApiMaTimelocks.loadAllZeitsperrenLector(days))
.then(result => {
this.arrayMaTimelocks = result.data;
})
},
loadZeitsperrenOE(days, oe){
console.log("in function oe " + oe);
this.$api
.call(ApiMaTimelocks.loadAllZeitsperrenOE(days, oe))
.then(result => {
this.arrayMaTimelocks = result.data;
})
},
loadZeitsperrenAss(days){
console.log("in ASS ");
this.$api
.call(ApiMaTimelocks.loadZeitsperrenAss(days))
.then(result => {
this.arrayMaTimelocks = result.data;
})
},
loadZeitsperrenStg(days, stg){
console.log("in function stg " + stg);
this.$api
.call(ApiMaTimelocks.loadZeitsperrenLectorStg(days, stg))
.then(result => {
this.arrayMaTimelocks = result.data;
})
},
createDays() {
const today = new Date();
//get Monday before today
const mondayBeforeToday = new Date(today);
const day = today.getDay();
const diff = day === 0 ? 6 : day - 1;
mondayBeforeToday.setDate(today.getDate() - diff);
this.days = Array.from({ length: this.interval+1 }, (_, i) => {
const date = new Date(mondayBeforeToday);
date.setDate(mondayBeforeToday.getDate() + i);
return {
date: date.toISOString().substring(0, 10), // 2026-07-13
weekday: date.toLocaleDateString('de-AT', { weekday: 'short' }),
day: date.toLocaleDateString('de-AT', {
day: '2-digit',
month: '2-digit'
})
};
});
},
isBlocked(mitarbeiter, tag) {
if (!mitarbeiter?.sperren) {
return false;
}
return mitarbeiter.sperren.some(s =>
tag >= s.vondatum &&
tag <= s.bisdatum
);
},
getSperre(mitarbeiter, tag){
return mitarbeiter.sperren.find(s =>
tag >= s.vondatum &&
tag <= s.bisdatum
);
},
limitDays(event) {
let value = event.target.value.replace(/\D/g, '').slice(0, 2);
event.target.value = value;
this.interval = value ? Number(value) : null;
},
filterOes(event) {
const query = event.query.toLowerCase();
this.filteredOes = this.listOes.filter(item =>
item.label.toLowerCase().includes(query)
);
},
filterStg(event) {
const query = event.query.toLowerCase();
this.filteredStg = this.listStg.filter(item =>
item.label.toLowerCase().includes(query)
);
},
//TODO(Manu) check link profile
link(uid) {
//https://www.fhcomplete.local/cis.php/Cis/Profil/getView/bell
return (
FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
"/Cis/Profil/getView/" +
uid
);
}
},
computed: {
today(){
const today = new Date();
const day = today.toLocaleDateString('de-AT', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
return day;
},
mondayBeforeToday(){
const today = new Date();
//get Monday before today
const mondayBeforeToday = new Date(today);
const day = today.getDay();
const diff = day === 0 ? 6 : day - 1;
mondayBeforeToday.setDate(today.getDate() - diff);
return mondayBeforeToday;
},
endInterval(){
const today = new Date();
const end = new Date(this.mondayBeforeToday);
end.setDate(end.getDate() + this.interval);
return end.toLocaleDateString('de-AT', {
day: '2-digit',
month: '2-digit',
year: 'numeric'
});
},
mitarbeiter() {
const map = {};
//vor version with uid in query
this.arrayMaTimelocks.forEach(z => {
if (!map[z.uid]) {
map[z.uid] = [];
}
map[z.uid].push(z);
});
return Object.entries(map).map(([mitarbeiter_uid, sperren]) => ({
mitarbeiter_uid,
sperren
}));
},
},
watch: {
interval: {
handler(newVal) {
if (newVal) {
if(this.type == "fix") {
console.log("fix");
this.loadZeitsperrenFixeMa(newVal);
}
else if(this.type == "lector") {
console.log("lector");
this.loadZeitsperrenLector(newVal);
}
else if(this.type == "oe") {
console.log("oe: in handler");
if(this.oe_kurzbz && this.oe_kurzbz !="")
this.loadZeitsperrenOE(newVal, this.oe_kurzbz);
else
console.log("Bitte OE auswählen");
}
else if(this.type == "all")
{
console.log("all active");
this.loadAllActiveZeitsperren(newVal);
}
else if(this.type == "ass") {
console.log("ass");
this.loadZeitsperrenAss(newVal);
}
else
{
console.log("not defined");
}
this.createDays();
}
},
deep: true,
},
selectedOe(newVal) {
this.oe_kurzbz = newVal?.oe_kurzbz || '';
},
oe_kurzbz(newVal){
{
if(newVal != "")
this.loadZeitsperrenOE(this.interval, newVal);
}
},
selectedStg(newVal) {
this.studiengang_kz = newVal?.studiengang_kz || '';
},
studiengang_kz(newVal){
{
console.log("STG triggered");
if(newVal != "")
this.loadZeitsperrenStg(this.interval, newVal);
}
},
},
created(){
if(this.type == "fix") {
console.log("fix");
this.loadZeitsperrenFixeMa(this.interval);
}
else if(this.type == "lector") {
console.log("lector");
this.loadZeitsperrenLector(this.interval);
}
else if(this.type == "oe") {
console.log("oeg");
this.$api
.call(ApiMaTimelocks.getAllOes())
.then(result => {
this.listOes = result.data;
/* this.listStg = this.listOes.filter(item =>
item.label.includes("[Studiengang]") && item.aktiv || item.label.includes("[Lehrgang]") && item.aktiv
);*/
})
.catch(this.$fhcAlert.handleSystemError);
}
else if(this.type == "lecStg") {
console.log("lecStg");
this.$api
.call(ApiMaTimelocks.getAllStg())
.then(result => {
this.listStg = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
}
else if(this.type == "all") {
console.log("all active");
this.loadAllActiveZeitsperren(this.interval);
}
else if(this.type == "ass") {
console.log("ass");
this.loadZeitsperrenAss(this.interval);
}
else
{
console.log("not defined");
}
this.createDays();
/* console.log('adams, 2026-07-16');
console.log(this.isBlocked('adams', '2026-07-16'));*/
},
template: `
<div class="w-100 h-100">
<h3 class="mt-3"><span v-if="type=='all'">Mitarbeiter*innen mit aktuellen </span>Zeitsperren
<span v-if="type=='fix'">Fixangestellte</span>
<span v-if="type=='lector'">aller fixer Lektoren</span>
<span v-if="type=='oe'">nach Organisationseinheit</span> {{ mondayBeforeToday.toLocaleDateString('de-AT') }} - {{endInterval}}
</h3>
<div class="d-flex align-items-center gap-2">
<label for="days" class="mb-0">Anzahl Tage:</label>
<input
id="days"
v-model.number="interval"
type="number"
class="form-control"
style="width: 90px"
min="1"
max="99"
@input="limitDays"
>
<label v-if="type=='oe'">{{$p.t('lehre/organisationseinheit')}}</label>
<div v-if="type=='oe'" class="flex-grow-1">
<form-form class="g-3 mt-2" ref="oeSelectForm">
<form-input
container-class="mb-3 w-50"
type="autocomplete"
name="oe_kurzbz"
v-model="selectedOe"
forceSelection
optionLabel="label"
optionValue="oe_kurzbz"
:suggestions="filteredOes"
dropdown
@complete="filterOes"
>
<template #option="slotProps">
<div
:class="!slotProps.option.aktiv
? 'item-inactive'
: ''"
>
{{slotProps.option.label}}
</div>
</template>
</form-input>
</form-form>
</div>
<label v-if="type=='lecStg'">{{$p.t('studium/lektoren')}}</label>
<div v-if="type=='lecStg'" class="flex-grow-1 mt-2">
<form-form class="g-3 mt-2" ref="oeSelectForm">
<form-input
container-class="mb-3 w-50"
type="autocomplete"
name="studiengang_kz"
v-model="selectedStg"
forceSelection
optionLabel="label"
optionValue="studiengang_kz"
:suggestions="filteredStg"
dropdown
@complete="filterStg"
>
<template #option="slotProps">
<div
:class="!slotProps.option.aktiv
? 'item-inactive'
: ''"
>
{{slotProps.option.label}}
</div>
</template>
</form-input>
</form-form>
</div>
</div>
<br> count results: {{mitarbeiter.length}}, days: {{interval}}
<br> type: {{type}} <br> {{oe_kurzbz}} | {{selectedOe}}
<br> {{selectedStg}} | {{studiengang_kz}}
{{arrayMaTimelocks[0]}}
<hr>
<table class="table table-dark table-striped table-bordered">
<thead>
<tr>
<th scope="col"> UID </th>
<th v-for="day in days" :key="day.date">
<div>{{ day.weekday }}</div>
<div>{{ day.day }}</div>
</th>
</tr>
</thead>
<tbody>
<tr
v-for="m in mitarbeiter"
:key="m.uid"
>
<td>{{m.sperren[0].nachname}} {{m.sperren[0].vorname}}</td>
<td
v-for="day in days"
:key="day.date"
:class="{ 'table-warning': day.weekday === 'Sa' || day.weekday === 'So' }"
>
<template v-if="sperre = getSperre(m, day.date)">
abwesend
<div v-if="sperre.kurzbz">
V: {{ sperre.kurzbz }}
</div>
<a :href="link(sperre.vertretung_uid)">
{{ sperre.kurzbz }}
</a>
<div v-if="sperre.erreichbarkeit_kurzbz">E: {{ sperre.erreichbarkeit_kurzbz }}</div>
</template>
</td>
</tr>
</tbody>
</table>
</div>
`,
}
@@ -0,0 +1,116 @@
import aktuelleZeitsperren from './Details/aktuelleZeitsperren.js';
export default {
name: 'ZeitsperrenMa',
components: {
aktuelleZeitsperren,
},
data(){
return {
arrayAllMa : [],
showAllCurrent: false,
showAllFix: false,
showAllLectors: false,
showSearchOes: false,
showAllAss: false,
showLectorsOe: false,
}
},
methods: {
showTableAllCurrent(){
this.showAllCurrent = !this.showAllCurrent;
this.showAllFix = false;
this.showAllLectors = false;
this.showSearchOes = false;
this.showAllAss = false;
this.showLectorsOe = false;
},
showTableAllFix(){
this.showAllFix = !this.showAllFix;
this.showAllCurrent = false;
this.showAllLectors = false;
this.showSearchOes = false;
this.showAllAss = false;
this.showLectorsOe = false;
},
showTableAllLectors(){
this.showAllLectors = !this.showAllLectors;
this.showAllFix = false;
this.showAllCurrent = false;
this.showSearchOes = false;
this.showAllAss = false;
this.showLectorsOe = false;
},
showTableSearchOes(){
this.showSearchOes = !this.showSearchOes;
this.showAllFix = false;
this.showAllCurrent = false;
this.showAllLectors = false;
this.showAllAss = false;
this.showLectorsOe = false;
},
showTableAllAss(){
this.showAllAss = !this.showAllAss;
this.showSearchOes = false;
this.showAllFix = false;
this.showAllCurrent = false;
this.showAllLectors = false;
this.showLectorsOe = false;
},
showTableLectorsFromStg(){
this.showLectorsOe = !this.showLectorsOe;
this.showSearchOes = false;
this.showAllFix = false;
this.showAllCurrent = false;
this.showAllAss = false;
this.showAllLectors = false;
},
},
template: `
<div class="base-zeitsperren w-100 h-100">
<div class="row g-1">
<div class="col">
<button type="button" class="btn btn-primary w-100";" @click="showTableAllCurrent">Aktuelle Zeitsperren</button>
</div>
<div class="col">
<button type="button" class="btn btn-secondary w-100";" @click="showTableAllFix">alle Fixangestellte</button>
</div>
<div class="col">
<button type="button" class="btn btn-secondary w-100";" @click="showTableAllLectors">Alle fixen Lektor*innen</button>
</div>
<div class="col">
<button type="button" class="btn btn-secondary w-100";" @click="showTableSearchOes">Nach Organisationseinheit</button>
</div>
<div class="col">
<button type="button" class="btn btn-warning w-100";" @click="showTableAllAss">Alle Assistent*innen</button>
</div>
<div class="col">
<button type="button" class="btn btn-success w-100";" @click="showTableLectorsFromStg">Lektoren nach Stg</button>
</div>
</div>
<div v-if="showAllCurrent">
<aktuelle-zeitsperren/>
</div>
<div v-if="showAllFix">
<aktuelle-zeitsperren type="fix"></>
</div>
<div v-if="showAllLectors">
<aktuelle-zeitsperren type="lector"></>
</div>
<div v-if="showSearchOes">
<aktuelle-zeitsperren type="oe"></>
</div>
<div v-if="showAllAss">
<aktuelle-zeitsperren type="ass"></>
</div>
<div v-if="showLectorsOe">
<aktuelle-zeitsperren type="lecStg"></>
</div>
</div>
`,
}
@@ -551,7 +551,6 @@ export default {
container-class="mb-3 col-3"
type="DatePicker"
v-model="formData.datum_von"
model-type="yyyy-MM-dd"
name="datum_von"
:label="$p.t('ui/from') + ' *'"
auto-apply
@@ -567,7 +566,6 @@ export default {
container-class="mb-3 col-3"
type="DatePicker"
v-model="formData.datum_bis"
model-type="yyyy-MM-dd"
name="datum_bis"
:label="$p.t('global/bis')"
auto-apply
@@ -470,7 +470,6 @@ export default {
:label="$p.t('admission', 'anmeldundRtAm')"
type="DatePicker"
v-model="formData.anmeldedatum"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -293,7 +293,6 @@ export default {
:label="$p.t('person', 'geburtsdatum')"
type="DatePicker"
v-model="data.gebdatum"
model-type="yyyy-MM-dd"
name="gebdatum"
:clearable="false"
no-today
@@ -103,7 +103,6 @@ export default {
<form-input
type="DatePicker"
v-model="formData.nachgereicht_am"
model-type="yyyy-MM-dd"
name="nachgereicht_am"
:label="$p.t('dokumente/nachreichungAm')"
auto-apply
@@ -27,7 +27,7 @@ export default {
return {
filter: false,
studiengang_kz: false,
counterdate: luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate()
counterdate: new Date()
};
},
computed: {
@@ -259,7 +259,6 @@ export default {
<form-input
type="DatePicker"
v-model="counterdate"
model-type="yyyy-MM-dd"
input-group
:enable-time-picker="false"
text-input
@@ -79,7 +79,6 @@ export default {
<form-input
type="DatePicker"
v-model="data.buchungsdatum"
model-type="yyyy-MM-dd"
name="buchungsdatum"
:label="$p.t('konto/buchungsdatum')"
:enable-time-picker="false"
@@ -88,7 +88,7 @@ export default {
this.data = {
buchungstyp_kurzbz: '',
betrag: '-0.00',
buchungsdatum: luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate(),
buchungsdatum: new Date(),
buchungstext: '',
mahnspanne: 30,
studiensemester_kurzbz: this.currentSemester,
@@ -154,7 +154,6 @@ export default {
<form-input
type="DatePicker"
v-model="data.buchungsdatum"
model-type="yyyy-MM-dd"
name="buchungsdatum"
:label="$p.t('konto/buchungsdatum')"
:enable-time-picker="false"
@@ -467,7 +467,6 @@ export default {
:label="$p.t('ui', 'von')"
type="DatePicker"
v-model="formData.von"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -502,7 +501,6 @@ export default {
:label="$p.t('global', 'bis')"
type="DatePicker"
v-model="formData.bis"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -325,7 +325,6 @@ export default {
:label="$p.t('infocenter', 'zgvDatum')"
type="DatePicker"
v-model="data.zgvdatum"
model-type="yyyy-MM-dd"
name="zgvdatum"
no-today
auto-apply
@@ -390,7 +389,6 @@ export default {
:label="$p.t('lehre', 'zgvMasterDatum')"
type="DatePicker"
v-model="data.zgvmadatum"
model-type="yyyy-MM-dd"
name="zgvmadatum"
no-today
auto-apply
@@ -456,7 +454,6 @@ export default {
:label="$p.t('lehre', 'zgvDoktorDatum')"
type="DatePicker"
v-model="data.zgvdoktordatum"
model-type="yyyy-MM-dd"
name="zgvdoktordatum"
no-today
auto-apply
@@ -276,7 +276,6 @@ export default{
container-class="mb-3"
type="DatePicker"
v-model="formData.datum"
model-type="yyyy-MM-dd"
name="datum"
:label="$p.t('global/datum')"
auto-apply
@@ -292,7 +291,6 @@ export default{
container-class="mb-3"
type="DatePicker"
v-model="formData.bestaetigtam"
model-type="yyyy-MM-dd"
name="bestaetigtam"
:label="$p.t('lehre/bestaetigt_am')"
auto-apply
@@ -308,14 +306,13 @@ export default{
container-class="mb-3"
type="DatePicker"
v-model="formData.bewerbung_abgeschicktamum"
model-type="yyyy-MM-dd HH:mm:ss"
name="bewerbung_abgeschicktamum"
:label="$p.t('lehre/bewerbung_abgeschickt_am')"
auto-apply
:enable-time-picker="true"
format="dd.MM.yyyy HH:mm:ss"
:enable-time-picker="false"
format="dd.MM.yyyy"
text-input
preview-format="dd.MM.yyyy HH:mm:ss"
preview-format="dd.MM.yyyy"
:teleport="true"
:disabled="bisLocked || !hasPrestudentstatusPermission"
>
@@ -285,7 +285,6 @@ export default {
uid="stv-list-new-gebdatum"
name="gebdatum"
v-model="formDataPerson['gebdatum']"
model-type="yyyy-MM-dd"
:disabled="!!person"
@update:model-value="loadSuggestions"
text-input
+3 -17
View File
@@ -4,7 +4,6 @@ import FormInput from '../Form/Input.js';
import ApiUdf from '../../api/udf.js';
export default {
name: 'CoreUdfCmpt',
components: {
CoreFetchCmpt,
FormInput
@@ -27,8 +26,7 @@ export default {
// The values as associative array
modelValue: Object,
// Show only fields with a name that exists in the filter
filter: [String, Array],
readonly: true
filter: [String, Array]
},
data() {
return {
@@ -37,13 +35,6 @@ export default {
};
},
computed: {
isPkValid() {
// If the provided pk is _not_ valid
return !Object.keys(this.pk).every(key => !this.pk[key]);
},
getReadonly() {
return this.readonly;
},
filterArray() {
if (!this.filter || Array.isArray(this.filter))
return this.filter;
@@ -70,10 +61,6 @@ export default {
},
watch: {
pk(n, o) {
// If the provided pk is _not_ valid
if (Object.keys(n).every(key => !n[key])) return;
if (!this.$refs.fetch)
return; // NOTE(chris): no initial load yet
@@ -137,7 +124,6 @@ export default {
template: `
<div class="core-udf row">
<core-fetch-cmpt
v-if="isPkValid"
ref="fetch"
:api-function="loadF"
:api-function-parameters="{ ciModel, pk }"
@@ -152,7 +138,7 @@ export default {
:type="field.type"
:multiple="field.multiple"
:title="field.description"
:disabled="field.disabled || getReadonly"
:disabled="field.disabled"
:clearable="field.clearable"
:auto-apply="field.autoApply"
:enable-time-picker="field.enableTimePicker"
@@ -166,4 +152,4 @@ export default {
</template>
</core-fetch-cmpt>
</div>`
}
}
@@ -4,6 +4,7 @@ import FhcHeader from "../DetailHeader/DetailHeader.js";
import VertraegeMitarbeiter from "./Vertraege.js";
import VerticalSplit from "../verticalsplit/verticalsplit.js";
import ApiCoreVertraege from '../../api/factory/vertraege/vertraege.js';
import ZeitsperrenProv from '../Cis/ZeitsperrenMitarbeiter/ZeitsperrenMa.js';
export default {
@@ -13,7 +14,8 @@ export default {
VerticalSplit,
MitarbeiterHeader,
FhcHeader,
VertraegeMitarbeiter
VertraegeMitarbeiter,
ZeitsperrenProv
},
props: {
config: Object,
@@ -50,6 +52,9 @@ export default {
},
template: `
<!-- Navigation component -->
<zeitsperren-prov/>
<core-navigation-cmpt/>
<div id="content">
+1
View File
@@ -0,0 +1 @@
../vendor
Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB