Zeiterfassung neues Feature:

Features für Project 7832:
* Das Pickerldatum Zusatzfeld
* Auftrennen PKW und Anhänger
* Dokumente Upload
* Standardsortierung
* Ausgeschieden Flag mit Datum
* zusätzliche migration
This commit is contained in:
Daniel Spitzer
2025-03-10 08:04:56 +01:00
parent 6deca44063
commit 7d176779c9
12 changed files with 1587 additions and 235 deletions

View File

@@ -1,6 +1,10 @@
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php"); <?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php");
$initialApproval = date("Y-m-d H:i:s", $timerecordingcar->initial_approval); $initialApproval = date("Y-m-d H:i:s", $timerecordingcar->initial_approval);
$initialApprovalMonth = date("m", $timerecordingcar->initial_approval); $initialApprovalMonth = date("m", $timerecordingcar->initial_approval);
if ($timerecordingcar->override_approval) {
$overrideApproval = date("Y-m-d H:i:s", $timerecordingcar->override_approval);
$initialApprovalMonth = date("m", $timerecordingcar->override_approval);
}
$firstApproval = strtotime('+' . $timerecordingcar->first_approval . 'years', strtotime($initialApproval)); $firstApproval = strtotime('+' . $timerecordingcar->first_approval . 'years', strtotime($initialApproval));
if ($firstApproval < time()) { if ($firstApproval < time()) {
$firstApproval = strtotime(date("Y-$initialApprovalMonth-01", time())); $firstApproval = strtotime(date("Y-$initialApprovalMonth-01", time()));
@@ -9,9 +13,13 @@ if ($firstApproval < time()) {
} }
} }
$approval = date("m/Y", $firstApproval); $approval = date("m/Y", $firstApproval);
$cartypes = TimerecordingCarModel::$carTypes;
?> ?>
<link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= date('U') ?>" rel="stylesheet" <link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= date('U') ?>" rel="stylesheet"
type="text/css"/> type="text/css"/>
<link href="<?= self::getResourcePath() ?>css/pages/TimerecordingCar/Form.css?<?= $git_merge_ts ?>" rel="stylesheet"
type="text/css"/>
<style> <style>
table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) { table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) {
padding-right: 10px; padding-right: 10px;
@@ -44,16 +52,32 @@ $approval = date("m/Y", $firstApproval);
<!-- end page title --> <!-- end page title -->
<div class="card"> <div class="card">
<div class="card-body mb-3"> <div class="card-body">
<div class="row"> <div class="row">
<div class="col-12 col-lg-5 card-border"> <div class="col-12 col-lg-8 card-border pr-0 pr-lg-1">
<div> <div class="card">
<div class="card-body">
<div class="row">
<div class="col-4">
<h4>Fahrzeug Informationen </h4> <h4>Fahrzeug Informationen </h4>
<?php if ($timerecordingcar->retired_date): ?>
<div class="alert alert-danger font-weight-500" role="alert">
Fahrzeug ausgeschieden
am <?= date("d.m.Y", $timerecordingcar->retired_date) ?>
von <?= $timerecordingcar->editor->name ?>
</div> </div>
<div> <?php endif; ?>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-6">
<table class="table table-sm"> <table class="table table-sm">
<tbody> <tbody>
<tr>
<th class="w-30">Fahrzeugtyp</th>
<td><?= $cartypes[$timerecordingcar->type] ?></td>
</tr>
<tr> <tr>
<th class="w-30">Marke</th> <th class="w-30">Marke</th>
<td><?= $timerecordingcar->brand ?></td> <td><?= $timerecordingcar->brand ?></td>
@@ -70,19 +94,11 @@ $approval = date("m/Y", $firstApproval);
<th>Fahrzeugverwalter</th> <th>Fahrzeugverwalter</th>
<td><?= ($timerecordingcar->user_id) ? $timerecordingcar->user->name : "-" ?></td> <td><?= ($timerecordingcar->user_id) ? $timerecordingcar->user->name : "-" ?></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
</div> </div>
<div class="col-12 col-lg-6 card-border">
</div>
<div class="col-12 col-lg-5 card-border">
<div>
<h4>&nbsp;</h4>
</div>
<div> <div>
<table class="table table-sm"> <table class="table table-sm">
<tbody> <tbody>
@@ -94,6 +110,12 @@ $approval = date("m/Y", $firstApproval);
<th>Erstzulassung</th> <th>Erstzulassung</th>
<td><?= ($timerecordingcar->initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?></td> <td><?= ($timerecordingcar->initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?></td>
</tr> </tr>
<?php if ($timerecordingcar->override_approval) : ?>
<tr>
<th>§57a Korrektur</th>
<td><?= ($timerecordingcar->initial_approval) ? date("m/Y", $timerecordingcar->override_approval) : "-" ?></td>
</tr>
<?php endif; ?>
<tr> <tr>
<th>Nächste $57a</th> <th>Nächste $57a</th>
<td><?= ($timerecordingcar->initial_approval) ? $approval : "-" ?></td> <td><?= ($timerecordingcar->initial_approval) ? $approval : "-" ?></td>
@@ -108,12 +130,57 @@ $approval = date("m/Y", $firstApproval);
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<?php if ($timerecordingcarDokuments) : ?>
<div class="col-12 col-lg-4 card-border pr-0 pl-lg-1">
<div class="card">
<div class="card-body">
<div class="row">
<div class="col-12">
<h4>Dokumente </h4>
</div>
</div>
<?php foreach ($timerecordingcarDokuments as $timerecordingcarDokument) :
$filesize = $timerecordingcarDokument->file_size;
if ($filesize < 1024) {
$filesize = number_format($filesize, 2) . " B";
} elseif ($filesize < 1024 * 1024) {
$filesize = number_format($filesize / 1024, 2) . " KB";
} else {
$filesize = number_format($filesize / 1024 / 1024, 2) . " MB";
}
$uploadDate = date("d.m.y", $timerecordingcarDokument->file->create);
$mimetype = $timerecordingcarDokument->file->mimetype;
if (!array_key_exists($mimetype, $mimetypes)) {
$mimetype = "fa-file";
} else
$mimetype = $mimetypes[$mimetype];
?>
<div class="doc-main-div border-bottom mb-1"
data-name="<?= $timerecordingcarDokument->file->name ?>">
<div class="d-inline-block doc-icon-div"><i
class="fa-duotone fa-solid <?= $mimetype ?>"></i>
</div>
<div class="d-inline-block doc-content-div"
style="margin-left: -3px;"><a
href="<?= self::getUrl("File", "download", ["id" => $timerecordingcarDokument->file_id]) ?>"
target="_blank"><?= $timerecordingcarDokument->file->name ?></a>
</div>
<span class="mt-2px float-right ml-1">(<?= $uploadDate ?>)</span>
<span class="mt-2px float-right"><?= $filesize ?></span>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php endif; ?>
</div>
</div>
</div>
<div class="card"> <div class="card">
@@ -158,7 +225,8 @@ $approval = date("m/Y", $firstApproval);
<tr> <tr>
<td class="text-center"><?= $timerecording->mileage_start ?> KM</td> <td class="text-center"><?= $timerecording->mileage_start ?> KM</td>
<td class="text-center"><?= $timerecording->mileage_end ?> KM</td> <td class="text-center"><?= $timerecording->mileage_end ?> KM</td>
<td class="text-center"><?= $timerecording->mileage_end - $timerecording->mileage_start ?>KM <td class="text-center"><?= $timerecording->mileage_end - $timerecording->mileage_start ?>
KM
<td class="text-center"><?= $timerecording->user->name ?></td> <td class="text-center"><?= $timerecording->user->name ?></td>
<td data-order="<?= $timerecording->start ?>" <td data-order="<?= $timerecording->start ?>"
class="text-center"><?= date("d.m.Y", $timerecording->start) ?></td> class="text-center"><?= date("d.m.Y", $timerecording->start) ?></td>

View File

@@ -8,8 +8,13 @@ foreach ($timerecordingusers as $timerecordinguser) {
$timerecordingUsers[$timerecordinguser->name] = $timerecordinguser->id; $timerecordingUsers[$timerecordinguser->name] = $timerecordinguser->id;
} }
ksort($timerecordingUsers); ksort($timerecordingUsers);
$cartypes = TimerecordingCarModel::$carTypes;
?> ?>
<link href="<?= self::getResourcePath() ?>assets/css/select2-cstm.css?<?= date('U') ?>" rel="stylesheet" <link href="<?= self::getResourcePath() ?>assets/css/select2-cstm.css?<?= $git_merge_ts ?>" rel="stylesheet"
type="text/css"/>
<link href="<?= self::getResourcePath() ?>css/pages/TimerecordingCar/Form.css?<?= $git_merge_ts ?>" rel="stylesheet"
type="text/css"/> type="text/css"/>
<!-- start page title --> <!-- start page title -->
<div class="row"> <div class="row">
@@ -41,23 +46,17 @@ ksort($timerecordingUsers);
action="<?= self::getUrl("TimerecordingCar", "save", ["returnto" => $_GET["returnto"]]) ?>"> action="<?= self::getUrl("TimerecordingCar", "save", ["returnto" => $_GET["returnto"]]) ?>">
<div class="card no-shadow"> <div class="card no-shadow">
<div class="card-body"> <div class="card-body">
<input type="hidden" name="id" value="<?= $timerecordingcars->id ?>"/> <div class="row">
<div class="col-lg-5">
<input type="hidden" id="id" name="id" value="<?= $timerecordingcars->id ?>"/>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" for="number_plate">Kennzeichen *</label> <label class="col-lg-4 col-form-label" for="brand">Fahrzeugtyp *</label>
<div class="col-lg-1"> <div class="col-lg-4">
<input required="required" type="text" id="number_plate" name="number_plate" <select id="type_select" name="type"
class="form-control"
value="<?= $timerecordingcars->number_plate ?>"/>
</div>
</div>
<div class="form-group row">
<label class="col-lg-2 col-form-label" for="brand">Fahrzeugverwalter</label>
<div class="col-lg-2">
<select id="user_id_select" name="user_id"
class="select2 form-control" required="required"> class="select2 form-control" required="required">
<option value="-">&nbsp</option> <?php foreach ($cartypes as $key => $cartype): ?>
<?php foreach ($timerecordingUsers as $key => $timerecordingUser): ?> <option <?= ($timerecordingcars->type == $key) ? 'selected="selected"' : "" ?>
<option <?= ($timerecordingcars->user_id==$timerecordingUser) ? 'selected="selected"' : "" ?> value="<?= $timerecordingUser ?>"><?= $key ?></option> value="<?= $key ?>"><?= $cartype ?></option>
<?php <?php
endforeach; ?> endforeach; ?>
</select> </select>
@@ -65,24 +64,50 @@ ksort($timerecordingUsers);
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" for="brand">Marke *</label> <label class="col-lg-4 col-form-label" for="number_plate">Kennzeichen
*</label>
<div class="col-lg-3"> <div class="col-lg-3">
<input required="required" type="text" id="number_plate"
name="number_plate"
class="form-control"
value="<?= $timerecordingcars->number_plate ?>"/>
</div>
</div>
<div class="form-group row">
<label class="col-lg-4 col-form-label" for="brand">Fahrzeugverwalter</label>
<div class="col-lg-4">
<select id="user_id_select" name="user_id"
class="select2 form-control" required="required">
<option value="-">&nbsp</option>
<?php foreach ($timerecordingUsers as $key => $timerecordingUser): ?>
<option <?= ($timerecordingcars->user_id == $timerecordingUser) ? 'selected="selected"' : "" ?>
value="<?= $timerecordingUser ?>"><?= $key ?></option>
<?php
endforeach; ?>
</select>
</div>
</div>
<div class="form-group row">
<label class="col-lg-4 col-form-label" for="brand">Marke *</label>
<div class="col-lg-4">
<input required="required" type="text" id="brand" name="brand" <input required="required" type="text" id="brand" name="brand"
class="form-control" class="form-control"
value="<?= $timerecordingcars->brand ?>"/> value="<?= $timerecordingcars->brand ?>"/>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" for="model">Model/Typ *</label> <label class="col-lg-4 col-form-label" for="model">Model/Typ *</label>
<div class="col-lg-3"> <div class="col-lg-4">
<input required="required" type="text" id="model" name="model" <input required="required" type="text" id="model" name="model"
class="form-control" class="form-control"
value="<?= $timerecordingcars->model ?>"/> value="<?= $timerecordingcars->model ?>"/>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" for="initial_approval">Erstzulassung</label> <label class="col-lg-4 col-form-label"
<div class="col-lg-2"> for="initial_approval">Erstzulassung</label>
<div class="col-lg-3">
<input type="month" id="initial_approval" <input type="month" id="initial_approval"
name="initial_approval" name="initial_approval"
class="form-control" class="form-control"
@@ -91,9 +116,22 @@ ksort($timerecordingUsers);
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" for="first_approval">Erste §57a nach</label> <label class="col-lg-4 col-form-label"
<div class="col-lg-2"> for="initial_approval">§57 Korrektur</label>
<select id="first_approval" name="first_approval" class="select2 form-control"> <div class="col-lg-3">
<input type="month" id="override_approval"
name="override_approval"
class="form-control"
value="<?= ($timerecordingcars->override_approval) ? date('Y-m', $timerecordingcars->override_approval) : "" ?>"/>
</div>
</div>
<div class="form-group row">
<label class="col-lg-4 col-form-label" for="first_approval">Erste §57a
nach</label>
<div class="col-lg-3">
<select id="first_approval" name="first_approval"
class="select2 form-control">
<option value=" ">&nbsp;</option> <option value=" ">&nbsp;</option>
<option value="1" <?= ($timerecordingcars->first_approval == "1") ? "selected='selected'" : "" ?>> <option value="1" <?= ($timerecordingcars->first_approval == "1") ? "selected='selected'" : "" ?>>
1 Jahr 1 Jahr
@@ -114,15 +152,15 @@ ksort($timerecordingUsers);
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" for="mileage">Kilometerstand</label> <label class="col-lg-4 col-form-label" for="mileage">Kilometerstand</label>
<div class="col-lg-1"> <div class="col-lg-2">
<input type="number" id="mileage" name="mileage" <input type="number" id="mileage" name="mileage"
class="form-control" class="form-control"
value="<?= $timerecordingcars->mileage ?>"/> value="<?= $timerecordingcars->mileage ?>"/>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2 col-form-label" <label class="col-lg-4 col-form-label"
for="timerecording">Digitales Fahrtenbuch</label> for="timerecording">Digitales Fahrtenbuch</label>
<div class="col-lg-3"> <div class="col-lg-3">
<div class="form-check"> <div class="form-check">
@@ -133,14 +171,85 @@ ksort($timerecordingUsers);
</div> </div>
</div> </div>
</div> </div>
<div class="col-lg-7">
<!-- <div class="form-group row">-->
<!-- <label class="col-lg-2 col-form-label" for="timerecording">Journal</label>-->
<!-- <div class="col-lg-10">-->
<!-- <textarea class="form-control eventmodal-input" id="description"-->
<!-- rows="2"></textarea>-->
<!-- </div>-->
<!-- </div>-->
<div id="documents" class="row mt-2 mb-2 justify-content-center">
<div class="col-6" id="ducuments" data-newkey="">
<label class="col-form-label fw-medium">Dokumente</label>
<div class="input-group mb-2">
<div class="custom-file">
<input type="file" class="custom-file-input" id="files-input"
name="files[]"
multiple>
<label class="custom-file-label" for="files-input"
aria-describedby="">Datei(en) auswählen oder
hereinziehen</label>
</div>
</div>
<div class="attachment-div mb-2">
<?php foreach ($timerecordingcarDokuments as $timerecordingcarDokument):
$filesize=$timerecordingcarDokument->file_size;
if ($filesize<1024) {
$filesize = number_format($filesize, 2) . " B";
} elseif ($filesize < 1024 * 1024) {
$filesize = number_format($filesize / 1024, 2) . " KB";
} else {
$filesize = number_format($filesize / 1024 / 1024, 2) . " MB";
}
$uploadDate = date("d.m.y", $timerecordingcarDokument->file->create);
$mimetype=$timerecordingcarDokument->file->mimetype;
if (!array_key_exists($mimetype, $mimetypes)) {
$mimetype = "fa-file";
} else
$mimetype = $mimetypes[$mimetype];
?>
<div class="doc-main-div"
data-name="<?= $timerecordingcarDokument->file->name ?>" data-id="<?= $timerecordingcarDokument->id?>">
<div class="d-inline-block doc-icon-div"><i
class="fa-duotone fa-solid <?= $mimetype ?>"></i>
</div>
<div class="d-inline-block doc-content-div"
style="margin-left: -3px;"><a
href="<?= self::getUrl("File", "download", ["id" => $timerecordingcarDokument->file_id]) ?>"
target="_blank"><?= $timerecordingcarDokument->file->name ?></a>
</div>
<span class="float-right"><i
title="<?= $timerecordingcarDokument->file->name ?>"
class="fas fa-trash fa-del-document ml-2"></i></span>
<span class="float-right ml-1">(<?= $uploadDate ?>)</span>
<span class="float-right"><?= $filesize ?></span>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-lg-2"></label> <div class="col-lg-2 mb-1 mb-sm-1">
<?php if ($timerecordingcars->id && !$timerecordingcars->retired): ?>
<button type="button" class="btn btn-danger" data-toggle="modal"
data-target="#retireModal">
Fahrzeug ausscheiden
</button>
<?php endif; ?>
</div>
<div class="col-lg-10"> <div class="col-lg-10">
<button type="submit" class="btn btn-primary">Speichern</button> <button type="submit" class="btn btn-primary">Speichern</button>
<a href="<?= $cancelUrl ?>"> <a href="<?= $cancelUrl ?>">
<button type="button" class="btn btn-secondary">Abbrechen</button> <button type="button" class="btn btn-secondary">Abbrechen</button>
</a> </a>
</div> </div>
</div> </div>
@@ -151,19 +260,35 @@ ksort($timerecordingUsers);
</div> </div>
</div> </div>
<div class="modal fade" id="retireModal" tabindex="-1" role="dialog" aria-labelledby="retireModalLabel"
<script type="text/javascript"> aria-hidden="true">
$(".select2").select2({placeholder: ""}); <div class="modal-dialog" role="document">
<div class="modal-content">
// disable mousewheel on a input number field when in focus <div class="modal-header">
$('form').on('focus', 'input[type=number]', function (e) { <h5 class="modal-title" id="retireModalLabel">Fahrzeug ausscheiden</h5>
$(this).on('wheel.disableScroll', function (e) { <button type="button" class="close" data-dismiss="modal" aria-label="Schließen">
e.preventDefault() <span aria-hidden="true">&times;</span>
}) </button>
}); </div>
$('form').on('blur', 'input[type=number]', function (e) { <div class="modal-body">
$(this).off('wheel.disableScroll') <label for="retireDate">Bitte Datum auswählen:</label>
}); <input type="date" value="<?= date("Y-m-d", time()) ?>" id="retireDate" class="form-control">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" id="confirmRetire">Fahrzeug ausscheiden</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">Abbrechen</button>
</div>
</div>
</div>
</div>
<script>
let requestDocumentUrl = "<?= self::getUrl("File", "download") ?>";
let requestDocumentUploadUrl = "<?= self::getUrl("TimerecordingCar", "api", ['do' => 'uploadDocuments']) ?>";
let requestDocumentDeleteUrl = "<?= self::getUrl("TimerecordingCar", "api", ['do' => 'deleteDocument']) ?>";
</script> </script>
<script type="text/javascript"
src="<?= self::getResourcePath() ?>plugins/tinymce/tinymce.min.js?<?= $git_merge_ts ?>"></script>
<script type="text/javascript"
src="<?= self::getResourcePath() ?>js/pages/TimerecordingCar/Form.js?<?= $git_merge_ts ?>"></script>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?> <?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>

View File

@@ -1,12 +1,30 @@
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php"); ?> <?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/header.php"); ?>
<link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= $git_merge_ts ?>" rel="stylesheet" <link href="<?= self::getResourcePath() ?>assets/css/datatables-std.css?<?= $git_merge_ts ?>" rel="stylesheet"
type="text/css"/> type="text/css"/>
<link href="<?= self::getResourcePath() ?>datatables/DataTables-2x/datatables.min.css?<?= $git_merge_ts ?>" rel="stylesheet"
type="text/css"/>
<style> <style>
table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) { table.dataTable.table-sm > thead > tr > th:not(.sorting_disabled) {
padding-right: 10px; padding-right: 15px;
} }
.retired {
background-color: #780000 !important;
color: #ffffff !important;
}
.retired-href {
color: #cfe6ff;
text-decoration: underline;
}
.retired-href:hover {
color: #ffffff;
}
.text-underlined {
text-decoration: underline;
}
</style> </style>
<!-- start page title --> <!-- start page title -->
<div class="row"> <div class="row">
@@ -39,6 +57,38 @@
</div> </div>
</div> </div>
</div> </div>
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a
class="nav-link active"
id="home-tab"
data-toggle="tab"
href="#home"
role="tab"
aria-controls="home"
aria-selected="true"
>PKW's</a>
</li>
<li class="nav-item">
<a
class="nav-link"
id="profile-tab"
data-toggle="tab"
href="#user-tab"
role="tab"
aria-controls="user-tab"
aria-selected="false"
>Anhänger</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div
class="tab-pane fade show active"
id="home"
role="tabpanel"
aria-labelledby="home-tab"
>
<table id="datatable" class="table table-striped table-hover table-sm"> <table id="datatable" class="table table-striped table-hover table-sm">
<thead> <thead>
<tr class="bg-white"> <tr class="bg-white">
@@ -46,10 +96,11 @@
<th class="text-center">Fahrzeugverwalter</th> <th class="text-center">Fahrzeugverwalter</th>
<th class="text-center">Marke</th> <th class="text-center">Marke</th>
<th class="text-center">Model/Typ</th> <th class="text-center">Model/Typ</th>
<th class="text-center">Erstzulassssung</th> <th class="text-center">Erstzulassung</th>
<th class="text-center">$57a</th> <th class="text-center">$57a</th>
<th class="text-center">Fahrtenbuch</th> <th class="text-center">Fahrtenbuch</th>
<th class="text-center">Kilometerstand</th> <th class="text-center">KM-Stand</th>
<th class="text-center">Aktiv</th>
<th class="edit-width-w70"></th> <th class="edit-width-w70"></th>
</tr> </tr>
<tr id="filterrow"> <tr id="filterrow">
@@ -62,10 +113,93 @@
<th></th> <th></th>
<th></th> <th></th>
<th></th> <th></th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php foreach ($timerecordingcars as $timerecordingcar): <?php foreach ($timerecordingcars as $timerecordingcar):
if ($timerecordingcar->type == 2) {
continue;
}
$initialApproval = date("Y-m-d H:i:s", $timerecordingcar->initial_approval);
$initialApprovalMonth = date("m", $timerecordingcar->initial_approval);
$firstApproval = strtotime('+' . $timerecordingcar->first_approval . 'years', strtotime($initialApproval));
if ($firstApproval < time()) {
$firstApproval = strtotime(date("Y-$initialApprovalMonth-01", time()));
if ($firstApproval < time()) {
$firstApproval = strtotime(date("Y-$initialApprovalMonth-01", strtotime('+1 year')));
}
}
$approval = date("m/Y", $firstApproval);
?>
<tr class="<?= ($timerecordingcar->retired) ? 'retired' : '' ?>">
<td>
<a class="<?= ($timerecordingcar->retired) ? 'retired-href' : 'text-underlined' ?>"
href="<?= self::getUrl("TimerecordingCar", "detail", ["id" => $timerecordingcar->id]) ?>"> <?= $timerecordingcar->number_plate ?></a>
</td>
<td><?= ($timerecordingcar->user_id) ? $timerecordingcar->user->name : "-" ?></td>
<td><?= $timerecordingcar->brand ?></td>
<td><?= $timerecordingcar->model ?></td>
<td class="text-center"
data-order="<?= ($timerecordingcar->initial_approval) ? $timerecordingcar->initial_approval : "-" ?>"><?= ($timerecordingcar->initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?></td>
<td class="text-center"
data-order="<?= ($timerecordingcar->initial_approval) ? $firstApproval : "-" ?>"><?= ($timerecordingcar->initial_approval) ? $approval : "-" ?></td>
<td class="text-center"><?= ($timerecordingcar->timerecording) ? "Ja" : "Nein" ?></td>
<td class="text-center"><?= ($timerecordingcar->mileage_now) ? number_format($timerecordingcar->mileage_now, 0, ',', '.') . " KM" : "-" ?>
<td class="text-center"><?= ($timerecordingcar->retired) ? "Nein" : "Ja" ?></td>
</td>
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
<a href="<?= self::getUrl("TimerecordingCar", "edit", ["id" => $timerecordingcar->id]) ?>"><i
class="far fa-edit" title="Bearbeiten"></i></a>
<a href="<?= self::getUrl("TimerecordingCar", "delete", ["id" => $timerecordingcar->id]) ?>"
onclick="if(!confirm('Fahrzeug wirklich löschen?')) return false;"
class="text-danger"
title="Löschen"><i class="fas fa-trash"></i></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<div
class="tab-pane fade col-12"
id="user-tab"
role="tabpanel"
aria-labelledby="profile-tab"
>
<table id="datatable2" class="table table-striped table-hover table-sm" style="width:100%">
<thead>
<tr class="bg-white">
<th class="text-center">Kennzeichen</th>
<th class="text-center">Fahrzeugverwalter</th>
<th class="text-center">Marke</th>
<th class="text-center">Model/Typ</th>
<th class="text-center">Erstzulassung</th>
<th class="text-center">$57a</th>
<th class="text-center">Fahrtenbuch</th>
<th class="text-center">KM-Stand</th>
<th class="text-center">Aktiv</th>
<th class="edit-width-w70"></th>
</tr>
<tr id="filterrow2">
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($timerecordingcars as $timerecordingcar):
if ($timerecordingcar->type == 1) {
continue;
}
$initialApproval = date("Y-m-d H:i:s", $timerecordingcar->initial_approval); $initialApproval = date("Y-m-d H:i:s", $timerecordingcar->initial_approval);
$initialApprovalMonth = date("m", $timerecordingcar->initial_approval); $initialApprovalMonth = date("m", $timerecordingcar->initial_approval);
$firstApproval = strtotime('+' . $timerecordingcar->first_approval . 'years', strtotime($initialApproval)); $firstApproval = strtotime('+' . $timerecordingcar->first_approval . 'years', strtotime($initialApproval));
@@ -80,47 +214,238 @@
?> ?>
<tr> <tr>
<td> <td>
<a href="<?= self::getUrl("TimerecordingCar", "detail", ["id" => $timerecordingcar->id]) ?>"> <?= $timerecordingcar->number_plate ?></a> <a class="<?= ($timerecordingcar->retired) ? 'retired-href' : 'text-underlined' ?>"
href="<?= self::getUrl("TimerecordingCar", "detail", ["id" => $timerecordingcar->id]) ?>"> <?= $timerecordingcar->number_plate ?></a>
</td> </td>
<td><?= ($timerecordingcar->user_id) ? $timerecordingcar->user->name : "-" ?></td> <td><?= ($timerecordingcar->user_id) ? $timerecordingcar->user->name : "-" ?></td>
<td><?= $timerecordingcar->brand ?></td> <td><?= $timerecordingcar->brand ?></td>
<td><?= $timerecordingcar->model ?></td> <td><?= $timerecordingcar->model ?></td>
<td class="text-center"><?= ($timerecordingcar->initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?></td> <td class="text-center"
<td class="text-center"><?= ($timerecordingcar->initial_approval) ? $approval : "-" ?></td> data-order="<?= ($timerecordingcar->initial_approval) ? $timerecordingcar->initial_approval : "-" ?>"><?= ($timerecordingcar->initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?></td>
<td class="text-center"
data-order="<?= ($timerecordingcar->initial_approval) ? $firstApproval : "-" ?>"><?= ($timerecordingcar->initial_approval) ? $approval : "-" ?></td>
<td class="text-center"><?= ($timerecordingcar->timerecording) ? "Ja" : "Nein" ?></td> <td class="text-center"><?= ($timerecordingcar->timerecording) ? "Ja" : "Nein" ?></td>
<td class="text-center"><?= ($timerecordingcar->mileage_now) ? number_format($timerecordingcar->mileage_now, 0, ',', '.') . " KM" : "-" ?> <td class="text-center"><?= ($timerecordingcar->mileage_now) ? number_format($timerecordingcar->mileage_now, 0, ',', '.') . " KM" : "-" ?>
<td class="text-center"><?= ($timerecordingcar->retired) ? "Nein" : "Ja" ?></td>
</td> </td>
<td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;"> <td style="text-align: left; letter-spacing: 4px; font-size: 1.1em;">
<a href="<?= self::getUrl("TimerecordingCar", "edit", ["id" => $timerecordingcar->id]) ?>"><i <a href="<?= self::getUrl("TimerecordingCar", "edit", ["id" => $timerecordingcar->id]) ?>"><i
class="far fa-edit" title="Bearbeiten"></i></a> class="far fa-edit" title="Bearbeiten"></i></a>
<a href="<?= self::getUrl("TimerecordingCar", "delete", ["id" => $timerecordingcar->id]) ?>" <a href="<?= self::getUrl("TimerecordingCar", "delete", ["id" => $timerecordingcar->id]) ?>"
onclick="if(!confirm('Fahrzeug wirklich löschen?')) return false;" class="text-danger" onclick="if(!confirm('Fahrzeug wirklich löschen?')) return false;"
class="text-danger"
title="Löschen"><i class="fas fa-trash"></i></a> title="Löschen"><i class="fas fa-trash"></i></a>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
</tbody> </tbody>
</table> </table>
</div>
</div>
<h3></h3>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<script type="text/javascript"
src="<?= self::getResourcePath() ?>datatables/DataTables-2x/datatables.min.js?<?= $git_merge_ts ?>"></script>
<script type="text/javascript"> <script type="text/javascript">
var hidesearch = [8]; let table, table2;
let tableInitialized = false;
// Variablen definieren, die du ggf. anpassen musst:
let hidesearchDT = [7, 9];
var columnfilter = [6]; let pageLength = 25;
var columnoptions = '<option value=""></option><option value="Ja">Ja</option><option value="Nein">Nein</option>'; let cstmdom = "flBrtip";
$(document).ready(function () { let columndefs = [];
let columnfilter = [6, 8];
let columnoptions = '<option value=""></option><option value="Ja">Ja</option><option value="Nein">Nein</option>';
// Initialisierung für die erste Tabelle (z. B. PKW's)
$('#filterrow th').each(function (i) {
let title = $('#datatable thead th').eq(i).text();
if (hidesearchDT.includes(i)) {
// Kein Filter hinzufügen
} else if (columnfilter.includes(i)) {
if (i === 8) {
$(this).html('<select id="selectsearch" style="padding: 0; height: 28px; text-align: center;" class="form-control" data-index="' + i + '"><option value=""></option><option selected="selected" value="Ja">Ja</option><option value="Nein">Nein</option></select>');
} else {
$(this).html('<select style="padding: 0; height: 28px; text-align: center;" class="form-control" data-index="' + i + '">' + columnoptions + '</select>');
}
} else {
$(this).html('<input type="text" placeholder="' + title + '" class="form-control" data-index="' + i + '" value="" />');
}
});
table = $('#datatable').DataTable({
responsive: {
breakpoints: [
{name: 'desktop', width: Infinity},
{name: 'tablet', width: 1024},
{name: 'fablet', width: 768},
{name: 'phone', width: 480}
]
},
pageLength: pageLength,
buttons: [{
extend: 'excelHtml5',
text: 'XLSX Export',
className: 'btn-success d-none margina d-lg-block',
exportOptions: {
columns: ':not(:last-child)',
format: {
body: function (data) {
data = $('<p>' + data + '</p>').text();
return $.isNumeric(data.replace(',', '.')) ? data.replace(',', '.') : data;
}
}
}
}],
columnDefs: columndefs,
language: {"url": "/datatables/json/german.json?v1"},
orderCellsTop: true,
stateSave: true,
stateDuration: 60 * 60 * 24 * 30,
stateLoadParams: function (settings, data) {
data.order = [[2, 'asc'], [1, 'asc']];
},
initComplete: function () {
$('#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('');
table.search('').columns().search('').draw();
});
$('#selectsearch').change();
},
dom: cstmdom
});
$('#filterrow').on('keyup', 'input', function () {
table
.column($(this).data('index'))
.search(this.value)
.draw();
});
$('#filterrow').on('change', 'select', function () {
table
.column($(this).data('index'))
.search(this.value)
.draw();
});
let state = table.state.loaded();
if (state) {
table.columns().eq(0).each(function (colIdx) {
var colSearch = state.columns[colIdx].search;
if (colSearch.search) {
if (colIdx == 8) {
} else {
$('#filterrow').find("[data-index='" + colIdx + "']").val(colSearch.search);
}
}
});
table.draw();
}
// Initialisierung für die zweite Tabelle (z. B. Anhänger)
$('#filterrow2 th').each(function (i) {
let title = $('#datatable2 thead th').eq(i).text();
if (hidesearchDT.includes(i)) {
// Kein Filter
} else if (columnfilter.includes(i)) {
if (i === 8) {
$(this).html('<select id="selectsearch2" style="padding: 0; height: 28px; text-align: center;" class="form-control" data-index="' + i + '"><option value=""></option><option selected="selected" value="Ja">Ja</option><option value="Nein">Nein</option></select>');
} else {
$(this).html('<select style="padding: 0; height: 28px; text-align: center;" class="form-control" data-index="' + i + '">' + columnoptions + '</select>');
}
} else {
$(this).html('<input type="text" placeholder="' + title + '" class="form-control" data-index="' + i + '" value="" />');
}
});
table2 = $('#datatable2').DataTable({
responsive: {
breakpoints: [
{name: 'desktop', width: Infinity},
{name: 'tablet', width: 1024},
{name: 'fablet', width: 768},
{name: 'phone', width: 480}
]
},
pageLength: pageLength,
buttons: [{
extend: 'excelHtml5',
text: 'XLSX Export',
className: 'btn-success d-none margina d-lg-block',
exportOptions: {
columns: ':not(:last-child)',
format: {
body: function (data) {
data = $('<p>' + data + '</p>').text();
return $.isNumeric(data.replace(',', '.')) ? data.replace(',', '.') : data;
}
}
}
}],
columnDefs: columndefs,
language: {"url": "/datatables/json/german.json?v1"},
orderCellsTop: true,
stateSave: true,
stateDuration: 60 * 60 * 24 * 30,
stateLoadParams: function (settings, data) {
data.order = [[2, 'asc'], [1, 'asc']];
},
initComplete: function () {
$('#datatable2_filter').append('<i id="clear_cookie2" class="fas fa-times clear-fa" title="Filter löschen" aria-hidden="true"></i>');
$('#clear_cookie2').click(function () {
$('#filterrow2 input').val('');
$('#filterrow2 select').val('');
table2.search('').columns().search('').draw();
});
$('#selectsearch2').change();
},
dom: cstmdom
});
$('#filterrow2').on('keyup', 'input', function () {
table2
.column($(this).data('index'))
.search(this.value)
.draw();
});
$('#filterrow2').on('change', 'select', function () {
table2
.column($(this).data('index'))
.search(this.value)
.draw();
});
let state2 = table2.state.loaded();
if (state2) {
table2.columns().eq(0).each(function (colIdx) {
var colSearch = state2.columns[colIdx].search;
if (colIdx == 8) {
} else {
$('#filterrow2').find("[data-index='" + colIdx + "']").val(colSearch.search);
}
}); });
table2.draw();
}
</script> </script>
<script type="text/javascript"
src="<?= self::getResourcePath() ?>assets/js/datatables-std2.js?<?= $git_merge_ts ?>"></script>
<?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?> <?php include(realpath(dirname(__FILE__) . "/../../$mfLayoutPackage") . "/footer.php"); ?>

View File

@@ -16,6 +16,34 @@ class TimerecordingCarController extends mfBaseController
} }
} }
protected function apiAction()
{
$do = $this->request->do;
switch ($do) {
case "uploadDocuments":
$return = $this->uploadDocument();
break;
case "getDocuments":
$return = $this->getDocuments();
break;
case "deleteDocument":
$return = $this->deleteDocument();
break;
default:
$return = false;
}
if (!is_array($return) || !count($return)) {
$data = ["status" => "error"];
$this->returnJson($data);
}
$data['status'] = "OK";
$data['result'] = $return;
$this->returnJson($data);
}
protected function indexAction() protected function indexAction()
{ {
@@ -28,6 +56,10 @@ class TimerecordingCarController extends mfBaseController
protected function detailAction() protected function detailAction()
{ {
$timerecordingcarid = $this->request->id; $timerecordingcarid = $this->request->id;
$mimetypes = TimerecordingCarDocumentsModel::$mimetypes;
$timerecordingcarDokuments = TimerecordingCarDocumentsModel::search(["timerecordingCar_id" => $timerecordingcarid]);
$this->layout()->set("mimetypes", $mimetypes);
$this->layout()->set("timerecordingcarDokuments", $timerecordingcarDokuments);
$this->layout()->setTemplate("TimerecordingCar/Detail"); $this->layout()->setTemplate("TimerecordingCar/Detail");
$timerecordingcar = TimerecordingCarModel::getOne($timerecordingcarid); $timerecordingcar = TimerecordingCarModel::getOne($timerecordingcarid);
$this->layout()->set("timerecordingcar", $timerecordingcar); $this->layout()->set("timerecordingcar", $timerecordingcar);
@@ -54,16 +86,44 @@ class TimerecordingCarController extends mfBaseController
} }
$timerecordingcars = new TimerecordingCar($id); $timerecordingcars = new TimerecordingCar($id);
$mimetypes = TimerecordingCarDocumentsModel::$mimetypes;
$timerecordingcarDokuments = TimerecordingCarDocumentsModel::search(["timerecordingCar_id" => $id]);
if ($timerecordingcars->id != $id) { if ($timerecordingcars->id != $id) {
$this->layout()->setFlash("Auto nicht gefunden", "error"); $this->layout()->setFlash("Auto nicht gefunden", "error");
$this->redirect("TimerecordingCar"); $this->redirect("TimerecordingCar");
} }
$this->layout()->set("mimetypes", $mimetypes);
$this->layout()->set("timerecordingcarDokuments", $timerecordingcarDokuments);
$this->layout()->set("timerecordingcars", $timerecordingcars); $this->layout()->set("timerecordingcars", $timerecordingcars);
return $this->addAction(); return $this->addAction();
} }
protected function retireAction()
{
$r = $this->request;
$id = $r->id;
$retired_date = $r->retired_date;
if (is_numeric($id) && $id > 0) {
$timerecordingcars = new TimerecordingCar($id);
if (!$timerecordingcars->id) {
$this->layout()->setFlash("Fahrzeug nicht gefunden", "error");
$this->redirect("TimerecordingCar");
}
} else {
$this->layout()->setFlash("Fahrzeug nicht gefunden", "error");
$this->redirect("TimerecordingCar");
}
$data = [];
$data['retired'] = 1;
$data['retired_date'] = strtotime($retired_date);
$data['edit_by'] = $this->me->id;
$timerecordingcars->update($data);
$timerecordingcars->save();
$this->layout()->setFlash("Fahrzeug erfolgreich ausgeschieden", "success");
$this->redirect("TimerecordingCar");
}
protected function saveAction() protected function saveAction()
{ {
$r = $this->request; $r = $this->request;
@@ -83,12 +143,15 @@ class TimerecordingCarController extends mfBaseController
$data = []; $data = [];
$data['number_plate'] = trim($r->number_plate); $data['number_plate'] = trim($r->number_plate);
$data['user_id'] = trim($r->user_id); $data['user_id'] = trim($r->user_id);
$data['type'] = trim($r->type);
$data['brand'] = trim($r->brand); $data['brand'] = trim($r->brand);
$data['model'] = trim($r->model); $data['model'] = trim($r->model);
$data['mileage'] = trim($r->mileage); $data['mileage'] = trim($r->mileage);
$data['initial_approval'] = strtotime($r->initial_approval); $data['initial_approval'] = strtotime($r->initial_approval);
$data['timerecording'] = $r->timerecording; $data['timerecording'] = $r->timerecording;
$data['first_approval'] = trim($r->first_approval); $data['first_approval'] = trim($r->first_approval);
$data['override_approval'] = strtotime(trim($r->override_approval));
$data['edit_by'] = $this->me->id;
if (!$data['user_id'] || $data['user_id'] == "-") { if (!$data['user_id'] || $data['user_id'] == "-") {
@@ -97,6 +160,9 @@ class TimerecordingCarController extends mfBaseController
if (!$data['initial_approval']) { if (!$data['initial_approval']) {
$data['initial_approval'] = null; $data['initial_approval'] = null;
} }
if (!$data['override_approval']) {
$data['override_approval'] = null;
}
if (!$data['timerecording']) { if (!$data['timerecording']) {
$data['timerecording'] = 0; $data['timerecording'] = 0;
@@ -176,4 +242,64 @@ class TimerecordingCarController extends mfBaseController
$this->redirect("TimerecordingCar"); $this->redirect("TimerecordingCar");
} }
protected function uploadDocument()
{
$r = $this->request;
if (array_key_exists("timeRecordingCar", $_FILES) && !$_FILES['timeRecordingCar']['error']) {
$upload_error = false;
$upload = new mfUpload("timeRecordingCar");
$upload->setSavepath(MFUPLOAD_FILE_SAVE_PATH . "/timeRecordingCar");
if (!$upload->getSize()) {
die();
}
$upload->save();
$file_data = [];
$file_data['name'] = $upload->getOriginalFilename();
$file_data['filename'] = ($r->file_filename) ? $r->file_filename : $upload->getOriginalFilename();
$file_data['subfolder'] = "timeRecordingCar";
$file_data['store_filename'] = $upload->getFilename();
$file_data['orig_filename'] = $upload->getOriginalFilename();
$file = FileModel::create($file_data);
$file_id = $file->save();
if (!$file_id) {
die();
} else {
$data = [];
$data['file_id'] = $file_id;
$data['file_size'] = $upload->getSize();
$data['timerecordingCar_id'] = $r->timerecordingCar_id;
$data['name'] = $upload->getOriginalFilename();
$timerecordingcardocumentss = TimerecordingCarDocumentsModel::create($data);
$id = $timerecordingcardocumentss->save();
}
$result['success'] = true;
$result['data']['file_id'] = $file_id;
$result['data']['id'] = $id;
} else {
echo "error";
}
echo json_encode($result);
die();
}
protected function getDocuments()
{
$r = $this->request;
$file_name = $r->file_name;
$timerecordingCarDokument = TimerecordingCarDocumentsModel::search(["file_name" => $file_name]);
return $timerecordingCarDokument->file_id;
}
protected function deleteDocument()
{
$r = $this->request;
$id = $r->id;
$timerecordingCarDokument = new TimerecordingCarDocuments($id);
$timerecordingCarDokument->file->delete();
$timerecordingCarDokument->delete();
}
} }

View File

@@ -3,6 +3,7 @@
class TimerecordingCarModel class TimerecordingCarModel
{ {
private $user_id; private $user_id;
private $type;
private $number_plate; private $number_plate;
private $brand; private $brand;
private $model; private $model;
@@ -10,8 +11,19 @@ class TimerecordingCarModel
private $mileage_now; private $mileage_now;
private $mileage_timestamp; private $mileage_timestamp;
private $initial_approval; private $initial_approval;
private $override_approval;
private $first_approval; private $first_approval;
private $timerecording; private $timerecording;
private $retired;
private $retired_date;
private $edit_by;
public static $carTypes = [
"1" => "PKW",
"2" => "Anhänger"
];
public static function find($data) public static function find($data)

View File

@@ -0,0 +1,61 @@
<?php
class TimerecordingCarDocuments extends mfBaseModel
{
private $editor;
private $creator;
private $file;
private $timerecordingCar;
public function getProperty($name)
{
if ($this->$name == null) {
if (!$this->id) {
return null;
}
if ($name == "creator") {
$this->creator = mfValuecache::singleton()->get("Worker-id-" . $this->create_by);
if ($this->creator === null) {
$this->creator = new User($this->create_by);
if ($this->creator->id) {
mfValuecache::singleton()->set("Worker-id-" . $this->create_by, $this->creator);
}
}
return $this->creator;
}
if ($name == "editor") {
$this->editor = mfValuecache::singleton()->get("Worker-id-" . $this->edit_by);
if ($this->editor === null) {
$this->editor = new User($this->edit_by);
if ($this->editor->id) {
mfValuecache::singleton()->set("Worker-id-" . $this->edit_by, $this->editor);
}
}
return $this->editor;
}
$classname = ucfirst($name);
$idfield = $name . "_id";
$this->$name = mfValuecache::singleton()->get("mfObjectmodel-$name-" . $this->$idfield);
if (!$this->$name) {
$this->$name = new $classname($this->$idfield);
}
if ($this->$name->id) {
mfValuecache::singleton()->set("mfObjectmodel-$name-" . $this->$name->id, $this->$name);
return $this->$name;
} else {
return null;
}
}
return $this->$name;
}
}

View File

@@ -0,0 +1,145 @@
<?php
class TimerecordingCarDocumentsController extends mfBaseController
{
protected function init()
{
$this->needlogin = true;
$me = new User();
$me->loadMe();
$this->me = $me;
$this->layout()->set("me", $me);
if (!$me->is(["Admin"])) {
$this->redirect("Dashboard");
}
}
protected function indexAction()
{
$this->layout()->setTemplate("TimerecordingCarDocuments/Index");
$timerecordingcardocumentss = TimerecordingCarDocumentsModel::getAll();
$this->layout()->set("timerecordingcardocumentss", $timerecordingcardocumentss);
}
protected function addAction()
{
$files=FileModel::getAll();
$this->layout()->set("files", $files);
$timerecordingCars=TimerecordingCarModel::getAll();
$this->layout()->set("timerecordingCars", $timerecordingCars);
$this->layout()->setTemplate("TimerecordingCarDocuments/Form");
}
protected function editAction()
{
$id = $this->request->id;
if (!is_numeric($id) || !$id) {
$this->layout()->setFlash("bla nicht gefunden", "error");
$this->redirect("TimerecordingCarDocuments");
}
$timerecordingcardocumentss = new TimerecordingCarDocuments($id);
if ($timerecordingcardocumentss->id != $id) {
$this->layout()->setFlash("bla nicht gefunden", "error");
$this->redirect("TimerecordingCarDocuments");
}
$this->layout()->set("timerecordingcardocumentss", $timerecordingcardocumentss);
return $this->addAction();
}
protected function saveAction()
{
$r = $this->request;
$id = $r->id;
//var_dump($r->get());exit;
if (is_numeric($id) && $id > 0) {
$mode = "edit";
$timerecordingcardocumentss = new TimerecordingCarDocuments($id);
if (!$timerecordingcardocumentss->id) {
$this->layout()->setFlash("gg nicht gefunden", "error");
$this->redirect("TimerecordingCarDocuments");
}
} else {
$mode = "add";
}
$data = [];
$data['file_id'] = trim($r->file_id);
$data['file_size'] = trim($r->file_size);
$data['timerecordingCar_id'] = trim($r->timerecordingCar_id);
$data['name'] = trim($r->name);
$data['description'] = trim($r->description);
$data['sort'] = trim($r->sort);
if (!$data['file_id']) {
$data['file_id']=NULL;
}
if (!$data['file_size']) {
$data['file_size']=NULL;
}
if (!$data['timerecordingCar_id']) {
$data['timerecordingCar_id']=NULL;
}
if (!$data['name']) {
$data['name']=NULL;
}
if (!$data['description']) {
$data['description']=NULL;
}
if (!$data['sort']) {
$data['sort']=NULL;
}
// var_dump($_FILES);
// var_dump($upload);
// exit;
if ($mode == "edit") {
$timerecordingcardocumentss->update($data);
} else {
$timerecordingcardocumentss = TimerecordingCarDocumentsModel::create($data);
}
// var_dump($filestore);
// exit;
$id = $timerecordingcardocumentss->save();
if (!$id) {
$this->layout()->setFlash("bla konnte nicht angelegt werden", "error");
$this->redirect("TimerecordingCarDocuments");
}
if ($mode == "edit") {
$this->layout()->setFlash("bla erfolgreich geändert", "success");
} else if ($mode = "add") {
$this->layout()->setFlash("bla erfolgreich angelegt", "success");
}
$this->redirect("TimerecordingCarDocuments");
}
protected function deleteAction()
{
$id = $this->request->id;
$timerecordingcardocumentss = new TimerecordingCarDocuments($id);
if (!$timerecordingcardocumentss->id || $timerecordingcardocumentss->id != $id) {
$this->layout()->setFlash("bla nicht gefunden.", "error");
$this->redirect("TimerecordingCarDocuments");
}
$timerecordingcardocumentss->delete();
$this->redirect("TimerecordingCarDocuments");
}
}

View File

@@ -0,0 +1,153 @@
<?php
class TimerecordingCarDocumentsModel
{
private $file_id;
private $file_size;
private $timerecordingCar_id;
private $name;
private $description;
private $sort;
public static $mimetypes = [
'application/pdf' => 'fa-file-pdf',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'fa-file-doc',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'fa-file-xls',
'application/octet-stream' => 'fa-file-csv',
'text/csv' => 'fa-file-csv',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'fa-file-ppt',
'application/zip' => 'fa-file-zip',
'application/x-zip-compressed' => 'fa-file-zip',
'application/x-rar-compressed' => 'fa-file-archive',
'application/x-7z-compressed' => 'fa-file-archive',
'application/x-tar' => 'fa-file-archive',
'application/x-gzip' => 'fa-file-archive',
'application/x-bzip2' => 'fa-file-archive',
'text/xml' => 'fa-file-xml',
'application/xml' => 'fa-file-xml',
'audio/mpeg' => 'fa-file-mp3',
'image/png' => 'fa-file-png',
'image/jpeg' => 'fa-file-jpg',
];
public static function find($data)
{
}
public static function create(array $data)
{
$model = new TimerecordingCarDocuments();
foreach ($data as $field => $value) {
if (property_exists(get_called_class(), $field)) {
if (substr($field, 0, 5) == "vlan_" && !$value) {
$model->$field = null;
continue;
}
$model->$field = $value;
}
}
$me = mfValuecache::singleton()->get("me");
if (!$me) {
$me = new User();
$me->loadMe();
mfValuecache::singleton()->set("me", $me);
}
if ($model->create_by === null) {
$model->create_by = $me->id;
}
if ($model->edit_by === null) {
$model->edit_by = $me->id;
}
return $model;
}
public static function getOne($id)
{
if (!is_numeric($id) || !$id) {
throw new Exception("Invalid number", 400);
}
$item = [];
$db = FronkDB::singleton();
$res = $db->select("TimerecordingCarDocuments", "*", "id=$id LIMIT 1");
if ($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new TimerecordingCarDocuments($data);
}
return $item;
}
public static function getAll()
{
$items = [];
$db = FronkDB::singleton();
$res = $db->select("TimerecordingCarDocuments", "*", "1=1");
if ($db->num_rows($res)) {
while ($data = $db->fetch_object($res)) {
$items[] = new TimerecordingCarDocuments($data);
}
}
return $items;
}
public static function getFirst()
{
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$res = $db->select("TimerecordingCarDocuments", "*", "$where ");
if ($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new TimerecordingCarDocuments($data);
if ($item->id) {
return $item;
} else {
return null;
}
}
return null;
}
public static function search($filter)
{
$items = [];
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$res = $db->select("TimerecordingCarDocuments", "*", "$where");
if ($db->num_rows($res)) {
while ($data = $db->fetch_object($res)) {
$items[] = new TimerecordingCarDocuments($data);
}
}
return $items;
}
private static function getSqlFilter($filter)
{
$where = "1=1 ";
//var_dump($filter);exit;
if (array_key_exists("file_name", $filter)) {
$file_name = $filter['file_name'];
$where .= " AND file_name=$file_name";
}
if (array_key_exists("timerecordingCar_id", $filter)) {
$timerecordingCar_id = $filter['timerecordingCar_id'];
$where .= " AND timerecordingCar_id=$timerecordingCar_id";
}
//var_dump($filter, $where);exit;
return $where;
}
}

View File

@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class TimerecordingCarDocuments extends AbstractMigration
{
public function up(): void
{
if ($this->getEnvironment() == "thetool") {
$table = $this->table("TimerecordingCarDocuments", ["signed" => true]);
$table->addColumn("file_id", "integer", ["null" => false]);
$table->addColumn("file_size", "integer", ["null" => false]);
$table->addColumn("timerecordingCar_id", "integer", ["null" => false]);
$table->addColumn("name", "string", ["null" => false]);
$table->addColumn("description", "text", ["null" => true]);
$table->addColumn("sort", "integer", ["null" => true]);
$table->addColumn("create_by", "integer", ["null" => false]);
$table->addColumn("edit_by", "integer", ["null" => false]);
$table->addColumn("create", "integer", ["null" => false]);
$table->addColumn("edit", "integer", ["null" => false]);
$table->save();
}
if ($this->getEnvironment() == "addressdb") {
}
}
public function down(): void
{
if ($this->getEnvironment() == "thetool") {
$this->table("TimerecordingCarDocuments")->drop()->save();
}
if ($this->getEnvironment() == "addressdb") {
}
}
}

View File

@@ -6,6 +6,14 @@
height: unset; height: unset;
} }
#filterrow2 input {
width: 100%;
padding: 3px;
box-sizing: border-box;
display: table-header-group;
height: unset;
}
.dataTables_wrapper .dataTables_filter { .dataTables_wrapper .dataTables_filter {
float: left; float: left;
text-align: left; text-align: left;

View File

@@ -0,0 +1,88 @@
.fa-duotone {
font-size: 20px;
cursor: pointer;
}
.doc-icon-div {
width: 25px;
}
.fa-file-pdf:after {
content: "\f1c1\f1c1";
color: #f00;
opacity: 0.5;
}
.fa-file-xls:after {
content: "\f1c1\f1c1";
color: #279800;
opacity: 0.5;
}
.fa-file-csv:after {
content: "\f1c1\f1c1";
color: #279800;
opacity: 0.5;
}
.fa-file-zip:after {
content: "\f1c1\f1c1";
color: #d9c800;
opacity: 0.8;
}
.fa-file-doc:after {
content: "\f1c1\f1c1";
color: #003498;
opacity: 0.5;
}
.fa-file-ppt:after {
content: "\f1c1\f1c1";
color: #ff6400;
opacity: 0.5;
}
.fa-file-xml:after {
content: "\f1c1\f1c1";
color: #009091;
opacity: 0.6;
}
.fa-file-mp3:after {
content: "\f1c1\f1c1";
color: #d104ad;
opacity: 0.6;
}
.fa-file-png:after, .fa-file-jpg:after {
content: "\f1c1\f1c1";
color: #001dff;
opacity: 0.5;
}
.fa-calendar-symbol:after {
color: #0600ff;
opacity: 0.7;
}
.fa-calendar-lines-pen:before {
color: #ff0000;
}
.fa-calendar-circle-plus:before {
color: #0d9f00;
}
.fa-del-document {
color: #ff0000;
cursor: pointer;
}
.doc-content-div a {
color: #000;
}
.mt-2px {
margin-top: 2px;
}

View File

@@ -0,0 +1,201 @@
const fileTypeClasses = {
'image/png': 'fa-file-png',
'image/jpeg': 'fa-file-jpg',
'application/pdf': 'fa-file-pdf',
'application/zip': 'fa-file-zip',
'application/x-zip-compressed': 'fa-file-zip',
'application/octet-stream': 'fa-file-csv',
'text/csv': 'fa-file-csv',
'text/xml': 'fa-file-xml',
'application/xml': 'fa-file-xml',
'audio/mpeg': 'fa-file-mp3',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'fa-file-doc',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'fa-file-xls',
'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'fa-file-ppt',
'application/x-rar-compressed': 'fa-file-archive',
'application/msword': 'fa-file-doc',
'application/vnd.ms-excel': 'fa-file-xls',
'application/vnd.ms-powerpoint': 'fa-file-ppt',
'application/vnd.ms-outlook': 'fa-file-outlook',
'application/vnd.ms-access': 'fa-file-access',
'application/vnd.ms-project': 'fa-file-project',
'application/vnd.ms-visio': 'fa-file-visio',
'application/vnd.ms-publisher': 'fa-file-publisher',
};
$(".select2").select2({placeholder: ""});
// disable mousewheel on a input number field when in focus
$('form').on('focus', 'input[type=number]', function (e) {
$(this).on('wheel.disableScroll', function (e) {
e.preventDefault()
})
});
$('form').on('blur', 'input[type=number]', function (e) {
$(this).off('wheel.disableScroll')
});
tinymce.init({
//font_formats: "Arial=arial,sans-serif;",
selector: '#description',
dialog_container: '#EventModal',
language: 'de',
branding: false,
height: 250,
menubar: false,
forced_root_block_attrs: {
style: 'margin:0;'
},
skin: "tinymce-5",
plugins: ' code link autolink lists table',
paste_block_drop: true,
paste_as_text: true,
paste_data_images: false,
promotion: false,
toolbar1: 'undo redo | styles | bold italic underline strikethrough | fontfamily fontsize forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent | table | link unlink',
content_css: "/assets/css/tinymce.css",
content_style: "body { font-family: 'Calibri', sans-serif; }",
font_family_formats: "Calibri=Calibri, sans-serif;Arial=arial,sans-serif; Courier New=courier new,courier,monospace; Georgia=georgia,palatino,serif; Helvetica=helvetica,sans-serif; Lucida Sans=lucida sans unicode,sans-serif; Tahoma=tahoma,arial,helvetica,sans-serif; Times New Roman=times new roman,times,serif",
setup: function (editor) {
}
});
$(document).ready(function () {
$('#confirmRetire').on('click', function () {
var retireDate = $('#retireDate').val();
if (!retireDate) {
alert("Bitte wählen Sie ein Datum aus.");
return;
}
window.location.href = "<?= self::getUrl('TimerecordingCar', 'retire', ['id' => $timerecordingcars->id]) ?>"
+ "&retired_date=" + encodeURIComponent(retireDate);
});
$('body').on('change', '#files-input', function () {
let fileList = $('#files-input').prop("files");
$('#uploadsts').html('');
let i;
for (i = 0; i < fileList.length; i++) {
let newkey = $('#attachments').data('newkey');
const filetype = fileList[i].type;
const classContentType = fileTypeClasses[filetype] || 'fa-file';
const today = new Date();
const day = today.getDate().toString().padStart(2, '0');
const month = (today.getMonth() + 1).toString().padStart(2, '0');
const year = today.getFullYear().toString().slice(-2);
const formattedDate = `${day}.${month}.${year}`;
// $('#uploadsts').append('<p class="upload-page">' + fileList[i].name + '<span class="loading-prep" id="prog' + i + '"></span></p>');
$('.attachment-div').append(`<div class="doc-main-div doc-main-div-dev" data-name="` + fileList[i].name + `" ><div class="d-inline-block doc-icon-div"><i class="fa-duotone fa-solid ` + classContentType + `"></i></div>
<div class="d-inline-block doc-content-div doc-content-div-dev" style="margin-left: -3px;"></div>
<span class="float-right"><i title="` + fileList[i].name + `" class="fas fa-trash fa-del-document ml-2"></i></span><span class="float-right ml-1">(` + formattedDate + `)</span><span class="float-right">` + formatFileSize(fileList[i].size) + `</span></div>
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated pb-` + fileList[i].size + `" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
`);
if (i == fileList.length - 1) {
uploadajax(fileList.length - 1, 0);
}
}
});
$('body').on('click', '.fa-del-document', function () {
if (confirm('Wollen Sie das Dokument wirklich löschen?')) {
let id = $(this).closest('.doc-main-div').data('id');
let doc = $(this).closest('.doc-main-div');
$.ajax({
url: requestDocumentDeleteUrl,
type: 'POST',
data: {
id: id
},
success: function (res) {
doc.remove();
}
});
}
});
});
function formatFileSize(bytes) {
// Wenn die Dateigröße größer als 1 MB ist
if (bytes >= 1024 * 1024) {
const megabytes = bytes / (1024 * 1024);
return megabytes.toFixed(2) + ' MB';
}
// Wenn die Dateigröße größer als 1 KB ist
else if (bytes >= 1024) {
const kilobytes = bytes / 1024;
return kilobytes.toFixed(2) + ' KB';
}
// Wenn die Dateigröße kleiner als 1 KB ist (also in Bytes)
else {
return Math.round(bytes) + ' Bytes'; // Keine Nachkommastellen
}
}
function uploadajax(ttl, cl) {
let fileList = $('#files-input').prop("files");
let form_data = "";
form_data = new FormData();
form_data.append("timeRecordingCar", fileList[cl]);
form_data.append("timerecordingCar_id", $('#id').val());
form_data.append("file_name", fileList[cl].name);
let request = $.ajax({
url: requestDocumentUploadUrl,
cache: false,
contentType: false,
processData: false,
async: true,
data: form_data,
type: 'POST',
xhr: function () {
let xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (event) {
let percent = 0;
if (event.lengthComputable) {
percent = Math.ceil(event.loaded / event.total * 100);
}
$('.pb-' + fileList[cl].size).css('width', percent + '%').attr('aria-valuenow', percent);
}, false);
}
return xhr;
},
success: function (res, status) {
if (status == 'success') {
percent = 0;
$('.pb-' + fileList[cl].size).closest('.progress').remove();
try {
var jsondecode = JSON.parse(res);
$('.doc-content-div-dev').eq(cl).html(`<a href="` + requestDocumentUrl + `&id=` + jsondecode.data.file_id + `" target="_blank">` + fileList[cl].name + `</a>`);
$('.doc-main-div-dev').eq(cl).data('id', jsondecode.data.id);
} catch (e) {
$('.doc-main-div-dev').eq(cl).html('<span class="text-danger doc-content-div-dev">Fehler: ' + fileList[cl].name + ' (Dateiendung nicht erlaubt)</span>');
}
if (cl < ttl) {
uploadajax(ttl, cl + 1);
} else {
$('.doc-content-div-dev').each(function (index, value) {
$(this).removeClass('doc-content-div-dev');
});
$('.doc-main-div-dev').each(function (index, value) {
$(this).removeClass('doc-main-div-dev');
});
}
}
},
fail: function (res) {
alert('Failed');
}
})
}