I just finished coding up a quick class and script, only took me a few hours. While working from home I was looking for something easy that will log my hours just like a punch in and punch out card, but online so that my boss can see while he is away at the same time. After searching the web to no avail I could not find a simple lightweight timesheet app. So I decided to create my own, and I’m releasing the code for free under the AGPLv3 license. Anyways, so it’s two main files -> the class, and the actual script. It does not rely on a MySql database all punch in’s and punch out’s are saved to a text file. It makes use of the awesome new Twitter Bootstrap and of course jQuery. It’s light weight and sufficient and get’s the job done. It can also calculate the pay for any given pay period that the user specifies. You can download the code below and view screenshots.
Download SimpleTimesheet_v1.0.0
License: AGPLv3
Here is the code for the SimpleTimesheet.class.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | <?php class SimpleTimesheet { private $database; function __construct() { $this->database = "database.txt"; } function get_database() { $db = $this->database; return $db; } function new_punch($date) { $data = $date."#"; $database = fopen($this->get_database(), 'a') or die("SimpleTimesheet could not open database"); fwrite($database, $data); fclose($database); } function get_punches() { $database = fopen($this->get_database(), 'r'); $size = filesize($this->get_database()); if($size==0){ $size=10; } $punches = fread($database, $size); fclose($database); $punches = explode("#", $punches); for($i=0;$i<count($punches);$i++){ $punches[$i] = $this->punch_to_array($punches[$i]); } $kill_last_element = array_pop($punches); return $punches; } function punch_to_array($punch) { $punch = explode("|", $punch); $new_punch[punched] = $punch[0]; $new_punch[day] = $punch[1]; $new_punch[date] = $punch[2]; $new_punch[month] = $punch[3]; $new_punch[year] = $punch[4]; $new_punch[time] = $punch[5]; return $new_punch; } function bootstrap() { echo "<link rel='stylesheet' href='http://twitter.github.com/bootstrap/assets/css/bootstrap-1.1.0.min.css'>"; echo "<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js' type='text/javascript'></script>"; } function initial_setup() { $db = "database.txt"; $handle = fopen($db, 'w') or die("TimeSheet could not create the database, try again"); fclose($handle); $result = "TimeSheet successfully created the database!"; return $result; } function calculate_pay($month, $year, $date_start, $date_end, $wage) { $punches = $this->get_punches(); for($i=0;$i<count($punches);$i++){ // Weed out the punches not in the month and year we're looking for if($punches[$i][month]==$month){ if($punches[$i][year]==$year){ if($punches[$i][date]>=$date_start){ if($punches[$i][date]<=$date_end){ $active_punches[$i] = $punches[$i]; } } } } } for($i=0;$i<count($active_punches);$i++){ // Make the time on the punches easier to do math with $active_punches[$i][time] = str_replace(":", ".", $active_punches[$i][time]); $active_punches[$i][time] = str_replace(" PM", "", $active_punches[$i][time]); $active_punches[$i][time] = str_replace(" AM", "", $active_punches[$i][time]); } for($i=0;$i<count($active_punches);$i++){ if(!is_float($i/2)){ $results[$i] = $active_punches[$i+1][time]-$active_punches[$i][time]; } } $result[total_time] = array_sum($results); $result[pay] = $result[total_time] * $wage; return $result; } function database_exist() { if(file_exists($this->get_database())){ return true; } else { return false; } } } |
and the actual script, index.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | <?php // Actual script include("SimpleTimesheet.class.php"); $timesheet = new SimpleTimesheet(); $timesheet->bootstrap(); // AJAX Functions if($_GET[ajax]=="initial_setup"){ $timesheet->initial_setup(); } else if($_GET[ajax]=="punch_in"){ $timesheet->new_punch("In|".$_POST[day]."|".$_POST[date]."|".$_POST[month]."|".$_POST[year]."|".$_POST[time]); } else if($_GET[ajax]=="punch_out"){ $timesheet->new_punch("Out|".$_POST[day]."|".$_POST[date]."|".$_POST[month]."|".$_POST[year]."|".$_POST[time]); } else if($_GET[ajax]=="calculate_pay"){ $result = $timesheet->calculate_pay($_GET[month], $_GET[year], $_GET[date_start], $_GET[date_end], $_GET[hourly]); ?> <div id="pay_result" class="alert-message success"> <p><strong>Total Hours Worked from <? echo $_GET[month]." ".$_GET[date_start]." to ".$_GET[month]." ".$_GET[date_end]; ?>:</strong> <?php echo $result[total_time]; ?> <strong>Ammount Made:</strong> $<?php echo $result[pay]; ?></p> </div> <?php die(); } if($timesheet->database_exist()){ ?> <?php if(!$_GET[view]){ ?> <body style="padding:20px;margin-right:auto;margin-left:auto;width:800px;"> <h1>Simple Timesheet</h1> <ul class="tabs"> <li id="timesheet" style="cursor:pointer;" class="active"><a onclick="change_view('timesheet');">View Timesheet</a></li> <li id="new_punch" style="cursor:pointer;"><a onclick="change_view('new_punch');">Punch In</a></li> <li id="out_punch" style="cursor:pointer;"><a onclick="change_view('out_punch');">Punch Out</a></li> <li id="calculate_pay" style="cursor:pointer;"><a onclick="change_view('calculate_pay');">Pay Sheet</a></li> <li id="about" style="cursor:pointer;"><a onclick="change_view('about');">About</a></li> </ul> <?php } ?> <div id="viewer"> <?php if($_GET[view]==""||$_GET[view]=="timesheet"){ ?> <!-- View Timesheet --> <table class="common-table zebra-striped"> <thead> <tr> <td>Punched</td> <td>Time</td> <td>Day</td> <td>Month</td> <td>Date</td> <td>Year</td> </tr> </thead> <tbody> <?php $punches = $timesheet->get_punches(); for($i=0;$i<count($punches);$i++){ ?> <tr> <td><? echo $punches[$i][punched]; ?></td> <td><? echo $punches[$i][time]; ?></td> <td><? echo $punches[$i][day]; ?></td> <td><? echo $punches[$i][month]; ?></td> <td><? echo $punches[$i][date]; ?></td> <td><? echo $punches[$i][year]; ?></td> </tr> <?php } ?> </tbody> </table> <?php } else if($_GET[view]=="new_punch"){ date_default_timezone_set("US/Arizona"); ?> <div id="punch_in_alert" class="alert-message success" style="display:none;"> <p><strong>Punched In!</strong> You have just punched in, now get to work!.</p> </div> <form id="punch_in_form"> <fieldset> <legend>Time Card Punch-In</legend> <div class="clearfix"> <label>Day</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="day" size="30" readonly="readonly" type="text" value="<?php echo date("l"); ?>" /> </div> </div> <div class="clearfix"> <label>Date</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="date" size="30" readonly="readonly" type="text" value="<?php echo date("j"); ?>" /> </div> </div> <div class="clearfix"> <label>Month</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="month" size="30" readonly="readonly" type="text" value="<?php echo date("F"); ?>" /> </div> </div> <div class="clearfix"> <label>Year</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="year" size="30" readonly="readonly" type="text" value="<?php echo date("Y"); ?>" /> </div> </div> <div class="clearfix"> <label>Time</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="time" size="30" readonly="readonly" type="text" value="<?php echo date("h").":".date("i")." ".date("A"); ?>" /> </div> </div> <div class="clearfix"> <button class="btn primary" onclick="punch_in();return false" style="margin-left:150px;">Punch In!</button> </div> </fieldset> </form> <?php } else if($_GET[view]=="out_punch"){ date_default_timezone_set("US/Arizona"); ?> <div id="punch_out_alert" class="alert-message success" style="display:none;"> <p><strong>Punched Out!</strong> You have just punched out, cya later!.</p> </div> <form id="punch_out_form"> <fieldset> <legend>Time Card Punch-Out</legend> <div class="clearfix"> <label>Day</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="day" size="30" readonly="readonly" type="text" value="<?php echo date("l"); ?>" /> </div> </div> <div class="clearfix"> <label>Date</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="date" size="30" readonly="readonly" type="text" value="<?php echo date("j"); ?>" /> </div> </div> <div class="clearfix"> <label>Month</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="month" size="30" readonly="readonly" type="text" value="<?php echo date("F"); ?>" /> </div> </div> <div class="clearfix"> <label>Year</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="year" size="30" readonly="readonly" type="text" value="<?php echo date("Y"); ?>" /> </div> </div> <div class="clearfix"> <label>Time</label> <div class="input"> <input class="xlarge disabled" id="disabledInput" style="height:30px;" name="time" size="30" readonly="readonly" type="text" value="<?php echo date("h").":".date("i")." ".date("A"); ?>" /> </div> </div> <div class="clearfix"> <button class="btn primary" onclick="punch_out();return false" style="margin-left:150px;">Punch Out!</button> </div> </fieldset> </form> <?php } else if($_GET[view]=="about"){ ?> <h3>About SimpleTimesheet v1.0.0</h3> <hr> <p style="text-align:left;">SimpleTimesheet is a quick and easy script class developed by <a href="http://ronaldarichardson.com/">Ronald A. Richardson</a> that easily allows a worker for a job, or project to punch in their work hours for each day of every month and year that they work on that project. Since it's an online web app employers can easily monitor their employee's work hours and automatically calculate their pay based upon their hourly wage. Click the button below to setup and start using SimpleTimesheet!</p> <?php } else if($_GET[view]=="calculate_pay"){ ?> <form id="pay"> <fieldset> <div class="clearfix"> <label for="hourly">Enter Hourly Pay:</label> <div class="input"> <input class="mini" id="hourly" name="hourly" style="height:30px;" value="0.00" onclick="this.value='';" size="30" type="text"> </div> </div> <div class="clearfix"> <label>Month:</label> <div class="input"> <select class="medium" name="month" id="month"> <option><?php echo date("F"); ?></option> <option>January</option> <option>Febuary</option> <option>March</option> <option>April</option> <option>May</option> <option>June</option> <option>July</option> <option>August</option> <option>September</option> <option>October</option> <option>November</option> <option>December</option> </select> </div> </div> <div class="clearfix"> <label>Year:</label> <div class="input"> <input class="mini" type="text" id="year" name="year" value="2011" style="height:30px;" /> </div> </div> <div class="clearfix"> <label>Date Range</label> <div class="input"> <div class="inline-inputs"> <input class="mini" value="1" type="text" name="date_start" style="height:30px;" /> to <input class="mini" value="31" type="text" name="date_end" style="height:30px;" /> </div> </div> </div> <div class="clearfix"> <button class="btn primary" onclick="calculate_pay();return false" style="margin-left:150px;">Calculate Pay!</button> </div> </fieldset> </form> <div id="displayPay"></div> <?php } ?> </div> <?php } else { ?> <body style="padding:20px;text-align:center;margin-right:auto;margin-left:auto;width:800px;"> <h1>This seems to be your first time using SimpleTimesheet!</h1> <hr> <p style="text-align:left;">SimpleTimesheet is a quick and easy script class developed by <a href="http://ronaldarichardson.com/">Ronald A. Richardson</a> that easily allows a worker for a job, or project to punch in their work hours for each day of every month and year that they work on that project. Since it's an online web app employers can easily monitor their employee's work hours and automatically calculate their pay based upon their hourly wage. Click the button below to setup and start using SimpleTimesheet!</p> <button class="btn primary" style="height:60px;width:300px;font-size:17px;" onclick="initial_setup();return false">Click here to setup your Timesheet</button> <?php } ?> <script> function initial_setup() { $.post("index.php?ajax=initial_setup"); $("body").html("<div class='modal' style='position: relative; top: auto; left: auto; margin: 0pt auto; z-index: 1;'><div class='modal-body'><p>Loading...</p></div></div>").load("index.php"); } function change_view(view) { $("#viewer").html("<div class='modal' style='position: relative; top: auto; left: auto; margin: 0pt auto; z-index: 1;'><div class='modal-body'><p>Loading...</p></div></div>").load("index.php?view="+view); $('li').removeClass('active'); $('#'+view).addClass('active'); } function punch_in() { $.post("index.php?ajax=punch_in", $("#punch_in_form").serialize()); $("#punch_in_alert").fadeIn("slow"); setTimeout("$('#punch_in_alert').fadeOut('slow')", 2100); } function punch_out() { $.post("index.php?ajax=punch_out", $("#punch_out_form").serialize()); $("#punch_out_alert").fadeIn("slow"); setTimeout("$('#punch_out_alert').fadeOut('slow')", 2100); } function calculate_pay() { $("#displayPay").html("<div class='modal' style='position: relative; top: auto; left: auto; margin: 0pt auto; z-index: 1;'><div class='modal-body'><p>Loading...</p></div></div>").load("index.php?ajax=calculate_pay&"+$("#pay").serialize()); } </script> |
Leave a Reply