Created
August 2, 2012 15:06
-
-
Save sreynen/3237766 to your computer and use it in GitHub Desktop.
Time report
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
require_once('basecamp/Basecamp.class.php'); // see http://code.google.com/p/basecamp-php-api/ | |
$bc = new Basecamp('https://[subdomain].basecamphq.com/','[username]','[password]', 'simplexml'); | |
$people = $bc->getPeopleForCompany([company ID]); | |
$person_id = array(); | |
foreach ($people['body']->person as $person) { | |
$name = (string)$person->{'first-name'}[0]; | |
$id = (int)$person->{'id'}[0]; | |
$person_id[$name] = $id; | |
$id_person[$id] = $name; | |
} // forach | |
$time = $bc->getTimeEntryReport('-' . $days_past .' days', 'today'); | |
$time_by_person_by_date = array(); | |
foreach ($time['body']->{'time-entry'} as $time_entry) { | |
$this_person_id = (int)$time_entry->{'person-id'}[0]; | |
$person = $id_person[$this_person_id]; | |
$date = (string)$time_entry->{'date'}[0]; | |
$hours = (float)$time_entry->{'hours'}[0]; | |
if (!isset($time_by_person_by_date[$person])) { | |
$time_by_person_by_date[$person] = array(); | |
} // if | |
if (!isset($time_by_person_by_date[$person][$date])) { | |
$time_by_person_by_date[$person][$date] = 0; | |
} // if | |
$time_by_person_by_date[$person][$date]+= $hours; | |
} // foreach | |
?> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<? | |
$aten_people = array( | |
'Ken' => '', | |
'Joel' => '', | |
'John' => '', | |
'Scott' => '', | |
'Rob' => '', | |
'Clayton' => 'last', | |
); | |
if ($_GET['person'] != '') { | |
$aten_people = array( | |
$_GET['person'] => 'last', | |
); | |
} // if | |
?> | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8" /> | |
<title>We good on time?</title> | |
<? | |
if ($_GET['subtle'] == '') { | |
?> | |
<link type="text/css" rel="stylesheet" media="all" href="style.css" /> | |
<? | |
} // if | |
?> | |
</head> | |
<body class="styled"> | |
<div class="container"> | |
<div class="header"> | |
<? | |
if ($_GET['subtle'] == '') { | |
?> | |
<h2>We good on time?</h2> | |
<? | |
} // if | |
$days_past = 7; | |
if ($_GET['days']) { | |
$days_past = intval($_GET['days']); | |
} // if | |
require_once('basecamp.php'); | |
$day = strtotime('-' . $days_past . ' days'); | |
$past_week = array(); | |
while (date('Y-m-d', $day) < date('Y-m-d')) { | |
if (date('N', $day) < 6) { | |
$past_week[] = $day; | |
} // if | |
$day = strtotime(date('Y-m-d', $day) . ' +1 day'); | |
} // while | |
$total_by_person = array(); | |
ob_start(); | |
?> | |
</div> | |
<table> | |
<thead> | |
<tr> | |
<th></th> | |
<? | |
foreach ($aten_people as $name => $class) { | |
?> | |
<th><?= $name ?></th> | |
<? | |
} // foreach | |
?> | |
</tr> | |
</thead> | |
<tbody> | |
<? | |
foreach ($past_week as $index => $day) { | |
$yesterday = $day; | |
$class = ' class="even"'; | |
if ($index % 2 == 0) { | |
$class = ' class="odd"'; | |
} // if | |
?> | |
<tr<?= $class ?>> | |
<th><em><?= date('D', $day) ?></em> <strong><?= date('m/d/Y', $day) ?></strong></th> | |
<? | |
foreach ($aten_people as $name => $class) { | |
?> | |
<td class="<= $class ?>"><a href="https://aten.basecamphq.com/time_entries/report?subject_id=<?= $person_id[$name] ?>&from%5Bmonth%5D=<?= date('n', $day) ?>&from%5Bday%5D=<?= date('j', $day) ?>&from%5Byear%5D=<?= date('Y', $day) ?>&to%5Bmonth%5D=<?= date('n', $day) ?>&to%5Bday%5D=<?= date('j', $day) ?>&to%5Byear%5D=<?= date('Y', $day) ?>&commit=Create+report"><?= number_format(floatval($time_by_person_by_date[$name][date('Y-m-d', $day)]), 2) ?></a></td> | |
<? | |
$total_by_person[$name] += $time_by_person_by_date[$name][date('Y-m-d', $day)]; | |
} // foreach | |
?> | |
</tr> | |
<? | |
} // foreach | |
$day = strtotime('today'); | |
$index++; | |
$class = ' class="even"'; | |
if ($index % 2 == 0) { | |
$class = ' class="odd"'; | |
} // if | |
?> | |
<tr<?= $class ?>> | |
<th><em><?= date('D', $day) ?></em> <strong><?= date('m/d/Y', $day) ?></strong></th> | |
<? | |
foreach ($aten_people as $name => $class) { | |
?> | |
<td class="<?= $class ?>"><a href="https://aten.basecamphq.com/time_entries/report?subject_id=<?= $person_id[$name] ?>&from%5Bmonth%5D=<?= date('n', $day) ?>&from%5Bday%5D=<?= date('j', $day) ?>&from%5Byear%5D=<?= date('Y', $day) ?>&to%5Bmonth%5D=<?= date('n', $day) ?>&to%5Bday%5D=<?= date('j', $day) ?>&to%5Byear%5D=<?= date('Y', $day) ?>&commit=Create+report"><?= number_format(floatval($time_by_person_by_date[$name][date('Y-m-d', $day)]), 2) ?></a></td> | |
<? | |
} // foreach | |
?> | |
</tr> | |
</tbody> | |
<tfoot> | |
<tr> | |
<th>Total</th> | |
<? | |
foreach ($aten_people as $name => $class) { | |
?> | |
<td class="<?= $class ?>"><?= number_format(floatval($total_by_person[$name]), 2) ?></td> | |
<? | |
} // foreach | |
?> | |
</tr> | |
</tfoot> | |
</table> | |
<? | |
$table = ob_get_clean(); | |
if ($_GET['subtle'] == '') { | |
$undone = array(); | |
$done = array(); | |
$yesterday = date('Y-m-d', $yesterday); | |
foreach ($aten_people as $name => $class) { | |
if ( | |
($total_by_person[$name] < 35) || | |
(number_format(floatval($time_by_person_by_date[$name][$yesterday]), 2) == 0) | |
) | |
$undone[] = $name; | |
} // foreach | |
if (count($undone) > 2) { | |
$last = array_pop($undone); | |
?> | |
<h1 class="no">No</h1> | |
<p><strong><?= implode('</strong>, <strong>', $undone) ?></strong> and <strong><?= $last ?></strong> are all slacking.</p> | |
<? | |
} // if | |
else if (count($undone) == 2) { | |
?> | |
<h1 class="no">No</h1> | |
<p><strong><?= $undone[0] ?></strong> and <strong><?= $undone[1] ?></strong> are to blame.</p> | |
<? | |
} // else if | |
else if (count($undone) == 1) { | |
?> | |
<h1 class="no">No</h1> | |
<p>And it's all <strong><?= $undone[0] ?>’s</strong> fault.</p> | |
<? | |
} // else if | |
else { | |
?> | |
<h1 class="yes">Yes!</h1> | |
<div class="message"><h3>Good job!</h3></div> | |
<? | |
} // else | |
} // if | |
print $table; | |
?> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0} | |
body{font:13px/1.5 'Helvetica Neue',Helvetica,Arial,'Liberation Sans',FreeSans,sans-serif}a:focus{outline:1px dotted}hr{border:0 #ccc solid;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:disc}li{margin-left:30px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset{margin-bottom:20px} | |
input, textarea, select {font: 13px/1.5 'Helvetica Neue',Helvetica,Arial,'Liberation Sans',FreeSans,sans-serif;} | |
/* -----clearfix -----*/ | |
/*.clear{clear:both;display:block;overflow:hidden;visibility:hidden;width:0;height:0}*/ | |
.clearfix:after{clear:both;content:' ';display:block;font-size:0;line-height:0;visibility:hidden;width:0;height:0}* html .clearfix,*:first-child+html .clearfix{zoom:1} | |
/* GENERAL STYLES */ | |
body { | |
text-align: center; | |
margin: 0; | |
padding: 40px 0; | |
} | |
h1 { | |
font-size: 10em; | |
line-height: 1em; | |
text-transform: uppercase; | |
font-weight: 900; | |
text-align: center; | |
} | |
h2 { | |
text-align: center; | |
} | |
table { | |
width: 100%; | |
} | |
thead th , | |
tbody td , | |
tfoot td { | |
text-align: center; | |
} | |
th , | |
td { | |
padding: 8px 10px; | |
} | |
/* GENERAL CLASSES */ | |
/* LAYOUT */ | |
.container { | |
width: 600px; | |
margin: 0 auto; | |
text-align: left; | |
} | |
.header p { | |
text-align: center; | |
} | |
body { | |
background: #193ca2 url(images/bg.png) 0 0 repeat-x; | |
color: #fff; | |
} | |
a { | |
color: #fff; | |
text-decoration: none; | |
} | |
.header h2 { | |
color: #f7e2b5; | |
text-shadow: #112988 0 1px 0; | |
} | |
.header h1 { | |
text-shadow: #112988 0 1px 3px; | |
margin-bottom: 40px; | |
} | |
.header p { | |
color: #193ca2; | |
font-size: 1.4em; | |
padding: 20px 20px; | |
-moz-border-radius: 5px; | |
-webkit-border-radius: 5px; | |
border-radius: 5px; | |
background-color: #ffffff; | |
-moz-box-shadow: 0px 1px 0px #000059; | |
-webkit-box-shadow: 0px 1px 0px #000059; | |
box-shadow: 0px 1px 0px #000059; | |
margin-bottom: 50px; | |
} | |
.header p strong { | |
color: #e3441f; | |
border-bottom: 1px dashed #e3441f; | |
} | |
.header p em { | |
font-family: Georgia, "Hoefler Text", Baskerville, Garamond, "Palatino Linotype", "Times New Roman", serif; | |
} | |
.header h3 { | |
text-align: center; | |
color: #f7e2b5; | |
text-shadow: #000045 0 1px 2px; | |
font-size: 2.8em; | |
padding: 20px 20px; | |
-moz-border-radius: 5px; | |
-webkit-border-radius: 5px; | |
border-radius: 5px; | |
background-color: #0d2076; | |
-moz-box-shadow: 0px -1px 0px #000045; | |
-webkit-box-shadow: 0px -1px 0px #000045; | |
box-shadow: 0px -1px 0px #000045; | |
margin-bottom: 50px; | |
} | |
table { | |
border-collapse: separate; | |
} | |
table thead tr { | |
background-color: #0d2076; | |
border-bottom: 1px solid #000045; | |
color: #f7e2b5; | |
} | |
table thead tr th { | |
font-size: 1.3em; | |
border-bottom: 1px solid #0a195e; | |
} | |
table tbody tr th em { | |
font-style: normal; | |
display: inline-block; | |
width: 40px; | |
} | |
table tbody tr th strong { | |
display: inline-block; | |
} | |
table tbody tr.odd { | |
background-color: #1f4eba; | |
} | |
table tbody tr.odd th { | |
background-color: #143291; | |
border-right: 1px solid #0f256b; | |
border-top: 1px solid #193ca7; | |
border-bottom: 1px solid #102679; | |
} | |
table tbody tr.odd td { | |
border-top: 1px solid #285fc8; | |
border-bottom: 1px solid #193cab; | |
border-right: 1px solid #1e46b3; | |
} | |
table tbody tr.odd td.last { | |
border-right: none; | |
} | |
table tbody tr.even { | |
background-color: #2251c2; | |
} | |
table tbody tr.even th { | |
background-color: #163699; | |
border-right: 1px solid #0f256b; | |
border-top: 1px solid #1a41ad; | |
border-bottom: 1px solid #122b85; | |
} | |
table tbody tr.even td { | |
border-top: 1px solid #2961ce; | |
border-bottom: 1px solid #1b41b6; | |
border-right: 1px solid #1f49bc; | |
} | |
table tbody tr.even td.last { | |
border-right: none; | |
} | |
table tfoot tr { | |
background-color: #000045; | |
} | |
table tfoot tr th { | |
text-transform: uppercase; | |
color: #f7e2b5; | |
background-color: #000022; | |
} | |
table tfoot tr td { | |
font-size: 1.5em; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment