Merge branch 'master' into fronkdev
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -11,6 +11,8 @@ todo
|
||||
files/*
|
||||
vendor/
|
||||
data/
|
||||
logs/
|
||||
xdebug_traces/
|
||||
phinx.php
|
||||
|
||||
*.sql
|
||||
|
||||
@@ -1,105 +1,71 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><?=MFAPPNAME_FULL?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!-- App favicon -->
|
||||
<link rel="shortcut icon" href="<?=self::getResourcePath()?>assets/images/favicon.ico">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><?=MFAPPNAME_FULL?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!-- App favicon -->
|
||||
<link rel="shortcut icon" href="<?=self::getResourcePath()?>assets/images/favicon.ico">
|
||||
|
||||
<!-- App css -->
|
||||
<link href="<?=self::getResourcePath()?>fontawesome/css/all.min.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap.min.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/icons.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/app.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/leaflet.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/thetool.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/libs/select2/select2.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>css/bootstrap-datepicker3.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>plugins/summernote/summernote-bs4.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>datatables/datatables.min.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/libs/select2/select2.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.de.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/geo/geo.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.MakiMarkers.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/popper.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/bootstrap-select.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-autocomplete.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>datatables/datatables.min.js"></script>
|
||||
|
||||
<?php if(MFAPPNAME == "devthetool"): ?>
|
||||
<!-- App css -->
|
||||
<link href="<?=self::getResourcePath()?>fontawesome/css/all.min.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap.min.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/icons.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/app.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/leaflet.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/thetool.css?<?=date('U')?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/libs/select2/select2.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>css/bootstrap-datepicker3.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>plugins/summernote/summernote-bs4.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>plugins/notification/notify.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>datatables/datatables.min.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/libs/select2/select2.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.de.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/geo/geo.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.MakiMarkers.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/popper.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/bootstrap-select.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-autocomplete.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>datatables/datatables.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>plugins/notification/notify.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.mfNotify = <?=isset($mfNotify) ? json_encode($mfNotify) : "null"; ?>;
|
||||
window.TT_CONFIG = {};
|
||||
|
||||
<?php
|
||||
if(isset($JSGlobals) && is_array($JSGlobals) && count($JSGlobals)):
|
||||
foreach($JSGlobals as $key => $value): ?>
|
||||
window.TT_CONFIG.<?=$key?> = <?=is_array($value) ? json_encode($value) : "'$value'"; ?>;
|
||||
<?php endforeach; endif;?>
|
||||
</script>
|
||||
|
||||
<?php if(MFAPPNAME == "devthetool"): ?>
|
||||
<style type="text/css">
|
||||
body {
|
||||
border-left: 8px dashed #f672a7;
|
||||
}
|
||||
body {
|
||||
border-left: 8px dashed #f672a7;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Navigation Bar-->
|
||||
<header id="topnav">
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/topbar.php"); ?>
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/menu.php"); ?>
|
||||
</header>
|
||||
<!-- End Navigation Bar-->
|
||||
|
||||
<body>
|
||||
|
||||
<!-- Navigation Bar-->
|
||||
<header id="topnav">
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/topbar.php"); ?>
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/menu.php"); ?>
|
||||
</header>
|
||||
<!-- End Navigation Bar-->
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="container-fluid">
|
||||
|
||||
<?php if(isset($_flash_set) && $_flash_set == true): ?>
|
||||
<?php if(isset($mfError) && !empty($mfError)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-ban"></i> Fehler</h5>
|
||||
<?=$mfError?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($mfWarning) && !empty($mfWarning)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-warning alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-exclamation-triangle"></i> Warnung</h5>
|
||||
<?=$mfWarning?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($mfInfo) && !empty($mfInfo)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-info alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-info"></i> Info</h5>
|
||||
<?=$mfInfo?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($mfSuccess) && !empty($mfSuccess)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-check"></i> Erfolgreich</h5>
|
||||
<?=$mfSuccess?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
<div class="container-fluid">
|
||||
|
||||
@@ -177,8 +177,18 @@ if (isset($_GET['returnto']) && $_GET['returnto'] == "device-detail") {
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="autobackup">Autobackup</label>
|
||||
<div class="col-lg-10">
|
||||
<div class="custom-control custom-switch mt-1">
|
||||
<input type="checkbox" <?= ($device->autobackup == "1") ? "checked='checked'" : "" ?> class="custom-control-input" value="1" id="autobackup" name="autobackup">
|
||||
<label class="custom-control-label no-user-select" for="autobackup">(Es wird täglich um 24:00 ein Device Backup erstellt)</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="serial">Seriennummer</label>
|
||||
<div class="col-lg-10">
|
||||
|
||||
@@ -67,7 +67,7 @@ $pagination_entity_name = "Device";
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th class="pr-1"></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -97,7 +97,9 @@ $pagination_entity_name = "Device";
|
||||
} else {
|
||||
$backup = '<i class="fa-regular fa-ban" title="Kein Configbackup"><span style="display: none">N/A</span></i>';
|
||||
}
|
||||
|
||||
if ($device->autobackup==1) {
|
||||
$backup = '<i class="fa-regular fa-circle-a mr-1"><span style="display: none">Auto</span></i>'.$backup;
|
||||
}
|
||||
if ($device->pop->id) {
|
||||
$destination = '<a href="' . self::getUrl("Pop", "Detail", ["id" => $device->pop->id]) . '">' . $device->pop->name . '</a>';
|
||||
} else if ($device->addr_street) {
|
||||
@@ -153,7 +155,7 @@ $pagination_entity_name = "Device";
|
||||
var columndefs = {type: 'ip-address', targets: 4};
|
||||
|
||||
var columnfilter = [9];
|
||||
var columnoptions = '<option value=""></option><option value="OK">OK</option><option value="AGED">AGED</option><option value="N/A">N/A</option>';
|
||||
var columnoptions = '<option value=""></option><option value="OK">OK</option><option value="AGED">AGED</option><option value="N/A">N/A</option><option value="Auto">AUTO</option>';
|
||||
$(document).ready(function () {
|
||||
|
||||
});
|
||||
|
||||
@@ -206,10 +206,8 @@ $pagination_entity_name = "Pops";
|
||||
markers[building.id] = marker;
|
||||
});
|
||||
|
||||
console.log(all_coords);
|
||||
// calculate center position
|
||||
mapCenterPos = GetCenterFromDegrees(all_coords);
|
||||
console.log(mapCenterPos);
|
||||
buildingMap.setView(mapCenterPos, 12);
|
||||
|
||||
return true;
|
||||
@@ -228,7 +226,6 @@ $pagination_entity_name = "Pops";
|
||||
filter: filter
|
||||
}, function (success) {
|
||||
if (success.status == "OK") {
|
||||
console.log(success);
|
||||
|
||||
if (Array.isArray(success.result.buildings)) {
|
||||
buildings = success.result.buildings;
|
||||
|
||||
@@ -18,7 +18,7 @@ for ($i = 1; $i <= 25; $i++) {
|
||||
$kw = date('W', $time);
|
||||
$year = date('Y', $time);
|
||||
$timestamp_montag = strtotime("{$year}-W{$kw}");
|
||||
$timestamp_freitag = strtotime("{$year}-W{$kw}-5");
|
||||
$timestamp_freitag = strtotime("{$year}-W{$kw}-7");
|
||||
$weeks[$time] = "KW" . $kw . " " . $year . " (" . date('d.m', $timestamp_montag) . "-" . date('d.m', $timestamp_freitag) . ")";
|
||||
$time = $time - 604800;
|
||||
}
|
||||
@@ -126,7 +126,9 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
data-approval="<?= $timerecordingCategories->approval ?>"
|
||||
data-comment="<?= $timerecordingCategories->require_comment ?>"
|
||||
data-hourday="<?= $timerecordingCategories->hourday ?>"
|
||||
data-businesstrip="<?= $timerecordingCategories->businesstrip ?>"><?= $timerecordingCategories->name ?></option>
|
||||
data-businesstrip="<?= $timerecordingCategories->businesstrip ?>"
|
||||
data-homeoffice="<?= ($timerecordingCategories->hourday == 1) ? 1 : 0 ?>"><?= $timerecordingCategories->name ?></option>
|
||||
</option>
|
||||
<?php
|
||||
endif;
|
||||
endforeach; ?>
|
||||
@@ -176,33 +178,50 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
<label class="col-form-label" for="comment">Anmerkung</label>
|
||||
<input type="text" id="comment" name="comment" class="form-control"/>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-lg-4" id="div-calc-overtime" style="display:none">
|
||||
<label class="col-form-label mobile-hide" for="comment"> </label>
|
||||
<div class=" d-block" style="padding: 0.45rem 0.9rem;" id="calc-overtime"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row" id="businesstrip-div">
|
||||
|
||||
<div class="col-lg-2 mb-2">
|
||||
<div class="row">
|
||||
<div class="col-lg-1 mb-2" id="homeoffice-div">
|
||||
|
||||
<div class="form-check text-center mt-1">
|
||||
<input class="form-check-input" type="checkbox" name="businesstrip" value=""
|
||||
id="businesstrip">
|
||||
<label class="form-check-label" for="businesstrip" value="1">
|
||||
<input class="form-check-input" type="checkbox" name="homeoffice"
|
||||
id="homeoffice" value="1">
|
||||
<label class="form-check-label" for="homeoffice">
|
||||
Homeoffice
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-2 mb-2 businesstrip-div">
|
||||
|
||||
<div class="form-check text-center mt-1">
|
||||
<input class="form-check-input" type="checkbox" name="businesstrip"
|
||||
id="businesstrip" value="1">
|
||||
<label class="form-check-label" for="businesstrip">
|
||||
Dienstreise > 12KM
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-2">
|
||||
<div class="col-lg-2 businesstrip-div">
|
||||
<input style="display:none" type="text" id="businesstrip_info" name="businesstrip_info"
|
||||
placeholder="Ort"
|
||||
class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" row mt-2">
|
||||
<div class="col-lg-2 ">
|
||||
<div class="col-lg-3 ">
|
||||
<button id="submit-button" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button id="cancel-button" type="button" class="btn btn-secondary" style="display:none">
|
||||
Abbrechen
|
||||
</button>
|
||||
|
||||
<button style="display:none" id="auto-workinghours-button" type="button" class="btn btn-dark">
|
||||
Arbeitswoche verbuchen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -290,7 +309,7 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
</div>
|
||||
<div class="col text-center">
|
||||
<div class="input-group ">
|
||||
<label class="col-form-label form-control fixed-state"><span
|
||||
<label id="plushours-label" class="col-form-label form-control fixed-state"><span
|
||||
class="text-bold">Gutzeit: </span><span
|
||||
id="plushours"
|
||||
class="ml-1 text-normal"></span></label>
|
||||
@@ -338,7 +357,10 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
let insertUrl = "<?= self::getUrl("Timerecording", "save") ?>";
|
||||
let deleteUrl = "<?= self::getUrl("Timerecording", "delete") ?>";
|
||||
let requestUrl = "<?= self::getUrl("Timerecording", "api", ['do' => 'getTimerecordings']) ?>";
|
||||
let autoWorkinghoursUrl = "<?= self::getUrl("Timerecording", "api", ['do' => 'fillWorkinghours']) ?>";
|
||||
let checkWorkinghoursUrl = "<?= self::getUrl("Timerecording", "api", ['do' => 'checkWorkinghours']) ?>";
|
||||
</script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>js/pages/timerecording/index.js?<?= date('U') ?>"></script>
|
||||
|
||||
|
||||
408
Layout/default/TimerecordingCalendar/Index.php
Normal file
408
Layout/default/TimerecordingCalendar/Index.php
Normal file
@@ -0,0 +1,408 @@
|
||||
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php");
|
||||
$daysgerm = array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
|
||||
?>
|
||||
<link href="<?= self::getResourcePath() ?>assets/css/select2-cstm.css?<?= date('U') ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<style>
|
||||
.fc-event {
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
cursor: move;
|
||||
font-size: 13px;
|
||||
margin: 3px 7px;
|
||||
padding: 3px 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-toolbar {
|
||||
@media (max-width: 767px) {
|
||||
flex-direction: column;
|
||||
.fc-toolbar-chunk {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fc .fc-button-primary:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.fc .fc-button:focus {
|
||||
box-shadow: none;
|
||||
outline: 0px;
|
||||
}
|
||||
|
||||
.fc .fc-button-primary:not(:disabled).fc-button-active:focus, .fc .fc-button-primary:not(:disabled):active:focus {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.popper, .tooltip {
|
||||
position: absolute;
|
||||
z-index: 9999;
|
||||
/* background: #FFC107; */
|
||||
color: #0f5be9;
|
||||
width: auto;
|
||||
/* border-radius: 3px; */
|
||||
/* box-shadow: 0 0 1px rgba(0, 0, 0, 0.5); */
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.tooltip-inner {
|
||||
max-width: 500px;
|
||||
padding: 0.4rem 0.8rem;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
background-color: #2c3e50;
|
||||
border-radius: 0.2rem;
|
||||
}
|
||||
|
||||
.style5 .tooltip {
|
||||
background: #1E252B;
|
||||
color: #FFFFFF;
|
||||
max-width: 200px;
|
||||
width: auto;
|
||||
font-size: .8rem;
|
||||
padding: .5em 1em;
|
||||
}
|
||||
|
||||
.popper .popper__arrow,
|
||||
.tooltip .tooltip-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.tooltip .tooltip-arrow,
|
||||
.popper .popper__arrow {
|
||||
border-color: #FFC107;
|
||||
}
|
||||
|
||||
.style5 .tooltip .tooltip-arrow {
|
||||
border-color: #1E252B;
|
||||
}
|
||||
|
||||
.popper[x-placement^="top"],
|
||||
.tooltip[x-placement^="top"] {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.popper[x-placement^="top"] .popper__arrow,
|
||||
.tooltip[x-placement^="top"] .tooltip-arrow {
|
||||
border-width: 5px 5px 0 5px;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
bottom: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.popper[x-placement^="bottom"],
|
||||
.tooltip[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.tooltip[x-placement^="bottom"] .tooltip-arrow,
|
||||
.popper[x-placement^="bottom"] .popper__arrow {
|
||||
border-width: 0 5px 5px 5px;
|
||||
border-left-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-top-color: transparent;
|
||||
top: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.tooltip[x-placement^="right"],
|
||||
.popper[x-placement^="right"] {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.popper[x-placement^="right"] .popper__arrow,
|
||||
.tooltip[x-placement^="right"] .tooltip-arrow {
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-left-color: transparent;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
left: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.popper[x-placement^="left"],
|
||||
.tooltip[x-placement^="left"] {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.popper[x-placement^="left"] .popper__arrow,
|
||||
.tooltip[x-placement^="left"] .tooltip-arrow {
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-top-color: transparent;
|
||||
border-right-color: transparent;
|
||||
border-bottom-color: transparent;
|
||||
right: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/moment/moment.min.js?<?= date('U') ?>"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/index.global.min.js?<?= date('U') ?>"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/moment/index.global.min.js?<?= date('U') ?>"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/locales-all.global.min.js?<?= date('U') ?>"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/calendar/tooltip.min.js?<?= date('U') ?>"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
let requestUrl = "<?= self::getUrl("TimerecordingReport", "api", ['do' => 'getTimerecordings', 'datatype' => '3', 'datayear' => time()]) ?>";
|
||||
var cindex = 1;
|
||||
var holiDays = [];
|
||||
var birthdays = [];
|
||||
<?php
|
||||
$counter = 1;
|
||||
foreach ($timerecordingholidays as $timerecordingholiday) :?>
|
||||
holiDays.push({
|
||||
id: <?= $counter ?>,
|
||||
start: '<?= date("Y-m-d", $timerecordingholiday->timestamp) ?>',
|
||||
end: '<?= date("Y-m-d", $timerecordingholiday->timestamp) ?>',
|
||||
title: '<?= $timerecordingholiday->description ?>',
|
||||
description: '<?= $timerecordingholiday->description ?>'
|
||||
});
|
||||
<?php
|
||||
$counter++;
|
||||
endforeach;
|
||||
foreach ($timerecordingemployees as $timerecordingemployee) :
|
||||
if ($timerecordingemployee->birthday) :
|
||||
$year = date("Y", time());
|
||||
$year = $year - 1;
|
||||
$Byear = date("Y", $timerecordingemployee->birthday);
|
||||
for ($i = 0; $i < 5; $i++) :
|
||||
$age = $year - $Byear;
|
||||
?>
|
||||
birthdays.push({
|
||||
id: <?= $counter ?>,
|
||||
start: '<?= date("$year-m-d", $timerecordingemployee->birthday) ?>',
|
||||
end: '<?= date("$year-m-d", $timerecordingemployee->birthday) ?>',
|
||||
title: '<?= $timerecordingemployee->user->name ?> (<?= $age ?>)',
|
||||
description: 'Geburtstag <?= $timerecordingemployee->user->name ?> (<?= $age ?>)'
|
||||
});
|
||||
<?php
|
||||
$year++;
|
||||
endfor;
|
||||
$counter++;
|
||||
endif;
|
||||
endforeach; ?>
|
||||
|
||||
cindex = <?= $counter ?>;
|
||||
$.getJSON(requestUrl, function (data) {
|
||||
|
||||
}).done(function (json) {
|
||||
var bgcolors = ['rgba(251, 71, 71,0.2)', 'rgba(253, 126, 20, 0.25)', 'rgba(91, 71, 251, 0.2)', 'rgba(71, 251, 151, 0.2)', 'rgba(251, 71, 194, 0.2)', 'rgba(20, 251, 253, 0.25)'];
|
||||
//read data from json
|
||||
var json = json.data;
|
||||
var holidays = [];
|
||||
var colorcount = 0;
|
||||
var oldname = "";
|
||||
$.each(json, function (index, value) {
|
||||
if (oldname != value.user.user) {
|
||||
colorcount++;
|
||||
if (colorcount > 5) {
|
||||
colorcount = 0;
|
||||
}
|
||||
oldname = value.user.user;
|
||||
}
|
||||
if (value.hourday.hourday!='5') {
|
||||
holidays.push({
|
||||
id: cindex,
|
||||
backgroundColor: bgcolors[colorcount],
|
||||
start: value.cstart.cstart,
|
||||
end: value.cend.cend,
|
||||
title: value.ccategory.ccategory + " " + value.user.user,
|
||||
description: value.ccategory.ccategory + " " + value.user.user
|
||||
});
|
||||
cindex++;
|
||||
}
|
||||
oldname = value.user.user;
|
||||
|
||||
});
|
||||
|
||||
var initialLocaleCode = 'en';
|
||||
var calendarEl = document.getElementById('fullcalendar');
|
||||
var containerEl = document.getElementById('external-events');
|
||||
var localeSelectorEl = document.getElementById('locale-selector');
|
||||
|
||||
var curYear = '2024';
|
||||
var curMonth = '02';
|
||||
|
||||
// Calendar Event Source
|
||||
|
||||
// Birthday Events Source
|
||||
var holiDayEvents = {
|
||||
id: 1,
|
||||
backgroundColor: 'rgba(255, 0, 0 , 1)',
|
||||
borderColor: 'rgba(255, 0, 0 , 1)',
|
||||
textColor: '#fff',
|
||||
events: holiDays
|
||||
|
||||
};
|
||||
var holidayEvents = {
|
||||
id: 7,
|
||||
backgroundColor: 'rgba(0,204,204,.25)',
|
||||
borderColor: 'rgb(8 241 8)',
|
||||
textColor: '#000',
|
||||
events: holidays
|
||||
};
|
||||
var birthdayEvents = {
|
||||
id: 5,
|
||||
backgroundColor: 'rgb(68 15 241 / 76%)',
|
||||
borderColor: 'rgb(68 15 241 / 76%)',
|
||||
textColor: '#fff',
|
||||
events: birthdays
|
||||
};
|
||||
var initialLocaleCode = 'en';
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
var calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
locale: 'de',
|
||||
headerToolbar: {
|
||||
left: "prev,today,next",
|
||||
center: 'title',
|
||||
right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
|
||||
},
|
||||
eventDidMount: function (info) {
|
||||
var tooltip = new Tooltip(info.el, {
|
||||
title: info.event.extendedProps.description,
|
||||
placement: 'top',
|
||||
trigger: 'hover',
|
||||
container: 'body'
|
||||
});
|
||||
},
|
||||
editable: true,
|
||||
droppable: true, // this allows things to be dropped onto the calendar
|
||||
fixedWeekCount: true,
|
||||
// height: 300,
|
||||
initialView: 'dayGridMonth',
|
||||
timeZone: 'UTC',
|
||||
hiddenDays: [],
|
||||
navLinks: 'true',
|
||||
events: [],
|
||||
height: 800,
|
||||
eventSources: [birthdayEvents, holiDayEvents, holidayEvents]
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<style>
|
||||
.edit-button {
|
||||
color: #007bff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.approved-open {
|
||||
background-color: #fdb751 !important;
|
||||
color: #000;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.approved-closed {
|
||||
background-color: #96ff68 !important;
|
||||
color: #000;
|
||||
border-radius: 5px;
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.fa-clock {
|
||||
color: #ff9b00;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.edit-placeholder {
|
||||
height: 15px;
|
||||
width: 22px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.fa-square-check {
|
||||
color: #23b900;
|
||||
font-size: 17px;
|
||||
vertical-align: middle;
|
||||
margin-bottom: 2px;
|
||||
margin-right: 3px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
<link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= date('U') ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<!-- start page title -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="page-title-box">
|
||||
<div class="page-title-right">
|
||||
<ol class="breadcrumb m-0">
|
||||
<li class="breadcrumb-item"><a href="<?= self::getUrl("Dashboard") ?>"><?= MFAPPNAME_SLUG ?></a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">Abwesenheitskalender</li>
|
||||
</ol>
|
||||
</div>
|
||||
<h4 class="page-title">Abwesenheitskalender</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- end page title -->
|
||||
<div class="card text-center">
|
||||
<div class="card-body mb-3 ">
|
||||
<div class="row ">
|
||||
<div class="col-12">
|
||||
<div class="float-left">
|
||||
<h4 class="header-title">Abwesenheitskalender</h4>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-lg-10">
|
||||
|
||||
<div id='calendar'></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var hidesearch = [2, 3, 4, 8];
|
||||
var columnfilter = [7];
|
||||
var columnoptions = '<option value=""></option><option value="Offen">Offen</option><option value="Genehmigt">Genehmigt</option><option value="Abgelehnt">Abgelehnt</option>';
|
||||
$(document).ready(function () {
|
||||
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
src="<?= self::getResourcePath() ?>assets/js/datatables-std.js?<?= date('U') ?>"></script>
|
||||
|
||||
|
||||
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>
|
||||
@@ -65,7 +65,8 @@
|
||||
<label class="col-lg-2 col-form-label" for="approval">Genehmigungspflichtig</label>
|
||||
<div class="col-lg-3">
|
||||
<div class="form-check">
|
||||
<input id="approval" class="form-check-input" <?php if ($timerecordingcategoriess->approval) echo 'checked="checked"'; ?>
|
||||
<input id="approval"
|
||||
class="form-check-input" <?php if ($timerecordingcategoriess->approval) echo 'checked="checked"'; ?>
|
||||
type="checkbox" name="approval" value="1" id="olt">
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,25 +76,30 @@
|
||||
Pflichtfeld</label>
|
||||
<div class="col-lg-3">
|
||||
<div class="form-check">
|
||||
<input id="require_comment" class="form-check-input" <?php if ($timerecordingcategoriess->require_comment) echo 'checked="checked"'; ?>
|
||||
<input id="require_comment"
|
||||
class="form-check-input" <?php if ($timerecordingcategoriess->require_comment) echo 'checked="checked"'; ?>
|
||||
type="checkbox" name="require_comment" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="businesstrip">Dienstreisemöglichkeit</label>
|
||||
<label class="col-lg-2 col-form-label"
|
||||
for="businesstrip">Dienstreisemöglichkeit</label>
|
||||
<div class="col-lg-3">
|
||||
<div class="form-check">
|
||||
<input id="businesstrip" class="form-check-input" <?php if ($timerecordingcategoriess->businesstrip) echo 'checked="checked"'; ?>
|
||||
<input id="businesstrip"
|
||||
class="form-check-input" <?php if ($timerecordingcategoriess->businesstrip) echo 'checked="checked"'; ?>
|
||||
type="checkbox" name="businesstrip" value="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="only_admin">Nur für Buchhaltung zu buchen</label>
|
||||
<label class="col-lg-2 col-form-label" for="only_admin">Nur für Buchhaltung zu
|
||||
buchen</label>
|
||||
<div class="col-lg-3">
|
||||
<div class="form-check">
|
||||
<input id="only_admin" class="form-check-input" <?php if ($timerecordingcategoriess->only_admin) echo 'checked="checked"'; ?>
|
||||
<input id="only_admin"
|
||||
class="form-check-input" <?php if ($timerecordingcategoriess->only_admin) echo 'checked="checked"'; ?>
|
||||
type="checkbox" name="only_admin" value="1">
|
||||
</div>
|
||||
</div>
|
||||
@@ -130,6 +136,15 @@
|
||||
$('form').on('blur', 'input[type=number]', function (e) {
|
||||
$(this).off('wheel.disableScroll')
|
||||
});
|
||||
$(document).ready(function () {
|
||||
$("body").on("change", "#hourday", function () {
|
||||
if ($(this).val() == 5) {
|
||||
$("#only_admin").prop("checked", true);
|
||||
} else {
|
||||
}
|
||||
});
|
||||
$("#hourday").change();
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>
|
||||
@@ -33,7 +33,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="datatable" class="table table-striped table-hover table-sm">
|
||||
<table id="datatable" class="table table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">Beizeichnung</th>
|
||||
|
||||
@@ -89,6 +89,15 @@ $daysSelect .= "</select>";
|
||||
value="<?= ($timerecordingemployees->startdate) ? date('Y-m-d', $timerecordingemployees->startdate): "" ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="birthday">Geburtstag</label>
|
||||
<div class="col-lg-2">
|
||||
<input type="date" id="birthday" name="birthday"
|
||||
class="form-control"
|
||||
value="<?= ($timerecordingemployees->birthday) ? date('Y-m-d', $timerecordingemployees->birthday): "" ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="holidays">Initiale Urlaubstage</label>
|
||||
<div class="col-lg-1">
|
||||
@@ -106,6 +115,14 @@ $daysSelect .= "</select>";
|
||||
value="<?= str_replace(".", ",", $timerecordingemployees->plushours / 3600) ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label" for="overtime">Initiale Überstunden</label>
|
||||
<div class="col-lg-1">
|
||||
<input type="text" id="overtime" name="overtime"
|
||||
class="form-control"
|
||||
value="<?= str_replace(".", ",", $timerecordingemployees->overtime / 3600) ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<label class="col-lg-2 col-form-label"
|
||||
for="auto_workinghours">Schnellbuchung</label>
|
||||
@@ -186,7 +203,6 @@ $daysSelect .= "</select>";
|
||||
function checktime() {
|
||||
var sum = 0;
|
||||
$(".wtime").each(function (index) {
|
||||
console.log($(this).find('.timeend').val());
|
||||
var newdatestart = new Date('2020/01/01 ' + $(this).find('.timestart').val() + ':00');
|
||||
var newdateend = new Date('2020/01/01 ' + $(this).find('.timeend').val() + ':00');
|
||||
var differenz = (newdateend - newdatestart) / 1000;
|
||||
|
||||
@@ -5,6 +5,14 @@ $type[3] = "Lehrling";
|
||||
?>
|
||||
<link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= date('U') ?>" rel="stylesheet"
|
||||
type="text/css"/>
|
||||
<style>
|
||||
.border-dark {
|
||||
border-color: #cbcbcb !important;
|
||||
}
|
||||
.border-bottom {
|
||||
border-bottom: 1px dotted #adadad !important;
|
||||
}
|
||||
</style>
|
||||
<!-- start page title -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@@ -34,7 +42,7 @@ $type[3] = "Lehrling";
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-12">
|
||||
<table id="datatable" class="table table-striped table-hover table-sm">
|
||||
<table id="datatable" class="table table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center">Mitarbeiter</th>
|
||||
@@ -42,6 +50,9 @@ $type[3] = "Lehrling";
|
||||
<th class="text-center">Start Zeitaufzeichnung</th>
|
||||
<th class="text-center">Sollzeiten</th>
|
||||
<th class="text-center">Sollstunden</th>
|
||||
<th class="text-center">Mehrstunden</th>
|
||||
<th class="text-center">Überstunden</th>
|
||||
<th class="text-center">Offene Urlaube</th>
|
||||
<th class="text-center edit-width">Schnellbuchung</th>
|
||||
<th class="edit-width"></th>
|
||||
</tr>
|
||||
@@ -53,6 +64,9 @@ $type[3] = "Lehrling";
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -65,14 +79,34 @@ $type[3] = "Lehrling";
|
||||
} else {
|
||||
$sum = "";
|
||||
}
|
||||
if ($timerecordingemployees[$timerecordinguser->id]['plushours_now'] < 0) {
|
||||
$plusHours = $timerecordingemployees[$timerecordinguser->id]['plushours_now'] * -1;
|
||||
$plusHours = "-" . sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
|
||||
} else {
|
||||
$plusHours = $timerecordingemployees[$timerecordinguser->id]['plushours_now'];
|
||||
$plusHours = sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
}
|
||||
if ($timerecordingemployees[$timerecordinguser->id]['overtime_now'] < 0) {
|
||||
$overTime = $timerecordingemployees[$timerecordinguser->id]['overtime_now'] * -1;
|
||||
$overTime = "-" . sprintf('%02dh:%02dm', floor($overTime / 3600), floor($overTime / 60 % 60));
|
||||
|
||||
} else {
|
||||
$overTime = $timerecordingemployees[$timerecordinguser->id]['overtime_now'];
|
||||
$overTime = sprintf('%02dh:%02dm', floor($overTime / 3600), floor($overTime / 60 % 60));
|
||||
}
|
||||
?>
|
||||
|
||||
<tr>
|
||||
<td><?= $timerecordinguser->name ?></td>
|
||||
<td><?= $type[$timerecordingemployees[$timerecordinguser->id]['type']] ?></td>
|
||||
<td class="text-center"><?= ($timerecordingemployees[$timerecordinguser->id]['startdate']) ? date("d.m.Y", $timerecordingemployees[$timerecordinguser->id]['startdate']) : "-" ?></td>
|
||||
<td class="text-center"><?= ($timerecordingworkinghours) ? $timerecordingworkinghours[$timerecordinguser->id]['datetimetext'] : "" ?></td>
|
||||
<td class="text-center text-nowrap"><?= ($timerecordingworkinghours) ? $timerecordingworkinghours[$timerecordinguser->id]['datetimetext'] : "" ?></td>
|
||||
<td class="text-center"><?= $sum ?></td>
|
||||
<td class="text-center"
|
||||
data-order="<?= ($timerecordingemployees[$timerecordinguser->id]['plushours_now']) ? $timerecordingemployees[$timerecordinguser->id]['plushours_now'] : 0 ?>"><?= $plusHours ?></td>
|
||||
<td class="text-center" data-order="<?= $timerecordingemployees[$timerecordinguser->id]['overtime_now'] ?>"><?= $overTime ?></td>
|
||||
<td class="text-center" data-order="<?= ($timerecordingemployees[$timerecordinguser->id]['holidays_now']) ? $timerecordingemployees[$timerecordinguser->id]['holidays_now'] : '' ?>"><?= ($timerecordingemployees[$timerecordinguser->id]['holidays_now']) ? $timerecordingemployees[$timerecordinguser->id]['holidays_now'] . ' Tage' : '' ?> </td>
|
||||
<td class="text-center"><?= ($timerecordingemployees[$timerecordinguser->id]['auto_workinghours'] == '1') ? 'Ja' : 'Nein' ?></td>
|
||||
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
|
||||
<a href="<?= self::getUrl("TimerecordingEmployee", "edit", ['id' => $timerecordingemployees[$timerecordinguser->id]['id'], "userid" => $timerecordinguser->id]) ?>"><i
|
||||
@@ -91,7 +125,7 @@ $type[3] = "Lehrling";
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
var hidesearch = [6];
|
||||
var hidesearch = [3, 4, 5, 6, 7, 9];
|
||||
|
||||
$(document).ready(function () {
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ $daysgerm = array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table id="datatable" class="table table-striped table-hover table-sm">
|
||||
<table id="datatable" class="table table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 200px;" class="text-center">Datum</th>
|
||||
|
||||
@@ -182,9 +182,9 @@ $daysgerm = array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
|
||||
<script type="text/javascript">
|
||||
var hidesearch = [2, 3, 4, 8];
|
||||
var columnfilter = [7];
|
||||
var columnoptions = '<option value=""></option><option value="Offen">Offen</option><option value="Genehmigt">Genehmigt</option><option value="Abgelehnt">Abgelehnt</option>';
|
||||
var columnoptions = '<option value=""></option><option selected="selected" value="Offen">Offen</option><option value="Genehmigt">Genehmigt</option><option value="Abgelehnt">Abgelehnt</option>';
|
||||
$(document).ready(function () {
|
||||
|
||||
$('#selectsearch').change();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@@ -23,7 +23,7 @@ for ($i = 1; $i <= 25; $i++) {
|
||||
$kw = date('W', $time);
|
||||
$year = date('Y', $time);
|
||||
$timestamp_montag = strtotime("{$year}-W{$kw}");
|
||||
$timestamp_freitag = strtotime("{$year}-W{$kw}-5");
|
||||
$timestamp_freitag = strtotime("{$year}-W{$kw}-7");
|
||||
|
||||
$weeks[$time] = "KW" . $kw . " " . $year . " (" . date('d.m', $timestamp_montag) . "-" . date('d.m', $timestamp_freitag) . ")";
|
||||
$time = $time - 604800;
|
||||
@@ -93,6 +93,9 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
background-color: #d0fbd9;
|
||||
}
|
||||
|
||||
.form-check-label {
|
||||
margin-top: 2px;
|
||||
}
|
||||
</style>
|
||||
<!-- start page title -->
|
||||
<div class="row">
|
||||
@@ -102,10 +105,10 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
<ol class="breadcrumb m-0">
|
||||
<li class="breadcrumb-item"><a href="<?= self::getUrl("Dashboard") ?>"><?= MFAPPNAME_SLUG ?></a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">Buchungen</li>
|
||||
<li class="breadcrumb-item active">Auswertungen/Korrekturen</li>
|
||||
</ol>
|
||||
</div>
|
||||
<h4 class="page-title">Buchungen</h4>
|
||||
<h4 class="page-title">Auswertungen/Korrekturen</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -139,7 +142,9 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
<option value="<?= $timerecordingCategories->id ?>"
|
||||
data-approval="<?= $timerecordingCategories->approval ?>"
|
||||
data-comment="<?= $timerecordingCategories->require_comment ?>"
|
||||
data-hourday="<?= $timerecordingCategories->hourday ?>"><?= $timerecordingCategories->name ?></option>
|
||||
data-hourday="<?= $timerecordingCategories->hourday ?>"
|
||||
data-businesstrip="<?= $timerecordingCategories->businesstrip ?>"
|
||||
data-homeoffice="<?= ($timerecordingCategories->hourday == 1) ? 1 : 0 ?>"><?= $timerecordingCategories->name ?></option>
|
||||
<?php
|
||||
endforeach; ?>
|
||||
</select>
|
||||
@@ -184,30 +189,72 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-lg-2">
|
||||
<label class="col-form-label" for="comment">Anmerkung</label>
|
||||
<input type="text" id="comment" name="comment" class="form-control"
|
||||
<div id="days-div" class="col-lg-1" style="display:none">
|
||||
<div class="form-row">
|
||||
<div class="form-group col">
|
||||
<label class=" col-form-label" for="days">Anzahl Tage</label>
|
||||
<input type="number" id="days" name="days" class="form-control "
|
||||
placeholder=""/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group col-lg-2">
|
||||
<label class="col-form-label" for="comment">Anmerkung</label>
|
||||
<input type="text" id="comment" name="comment" class="form-control">
|
||||
</div>
|
||||
<div class="form-group col-lg-2" id="div-calc-overtime" style="display:none">
|
||||
<label class="col-form-label mobile-hide" for="comment"> </label>
|
||||
<div class=" d-block" style="padding: 0.45rem 0.9rem;" id="calc-overtime"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" row mt-2">
|
||||
<div class="col-lg-2 ">
|
||||
<button id="submit-button" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button id="cancel-button" type="button" class="btn btn-secondary" style="display:none">Abbrechen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" row mt-2">
|
||||
<div class="col-lg-4" id="message-box">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-1 mb-2" id="homeoffice-div">
|
||||
|
||||
<div class="form-check text-center mt-1">
|
||||
<input class="form-check-input" type="checkbox" name="homeoffice"
|
||||
id="homeoffice" value="1">
|
||||
<label class="form-check-label" for="homeoffice">
|
||||
Homeoffice
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-2 mb-2 businesstrip-div">
|
||||
|
||||
<div class="form-check text-center mt-1">
|
||||
<input class="form-check-input" type="checkbox" name="businesstrip"
|
||||
id="businesstrip" value="1">
|
||||
<label class="form-check-label" for="businesstrip">
|
||||
Dienstreise > 12KM
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-2 businesstrip-div">
|
||||
<input style="display:none" type="text" id="businesstrip_info" name="businesstrip_info"
|
||||
placeholder="Ort"
|
||||
class="form-control"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class=" row mt-2">
|
||||
<div class="col-lg-2 ">
|
||||
<button id="submit-button" type="submit" class="btn btn-primary">Speichern</button>
|
||||
<button id="cancel-button" type="button" class="btn btn-secondary" style="display:none">
|
||||
Abbrechen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" row mt-2">
|
||||
<div class="col-lg-4" id="message-box">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body mb-3">
|
||||
<div class="form-group module-row row mb-3">
|
||||
@@ -271,32 +318,32 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="col-lg-3">-->
|
||||
<!-- <div class="form-row">-->
|
||||
<!-- <div class="col text-center">-->
|
||||
<!-- <div class="input-group ">-->
|
||||
<!-- <label class="col-form-label form-control fixed-state"><span-->
|
||||
<!-- class="text-bold">Urlaubstage: </span><span id="holidays"-->
|
||||
<!-- class="ml-1 text-normal"></span></label>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col text-center">-->
|
||||
<!-- <div class="input-group ">-->
|
||||
<!-- <label class="col-form-label form-control fixed-state"><span-->
|
||||
<!-- class="text-bold">Gutzeit: </span><span-->
|
||||
<!-- id="plushours"-->
|
||||
<!-- class="ml-1 text-normal"></span></label>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col-lg-3">-->
|
||||
<!-- <div class="form-row">-->
|
||||
<!-- <div class="col text-center">-->
|
||||
<!-- <div class="input-group ">-->
|
||||
<!-- <label class="col-form-label form-control fixed-state"><span-->
|
||||
<!-- class="text-bold">Urlaubstage: </span><span id="holidays"-->
|
||||
<!-- class="ml-1 text-normal"></span></label>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="col text-center">-->
|
||||
<!-- <div class="input-group ">-->
|
||||
<!-- <label class="col-form-label form-control fixed-state"><span-->
|
||||
<!-- class="text-bold">Gutzeit: </span><span-->
|
||||
<!-- id="plushours"-->
|
||||
<!-- class="ml-1 text-normal"></span></label>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
|
||||
|
||||
<table id="datatable" class="table table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-center text-nowrap ">Mitarbeiter</th>
|
||||
<th style="min-width: 250px;" class="text-center text-nowrap ">Mitarbeiter</th>
|
||||
<th style="width: 200px;" class="text-center text-nowrap ">Datum</th>
|
||||
<th class="text-nowrap edit-width text-center">Von</th>
|
||||
<th class="text-nowrap edit-width text-center">Bis</th>
|
||||
@@ -332,7 +379,8 @@ $years[time() - 31536000] = date('Y', time() - 31536000);
|
||||
let insertUrl = "<?= self::getUrl("Timerecording", "save") ?>";
|
||||
let deleteUrl = "<?= self::getUrl("Timerecording", "delete") ?>";
|
||||
let requestUrl = "<?= self::getUrl("TimerecordingReport", "api", ['do' => 'getTimerecordings']) ?>";
|
||||
|
||||
let requestTimesUrl = "<?= self::getUrl("TimerecordingReport", "api", ['do' => 'getTimerecordingsTimes']) ?>";
|
||||
let checkWorkinghoursUrl = "<?= self::getUrl("Timerecording", "api", ['do' => 'checkWorkinghours']) ?>";
|
||||
|
||||
</script>
|
||||
<script type="text/javascript"
|
||||
|
||||
@@ -1,129 +1,87 @@
|
||||
<?/** @var TYPE_NAME $git_merge_ts */?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><?=MFAPPNAME_FULL?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!-- App favicon -->
|
||||
<link rel="shortcut icon" href="<?=self::getResourcePath()?>assets/images/favicon.ico">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title><?=MFAPPNAME_FULL?></title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<!-- App favicon -->
|
||||
<link rel="shortcut icon" href="<?=self::getResourcePath()?>assets/images/favicon.ico">
|
||||
|
||||
<!-- App css -->
|
||||
<link href="<?=self::getResourcePath()?>fontawesome/css/all.min.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap.min.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/icons.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/app.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/leaflet.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/thetool.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/libs/select2/select2.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>css/bootstrap-datepicker3.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>plugins/summernote/summernote-bs4.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>datatables/datatables.min.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
|
||||
<?php if(isset($additionalCSS) && is_array($additionalCSS) && count($additionalCSS)): ?>
|
||||
<?php foreach($additionalCSS as $css): ?>
|
||||
<!-- App css -->
|
||||
<link href="<?=self::getResourcePath()?>fontawesome/css/all.min.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap.min.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/icons.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/app.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/leaflet.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/thetool.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/libs/select2/select2.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>assets/css/bootstrap-select.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>css/bootstrap-datepicker3.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>plugins/summernote/summernote-bs4.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>plugins/notification/notify.min.css" rel="stylesheet" type="text/css" />
|
||||
<link href="<?=self::getResourcePath()?>datatables/datatables.min.css?<?=$git_merge_ts?>" rel="stylesheet" type="text/css" />
|
||||
|
||||
<?php if(isset($additionalCSS) && is_array($additionalCSS) && count($additionalCSS)): ?>
|
||||
<?php foreach($additionalCSS as $css): ?>
|
||||
<link rel="stylesheet" href="<?=self::getResourcePath()?><?=$css?>?<?=$git_merge_ts?>" />
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/libs/select2/select2.full.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.de.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/geo/geo.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.MakiMarkers.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/popper.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/bootstrap-select.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-autocomplete.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>datatables/datatables.min.js?<?=$git_merge_ts?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($JSGlobals) && is_array($JSGlobals) && count($JSGlobals)): ?>
|
||||
<script type="text/javascript">
|
||||
window.TT_CONFIG = {};
|
||||
<?php foreach($JSGlobals as $key => $value): ?>
|
||||
window.TT_CONFIG.<?=$key?> = <?=is_array($value) ? json_encode($value) : "'$value'"; ?>;
|
||||
<?php endforeach; ?>
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($additionalJS) && is_array($additionalJS) && count($additionalJS)): ?>
|
||||
<?php foreach($additionalJS as $js): ?>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/libs/select2/select2.full.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-datepicker.de.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/geo/geo.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/leaflet.MakiMarkers.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/popper.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>assets/js/bootstrap-select.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>js/bootstrap-autocomplete.min.js"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>datatables/datatables.min.js?<?=$git_merge_ts?>"></script>
|
||||
<script type="text/javascript" src="<?=self::getResourcePath()?>plugins/notification/notify.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.mfNotify = <?=isset($mfNotify) ? json_encode($mfNotify) : "null"; ?>;
|
||||
window.TT_CONFIG = {};
|
||||
|
||||
<?php
|
||||
if(isset($JSGlobals) && is_array($JSGlobals) && count($JSGlobals)):
|
||||
foreach($JSGlobals as $key => $value): ?>
|
||||
window.TT_CONFIG.<?=$key?> = <?=is_array($value) ? json_encode($value) : "'$value'"; ?>;
|
||||
<?php endforeach; endif;?>
|
||||
</script>
|
||||
|
||||
<?php if(isset($additionalJS) && is_array($additionalJS) && count($additionalJS)): ?>
|
||||
<?php foreach($additionalJS as $js): ?>
|
||||
<script src="<?=self::getResourcePath()?><?=$js?>?<?=$git_merge_ts?>"></script>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(MFAPPNAME == "devthetool"): ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(MFAPPNAME == "devthetool"): ?>
|
||||
<style type="text/css">
|
||||
body {
|
||||
border-left: 8px dashed #f672a7;
|
||||
}
|
||||
body {
|
||||
border-left: 8px dashed #f672a7;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
baseurl = '<?=self::getResourcePath()?>';
|
||||
</script>
|
||||
|
||||
<!-- Navigation Bar-->
|
||||
<header id="topnav">
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/topbar.php"); ?>
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/menu.php"); ?>
|
||||
</header>
|
||||
<!-- End Navigation Bar-->
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
baseurl = '<?=self::getResourcePath()?>';
|
||||
</script>
|
||||
|
||||
<!-- Navigation Bar-->
|
||||
<header id="topnav">
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/topbar.php"); ?>
|
||||
<?php include(realpath(dirname(__FILE__)."/")."/menu.php"); ?>
|
||||
</header>
|
||||
<!-- End Navigation Bar-->
|
||||
|
||||
|
||||
<div class="wrapper pl-0 pl-lg-1 pr-0 pr-lg-1 ">
|
||||
<div class="container-fluid">
|
||||
|
||||
<?php if(isset($_flash_set) && $_flash_set == true): ?>
|
||||
<?php if(isset($mfError) && !empty($mfError)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-danger alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-ban"></i> Fehler</h5>
|
||||
<?=$mfError?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($mfWarning) && !empty($mfWarning)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-warning alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-exclamation-triangle"></i> Warnung</h5>
|
||||
<?=$mfWarning?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($mfInfo) && !empty($mfInfo)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-info alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-info"></i> Info</h5>
|
||||
<?=$mfInfo?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if(isset($mfSuccess) && !empty($mfSuccess)): ?>
|
||||
<div class="row mr-1">
|
||||
<div class="col-md-1"></div>
|
||||
<div class="col-md-10 alert alert-success alert-dismissible">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<h5><i class="icon fas fa-check"></i> Erfolgreich</h5>
|
||||
<?=$mfSuccess?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php endif; ?>
|
||||
<div class="container-fluid">
|
||||
|
||||
@@ -36,9 +36,10 @@
|
||||
<li class="has-submenu"><a href="#"><i class="far fa-fw fa-calendar-clock"></i>Zeiterfassung <div class="arrow-down"></div></a>
|
||||
<ul class="submenu">
|
||||
<li><a href="<?=self::getUrl("Timerecording")?>"><i class="far fa-fw fa-calendar text-info"></i> Buchungen</a></li>
|
||||
<li><a href="<?=self::getUrl("TimerecordingCalendar")?>"><i class="far fa-fw fa-calendar-days text-info"></i> Abwesenheitskalender</a></li>
|
||||
<?php if ($me->can('Fibu')): ?>
|
||||
<li><a href="<?=self::getUrl("TimerecordingPermit")?>"><i class="far fa-fw fa-calendar-check text-info"></i> Freigaben</a></li>
|
||||
<li><a href="<?=self::getUrl("TimerecordingReport")?>"><i class="far fa-fw fa-chart-pie text-info"></i> Auswertungen</a></li>
|
||||
<li><a href="<?=self::getUrl("TimerecordingReport")?>"><i class="far fa-fw fa-chart-pie text-info"></i> Auswertung/Korrektur</a></li>
|
||||
<li><a href="<?=self::getUrl("TimerecordingCategory")?>"><i class="far fa-fw fa-list text-info"></i> Buchungsarten</a></li>
|
||||
<li><a href="<?=self::getUrl("TimerecordingHoliday")?>"><i class="far fa-fw fa-umbrella-beach text-info"></i> Feiertage</a></li>
|
||||
<li><a href="<?=self::getUrl("TimerecordingEmployee")?>"><i class="far fa-fw fa-user text-info"></i> Personaladministration</a></li>
|
||||
|
||||
@@ -32,46 +32,46 @@ class AddressModel {
|
||||
public $sepa_date;
|
||||
public $allow_contact;
|
||||
public $allow_spin;
|
||||
|
||||
|
||||
public $note;
|
||||
|
||||
|
||||
public $create_by;
|
||||
public $edit_by;
|
||||
public $create;
|
||||
public $edit;
|
||||
|
||||
public static function create(Array $data) {
|
||||
public static function create(array $data) {
|
||||
$model = new Address();
|
||||
|
||||
foreach($data as $field => $value) {
|
||||
if(property_exists(get_called_class(), $field)) {
|
||||
|
||||
foreach ($data as $field => $value) {
|
||||
if (property_exists(get_called_class(), $field)) {
|
||||
$model->$field = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
|
||||
if(!is_numeric($model->create_by) && !$model->create_by) {
|
||||
if (!is_numeric($model->create_by) && !$model->create_by) {
|
||||
$model->create_by = $me->id;
|
||||
}
|
||||
if(!is_numeric($model->edit_by) && !$model->edit_by) {
|
||||
if (!is_numeric($model->edit_by) && !$model->edit_by) {
|
||||
$model->edit_by = $me->id;
|
||||
}
|
||||
|
||||
if(!array_key_exists("note", $data)) {
|
||||
|
||||
if (!array_key_exists("note", $data)) {
|
||||
$model->note = "";
|
||||
}
|
||||
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
public static function getFirst($filter = null) {
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
|
||||
$where = self::getSqlFilter($filter);
|
||||
//mfLoghandler::singleton()->debug($where);
|
||||
|
||||
|
||||
$sql = "SELECT Address.* FROM Address
|
||||
LEFT JOIN Addresstype ON (Addresstype.address_id = Address.id)
|
||||
LEFT JOIN Country ON (Country.id = Address.country_id)
|
||||
@@ -80,14 +80,14 @@ class AddressModel {
|
||||
ORDER BY company, lastname, firstname, zip, city, Address.id
|
||||
LIMIT 1
|
||||
";
|
||||
|
||||
|
||||
$res = $db->query($sql);
|
||||
//$res = $db->select("Address", "*", "$where ORDER BY company, lastname, firstname, zip, city LIMIT 1");
|
||||
|
||||
if($db->num_rows($res)) {
|
||||
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
$item = new Address($data);
|
||||
if($item->id) {
|
||||
if ($item->id) {
|
||||
return $item;
|
||||
} else {
|
||||
return null;
|
||||
@@ -95,83 +95,83 @@ class AddressModel {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static function getOne($id) {
|
||||
if(!is_numeric($id) || !$id) {
|
||||
if (!is_numeric($id) || !$id) {
|
||||
throw new Exception("Invalid number", 400);
|
||||
}
|
||||
$item = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
|
||||
$res = $db->select("Address", "*", "id=$id LIMIT 1");
|
||||
if($db->num_rows($res)) {
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
$item = new Address($data);
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
|
||||
public static function getAll() {
|
||||
$items = [];
|
||||
|
||||
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
|
||||
$res = $db->select("Address", "*");
|
||||
if($db->num_rows($res)) {
|
||||
while($data = $db->fetch_object($res)) {
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new Address($data);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static function getLastCustomerNumber() {
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$res = $db->select("Address","customer_number", "customer_number > 0 AND customer_number < 200000 ORDER BY customer_number DESC LIMIT 1");
|
||||
if($db->num_rows($res)) {
|
||||
|
||||
$res = $db->select("Address", "customer_number", "customer_number > 0 AND customer_number < 200000 ORDER BY customer_number DESC LIMIT 1");
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
if($data->customer_number + 1 >= 200000) {
|
||||
$res = $db->select("Address","customer_number", "customer_number > 0 ORDER BY customer_number DESC LIMIT 1");
|
||||
if ($data->customer_number + 1 >= 200000) {
|
||||
$res = $db->select("Address", "customer_number", "customer_number > 0 ORDER BY customer_number DESC LIMIT 1");
|
||||
$data = $db->fetch_object($res);
|
||||
return $data->customer_number;
|
||||
}
|
||||
return $data->customer_number;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static function byNetwork($network_id, $addresstype) {
|
||||
if(!is_numeric($network_id) || !$network_id) {
|
||||
if (!is_numeric($network_id) || !$network_id) {
|
||||
return false;
|
||||
}
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
|
||||
$addresses = [];
|
||||
|
||||
|
||||
// get all addresses of network
|
||||
|
||||
|
||||
$sql = "SELECT Address.id as id FROM `Address`
|
||||
LEFT JOIN NetworkAddress ON (NetworkAddress.address_id = Address.id)
|
||||
WHERE NetworkAddress.type = '$addresstype'
|
||||
AND network_id = $network_id
|
||||
GROUP BY id";
|
||||
|
||||
|
||||
$res = $db->query($sql);
|
||||
if($db->num_rows($res)) {
|
||||
while($data = $db->fetch_object($res)) {
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$addresses[] = new Address($data->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $addresses;
|
||||
}
|
||||
|
||||
|
||||
public static function count($filter) {
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
|
||||
$where = self::getSqlFilter($filter);
|
||||
$sql = "SELECT COUNT(*) as cnt FROM (
|
||||
SELECT Address.id as address_id
|
||||
@@ -182,21 +182,21 @@ class AddressModel {
|
||||
GROUP BY Address.id
|
||||
) as tbl";
|
||||
//mfLoghandler::singleton()->debug($sql);
|
||||
|
||||
|
||||
$res = $db->query($sql);
|
||||
if($db->num_rows($res)) {
|
||||
if ($db->num_rows($res)) {
|
||||
$data = $db->fetch_object($res);
|
||||
return (int)$data->cnt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static function search($filter, $limit = false) {
|
||||
//var_dump($filter);exit;
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
|
||||
$where = self::getSqlFilter($filter);
|
||||
$have = [];
|
||||
/*$sql = "SELECT Address.* FROM Address, Addresstype
|
||||
@@ -210,20 +210,20 @@ class AddressModel {
|
||||
WHERE $where
|
||||
GROUP BY Address.id
|
||||
ORDER BY company, lastname, firstname, zip, city, Address.id";
|
||||
|
||||
if(is_array($limit) && count($limit)) {
|
||||
if(is_numeric($limit['start']) && is_numeric($limit['count'])) {
|
||||
$sql .= " LIMIT ".$limit['start'].", ".$limit['count'];
|
||||
} elseif(is_numeric($count)) {
|
||||
$sql .= " LIMIT ".$limit['count'];
|
||||
|
||||
if (is_array($limit) && count($limit)) {
|
||||
if (is_numeric($limit['start']) && is_numeric($limit['count'])) {
|
||||
$sql .= " LIMIT " . $limit['start'] . ", " . $limit['count'];
|
||||
} elseif (is_numeric($count)) {
|
||||
$sql .= " LIMIT " . $limit['count'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mfLoghandler::singleton()->debug($sql);
|
||||
|
||||
|
||||
$res = $db->query($sql);
|
||||
if($db->num_rows($res)) {
|
||||
while($data = $db->fetch_object($res)) {
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new Address($data);
|
||||
//$have[] = $data->id;
|
||||
}
|
||||
@@ -241,29 +241,29 @@ class AddressModel {
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
|
||||
private static function getSqlFilter($filter) {
|
||||
$where = "1=1 ";
|
||||
|
||||
|
||||
//var_dump($filter);exit;
|
||||
if(array_key_exists("customer_number", $filter)) {
|
||||
if (array_key_exists("customer_number", $filter)) {
|
||||
$cn = $filter["customer_number"];
|
||||
if(is_numeric($cn)) {
|
||||
if (is_numeric($cn)) {
|
||||
$where .= " AND customer_number=$cn";
|
||||
} elseif($cn === true) {
|
||||
} elseif ($cn === true) {
|
||||
$where .= " AND customer_number > 0";
|
||||
} elseif($cn === false || $cn === null) {
|
||||
} elseif ($cn === false || $cn === null) {
|
||||
$where .= " AND customer_number IS NULL";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("fibu_account_number", $filter)) {
|
||||
|
||||
if (array_key_exists("fibu_account_number", $filter)) {
|
||||
$fan = $filter["fibu_account_number"];
|
||||
if($fan) {
|
||||
if(is_numeric($fan)) {
|
||||
if ($fan) {
|
||||
if (is_numeric($fan)) {
|
||||
$where .= " AND fibu_account_number=$fan";
|
||||
} else {
|
||||
$fan = FronkDB::singleton()->escape($fan);
|
||||
@@ -271,159 +271,167 @@ class AddressModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("fibu_supplier_number", $filter)) {
|
||||
|
||||
if (array_key_exists("fibu_supplier_number", $filter)) {
|
||||
$fsn = $filter["fibu_supplier_number"];
|
||||
if(is_numeric($fsn)) {
|
||||
if (is_numeric($fsn)) {
|
||||
$where .= " AND fibu_supplier_number=$fsn";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("fibu_or_supplier_account_number", $filter)) {
|
||||
|
||||
if (array_key_exists("fibu_or_supplier_account_number", $filter)) {
|
||||
$fsn = $filter["fibu_or_supplier_account_number"];
|
||||
if($fsn) {
|
||||
if ($fsn) {
|
||||
$where .= " AND (fibu_account_number LIKE '$fsn' OR fibu_supplier_number LIKE '$fsn')";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("fibu_primary_account", $filter)) {
|
||||
|
||||
if (array_key_exists("fibu_primary_account", $filter)) {
|
||||
$fpa = $filter["fibu_primary_account"];
|
||||
if($fpa) {
|
||||
if ($fpa) {
|
||||
$where .= " AND fibu_primary_account=1";
|
||||
} else {
|
||||
$where .= " AND fibu_primary_account=0";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("customer_or_fibu_numbers", $filter)) {
|
||||
|
||||
if (array_key_exists("customer_or_fibu_numbers", $filter)) {
|
||||
$cn = $filter["customer_or_fibu_numbers"];
|
||||
if($cn === true) {
|
||||
if ($cn === true) {
|
||||
$where .= " AND (customer_number > 0 OR fibu_account_number > 0 OR fibu_supplier_number > 0)";
|
||||
} elseif($cn === false || $cn === null) {
|
||||
} elseif ($cn === false || $cn === null) {
|
||||
$where .= " AND customer_number IS NULL AND fibu_account_number IS NULL AND fibu_supplier_number IS NULL";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("spin", $filter)) {
|
||||
|
||||
if (array_key_exists("spin", $filter)) {
|
||||
$spin = FronkDB::singleton()->escape($filter["spin"]);
|
||||
if($spin) {
|
||||
if ($spin) {
|
||||
$where .= " AND spin='$spin'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("company", $filter)) {
|
||||
|
||||
if (array_key_exists("company", $filter)) {
|
||||
$company = FronkDB::singleton()->escape($filter["company"]);
|
||||
if($company) {
|
||||
if ($company) {
|
||||
$where .= " AND company like '%$company%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("firstname", $filter)) {
|
||||
|
||||
if (array_key_exists("firstname", $filter)) {
|
||||
$firstname = FronkDB::singleton()->escape($filter["firstname"]);
|
||||
if($firstname) {
|
||||
if ($firstname) {
|
||||
$where .= " AND firstname like '%$firstname%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("lastname", $filter)) {
|
||||
|
||||
if (array_key_exists("lastname", $filter)) {
|
||||
$lastname = FronkDB::singleton()->escape($filter["lastname"]);
|
||||
if($lastname) {
|
||||
if ($lastname) {
|
||||
$where .= " AND lastname like '%$lastname%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("mergedName", $filter)) {
|
||||
|
||||
if (array_key_exists("mergedName", $filter)) {
|
||||
$name = FronkDB::singleton()->escape($filter["mergedName"]);
|
||||
if($name) {
|
||||
if ($name) {
|
||||
$where .= " AND (CONCAT(firstname, ' ', lastname) like '%$name%' OR CONCAT(lastname, ' ', firstname) like '%$name%' )";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("street", $filter)) {
|
||||
|
||||
if (array_key_exists("street", $filter)) {
|
||||
$street = FronkDB::singleton()->escape($filter["street"]);
|
||||
if($street) {
|
||||
if ($street) {
|
||||
$where .= " AND street like '%$street%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("zip", $filter)) {
|
||||
|
||||
if (array_key_exists("zip", $filter)) {
|
||||
$zip = FronkDB::singleton()->escape($filter["zip"]);
|
||||
if($zip) {
|
||||
if ($zip) {
|
||||
$where .= " AND zip like '%$zip%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("city", $filter)) {
|
||||
|
||||
if (array_key_exists("city", $filter)) {
|
||||
$city = FronkDB::singleton()->escape($filter["city"]);
|
||||
if($city) {
|
||||
if ($city) {
|
||||
$where .= " AND city like '%$city%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("country", $filter)) {
|
||||
|
||||
if (array_key_exists("country", $filter)) {
|
||||
$country = FronkDB::singleton()->escape($filter["country"]);
|
||||
if($country) {
|
||||
if ($country) {
|
||||
$where .= " AND (Country.name like '%$country%' OR Country.isocode = '$country')";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("email", $filter)) {
|
||||
|
||||
if (array_key_exists("email", $filter)) {
|
||||
$email = FronkDB::singleton()->escape($filter["email"]);
|
||||
if($email) {
|
||||
if ($email) {
|
||||
$where .= " AND email like '%$email%'";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("pfm", $filter)) {
|
||||
|
||||
if (array_key_exists("pfm", $filter)) {
|
||||
$pfm = FronkDB::singleton()->escape($filter["pfm"]);
|
||||
if($pfm) {
|
||||
if ($pfm) {
|
||||
$where .= " AND (phone like '%$pfm%' OR fax like '%$pfm%' OR mobile like '%$pfm%' )";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("billing_type", $filter)) {
|
||||
|
||||
if (array_key_exists("billing_type", $filter)) {
|
||||
$billing_type = FronkDB::singleton()->escape($filter["billing_type"]);
|
||||
if($billing_type) {
|
||||
if ($billing_type) {
|
||||
$where .= " AND billing_type='$billing_type'";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (array_key_exists("id", $filter)) {
|
||||
$id = $filter["id"];
|
||||
if (is_numeric($id)) {
|
||||
$where .= " AND Address.id=$id";
|
||||
} elseif (is_array($id) && count($id)) {
|
||||
$where .= " AND Address.id IN (" . implode(",", $id) . ")";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Address Type
|
||||
*/
|
||||
if(array_key_exists("addresstype", $filter) && is_array($filter['addresstype']) && count($filter['addresstype'])) {
|
||||
if (array_key_exists("addresstype", $filter) && is_array($filter['addresstype']) && count($filter['addresstype'])) {
|
||||
$at = $filter['addresstype'];
|
||||
$in = [];
|
||||
foreach(TT_ROLES as $role) {
|
||||
if(in_array($role, $at)) {
|
||||
foreach (TT_ROLES as $role) {
|
||||
if (in_array($role, $at)) {
|
||||
$in[] = "Addresstype.type = '$role'";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$or = "";
|
||||
if(count($in)) {
|
||||
if (count($in)) {
|
||||
$or = implode(" OR ", $in);
|
||||
$where .= " AND ( $or )";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//var_dump($filter);exit;
|
||||
if(array_key_exists("parent_id", $filter)) {
|
||||
if (array_key_exists("parent_id", $filter)) {
|
||||
$parentid = $filter['parent_id'];
|
||||
if($parentid === null || $parent_id == "null") {
|
||||
if ($parentid === null || $parent_id == "null") {
|
||||
$where .= " AND parent_id IS NULL";
|
||||
} elseif(is_numeric($parentid)) {
|
||||
} elseif (is_numeric($parentid)) {
|
||||
$where .= " AND parent_id=$parentid";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("create_by", $filter)) {
|
||||
|
||||
if (array_key_exists("create_by", $filter)) {
|
||||
$create_by = $filter['create_by'];
|
||||
if(is_numeric($create_by)) {
|
||||
if (is_numeric($create_by)) {
|
||||
$where .= " AND Address.create_by=$create_by";
|
||||
} elseif(is_array($create_by) && count($create_by)) {
|
||||
$where .= " AND Address.create_by IN (". implode(",",$create_by).")";
|
||||
} elseif (is_array($create_by) && count($create_by)) {
|
||||
$where .= " AND Address.create_by IN (" . implode(",", $create_by) . ")";
|
||||
}
|
||||
}
|
||||
/*
|
||||
@@ -433,42 +441,42 @@ class AddressModel {
|
||||
$where .= " AND parent_id IS NULL";
|
||||
}
|
||||
}*/
|
||||
|
||||
if(array_key_exists("create>", $filter)) {
|
||||
|
||||
if (array_key_exists("create>", $filter)) {
|
||||
$create = $filter['create>'];
|
||||
if(is_numeric($create)) {
|
||||
if (is_numeric($create)) {
|
||||
$where .= " AND Address.create > $create";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("create<", $filter)) {
|
||||
|
||||
if (array_key_exists("create<", $filter)) {
|
||||
$create = $filter['create<'];
|
||||
if(is_numeric($create)) {
|
||||
if (is_numeric($create)) {
|
||||
$where .= " AND Address.create < $create";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("edit>", $filter)) {
|
||||
|
||||
if (array_key_exists("edit>", $filter)) {
|
||||
$edit = $filter['edit>'];
|
||||
if(is_numeric($edit)) {
|
||||
if (is_numeric($edit)) {
|
||||
$where .= " AND Address.edit > $edit";
|
||||
}
|
||||
}
|
||||
|
||||
if(array_key_exists("edit<", $filter)) {
|
||||
|
||||
if (array_key_exists("edit<", $filter)) {
|
||||
$edit = $filter['edit<'];
|
||||
if(is_numeric($edit)) {
|
||||
if (is_numeric($edit)) {
|
||||
$where .= " AND Address.edit < $edit";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// custom where clause
|
||||
if(array_key_exists("add-where", $filter)) {
|
||||
$where .= " ".$filter['add-where'];
|
||||
if (array_key_exists("add-where", $filter)) {
|
||||
$where .= " " . $filter['add-where'];
|
||||
}
|
||||
|
||||
|
||||
//var_dump($filter, $where);exit;
|
||||
return $where;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ class DeviceApicontroller extends mfBaseApicontroller
|
||||
$deviceReturn[$key]['serial'] = $device->serial;
|
||||
$deviceReturn[$key]['last_config_backup'] = $device->last_config_backup;
|
||||
$deviceReturn[$key]['manufactor'] = $device->devicetype->devicemanufactor->name;
|
||||
$deviceReturn[$key]['autobackup'] = $device->autobackup;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -250,30 +250,57 @@ class DashboardController extends mfBaseController {
|
||||
return $orders;
|
||||
//var_dump($orders);exit;
|
||||
}
|
||||
|
||||
|
||||
private function getPartnerOrdersByStatus($preordercampaign_id = [], $gemeinde_id = false) {
|
||||
$orders = [];
|
||||
|
||||
if($gemeinde_id) {
|
||||
|
||||
if ($gemeinde_id) {
|
||||
$preorders = PreorderModel::searchActive(["preordercampaign_id" => $preordercampaign_id, "gemeinde_id" => $gemeinde_id]);
|
||||
} else {
|
||||
$preorders = PreorderModel::searchActive(["preordercampaign_id" => $preordercampaign_id]);
|
||||
$preorders = PreorderModel::searchActive(["preordercampaign_id" => $preordercampaign_id], false, false, true);
|
||||
}
|
||||
|
||||
foreach($preorders as $preorder) {
|
||||
$name = $preorder->partner->getCompanyOrName();
|
||||
if(!$name) $name = "Kein Partner";
|
||||
if(!array_key_exists($name, $orders)) {
|
||||
|
||||
$preorderStatus = PreorderstatusModel::getAll();
|
||||
$preorderStatus = array_column($preorderStatus, null, 'id');
|
||||
|
||||
|
||||
$partners = [];
|
||||
// log add partnerids from preorders
|
||||
$parnerIDs = [];
|
||||
foreach ($preorders as $preorder) {
|
||||
if (!in_array($preorder->partner_id, $parnerIDs))
|
||||
$parnerIDs[] = $preorder->partner_id;
|
||||
}
|
||||
|
||||
foreach ($preorders as $preorder) {
|
||||
$partnerId = $preorder->partner_id;
|
||||
if (!array_key_exists($partnerId, $partners) && $partnerId !== null) {
|
||||
$partner = AddressModel::getFirst(["id" => $partnerId]);
|
||||
$partners[$partnerId] = $partner->getCompanyOrName();
|
||||
$name = $partners[$partnerId];
|
||||
} else if ($partnerId === null) {
|
||||
$name = "Kein Partner";
|
||||
} else {
|
||||
$name = $partners[$partnerId];
|
||||
}
|
||||
|
||||
if (!array_key_exists($name, $orders)) {
|
||||
$orders[$name] = [];
|
||||
$orders[$name]["total"] = 0;
|
||||
}
|
||||
if(!array_key_exists($preorder->status->id, $orders[$name])) {
|
||||
$orders[$name][$preorder->status->id] = 0;
|
||||
|
||||
$status_id = $preorder->status_id;
|
||||
$status_code = $preorderStatus[$status_id]->code;
|
||||
|
||||
if (!array_key_exists($preorder->status_id, $orders[$name])) {
|
||||
$orders[$name][$preorder->status_id] = 0;
|
||||
}
|
||||
$orders[$name][$preorder->status->id]++;
|
||||
|
||||
$orders[$name][$preorder->status_id]++;
|
||||
$orders[$name]["total"]++;
|
||||
}
|
||||
//var_dump($orders);exit;
|
||||
|
||||
|
||||
return $orders;
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,8 @@ class DeviceController extends mfBaseController
|
||||
$data = [];
|
||||
$data['name'] = trim($r->name);
|
||||
$data['devicetype_id'] = $r->devicetype_id;
|
||||
$data['autobackup'] = trim($r->autobackup);
|
||||
|
||||
if (trim($r->pop_id) == "0") {
|
||||
$data['pop_id'] = NULL;
|
||||
} else {
|
||||
@@ -127,6 +129,9 @@ class DeviceController extends mfBaseController
|
||||
$data['gps_lat'] = $r->gps_lat;
|
||||
$data['gps_long'] = $r->gps_long;
|
||||
}
|
||||
if ($data['autobackup'] != "1") {
|
||||
$data['autobackup'] = "0";
|
||||
}
|
||||
$data['ip'] = $r->ip;
|
||||
$data['mac'] = $r->mac;
|
||||
$data['serial'] = $r->serial;
|
||||
|
||||
@@ -16,6 +16,7 @@ class DeviceModel
|
||||
public $gps_lat = null;
|
||||
public $addr_city = null;
|
||||
public $gps_long = null;
|
||||
public $autobackup = null;
|
||||
public $create_by = null;
|
||||
public $snmp_version = null;
|
||||
public $edit_by = null;
|
||||
|
||||
@@ -350,11 +350,11 @@ class PreorderModel {
|
||||
|
||||
return self::count($filter);
|
||||
}
|
||||
|
||||
public static function searchActive($filter = [], $limit = false, $returnDBRessource = false) {
|
||||
if(!is_array($filter)) return false;
|
||||
|
||||
if(!array_key_exists("deleted", $filter)) {
|
||||
|
||||
public static function searchActive($filter = [], $limit = false, $returnDBRessource = false, $returnArray = false) {
|
||||
if (!is_array($filter)) return false;
|
||||
|
||||
if (!array_key_exists("deleted", $filter)) {
|
||||
$filter["deleted"] = null;
|
||||
}
|
||||
|
||||
@@ -362,8 +362,8 @@ class PreorderModel {
|
||||
&& !array_key_exists("<status_id", $filter) && !array_key_exists(">status_id", $filter) && !array_key_exists("status_id", $filter) ) {
|
||||
$filter["<status_code"] = 899;
|
||||
}
|
||||
|
||||
return self::search($filter, $limit, $returnDBRessource);
|
||||
|
||||
return self::search($filter, $limit, $returnDBRessource, $returnArray);
|
||||
}
|
||||
|
||||
public static function count($filter) {
|
||||
@@ -387,8 +387,8 @@ class PreorderModel {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static function search($filter = [], $limit = false, $returnDBRessource = false) {
|
||||
|
||||
public static function search($filter = [], $limit = false, $returnDBRessource = false, $returnArray = false) {
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
@@ -425,9 +425,13 @@ class PreorderModel {
|
||||
if($returnDBRessource) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
while($data = $db->fetch_object($res)) {
|
||||
$items[] = new Preorder($data);
|
||||
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
if ($returnArray) {
|
||||
$items[] = $data;
|
||||
} else {
|
||||
$items[] = new Preorder($data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
|
||||
@@ -60,13 +60,12 @@ class RaspberryDisplayController extends mfBaseController
|
||||
}
|
||||
|
||||
protected function getConfig() {
|
||||
$ip = $_SERVER['REMOTE_ADDR'];
|
||||
$hostname = $this->request->hostname;
|
||||
|
||||
$displays = RaspberryDisplayModel::getByHostnameAndIp($hostname, $ip);
|
||||
$displays = RaspberryDisplayModel::getByHostname($hostname);
|
||||
|
||||
if ($displays === null) {
|
||||
die("No display found for this hostname and ip:" . $hostname . " X " . $ip);
|
||||
die("No display found for this hostname and ip:" . $hostname . " X ");
|
||||
}
|
||||
|
||||
return array_map(function ($display) {
|
||||
@@ -82,7 +81,7 @@ class RaspberryDisplayController extends mfBaseController
|
||||
protected function apiAction() {
|
||||
$do = $this->request->do;
|
||||
|
||||
if (!$this->me->is("employee") && !in_array($do, ["getDisplays", "change", "reboot"])) {
|
||||
if ($do !== "getConfig" && !$this->me->is("employee")) {
|
||||
$this->redirect("dashboard");
|
||||
}
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ class RaspberryDisplayModel
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getByHostnameAndIp($hostname, $ip)
|
||||
public static function getByHostname($hostname)
|
||||
{
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$res = $db->select("RaspberryDisplay", "*", "hostname = '$hostname' AND ip_address = '$ip'");
|
||||
$res = $db->select("RaspberryDisplay", "*", "hostname = '$hostname'");
|
||||
//fetch 2 rows
|
||||
|
||||
if ($db->num_rows($res)) {
|
||||
|
||||
@@ -18,6 +18,9 @@ class TimerecordingController extends mfBaseController
|
||||
|
||||
protected function indexAction()
|
||||
{
|
||||
$this->updatePlushours($this->me->id);
|
||||
$this->updateHolidays($this->me->id);
|
||||
|
||||
$timerecordingCategoriess = TimerecordingCategoryModel::getAll();
|
||||
$this->layout()->set("timerecordingCategoriess", $timerecordingCategoriess);
|
||||
$this->layout()->setTemplate("Timerecording/Index");
|
||||
@@ -30,6 +33,7 @@ class TimerecordingController extends mfBaseController
|
||||
$dataweek = $this->request->dataweek;
|
||||
$datamonth = $this->request->datamonth;
|
||||
$datayear = $this->request->datayear;
|
||||
$ajax = $this->request->ajax;
|
||||
|
||||
$data = [];
|
||||
|
||||
@@ -37,10 +41,16 @@ class TimerecordingController extends mfBaseController
|
||||
case "getTimerecordings":
|
||||
$return = $this->getTimerecordingsApi($datatype, $dataweek, $datamonth, $datayear);
|
||||
break;
|
||||
case "fillWorkinghours":
|
||||
$return = $this->fillWorkinghours($dataweek);
|
||||
break;
|
||||
case "checkWorkinghours":
|
||||
$return = $this->checkWorkingHours($ajax);
|
||||
break;
|
||||
default:
|
||||
$return = false;
|
||||
}
|
||||
|
||||
echo $do;
|
||||
if (!is_array($return) || !count($return)) {
|
||||
$data = ["status" => "error"];
|
||||
$this->returnJson($data);
|
||||
@@ -86,6 +96,9 @@ class TimerecordingController extends mfBaseController
|
||||
} else {
|
||||
$userid = $this->me->id;
|
||||
}
|
||||
if (!$endtime) {
|
||||
$endtime = strtotime(date("Y-m-d", $starttime) . " 23:59:00");
|
||||
}
|
||||
|
||||
$searchArray = ['user_id' => $userid, 'starttime' => $starttime, 'endtime' => $endtime];
|
||||
if ($id) {
|
||||
@@ -102,23 +115,177 @@ class TimerecordingController extends mfBaseController
|
||||
return $result;
|
||||
}
|
||||
|
||||
protected function updateOpenTimerecording()
|
||||
{
|
||||
$r = $this->request;
|
||||
$date = strtotime($r->date . " 23:59:00");
|
||||
if ($r->user_id) {
|
||||
$userid = $r->user_id;
|
||||
} else {
|
||||
$userid = $this->me->id;
|
||||
}
|
||||
$searchArray = ['user_id' => $userid, 'type' => 'opentimerecording'];
|
||||
$timerecordings = TimerecordingModel::search($searchArray);
|
||||
$timerecordingssave = new Timerecording($timerecordings[0]->id);
|
||||
|
||||
|
||||
$data = [];
|
||||
$data['end'] = $date;
|
||||
$timerecordingssave->update($data);
|
||||
$id = $timerecordingssave->save();
|
||||
if ($timerecordingssave->id) {
|
||||
if ($r->ajax == 1) {
|
||||
$message = "Buchung erfolgreich angelegt";
|
||||
$result['state'] = "success";
|
||||
$result['message'] = "$message";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
} else {
|
||||
if ($r->ajax == 1) {
|
||||
$message = "Buchung konnte nicht angelegt werden";
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "$message";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function checkWorkingHours($ajax = 0)
|
||||
{
|
||||
|
||||
$r = $this->request;
|
||||
|
||||
$starttime = strtotime($r->date . " " . $r->start . ":00");
|
||||
$endtime = strtotime($r->date . " " . $r->end . ":00");
|
||||
$date = $r->date;
|
||||
|
||||
if ($r->user_id) {
|
||||
$userid = $r->user_id;
|
||||
} else {
|
||||
$userid = $this->me->id;
|
||||
}
|
||||
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $userid]);
|
||||
$realHolidays = TimerecordingHolidayModel::getAll();
|
||||
foreach ($realHolidays as $realHoliday) {
|
||||
$realholiDay[date('Y-m-d', $realHoliday->timestamp)] = $realHoliday->timestamp;
|
||||
}
|
||||
if ($realholiDay[$date]) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Kein Zeitausgleich an einem Feiertag möglich";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
foreach ($workinghours as $workinghour) {
|
||||
$whstart = strtotime(date('Y-m-d', time()) . " " . $workinghour->start . ":00");
|
||||
$whend = strtotime(date('Y-m-d', time()) . " " . $workinghour->end . ":00");
|
||||
if (!$workingHours[$workinghour->day]) {
|
||||
$workingHours[$workinghour->day] = $whend - $whstart;
|
||||
} else {
|
||||
$workingHours[$workinghour->day] = $workingHours[$workinghour->day] + $whend - $whstart;
|
||||
}
|
||||
}
|
||||
if (!$workingHours[date("w", $starttime)]) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Kein Zeitausgleich außerhalb der Arbeitszeiten möglich";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
$maxTime = $workingHours[date("w", $starttime)];
|
||||
$isTime = $endtime - $starttime;
|
||||
$cleanTime = $isTime;
|
||||
if ($maxTime < $isTime) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Zeitausgleich kann maximal " . sprintf('%02dh:%02dm', floor($maxTime / 3600), floor($maxTime / 60 % 60)) . " an diesem Tag betragen.";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $userid]);
|
||||
|
||||
$plushours = $employee[0]->plushours_now * 1.25;
|
||||
$overtime = $employee[0]->overtime * 1.5;
|
||||
$overtimesum = $plushours + $overtime;
|
||||
if ($overtimesum < $isTime) {
|
||||
if ($overtimesum < 0) {
|
||||
$overtimesum = 0;
|
||||
}
|
||||
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Maximal verfügbarer ZA: " . sprintf('%02dh:%02dm', floor($overtimesum / 3600), floor($overtimesum / 60 % 60)) . ".";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
if ($plushours >= $isTime) {
|
||||
$isTime = $isTime * 0.8;
|
||||
$return['hours'] = $isTime;
|
||||
} elseif ($plushours <= 0) {
|
||||
$isTime = $isTime * 0.66666666666666666666666666666667;
|
||||
$return ['hours_overtime'] = $isTime;
|
||||
} else {
|
||||
$isTime25 = $plushours;
|
||||
$isTime50 = $isTime - $plushours;
|
||||
$isTime25 = $isTime25 * 0.8;
|
||||
$isTime50 = $isTime50 * 0.66666666666666666666666666666667;
|
||||
$isTime = $isTime25 + $isTime50;
|
||||
$return['hours'] = $isTime25;
|
||||
$return['hours_overtime'] = $isTime50;
|
||||
}
|
||||
if ($ajax == 1) {
|
||||
if ($r->ajax == 1) {
|
||||
if ($isTime<0) {
|
||||
$isTime = 0;
|
||||
}
|
||||
if ($cleanTime<0) {
|
||||
$cleanTime = 0;
|
||||
}
|
||||
$result['state'] = "success";
|
||||
$result['message'] = "<span class='text-bold'>Abzug:</span> " . sprintf('%02dh:%02dm', floor($isTime / 3600), floor($isTime / 60 % 60)) . " <span class='text-bold ml-1'>Zeitwert:</span> " . sprintf('%02dh:%02dm', floor($cleanTime / 3600), floor($cleanTime / 60 % 60));
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
} else {
|
||||
return $return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
protected function saveAction()
|
||||
{
|
||||
$r = $this->request;
|
||||
$id = $r->id;
|
||||
$enddate = $r->enddate;
|
||||
if (!$enddate && $r->start && $r->end) {
|
||||
$hourday = $r->hourday;
|
||||
|
||||
if ($hourday == 4) {
|
||||
|
||||
$this->updateOpenTimerecording();
|
||||
}
|
||||
$data = [];
|
||||
if ($hourday == 1 || $hourday == 6) {
|
||||
$starttime = strtotime($r->date . " " . $r->start . ":00");
|
||||
$endtime = strtotime($r->date . " " . $r->end . ":00");
|
||||
} elseif ($enddate) {
|
||||
if ($hourday == 6) {
|
||||
$data = $this->checkWorkingHours();
|
||||
}
|
||||
} elseif ($hourday == 2) {
|
||||
$starttime = strtotime($r->date . " 00:00:00");
|
||||
$endtime = strtotime($enddate . " 23:59:00");
|
||||
} else if (!$enddate && !$r->start && !$r->end) {
|
||||
} else if ($hourday == 3) {
|
||||
$starttime = strtotime($r->date . " 00:00:00");
|
||||
$endtime = NULL;
|
||||
} else if ($hourday == 5) {
|
||||
$starttime = strtotime($r->date . " 00:00:00");
|
||||
$endtime = strtotime($r->date . " 23:59:00");
|
||||
}
|
||||
|
||||
$result = $this->checkTimerecording($starttime, $endtime, $id);
|
||||
if ($hourday != 5) {
|
||||
$result = $this->checkTimerecording($starttime, $endtime, $id);
|
||||
}
|
||||
if ($result['state'] == "error") {
|
||||
if ($r->ajax == 1) {
|
||||
echo json_encode($result);
|
||||
@@ -140,28 +307,73 @@ class TimerecordingController extends mfBaseController
|
||||
$mode = "add";
|
||||
}
|
||||
|
||||
$data = [];
|
||||
|
||||
if ($r->user_id) {
|
||||
$data['user_id'] = $r->user_id;
|
||||
} else {
|
||||
$data['user_id'] = $this->me->id;
|
||||
}
|
||||
|
||||
$data['start'] = $starttime;
|
||||
$data['end'] = $endtime;
|
||||
$data['timerecordingCategory_id'] = trim($r->timerecordingCategory_id);
|
||||
$data['comment'] = trim($r->comment);
|
||||
$data['businesstrip'] = $r->businesstrip;
|
||||
$data['businesstrip_info'] = $r->businesstrip_info;
|
||||
$data['homeoffice'] = $r->homeoffice;
|
||||
$data['days'] = $r->days;
|
||||
|
||||
if (!$data['businesstrip'] || $data['businesstrip'] == "false") {
|
||||
$data['businesstrip'] = 0;
|
||||
}
|
||||
if (!$data['homeoffice'] || $data['homeoffice'] == "false") {
|
||||
$data['homeoffice'] = 0;
|
||||
}
|
||||
if (!$data['days'] || $data['days'] == "false") {
|
||||
$data['days'] = 0;
|
||||
}
|
||||
if ($r->businesstrip == 1 && !$r->businesstrip_info) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Dienstreiseort darf nicht leer sein";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
if (!$data['businesstrip_info']) {
|
||||
$data['businesstrip_info'] = NULL;
|
||||
}
|
||||
|
||||
|
||||
if (!$data['user_id']) {
|
||||
if ($r->ajax == 1) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Benutzer darf nicht leer sein";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
$this->layout()->setFlash("Benutzer darf nicht leer sein", "error");
|
||||
$this->redirect("Timerecording");
|
||||
|
||||
}
|
||||
if ($data['start'] < 1577833200) {
|
||||
if ($r->ajax == 1) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Ungültige Startzeit";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
$this->layout()->setFlash("Ungültige Startzeit", "error");
|
||||
$this->redirect("Timerecording");
|
||||
}
|
||||
if ($data['end'] && $data['end'] < 1577833200) {
|
||||
if ($r->ajax == 1) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Ungültige Endzeit";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
$this->layout()->setFlash("Ungültige Endzeit", "error");
|
||||
$this->redirect("Timerecording");
|
||||
|
||||
}
|
||||
if (!$data['timerecordingCategory_id']) {
|
||||
$data['timerecordingCategory_id'] = NULL;
|
||||
@@ -195,7 +407,7 @@ class TimerecordingController extends mfBaseController
|
||||
}
|
||||
if ($id) {
|
||||
$timerecordingCategoriess = TimerecordingCategoryModel::search(['id' => $data['timerecordingCategory_id']]);
|
||||
if ($timerecordingCategoriess[0]->approval == "1") {
|
||||
if ($timerecordingCategoriess[0]->approval == "1" && !$r->user_id) {
|
||||
$body = 'Beantrag von: ' . $this->me->name . '
|
||||
';
|
||||
$body .= 'Buchungsart: ' . $timerecordingCategoriess[0]->name . '
|
||||
@@ -204,14 +416,27 @@ class TimerecordingController extends mfBaseController
|
||||
$body .= 'von: ' . date("d.m.Y H:i", $data['start']) . ' bis: ' . date("H:i", $data['end']);
|
||||
} else if ($timerecordingCategoriess[0]->hourday == "2") {
|
||||
$body .= 'von: ' . date("d.m.Y", $data['start']) . ' bis: ' . date("d.m.Y", $data['end']);
|
||||
} else if ($timerecordingCategoriess[0]->hourday == "6") {
|
||||
$body .= 'von: ' . date("d.m.Y H:i", $data['start']) . ' bis: ' . date("H:i", $data['end']);
|
||||
}
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject('Antrag für ' . $timerecordingCategoriess[0]->name . ' erstellt');
|
||||
$email->setBody($body);
|
||||
$email->setFrom('zeiterfassung@xinon.at', 'Xinon Zeiterfassung');
|
||||
$email->setTo('daniel.spitzer@inode.at');
|
||||
$email->setFrom(TT_TIMERECORDING_EMAIL, TT_TIMERECORDING_EMAIL_NAME);
|
||||
$email->setTo($this->me->email);
|
||||
$email->send();
|
||||
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject('Antrag für ' . $timerecordingCategoriess[0]->name . ' erstellt (' . $this->me->name . ')');
|
||||
$email->setBody($body);
|
||||
$email->setFrom(TT_TIMERECORDING_EMAIL, TT_TIMERECORDING_EMAIL_NAME);
|
||||
$email->setTo(TT_TIMERECORDING_EMAIL);
|
||||
$email->send();
|
||||
}
|
||||
if ($data['timerecordingCategory_id'] == "3" || $timerecordingCategoriess[0]->hourday == "5") {
|
||||
$this->updateHolidays($data['user_id']);
|
||||
}
|
||||
$this->updatePlushours($data['user_id']);
|
||||
}
|
||||
|
||||
if ($mode == "edit") {
|
||||
@@ -229,22 +454,149 @@ class TimerecordingController extends mfBaseController
|
||||
$this->redirect("Timerecording");
|
||||
}
|
||||
|
||||
public function updateHolidays($userid)
|
||||
{
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $userid]);
|
||||
if ($employee) {
|
||||
$employee = $employee[0];
|
||||
$holidays = $employee->holidays;
|
||||
$holidays_now = $employee->holidays_now;
|
||||
$holidays_timestamp = $employee->holidays_timestamp;
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $userid]);
|
||||
$realHolidays = TimerecordingHolidayModel::getAll();
|
||||
foreach ($realHolidays as $realHoliday) {
|
||||
$realholiDay[date('Y-m-d', $realHoliday->timestamp)] = $realHoliday->timestamp;
|
||||
}
|
||||
if (!$holidays_timestamp) {
|
||||
//$holidays_timestamp = $employee->startdate;
|
||||
$holidays_timestamp = strtotime('2024-01-01 00:00:00');
|
||||
$holidays_now = $holidays;
|
||||
}
|
||||
$timerecordings = TimerecordingModel::search(['user_id' => $userid, 'start' => $holidays_timestamp, 'timerecordingCategory_id' => 3]);
|
||||
$timerecordingscorrections = TimerecordingModel::search(['user_id' => $userid, 'start' => $holidays_timestamp, 'days' => 1]);
|
||||
foreach ($timerecordings as $timerecording) {
|
||||
$daycounter = ($timerecording->end - $timerecording->start) / 86400;
|
||||
$daycounter = intval(round($daycounter, 0, PHP_ROUND_HALF_DOWN));
|
||||
$daycounter = $daycounter * 86400;
|
||||
if (is_int($daycounter)) {
|
||||
for ($i = 86400; $i <= $daycounter; $i = $i + 86400) {
|
||||
$holidayDays[date("Y-m-d", $timerecording->start + $i - 86400)] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTimerecordingsApi($datatype, $dataweek, $datamonth, $datayear)
|
||||
|
||||
foreach ($workinghours as $workinghour) {
|
||||
|
||||
$whstart = strtotime(date('Y-m-d', time()) . " " . $workinghour->start . ":00");
|
||||
$whend = strtotime(date('Y-m-d', time()) . " " . $workinghour->end . ":00");
|
||||
if (!$workingHours[$workinghour->day]) {
|
||||
$workingHours[$workinghour->day] = $whend - $whstart;
|
||||
} else {
|
||||
$workingHours[$workinghour->day] = $workingHours[$workinghour->day] + $whend - $whstart;
|
||||
}
|
||||
}
|
||||
//check if holiday is already in the list
|
||||
foreach ($holidayDays as $key => $holidayDay) {
|
||||
if (($realholiDay[$key])) {
|
||||
|
||||
} else if ($workingHours[date('w', strtotime($key))]) {
|
||||
$holidays_now--;
|
||||
}
|
||||
}
|
||||
foreach ($timerecordingscorrections as $timerecordingscorrection) {
|
||||
$holidays_now = $holidays_now + $timerecordingscorrection->days;
|
||||
}
|
||||
|
||||
if ($holidays_now != $employee->holidays_now) {
|
||||
$employeeupdate = new TimerecordingEmployee($employee->id);
|
||||
$data = [];
|
||||
$data['holidays_now'] = $holidays_now;
|
||||
$employeeupdate->update($data);
|
||||
$employeeupdate->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function updatePlushours($userid)
|
||||
{
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $userid]);
|
||||
if ($employee) {
|
||||
$employee = $employee[0];
|
||||
$plushours = $employee->plushours;
|
||||
$plushours_now = $employee->plushours_now;
|
||||
$plushours_timestamp = $employee->plushours_timestamp;
|
||||
$overtime = $employee->overtime;
|
||||
$overtime_now = $employee->overtime_now;
|
||||
$overtime_timestamp = $employee->overtime_timestamp;
|
||||
|
||||
if (!$plushours_timestamp) {
|
||||
$plushours_timestamp = $employee->startdate;
|
||||
$plushours_now = $plushours;
|
||||
|
||||
}
|
||||
if (!$overtime_timestamp) {
|
||||
$overtime_timestamp = $employee->startdate;
|
||||
$overtime_now = $overtime;
|
||||
}
|
||||
$endtime = time() - 86400;
|
||||
$endtime = date("Y-m-d", $endtime);
|
||||
$endtime = strtotime($endtime . " 23:59:00");
|
||||
|
||||
if ($plushours_timestamp > 0) {
|
||||
$return = $this->getTimerecordingsApi(5, null, null, null, $plushours_timestamp, $endtime, $userid);
|
||||
$diffTime = $return['is'] - $return['must'];
|
||||
$plushours_now = $plushours_now + $diffTime;
|
||||
} else {
|
||||
$diffTime = 0;
|
||||
}
|
||||
$minushours = 0;
|
||||
$minushoursovertime = 0;
|
||||
$timerecordings = TimerecordingModel::search(['user_id' => $userid, 'start' => $plushours_timestamp, 'hours' => 1]);
|
||||
foreach ($timerecordings as $timerecording) {
|
||||
if ($timerecording->hours) {
|
||||
$timediff = $timerecording->hours;
|
||||
$minushours = $minushours + $timediff;
|
||||
}
|
||||
if ($timerecording->hours_overtime) {
|
||||
$timediffovertime = $timerecording->hours_overtime;
|
||||
$minushoursovertime = $minushoursovertime + $timediffovertime;
|
||||
}
|
||||
}
|
||||
$plushours_now = $plushours_now - $minushours;
|
||||
$diffTime = $diffTime - $minushours;
|
||||
$overtime_now = $overtime_now - $minushoursovertime;
|
||||
if ($employee->plushours_now != $plushours_now || $employee->overtime_now != $overtime_now) {
|
||||
$employeeupdate = new TimerecordingEmployee($employee->id);
|
||||
$data = [];
|
||||
$data['plushours_now'] = $plushours_now;
|
||||
$data['overtime_now'] = $overtime_now;
|
||||
$employeeupdate->update($data);
|
||||
$employeeupdate->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function getTimerecordingsApi($datatype, $dataweek, $datamonth, $datayear, $startime = null, $endtime = null, $userid = null)
|
||||
{
|
||||
$mustSeconds = 0;
|
||||
$isSeconds = 0;
|
||||
$holiDays = 0;
|
||||
$plusHours = 0;
|
||||
|
||||
$rows = [];
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $this->me->id]);
|
||||
if ($employee) {
|
||||
$holiDays = $employee[0]->holidays;
|
||||
$plusHours = $employee[0]->plushours;
|
||||
|
||||
$startdate = time();
|
||||
if (!$userid) {
|
||||
$userid = $this->me->id;
|
||||
}
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $this->me->id]);
|
||||
$rows = [];
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $userid]);
|
||||
if ($employee) {
|
||||
$holiDays = $employee[0]->holidays_now;
|
||||
$plusHours = $employee[0]->plushours_now;
|
||||
$auto_workinghours = $employee[0]->auto_workinghours;
|
||||
$startdate = $employee[0]->startdate;
|
||||
$overtime = $employee[0]->overtime_now;
|
||||
}
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $userid]);
|
||||
$holidays = TimerecordingHolidayModel::getAll();
|
||||
foreach ($workinghours as $workinghour) {
|
||||
|
||||
@@ -265,8 +617,9 @@ class TimerecordingController extends mfBaseController
|
||||
$year = date('Y', $dataweek);
|
||||
$timestamp_montag = strtotime("{$year}-W{$kw}");
|
||||
$timestamp_sonntag = strtotime("{$year}-W{$kw}-7");
|
||||
$firstdate = strtotime(date("Y-m-d", $timestamp_montag) . " 00:00:00");
|
||||
$lastdate = strtotime(date("Y-m-d", $timestamp_sonntag) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $this->me->id, 'start' => $timestamp_montag, 'end' => $lastdate];
|
||||
$searchArray = ['user_id' => $userid, 'start' => $timestamp_montag, 'end' => $lastdate];
|
||||
|
||||
$daycounter = '0';
|
||||
|
||||
@@ -274,7 +627,7 @@ class TimerecordingController extends mfBaseController
|
||||
for ($i = 1; $i <= 7; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate]) {
|
||||
if (!$holiDay[$dDate] && $dDate >= date('Y-m-d', $startdate)) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
|
||||
@@ -285,7 +638,23 @@ class TimerecordingController extends mfBaseController
|
||||
$lastdate = strtotime(date("Y-m-t", $datamonth));
|
||||
$daycount = date("t", $datamonth);
|
||||
$lastdate = strtotime(date("Y-m-d", $lastdate) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $this->me->id, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$searchArray = ['user_id' => $userid, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate] && $dDate >= date('Y-m-d', $startdate)) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
} else if ($datatype == 3) {
|
||||
$firstdate = strtotime(date("Y-01-01", $datayear));
|
||||
$lastdate = strtotime(date("Y-12-31 23:59:59", $datayear));
|
||||
$daycount = date("t", $datamonth);
|
||||
$lastdate = strtotime(date("Y-m-d", $lastdate) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $userid, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
@@ -294,17 +663,15 @@ class TimerecordingController extends mfBaseController
|
||||
if (!$holiDay[$dDate]) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
|
||||
|
||||
} else if ($datatype == 3) {
|
||||
$firstdate = strtotime(date("Y-01-01", $datayear));
|
||||
$lastdate = strtotime(date("Y-12-31 23:59:59", $datayear));
|
||||
$daycount = date("t", $datamonth);
|
||||
$lastdate = strtotime(date("Y-m-d", $lastdate) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $this->me->id, 'start' => $firstdate, 'end' => $lastdate];
|
||||
} else if ($datatype == 5) {
|
||||
$firstdate = $startime;
|
||||
$lastdate = $endtime;
|
||||
$timediff = $lastdate - $firstdate;
|
||||
$daycount = $timediff / 86400;
|
||||
$daycount = round($daycount, 0, PHP_ROUND_HALF_DOWN);
|
||||
$searchArray = ['user_id' => $userid, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
@@ -343,7 +710,8 @@ class TimerecordingController extends mfBaseController
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 2) {
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 2 || ($timerecording->timerecordingCategory->hourday == 3 && $timerecording->end)) {
|
||||
|
||||
$date = date("d.m.", $timerecording->start) . " - " . $daysgerm[date("w", $timerecording->end)] . " " . date("d.m.Y", $timerecording->end);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$enddate = date("Y-m-d", $timerecording->end);
|
||||
@@ -356,23 +724,111 @@ class TimerecordingController extends mfBaseController
|
||||
} else {
|
||||
$endtimecalc = $timerecording->end;
|
||||
}
|
||||
if ($firstdate > $timerecording->start) {
|
||||
$starttimecalc = $firstdate;
|
||||
} else {
|
||||
$starttimecalc = $timerecording->start;
|
||||
}
|
||||
$summcounter = 0;
|
||||
for ($i = $timerecording->start; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$savecounter = 0;
|
||||
$sumdays = 0;
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$holidaycounter = $workingHours[date("w", $i)];
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
if (!$holiDay[$daycheck]) {
|
||||
if ($holidaycounter) {
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;
|
||||
$sumdays++;
|
||||
}
|
||||
}
|
||||
if ($savecounter == 1000) {
|
||||
echo $savecounter;
|
||||
die();
|
||||
}
|
||||
$savecounter++;
|
||||
}
|
||||
$seconds = $summcounter;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
// $sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
if ($sumdays == 1 || $sumdays == 0) {
|
||||
$sum = $sumdays . " Tag";
|
||||
} else if ($sumdays > 1) {
|
||||
$sum = $sumdays . " Tage";
|
||||
}
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 3 && !$timerecording->end) {
|
||||
$date = date("d.m.Y", $timerecording->start) . " - " . $daysgerm[date("w", time())] . " " . date("d.m.Y", time());;
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$enddatetemp = date("Y-m-d", time());
|
||||
$enddatetemp = strtotime($enddatetemp . " 23:59:59");
|
||||
$enddate = date("Y-m-d", $enddatetemp + 7200);
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
|
||||
if ($lastdate < time()) {
|
||||
$endtimecalc = $lastdate;
|
||||
} else {
|
||||
$endtimecalc = time();
|
||||
}
|
||||
$summcounter = 0;
|
||||
if ($firstdate > $timerecording->start) {
|
||||
$starttimecalc = $firstdate;
|
||||
} else {
|
||||
$starttimecalc = $timerecording->start;
|
||||
}
|
||||
$summcounter = 0;
|
||||
$savecounter = 0;
|
||||
// echo $starttimecalc."<br>";
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$holidaycounter = $workingHours[$timerecording->user_id][date("w", $i)];
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
if (!$holiDay[$daycheck]) {
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;;
|
||||
}
|
||||
if ($savecounter == 1000) {
|
||||
echo $savecounter;
|
||||
die();
|
||||
}
|
||||
$savecounter++;
|
||||
}
|
||||
$seconds = $summcounter;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 3 || $timerecording->timerecordingCategory->hourday == 4) {
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 5) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
if ($timerecording->days > 0) {
|
||||
if ($timerecording->days == 1) {
|
||||
$sum = "+" . $timerecording->days . " Tag";
|
||||
} else {
|
||||
$sum = "+" . $timerecording->days . " Tage";
|
||||
}
|
||||
} else {
|
||||
if ($timerecording->days == -1) {
|
||||
$sum = $timerecording->days . " Tag";
|
||||
} else {
|
||||
$sum = $timerecording->days . " Tage";
|
||||
}
|
||||
}
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 6) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$start = date("H:i", $timerecording->start);
|
||||
$end = date("H:i", $timerecording->end);
|
||||
// $seconds = $timerecording->hours;
|
||||
$seconds = $timerecording->end - $timerecording->start;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = "-" . sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
}
|
||||
|
||||
if ($timerecording->timerecordingCategory->approval == 1 && $timerecording->approved == 0) {
|
||||
@@ -381,6 +837,18 @@ class TimerecordingController extends mfBaseController
|
||||
$state = '<i class="fa-regular fa-circle-check mr-1"></i>';
|
||||
}
|
||||
$edit = "";
|
||||
if ($timerecording->businesstrip == 1) {
|
||||
$category = "<span>" . $timerecording->timerecordingCategory->name . "</span><span class='text-bold ml-1'> (Dienstreise: " . $timerecording->businesstrip_info . ")</span>";
|
||||
} else if ($timerecording->homeoffice == 1) {
|
||||
$category = "<span>" . $timerecording->timerecordingCategory->name . "</span><span class='text-bold ml-1'> (Homeoffice)</span>";
|
||||
} else {
|
||||
$category = $timerecording->timerecordingCategory->name;
|
||||
}
|
||||
if ($timerecording->timerecordingCategory->hourday == 3 && !$timerecording->end) {
|
||||
$category = $category . "<span class='text-bold ml-2'>(offen)</span>";
|
||||
}
|
||||
|
||||
|
||||
if ($timerecording->completed == 0 && $timerecording->timerecordingCategory->only_admin == 0):
|
||||
if ($timerecording->approved == 0) :
|
||||
$edit = '<i class="far fa-edit edit-button" data-id="' . $timerecording->id . '"
|
||||
@@ -390,6 +858,9 @@ class TimerecordingController extends mfBaseController
|
||||
data-end="' . $end . '"
|
||||
data-enddate="' . $enddate . '"
|
||||
data-comment="' . $timerecording->comment . '"
|
||||
data-businesstrip="' . $timerecording->businesstrip . '"
|
||||
data-businesstripinfo="' . $timerecording->businesstrip_info . '"
|
||||
data-homeoffice="' . $timerecording->homeoffice . '"
|
||||
title="Bearbeiten"></i>';
|
||||
else :
|
||||
$edit .= '<div class="edit-placeholder"></div>';
|
||||
@@ -403,35 +874,136 @@ class TimerecordingController extends mfBaseController
|
||||
'start' => array('start' => $start, 'order' => $start),
|
||||
'end' => array('end' => $end, 'order' => $end),
|
||||
'sum' => array('sum' => $sum, 'order' => $sum),
|
||||
'category' => array('category' => $timerecording->timerecordingCategory->name, 'order' => $timerecording->timerecordingCategory->name),
|
||||
'category' => array('category' => $category, 'order' => $timerecording->timerecordingCategory->name),
|
||||
'comment' => array('comment' => $timerecording->comment, 'order' => $timerecording->comment),
|
||||
'edit' => array('edit' => $edit, 'order' => $edit),
|
||||
);
|
||||
}
|
||||
endforeach;
|
||||
$json['success'] = true;
|
||||
$json['time']['is'] = sprintf('%02dh:%02dm', floor($isSeconds / 3600), floor($isSeconds / 60 % 60));
|
||||
$json['time']['must'] = sprintf('%02dh:%02dm', floor($mustSeconds / 3600), floor($mustSeconds / 60 % 60));
|
||||
$json['time']['holidays'] = $holiDays;
|
||||
$json['time']['plushours'] = sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
$json['data'] = $rows;
|
||||
$json['recordsFiltered'] = $responsecount;
|
||||
$json['recordsTotal'] = $responsecount;
|
||||
$json = json_encode($json);
|
||||
echo trim($json);
|
||||
die();
|
||||
if ($datatype == 5) {
|
||||
$response['is'] = $isSeconds;
|
||||
$response['must'] = $mustSeconds;
|
||||
return $response;
|
||||
} else {
|
||||
$plusHours = $overtime + $plusHours;
|
||||
if ($plusHours < 0) {
|
||||
$plusHours = $plusHours * -1;
|
||||
$plusHours = "-" . sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
} else {
|
||||
$plusHours = sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
}
|
||||
if ($isSeconds < 0) {
|
||||
$isSeconds = $isSeconds * -1;
|
||||
$isSeconds = "-" . sprintf('%02dh:%02dm', floor($isSeconds / 3600), floor($isSeconds / 60 % 60));
|
||||
} else {
|
||||
$isSeconds = sprintf('%02dh:%02dm', floor($isSeconds / 3600), floor($isSeconds / 60 % 60));
|
||||
}
|
||||
|
||||
|
||||
$json['success'] = true;
|
||||
$json['time']['auto_workinghours'] = $auto_workinghours;
|
||||
$json['time']['is'] = $isSeconds;
|
||||
$json['time']['must'] = sprintf('%02dh:%02dm', floor($mustSeconds / 3600), floor($mustSeconds / 60 % 60));
|
||||
$json['time']['holidays'] = $holiDays;
|
||||
$json['time']['plushours'] = $plusHours;
|
||||
$json['data'] = $rows;
|
||||
$json['recordsFiltered'] = $responsecount;
|
||||
$json['recordsTotal'] = $responsecount;
|
||||
$json = json_encode($json);
|
||||
echo trim($json);
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
protected function fillWorkinghours($dataweek)
|
||||
{
|
||||
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $this->me->id]);
|
||||
if ($employee) {
|
||||
$auto_workinghours = $employee[0]->auto_workinghours;
|
||||
}
|
||||
if ($auto_workinghours == 0) {
|
||||
$result['state'] = "error";
|
||||
$result['error'] = "Automatische Arbeitszeiten sind deaktiviert";
|
||||
echo json_encode($result);
|
||||
die();
|
||||
}
|
||||
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $this->me->id]);
|
||||
$holidays = TimerecordingHolidayModel::getAll();
|
||||
foreach ($workinghours as $workinghour) {
|
||||
$workingHours[$workinghour->day][] = array('start' => $workinghour->start, 'end' => $workinghour->end);
|
||||
}
|
||||
foreach ($holidays as $holiday) {
|
||||
$holiDay[date('Y-m-d', $holiday->timestamp)] = $holiday->timestamp;
|
||||
}
|
||||
|
||||
|
||||
$kw = date('W', $dataweek);
|
||||
$year = date('Y', $dataweek);
|
||||
$timestamp_montag = strtotime("{$year}-W{$kw}");
|
||||
$timestamp_sonntag = strtotime("{$year}-W{$kw}-7");
|
||||
$firstdate = strtotime(date("Y-m-d", $timestamp_montag) . " 00:00:00");
|
||||
$lastdate = strtotime(date("Y-m-d", $timestamp_sonntag) . ' 23:59:59');
|
||||
|
||||
$searchArray = ['user_id' => $this->me->id, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timerecording = TimerecordingModel::search($searchArray);
|
||||
|
||||
|
||||
$daycounter = '0';
|
||||
$update = false;
|
||||
$timestamp = $timestamp_montag;
|
||||
for ($i = 1; $i <= 7; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate]) {
|
||||
if ($workingHours[$dDay]) {
|
||||
foreach ($workingHours[$dDay] as $workingHour) {
|
||||
|
||||
$starttime = strtotime($dDate . " " . $workingHour['start'] . ":00");
|
||||
$endtime = strtotime($dDate . " " . $workingHour['end'] . ":00");
|
||||
$check = $this->checkTimerecording($starttime, $endtime);
|
||||
if ($employee[0]->startdate <= $starttime) {
|
||||
if ($check['state'] == "success") {
|
||||
$update = 1;
|
||||
$data = [];
|
||||
$data['user_id'] = $this->me->id;
|
||||
$data['start'] = $starttime;
|
||||
$data['end'] = $endtime;
|
||||
$data['timerecordingCategory_id'] = 1;
|
||||
$data['comment'] = "Automatisch eingetragen";
|
||||
$data['businesstrip'] = 0;
|
||||
$data['businesstrip_info'] = NULL;
|
||||
$timerecordings = TimerecordingModel::create($data);
|
||||
$id = $timerecordings->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;;
|
||||
}
|
||||
if ($update) {
|
||||
$this->updatePlushours($this->me->id);
|
||||
$this->updateHolidays($this->me->id);
|
||||
}
|
||||
}
|
||||
|
||||
protected function deleteAction()
|
||||
{
|
||||
$id = $this->request->id;
|
||||
$timerecordings = new Timerecording($id);
|
||||
$userid = $timerecordings->user_id;
|
||||
if (!$timerecordings->id || $timerecordings->id != $id) {
|
||||
$this->layout()->setFlash("Buchung nicht gefunden.", "error");
|
||||
$this->redirect("Timerecording");
|
||||
}
|
||||
|
||||
$timerecordings->delete();
|
||||
$this->updateHolidays($userid);
|
||||
$this->updatePlushours($userid);
|
||||
|
||||
if ($this->request->ajax == 1) {
|
||||
die();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,13 @@ class TimerecordingModel
|
||||
private $user_id;
|
||||
private $start;
|
||||
private $end;
|
||||
private $hours;
|
||||
private $hours_overtime;
|
||||
private $days;
|
||||
private $timerecordingCategory_id;
|
||||
private $businesstrip;
|
||||
private $businesstrip_info;
|
||||
private $homeoffice;
|
||||
private $comment;
|
||||
private $approved;
|
||||
private $completed;
|
||||
@@ -122,7 +128,7 @@ class TimerecordingModel
|
||||
$items = [];
|
||||
$db = FronkDB::singleton();
|
||||
$where = self::getSqlFilter($filter);
|
||||
$res = $db->select("Timerecording", "*", "$where");
|
||||
$res = $db->select("Timerecording", "*", "$where ");
|
||||
if ($db->num_rows($res)) {
|
||||
while ($data = $db->fetch_object($res)) {
|
||||
$items[] = new Timerecording($data);
|
||||
@@ -133,7 +139,7 @@ class TimerecordingModel
|
||||
|
||||
private static function getSqlFilter($filter)
|
||||
{
|
||||
$where = "1=1 ";
|
||||
$where = "1=1";
|
||||
|
||||
if (array_key_exists("user_id", $filter)) {
|
||||
$userid = $filter['user_id'];
|
||||
@@ -145,19 +151,48 @@ class TimerecordingModel
|
||||
$start = $filter['start'];
|
||||
$end = $filter['end'];
|
||||
if (is_numeric($start) && is_numeric($end)) {
|
||||
$where .= " AND `start` > $start AND `start` < $end";
|
||||
$where .= " AND ((`start` >= $start AND `start` <= $end) OR (`end` >= $start AND `end` <= $end) OR `end` is NULL) ORDER by user_id ASC";
|
||||
}
|
||||
}
|
||||
if (array_key_exists("start", $filter) && array_key_exists("timerecordingCategory_id", $filter)) {
|
||||
$start = $filter['start'];
|
||||
$timerecordingCategory_id = $filter['timerecordingCategory_id'];
|
||||
if (is_numeric($start) && is_numeric($timerecordingCategory_id)) {
|
||||
$where .= " AND `start` >= $start AND `timerecordingCategory_id` = $timerecordingCategory_id ORDER by start ASC";
|
||||
}
|
||||
}
|
||||
if (array_key_exists("start", $filter) && array_key_exists("hours", $filter)) {
|
||||
$start = $filter['start'];
|
||||
if (is_numeric($start)) {
|
||||
$where .= " AND `start` >= $start AND (`hours`>0 or `hours_overtime`>0) ORDER by start ASC";
|
||||
}
|
||||
}
|
||||
if (array_key_exists("start", $filter) && array_key_exists("days", $filter)) {
|
||||
$days = $filter['days'];
|
||||
$start = $filter['start'];
|
||||
if ($days === 1) {
|
||||
$where .= " AND `start` >= $start AND `days` !=0 ORDER by start ASC";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (array_key_exists("starttime", $filter) && array_key_exists("endtime", $filter)) {
|
||||
$starttime = $filter['starttime'];
|
||||
$endtime = $filter['endtime'];
|
||||
$id = $filter['id'];
|
||||
if (is_numeric($starttime) && is_numeric($endtime)) {
|
||||
$where .= " AND ((`start` <= $starttime AND `end` >= $starttime ) || (`start` >= $endtime AND `end` <= $endtime) || (`start` >= $starttime AND `end` >= $starttime AND `start` <= $endtime AND `end` <= $endtime))";
|
||||
if ($id && is_numeric($id)) {
|
||||
$where .= " AND `id` != $id";
|
||||
}
|
||||
$where .= " AND (((`start` <= $starttime AND `end` > $starttime ) OR (`start` > $endtime AND `end` < $endtime) OR (`start` > $starttime AND `end` > $starttime AND `start` <= $endtime AND `end` <= $endtime) OR (`start` > $starttime AND `end` > $starttime AND `start` < $endtime AND `end` > $endtime) OR (`start` = $starttime AND `end` = $endtime )) OR ( `start` <= $starttime AND `end` IS NULL)) ORDER by user_id ASC";
|
||||
|
||||
//var_dump($where);exit;
|
||||
}
|
||||
}
|
||||
if (array_key_exists("type", $filter)) {
|
||||
$type = $filter['type'];
|
||||
if ($type === "opentimerecording") {
|
||||
$where .= " AND `end` IS NULL ORDER by start DESC LIMIT 1";
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
class TimerecordingCalendarController extends mfBaseController
|
||||
{
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$this->needlogin = true;
|
||||
$me = new User();
|
||||
$me->loadMe();
|
||||
$this->me = $me;
|
||||
$this->layout()->set("me", $me);
|
||||
|
||||
if (!$me->is(["employee"])) {
|
||||
$this->redirect("Dashboard");
|
||||
}
|
||||
}
|
||||
|
||||
protected function indexAction()
|
||||
{
|
||||
$timerecordingholidays = TimerecordingHolidayModel::getAll();
|
||||
$this->layout()->set("timerecordingholidays", $timerecordingholidays);
|
||||
$timerecordingemployees = TimerecordingEmployeeModel::getAll();
|
||||
$this->layout()->set("timerecordingemployees", $timerecordingemployees);
|
||||
$this->layout()->setTemplate("TimerecordingCalendar/Index");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,7 +9,7 @@ class TimerecordingCategoryModel
|
||||
private $require_comment;
|
||||
private $only_admin;
|
||||
private $businesstrip;
|
||||
public static $hourday_definition = array(1 => "Uhrzeit (von/bis)", 2 => "Tage (von/bis)", 3 => "Startdatum", 4 => "Enddatum");
|
||||
public static $hourday_definition = array(1 => "Uhrzeit (von/bis)", 2 => "Tage (von/bis)", 3 => "Startdatum", 4 => "Enddatum", 5 => "Anzahl Tage", 6 => "ZA Uhrzeit (von/bis)");
|
||||
public static $approval_definition = array(0 => "Nein", 1 => "Ja");
|
||||
public static $require_comment_definition = array(0 => "Nein", 1 => "Ja");
|
||||
public static $businesstrip_definition = array(0 => "Nein", 1 => "Ja");
|
||||
|
||||
@@ -101,6 +101,12 @@ class TimerecordingEmployeeController extends mfBaseController
|
||||
if (is_numeric($plushours)) {
|
||||
$plushours = $plushours * 3600;
|
||||
}
|
||||
$overtime = $r->overtime;
|
||||
$overtime = str_replace(',', '.', $overtime);
|
||||
if (is_numeric($overtime)) {
|
||||
$overtime = $overtime * 3600;
|
||||
}
|
||||
|
||||
|
||||
$data = [];
|
||||
$data['user_id'] = trim($r->user_id);
|
||||
@@ -109,8 +115,18 @@ class TimerecordingEmployeeController extends mfBaseController
|
||||
$data['plushours'] = $plushours;
|
||||
$data['startdate'] = strtotime($r->startdate);
|
||||
$data['type'] = trim($r->type);
|
||||
$data['overtime'] = $overtime;
|
||||
#
|
||||
|
||||
if (!$data['overtime']) {
|
||||
$data['overtime'] = 0;
|
||||
}
|
||||
|
||||
if ($r->birthday) {
|
||||
$data['birthday'] = strtotime($r->birthday);
|
||||
} else {
|
||||
$data['birthday'] = null;
|
||||
}
|
||||
if (!$data['user_id']) {
|
||||
$this->layout()->setFlash("Mitarbeiter darf nicht leer sein", "error");
|
||||
$this->redirect("TimerecordingEmployee");
|
||||
|
||||
@@ -6,8 +6,17 @@ class TimerecordingEmployeeModel
|
||||
private $type;
|
||||
private $auto_workinghours;
|
||||
private $holidays;
|
||||
private $holidays_now;
|
||||
private $holidays_timestamp;
|
||||
private $plushours;
|
||||
private $plushours_now;
|
||||
private $plushours_timestamp;
|
||||
private $overtime;
|
||||
private $overtime_now;
|
||||
private $overtime_timestamp;
|
||||
private $bpahours;
|
||||
private $startdate;
|
||||
private $birthday;
|
||||
|
||||
|
||||
public static function find($data)
|
||||
@@ -138,6 +147,9 @@ class TimerecordingEmployeeModel
|
||||
$where .= " AND user_id=$userid";
|
||||
}
|
||||
}
|
||||
if (array_key_exists("startdate", $filter)) {
|
||||
$where .= " AND startdate is not null";
|
||||
}
|
||||
|
||||
//var_dump($filter, $where);exit;
|
||||
return $where;
|
||||
|
||||
@@ -103,6 +103,8 @@ class TimerecordingEmployeeWorkingHourModel
|
||||
$secondcounter = 0;
|
||||
|
||||
while ($data = $db->fetch_array($res)) {
|
||||
$dayHours[$data['user_id']][$data['day']][] = $data['start'] . " - " . $data['end'];
|
||||
|
||||
if ($olduser != $data['user_id']) {
|
||||
if ($counter > 0) {
|
||||
$secondcounter = 0;
|
||||
@@ -121,7 +123,6 @@ class TimerecordingEmployeeWorkingHourModel
|
||||
if (!$datetimetext) {
|
||||
$datetimetext = $daysshort[$data['day']];
|
||||
}
|
||||
echo $oldstart . $data['start'];
|
||||
if (($oldstart != $data['start'] || $oldend != $data['end']) && $oldend) {
|
||||
$datetimetext .= " - " . $daysshort[$oldday] . " " . $oldstart . " - " . $oldend;
|
||||
$datetimetext .= "<br> " . $daysshort[$data['day']];
|
||||
@@ -139,6 +140,51 @@ class TimerecordingEmployeeWorkingHourModel
|
||||
$datetimetext = TimerecordingEmployeeWorkingHourModel::cleardays($datetimetext);
|
||||
$items[$olduser]['datetimetext'] = $datetimetext;
|
||||
}
|
||||
foreach ($dayHours as $key => $dayHour) {
|
||||
foreach ($dayHour as $key2 => $dayHour2) {
|
||||
$dayhours[$key][$key2] = implode("<br>", $dayHour2);
|
||||
}
|
||||
}
|
||||
foreach ($dayhours as $key => $dayhour) {
|
||||
$oldday = false;
|
||||
$oldstring = false;
|
||||
$counter = 0;
|
||||
$oldkey = false;
|
||||
$oldkey2 = false;
|
||||
foreach ($dayhour as $key2 => $dayhour2) {
|
||||
if ($oldday != $key2) {
|
||||
if ($oldstring != $dayhour2 || $key2!=$oldkey2+1) {
|
||||
if ($oldkey2) {
|
||||
$daysitems[$key][$counter]['end'] = $oldkey2;
|
||||
$counter++;
|
||||
}
|
||||
$daysitems[$key][$counter]['start'] = $key2;
|
||||
}
|
||||
|
||||
$daysitems[$key][$counter]['string'] = $dayhour2;
|
||||
}
|
||||
$oldkey2 = $key2;
|
||||
$oldkey = $key;
|
||||
$oldstring = $dayhour2;
|
||||
|
||||
}
|
||||
$daysitems[$key][$counter]['end'] = $key2;
|
||||
|
||||
}
|
||||
|
||||
foreach ($daysitems as $key => $daysitem) {
|
||||
$datetimetext = "";
|
||||
foreach ($daysitem as $key2 => $daysItem) {
|
||||
if ($daysItem['start'] != $daysItem['end']) {
|
||||
$datetimetext .= '<div class="d-table border-bottom border-dark"><div class="d-table-cell w-50 align-middle pr-2 ">' . $daysshort[$daysItem['start']] . "-" . $daysshort[$daysItem['end']] . '</div><div class="d-table-cell">' . $daysItem['string'] . '</div></div>';
|
||||
} else {
|
||||
$datetimetext .= '<div class="d-table border-bottom border-dark"><div class="d-table-cell w-50 align-middle pr-2 ">' . $daysshort[$daysItem['start']] . '</div><div class="d-table-cell">' . $daysItem['string'] . '</div></div>';
|
||||
}
|
||||
}
|
||||
$items[$key]['datetimetext'] = $datetimetext;
|
||||
}
|
||||
|
||||
|
||||
return $items;
|
||||
|
||||
}
|
||||
@@ -153,7 +199,6 @@ class TimerecordingEmployeeWorkingHourModel
|
||||
public static function getFirst()
|
||||
{
|
||||
$db = FronkDB::singleton();
|
||||
|
||||
$where = self::getSqlFilter($filter);
|
||||
$res = $db->select("TimerecordingEmployeeWorkingHour", "*", "$where ");
|
||||
if ($db->num_rows($res)) {
|
||||
|
||||
@@ -56,7 +56,7 @@ class TimerecordingPermitController extends mfBaseController
|
||||
$body .= 'Buchungsart: ' . $timerecordingCategoriess[0]->name . '
|
||||
';
|
||||
if ($timerecordingCategoriess[0]->hourday == "1") {
|
||||
$body .= 'von: ' . date("d.m.Y H:i", $timerecordings->start) . ' bis: ' . date("H:i", $timerecordings->end). '
|
||||
$body .= 'von: ' . date("d.m.Y H:i", $timerecordings->start) . ' bis: ' . date("H:i", $timerecordings->end) . '
|
||||
|
||||
';
|
||||
} else if ($timerecordingCategoriess[0]->hourday == "2") {
|
||||
@@ -69,9 +69,16 @@ class TimerecordingPermitController extends mfBaseController
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject('Antrag für ' . $timerecordingCategoriess[0]->name . ' ' . $sendtext);
|
||||
$email->setBody($body);
|
||||
$email->setFrom('zeiterfassung@xinon.at', 'Xinon Zeiterfassung');
|
||||
$email->setFrom(TT_TIMERECORDING_EMAIL, TT_TIMERECORDING_EMAIL_NAME);
|
||||
$email->setTo($user->email);
|
||||
$email->send();
|
||||
|
||||
$email = new Emailnotification();
|
||||
$email->setSubject('Antrag für ' . $timerecordingCategoriess[0]->name . ' ' . $sendtext . ' (' . $user->name . ')');
|
||||
$email->setBody($body);
|
||||
$email->setFrom(TT_TIMERECORDING_EMAIL, TT_TIMERECORDING_EMAIL_NAME);
|
||||
$email->setTo(TT_TIMERECORDING_EMAIL);
|
||||
$email->send();
|
||||
}
|
||||
|
||||
protected function approveAction()
|
||||
|
||||
@@ -11,7 +11,7 @@ class TimerecordingReportController extends mfBaseController
|
||||
$this->me = $me;
|
||||
$this->layout()->set("me", $me);
|
||||
|
||||
if (!$me->can(["Fibu"])) {
|
||||
if (!$me->is(["employee"])) {
|
||||
$this->redirect("Dashboard");
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,9 @@ class TimerecordingReportController extends mfBaseController
|
||||
case "getTimerecordings":
|
||||
$return = $this->getTimerecordingsApi($datatype, $dataweek, $datamonth, $datayear);
|
||||
break;
|
||||
case "getTimerecordingsTimes":
|
||||
$return = $this->getTimerecordingsTimes($datatype, $dataweek, $datamonth, $datayear);
|
||||
break;
|
||||
default:
|
||||
$return = false;
|
||||
}
|
||||
@@ -74,10 +77,10 @@ class TimerecordingReportController extends mfBaseController
|
||||
|
||||
$whstart = strtotime(date('Y-m-d', time()) . " " . $workinghour->start . ":00");
|
||||
$whend = strtotime(date('Y-m-d', time()) . " " . $workinghour->end . ":00");
|
||||
if (!$workingHours[$workinghour->day]) {
|
||||
$workingHours[$workinghour->day] = $whend - $whstart;
|
||||
if (!$workingHours[$workinghour->user_id][$workinghour->day]) {
|
||||
$workingHours[$workinghour->user_id][$workinghour->day] = $whend - $whstart;
|
||||
} else {
|
||||
$workingHours[$workinghour->day] = $workingHours[$workinghour->day] + $whend - $whstart;
|
||||
$workingHours[$workinghour->user_id][$workinghour->day] = $workingHours[$workinghour->user_id][$workinghour->day] + $whend - $whstart;
|
||||
}
|
||||
}
|
||||
foreach ($holidays as $holiday) {
|
||||
@@ -89,6 +92,7 @@ class TimerecordingReportController extends mfBaseController
|
||||
$year = date('Y', $dataweek);
|
||||
$timestamp_montag = strtotime("{$year}-W{$kw}");
|
||||
$timestamp_sonntag = strtotime("{$year}-W{$kw}-7");
|
||||
$firstdate = strtotime(date("Y-m-d", $timestamp_montag) . " 00:00:00");
|
||||
$lastdate = strtotime(date("Y-m-d", $timestamp_sonntag) . ' 23:59:59');
|
||||
$searchArray = ['start' => $timestamp_montag, 'end' => $lastdate];
|
||||
|
||||
@@ -99,7 +103,7 @@ class TimerecordingReportController extends mfBaseController
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate]) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
// $mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;
|
||||
@@ -116,7 +120,7 @@ class TimerecordingReportController extends mfBaseController
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate]) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
// $mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
@@ -128,6 +132,318 @@ class TimerecordingReportController extends mfBaseController
|
||||
$searchArray = ['start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate]) {
|
||||
//$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
$daysgerm = array("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa");
|
||||
$timerecordingcategories = TimerecordingCategoryModel::getAll();
|
||||
|
||||
$timerecordings = TimerecordingModel::search($searchArray);
|
||||
$responsecount = count($timerecordings);
|
||||
foreach ($timerecordings as $timerecording):
|
||||
$state = "";
|
||||
$enddate = "";
|
||||
$sum = "-";
|
||||
$day = "";
|
||||
$orderdate = $timerecording->start;
|
||||
if ($timerecording->timerecordingCategory->hourday == 1) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$start = date("H:i", $timerecording->start);
|
||||
$end = date("H:i", $timerecording->end);
|
||||
$seconds = $timerecording->end - $timerecording->start;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 2 || ($timerecording->timerecordingCategory->hourday == 3 && $timerecording->end)) {
|
||||
$date = date("d.m.", $timerecording->start) . " - " . $daysgerm[date("w", $timerecording->end)] . " " . date("d.m.Y", $timerecording->end);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$enddate = date("Y-m-d", $timerecording->end + 7200);
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
|
||||
if ($lastdate < $timerecording->end) {
|
||||
$endtimecalc = $lastdate;
|
||||
} else {
|
||||
$endtimecalc = $timerecording->end;
|
||||
}
|
||||
|
||||
if ($firstdate > $timerecording->start) {
|
||||
$starttimecalc = $firstdate;
|
||||
} else {
|
||||
$starttimecalc = $timerecording->start;
|
||||
}
|
||||
$summcounter = 0;
|
||||
$savecounter = 0;
|
||||
$sumdays = 0;
|
||||
// echo $starttimecalc."<br>";
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$holidaycounter = $workingHours[$timerecording->user_id][date("w", $i)];
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
if (!$holiDay[$daycheck]) {
|
||||
if ($holidaycounter) {
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;
|
||||
$sumdays++;
|
||||
}
|
||||
}
|
||||
if ($savecounter == 1000) {
|
||||
echo $savecounter;
|
||||
die();
|
||||
}
|
||||
$savecounter++;
|
||||
}
|
||||
$seconds = $summcounter;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
// $sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
if ($sumdays == 1 || $sumdays == 0) {
|
||||
$sum = $sumdays . " Tag";
|
||||
} else if ($sumdays > 1) {
|
||||
$sum = $sumdays . " Tage";
|
||||
}
|
||||
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 3 && !$timerecording->end) {
|
||||
$date = date("d.m.Y", $timerecording->start) . " - " . $daysgerm[date("w", time())] . " " . date("d.m.Y", time());;
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$enddatetemp = date("Y-m-d", time());
|
||||
$enddatetemp = strtotime($enddatetemp . " 23:59:59");
|
||||
$enddate = date("Y-m-d", $enddatetemp + 7200);
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
|
||||
if ($lastdate < time()) {
|
||||
$endtimecalc = $lastdate;
|
||||
} else {
|
||||
$endtimecalc = time();
|
||||
}
|
||||
$summcounter = 0;
|
||||
if ($firstdate > $timerecording->start) {
|
||||
$starttimecalc = $firstdate;
|
||||
} else {
|
||||
$starttimecalc = $timerecording->start;
|
||||
}
|
||||
$summcounter = 0;
|
||||
$savecounter = 0;
|
||||
// echo $starttimecalc."<br>";
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$holidaycounter = $workingHours[$timerecording->user_id][date("w", $i)];
|
||||
$daycheck = date("Y-m-d", $i);
|
||||
if (!$holiDay[$daycheck]) {
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;;
|
||||
}
|
||||
if ($savecounter == 1000) {
|
||||
echo $savecounter;
|
||||
die();
|
||||
}
|
||||
$savecounter++;
|
||||
}
|
||||
$seconds = $summcounter;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 5) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
if ($timerecording->days > 0) {
|
||||
if ($timerecording->days == 1) {
|
||||
$sum = "+" . $timerecording->days . " Tag";
|
||||
} else {
|
||||
$sum = "+" . $timerecording->days . " Tage";
|
||||
}
|
||||
} else {
|
||||
if ($timerecording->days == -1) {
|
||||
$sum = $timerecording->days . " Tag";
|
||||
} else {
|
||||
$sum = $timerecording->days . " Tage";
|
||||
}
|
||||
|
||||
}
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 6) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$start = date("H:i", $timerecording->start);
|
||||
$end = date("H:i", $timerecording->end);
|
||||
// $seconds = $timerecording->hours;
|
||||
$seconds = $timerecording->end - $timerecording->start;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = "-" . sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
}
|
||||
|
||||
if ($timerecording->timerecordingCategory->approval == 1 && $timerecording->approved == 0) {
|
||||
$state = '<i class="fa-regular fa-clock mr-1"></i>';
|
||||
} else if ($timerecording->timerecordingCategory->approval == 1 && $timerecording->approved == 1) {
|
||||
$state = '<i class="fa-regular fa-circle-check mr-1"></i>';
|
||||
}
|
||||
$edit = "";
|
||||
if ($timerecording->businesstrip == 1) {
|
||||
$category = "<span>" . $timerecording->timerecordingCategory->name . "</span><span class='text-bold ml-1'> (Dienstreise: " . $timerecording->businesstrip_info . ")</span>";
|
||||
} else if ($timerecording->homeoffice == 1) {
|
||||
$category = "<span>" . $timerecording->timerecordingCategory->name . "</span><span class='text-bold ml-1'> (Homeoffice)</span>";
|
||||
} else {
|
||||
$category = $timerecording->timerecordingCategory->name;
|
||||
}
|
||||
if ($timerecording->timerecordingCategory->hourday == 3 && !$timerecording->end) {
|
||||
$category = $category . " <span class='text-bold ml-1'>(Offen)</span>";
|
||||
}
|
||||
|
||||
|
||||
if ($timerecording->completed == 0):
|
||||
if ($timerecording->approved == 0) :
|
||||
$edit = '<i class="far fa-edit edit-button" data-id="' . $timerecording->id . '"
|
||||
data-date="' . $datadate . '"
|
||||
data-category="' . $timerecording->timerecordingCategory->id . '"
|
||||
data-start="' . $start . '"
|
||||
data-end="' . $end . '"
|
||||
data-enddate="' . $enddate . '"
|
||||
data-comment="' . $timerecording->comment . '"
|
||||
data-userid="' . $timerecording->user_id . '"
|
||||
data-businesstrip="' . $timerecording->businesstrip . '"
|
||||
data-businesstripinfo="' . $timerecording->businesstrip_info . '"
|
||||
data-homeoffice="' . $timerecording->homeoffice . '"
|
||||
data-days="' . $timerecording->days . '"
|
||||
title="Bearbeiten"></i>';
|
||||
else :
|
||||
$edit .= '<div class="edit-placeholder"></div>';
|
||||
endif;
|
||||
$edit .= '<i data-id="' . $timerecording->id . '" class="fas fa-trash text-danger delete-item" ></i>';
|
||||
endif;
|
||||
if ($datatype == 3 && $timerecording->timerecordingCategory->hourday == 1) {
|
||||
} else {
|
||||
$rows[] = array(
|
||||
'user' => array('user' => $timerecording->user->name, 'order' => $timerecording->user->name),
|
||||
'date' => array('date' => $state . $day . " " . $date, 'order' => $orderdate),
|
||||
'start' => array('start' => $start, 'order' => $start),
|
||||
'end' => array('end' => $end, 'order' => $end),
|
||||
'sum' => array('sum' => $sum, 'order' => $sum),
|
||||
'cstart' => array('cstart' => $datadate, 'order' => $datadate),
|
||||
'cend' => array('cend' => $enddate, 'order' => $enddate),
|
||||
'ccategory' => array('ccategory' => $timerecording->timerecordingCategory->name, 'order' => $timerecording->timerecordingCategory->name),
|
||||
'category' => array('category' => $category, 'order' => $timerecording->timerecordingCategory->name),
|
||||
'comment' => array('comment' => $timerecording->comment, 'order' => $timerecording->comment),
|
||||
'edit' => array('edit' => $edit, 'order' => $edit),
|
||||
'hourday' => array('hourday' => $timerecording->timerecordingCategory->hourday, 'order' => $timerecording->timerecordingCategory->hourday),
|
||||
|
||||
);
|
||||
}
|
||||
endforeach;
|
||||
$json['success'] = true;
|
||||
$json['time']['is'] = sprintf('%02dh:%02dm', floor($isSeconds / 3600), floor($isSeconds / 60 % 60));
|
||||
$json['time']['must'] = sprintf('%02dh:%02dm', floor($mustSeconds / 3600), floor($mustSeconds / 60 % 60));
|
||||
$json['time']['holidays'] = $holiDays;
|
||||
$json['time']['plushours'] = sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
$json['data'] = $rows;
|
||||
$json['recordsFiltered'] = $responsecount;
|
||||
$json['recordsTotal'] = $responsecount;
|
||||
$json = json_encode($json);
|
||||
echo trim($json);
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
protected function getTimerecordingsTimes($datatype, $dataweek, $datamonth, $datayear)
|
||||
{
|
||||
$r = $this->request;
|
||||
$mustSeconds = 0;
|
||||
$isSeconds = 0;
|
||||
$holiDays = 0;
|
||||
$plusHours = 0;
|
||||
|
||||
$rows = [];
|
||||
$employee = TimerecordingEmployeeModel::search(['user_id' => $r->user_id]);
|
||||
if ($employee) {
|
||||
$holiDays = $employee[0]->holidays;
|
||||
$plusHours = $employee[0]->plushours;
|
||||
$auto_workinghours = $employee[0]->auto_workinghours;
|
||||
$startdate = $employee[0]->startdate;
|
||||
}
|
||||
$workinghours = TimerecordingEmployeeWorkingHourModel::search(['user_id' => $r->user_id]);
|
||||
$holidays = TimerecordingHolidayModel::getAll();
|
||||
foreach ($workinghours as $workinghour) {
|
||||
|
||||
$whstart = strtotime(date('Y-m-d', time()) . " " . $workinghour->start . ":00");
|
||||
$whend = strtotime(date('Y-m-d', time()) . " " . $workinghour->end . ":00");
|
||||
if (!$workingHours[$workinghour->day]) {
|
||||
$workingHours[$workinghour->day] = $whend - $whstart;
|
||||
} else {
|
||||
$workingHours[$workinghour->day] = $workingHours[$workinghour->day] + $whend - $whstart;
|
||||
}
|
||||
}
|
||||
foreach ($holidays as $holiday) {
|
||||
$holiDay[date('Y-m-d', $holiday->timestamp)] = $holiday->timestamp;
|
||||
}
|
||||
|
||||
if ($datatype == 1) {
|
||||
$kw = date('W', $dataweek);
|
||||
$year = date('Y', $dataweek);
|
||||
$timestamp_montag = strtotime("{$year}-W{$kw}");
|
||||
$timestamp_sonntag = strtotime("{$year}-W{$kw}-7");
|
||||
$firstdate = strtotime(date("Y-m-d", $timestamp_montag) . " 00:00:00");
|
||||
$lastdate = strtotime(date("Y-m-d", $timestamp_sonntag) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $r->user_id, 'start' => $timestamp_montag, 'end' => $lastdate];
|
||||
|
||||
$daycounter = '0';
|
||||
|
||||
$timestamp = $timestamp_montag;
|
||||
for ($i = 1; $i <= 7; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
|
||||
if (!$holiDay[$dDate] && $dDate >= date('Y-m-d', $startdate)) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
} else if ($datatype == 2) {
|
||||
$firstdate = strtotime(date("Y-m-01", $datamonth));
|
||||
$lastdate = strtotime(date("Y-m-t", $datamonth));
|
||||
$daycount = date("t", $datamonth);
|
||||
$lastdate = strtotime(date("Y-m-d", $lastdate) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $r->user_id, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
if (!$holiDay[$dDate] && $dDate >= date('Y-m-d', $startdate)) {
|
||||
$mustSeconds = $mustSeconds + $workingHours[$dDay];
|
||||
}
|
||||
|
||||
$timestamp = $timestamp + 86400;
|
||||
}
|
||||
|
||||
|
||||
} else if ($datatype == 3) {
|
||||
$firstdate = strtotime(date("Y-01-01", $datayear));
|
||||
$lastdate = strtotime(date("Y-12-31 23:59:59", $datayear));
|
||||
$daycount = date("t", $datamonth);
|
||||
$lastdate = strtotime(date("Y-m-d", $lastdate) . ' 23:59:59');
|
||||
$searchArray = ['user_id' => $r->user_id, 'start' => $firstdate, 'end' => $lastdate];
|
||||
$timestamp = $firstdate;
|
||||
|
||||
for ($i = 1; $i <= $daycount; $i++) {
|
||||
$dDate = date('Y-m-d', $timestamp);
|
||||
$dDay = date('w', $timestamp);
|
||||
@@ -164,7 +480,7 @@ class TimerecordingReportController extends mfBaseController
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$isSeconds = $isSeconds + $seconds;
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 2) {
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 2 || ($timerecording->timerecordingCategory->hourday == 3 && $timerecording->end)) {
|
||||
$date = date("d.m.", $timerecording->start) . " - " . $daysgerm[date("w", $timerecording->end)] . " " . date("d.m.Y", $timerecording->end);
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$enddate = date("Y-m-d", $timerecording->end);
|
||||
@@ -177,23 +493,67 @@ class TimerecordingReportController extends mfBaseController
|
||||
} else {
|
||||
$endtimecalc = $timerecording->end;
|
||||
}
|
||||
if ($firstdate > $timerecording->start) {
|
||||
$starttimecalc = $firstdate;
|
||||
} else {
|
||||
$starttimecalc = $timerecording->start;
|
||||
}
|
||||
$summcounter = 0;
|
||||
for ($i = $timerecording->start; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$savecounter = 0;
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$holidaycounter = $workingHours[date("w", $i)];
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;
|
||||
if ($savecounter == 1000) {
|
||||
echo $savecounter;
|
||||
die();
|
||||
}
|
||||
$savecounter++;
|
||||
}
|
||||
$seconds = $summcounter;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 3 || $timerecording->timerecordingCategory->hourday == 4) {
|
||||
$date = date("d.m.Y", $timerecording->start);
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 3 && !$timerecording->end) {
|
||||
$date = date("d.m.Y", $timerecording->start) . " - " . $daysgerm[date("w", time())] . " " . date("d.m.Y", time());;
|
||||
$datadate = date("Y-m-d", $timerecording->start);
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
if ($lastdate < $timerecording->end) {
|
||||
$endtimecalc = $lastdate;
|
||||
} else {
|
||||
$endtimecalc = $timerecording->end;
|
||||
}
|
||||
if ($firstdate > $timerecording->start) {
|
||||
$starttimecalc = $firstdate;
|
||||
} else {
|
||||
$starttimecalc = $timerecording->start;
|
||||
}
|
||||
$summcounter = 0;
|
||||
$savecounter = 0;
|
||||
for ($i = $starttimecalc; $i <= $endtimecalc; $i = $i + 86400) {
|
||||
$holidaycounter = $workingHours[date("w", $i)];
|
||||
$isSeconds = $isSeconds + $holidaycounter;
|
||||
$summcounter = $summcounter + $holidaycounter;
|
||||
if ($savecounter == 1000) {
|
||||
echo $savecounter;
|
||||
die();
|
||||
}
|
||||
$savecounter++;
|
||||
}
|
||||
$seconds = $summcounter;
|
||||
$minutes = floor(($seconds % 3600) / 60);
|
||||
$hours = floor($seconds / 3600);
|
||||
$sum = sprintf("%02d", $hours) . ":" . sprintf("%02d", $minutes);
|
||||
|
||||
} else if ($timerecording->timerecordingCategory->hourday == 5) {
|
||||
|
||||
$start = "-";
|
||||
$end = "-";
|
||||
$day = $daysgerm[date("w", $timerecording->start)];
|
||||
$sum = $timerecording->days . " Tage";
|
||||
}
|
||||
|
||||
if ($timerecording->timerecordingCategory->approval == 1 && $timerecording->approved == 0) {
|
||||
@@ -202,6 +562,16 @@ class TimerecordingReportController extends mfBaseController
|
||||
$state = '<i class="fa-regular fa-circle-check mr-1"></i>';
|
||||
}
|
||||
$edit = "";
|
||||
if ($timerecording->businesstrip == 1) {
|
||||
$category = "<span>" . $timerecording->timerecordingCategory->name . "</span><span class='text-bold ml-2'> (Dienstreise: " . $timerecording->businesstrip_info . ")</span>";
|
||||
} else {
|
||||
$category = $timerecording->timerecordingCategory->name;
|
||||
}
|
||||
if ($timerecording->timerecordingCategory->hourday == 3 && !$timerecording->end) {
|
||||
$category = $category . "<span class='text-bold ml-2'>(offen)</span>";
|
||||
}
|
||||
|
||||
|
||||
if ($timerecording->completed == 0 && $timerecording->timerecordingCategory->only_admin == 0):
|
||||
if ($timerecording->approved == 0) :
|
||||
$edit = '<i class="far fa-edit edit-button" data-id="' . $timerecording->id . '"
|
||||
@@ -211,7 +581,8 @@ class TimerecordingReportController extends mfBaseController
|
||||
data-end="' . $end . '"
|
||||
data-enddate="' . $enddate . '"
|
||||
data-comment="' . $timerecording->comment . '"
|
||||
data-userid="' . $timerecording->user_id . '"
|
||||
data-businesstrip="' . $timerecording->businesstrip . '"
|
||||
data-businesstripinfo="' . $timerecording->businesstrip_info . '"
|
||||
title="Bearbeiten"></i>';
|
||||
else :
|
||||
$edit .= '<div class="edit-placeholder"></div>';
|
||||
@@ -220,24 +591,15 @@ class TimerecordingReportController extends mfBaseController
|
||||
endif;
|
||||
if ($datatype == 3 && $timerecording->timerecordingCategory->hourday == 1) {
|
||||
} else {
|
||||
$rows[] = array(
|
||||
'user' => array('user' => $timerecording->user->name, 'order' => $timerecording->user->name),
|
||||
'date' => array('date' => $state . $day . " " . $date, 'order' => $orderdate),
|
||||
'start' => array('start' => $start, 'order' => $start),
|
||||
'end' => array('end' => $end, 'order' => $end),
|
||||
'sum' => array('sum' => $sum, 'order' => $sum),
|
||||
'category' => array('category' => $timerecording->timerecordingCategory->name, 'order' => $timerecording->timerecordingCategory->name),
|
||||
'comment' => array('comment' => $timerecording->comment, 'order' => $timerecording->comment),
|
||||
'edit' => array('edit' => $edit, 'order' => $edit),
|
||||
);
|
||||
|
||||
}
|
||||
endforeach;
|
||||
$json['success'] = true;
|
||||
$json['time']['auto_workinghours'] = $auto_workinghours;
|
||||
$json['time']['is'] = sprintf('%02dh:%02dm', floor($isSeconds / 3600), floor($isSeconds / 60 % 60));
|
||||
$json['time']['must'] = sprintf('%02dh:%02dm', floor($mustSeconds / 3600), floor($mustSeconds / 60 % 60));
|
||||
$json['time']['holidays'] = $holiDays;
|
||||
$json['time']['plushours'] = sprintf('%02dh:%02dm', floor($plusHours / 3600), floor($plusHours / 60 % 60));
|
||||
$json['data'] = $rows;
|
||||
$json['recordsFiltered'] = $responsecount;
|
||||
$json['recordsTotal'] = $responsecount;
|
||||
$json = json_encode($json);
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class TimerecordingEmployeeAddFieldOvertime extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("TimerecordingEmployee", ["signed" => true]);
|
||||
$table->addColumn("overtime", "integer", ["null" => false, "default" => '0', "after" => "plushours_now"]);
|
||||
$table->addColumn("overtime_now", "integer", ["null" => false, "default" => '0', "after" => "plushours_now"]);
|
||||
$table->addColumn("overtime_timestamp", "integer", ["null" => true, "after" => "overtime_now"]);
|
||||
$table->addColumn("holidays_timestamp", "integer", ["null" => true, "after" => "holidays_now"]);
|
||||
$table->addColumn("plushours_timestamp", "integer", ["null" => true, "after" => "plushours_now"]);
|
||||
$table->addColumn("birthday", "integer", ["null" => true, "after" => "startdate"]);
|
||||
|
||||
|
||||
$table->addColumn("bpahours", "integer", ["null" => false, "default" => '0', "after" => "overtime"]);
|
||||
$table->changeColumn('holidays_now', 'integer', ["null" => false, "default" => '0']);
|
||||
$table->changeColumn('plushours_now', 'integer', ["null" => false, "default" => '0']);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$this->table("TimerecordingEmployee")->removeColumn("overtime")->save();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class TimerecordingAddFieldsHomeoffice extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("Timerecording", ["signed" => true]);
|
||||
$table->addColumn("homeoffice", "integer", ["null" => false, "default" => '0', "after" => "businesstrip_info"]);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$this->table("Timerecording")->removeColumn("homeoffice")->save();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class TimerecordingAddFieldsDays extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("Timerecording", ["signed" => true]);
|
||||
$table->addColumn("days", "integer", ["null" => false, "default" => '0', "after" => "end"]);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$this->table("Timerecording")->removeColumn("days")->save();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class TimerecordingAddFieldEnddate extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("TimerecordingEmployee", ["signed" => true]);
|
||||
$table->addColumn("enddate", "integer", ["null" => true,"default" => NULL, "after" => "startdate"]);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$this->table("TimerecordingEmployee")->removeColumn("enddate")->save();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class TimerecordingAddFieldHours extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if ($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("Timerecording", ["signed" => true]);
|
||||
$table->addColumn("hours", "integer", ["null" => true, "default" => NULL, "after" => "end"]);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if ($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if ($this->getEnvironment() == "thetool") {
|
||||
$this->table("Timerecording")->removeColumn("hours")->save();
|
||||
}
|
||||
|
||||
if ($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
31
db/migrations/20240310193146_device_add_field_autobackup.php
Normal file
31
db/migrations/20240310193146_device_add_field_autobackup.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class DeviceAddFieldAutobackup extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("Device", ["signed" => true]);
|
||||
$table->addColumn("autobackup", "integer", ["null" => false, "default" => '0', "after" => "last_config_backup"]);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if($this->getEnvironment() == "thetool") {
|
||||
$this->table("Device")->removeColumn("autobackup")->save();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
use Phinx\Migration\AbstractMigration;
|
||||
|
||||
final class TimerecordingAddFieldHoursOvertime extends AbstractMigration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
if ($this->getEnvironment() == "thetool") {
|
||||
$table = $this->table("Timerecording", ["signed" => true]);
|
||||
$table->addColumn("hours_overtime", "integer", ["null" => true, "default" => NULL, "after" => "hours"]);
|
||||
$table->update();
|
||||
}
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
if ($this->getEnvironment() == "thetool") {
|
||||
$this->table("Timerecording")->removeColumn("hours_overtime")->save();
|
||||
}
|
||||
|
||||
|
||||
if($this->getEnvironment() == "addressdb") {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ services:
|
||||
php:
|
||||
image: debian-php2
|
||||
ports:
|
||||
- 80:80
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./docker/apache2/000-default.conf:/etc/apache2/sites-available/000-default.conf
|
||||
- ./:/var/www/html
|
||||
@@ -18,14 +18,19 @@ services:
|
||||
- MYSQL_USER=luca
|
||||
- MYSQL_PASSWORD=junghan5
|
||||
volumes:
|
||||
- ./docker/mysql/data:/var/lib/mysql
|
||||
- ./docker/mysql/data:/var/lib/mysql
|
||||
- ./docker/mysql/conf.d:/etc/mysql/conf.d
|
||||
- ./docker/mysql/logs:/var/log/mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
|
||||
adminer:
|
||||
image: adminer
|
||||
ports:
|
||||
- 8080:8080
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- ./docker/adminer.php.ini:/etc/php/7.4/cli/conf.d/php.local.ini
|
||||
|
||||
|
||||
volumes:
|
||||
vendor:
|
||||
|
||||
34
docker/SqlCollationSwitcher/SqlCollationSwitcher.ps1
Normal file
34
docker/SqlCollationSwitcher/SqlCollationSwitcher.ps1
Normal file
@@ -0,0 +1,34 @@
|
||||
param(
|
||||
[string]$compressedFile
|
||||
)
|
||||
|
||||
# Load .NET assembly for file handling
|
||||
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||
|
||||
# Resolve absolute path of the compressed file
|
||||
$absoluteCompressedFile = Resolve-Path $compressedFile
|
||||
|
||||
# Generate file names
|
||||
$workingDir = Split-Path $absoluteCompressedFile
|
||||
$uncompressedFile = Join-Path $workingDir ($compressedFile -replace '^\.\\', '' -replace '\.sql\.gz$', '_uncompressed.sql')
|
||||
$modifiedFile = Join-Path $workingDir ($compressedFile -replace '^\.\\', '' -replace '\.sql\.gz$', '_modified.sql')
|
||||
$recompressedFile = Join-Path $workingDir ($compressedFile -replace '^\.\\', '' -replace '\.gz$', '_modified.sql.gz')
|
||||
|
||||
# Decompress .sql.gz file using .NET Framework
|
||||
[System.IO.Compression.ZipFile]::ExtractToDirectory($absoluteCompressedFile, $workingDir)
|
||||
|
||||
# Read content of uncompressed file
|
||||
$content = Get-Content -Path $uncompressedFile -Raw
|
||||
|
||||
# Replace text
|
||||
$content = $content -replace 'utf8mb4_0900_ai_ci', 'utf8mb4_general_ci'
|
||||
|
||||
# Write modified content to file
|
||||
Set-Content -Path $modifiedFile -Value $content -Encoding UTF8
|
||||
|
||||
# Compress .sql file back to .sql.gz using .NET Framework
|
||||
[System.IO.Compression.ZipFile]::CreateFromDirectory($workingDir, $recompressedFile)
|
||||
|
||||
# Cleanup: Optionally, you can remove the uncompressed and modified files if you don't need them anymore
|
||||
# Remove-Item $uncompressedFile
|
||||
# Remove-Item $modifiedFile
|
||||
21
docker/SqlCollationSwitcher/SqlCollationSwitcher2.ps1
Normal file
21
docker/SqlCollationSwitcher/SqlCollationSwitcher2.ps1
Normal file
@@ -0,0 +1,21 @@
|
||||
param(
|
||||
[string]$compressedFile
|
||||
)
|
||||
|
||||
# Generate file names
|
||||
$uncompressedFile = $compressedFile -replace '\.sql\.gz$', '_uncompressed.sql'
|
||||
$modifiedFile = $compressedFile -replace '\.sql\.gz$', '_modified.sql'
|
||||
$recompressedFile = $compressedFile -replace '\.gz$', '_modified.sql.gz'
|
||||
|
||||
# Decompress .sql.gz file using 7-Zip
|
||||
& "C:\Program Files\7-Zip\7z.exe" x -so $compressedFile | Set-Content -Path $uncompressedFile -Encoding UTF8
|
||||
|
||||
# Replace text using PowerShell
|
||||
(Get-Content $uncompressedFile) -replace "utf8mb4_0900_ai_ci", "utf8mb4_general_ci" | Set-Content $modifiedFile -Encoding UTF8
|
||||
|
||||
# Compress .sql file back to .sql.gz using 7-Zip
|
||||
& "C:\Program Files\7-Zip\7z.exe" a -tgzip $recompressedFile $modifiedFile
|
||||
|
||||
# Cleanup: Optionally, you can remove the uncompressed and modified files if you don't need them anymore
|
||||
#Remove-Item $uncompressedFile
|
||||
#Remove-Item $modifiedFile
|
||||
3
docker/adminer.php.ini
Normal file
3
docker/adminer.php.ini
Normal file
@@ -0,0 +1,3 @@
|
||||
post_max_size = 516M
|
||||
upload_max_filesize = 516M
|
||||
memory_limit = 2G
|
||||
9
docker/apache2/000-default.conf
Normal file
9
docker/apache2/000-default.conf
Normal file
@@ -0,0 +1,9 @@
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin webmaster@localhost
|
||||
DocumentRoot /var/www/html/public
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
<Directory /var/www/html>
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
@@ -44,7 +44,7 @@ $l['preorder.provision'] = "Vorsorgeanschluss";
|
||||
$l['preorder.order'] = "Vollanschluss";
|
||||
$l['preorder.reorder'] = "Nachbestellung";
|
||||
|
||||
$l['preorder.single-dwelling'] = "Einfahmilienhaus";
|
||||
$l['preorder.single-dwelling'] = "Einfamilienhaus";
|
||||
$l['preorder.multi-dwelling'] = "Mehrfamilienhaus";
|
||||
$l['preorder.apartment-building'] = "Mehrparteienhaus";
|
||||
$l['preorder.apartment'] = "Wohneinheit in Mehrparteienhaus";
|
||||
|
||||
@@ -2,309 +2,285 @@
|
||||
|
||||
class mfLayout {
|
||||
|
||||
private $log;
|
||||
private $tvars = array();
|
||||
private $template = "cli";
|
||||
private $package = "default";
|
||||
private $inline;
|
||||
private $returnValue;
|
||||
protected static $instance;
|
||||
private $log;
|
||||
private $tvars = array();
|
||||
private $template = "cli";
|
||||
private $package = "default";
|
||||
private $inline;
|
||||
private $returnValue;
|
||||
protected static $instance;
|
||||
|
||||
public function __construct() {
|
||||
$this->log = mfLoghandler::singleton();
|
||||
$this->inline = new stdClass();
|
||||
public function __construct() {
|
||||
$this->log = mfLoghandler::singleton();
|
||||
$this->inline = new stdClass();
|
||||
|
||||
if (!defined("LAYOUT_DEFAULTPACKAGE")) {
|
||||
$this->package = "default";
|
||||
} else {
|
||||
$this->package = LAYOUT_DEFAULTPACKAGE;
|
||||
}
|
||||
|
||||
if (method_exists($this, "init")) {
|
||||
$this->init();
|
||||
}
|
||||
}
|
||||
|
||||
public static function singleton($param = false) {
|
||||
if (!isset(self::$instance)) {
|
||||
$c = __CLASS__;
|
||||
self::$instance = new $c($param);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
public function set($name, $value) {
|
||||
$this->tvars[$name] = $value;
|
||||
}
|
||||
|
||||
public function get($name) {
|
||||
if(array_key_exists($name, $this->tvars)) {
|
||||
return $this->tvars[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setPackage($package) {
|
||||
$this->package = $package;
|
||||
}
|
||||
|
||||
public function setTemplate($template) {
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
private function setReturnValue($value) {
|
||||
$this->returnValue = $value;
|
||||
}
|
||||
|
||||
public function getReturnedValue() {
|
||||
return $this->returnValue;
|
||||
}
|
||||
|
||||
private function getTplPath() {
|
||||
return VIEWDIR . "/" . $this->package . "/" . $this->template . ".php";
|
||||
}
|
||||
|
||||
public function templatePathExists() {
|
||||
return file_exists($this->getTplPath());
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$this->defaultLayoutvariables();
|
||||
|
||||
$tpl_path = $this->getTplPath();
|
||||
if(!is_file($tpl_path)) {
|
||||
$tpl_path = VIEWDIR . "/default/" . $this->template . ".php";
|
||||
}
|
||||
|
||||
foreach ($this->tvars as $name => $value) {
|
||||
if ($name === "this")
|
||||
continue;
|
||||
$$name = $value;
|
||||
}
|
||||
|
||||
ob_end_clean();
|
||||
ob_start();
|
||||
include($tpl_path);
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public function display() {
|
||||
echo $this->render();
|
||||
}
|
||||
|
||||
public function renderPDF($filename = false, $extraPdfArgs = false) {
|
||||
$html = $this->render();
|
||||
|
||||
if (!$filename)
|
||||
$filename = date('U') . "-" . rand(1000, 9999) . ".pdf";
|
||||
|
||||
$wk = new mfWkhtmltopdf($html);
|
||||
|
||||
$pdfargs = "";
|
||||
if ($extraPdfArgs) {
|
||||
$pdfargs .= " $extraPdfArgs";
|
||||
}
|
||||
|
||||
$filename = $wk->generate($filename, $pdfargs);
|
||||
|
||||
if (!$filename) {
|
||||
throw new Exception("Error generating PDF document.");
|
||||
}
|
||||
|
||||
$file = PDFOUTPUTPATH . "/$filename";
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function displayPDF($filename = false, $extraPdfArgs = false) {
|
||||
$filepath = $this->renderPDF($filename, $extraPdfArgs);
|
||||
|
||||
if (!$filename && strpos($filepath, "/") !== false) {
|
||||
$path_parts = explode("/", $filepath);
|
||||
$filename = end($path_parts);
|
||||
}
|
||||
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-disposition: attachment; filename=' . $filename);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Content-Type: ' . mime_content_type($filepath));
|
||||
header("Content-Length: " . filesize($filepath));
|
||||
|
||||
readfile($filepath);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function setFlash($msg, $type = "info") {
|
||||
// info, warning, error
|
||||
if (!$msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($type == "error") {
|
||||
$_SESSION[MFAPPNAME . '_mfError'] = $msg;
|
||||
} elseif ($type == "warning" || $type == "warn") {
|
||||
$_SESSION[MFAPPNAME . '_mfWarning'] = $msg;
|
||||
} elseif ($type == "success") {
|
||||
$_SESSION[MFAPPNAME . '_mfSuccess'] = $msg;
|
||||
} else {
|
||||
$_SESSION[MFAPPNAME . '_mfInfo'] = $msg;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function defaultLayoutvariables() {
|
||||
$this->set('mfLayoutPackage', $this->package);
|
||||
|
||||
if (isset($_SESSION[MFAPPNAME . '_mfError'])) {
|
||||
$this->set("mfError", $_SESSION[MFAPPNAME . '_mfError']);
|
||||
$this->set("_flash_set", true);
|
||||
unset($_SESSION[MFAPPNAME . '_mfError']);
|
||||
}
|
||||
if (isset($_SESSION[MFAPPNAME . '_mfWarning'])) {
|
||||
$this->set("mfWarning", $_SESSION[MFAPPNAME . '_mfWarning']);
|
||||
$this->set("_flash_set", true);
|
||||
unset($_SESSION[MFAPPNAME . '_mfWarning']);
|
||||
}
|
||||
if (isset($_SESSION[MFAPPNAME . '_mfInfo'])) {
|
||||
$this->set("mfInfo", $_SESSION[MFAPPNAME . '_mfInfo']);
|
||||
$this->set("_flash_set", true);
|
||||
unset($_SESSION[MFAPPNAME . '_mfInfo']);
|
||||
}
|
||||
if (isset($_SESSION[MFAPPNAME . '_mfSuccess'])) {
|
||||
$this->set("mfSuccess", $_SESSION[MFAPPNAME . '_mfSuccess']);
|
||||
$this->set("_flash_set", true);
|
||||
unset($_SESSION[MFAPPNAME . '_mfSuccess']);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin inline functions
|
||||
*/
|
||||
|
||||
public static function strtrim($string, $chars) {
|
||||
if (strlen($string) <= $chars)
|
||||
return $string;
|
||||
return substr($string, 0, $chars) . "...";
|
||||
}
|
||||
|
||||
// produces url for generating links
|
||||
public static function getUrl($mod, $action = null, $param = null) {
|
||||
if (!$mod) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
if (MFUSEFANCYURLS) {
|
||||
// use fancy urls
|
||||
$url = MFFANCYBASEURL;
|
||||
if ($mod) {
|
||||
$url .= "/$mod";
|
||||
if ($action) {
|
||||
$url .= "/$action";
|
||||
if (!defined("LAYOUT_DEFAULTPACKAGE")) {
|
||||
$this->package = "default";
|
||||
} else {
|
||||
$this->package = LAYOUT_DEFAULTPACKAGE;
|
||||
}
|
||||
|
||||
if (method_exists($this, "init")) {
|
||||
$this->init();
|
||||
}
|
||||
}
|
||||
$url = preg_replace('#//#', '/', $url);
|
||||
} else {
|
||||
// no fancy urls
|
||||
$url = "?action=$mod";
|
||||
if ($action) {
|
||||
$url .= "_$action";
|
||||
}
|
||||
}
|
||||
if (is_array($param) && count($param)) {
|
||||
$url .= (MFUSEFANCYURLS) ? "/?" : "&";
|
||||
$param_qs = http_build_query($param);
|
||||
$url .= "$param_qs";
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public static function getResourcePath() {
|
||||
if (MFUSEFANCYURLS) {
|
||||
$path = MFFANCYBASEURL;
|
||||
if (substr($path, -1, 1) != "/") {
|
||||
$path .= "/";
|
||||
}
|
||||
} else {
|
||||
$path = "";
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function cycle() {
|
||||
$args = func_get_args();
|
||||
|
||||
if (is_array($this->inline->cycle) && count($this->inline->cycle)) {
|
||||
if (array_diff($this->inline->cycle, $args)) { // if different, start new cycle
|
||||
$this->inline->cycle = $args;
|
||||
$this->inline->cyclecount = 0;
|
||||
}
|
||||
} else {
|
||||
$this->inline->cycle = $args;
|
||||
$this->inline->cyclecount = 0;
|
||||
public static function singleton($param = false) {
|
||||
if (!isset(self::$instance)) {
|
||||
$c = __CLASS__;
|
||||
self::$instance = new $c($param);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
if ($this->inline->cyclecount >= count($this->inline->cycle)) {
|
||||
$this->inline->cyclecount = 0;
|
||||
public function set($name, $value) {
|
||||
$this->tvars[$name] = $value;
|
||||
}
|
||||
|
||||
return $this->inline->cycle[$this->inline->cyclecount++];
|
||||
}
|
||||
public function get($name) {
|
||||
if(array_key_exists($name, $this->tvars)) {
|
||||
return $this->tvars[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function setPackage($package) {
|
||||
$this->package = $package;
|
||||
}
|
||||
|
||||
public function setTemplate($template) {
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
private function setReturnValue($value) {
|
||||
$this->returnValue = $value;
|
||||
}
|
||||
|
||||
public function getReturnedValue() {
|
||||
return $this->returnValue;
|
||||
}
|
||||
|
||||
private function getTplPath() {
|
||||
return VIEWDIR . "/" . $this->package . "/" . $this->template . ".php";
|
||||
}
|
||||
|
||||
public function templatePathExists() {
|
||||
return file_exists($this->getTplPath());
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$this->defaultLayoutvariables();
|
||||
|
||||
$tpl_path = $this->getTplPath();
|
||||
if(!is_file($tpl_path)) {
|
||||
$tpl_path = VIEWDIR . "/default/" . $this->template . ".php";
|
||||
}
|
||||
|
||||
foreach ($this->tvars as $name => $value) {
|
||||
if ($name === "this")
|
||||
continue;
|
||||
$$name = $value;
|
||||
}
|
||||
|
||||
ob_end_clean();
|
||||
ob_start();
|
||||
include($tpl_path);
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
public function display() {
|
||||
echo $this->render();
|
||||
}
|
||||
|
||||
public function renderPDF($filename = false, $extraPdfArgs = false) {
|
||||
$html = $this->render();
|
||||
|
||||
if (!$filename)
|
||||
$filename = date('U') . "-" . rand(1000, 9999) . ".pdf";
|
||||
|
||||
$wk = new mfWkhtmltopdf($html);
|
||||
|
||||
$pdfargs = "";
|
||||
if ($extraPdfArgs) {
|
||||
$pdfargs .= " $extraPdfArgs";
|
||||
}
|
||||
|
||||
$filename = $wk->generate($filename, $pdfargs);
|
||||
|
||||
if (!$filename) {
|
||||
throw new Exception("Error generating PDF document.");
|
||||
}
|
||||
|
||||
$file = PDFOUTPUTPATH . "/$filename";
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
public function displayPDF($filename = false, $extraPdfArgs = false) {
|
||||
$filepath = $this->renderPDF($filename, $extraPdfArgs);
|
||||
|
||||
if (!$filename && strpos($filepath, "/") !== false) {
|
||||
$path_parts = explode("/", $filepath);
|
||||
$filename = end($path_parts);
|
||||
}
|
||||
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-disposition: attachment; filename=' . $filename);
|
||||
header('Content-Transfer-Encoding: binary');
|
||||
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||
header('Content-Type: ' . mime_content_type($filepath));
|
||||
header("Content-Length: " . filesize($filepath));
|
||||
|
||||
readfile($filepath);
|
||||
exit;
|
||||
}
|
||||
|
||||
public function setFlash($msg, $type = "info") {
|
||||
// info, warning, error
|
||||
if (!$msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$_SESSION[MFAPPNAME . '_mfNotify'] = array("type" => $type, "message" => $msg);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function defaultLayoutvariables() {
|
||||
$this->set('mfLayoutPackage', $this->package);
|
||||
|
||||
if (isset($_SESSION[MFAPPNAME . '_mfNotify'])) {
|
||||
$this->set("mfNotify", $_SESSION[MFAPPNAME . '_mfNotify']);
|
||||
unset($_SESSION[MFAPPNAME . '_mfNotify']);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Begin inline functions
|
||||
*/
|
||||
|
||||
public static function strtrim($string, $chars) {
|
||||
if (strlen($string) <= $chars)
|
||||
return $string;
|
||||
return substr($string, 0, $chars) . "...";
|
||||
}
|
||||
|
||||
// produces url for generating links
|
||||
public static function getUrl($mod, $action = null, $param = null) {
|
||||
if (!$mod) {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
if (MFUSEFANCYURLS) {
|
||||
// use fancy urls
|
||||
$url = MFFANCYBASEURL;
|
||||
if ($mod) {
|
||||
$url .= "/$mod";
|
||||
if ($action) {
|
||||
$url .= "/$action";
|
||||
}
|
||||
}
|
||||
$url = preg_replace('#//#', '/', $url);
|
||||
} else {
|
||||
// no fancy urls
|
||||
$url = "?action=$mod";
|
||||
if ($action) {
|
||||
$url .= "_$action";
|
||||
}
|
||||
}
|
||||
if (is_array($param) && count($param)) {
|
||||
$url .= (MFUSEFANCYURLS) ? "/?" : "&";
|
||||
$param_qs = http_build_query($param);
|
||||
$url .= "$param_qs";
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
public static function getResourcePath() {
|
||||
if (MFUSEFANCYURLS) {
|
||||
$path = MFFANCYBASEURL;
|
||||
if (substr($path, -1, 1) != "/") {
|
||||
$path .= "/";
|
||||
}
|
||||
} else {
|
||||
$path = "";
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
|
||||
public function cycle() {
|
||||
$args = func_get_args();
|
||||
|
||||
if (is_array($this->inline->cycle) && count($this->inline->cycle)) {
|
||||
if (array_diff($this->inline->cycle, $args)) { // if different, start new cycle
|
||||
$this->inline->cycle = $args;
|
||||
$this->inline->cyclecount = 0;
|
||||
}
|
||||
} else {
|
||||
$this->inline->cycle = $args;
|
||||
$this->inline->cyclecount = 0;
|
||||
}
|
||||
|
||||
if ($this->inline->cyclecount >= count($this->inline->cycle)) {
|
||||
$this->inline->cyclecount = 0;
|
||||
}
|
||||
|
||||
return $this->inline->cycle[$this->inline->cyclecount++];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function mfLayoutInclude($filename, $folder = "") {
|
||||
global $mfLayoutPackage;
|
||||
|
||||
if($folder) {
|
||||
$folder = $folder."/";
|
||||
}
|
||||
global $mfLayoutPackage;
|
||||
|
||||
$inc_path = VIEWDIR . "/" . LAYOUT_DEFAULTPACKAGE . "/" . $folder . $filename;
|
||||
if(!file_exists($inc_path)) {
|
||||
$inc_path = VIEWDIR . "/default/" . $folder . $filename;
|
||||
}
|
||||
if($folder) {
|
||||
$folder = $folder."/";
|
||||
}
|
||||
|
||||
include $inc_path;
|
||||
$inc_path = VIEWDIR . "/" . LAYOUT_DEFAULTPACKAGE . "/" . $folder . $filename;
|
||||
if(!file_exists($inc_path)) {
|
||||
$inc_path = VIEWDIR . "/default/" . $folder . $filename;
|
||||
}
|
||||
|
||||
include $inc_path;
|
||||
}
|
||||
|
||||
/*
|
||||
* global variable $lang to avoid loading it every time it's accessed
|
||||
*/
|
||||
if(!isset($lang)) {
|
||||
$lang = [];
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
$last_translation_failed = false;
|
||||
|
||||
function __($_string, $prefix = null) {
|
||||
global $lang;
|
||||
global $last_translation_failed;
|
||||
$last_translation_failed = false;
|
||||
|
||||
$string = str_replace(["Ä","Ö","Ü","ß","ä","ö","ü","ß"], ["ae","oe","ue","ss","ae","oe","ue", "ss"], strtolower($_string));
|
||||
|
||||
if(!$lang) {
|
||||
//mfLoghandler::singleton()->debug("Loading language file for __() function");
|
||||
include(BASEDIR . "/lang/de.php");
|
||||
}
|
||||
|
||||
if($prefix) {
|
||||
$string = "$prefix.$string";
|
||||
}
|
||||
|
||||
if (array_key_exists($string, $lang['de'])) {
|
||||
return $lang['de'][$string];
|
||||
}
|
||||
$last_translation_failed = true;
|
||||
return $string;
|
||||
global $lang;
|
||||
global $last_translation_failed;
|
||||
$last_translation_failed = false;
|
||||
|
||||
$string = str_replace(["Ä","Ö","Ü","ß","ä","ö","ü","ß"], ["ae","oe","ue","ss","ae","oe","ue", "ss"], strtolower($_string));
|
||||
|
||||
if(!$lang) {
|
||||
//mfLoghandler::singleton()->debug("Loading language file for __() function");
|
||||
include(BASEDIR . "/lang/de.php");
|
||||
}
|
||||
|
||||
if($prefix) {
|
||||
$string = "$prefix.$string";
|
||||
}
|
||||
|
||||
if (array_key_exists($string, $lang['de'])) {
|
||||
return $lang['de'][$string];
|
||||
}
|
||||
$last_translation_failed = true;
|
||||
return $string;
|
||||
}
|
||||
|
||||
function __last_translation_failed() {
|
||||
global $last_translation_failed;
|
||||
return $last_translation_failed;
|
||||
}
|
||||
global $last_translation_failed;
|
||||
return $last_translation_failed;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ table.dataTable > tbody > tr.child span.dtr-data {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.fa-circle-check {
|
||||
.fa-circle-check,.fa-circle-a {
|
||||
color: #23b900;
|
||||
font-size: 15px;
|
||||
}
|
||||
@@ -125,26 +125,39 @@ table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) {
|
||||
width: unset;
|
||||
display: table-cell;
|
||||
}
|
||||
.deny-button
|
||||
{
|
||||
|
||||
.deny-button {
|
||||
color: #f00;
|
||||
}
|
||||
|
||||
.edit-td {
|
||||
text-align: left;
|
||||
letter-spacing: 12px;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.display-calendar
|
||||
{
|
||||
color:#0d6efd;
|
||||
|
||||
.display-calendar {
|
||||
color: #0d6efd;
|
||||
font-size: 30px;
|
||||
margin-right:10px;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.active-calendar
|
||||
{
|
||||
color:#25b343;
|
||||
|
||||
.active-calendar {
|
||||
color: #25b343;
|
||||
}
|
||||
|
||||
.select2-minw {
|
||||
min-width: 150px;
|
||||
}
|
||||
|
||||
.no-user-select {
|
||||
-ms-user-select: None;
|
||||
-moz-user-select: None;
|
||||
-webkit-user-select: None;
|
||||
user-select: None;
|
||||
}
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.fa-circle-xmark, .fa-ban, .fa-trash, .fa-edit, .fa-square-check, .fa-arrows-up-down-left-right {
|
||||
font-size: 25px;
|
||||
@@ -212,17 +225,21 @@ table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) {
|
||||
font-size: 14px;
|
||||
margin: 12px 3px 7px 0px;
|
||||
}
|
||||
.display-calendar
|
||||
{
|
||||
font-size:35px;
|
||||
margin-top:5px;
|
||||
margin-right:10px;
|
||||
margin-bottom:20px;
|
||||
|
||||
.display-calendar {
|
||||
font-size: 35px;
|
||||
margin-top: 5px;
|
||||
margin-right: 10px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
}
|
||||
.label-calendar
|
||||
{
|
||||
margin-top:7px;
|
||||
|
||||
.label-calendar {
|
||||
margin-top: 7px;
|
||||
}
|
||||
|
||||
.select2-minw {
|
||||
min-width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -270,10 +287,11 @@ table.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before
|
||||
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
|
||||
transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out, -webkit-box-shadow .15s ease-in-out;
|
||||
}
|
||||
table.dataTable.table-hover>tbody>tr:hover>* {
|
||||
|
||||
table.dataTable.table-hover > tbody > tr:hover > * {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table.dataTable.table-striped>tbody>tr:nth-of-type(2n+1)>* {
|
||||
box-shadow: none;
|
||||
table.dataTable.table-striped > tbody > tr:nth-of-type(2n+1) > * {
|
||||
box-shadow: none;
|
||||
}
|
||||
6
public/assets/js/calendar/index.global.min.js
vendored
Normal file
6
public/assets/js/calendar/index.global.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
public/assets/js/calendar/locales-all.global.min.js
vendored
Normal file
6
public/assets/js/calendar/locales-all.global.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
6
public/assets/js/calendar/moment/index.global.min.js
vendored
Normal file
6
public/assets/js/calendar/moment/index.global.min.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
/*!
|
||||
FullCalendar Moment Plugin v6.1.10
|
||||
Docs & License: https://fullcalendar.io/docs/moment-plugin
|
||||
(c) 2023 Adam Shaw
|
||||
*/
|
||||
FullCalendar.Moment=function(e,t,l,n){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}var r=a(l);function u(e,t,l,n){let a;return"local"===t?a=r.default(e):"UTC"===t?a=r.default.utc(e):r.default.tz?a=r.default.tz(e,t):(a=r.default.utc(e),null!=l&&a.utcOffset(l)),a.locale(n),a}function o(e){return t=>t?e.format(t):""}var d=t.createPlugin({name:"@fullcalendar/moment",cmdFormatter:function(e,t){let l=function e(t){let l=t.match(/^(.*?)\{(.*)\}(.*)$/);if(l){let t=e(l[2]);return{head:l[1],middle:t,tail:l[3],whole:l[1]+t.whole+l[3]}}return{head:null,middle:null,tail:null,whole:t}}(e);if(t.end){let e=u(t.start.array,t.timeZone,t.start.timeZoneOffset,t.localeCodes[0]),n=u(t.end.array,t.timeZone,t.end.timeZoneOffset,t.localeCodes[0]);return function e(t,l,n,a){if(t.middle){let r=l(t.head),u=e(t.middle,l,n,a),o=l(t.tail),d=n(t.head),i=e(t.middle,l,n,a),f=n(t.tail);if(r===d&&o===f)return r+(u===i?u:u+a+i)+o}let r=l(t.whole),u=n(t.whole);if(r===u)return r;return r+a+u}(l,o(e),o(n),t.defaultSeparator)}return u(t.date.array,t.timeZone,t.date.timeZoneOffset,t.localeCodes[0]).format(l.whole)}});return t.globalPlugins.push(d),e.default=d,e.toMoment=function(e,t){if(!(t instanceof n.CalendarImpl))throw new Error("must supply a CalendarApi instance");let{dateEnv:l}=t.getCurrentData();return u(e,l.timeZone,null,l.locale.codes[0])},e.toMomentDuration=function(e){return r.default.duration(e)},Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,moment,FullCalendar.Internal);
|
||||
2
public/assets/js/calendar/moment/moment.min.js
vendored
Normal file
2
public/assets/js/calendar/moment/moment.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
public/assets/js/calendar/tooltip.min.js
vendored
Normal file
5
public/assets/js/calendar/tooltip.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -69,7 +69,7 @@ table = $('#datatable').DataTable({
|
||||
"dom": cstmdom,
|
||||
"ajax": {
|
||||
"url": requestUrl,
|
||||
"type": "GET",
|
||||
"type": "POST",
|
||||
"data": function (d) {
|
||||
$('.display-calendar').each(function (index) {
|
||||
if ($(this).hasClass('active-calendar')) {
|
||||
@@ -86,6 +86,14 @@ table = $('#datatable').DataTable({
|
||||
$('#must-time').text(json.time.must);
|
||||
$('#holidays').text(json.time.holidays);
|
||||
$('#plushours').text(json.time.plushours);
|
||||
if ($("#plushours").text().includes("-")) {
|
||||
$('#plushours-label').css('background-color', '#fda7a7');
|
||||
} else {
|
||||
$('#plushours-label').css('background-color', '#d0fbd9');
|
||||
}
|
||||
if (json.time.auto_workinghours == "1") {
|
||||
$('#auto-workinghours-button').show();
|
||||
}
|
||||
return json.data;
|
||||
}
|
||||
|
||||
@@ -127,7 +135,7 @@ table = $('#datatable').DataTable({
|
||||
_: "comment.comment",
|
||||
"sort": "comment.order"
|
||||
},
|
||||
className: "text-center"
|
||||
className: "text-left"
|
||||
}, {
|
||||
"data": {
|
||||
_: "edit.edit",
|
||||
@@ -182,8 +190,14 @@ $(document).ready(function () {
|
||||
$(this).prop("required", true);
|
||||
$(this).prop("min", $('#date').val());
|
||||
$(this).val($('#date').val());
|
||||
})
|
||||
} else if (parseInt($(this).find(':selected').data('hourday')) === 1) {
|
||||
});
|
||||
$("#div-calc-overtime").hide();
|
||||
} else if (parseInt($(this).find(':selected').data('hourday')) === 1 || parseInt($(this).find(':selected').data('hourday')) === 6) {
|
||||
if (parseInt($(this).find(':selected').data('hourday')) === 6) {
|
||||
$("#div-calc-overtime").show();
|
||||
} else {
|
||||
$("#div-calc-overtime").hide();
|
||||
}
|
||||
$("#endtime-div").show();
|
||||
$("#endtime-div").find('input').each(function () {
|
||||
$(this).prop("required", true);
|
||||
@@ -202,6 +216,7 @@ $(document).ready(function () {
|
||||
$(this).prop("disabled", true);
|
||||
|
||||
});
|
||||
$("#div-calc-overtime").hide();
|
||||
$("#enddate-div").hide();
|
||||
$("#enddate-div").find('input').each(function () {
|
||||
$(this).prop("required", false);
|
||||
@@ -214,6 +229,26 @@ $(document).ready(function () {
|
||||
} else {
|
||||
$('#comment').prop("required", false);
|
||||
}
|
||||
|
||||
if (parseInt($(this).find(':selected').data('businesstrip')) === 1) {
|
||||
$('.businesstrip-div').show();
|
||||
$('#businesstrip').prop("checked", false);
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').hide();
|
||||
} else {
|
||||
$('.businesstrip-div').hide();
|
||||
$('#businesstrip').prop("checked", false);
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').hide();
|
||||
}
|
||||
|
||||
if (parseInt($(this).find(':selected').data('homeoffice')) === 1) {
|
||||
$('#homeoffice-div').show();
|
||||
$('#homeoffice').prop("checked", false);
|
||||
} else {
|
||||
$('#homeoffice').prop("checked", false);
|
||||
$('#homeoffice-div').hide();
|
||||
}
|
||||
});
|
||||
$("body").on("change", "#date", function () {
|
||||
if ($('#enddate-div').css('display') === "block") {
|
||||
@@ -233,6 +268,25 @@ $(document).ready(function () {
|
||||
$('#end').prop("min", $('#start').val());
|
||||
});
|
||||
|
||||
$("body").on("change", "#start,#end,#date,#timerecordingCategory_id", function () {
|
||||
if (parseInt($('#timerecordingCategory_id').find(':selected').data('hourday')) === 6) {
|
||||
$.post(checkWorkinghoursUrl, {
|
||||
date: $.trim($('#date').val()),
|
||||
start: $.trim($('#start').val()),
|
||||
end: $.trim($('#end').val()),
|
||||
ajax: 1
|
||||
}).done(function (data) {
|
||||
var result = $.parseJSON(data);
|
||||
if (result.state === "success") {
|
||||
$('#calc-overtime').html(result.message);
|
||||
}
|
||||
if (result.state === "error") {
|
||||
$('#calc-overtime').html('<div class="text-danger text-bold">' + result.error + '</div>');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", ".edit-button", function () {
|
||||
$('#submit-button').hide().removeClass('btn-primary').addClass('btn-danger').show();
|
||||
$('#submit-button').text('Ändern');
|
||||
@@ -242,8 +296,22 @@ $(document).ready(function () {
|
||||
$('#date').val($(this).data('date'));
|
||||
$('#start').val($(this).data('start'));
|
||||
$('#end').val($(this).data('end'));
|
||||
$('#end').prop("min", $('#start').val());
|
||||
$('#enddate').val($(this).data('enddate'));
|
||||
$('#enddate').prop("min", $('#date').val());
|
||||
$('#comment').val($(this).data('comment'));
|
||||
if ($(this).data('businesstrip') == 1) {
|
||||
$('#businesstrip').prop("checked", true);
|
||||
$('#businesstrip_info').val($(this).data('businesstripinfo'));
|
||||
$('#businesstrip_info').show();
|
||||
$('#businesstrip_info').prop('required', true);
|
||||
$('#homeoffice-div').hide();
|
||||
}
|
||||
if ($(this).data('homeoffice') == 1) {
|
||||
$('.businesstrip-div').hide();
|
||||
$('#homeoffice').prop("checked", true);
|
||||
$('#homeoffice-div').show();
|
||||
}
|
||||
$('.alert-success').remove();
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
@@ -252,6 +320,12 @@ $(document).ready(function () {
|
||||
$('#submit-button').text('Speichern');
|
||||
$('#cancel-button').hide();
|
||||
$('#id').val('');
|
||||
$('.businesstrip-div').hide();
|
||||
$('#businesstrip').prop("checked", false);
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').hide();
|
||||
$('#homeoffice').prop("checked", false);
|
||||
$('#timerecordingCategory_id').change();
|
||||
});
|
||||
|
||||
$("body").on("change", "#dataweek,#datamonth,#datayear", function () {
|
||||
@@ -286,11 +360,56 @@ $(document).ready(function () {
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#businesstrip_info').show();
|
||||
$('#businesstrip_info').prop('required', true);
|
||||
$('#homeoffice').prop('checked', false);
|
||||
$('#homeoffice-div').hide();
|
||||
|
||||
} else {
|
||||
$('#businesstrip_info').hide();
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').prop('required', false);
|
||||
$('#timerecordingCategory_id').change();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
$("body").on("click", "#homeoffice", function () {
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#businesstrip').prop('checked', false);
|
||||
$('.businesstrip-div').hide();
|
||||
$('#businesstrip_info').hide();
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').prop('required', false);
|
||||
|
||||
} else {
|
||||
$('#timerecordingCategory_id').change();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$("body").on("click", "#auto-workinghours-button", function () {
|
||||
var timestamp = $('#dataweek').val() * 1000
|
||||
const date = new Date(timestamp);
|
||||
var day = date.getDay(),
|
||||
diff = date.getDate() - day + (day == 0 ? -6 : 1);
|
||||
diff = date.getDate() - day + (day == 0 ? -6 : 1);
|
||||
var monday = new Date(date.setDate(diff));
|
||||
monday = monday.getTime();
|
||||
monday = new Date(monday);
|
||||
monday = monday.toLocaleDateString('de-DE');
|
||||
//last day of week
|
||||
var sunday = new Date(date.setDate(diff + 6));
|
||||
sunday = sunday.getTime();
|
||||
sunday = new Date(sunday);
|
||||
sunday = sunday.toLocaleDateString('de-DE');
|
||||
|
||||
if (confirm('Sollen die Arbeitszeiten von ' + monday + ' bis ' + sunday + ' automatisch eingetragen werden?')) {
|
||||
$.post(autoWorkinghoursUrl, {
|
||||
dataweek: $.trim($('#dataweek').val()),
|
||||
ajax: 1
|
||||
}).done(function (data) {
|
||||
table.ajax.reload();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -309,6 +428,14 @@ $(document).ready(function () {
|
||||
$('form').submit(function (e) {
|
||||
e.preventDefault();
|
||||
$('#alert-box').remove();
|
||||
var businesstrip = false;
|
||||
var homeoffice = false;
|
||||
if ($('#businesstrip').prop('checked') == true) {
|
||||
businesstrip = 1;
|
||||
}
|
||||
if ($('#homeoffice').prop('checked') == true) {
|
||||
homeoffice = 1;
|
||||
}
|
||||
$.post(insertUrl, {
|
||||
id: $.trim($('#id').val()),
|
||||
timerecordingCategory_id: $.trim($('#timerecordingCategory_id').val()),
|
||||
@@ -317,6 +444,10 @@ $(document).ready(function () {
|
||||
start: $.trim($('#start').val()),
|
||||
end: $.trim($('#end').val()),
|
||||
comment: $.trim($('#comment').val()),
|
||||
businesstrip: businesstrip,
|
||||
businesstrip_info: $.trim($('#businesstrip_info').val()),
|
||||
homeoffice: homeoffice,
|
||||
hourday: $.trim($('#timerecordingCategory_id').find(':selected').data('hourday')),
|
||||
ajax: 1
|
||||
}).done(function (data) {
|
||||
var result = $.parseJSON(data);
|
||||
@@ -328,6 +459,10 @@ $(document).ready(function () {
|
||||
<h5><i class="icon fas fa-check"></i> Erfolgreich</h5>
|
||||
` + result.message + `</div>
|
||||
</div>`);
|
||||
$('#businesstrip').prop('checked', false);
|
||||
$('#businesstrip_info').hide();
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').prop('required', false);
|
||||
}
|
||||
if (result.state === "error") {
|
||||
$('.wrapper .container-fluid').prepend(`<div id="alert-box" class="row">
|
||||
@@ -345,5 +480,6 @@ $(document).ready(function () {
|
||||
table.ajax.reload();
|
||||
});
|
||||
});
|
||||
$('#timerecordingCategory_id').change();
|
||||
})
|
||||
;
|
||||
@@ -29,8 +29,13 @@ $('#filterrow th').each(function (i) {
|
||||
|
||||
if (hidesearch.includes($(this).index())) {
|
||||
|
||||
} else if (columnfilter.includes($(this).index())) {
|
||||
$(this).html('<select style="padding: 0;height: 28px;;text-align: center;" id="selectsearch" class="form-control form-control-select form-control-special" data-index="' + i + '">' + columnoptions + '</select>');
|
||||
} else if ($(this).index() == 0) {
|
||||
var options = '<option value="">Alle</option>';
|
||||
$('#user_id_select').find('option').each(function () {
|
||||
options += '<option data-userid="' + $(this).val() + '" value="' + $(this).text() + '">' + $(this).text() + '</option>';
|
||||
});
|
||||
|
||||
$(this).html('<select id="selectsearch" class="form-control form-control-select form-control-special select2 select2-minw" data-index="' + i + '">' + options + '</select>');
|
||||
|
||||
} else {
|
||||
$(this).html('<input type="text" placeholder="' + title + '" class="form-control" data-index="' + i + '" value="" />');
|
||||
@@ -61,7 +66,7 @@ table = $('#datatable').DataTable({
|
||||
$('#datatable_filter').append('<i id="clear_cookie" class="fas fa-times clear-fa" title="Filter löschen" aria-hidden="true" ></i>');
|
||||
$('#clear_cookie').click(function () {
|
||||
$('#filterrow input').val('');
|
||||
$('#filterrow select').val('');
|
||||
$('#filterrow select').val('').change();
|
||||
table.search('').columns().search('').draw();
|
||||
});
|
||||
},
|
||||
@@ -85,6 +90,7 @@ table = $('#datatable').DataTable({
|
||||
$('#must-time').text(json.time.must);
|
||||
$('#holidays').text(json.time.holidays);
|
||||
$('#plushours').text(json.time.plushours);
|
||||
$('#selectsearch').change();
|
||||
return json.data;
|
||||
}
|
||||
|
||||
@@ -133,7 +139,7 @@ table = $('#datatable').DataTable({
|
||||
_: "comment.comment",
|
||||
"sort": "comment.order"
|
||||
},
|
||||
className: "text-center"
|
||||
className: "text-left"
|
||||
}, {
|
||||
"data": {
|
||||
_: "edit.edit",
|
||||
@@ -177,6 +183,7 @@ if (state) {
|
||||
$(document).ready(function () {
|
||||
$(".select2").select2();
|
||||
|
||||
|
||||
$("body").on("change", "#timerecordingCategory_id", function () {
|
||||
if (parseInt($(this).find(':selected').data('hourday')) === 2) {
|
||||
$("#endtime-div").hide();
|
||||
@@ -188,8 +195,16 @@ $(document).ready(function () {
|
||||
$(this).prop("required", true);
|
||||
$(this).prop("min", $('#date').val());
|
||||
$(this).val($('#date').val());
|
||||
})
|
||||
} else if (parseInt($(this).find(':selected').data('hourday')) === 1) {
|
||||
});
|
||||
$('#days-div').hide();
|
||||
$('#days').prop("required", false);
|
||||
$("#div-calc-overtime").hide();
|
||||
} else if (parseInt($(this).find(':selected').data('hourday')) === 1 || parseInt($(this).find(':selected').data('hourday')) === 6) {
|
||||
if (parseInt($(this).find(':selected').data('hourday')) === 6) {
|
||||
$("#div-calc-overtime").show();
|
||||
} else {
|
||||
$("#div-calc-overtime").hide();
|
||||
}
|
||||
$("#endtime-div").show();
|
||||
$("#endtime-div").find('input').each(function () {
|
||||
$(this).prop("required", true);
|
||||
@@ -200,26 +215,67 @@ $(document).ready(function () {
|
||||
$(this).prop("required", false);
|
||||
$(this).prop("min", '');
|
||||
$(this).val('');
|
||||
})
|
||||
});
|
||||
$('#days-div').hide();
|
||||
$('#days').prop("required", false);
|
||||
} else if (parseInt($(this).find(':selected').data('hourday')) === 3 || parseInt($(this).find(':selected').data('hourday')) === 4) {
|
||||
$("#endtime-div").hide();
|
||||
$("#endtime-div").find('input').each(function () {
|
||||
$(this).prop("required", false);
|
||||
$(this).prop("disabled", true);
|
||||
|
||||
});
|
||||
$("#div-calc-overtime").hide();
|
||||
$("#enddate-div").hide();
|
||||
$("#enddate-div").find('input').each(function () {
|
||||
$(this).prop("required", false);
|
||||
$(this).prop("min", '');
|
||||
$(this).val('');
|
||||
});
|
||||
$('#days-div').hide();
|
||||
$('#days').prop("required", false);
|
||||
} else if (parseInt($(this).find(':selected').data('hourday')) === 5) {
|
||||
$("#endtime-div").hide();
|
||||
$("#endtime-div").find('input').each(function () {
|
||||
$(this).prop("required", false);
|
||||
$(this).prop("disabled", true);
|
||||
|
||||
});
|
||||
$("#enddate-div").hide();
|
||||
$("#enddate-div").find('input').each(function () {
|
||||
$(this).prop("required", false);
|
||||
$(this).prop("min", '');
|
||||
$(this).val('');
|
||||
})
|
||||
});
|
||||
$('#days-div').show();
|
||||
$('#days').prop("required", true);
|
||||
|
||||
}
|
||||
if (parseInt($(this).find(':selected').data('comment')) === 1) {
|
||||
$('#comment').prop("required", true);
|
||||
} else {
|
||||
$('#comment').prop("required", false);
|
||||
}
|
||||
|
||||
if (parseInt($(this).find(':selected').data('businesstrip')) === 1) {
|
||||
$('.businesstrip-div').show();
|
||||
$('#businesstrip').prop("checked", false);
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').hide();
|
||||
} else {
|
||||
$('.businesstrip-div').hide();
|
||||
$('#businesstrip').prop("checked", false);
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').hide();
|
||||
}
|
||||
|
||||
if (parseInt($(this).find(':selected').data('homeoffice')) === 1) {
|
||||
$('#homeoffice-div').show();
|
||||
$('#homeoffice').prop("checked", false);
|
||||
} else {
|
||||
$('#homeoffice').prop("checked", false);
|
||||
$('#homeoffice-div').hide();
|
||||
}
|
||||
});
|
||||
$("body").on("change", "#date", function () {
|
||||
if ($('#enddate-div').css('display') === "block") {
|
||||
@@ -238,6 +294,27 @@ $(document).ready(function () {
|
||||
}
|
||||
$('#end').prop("min", $('#start').val());
|
||||
});
|
||||
$("body").on("change", "#start,#end,#date,#timerecordingCategory_id,#user_id_select", function () {
|
||||
if (parseInt($('#timerecordingCategory_id').find(':selected').data('hourday')) === 6) {
|
||||
var userid;
|
||||
userid = $('#user_id_select').val();
|
||||
$.post(checkWorkinghoursUrl, {
|
||||
user_id: userid,
|
||||
date: $.trim($('#date').val()),
|
||||
start: $.trim($('#start').val()),
|
||||
end: $.trim($('#end').val()),
|
||||
ajax: 1
|
||||
}).done(function (data) {
|
||||
var result = $.parseJSON(data);
|
||||
if (result.state === "success") {
|
||||
$('#calc-overtime').html(result.message);
|
||||
}
|
||||
if (result.state === "error") {
|
||||
$('#calc-overtime').html('<div class="text-danger text-bold">' + result.error + '</div>');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$("body").on("click", ".edit-button", function () {
|
||||
$('#submit-button').hide().removeClass('btn-primary').addClass('btn-danger').show();
|
||||
@@ -254,24 +331,74 @@ $(document).ready(function () {
|
||||
$('#date').val($(this).data('date'));
|
||||
$('#start').val($(this).data('start'));
|
||||
$('#end').val($(this).data('end'));
|
||||
$('#end').prop("min", $('#start').val());
|
||||
$('#days').val($(this).data('days'));
|
||||
$('#enddate').val($(this).data('enddate'));
|
||||
$('#enddate').prop("min", $('#date').val());
|
||||
$('#comment').val($(this).data('comment'));
|
||||
if ($(this).data('businesstrip') == 1) {
|
||||
$('#businesstrip').prop("checked", true);
|
||||
$('#businesstrip_info').val($(this).data('businesstripinfo'));
|
||||
$('#businesstrip_info').show();
|
||||
$('#businesstrip_info').prop('required', true);
|
||||
$('#homeoffice-div').hide();
|
||||
}
|
||||
if ($(this).data('homeoffice') == 1) {
|
||||
$('.businesstrip-div').hide();
|
||||
$('#homeoffice').prop("checked", true);
|
||||
$('#homeoffice-div').show();
|
||||
}
|
||||
$('.alert-success').remove();
|
||||
window.scrollTo(0, 0);
|
||||
});
|
||||
$("body").on("click", "#cancel-button", function () {
|
||||
$('#submit-button').hide().removeClass('btn-danger').addClass('btn-primary').show();
|
||||
$('#submit-button').text('Speichern');
|
||||
$('#cancel-button').hide();
|
||||
$('#user_id_select').prop('disabled', false);
|
||||
$('#user_id_input').prop('disabled', true);
|
||||
$('#user_id_select').change();
|
||||
$('#timerecordingCategory_id').val($(this).data('category')).change();
|
||||
$('#timerecordingCategory_id').change();
|
||||
$('#id').val('');
|
||||
$('.businesstrip-div').hide();
|
||||
$('#businesstrip').prop("checked", false);
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').hide();
|
||||
$('#homeoffice').prop("checked", false);
|
||||
$('#timerecordingCategory_id').change();
|
||||
});
|
||||
|
||||
$("body").on("change", "#dataweek,#datamonth,#datayear", function () {
|
||||
table.ajax.reload(null, false);
|
||||
});
|
||||
|
||||
$("body").on("change", "#selectsearch", function () {
|
||||
var datatype;
|
||||
if (!$(this).val()) {
|
||||
$('#must-time').text('N/A');
|
||||
$('#is-time').text('N/A');
|
||||
} else {
|
||||
$('.display-calendar').each(function (index) {
|
||||
if ($(this).hasClass('active-calendar')) {
|
||||
datatype = $(this).data('datatype');
|
||||
}
|
||||
});
|
||||
if (datatype == 1 || datatype == 2) {
|
||||
$.post(requestTimesUrl, {
|
||||
id: $.trim($(this).data('id')),
|
||||
datatype: datatype,
|
||||
user_id: $(this).find(':selected').data('userid'),
|
||||
dataweek: $('#dataweek').val(),
|
||||
datamonth: $('#datamonth').val(),
|
||||
ajax: 1
|
||||
}).done(function (data) {
|
||||
var json = $.parseJSON(data);
|
||||
$('#must-time').text(json.time.must);
|
||||
$('#is-time').text(json.time.is);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
$("body").on("click", ".display-calendar", function () {
|
||||
$('.display-calendar').each(function (index) {
|
||||
$(this).removeClass('active-calendar');
|
||||
@@ -297,6 +424,38 @@ $(document).ready(function () {
|
||||
$(".select2").select2();
|
||||
table.ajax.reload(null, false);
|
||||
});
|
||||
|
||||
$("body").on("click", "#businesstrip", function () {
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#businesstrip_info').show();
|
||||
$('#businesstrip_info').prop('required', true);
|
||||
$('#homeoffice').prop('checked', false);
|
||||
$('#homeoffice-div').hide();
|
||||
|
||||
} else {
|
||||
$('#businesstrip_info').hide();
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').prop('required', false);
|
||||
$('#timerecordingCategory_id').change();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
$("body").on("click", "#homeoffice", function () {
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#businesstrip').prop('checked', false);
|
||||
$('.businesstrip-div').hide();
|
||||
$('#businesstrip_info').hide();
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').prop('required', false);
|
||||
|
||||
} else {
|
||||
$('#timerecordingCategory_id').change();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
$("body").on("click", ".delete-item", function () {
|
||||
if (confirm('Buchung wirklich löschen?')) {
|
||||
$.post(deleteUrl, {
|
||||
@@ -312,10 +471,15 @@ $(document).ready(function () {
|
||||
e.preventDefault();
|
||||
$('#alert-box').remove();
|
||||
var userid;
|
||||
if ($.trim($('#id').val())) {
|
||||
userid = $('#user_id_input').val();
|
||||
userid = $('#user_id_select').val();
|
||||
var businesstrip = false;
|
||||
var homeoffice = false;
|
||||
if ($('#businesstrip').prop('checked') == true) {
|
||||
businesstrip = 1;
|
||||
}
|
||||
if ($('#homeoffice').prop('checked') == true) {
|
||||
homeoffice = 1;
|
||||
}
|
||||
|
||||
$.post(insertUrl, {
|
||||
id: $.trim($('#id').val()),
|
||||
user_id: userid,
|
||||
@@ -324,7 +488,12 @@ $(document).ready(function () {
|
||||
enddate: $.trim($('#enddate').val()),
|
||||
start: $.trim($('#start').val()),
|
||||
end: $.trim($('#end').val()),
|
||||
days: $.trim($('#days').val()),
|
||||
comment: $.trim($('#comment').val()),
|
||||
businesstrip: businesstrip,
|
||||
businesstrip_info: $.trim($('#businesstrip_info').val()),
|
||||
homeoffice: homeoffice,
|
||||
hourday: $.trim($('#timerecordingCategory_id').find(':selected').data('hourday')),
|
||||
ajax: 1
|
||||
}).done(function (data) {
|
||||
var result = $.parseJSON(data);
|
||||
@@ -336,6 +505,10 @@ $(document).ready(function () {
|
||||
<h5><i class="icon fas fa-check"></i> Erfolgreich</h5>
|
||||
` + result.message + `</div>
|
||||
</div>`);
|
||||
$('#businesstrip').prop('checked', false);
|
||||
$('#businesstrip_info').hide();
|
||||
$('#businesstrip_info').val('');
|
||||
$('#businesstrip_info').prop('required', false);
|
||||
}
|
||||
if (result.state === "error") {
|
||||
$('.wrapper .container-fluid').prepend(`<div id="alert-box" class="row">
|
||||
@@ -356,5 +529,7 @@ $(document).ready(function () {
|
||||
table.ajax.reload(null, false);
|
||||
});
|
||||
});
|
||||
$('#timerecordingCategory_id').change();
|
||||
|
||||
})
|
||||
;
|
||||
42
public/plugins/notification/notify.js
Normal file
42
public/plugins/notification/notify.js
Normal file
File diff suppressed because one or more lines are too long
1
public/plugins/notification/notify.min.css
vendored
Normal file
1
public/plugins/notification/notify.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
26
scripts/check_timerecording_plushours.php
Normal file
26
scripts/check_timerecording_plushours.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
//require 'vendor/autoload.php';
|
||||
require("../config/config.php");
|
||||
|
||||
define('FRONKDB_SQLDEBUG', false);
|
||||
error_reporting(E_ALL & ~(E_NOTICE | E_STRICT | E_DEPRECATED));
|
||||
|
||||
require_once(LIBDIR . "/mvcfronk/mfRouter/mfRouter.php");
|
||||
require_once(LIBDIR . "/mvcfronk/mfBase/mfBaseModel.php");
|
||||
require_once(LIBDIR . "/mvcfronk/mfBase/mfBaseController.php");
|
||||
|
||||
$me = new User(154);
|
||||
define("INTERNAL_USER_ID", $me->id);
|
||||
define("INTERNAL_USER_USERNAME", $me->username);
|
||||
|
||||
|
||||
|
||||
$timerecordingemployees = TimerecordingEmployeeModel::search(['startdate' => 1]);
|
||||
//var_dump($timerecordingemployees);
|
||||
foreach ($timerecordingemployees as $timerecordingemployee) {
|
||||
$employee = new TimerecordingController();
|
||||
$employee->updatePlushours($timerecordingemployee->user_id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user