Compare commits

...

4 Commits

Author SHA1 Message Date
Harald Bamberger 9c7e98f1cb js import add missing file extension 2026-05-06 18:31:26 +02:00
ma0068 c34ffedb42 Autocomplete Field Vertretung
Form with ISO fields for hours
Admin functionality for seeing Timelocks of uid in route
Backend with CI-Validations
Phrases
2026-01-21 10:59:16 +01:00
ma0068 b5382b1bdf Form and Start Backend 2026-01-15 15:39:42 +01:00
ma0068 519cbc7601 base structure and table 2026-01-14 09:26:15 +01:00
9 changed files with 1776 additions and 0 deletions
@@ -0,0 +1,30 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Zeitsperren extends Auth_Controller
{
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* index loads the view Zeitsperren
* @access public
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'zeitsperren']);
}
}
@@ -0,0 +1,367 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Zeitsperren extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getZeitsperrenUser' => self::PERM_LOGGED,
'getTypenZeitsperren' => self::PERM_LOGGED,
'getTypenErreichbarkeit' => self::PERM_LOGGED,
'getStunden' => self::PERM_LOGGED,
'loadZeitsperre' => self::PERM_LOGGED,
'add' => self::PERM_LOGGED,
'update' => self::PERM_LOGGED,
'delete' => 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');
$this->load->model('ressource/Zeitsperretyp_model', 'ZeitsperretypModel');
$this->load->model('ressource/Erreichbarkeit_model', 'ErreichbarkeitModel');
$this->load->model('ressource/Stunde_model', 'StundeModel');
$this->load->model('ressource/Zeitaufzeichnung_model', 'ZeitaufzeichnungModel');
}
public function getZeitsperrenUser($uid)
{
//check if $uid is passedUser
$loggedInUser = getAuthUID();
if($loggedInUser != $uid) {
$this->load->library('PermissionLib');
$isAdmin = $this->permissionlib->isBerechtigt('admin');
if(!$isAdmin) {
$this->terminateWithError($this->p->t('ui', 'noAdmin'), self::ERROR_TYPE_GENERAL);
}
}
$result = $this->ZeitsperreModel->getZeitsperrenUser($uid);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getTypenZeitsperren()
{
$this->ZeitsperretypModel->addOrder('beschreibung', 'ASC');
$result = $this->ZeitsperretypModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getTypenErreichbarkeit()
{
$result = $this->ErreichbarkeitModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getStunden()
{
$this->StundeModel->addOrder('stunde', 'ASC');
$result = $this->StundeModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function loadZeitsperre($zeitsperre_id)
{
$this->ZeitsperreModel->addSelect(
'campus.tbl_zeitsperre.*, typ.*,
ma.person_id AS ma_person_id, ma.vorname AS ma_vorname, ma.nachname AS ma_nachname,
ma.titelpre AS ma_titelpre, ma.titelpost AS ma_titelpost'
);
$this->ZeitsperreModel->addJoin('campus.tbl_zeitsperretyp typ', 'ON (typ.zeitsperretyp_kurzbz = campus.tbl_zeitsperre.zeitsperretyp_kurzbz)');
$this->ZeitsperreModel->addJoin('public.tbl_benutzer ben', 'ON (ben.uid = campus.tbl_zeitsperre.vertretung_uid)', 'LEFT');
$this->ZeitsperreModel->addJoin('public.tbl_person ma', 'ON (ma.person_id = ben.person_id)', 'LEFT');
$result = $this->ZeitsperreModel->loadWhere(
array('zeitsperre_id' => $zeitsperre_id)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((current(getData($result)) ?: []));
}
public function add($mitarbeiter_uid)
{
$loggedInUser = getAuthUID();
if($mitarbeiter_uid != $loggedInUser)
$this->terminateWithError($this->p->t('ui', 'noPermission'), self::ERROR_TYPE_GENERAL);
$this->form_validation->set_rules('zeitsperretyp_kurzbz', 'Grund Zeitsperre', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Grund Zeitsperre'])
]);
$this->form_validation->set_rules('vondatum', 'VonDatum', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('bisdatum', 'BisDatum', 'required|is_valid_date|callback_check_von_bis_datum|callback_check_diff_intval', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'BisDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'BisDatum']),
'check_von_bis_datum' => $this->p->t('zeitsperre', 'error_VonDatumGroesserAlsBisDatum'),
'check_diff_intval' => $this->p->t('zeitsperre', 'error_zeitraumAuffallendHoch')
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$bezeichnung = $this->input->post('bezeichnung');
$vondatum = $this->input->post('vondatum');
$vonstunde = $this->input->post('vonstunde');
$bisdatum = $this->input->post('bisdatum');
$bisstunde = $this->input->post('bisstunde');
//$vonIso = $this->input->post('vonISO'); //Timestamp für Stunde
//$bisIso = $this->input->post('bisISO'); //Timestamp für Stunde
$erreichbarkeit_kurzbz = $this->input->post('erreichbarkeit_kurzbz');
$vertretung_uid = $this->input->post('vertretung_uid');
$zeitsperretyp_kurzbz = $this->input->post('zeitsperretyp_kurzbz');
//check if existing zeitsperre
$result = $this->ZeitsperreModel->getSperreByDate($mitarbeiter_uid, $vondatum, $vonstunde, true);
$data = $this->getDataOrTerminateWithError($result);
if(hasData($result))
{
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitsperre', ['typ'=> current($data)->zeitsperretyp_kurzbz]), self::ERROR_TYPE_GENERAL);
}
//check if existing zeitaufzeichnung
if(in_array($zeitsperretyp_kurzbz, Zeitsperre_model::BLOCKIERENDE_ZEITSPERREN))
{
$result = $this->ZeitsperreModel->existsZeitaufzeichnung($mitarbeiter_uid, $vondatum, $bisdatum);
if(hasData($result))
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitaufzeichnung'), self::ERROR_TYPE_GENERAL);
}
$result = $this->ZeitsperreModel->insert(
[
'mitarbeiter_uid' => $mitarbeiter_uid,
'bezeichnung' => $bezeichnung,
'vondatum' => $vondatum,
'vonstunde' => $vonstunde,
'bisdatum' => $bisdatum,
'bisstunde' => $bisstunde,
'erreichbarkeit_kurzbz' => $erreichbarkeit_kurzbz,
'zeitsperretyp_kurzbz' => $zeitsperretyp_kurzbz,
'vertretung_uid' => $vertretung_uid,
'insertvon' => $loggedInUser,
'insertamum' => date('c'),
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function update($zeitsperre_id)
{
//check if loggedin User is owner of the zeitsperre
$loggedInUser = getAuthUID();
$result = $this->ZeitsperreModel->load($zeitsperre_id);
$data = $this->getDataOrTerminateWithError($result);
$uid = current($data)->mitarbeiter_uid;
if($uid != $loggedInUser)
$this->terminateWithError($this->p->t('ui', 'noPermission'), self::ERROR_TYPE_GENERAL);
if(!$zeitsperre_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Zeitsperre_id']), self::ERROR_TYPE_GENERAL);
}
//get current params
$array_update = [
'bezeichnung',
'vondatum',
'vonstunde',
'bisdatum',
'bisstunde',
// 'vonISO', //Timestamp für Stunde
// 'bisISO', //Timestamp für Stunde
'erreichbarkeit_kurzbz',
'vertretung_uid',
'zeitsperretyp_kurzbz',
'mitarbeiter_uid',
];
$post = $this->input->post();
$update = [];
foreach ($array_update as $prop)
{
if (array_key_exists($prop, $post))
{
$update[$prop] = $post[$prop];
}
}
// Validation
$rulesDefined = false; //necessary, otherwise CI validation will always be triggered, even without rules
foreach ($update as $key => $val) {
switch ($key) {
case 'zeitsperretyp_kurzbz':
$this->form_validation->set_rules(
$key,
'Grund Zeitsperre',
'required',
['required' => $this->p->t('ui', 'error_fieldRequired', ['field'=>'Grund Zeitsperre'])]
);
$rulesDefined = true;
break;
case 'vondatum':
$this->form_validation->set_rules(
$key,
'VonDatum',
'required|is_valid_date',
[
'required' => $this->p->t('ui', 'error_fieldRequired', ['field'=>'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field'=>'VonDatum'])
]
);
$rulesDefined = true;
break;
case 'bisdatum':
$rules = 'required|is_valid_date';
if (array_key_exists('vondatum', $update)) {
$rules .= '|callback_check_von_bis_datum|callback_check_diff_intval';
}
$this->form_validation->set_rules(
$key,
'BisDatum',
$rules,
[
'required' => $this->p->t('ui', 'error_fieldRequired', ['field'=>'BisDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field'=>'BisDatum']),
'check_von_bis_datum' => $this->p->t('zeitsperre', 'error_VonDatumGroesserAlsBisDatum'),
'check_diff_intval' => $this->p->t('zeitsperre', 'error_zeitraumAuffallendHoch')
]
);
$rulesDefined = true;
break;
}
}
if ($rulesDefined && $this->form_validation->run() == false) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if(array_key_exists('vondatum', $post) || array_key_exists('bisdatum', $post))
{
$result = $this->ZeitsperreModel->load($zeitsperre_id);
$data = $this->getDataOrTerminateWithError($result);
$data = current($data);
$mitarbeiter_uid = array_key_exists('mitarbeiter_uid', $post) ? $update['mitarbeiter_uid'] : $data->mitarbeiter_uid;
$vondatum = array_key_exists('vondatum', $post) ? $update['vondatum'] : $data->vondatum;
$bisdatum = array_key_exists('bisdatum', $post) ? $update['bisdatum'] : $data->bisdatum;
$vonstunde = array_key_exists('vonstunde', $post) ? $update['vonstunde'] : $data->vonstunde;
$zeitsperretyp_kurzbz = array_key_exists('zeitsperretyp_kurzbz', $post) ? $update['zeitsperretyp_kurzbz'] : $data->zeitsperretyp_kurzbz;
$result = $this->ZeitsperreModel->getSperreByDate($mitarbeiter_uid, $vondatum, $vonstunde, true);
$data = $this->getDataOrTerminateWithError($result);
if(hasData($result))
{
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitsperre', ['typ'=> current($data)->zeitsperretyp_kurzbz]), self::ERROR_TYPE_GENERAL);
}
//check if existing zeitaufzeichnung
if(in_array($zeitsperretyp_kurzbz, Zeitsperre_model::BLOCKIERENDE_ZEITSPERREN))
{
$result = $this->ZeitsperreModel->existsZeitaufzeichnung($mitarbeiter_uid, $vondatum, $bisdatum);
if(hasData($result))
$this->terminateWithError($this->p->t('zeitsperren', 'error_existingZeitaufzeichnung'), self::ERROR_TYPE_GENERAL);
}
}
if (!empty($update)) {
$update['updatevon'] = $loggedInUser;
$update['updateamum'] = date('c');
$result = $this->ZeitsperreModel->update($zeitsperre_id, $update);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
else
$this->terminateWithSuccess("no update");
}
public function delete($zeitsperre_id)
{
if (!is_numeric($zeitsperre_id) || (int)$zeitsperre_id <= 0)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Zeitsperre_id']), self::ERROR_TYPE_GENERAL);
}
//check if loggedin User is owner of the zeitsperre
$loggedInUser = getAuthUID();
$result = $this->ZeitsperreModel->load($zeitsperre_id);
$data = $this->getDataOrTerminateWithError($result);
$uid = current($data)->mitarbeiter_uid;
if($uid != $loggedInUser)
$this->terminateWithError($this->p->t('ui', 'noPermission'), self::ERROR_TYPE_GENERAL);
$result = $this->ZeitsperreModel->delete(
array('zeitsperre_id' => $zeitsperre_id)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function check_von_bis_datum($bisdatum)
{
$vondatum = $this->input->post('vondatum');
return $vondatum <= $bisdatum;
}
public function check_diff_intval($bisdatum)
{
$vondatum = $this->input->post('vondatum');
// Intervall in days
$vonTs = strtotime($vondatum);
$bisTs = strtotime($bisdatum);
$tage = ($bisTs - $vonTs) / 86400;
// if intervall > 14
return $tage <= 14;
}
}
@@ -12,6 +12,8 @@ class Zeitsperre_model extends DB_Model
$this->pk = 'zeitsperre_id';
}
const BLOCKIERENDE_ZEITSPERREN = ['Krank','Urlaub','ZA','DienstV','PflegeU','DienstF','CovidSB','CovidKS'];
/**
* Save or update Zeitsperre.
*
@@ -61,4 +63,128 @@ class Zeitsperre_model extends DB_Model
return $this->execQuery($qry);
}
/**
* get Zeitsperren of a user
*
* @param $uid mitarbeiteruid
* @param $bisgrenze @true show only entries of actual business year (1.9.- 31.8.)
*
* @return array
*/
public function getZeitsperrenUser($uid, $bisgrenze = true)
{
$qry = "
SELECT
tbl_zeitsperre.*, tbl_zeitsperretyp.*, tbl_erreichbarkeit.farbe AS erreichbarkeit_farbe,
tbl_erreichbarkeit.beschreibung AS erreichbarkeit_beschreibung,
CONCAT (ps.vorname, ' ', ps.nachname) as vertretung
FROM (campus.tbl_zeitsperre JOIN campus.tbl_zeitsperretyp USING (zeitsperretyp_kurzbz))
LEFT JOIN campus.tbl_erreichbarkeit USING (erreichbarkeit_kurzbz)
LEFT JOIN public.tbl_benutzer ON campus.tbl_zeitsperre.vertretung_uid = public.tbl_benutzer.uid
LEFT JOIN public.tbl_person ps USING (person_id)
WHERE mitarbeiter_uid= ?
";
if($bisgrenze)
{
$qry.="
AND (
(date_part('month',vondatum)>=9 AND date_part('year', vondatum)>='".(date('Y')-1)."')
OR
(date_part('month',vondatum)<9 AND date_part('year', vondatum)>='".(date('Y'))."')
)";
}
$qry.= " ORDER BY vondatum DESC";
return $this->execQuery($qry, array('mitarbeiter_uid' => $uid));
}
/**
* check a date for existing zeitsperre
*
* @param $uid mitarbeiteruid
* @param $datum datum to check
* @param $stunde stunde (default = null)
* @param bool $nurblockierend if only hr relevante zeitsperren have to be checked
*
* @return array
*/
public function getSperreByDate($uid, $datum, $stunde = null, $nurblockierend = false)
{
$parametersArray = [$datum, $datum];
$qry = "
SELECT
*
FROM
campus.tbl_zeitsperre
WHERE
vondatum <= ?
AND bisdatum>= ?";
if($nurblockierend)
{
$qry .= " AND zeitsperretyp_kurzbz IN ('"
. implode("','", self::BLOCKIERENDE_ZEITSPERREN)
. "')";
}
if(!is_null($stunde))
{
$parametersArray = array_merge(
$parametersArray,
[$datum, $stunde, $datum, $datum, $stunde, $datum]
);
$qry.=" AND
((vondatum= ? AND vonstunde<= ? OR vonstunde is null OR vondatum<> ?) AND
(bisdatum= ? AND bisstunde>= ? OR bisstunde is null OR bisdatum<> ?))";
}
array_push($parametersArray, $uid);
$qry .= "AND mitarbeiter_uid= ? ";
return $this->execQuery($qry, $parametersArray);
}
/**
* check a date for existing zeitsperre
*
* @param $uid mitarbeiteruid
* @param $vondatum datum in Format IS0
* @param $bisdatum datum in Format ISO
*
* @return array
*/
public function existsZeitaufzeichnung($uid, $vonDay, $bisDay)
{
try {
$from = new DateTime($vonDay);
$to = new DateTime($bisDay);
} catch (Exception $e) {
throw new Exception("Invalid date format");
}
//remove hour stamps
$from->setTime(0, 0, 0);
$to->setTime(0, 0, 0)->modify('+1 day');
$fromSql = $from->format('Y-m-d');
$toSql = $to->format('Y-m-d');
$params = [$uid, $fromSql, $toSql];
$qry = "
SELECT *
FROM campus.tbl_zeitaufzeichnung
WHERE uid = ?
AND start >= ?
AND ende < ? ";
$result = $this->execQuery($qry, $params);
return $result;
}
}
@@ -23,6 +23,7 @@ $includesArray = array(
'public/css/components/FormUnderline.css',
'public/css/Cis4/Cms.css',
'public/css/Cis4/Studium.css',
'public/css/Cis4/Zeitsperren.css',
),
'customJSs' => array(
'vendor/npm-asset/primevue/accordion/accordion.min.js',
+39
View File
@@ -0,0 +1,39 @@
/* Repositioning clear icon Datepicker for not being outside the textfield */
/* Wrapper */
.dp__input_wrap {
position: relative;
}
/* calender-Icon left */
.dp__input_icon {
position: absolute;
left: 10px;
right: auto;
top: 50%;
transform: translateY(-50%);
}
/* Clear-Icon right */
.dp__clear_icon {
position: absolute;
right: 10px;
left: auto;
top: 50%;
transform: translateY(-50%);
}
/* padding for Icons */
.dp__input {
padding-left: 36px !important;
padding-right: 36px !important;
}
.info-feedback {
display: block;
font-size: 0.875em;
color: #0d6efd; /* Bootstrap primary */
}
.is-info {
border-color: #0d6efd;
}
+70
View File
@@ -0,0 +1,70 @@
/**
* 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 {
getTimelocksUser(uid) {
return {
method: 'get',
url: '/api/frontend/v1/Zeitsperren/getZeitsperrenUser/' + uid
};
},
getTypenZeitsperren(){
return {
method: 'get',
url: '/api/frontend/v1/Zeitsperren/getTypenZeitsperren/'
};
},
getTypenErreichbarkeit(){
return {
method: 'get',
url: '/api/frontend/v1/Zeitsperren/getTypenErreichbarkeit/'
};
},
getStunden(){
return {
method: 'get',
url: '/api/frontend/v1/Zeitsperren/getStunden/'
};
},
addZeitsperre(uid, params) {
return {
method: 'post',
url: '/api/frontend/v1/Zeitsperren/add/' + uid,
params
};
},
editZeitsperre(zeitsperre_id, params) {
return {
method: 'post',
url: '/api/frontend/v1/Zeitsperren/update/' + zeitsperre_id,
params
};
},
loadZeitsperre(zeitsperre_id) {
return {
method: 'get',
url: '/api/frontend/v1/Zeitsperren/loadZeitsperre/' + zeitsperre_id
};
},
deleteZeitsperre(zeitsperre_id) {
return {
method: 'post',
url: '/api/frontend/v1/Zeitsperren/delete/' + zeitsperre_id
};
}
};
+7
View File
@@ -16,6 +16,7 @@ import AbgabetoolStudent from "../../components/Cis/Abgabetool/AbgabetoolStudent
import AbgabetoolMitarbeiter from "../../components/Cis/Abgabetool/AbgabetoolMitarbeiter.js";
import DeadlineOverview from "../../components/Cis/Abgabetool/DeadlineOverview.js";
import Studium from "../../components/Cis/Studium/Studium.js";
import Zeitsperren from "../../components/Cis/Zeitsperren/Zeitsperren.js";
import ApiRenderers from '../../api/factory/renderers.js';
import ApiRouteInfo from '../../api/factory/routeinfo.js';
@@ -216,6 +217,12 @@ const router = VueRouter.createRouter({
};
},
},
{
path: `/Cis/Zeitsperren`,
name: 'Zeitsperren',
component: Zeitsperren,
props: true
},
]
})
@@ -0,0 +1,673 @@
import {CoreFilterCmpt} from "../../filter/Filter.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';
import ApiAuthinfo from '../../../api/factory/authinfo.js';
import ApiTimelocks from "../../../api/factory/cis/zeitsperren.js";
import ApiStvAbschlusspruefung from "../../../api/factory/stv/abschlusspruefung.js";
export default {
name: 'ZeitsperrenComponent',
components: {
CoreFilterCmpt,
FormForm,
FormInput,
PvAutoComplete
},
data(){
return {
uid: null,
statusNew: true,
timeRecordingLockedUntil: '2015-08-31', //TODO(Manu) check if needed
typesTimeLocks: ["Urlaub", "PflegeU", "ZA", "Krank", "DienstF", "DienstV", "CovidSB", "CovidKS"],
typesHideStunden: ["Urlaub", "ZA", "Krank", "DienstF", "DienstV", "CovidSB", "CovidKS"],
listTypenZeitsperren: [],
listTypenErreichbarkeit: [],
listStunden: [],
tabulatorOptions: null,
tabulatorEvents: [],
originalData: {},
zeitsperreData: {
vondatum : new Date(),
bisdatum: new Date(),
vonISO : "00:00:00", //later
bisISO: "23:59:59", //later
erreichbarkeit_kurzbz: 'n',
zeitsperretyp_kurzbz: 'Arzt',
vonstunde: null,
bisstunde: null
},
changedData: {},
selectedVertretung: null,
filteredMitarbeiter: [],
abortController: {
mitarbeiter: null
},
};
},
computed: {
dienstverhinderungen() {
return {
"Eheschließung": "a) " + this.$p.t('zeitsperren', 'eheschliessung'),
"Geburt eigenes Kind": "b) " + this.$p.t('zeitsperren', 'geburt'),
"Heirat Kind/Geschwister": "c) " + this.$p.t('zeitsperren', 'heirat'),
"Eigene Sponsion/Promotion": "d) " + this.$p.t('zeitsperren', 'sponsion'),
"Lebensbedr. Erkrankung P/K/E": "e) " + this.$p.t('zeitsperren', 'erkrankung_lebensbedr'),
"Ableben P/K/E": "f) " + this.$p.t('zeitsperren', 'ableben'),
"Bestattung G/S/G": "g) " + this.$p.t('zeitsperren', 'bestattung'),
"Wohnungswechsel": "h) " + this.$p.t('zeitsperren', 'umzug'),
"Bundesheer": "i) " + this.$p.t('zeitsperren', 'bundesheer'),
"Volksschultag": "j) " + this.$p.t('zeitsperren', 'volksschultag')};
},
showInfo(){
return this.zeitsperreData.zeitsperretyp_kurzbz === 'DienstF';
},
},
methods: {
actionEditZeitsperre(zeitsperre_id){
this.statusNew = false;
return this.$api
.call(ApiTimelocks.loadZeitsperre(zeitsperre_id))
.then(response => {
this.originalData = structuredClone(response.data);
this.zeitsperreData = structuredClone(response.data);
this.selectedVertretung = {
label: this.getPersonLabel(this.zeitsperreData.ma_titelpre, this.zeitsperreData.ma_nachname, this.zeitsperreData.ma_vorname, this.zeitsperreData.ma_titelpost, this.zeitsperreData.vertretung_uid),
person_id: this.zeitsperreData.ma_person_id,
mitarbeiter_uid: this.zeitsperreData.vertretung_uid
};
})
.catch(this.$fhcAlert.handleSystemError);
},
actionDeleteZeitsperre(zeitsperre_id){
this.$fhcAlert
.confirmDelete()
.then(result => result
? zeitsperre_id
: Promise.reject({ handled: true })
)
.then(() => this.deleteZeitsperre(zeitsperre_id))
.catch(this.$fhcAlert.handleSystemError);
},
saveZeitsperre(zeitsperreId = null) {
const isNew = !zeitsperreId;
let payload = isNew
? { ...this.zeitsperreData } // add
: this.getChangedFields(this.originalData, // edit
this.zeitsperreData);
if (!isNew && Object.keys(payload).length === 0) {
return Promise.resolve();
}
const request = isNew
? ApiTimelocks.addZeitsperre(this.uid, payload)
: ApiTimelocks.editZeitsperre(zeitsperreId, payload);
return this.$refs.dataZeitsperre
.call(request)
.then(() => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
this.reset();
this.reload();
})
.catch(this.$fhcAlert.handleSystemError);
},
deleteZeitsperre(zeitsperre_id){
return this.$api
.call(ApiTimelocks.deleteZeitsperre(zeitsperre_id))
.then(response => {
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
})
.catch(this.$fhcAlert.handleSystemError)
.finally(()=> {
this.reload();
});
},
searchMitarbeiter(event) {
if (this.abortController.mitarbeiter) {
this.abortController.mitarbeiter.abort();
}
this.abortController.mitarbeiter = new AbortController();
return this.$api
.call(ApiStvAbschlusspruefung.getMitarbeiter(event.query))
.then(result => {
this.filteredMitarbeiter = [];
for (let mitarbeiter of result.data.retval) {
this.filteredMitarbeiter.push(
{
label: this.getPersonLabel(
mitarbeiter.titelpre,
mitarbeiter.nachname,
mitarbeiter.vorname,
mitarbeiter.titelpost,
mitarbeiter.mitarbeiter_uid
),
person_id: mitarbeiter.person_id,
mitarbeiter_uid: mitarbeiter.mitarbeiter_uid
}
);
}
});
},
getPersonLabel(titelpre, nachname, vorname, titelpost, uid) {
if(!uid)
return '';
return nachname + ' ' + vorname + (titelpre ? ' ' + titelpre : '') + (titelpost ? ' ' + titelpost : '') + (uid ? ' (' + uid + ')' : '');
},
reload() {
if (this.$refs.table)
this.$refs.table.reloadTable();
},
reset(){
this.statusNew = true;
this.selectedVertretung = null;
this.zeitsperreData = {
vondatum : new Date(),
bisdatum: new Date(),
vonISO : "00:00:00", //later
bisISO: "23:59:59", //later
erreichbarkeit_kurzbz: 'n',
zeitsperretyp_kurzbz: 'Arzt',
vonstunde: null,
bisstunde: null
};
this.originalData = {};
},
handleChangeVonStunde(){
let stunde = this.zeitsperreData.vonstunde;
const result = this.listStunden.find(item => item.stunde === stunde);
if (!result) {
this.zeitsperreData.vonISO = '00:00:00';
return;
}
this.zeitsperreData.vonISO = result.beginn;
},
handleChangeBisStunde(){
let stunde = this.zeitsperreData.bisstunde;
const result = this.listStunden.find(item => item.stunde === stunde);
if (!result) {
this.zeitsperreData.bisISO = '23:59:59';
return;
}
this.zeitsperreData.bisISO = result.ende;
},
handleStunden(){
if (this.typesHideStunden.includes(this.zeitsperreData.zeitsperretyp_kurzbz)){
this.zeitsperreData.vonstunde = null;
this.zeitsperreData.bisstunde = null;
this.zeitsperreData.vonISO = '00:00:00';
this.zeitsperreData.bisISO = '23:59:59';
}
},
copyDateForBis(){
this.zeitsperreData.bisdatum = this.zeitsperreData.vondatum;
},
getChangedFields(original, current) {
const diff = {};
Object.keys(current).forEach((key) => {
if (current[key] !== original[key]) {
diff[key] = current[key];
}
});
return diff;
},
},
watch: {
selectedVertretung(newVal) {
this.zeitsperreData.vertretung_uid = newVal?.mitarbeiter_uid || null;
},
'zeitsperreData.zeitsperretyp_kurzbz'(newVal) {
if (newVal === 'DienstV') {
// set first key as default
if (!this.zeitsperreData.bezeichnung) {
const firstKey = Object.keys(this.dienstverhinderungen)[0];
this.zeitsperreData.bezeichnung = firstKey;
}
} else {
this.zeitsperreData.bezeichnung = '';
}
}
},
created() {
this.$api.call(ApiAuthinfo.getAuthUID()).then(res => {
//check if there is a user, passed via route
const urlUid = this.$route?.query?.uid;
this.uid = urlUid ? urlUid : res.data.uid;
this.tabulatorOptions = {
ajaxURL: 'dummy',
ajaxRequestFunc: () =>
this.$api.call(ApiTimelocks.getTimelocksUser(this.uid)),
ajaxResponse: (url, params, response) => response.data,
columns: [
{title:"bezeichnung", field:"bezeichnung"},
{title:"Grund", field:"beschreibung"},
{title:"Von", field:"vondatum",
formatter: function (cell) {
const dateStr = cell.getValue();
if (!dateStr) return "";
const date = new Date(dateStr);
return date.toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
}
},
{title:"Bis", field:"bisdatum",
formatter: function (cell) {
const dateStr = cell.getValue();
if (!dateStr) return "";
const date = new Date(dateStr);
return date.toLocaleString("de-DE", {
day: "2-digit",
month: "2-digit",
year: "numeric",
});
}
},
{title:"vonstunde", field:"vonstunde", visible: false},
{title:"bisstunde", field:"bisstunde", visible: false},
{title:"Vertretung", field:"vertretung"},
{title:"Erreichbarkeit", field:"erreichbarkeit_beschreibung"},
{title:"zeitsperre_id", field:"zeitsperre_id", visible: false},
{title:"mitarbeiter_uid", field:"mitarbeiter_uid", visible: false},
{title:"freigabeamum", field:"freigabeamum", visible: false,
formatter: function (cell) {
const value = cell.getValue();
return value === null
? ''
: '<i class="fa fa-check text-success"></i>';
}
},
{title: 'Aktionen', field: 'actions',
minWidth: 150, // Ensures Action-buttons will be always fully displayed
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement('div');
container.className = "d-flex gap-2";
let button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-edit"></i>';
button.title = this.$p.t('ui', 'bearbeiten');
button.addEventListener('click', (event) =>
this.actionEditZeitsperre(cell.getData().zeitsperre_id)
);
if(cell.getData().zeitsperretyp_kurzbz == 'DienstV' || cell.getData().zeitsperretyp_kurzbz == 'ZVerfueg'){
button.disabled = true;
}
//TODO(Manu) check if needed
if(this.typesTimeLocks.includes(cell.getData().zeitsperretyp_kurzbz) && (cell.getData().vondatum < this.timeRecordingLockedUntil)){
button.disabled = true;
}
container.append(button);
button = document.createElement('button');
button.className = 'btn btn-outline-secondary btn-action';
button.innerHTML = '<i class="fa fa-xmark"></i>';
button.title = this.$p.t('ui', 'loeschen');
button.addEventListener('click', () =>
//this.deleteZeitsperre(cell.getData().zeitsperre_id)
this.actionDeleteZeitsperre(cell.getData().zeitsperre_id)
);
if(cell.getData().zeitsperretyp_kurzbz == 'Urlaub' || cell.getData().zeitsperretyp_kurzbz == 'ZVerfueg'){
button.disabled = true;
}
//TODO(Manu) check if needed
if(this.typesTimeLocks.includes(cell.getData().zeitsperretyp_kurzbz) && (cell.getData().vondatum < this.timeRecordingLockedUntil)){
button.disabled = true;
}
container.append(button);
return container;
},
frozen: true
},
]
};
this.tabulatorEvents = [
{
event: 'tableBuilt',
handler: async() => {
await this.$p.loadCategory(['global', 'person', 'zeitsperren', 'ui', 'abschlusspruefung']);
let cm = this.$refs.table.tabulator.columnManager;
cm.getColumnByField('bezeichnung').component.updateDefinition({
title: this.$p.t('person', 'grund')
});
cm.getColumnByField('beschreibung').component.updateDefinition({
title: this.$p.t('global', 'bezeichnung')
});
cm.getColumnByField('vondatum').component.updateDefinition({
title: this.$p.t('ui', 'von')
});
cm.getColumnByField('bisdatum').component.updateDefinition({
title: this.$p.t('global', 'bis')
});
cm.getColumnByField('vonstunde').component.updateDefinition({
title: this.$p.t('zeitsperren', 'stunde_von')
});
cm.getColumnByField('bisstunde').component.updateDefinition({
title: this.$p.t('zeitsperren', 'stunde_bis')
});
cm.getColumnByField('vertretung').component.updateDefinition({
title: this.$p.t('person', 'vertretung')
});
cm.getColumnByField('erreichbarkeit_beschreibung').component.updateDefinition({
title: this.$p.t('person', 'erreichbarkeit')
});
cm.getColumnByField('freigabeamum').component.updateDefinition({
title: this.$p.t('abschlusspruefung', 'freigabe')
});
/* cm.getColumnByField('actions').component.updateDefinition({
title: this.$p.t('global', 'aktionen')
});*/
}
}
];
});
this.$api
.call(ApiTimelocks.getTypenZeitsperren())
.then(result => {
this.listTypenZeitsperren = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiTimelocks.getTypenErreichbarkeit())
.then(result => {
this.listTypenErreichbarkeit = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
this.$api
.call(ApiTimelocks.getStunden())
.then(result => {
this.listStunden = result.data;
})
.catch(this.$fhcAlert.handleSystemError);
},
template: /* html */`
<div class="zeitsperre">
<h4>{{$p.t('zeitsperren', 'header_zeitsperren')}} ({{uid}}) </h4>
<form-form class="row g-3 mt-3" ref="dataZeitsperre">
<div class= "w-50">
<div class="row mb-3">
<form-input
type="select"
:class="showInfo ? 'is-info' : ''"
name="zeitsperretyp_kurzbz"
:label="$p.t('person/grund')"
v-model="zeitsperreData.zeitsperretyp_kurzbz"
@change="handleStunden"
>
<option
v-for="typ in listTypenZeitsperren"
:key="typ.zeitsperretyp_kurzbz"
:value="typ.zeitsperretyp_kurzbz"
:disabled="typ.zeitsperretyp_kurzbz == 'Urlaub'"
>
{{typ.beschreibung}}
</option>
</form-input>
<div v-if="showInfo" class="info-feedback">
<strong> Dienstfreistellungen</strong> nur in Absprache mit HR Service eintragen!
</div>
</div>
<div v-if="zeitsperreData.zeitsperretyp_kurzbz == 'DienstV'" class="row mb-3">
<form-input
type="select"
name="beschreibung"
:label="$p.t('ui/bezeichnung')"
v-model="zeitsperreData.bezeichnung"
>
<option v-for="(beschreibung, key) in dienstverhinderungen"
:key="key"
:value="key">{{beschreibung}}
</option>
</form-input>
</div>
<div v-else class="row mb-3">
<form-input
type="text"
name="beschreibung"
:label="$p.t('ui/bezeichnung')"
v-model="zeitsperreData.bezeichnung"
>
</form-input>
</div>
</div>
<div>
<div class="row">
<div class="mb-3 col-2">
<form-input
type="DatePicker"
name="vondatum"
:label="$p.t('ui/from')"
v-model="zeitsperreData.vondatum"
auto-apply
:enable-time-picker="false"
format="dd.MM.yyyy"
text-input
preview-format="dd.MM.yyyy"
:teleport="true"
required
>
</form-input>
</div>
<div class="mb-3 col-1 d-flex align-items-end">
<button
class="btn btn-outline-secondary"
title="Für Bis-Datum übernehmen"
@click.prevent="copyDateForBis"
>
<i class="fa-solid fa-arrow-down"></i>
</button>
</div>
<div class="mb-3 col-3">
<form-input
v-if="!typesHideStunden.includes(zeitsperreData.zeitsperretyp_kurzbz)"
type="select"
name="vonstunde"
:label="$p.t('zeitsperren/stunde')"
v-model="zeitsperreData.vonstunde"
@change="handleChangeVonStunde"
>
<option value='null'>*</option>
<option
v-for="std in listStunden"
:key="std.stunde"
:value="std.stunde"
>
{{std.stunde}} ({{std.beginn}} - {{std.ende}})
</option>
</form-input>
</div>
<!-- Uncomment to use timestamp VON
<div class="mb-3 col-3">
<form-input
type="text"
name="vonISO"
label="vonISO"
v-model="zeitsperreData.vonISO"
auto-apply
:enable-time-picker="true"
format="dd.MM.yyyy HH:mm"
text-input
preview-format="dd.MM.yyyy HH:mm"
:teleport="true"
>
{{timestampHoursVon}}
</form-input>
</div>
-->
</div>
<div class="row">
<div class="mb-3 col-2">
<form-input
type="DatePicker"
name="bisdatum"
:label="$p.t('global/bis')"
v-model="zeitsperreData.bisdatum"
auto-apply
:enable-time-picker="false"
format="dd.MM.yyyy"
text-input
preview-format="dd.MM.yyyy"
:teleport="true"
required
>
</form-input>
</div>
<div class="mb-3 col-1"></div>
<div class="mb-3 col-3">
<form-input
v-if="!typesHideStunden.includes(zeitsperreData.zeitsperretyp_kurzbz)"
type="select"
name="bisstunde"
:label="$p.t('zeitsperren/stunde')"
v-model="zeitsperreData.bisstunde"
@change="handleChangeBisStunde"
>
<option value='null'>*</option>
<option
v-for="std in listStunden"
:key="std.stunde"
:value="std.stunde"
>
{{std.stunde}} ({{std.beginn}} - {{std.ende}})
</option>
</form-input>
</div>
<!-- Uncomment to use timestamp BIS
<div class="mb-3 col-3">
<form-input
type="text"
name="bisISO"
label="bisISO"
v-model="zeitsperreData.bisISO"
auto-apply
:enable-time-picker="true"
format="dd.MM.yyyy HH:mm"
text-input
preview-format="dd.MM.yyyy HH:mm"
:teleport="true"
>
</form-input>
</div>
-->
</div>
<div class= "w-50">
<div class="row mb-3">
<form-input
type="autocomplete"
name="vertretung_uid"
:label="$p.t('person/vertretung')"
v-model="selectedVertretung"
optionLabel="label"
optionValue="mitarbeiter_uid"
dropdown
forceSelection
:suggestions="filteredMitarbeiter"
@complete="searchMitarbeiter"
:min-length="3"
>
</form-input>
</div>
</div>
<div class="row align-items-end">
<div class="mb-3 col-4">
<form-input
type="select"
name="erreichbarkeit"
:label="$p.t('person/erreichbarkeit')"
v-model="zeitsperreData.erreichbarkeit_kurzbz"
>
<option
v-for="typ in listTypenErreichbarkeit"
:key="typ.erreichbarkeit_kurzbz"
:value="typ.erreichbarkeit_kurzbz"
>
{{typ.beschreibung}}
</option>
</form-input>
</div>
<div class="mb-3 col-3">
<button
v-if="statusNew"
type="button"
class="btn btn-primary"
@click="saveZeitsperre()">
{{$p.t('zeitsperren', 'addZeitsperre')}}
</button>
<button
v-else
type="button"
class="btn btn-warning"
@click="saveZeitsperre(zeitsperreData.zeitsperre_id)">
{{$p.t('zeitsperren', 'saveZeitsperre')}}
</button>
</div>
</div>
</div>
</form-form>
<div class="d-flex align-items-start text-muted small">
<i class="fa fa-circle-info me-2 mt-1"></i>
<div>
<strong>{{$p.t('alert', 'attention')}}</strong><br>
{{$p.t('zeitsperren', 'info_zeitsperrenMoreDays')}}
</div>
</div>
<hr>
<core-filter-cmpt
v-if="tabulatorOptions"
ref="table"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
table-only
:side-menu="false"
reload
:reload-btn-infotext="this.$p.t('table', 'reload')"
>
</core-filter-cmpt>
</div>
`
};
+463
View File
@@ -52851,6 +52851,469 @@ I have been informed that I am under no obligation to consent to the transmissio
)
),
// ### Refactor Messages END
//// ### ZEITSPERREN START
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'eheschliessung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Eigene Eheschließung oder Verpartnerung (3 Tage)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Own marriage or civil partnership (3 days)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'geburt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Geburt eines Kindes der Ehefrau/Lebensgefährtin (2 Tage)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Birth of a child of the wife/partner (2 days)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'heirat',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Eheschließung oder Verpartnerung eines Kindes/eigener Geschwister (1 Tag)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Marriage or civil partnership of a child or own sibling (1 day)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'sponsion',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Teilnahme an eigener Sponsion/Promotion (1 Tag)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Participation in own graduation/promotion ceremony (1 day)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'erkrankung_lebensbedr',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Lebensbedrohliche Erkrankung Partner/Kinder/Eltern (3 Tage)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Life-threatening illness of partner/children/parents (3 days)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'ableben',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ableben Partner/Kinder/Elternteil (3 Tage)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Death of partner/children/parent (3 days)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'bestattung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Teilnahme an Bestattung Geschwister/Schwiegereltern/eigener Großeltern (1 Tag)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Attendance at the funeral of siblings/parents-in-law/own grandparents (1 day)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'umzug',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Wohnungswechsel in eigenen Haushalt (2 Tage)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Moving to your own home (2 days)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'bundesheer',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Einberufung Bundesheer',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Conscription of the Austrian Armed Forces',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'volksschultag',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'erster Volksschultag (1 Tag)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'First day of primary school (1 day)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'error_VonDatumGroesserAlsBisDatum',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'VonDatum ist größer als BisDatum',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'The start date is greater than the end date.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'error_zeitraumAuffallendHoch',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Achtung, eingegebener Zeitraum ist auffallend hoch. \nWollen Sie die Daten dennoch speichern?',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Attention, the entered time period is unusually long. Do you still want to save the data?',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'stunde',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Stunde(inklusive)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Hour(inclusive)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'stunde_von',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Stunde(von)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'hour(from)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'stunde_bis',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Stunde(bis)',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'hour(to)',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'addZeitsperre',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zeitsperre hinzufügen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'add Timelock',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'saveZeitsperre',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zeitsperre speichern',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'save Timelock',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'noAdmin',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Für diese Aktion benötigen Sie Administratorenrechte',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'You need administrator rights to perform this action.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'noPermission',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Sie haben keine Berechtigung, für einen anderen User einen Datensatz anzulegen, zu bearbeiten oder zu löschen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'You do not have permission to create, edit, or delete a record for another user.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'info_zeitsperrenMoreDays',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Es werden alle eingegebenen Tage bei der Berechnung berücksichtigt. Daher müssen mehrtägige Zeitsperren an Unterbrechungen wie Wochenenden oder Feiertagen unterteilt werden!',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'All entered days will be included in the calculation. Therefore, multi-day time blocks must be broken down by breaks such as weekends or holidays!',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'header_zeitsperren',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Meine Zeitsperren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'My timelocks',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'error_existingZeitaufzeichnung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Es existiert mindestens eine Zeitaufzeichnung im angegebenen Zeitraum',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'At least one time recording exists within the specified period.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'zeitsperren',
'phrase' => 'error_existingZeitsperre',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zeitsperre vom Typ {typ} vorhanden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Time lock of type {type} exists',
'description' => '',
'insertvon' => 'system'
)
)
),
/// ### ZEITSPERREN END
);