Add timecard editing (close #2)
This commit is contained in:
parent
0a2ced319a
commit
30db1512f5
67
action.php
67
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']])) {
|
||||
|
@ -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.",
|
||||
]);
|
@ -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"
|
||||
],
|
||||
]);
|
||||
|
@ -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 = [];
|
||||
if ($showmanaged) {
|
||||
$managed_uids = getManagedUIDs($_SESSION['uid']);
|
||||
}
|
||||
$managed_uids[] = $_SESSION['uid'];
|
||||
if ($showmanaged) {
|
||||
if ($account_is_admin) {
|
||||
$managed_uids = false;
|
||||
} else {
|
||||
$managed_uids = getManagedUIDs($_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,6 +86,8 @@ $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']])) {
|
||||
@ -80,14 +95,25 @@ for ($i = 0; $i < count($punches); $i++) {
|
||||
}
|
||||
|
||||
$punches[$i][0] = "";
|
||||
$punches[$i][1] = $usercache[$punches[$i]['uid']]['name'];
|
||||
$punches[$i][2] = date(DATETIME_FORMAT, strtotime($punches[$i]['in']));
|
||||
if (is_null($punches[$i]['out'])) {
|
||||
$punches[$i][3] = lang("na", false);
|
||||
if ($_SESSION['uid'] == $punches[$i]['uid']) {
|
||||
if ($editself) {
|
||||
$punches[$i][1] = '<a class="btn btn-blue btn-xs" href="app.php?page=editpunch&pid=' . $punches[$i]['punchid'] . '"><i class="fa fa-pencil-square-o"></i> ' . lang("edit", false) . '</a>';
|
||||
} else {
|
||||
$punches[$i][3] = date(DATETIME_FORMAT, strtotime($punches[$i]['out']));
|
||||
$punches[$i][1] = "";
|
||||
}
|
||||
$punches[$i][4] = $punches[$i]['notes'];
|
||||
} else if ($showmanaged) {
|
||||
$punches[$i][1] = '<a class="btn btn-blue btn-xs" href="app.php?page=editpunch&pid=' . $punches[$i]['punchid'] . '"><i class="fa fa-pencil-square-o"></i> ' . lang("edit", false) . '</a>';
|
||||
} 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][4] = lang("na", false);
|
||||
} else {
|
||||
$punches[$i][4] = date(DATETIME_FORMAT, strtotime($punches[$i]['out']));
|
||||
}
|
||||
$punches[$i][5] = $punches[$i]['notes'];
|
||||
}
|
||||
|
||||
$out['status'] = "OK";
|
||||
|
14
pages.php
14
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,
|
||||
|
114
pages/editpunch.php
Normal file
114
pages/editpunch.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/../required.php';
|
||||
require_once __DIR__ . '/../lib/login.php';
|
||||
require_once __DIR__ . '/../lib/userinfo.php';
|
||||
|
||||
redirectifnotloggedin();
|
||||
|
||||
$data = [
|
||||
"punchid" => "",
|
||||
"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'];
|
||||
}
|
||||
?>
|
||||
|
||||
<form role="form" action="action.php" method="POST">
|
||||
<div class="panel panel-blue">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">
|
||||
<?php if ($editing) { ?>
|
||||
<i class="fa fa-calendar-o"></i> <?php lang("edit punch"); ?>
|
||||
<?php } else { ?>
|
||||
<i class="fa fa-calendar-plus-o"></i> <?php lang("new punch"); ?>
|
||||
<?php } ?>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6 col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="user"><i class="fa fa-user"></i> <?php lang("user"); ?></label>
|
||||
<input type="text" class="form-control" name="user" id="user" required="required" value="<?php echo $data['username']; ?>" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="in"><i class="fa fa-play"></i> <?php lang("in"); ?></label>
|
||||
<input type="text" class="form-control" name="in" id="in" required="required" value="<?php echo is_empty($data['in']) ? "" : date("D F j Y g:i a", strtotime($data['in'])); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-4">
|
||||
<div class="form-group">
|
||||
<label for="out"><i class="fa fa-stop"></i> <?php lang("out"); ?></label>
|
||||
<input type="text" class="form-control" name="out" id="out" required="required" value="<?php echo is_empty($data['out']) ? "" : date("D F j Y g:i a", strtotime($data['out'])); ?>" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="notes"><i class="fa fa-sticky-note-o"></i> <?php lang("notes"); ?></label>
|
||||
<textarea class="form-control" name="notes" maxlength="1000"><?php echo htmlspecialchars($data['notes']); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="punchid" value="<?php echo $data['punchid']; ?>" />
|
||||
<input type="hidden" name="action" value="editpunch" />
|
||||
<input type="hidden" name="source" value="punches" />
|
||||
|
||||
<div class="panel-footer">
|
||||
<button type="submit" class="btn btn-success"><i class="fa fa-floppy-o"></i> <?php lang("save"); ?></button>
|
||||
<?php
|
||||
if ($editing) {
|
||||
?>
|
||||
<a href="action.php?action=deletepunch&source=punches&punchid=<?php echo $data['punchid']; ?>" class="btn btn-danger btn-xs pull-right mgn-top-8px"><i class="fa fa-times"></i> <?php lang('delete'); ?></a>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
@ -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")) {
|
||||
?>
|
||||
<div class="alert alert-danger"><?php lang("missing permission") ?></div>
|
||||
<?php
|
||||
|
@ -6,7 +6,8 @@ redirectifnotloggedin();
|
||||
|
||||
require_once __DIR__ . "/../lib/dates.php";
|
||||
$weekstart = sqldatetime(getstartofweek(WEEK_START));
|
||||
$punches = $database->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);
|
||||
<div class="panel-body">
|
||||
<h4>
|
||||
<?php
|
||||
if ($totalpunches != 1) {
|
||||
lang2("x punches", ["count" => $totalpunches]);
|
||||
} else {
|
||||
lang("1 punch");
|
||||
}
|
||||
?>
|
||||
</h4>
|
||||
</div>
|
||||
@ -49,6 +54,7 @@ $totalpunches = count($punches);
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-priority="0"></th>
|
||||
<th data-priority="1"><?php lang('actions'); ?></th>
|
||||
<th data-priority="2"><i class="fa fa-fw fa-user hidden-xs"></i> <?php lang('name'); ?></th>
|
||||
<th data-priority="1"><i class="fa fa-fw fa-play hidden-xs"></i> <?php lang('in'); ?></th>
|
||||
<th data-priority="1"><i class="fa fa-fw fa-stop hidden-xs"></i> <?php lang('out'); ?></th>
|
||||
@ -61,6 +67,7 @@ $totalpunches = count($punches);
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th data-priority="0"></th>
|
||||
<th data-priority="1"><?php lang('actions'); ?></th>
|
||||
<th data-priority="2"><i class="fa fa-fw fa-user hidden-xs"></i> <?php lang('name'); ?></th>
|
||||
<th data-priority="1"><i class="fa fa-fw fa-play hidden-xs"></i> <?php lang('in'); ?></th>
|
||||
<th data-priority="1"><i class="fa fa-fw fa-stop hidden-xs"></i> <?php lang('out'); ?></th>
|
||||
|
37
static/js/editpunch.js
Normal file
37
static/js/editpunch.js
Normal file
@ -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 + " <i class=\"small\">" + item.username + "</i>";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$("#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
|
||||
});
|
||||
});
|
@ -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: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user