From 7d176779c9eb2cd4aa43c34b93bfb89432ce265d Mon Sep 17 00:00:00 2001 From: Daniel Spitzer Date: Mon, 10 Mar 2025 08:04:56 +0100 Subject: [PATCH] =?UTF-8?q?Zeiterfassung=20neues=20Feature:=20Features=20f?= =?UTF-8?q?=C3=BCr=20Project=207832:=20*=20Das=20Pickerldatum=20Zusatzfeld?= =?UTF-8?q?=20*=20Auftrennen=20PKW=20und=20Anh=C3=A4nger=20*=20Dokumente?= =?UTF-8?q?=20Upload=20*=20Standardsortierung=20*=20Ausgeschieden=20Flag?= =?UTF-8?q?=20mit=20Datum=20*=20zus=C3=A4tzliche=20migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Layout/default/TimerecordingCar/Detail.php | 192 ++++--- Layout/default/TimerecordingCar/Form.php | 325 ++++++++---- Layout/default/TimerecordingCar/Index.php | 469 +++++++++++++++--- .../TimerecordingCarController.php | 128 ++++- .../TimerecordingCarModel.php | 12 + .../TimerecordingCarDocuments.php | 61 +++ .../TimerecordingCarDocumentsController.php | 145 ++++++ .../TimerecordingCarDocumentsModel.php | 153 ++++++ ...0308144915_timerecording_car_documents.php | 40 ++ public/assets/css/datatables-std.css | 8 + public/css/pages/TimerecordingCar/Form.css | 88 ++++ public/js/pages/TimerecordingCar/Form.js | 201 ++++++++ 12 files changed, 1587 insertions(+), 235 deletions(-) create mode 100644 application/TimerecordingCarDocuments/TimerecordingCarDocuments.php create mode 100644 application/TimerecordingCarDocuments/TimerecordingCarDocumentsController.php create mode 100644 application/TimerecordingCarDocuments/TimerecordingCarDocumentsModel.php create mode 100644 db/migrations/20250308144915_timerecording_car_documents.php create mode 100644 public/css/pages/TimerecordingCar/Form.css create mode 100644 public/js/pages/TimerecordingCar/Form.js diff --git a/Layout/default/TimerecordingCar/Detail.php b/Layout/default/TimerecordingCar/Detail.php index 1c147c8ee..8e8a5bba6 100644 --- a/Layout/default/TimerecordingCar/Detail.php +++ b/Layout/default/TimerecordingCar/Detail.php @@ -1,6 +1,10 @@ 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)); if ($firstApproval < time()) { $firstApproval = strtotime(date("Y-$initialApprovalMonth-01", time())); @@ -9,9 +13,13 @@ if ($firstApproval < time()) { } } $approval = date("m/Y", $firstApproval); +$cartypes = TimerecordingCarModel::$carTypes; + ?> +
@@ -39,88 +57,395 @@
- - - - - - - - - - - - - - - - - - - - - - - - - - - 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); + + +
+
+
KennzeichenFahrzeugverwalterMarkeModel/TypErstzulassssung$57aFahrtenbuchKilometerstand
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + 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); + + ?> + + + + + + + + + + + + + + +
KennzeichenFahrzeugverwalterMarkeModel/TypErstzulassung$57aFahrtenbuchKM-StandAktiv
+ $timerecordingcar->id]) ?>"> number_plate ?> + user_id) ? $timerecordingcar->user->name : "-" ?>brand ?>model ?>">initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?>">initial_approval) ? $approval : "-" ?>timerecording) ? "Ja" : "Nein" ?>mileage_now) ? number_format($timerecordingcar->mileage_now, 0, ',', '.') . " KM" : "-" ?> + retired) ? "Nein" : "Ja" ?> + $timerecordingcar->id]) ?>"> + $timerecordingcar->id]) ?>" + onclick="if(!confirm('Fahrzeug wirklich löschen?')) return false;" + class="text-danger" + title="Löschen"> +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + type == 1) { + 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); + + ?> + + + + + + + + + + + + + + +
KennzeichenFahrzeugverwalterMarkeModel/TypErstzulassung$57aFahrtenbuchKM-StandAktiv
+ $timerecordingcar->id]) ?>"> number_plate ?> + user_id) ? $timerecordingcar->user->name : "-" ?>brand ?>model ?>">initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?>">initial_approval) ? $approval : "-" ?>timerecording) ? "Ja" : "Nein" ?>mileage_now) ? number_format($timerecordingcar->mileage_now, 0, ',', '.') . " KM" : "-" ?> + retired) ? "Nein" : "Ja" ?> + $timerecordingcar->id]) ?>"> + $timerecordingcar->id]) ?>" + onclick="if(!confirm('Fahrzeug wirklich löschen?')) return false;" + class="text-danger" + title="Löschen"> +
+
+ +

