From c38a9919b66e0ba35a943f0c5a01cd349a32d309 Mon Sep 17 00:00:00 2001 From: Daniel Spitzer Date: Fri, 7 Feb 2025 12:27:19 +0100 Subject: [PATCH] =?UTF-8?q?Zeiterfassung=20=20*=20Feature=20Implementation?= =?UTF-8?q?=20Arbeitszeit=C3=A4nderungen=20mit=20History=20f=C3=BCr=20alle?= =?UTF-8?q?=20m=C3=B6glichen=20historischen=20Berechnungen=20und=20Auswert?= =?UTF-8?q?ung=20=20*=20neue=20Migration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Layout/default/TimerecordingEmployee/Form.php | 184 +++++++++++++++++- .../TimerecordingEmployeeController.php | 65 +++++++ ...imerecordingEmployeeWorkingHourHistory.php | 60 ++++++ ...ngEmployeeWorkingHourHistoryController.php | 131 +++++++++++++ ...cordingEmployeeWorkingHourHistoryModel.php | 128 ++++++++++++ ...ecording_employee_working_hour_history.php | 37 ++++ 6 files changed, 603 insertions(+), 2 deletions(-) create mode 100644 application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistory.php create mode 100644 application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryController.php create mode 100644 application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryModel.php create mode 100644 db/migrations/20250207063605_timerecording_employee_working_hour_history.php diff --git a/Layout/default/TimerecordingEmployee/Form.php b/Layout/default/TimerecordingEmployee/Form.php index 58e7b1d76..15c8cf7f5 100644 --- a/Layout/default/TimerecordingEmployee/Form.php +++ b/Layout/default/TimerecordingEmployee/Form.php @@ -4,6 +4,7 @@ foreach ($days as $key => $day) { $daysSelect .= ''; } $daysSelect .= ""; + ?> - \ No newline at end of file + diff --git a/application/TimerecordingEmployee/TimerecordingEmployeeController.php b/application/TimerecordingEmployee/TimerecordingEmployeeController.php index 51836ac9f..cd51e7a93 100644 --- a/application/TimerecordingEmployee/TimerecordingEmployeeController.php +++ b/application/TimerecordingEmployee/TimerecordingEmployeeController.php @@ -16,6 +16,47 @@ class TimerecordingEmployeeController extends mfBaseController } } + protected function apiAction() + { + $do = $this->request->do; + $r = $this->request; + + $data = []; + + switch ($do) { + case "saveWorkingHours": + $userid = $r->userid; + $enddate = $r->enddate; + $workinghours = $r->workingHours; + $data = []; + $data['user_id'] = $userid; + $data['enddate'] = strtotime($enddate) + 10800; + $data['workinghours'] = json_encode($workinghours); + $timerecordingemployeesworkinghoursHistory = TimerecordingEmployeeWorkingHourHistoryModel::create($data); + $timerecordingemployeesworkinghoursHistory->save(); + break; + case "deleteWorkingHours": + $id = $r->id; + $timerecordingemployeesworkinghoursHistory = new TimerecordingEmployeeWorkingHourHistory($id); + if (!$timerecordingemployeesworkinghoursHistory->id || $timerecordingemployeesworkinghoursHistory->id != $id) { + $data = ["status" => "error"]; + $this->returnJson($data); + } + $timerecordingemployeesworkinghoursHistory->delete(); + break; + default: + $data = ["status" => "error"]; + $this->returnJson($data); + } + if (!is_array($return) || !count($return)) { + $data = ["status" => "error"]; + $this->returnJson($data); + } + $data['status'] = "OK"; + $data['result'] = $return; + $this->returnJson($data); + } + protected function indexAction() { @@ -56,6 +97,8 @@ class TimerecordingEmployeeController extends mfBaseController $this->layout()->set("timerecordingemployees", $timerecordingemployees); } + $timerecordingworkinghourshistory = $this->generateWorkingHoursHistory($userid); + $this->layout()->set("timerecordingworkinghourshistory", $timerecordingworkinghourshistory); $timerecordinguser = UserModel::search(['worker_id' => $userid]); $this->layout()->set("timerecordinguser", $timerecordinguser); return $this->addAction(); @@ -219,4 +262,26 @@ class TimerecordingEmployeeController extends mfBaseController $this->redirect("TimerecordingEmployee"); } + protected function generateWorkingHoursHistory($userid) + { + $days_short = TimerecordingEmployeeWorkingHourModel::$days_short; + $TimerecordingEmployeeWorkingHourHistory = TimerecordingEmployeeWorkingHourHistoryModel::search(['user_id' => $userid]); + foreach ($TimerecordingEmployeeWorkingHourHistory as $key => $value) { + $workinghours = json_decode($value->workinghours, true); + $datetimetext = ""; + $secondcounter = ""; + foreach ($workinghours as $key2 => $data) { + $secondcounter = $secondcounter + strtotime(date("Y-m-d " . $data['end'] . ":00")) - strtotime(date("Y-m-d " . $data['start'] . ":00")); + $datetimetext .= $days_short[$data['day']] . " " . $data['start'] . " - " . $data['end'] . "
"; + $datetimetext = TimerecordingEmployeeWorkingHourModel::cleardays($datetimetext); + } + + + $result[$value->enddate]['workinghours'] = $datetimetext; + $result[$value->enddate]['workingtime'] = $secondcounter; + $result[$value->enddate]['id'] = $value->id; + } + return $result; + } + } diff --git a/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistory.php b/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistory.php new file mode 100644 index 000000000..36d7ea7ff --- /dev/null +++ b/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistory.php @@ -0,0 +1,60 @@ +$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/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryController.php b/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryController.php new file mode 100644 index 000000000..4deac35fa --- /dev/null +++ b/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryController.php @@ -0,0 +1,131 @@ +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("TimerecordingEmployeeWorkingHourHistory/Index"); + $timerecordingemployeeworkinghourhistorys = TimerecordingEmployeeWorkingHourHistoryModel::getAll(); + $this->layout()->set("timerecordingemployeeworkinghourhistorys", $timerecordingemployeeworkinghourhistorys); + + } + + protected function addAction() + { + $users=UserModel::getAll(); + $this->layout()->set("users", $users); + + $this->layout()->setTemplate("TimerecordingEmployeeWorkingHourHistory/Form"); + + } + + protected function editAction() + { + $id = $this->request->id; + + if (!is_numeric($id) || !$id) { + $this->layout()->setFlash("tt History nicht gefunden", "error"); + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + + $timerecordingemployeeworkinghourhistorys = new TimerecordingEmployeeWorkingHourHistory($id); + if ($timerecordingemployeeworkinghourhistorys->id != $id) { + $this->layout()->setFlash("tt History nicht gefunden", "error"); + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + + $this->layout()->set("timerecordingemployeeworkinghourhistorys", $timerecordingemployeeworkinghourhistorys); + 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"; + $timerecordingemployeeworkinghourhistorys = new TimerecordingEmployeeWorkingHourHistory($id); + if (!$timerecordingemployeeworkinghourhistorys->id) { + $this->layout()->setFlash("tt History nicht gefunden", "error"); + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + } else { + $mode = "add"; + } + + $data = []; + $data['user_id'] = trim($r->user_id); + $data['end'] = trim($r->end); + $data['times'] = trim($r->times); + + + if (!$data['user_id']) { + $data['user_id']=NULL; + } + if (!$data['end']) { + $data['end']=NULL; + } + if (!$data['times']) { + $data['times']=NULL; + } + + +// var_dump($_FILES); +// var_dump($upload); +// exit; + + + if ($mode == "edit") { + $timerecordingemployeeworkinghourhistorys->update($data); + + } else { + $timerecordingemployeeworkinghourhistorys = TimerecordingEmployeeWorkingHourHistoryModel::create($data); + } +// var_dump($filestore); +// exit; + $id = $timerecordingemployeeworkinghourhistorys->save(); + + if (!$id) { + $this->layout()->setFlash("tt History konnte nicht angelegt werden", "error"); + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + + if ($mode == "edit") { + $this->layout()->setFlash("tt History erfolgreich geändert", "success"); + } else if ($mode = "add") { + $this->layout()->setFlash("tt History erfolgreich angelegt", "success"); + } + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + + + protected function deleteAction() + { + $id = $this->request->id; + $timerecordingemployeeworkinghourhistorys = new TimerecordingEmployeeWorkingHourHistory($id); + if (!$timerecordingemployeeworkinghourhistorys->id || $timerecordingemployeeworkinghourhistorys->id != $id) { + $this->layout()->setFlash("tt History nicht gefunden.", "error"); + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + + $timerecordingemployeeworkinghourhistorys->delete(); + $this->redirect("TimerecordingEmployeeWorkingHourHistory"); + } + +} diff --git a/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryModel.php b/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryModel.php new file mode 100644 index 000000000..23eff1dba --- /dev/null +++ b/application/TimerecordingEmployeeWorkingHourHistory/TimerecordingEmployeeWorkingHourHistoryModel.php @@ -0,0 +1,128 @@ + $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("TimerecordingEmployeeWorkingHourHistory", "*", "id=$id LIMIT 1"); + if ($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new TimerecordingEmployeeWorkingHourHistory($data); + } + return $item; + } + + + public static function getAll() + { + $items = []; + + $db = FronkDB::singleton(); + + $res = $db->select("TimerecordingEmployeeWorkingHourHistory", "*", "1=1"); + if ($db->num_rows($res)) { + while ($data = $db->fetch_object($res)) { + $items[] = new TimerecordingEmployeeWorkingHourHistory($data); + } + } + return $items; + + } + + public static function getFirst() + { + $db = FronkDB::singleton(); + + $where = self::getSqlFilter($filter); + $res = $db->select("TimerecordingEmployeeWorkingHourHistory", "*", "$where "); + if ($db->num_rows($res)) { + $data = $db->fetch_object($res); + $item = new TimerecordingEmployeeWorkingHourHistory($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("TimerecordingEmployeeWorkingHourHistory", "*", "$where ORDER by enddate DESC"); + if ($db->num_rows($res)) { + while ($data = $db->fetch_object($res)) { + $items[] = new TimerecordingEmployeeWorkingHourHistory($data); + } + } + return $items; + } + + private static function getSqlFilter($filter) + { + $where = "1=1 "; + + //var_dump($filter);exit; + if (array_key_exists("user_id", $filter)) { + $userid = $filter['user_id']; + if (is_numeric($userid)) { + $where .= " AND user_id=$userid"; + } + } + + //var_dump($filter, $where);exit; + return $where; + } + +} diff --git a/db/migrations/20250207063605_timerecording_employee_working_hour_history.php b/db/migrations/20250207063605_timerecording_employee_working_hour_history.php new file mode 100644 index 000000000..84c915de5 --- /dev/null +++ b/db/migrations/20250207063605_timerecording_employee_working_hour_history.php @@ -0,0 +1,37 @@ +getEnvironment() == "thetool") { + $table = $this->table("TimerecordingEmployeeWorkingHourHistory", ["signed" => true]); + $table->addColumn("user_id", "integer", ["null" => false]); + $table->addColumn("enddate", "integer", ["null" => false, "limit" => 64]); + $table->addColumn("workinghours", "string", ["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("TimerecordingEmployeeWorkingHourHistory")->drop()->save(); + } + + if($this->getEnvironment() == "addressdb") { + + } + } +}