From a02d96385ca7bc8f92931cb8fdc5039f854b1d5d Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Mon, 20 Nov 2017 18:29:38 -0700 Subject: [PATCH] Add punches report, check if user assigned to a shift, add report date filter, attach punches to shift in DB --- action.php | 24 ++++++++- database.mwb | Bin 8508 -> 9217 bytes database.sql | 93 +++++++++++++++++++++++++++++++++ lang/en_us.php | 12 ++++- lang/messages.php | 4 ++ lib/reports.php | 119 ++++++++++++++++++++++++++++++++++++------ pages.php | 3 ++ pages/export.php | 86 ++++++++++++++++++++---------- settings.template.php | 3 ++ static/js/export.js | 13 ++++- 10 files changed, 308 insertions(+), 49 deletions(-) create mode 100644 database.sql diff --git a/action.php b/action.php index 9599709..e697b3c 100644 --- a/action.php +++ b/action.php @@ -35,7 +35,29 @@ switch ($VARS['action']) { if ($database->has('punches', ['AND' => ['uid' => $_SESSION['uid'], 'out' => null]])) { returnToSender("already_in"); } - $database->insert('punches', ['uid' => $_SESSION['uid'], 'in' => date("Y-m-d H:i:s"), 'out' => null, 'notes' => '']); + + $shiftid = null; + if ($database->has('assigned_shifts', ['uid' => $_SESSION['uid']])) { + $minclockintime = strtotime("now + 5 minutes"); + $shifts = $database->select('shifts', ["[>]assigned_shifts" => ['shiftid' => 'shiftid']], ["shifts.shiftid", "start", "end", "days"], ["AND" =>['uid' => $_SESSION['uid'], 'start[<=]' => date("H:i:s", $minclockintime)]]); + foreach ($shifts as $shift) { + $curday = substr(date("D"), 0, 2); + if (strpos($shift['days'], $curday) === FALSE) { + continue; + } + if (strtotime($shift['end']) >= strtotime($shift['start'])) { + if (strtotime("now") >= strtotime($shift['end'])) { + continue; // shift is already over + } + } + $shiftid = $shift['shiftid']; + } + if (is_null($shiftid)) { + returnToSender("not_assigned_to_work"); + } + } + + $database->insert('punches', ['uid' => $_SESSION['uid'], 'in' => date("Y-m-d H:i:s"), 'out' => null, 'notes' => '', 'shiftid' => $shiftid]); returnToSender("punched_in"); case "punchout": if (!$database->has('punches', ['AND' => ['uid' => $_SESSION['uid'], 'out' => null]])) { diff --git a/database.mwb b/database.mwb index 2d9040ba1b24e3e31235cabbe6238334df60e148..06f6e70426ab23f72618834f6b2cac52f2ef508c 100644 GIT binary patch delta 9106 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 PYgFVgh_uPCRHFX}7Br)R literal 8508 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 "CSV text file", "ods file" => "ODS spreadsheet", "html file" => "HTML web page", - "report filtered to" => "Report filtered to {name} ({username})", + "report filtered to user" => "Report filtered to {name} ({username})", + "report filtered to start date" => "Only showing entries later than {date}", + "report filtered to end date" => "Only showing entries earlier than {date}", "all users" => "All users", "one user" => "One user", "choose user" => "Type to choose user", - "filter" => "Filter" + "filter" => "Filter", + "date range" => "Date range", + "punchid" => "Punch ID", + "shiftid" => "Shift ID", + "shiftname" => "Shift Name", + "punches" => "Punches", + "not assigned to work now" => "You are not assigned to work right now." ]); \ No newline at end of file diff --git a/lang/messages.php b/lang/messages.php index b051d5d..a65340d 100644 --- a/lang/messages.php +++ b/lang/messages.php @@ -60,5 +60,9 @@ define("MESSAGES", [ "shift_assigned" => [ "string" => "shift assigned", "type" => "success" + ], + "not_assigned_to_work" => [ + "string" => "not assigned to work now", + "type" => "danger" ] ]); diff --git a/lib/reports.php b/lib/reports.php index d70e2b8..f5f3a21 100644 --- a/lib/reports.php +++ b/lib/reports.php @@ -40,7 +40,7 @@ if (LOADED) { $user = getUserByUsername($VARS['user']); } if (isset($VARS['type']) && isset($VARS['format'])) { - generateReport($VARS['type'], $VARS['format'], $user); + generateReport($VARS['type'], $VARS['format'], $user, $VARS['startdate'], $VARS['enddate']); die(); } else { lang("invalid parameters"); @@ -90,33 +90,93 @@ function getShiftReport($user = null) { return $out; } -function getReportData($type, $user = null) { +function getPunchReport($user = null, $start = null, $end = null) { + global $database; + $where = []; + if ((bool) strtotime($start) == TRUE) { + $where["OR #start"] = [ + "in[>=]" => date("Y-m-d", strtotime($start)), + "out[>=]" => date("Y-m-d", strtotime($start)) + ]; + } + if ((bool) strtotime($end) == TRUE) { + // Make the date be the end of the day, not the start + $where["in[<=]"] = date("Y-m-d", strtotime($end)) . " 23:59:59"; + } + if ($user != null && array_key_exists('uid', $user)) { + $where["uid"] = $user['uid']; + } + if (count($where) > 1) { + $where = ["AND" => $where]; + } + $punches = $database->select( + "punches", [ + "[>]shifts" => ["shiftid" => "shiftid"] + ], [ + "punchid", "uid", "in", "out", "notes", "punches.shiftid", "shiftname" + ], $where + ); + $header = [lang("punchid", false), lang("name", false), lang("in", false), lang("out", false), lang("shiftid", false), lang("shiftname", false), lang("notes", false)]; + $out = [$header]; + $usercache = []; + for ($i = 0; $i < count($punches); $i++) { + if (!array_key_exists($punches[$i]["uid"], $usercache)) { + $usercache[$punches[$i]["uid"]] = getUserByID($punches[$i]["uid"]); + } + $out[] = [ + $punches[$i]["punchid"], + $usercache[$punches[$i]["uid"]]["name"] . " (" . $usercache[$punches[$i]["uid"]]["username"] . ")", + date(DATETIME_FORMAT, strtotime($punches[$i]['in'])), + (is_null($punches[$i]['out']) ? "" : date(DATETIME_FORMAT, strtotime($punches[$i]['out']))), + $punches[$i]['shiftid'], + $punches[$i]['shiftname'], + $punches[$i]['notes'] + ]; + } + return $out; +} + +function getReportData($type, $user = null, $start = null, $end = null) { switch ($type) { case "shifts": return getShiftReport($user); break; + case "punches": + return getPunchReport($user, $start, $end); + break; default: return [["error"]]; } } -function dataToCSV($data, $name = "report", $user = null) { +function dataToCSV($data, $name = "report", $user = null, $start = null, $end = null) { $csv = Writer::createFromString(''); $usernotice = ""; $usertitle = ""; + $datetitle = ""; if ($user != null && array_key_exists('username', $user) && array_key_exists('name', $user)) { - $usernotice = lang2("report filtered to", ["name" => $user['name'], "username" => $user['username']], false); + $usernotice = lang2("report filtered to user", ["name" => $user['name'], "username" => $user['username']], false); $usertitle = "_" . $user['username']; $csv->insertOne([$usernotice]); } + if ($start != null && (bool) strtotime($start)) { + $datenotice = lang2("report filtered to start date", ["date" => date(DATE_FORMAT, strtotime($start))], false); + $datetitle = "_" . date(DATE_FORMAT, strtotime($start)); + $csv->insertOne([$datenotice]); + } + if ($end != null && (bool) strtotime($end)) { + $datenotice = lang2("report filtered to end date", ["date" => date(DATE_FORMAT, strtotime($end))], false); + $datetitle .= ($datetitle == "" ? "_" : "-") . date(DATE_FORMAT, strtotime($end)); + $csv->insertOne([$datenotice]); + } $csv->insertAll($data); header('Content-type: text/csv'); - header('Content-Disposition: attachment; filename="' . $name . $usertitle . "_" . date("Y-m-d_Hi") . ".csv" . '"'); + header('Content-Disposition: attachment; filename="' . $name . $usertitle . $datetitle . "_" . date("Y-m-d_Hi") . ".csv" . '"'); echo $csv; die(); } -function dataToODS($data, $name = "report", $user = null) { +function dataToODS($data, $name = "report", $user = null, $start = null, $end = null) { $ods = new ods(); $styleColumn = new odsStyleTableColumn(); $styleColumn->setUseOptimalColumnWidth(true); @@ -130,13 +190,28 @@ function dataToODS($data, $name = "report", $user = null) { $usernotice = ""; $usertitle = ""; + $datetitle = ""; if ($user != null && array_key_exists('username', $user) && array_key_exists('name', $user)) { - $usernotice = lang2("report filtered to", ["name" => $user['name'], "username" => $user['username']], false); + $usernotice = lang2("report filtered to user", ["name" => $user['name'], "username" => $user['username']], false); $usertitle = "_" . $user['username']; $row = new odsTableRow(); $row->addCell(new odsTableCellString($usernotice)); $table->addRow($row); } + if ($start != null && (bool) strtotime($start)) { + $datenotice = lang2("report filtered to start date", ["date" => date(DATE_FORMAT, strtotime($start))], false); + $datetitle = "_" . date(DATE_FORMAT, strtotime($start)); + $row = new odsTableRow(); + $row->addCell(new odsTableCellString($datenotice)); + $table->addRow($row); + } + if ($end != null && (bool) strtotime($end)) { + $datenotice = lang2("report filtered to end date", ["date" => date(DATE_FORMAT, strtotime($end))], false); + $datetitle .= ($datetitle == "" ? "_" : "-") . date(DATE_FORMAT, strtotime($end)); + $row = new odsTableRow(); + $row->addCell(new odsTableCellString($datenotice)); + $table->addRow($row); + } $rowid = 0; foreach ($data as $datarow) { @@ -152,10 +227,10 @@ function dataToODS($data, $name = "report", $user = null) { $rowid++; } $ods->addTable($table); - $ods->downloadOdsFile($name . $usertitle . "_" . date("Y-m-d_Hi") . ".ods"); + $ods->downloadOdsFile($name . $usertitle . $datetitle . "_" . date("Y-m-d_Hi") . ".ods"); } -function dataToHTML($data, $name = "report", $user = null) { +function dataToHTML($data, $name = "report", $user = null, $start = null, $end = null) { global $SECURE_NONCE; // HTML exporter doesn't like null values for ($i = 0; $i < count($data); $i++) { @@ -167,16 +242,26 @@ function dataToHTML($data, $name = "report", $user = null) { } $usernotice = ""; $usertitle = ""; + $datenotice = ""; + $datetitle = ""; if ($user != null && array_key_exists('username', $user) && array_key_exists('name', $user)) { - $usernotice = "" . lang2("report filtered to", ["name" => $user['name'], "username" => $user['username']], false) . "
"; + $usernotice = "" . lang2("report filtered to user", ["name" => $user['name'], "username" => $user['username']], false) . "
"; $usertitle = "_" . $user['username']; } + if ($start != null && (bool) strtotime($start)) { + $datenotice = "" . lang2("report filtered to start date", ["date" => date(DATE_FORMAT, strtotime($start))], false) . "
"; + $datetitle = "_" . date(DATE_FORMAT, strtotime($start)); + } + if ($end != null && (bool) strtotime($end)) { + $datenotice .= "" . lang2("report filtered to end date", ["date" => date(DATE_FORMAT, strtotime($end))], false) . "
"; + $datetitle .= ($datetitle == "" ? "_" : "-") . date(DATE_FORMAT, strtotime($end)); + } header('Content-type: text/html'); $converter = new HTMLConverter(); $out = "\n" . "\n" . "\n" - . "" . $name . $usertitle . "_" . date("Y-m-d_Hi") . "\n" + . "" . $name . $usertitle . $datetitle . "_" . date("Y-m-d_Hi") . "\n" . << STYLE - . $usernotice + . $usernotice . $datenotice . $converter->convert($data); echo $out; } -function generateReport($type, $format, $user = null) { - $data = getReportData($type, $user); +function generateReport($type, $format, $user = null, $start = null, $end = null) { + $data = getReportData($type, $user, $start, $end); switch ($format) { case "ods": - dataToODS($data, $type, $user); + dataToODS($data, $type, $user, $start, $end); break; case "html": - dataToHTML($data, $type, $user); + dataToHTML($data, $type, $user, $start, $end); break; case "csv": default: - echo dataToCSV($data, $type, $user); + echo dataToCSV($data, $type, $user, $start, $end); break; } } diff --git a/pages.php b/pages.php index 7e1dca4..aceb669 100644 --- a/pages.php +++ b/pages.php @@ -56,9 +56,12 @@ define("PAGES", [ "navbar" => true, "icon" => "download", "styles" => [ + "static/css/bootstrap-datetimepicker.min.css", "static/css/easy-autocomplete.min.css" ], "scripts" => [ + "static/js/moment.min.js", + "static/js/bootstrap-datetimepicker.min.js", "static/js/jquery.easy-autocomplete.min.js", "static/js/export.js" ] diff --git a/pages/export.php b/pages/export.php index 88c4665..f9fd44c 100644 --- a/pages/export.php +++ b/pages/export.php @@ -5,41 +5,71 @@ redirectifnotloggedin(); if (!account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE")) { ?> -
+
-
- - -
-
- -
- -
-
- +
+
+
+
+
+

+
+
+ +
+
+
+
+
+
+

+
+
+ +
+
+
-
- - +
+
+
+

+
+
+
+ +
+
+ +
+
+
+
+ + + +
+
+

diff --git a/settings.template.php b/settings.template.php index d103445..84f7371 100644 --- a/settings.template.php +++ b/settings.template.php @@ -43,6 +43,9 @@ define("TIME_FORMAT", "g:i A"); // 12 hour time define("DATETIME_FORMAT", "M j Y g:i:s A"); // 12 hour time #define("DATETIME_FORMAT", "M j Y G:i:s"); // 24 hour time +// Used for reports +define("DATE_FORMAT", "M j, Y"); + // Used on the clock widget define("LONG_DATE_FORMAT", "l F j"); diff --git a/static/js/export.js b/static/js/export.js index 07d3329..2055041 100644 --- a/static/js/export.js +++ b/static/js/export.js @@ -28,4 +28,15 @@ var options = { } }; -$("#user-box").easyAutocomplete(options); \ No newline at end of file +$("#user-box").easyAutocomplete(options); + +$(function () { + $('#startdate').datetimepicker({ + format: "MMM D YYYY", + useCurrent: false + }); + $('#enddate').datetimepicker({ + format: "MMM D YYYY"/*"YYYY-M-DTH:m"*/, + useCurrent: true + }); +}); \ No newline at end of file