- ?> - - - $timerecordingcar->id]) ?>"> number_plate ?> - - user_id) ? $timerecordingcar->user->name : "-" ?> - brand ?> - model ?> - initial_approval) ? date("m/Y", $timerecordingcar->initial_approval) : "-" ?> - initial_approval) ? $approval : "-" ?> - timerecording) ? "Ja" : "Nein" ?> - mileage_now) ? number_format($timerecordingcar->mileage_now, 0, ',', '.')." KM" : "-" ?> - - - $timerecordingcar->id]) ?>"> - $timerecordingcar->id]) ?>" - onclick="if(!confirm('Fahrzeug wirklich löschen?')) return false;" class="text-danger" - title="Löschen"> - - - - - - + - \ No newline at end of file diff --git a/application/TimerecordingCar/TimerecordingCarController.php b/application/TimerecordingCar/TimerecordingCarController.php index 84277f341..fec5c0f06 100644 --- a/application/TimerecordingCar/TimerecordingCarController.php +++ b/application/TimerecordingCar/TimerecordingCarController.php @@ -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() { @@ -28,6 +56,10 @@ class TimerecordingCarController extends mfBaseController protected function detailAction() { $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"); $timerecordingcar = TimerecordingCarModel::getOne($timerecordingcarid); $this->layout()->set("timerecordingcar", $timerecordingcar); @@ -54,16 +86,44 @@ class TimerecordingCarController extends mfBaseController } $timerecordingcars = new TimerecordingCar($id); + $mimetypes = TimerecordingCarDocumentsModel::$mimetypes; + $timerecordingcarDokuments = TimerecordingCarDocumentsModel::search(["timerecordingCar_id" => $id]); if ($timerecordingcars->id != $id) { $this->layout()->setFlash("Auto nicht gefunden", "error"); $this->redirect("TimerecordingCar"); } - + $this->layout()->set("mimetypes", $mimetypes); + $this->layout()->set("timerecordingcarDokuments", $timerecordingcarDokuments); $this->layout()->set("timerecordingcars", $timerecordingcars); 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() { $r = $this->request; @@ -83,12 +143,15 @@ class TimerecordingCarController extends mfBaseController $data = []; $data['number_plate'] = trim($r->number_plate); $data['user_id'] = trim($r->user_id); + $data['type'] = trim($r->type); $data['brand'] = trim($r->brand); $data['model'] = trim($r->model); $data['mileage'] = trim($r->mileage); $data['initial_approval'] = strtotime($r->initial_approval); $data['timerecording'] = $r->timerecording; $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'] == "-") { @@ -97,6 +160,9 @@ class TimerecordingCarController extends mfBaseController if (!$data['initial_approval']) { $data['initial_approval'] = null; } + if (!$data['override_approval']) { + $data['override_approval'] = null; + } if (!$data['timerecording']) { $data['timerecording'] = 0; @@ -176,4 +242,64 @@ class TimerecordingCarController extends mfBaseController $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(); + } + } diff --git a/application/TimerecordingCar/TimerecordingCarModel.php b/application/TimerecordingCar/TimerecordingCarModel.php index d77f3fef6..521ad16fa 100644 --- a/application/TimerecordingCar/TimerecordingCarModel.php +++ b/application/TimerecordingCar/TimerecordingCarModel.php @@ -3,6 +3,7 @@ class TimerecordingCarModel { private $user_id; + private $type; private $number_plate; private $brand; private $model; @@ -10,8 +11,19 @@ class TimerecordingCarModel private $mileage_now; private $mileage_timestamp; private $initial_approval; + private $override_approval; private $first_approval; private $timerecording; + private $retired; + private $retired_date; + private $edit_by; + + + public static $carTypes = [ + "1" => "PKW", + "2" => "Anhänger" + ]; + public static function find($data) diff --git a/application/TimerecordingCarDocuments/TimerecordingCarDocuments.php b/application/TimerecordingCarDocuments/TimerecordingCarDocuments.php new file mode 100644 index 000000000..222bd7ab7 --- /dev/null +++ b/application/TimerecordingCarDocuments/TimerecordingCarDocuments.php @@ -0,0 +1,61 @@ +$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; +} + +} \ No newline at end of file diff --git a/application/TimerecordingCarDocuments/TimerecordingCarDocumentsController.php b/application/TimerecordingCarDocuments/TimerecordingCarDocumentsController.php new file mode 100644 index 000000000..3904c70ad --- /dev/null +++ b/application/TimerecordingCarDocuments/TimerecordingCarDocumentsController.php @@ -0,0 +1,145 @@ +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"); + } + +} diff --git a/application/TimerecordingCarDocuments/TimerecordingCarDocumentsModel.php b/application/TimerecordingCarDocuments/TimerecordingCarDocumentsModel.php new file mode 100644 index 000000000..17e1f95f7 --- /dev/null +++ b/application/TimerecordingCarDocuments/TimerecordingCarDocumentsModel.php @@ -0,0 +1,153 @@ + '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; + } + +} diff --git a/db/migrations/20250308144915_timerecording_car_documents.php b/db/migrations/20250308144915_timerecording_car_documents.php new file mode 100644 index 000000000..c4d4f0032 --- /dev/null +++ b/db/migrations/20250308144915_timerecording_car_documents.php @@ -0,0 +1,40 @@ +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") { + + } + } +} diff --git a/public/assets/css/datatables-std.css b/public/assets/css/datatables-std.css index 32b8b27e4..7f7d73dee 100644 --- a/public/assets/css/datatables-std.css +++ b/public/assets/css/datatables-std.css @@ -6,6 +6,14 @@ height: unset; } +#filterrow2 input { + width: 100%; + padding: 3px; + box-sizing: border-box; + display: table-header-group; + height: unset; +} + .dataTables_wrapper .dataTables_filter { float: left; text-align: left; diff --git a/public/css/pages/TimerecordingCar/Form.css b/public/css/pages/TimerecordingCar/Form.css new file mode 100644 index 000000000..3cdbb0c32 --- /dev/null +++ b/public/css/pages/TimerecordingCar/Form.css @@ -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; +} diff --git a/public/js/pages/TimerecordingCar/Form.js b/public/js/pages/TimerecordingCar/Form.js new file mode 100644 index 000000000..eab8186f3 --- /dev/null +++ b/public/js/pages/TimerecordingCar/Form.js @@ -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 = " $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('

' + fileList[i].name + '

'); + $('.attachment-div').append(`
+
+(` + formattedDate + `)` + formatFileSize(fileList[i].size) + `
+
+
+
+`); + 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(`` + fileList[cl].name + ``); + $('.doc-main-div-dev').eq(cl).data('id', jsondecode.data.id); + } catch (e) { + $('.doc-main-div-dev').eq(cl).html('Fehler: ' + fileList[cl].name + ' (Dateiendung nicht erlaubt)'); + + } + + 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'); + } + }) +} \ No newline at end of file