From 30db1512f56e46735c5212f80c56811c96567c5e Mon Sep 17 00:00:00 2001 From: Skylar Ittner Date: Tue, 28 Nov 2017 23:07:12 -0700 Subject: [PATCH] Add timecard editing (close #2) --- action.php | 67 +++++++++++++++++++++++- lang/en_us.php | 12 +++++ lang/messages.php | 26 +++++++++- lib/getpunchtable.php | 52 ++++++++++++++----- pages.php | 14 +++++ pages/editpunch.php | 114 +++++++++++++++++++++++++++++++++++++++++ pages/export.php | 2 +- pages/punches.php | 11 +++- static/js/editpunch.js | 37 +++++++++++++ static/js/punches.js | 10 ++-- 10 files changed, 324 insertions(+), 21 deletions(-) create mode 100644 pages/editpunch.php create mode 100644 static/js/editpunch.js diff --git a/action.php b/action.php index 0788b18..dcea430 100644 --- a/action.php +++ b/action.php @@ -74,6 +74,71 @@ switch ($VARS['action']) { $out = ["status" => "OK", "in" => $in]; header('Content-Type: application/json'); exit(json_encode($out)); + case "editpunch": + require_once __DIR__ . "/lib/userinfo.php"; + if (user_exists($VARS['user'])) { + $uid = getUserByUsername($VARS['user'])['uid']; + } else { + returnToSender("invalid_user"); + } + + $in = strtotime($VARS['in']); + $out = strtotime($VARS['out']); + if ($in === false) { + returnToSender("invalid_datetime"); + } + if ($out === false) { + returnToSender("invalid_datetime"); + } + if ($out < $in) { + returnToSender("in_before_out"); + } + + if ( + account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN") || ( + account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE") && isManagerOf($_SESSION['uid'], $uid) + ) || ( + account_has_permission($_SESSION['username'], "QWIKCLOCK_EDITSELF") && $_SESSION['uid'] == $uid + ) + ) { + $data = [ + "uid" => $uid, + "in" => date('Y-m-d H:i:s', $in), + "out" => date('Y-m-d H:i:s', $out), + "notes" => $VARS['notes'] + ]; + if ($database->has("punches", ["punchid" => $VARS['punchid']])) { + $database->update("punches", $data, ["punchid" => $VARS['punchid']]); + } else { + $database->insert("punches", $data); + } + returnToSender("punch_saved"); + } else { + returnToSender("no_permission"); + } + case "deletepunch": + require_once __DIR__ . "/lib/userinfo.php"; + + if (!$database->has("punches", ["punchid" => $VARS['punchid']])) { + returnToSender("invalid_parameters"); + } + + $pid = $VARS['punchid']; + $uid = $database->get("punches", "uid", ["punchid" => $pid]); + + if ( + account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN") || ( + account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE") && isManagerOf($_SESSION['uid'], $uid) + ) || ( + account_has_permission($_SESSION['username'], "QWIKCLOCK_EDITSELF") && $_SESSION['uid'] == $uid + ) + ) { + + $database->delete("punches", ["punchid" => $VARS['punchid']]); + returnToSender("punch_deleted"); + } else { + returnToSender("no_permission"); + } case "editshift": if (account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN")) { $valid_daycodes = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]; @@ -134,7 +199,7 @@ switch ($VARS['action']) { returnToSender("no_permission"); } case "assignshift": - if (!account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE")) { + if (!account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE") && !account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN")) { returnToSender("no_permission"); } if (!$database->has('shifts', ['shiftid' => $VARS['shift']])) { diff --git a/lang/en_us.php b/lang/en_us.php index 047be84..1ae5a87 100644 --- a/lang/en_us.php +++ b/lang/en_us.php @@ -45,6 +45,7 @@ define("STRINGS", [ "this week" => "This Week", "x on the clock" => "{time} on the clock", "x punches" => "{count} punches", + "1 punch" => "1 punch", "history" => "History", "shifts" => "Shifts", "show all punches" => "Show other users", @@ -102,4 +103,15 @@ define("STRINGS", [ "punches" => "Punches", "not assigned to work now" => "You are not assigned to work right now.", "not a managed user" => "Not a managed user", + "actions" => "Actions", + "edit" => "Edit", + "invalid user" => "That user does not exist.", + "no editself permission" => "You don't have permission to edit your own punches.", + "edit punch" => "Edit Punch", + "new punch" => "New Punch", + "user" => "User", + "in must be before out" => "The in time must be before the out time.", + "punch saved" => "Punch saved.", + "invalid datetime" => "Could not understand the dates/times given. Please use a standard format, such as \"January 1, 2018 3:30pm\".", + "punch deleted" => "Punch deleted.", ]); \ No newline at end of file diff --git a/lang/messages.php b/lang/messages.php index 5c24bc3..417cac1 100644 --- a/lang/messages.php +++ b/lang/messages.php @@ -76,5 +76,29 @@ define("MESSAGES", [ "not_assigned_to_work" => [ "string" => "not assigned to work now", "type" => "danger" - ] + ], + "invalid_user" => [ + "string" => "invalid user", + "type" => "danger" + ], + "no_editself_permission" => [ + "string" => "no editself permission", + "type" => "danger" + ], + "in_before_out" => [ + "string" => "in must be before out", + "type" => "danger" + ], + "punch_saved" => [ + "string" => "punch saved", + "type" => "success" + ], + "invalid_datetime" => [ + "string" => "invalid datetime", + "type" => "danger" + ], + "punch_deleted" => [ + "string" => "punch deleted", + "type" => "success" + ], ]); diff --git a/lib/getpunchtable.php b/lib/getpunchtable.php index 9d73d33..e2326b1 100644 --- a/lib/getpunchtable.php +++ b/lib/getpunchtable.php @@ -9,12 +9,18 @@ header("Content-Type: application/json"); require_once __DIR__ . "/login.php"; require_once __DIR__ . "/userinfo.php"; -$showmanaged = ($VARS['show_all'] == 1 && account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE")); +$account_is_admin = account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN"); +$showmanaged = ($VARS['show_all'] == 1 && (account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE") || $account_is_admin)); $managed_uids = []; +$managed_uids[] = $_SESSION['uid']; if ($showmanaged) { - $managed_uids = getManagedUIDs($_SESSION['uid']); + if ($account_is_admin) { + $managed_uids = false; + } else { + $managed_uids = getManagedUIDs($_SESSION['uid']); + $managed_uids[] = $_SESSION['uid']; + } } -$managed_uids[] = $_SESSION['uid']; $out = []; @@ -30,13 +36,13 @@ if ($VARS['order'][0]['dir'] == 'asc') { $sortby = "ASC"; } switch ($VARS['order'][0]['column']) { - case 1: + case 2: $order = ["uid" => $sortby]; break; - case 2: + case 3: $order = ["in" => $sortby]; break; - case 3: + case 4: $order = ["out" => $sortby]; break; } @@ -53,10 +59,16 @@ if (!is_empty($VARS['search']['value'])) { "uid" => $managed_uids ] ]; + if ($managed_uids !== false) { + $where["AND"]["uid"] = $managed_uids; + } $where = $wherenolimit; $where["LIMIT"] = [$VARS['start'], $VARS['length']]; } else { - $where = ["uid" => $managed_uids, "LIMIT" => [$VARS['start'], $VARS['length']]]; + $where = ["LIMIT" => [$VARS['start'], $VARS['length']]]; + if ($managed_uids !== false) { + $where["uid"] = $managed_uids; + } } if (!is_null($order)) { @@ -65,6 +77,7 @@ if (!is_null($order)) { $punches = $database->select('punches', [ + 'punchid', 'uid', 'in', 'out', @@ -73,21 +86,34 @@ $punches = $database->select('punches', [ $usercache = []; +$editself = account_has_permission($_SESSION['username'], "QWIKCLOCK_EDITSELF"); + for ($i = 0; $i < count($punches); $i++) { // Get user info if (!isset($usercache[$punches[$i]['uid']])) { $usercache[$punches[$i]['uid']] = getUserByID($punches[$i]['uid']); } - + $punches[$i][0] = ""; - $punches[$i][1] = $usercache[$punches[$i]['uid']]['name']; - $punches[$i][2] = date(DATETIME_FORMAT, strtotime($punches[$i]['in'])); + if ($_SESSION['uid'] == $punches[$i]['uid']) { + if ($editself) { + $punches[$i][1] = ' ' . lang("edit", false) . ''; + } else { + $punches[$i][1] = ""; + } + } else if ($showmanaged) { + $punches[$i][1] = ' ' . lang("edit", false) . ''; + } else { + $punches[$i][1] = ""; + } + $punches[$i][2] = $usercache[$punches[$i]['uid']]['name']; + $punches[$i][3] = date(DATETIME_FORMAT, strtotime($punches[$i]['in'])); if (is_null($punches[$i]['out'])) { - $punches[$i][3] = lang("na", false); + $punches[$i][4] = lang("na", false); } else { - $punches[$i][3] = date(DATETIME_FORMAT, strtotime($punches[$i]['out'])); + $punches[$i][4] = date(DATETIME_FORMAT, strtotime($punches[$i]['out'])); } - $punches[$i][4] = $punches[$i]['notes']; + $punches[$i][5] = $punches[$i]['notes']; } $out['status'] = "OK"; diff --git a/pages.php b/pages.php index aceb669..f4c3809 100644 --- a/pages.php +++ b/pages.php @@ -51,6 +51,20 @@ define("PAGES", [ "static/js/addshift.js" ] ], + "editpunch" => [ + "title" => "edit punch", + "navbar" => false, + "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/editpunch.js" + ] + ], "export" => [ "title" => "report export", "navbar" => true, diff --git a/pages/editpunch.php b/pages/editpunch.php new file mode 100644 index 0000000..991506d --- /dev/null +++ b/pages/editpunch.php @@ -0,0 +1,114 @@ + "", + "uid" => "", + "in" => "", + "out" => "", + "notes" => "", + "username" => "" +]; + +$editing = false; +$ownpunch = false; +if (isset($VARS['pid']) && $database->has('punches', ['punchid' => $VARS['pid']])) { + $editing = true; + $data = $database->get('punches', [ + "punchid", + "uid", + "in", + "out", + "notes", + "shiftid" + ], [ + 'punchid' => $VARS['pid'] + ]); + if ($data["uid"] == $_SESSION['uid']) { + $ownpunch = true; + } +} + +if ($ownpunch) { + if (!account_has_permission($_SESSION['username'], "QWIKCLOCK_EDITSELF")) { + header("Location: app.php?page=punches&msg=no_editself_permission"); + die(); + } +} else { + if (account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN")) { + // All good + } else if (account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE")) { + if ($editing && !isManagerOf($_SESSION['uid'], $data['uid'])) { + header("Location: app.php?page=punches&msg=you_arent_my_supervisor"); + die(); + } + } else { + header("Location: app.php?page=punches&msg=no_permission"); + die(); + } +} +if ($data['uid'] != "") { + $data['username'] = getUserByID($data['uid'])['username']; +} +?> + +
+
+
+

+ + + + + +

+
+
+
+
+
+ + +
+
+
+
+ + " /> +
+
+
+
+ + " /> +
+
+
+
+ + +
+
+
+
+ + + + + + +
+
\ No newline at end of file diff --git a/pages/export.php b/pages/export.php index 789beb8..75cc6dc 100644 --- a/pages/export.php +++ b/pages/export.php @@ -3,7 +3,7 @@ require_once __DIR__ . '/../required.php'; redirectifnotloggedin(); -if (!account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE")) { +if (!account_has_permission($_SESSION['username'], "QWIKCLOCK_MANAGE") && !account_has_permission($_SESSION['username'], "QWIKCLOCK_ADMIN")) { ?>
select('punches', ['in', 'out'], ['AND' => ['uid' => $_SESSION['uid'], 'in[>]' => $weekstart]]); +$weekend = sqldatetime(getstartofweek(WEEK_START) + 604800); +$punches = $database->select('punches', ['in', 'out'], ['AND' => ['uid' => $_SESSION['uid'], 'in[>]' => $weekstart, 'in[<]' => $weekend]]); $punchtimes = []; foreach ($punches as $p) { $punchtimes[] = [$p['in'], $p['out']]; @@ -34,7 +35,11 @@ $totalpunches = count($punches);

$totalpunches]); + if ($totalpunches != 1) { + lang2("x punches", ["count" => $totalpunches]); + } else { + lang("1 punch"); + } ?>

@@ -49,6 +54,7 @@ $totalpunches = count($punches); + @@ -61,6 +67,7 @@ $totalpunches = count($punches); + diff --git a/static/js/editpunch.js b/static/js/editpunch.js new file mode 100644 index 0000000..226a358 --- /dev/null +++ b/static/js/editpunch.js @@ -0,0 +1,37 @@ +var options = { + url: "action.php", + ajaxSettings: { + dataType: "json", + method: "GET", + data: { + action: "autocomplete_user" + } + }, + preparePostData: function (data) { + data.q = $("#user").val(); + return data; + }, + getValue: function (element) { + return element.username; + }, + template: { + type: "custom", + method: function (value, item) { + return item.name + " " + item.username + ""; + } + } +}; + +$("#user").easyAutocomplete(options); + + +$(function () { + $('#in').datetimepicker({ + format: "ddd MMMM D YYYY h:mm a", + useCurrent: false + }); + $('#out').datetimepicker({ + format: "ddd MMMM D YYYY h:mm a", + useCurrent: false + }); +}); \ No newline at end of file diff --git a/static/js/punches.js b/static/js/punches.js index b2ccd0c..40b4ed5 100644 --- a/static/js/punches.js +++ b/static/js/punches.js @@ -20,12 +20,16 @@ var punchtable = $('#punchtable').DataTable({ orderable: false }, { - targets: 4, + targets: 1, orderable: false - } + }, + { + targets: 5, + orderable: false + }, ], order: [ - [2, 'desc'] + [3, 'desc'] ], serverSide: true, ajax: {