Location: PHPKode > projects > ConPortal > conportal/inc/punches/display.php
<?php
/*
 *  ConPortal - Pomona College ITS & Bucknell University ISR scheduling appplication
 *  Copyright (C) 2005-2008  Pomona College, Bucknell University
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of version 2 of the GNU General Public License
 *  as published by the Free Software Foundation.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
Implemented in this file
	show_punched_in
	show_punch_button
	print_all_punch_histories
	print_punch_history
	print_friendly_punch_history
	print_logout_report
	sum_time
	subtract_time
	make_friendly_time
	findDifferentialShifts
	determineCase
	getTimestamp
	print_add_edit_punch_form
	print_meeting_punch_form
	print_ip_form

 */

function show_punched_in()
{
	$punchedIn = getPunchedIn();
	foreach($punchedIn as $punchedUser)
	{
			echo $punchedUser['first'] . " " . $punchedUser['last'] . 
			" at " . date("D, M j, g:i a", strtotime($punchedUser['time_in']));

			if(ALBANY_OPTIONS)
			{
				echo " from " . $punchedUser['description'];
			}
			echo "<br>" ;  
	}
	?></center><?php
}

function show_punch_button()
{
	
	//set ipOK to true; if punch in returns false, set it to false and display warning
	$ipOK = true;
	$posted = false;
	if($_SERVER['REQUEST_METHOD']=='POST')
		$posted = true;
	$punched = isPunchedIn($_SESSION['pid']);
	//just for fun...
	$name = getNameForUser($_SESSION['pid']);

		//if login isn't ok, display error message 
	if(isset($_SESSION['ipOK']) && $_SESSION['ipOK']==FALSE)
	{ ?>
	<br /><br /><center><img src="images/hal9000.jpg"><br /><br />
	<b>I'm sorry Dave, I'm afraid I can't do that.</b></center><br /> <?php
	
	//reset value
	$_SESSION['ipOK']==TRUE;
		}
	
?>
	<br><br>
	<form method='post' action='redirects/punch_in_out.php'><center> <?
	
	if($punched)
	{ ?>
		<input type='submit' value='Punch me out!' /> <br /><br />
		<?}
	else if(!$punched)
	{ ?>
		<input type='submit' value='Punch me in!' /> <br /><br />
	<?}
	
	if(OH_NOES)
	{
		echo "<input type=\"checkbox\" name=\"fix_punch\">" . PUNCHES_FIX_MY_PUNCH; 
	}
	else
	{
		echo "If you have forgotten to punch out, please notify your supervisor.";
	}
	?>	
	</form>
<?php

}

function print_all_punch_histories($start, $end)
{
	$users = sortUsersByName(getAllUserDetails());
    foreach ($users as $user) {
        print "<h2 class='center' style='margin-top: 1em'>".$user['name']."</h2>\n";
        print_punch_history($user['pid'], $start, $end, FALSE);
	}
}

/*clickable argument added so print_punch_history can do double duty as 
a regular display of punch history and as part of the "edit a punch" administrivia functionality. */
function print_punch_history($pid, $start, $end, $clickable)
{
	$punches = getPunchDetailsForArray(getPunchesForDateRangeAndUser($pid, $start, $end));
	$diff_shifts = getDifferentialShiftsNumeric();
		
	if(ALBANY_OPTIONS == TRUE)
	{
		$usr = getUserDetails($pid);
  		$albanyid = getAlbanyId($usr['username']); 
   		$name = getNameForUser($pid);
		#print "<div class='center'>Timesheet for $name<br>udent ID #: ". $albanyid ."\t Department ID #: 900540.01</div><br>\n";
	}

    if(count($punches) == 0)
	{
        print "<div class='center'>None</div>\n";
        return;
    }
	
	//setup for regular & differential time summing
	$reg_time = "00:00:00";
	$diff_time = "00:00:00";
	$friendly_reg_time = 0.00;
	$friendly_diff_time = 0.00;
	
	$rows = array();
	foreach($punches as $punch)
	{
		$in_time = date("D, M j, g:i a", strtotime($punch['time_in']));
		if($punch['time_out'] == "0000-00-00 00:00:00")
			$out_time = "";
		else
			$out_time = date("D, M j, g:i a", strtotime($punch['time_out']));
		
		//won't need this in the case where the row is clickable, but 
		$friendly_this_time = make_friendly_time($punch['time_worked']);
		
		//if clickable, we're editing punches, not displaying them for user consumption!
		if($clickable)
		{
			$rowstring = "<tr><td><a href=\"" . BASE_URL . "add_punch.php?pid=" . 
							$punch['pid'] . "\">" . $punch['pid'] . "</a></td>
							<td>" .  $in_time . "</td>
							<td> " . $out_time . "</td>
							<td> " . $punch['time_worked'] . "</td></tr>";
		
		}	
		else if(($friendly_this_time == -1) || ($out_time == ""))
		{
		$rowstring= "<tr><td class='punch_error'>" . $in_time . "</td>
							<td class='punch_error'>" . $out_time . "</td>
							<td class='punch_error'> " . $punch['time_worked'] . "</td>
							<td class='punch_error'>DOES NOT COMPUTE!</td></tr>";
		}
		else
		{
			$rowstring = findDifferentialShifts($diff_shifts, $punch, $diff_time, $reg_time, $friendly_reg_time, $friendly_diff_time, $friendly_this_time, $punch['time_worked']);
		}
		//the following code is disabled because it's superceeded by the new differential shift system
		//but since I'm extremely paranoid I'll leave it in and commented out for 
		//"OH CRAP I NEED THAT OLD CODE *QUICK*!" peace-of-mind.  It'll eventually go away, don't worry.
		
		/*else if(($day == "Sat") || ($day == "Sun"))
		{
		$rowstring= "<tr><td class='weekend'>" . $in_time . "</td>
							<td class='weekend'>" . $out_time . "</td>
							<td class='weekend'> " . $punch['time_worked'] . "</td>
							<td class='weekend'> " . sprintf('%.2f', $friendly_this_time) . "</td></tr>";
		sum_time($diff_time,$punch['time_worked']);
		$friendly_diff_time = $friendly_diff_time + $friendly_this_time;
			
		}
		
		else
		{
		
			$rowstring = displayHighlighted($in_time, $out_time, $reg_time, $diff_time, $friendly_reg_time, $friendly_diff_time)
		$rowstring= "<tr><td>" . $in_time . "</td>
							<td>" . $out_time . "</td>
							<td> " . $punch['time_worked'] . "</td>
							<td> " . sprintf('%.2f',$friendly_this_time) . "</td></tr>";
		sum_time($reg_time,$punch['time_worked']);
		$friendly_reg_time = $friendly_reg_time + $friendly_this_time;
		
		} */
		
		$rows[] = $rowstring;
		
	}
	if($clickable)
		echo "<center><b>Click on the Punch Id to chose that punch for editing.</center></b><br><br>";
	?>
	<table class='shift_history'>
    	<tr><? if($clickable) echo "<th>Punch Id</th>" ?><th>Punch In</th><th>Punch Out</th>
	<th>Time Worked</th>
	<? 
	if(!($clickable))
	{
		echo "<th>Timesheet Time</th></tr>";
	}
			
   	foreach ($rows as $row)
        	echo $row;

	?>
	</table>
	<?

	if(!($clickable))
	{
		if(BUCKNELL_OPTIONS == TRUE)
		{
			echo "<center>Regular Time: " . $reg_time . "<br>" .
				"Timesheet-Friendly Regular Time: " . sprintf('%.2f',$friendly_reg_time) . "<br><br>" .
				"<div class='weekend'>Differential Time: " . $diff_time . "<br>" .
				"Timesheet-Friendly Differential Time: " . sprintf('%.2f',$friendly_diff_time) . "</div><br>";
		}
	sum_time($reg_time,$diff_time);
	$friendly_total_time = $friendly_reg_time + $friendly_diff_time;
	
		if(BUCKNELL_OPTIONS == TRUE)
		{
			echo "Total Time Worked: " . $reg_time . "<br>Timesheet-Friendly Total Time Worked: " . sprintf('%.2f',$friendly_total_time) . "<br>";
		}
		if(ALBANY_OPTIONS == TRUE)
		{
			// BobWachs - Added back the row regarding weekend hours to prevent confusion on how hours are totaled.
			echo "<tr><td colspan=3 align=right style=\"border: 0px\">Total Time Worked: </td><td style=\"border: 0px\">" . $reg_time . "</td></tr><tr><td colspan=3 align=right  class='weekend' style=\"border: 0px\">Total Weekend Time Worked: </td><td  class='weekend' style=\"border: 0px\">" . $diff_time . "</td></tr><tr><td colspan=3 align=right style=\"border: 0px\">Timesheet-Friendly Total Time Worked: </td><td style=\"border: 0px\"> " . sprintf('%.2f',$friendly_total_time) . "</td></tr>";	
		
			?>
			</table><br>
			<?	
		}
	}
	
	echo "</center>";
}

//A function that allows the folks in Albany to print histories and a signable timesheet
//I've left this as-is, and haven't added the differential shift stuff above, but it'd be simple to integrate - 
//just follow the example of the above function.  It's just I'm leery of breaking other people's stuff, ya know?  
//Also, I'm not clear on where this ever gets called...
function print_friendly_punch_history($pid, $start, $end, $clickable)
{
   $usr = getUserDetails($pid);
   $albanyid = getAlbanyId($usr['username']); 
   $name = getNameForUser($pid);
	$punches = getPunchDetailsForArray(getPunchesForDateRangeAndUser($pid, $start, $end));
	print "<div align=center>
		<table>
		<tr>
			<td colspan='5' align='center'><img src='images/ualbany.gif'></td>
		</tr>
		<tr>
			<td colspan='5'>&nbsp;</td>
		</tr>
			<td width=20%>Student Name</td><td width=20%><b>$name</b></td><td width=10%>&nbsp;</td><td width=20%>Department Account Number</td><td width=20%><b>900540.01</b></td>
		</tr>
		<tr>	
			<td>AlbanyID</td><td><b>$albanyid</b></td><td>&nbsp;</td><td>Departmental Title</td><td>ITS HelpDesk</td>
		</tr>	
		</table></div><br><br>";
    if(count($punches) == 0)
	{
        print "<div class='center'>None</div>\n";
        return;
    }
	
	//setup for regular & differential time summing
	$reg_time = "00:00:00";
	$diff_time = "00:00:00";
	$friendly_reg_time = 0.00;
	$friendly_diff_time = 0.00;
	
	$rows = array();
	foreach($punches as $punch)
	{
		$in_time = date("D, M j, g:i a", strtotime($punch['time_in']));
		if($punch['time_out'] == "0000-00-00 00:00:00")
			$out_time = "";
		else
			$out_time = date("D, M j, g:i a", strtotime($punch['time_out']));
		
		//won't need this in the case where the row is clickable, but 
		$friendly_this_time = make_friendly_time($punch['time_worked']);
		
		//so we can color weekends read
		$day = substr($in_time, 0, 3);
		
		if($clickable)
		{
			$rowstring = "<tr><td><a href=\"" . BASE_URL . "add_punch.php?pid=" . 
							$punch['pid'] . "\">" . $punch['pid'] . "</a></td>
							<td>" .  $in_time . "</td>
							<td> " . $out_time . "</td>
							<td> " . $punch['time_worked'] . "</td></tr>";
		
		}
		else if(($day == "Sat") || ($day == "Sun"))
		{
		$rowstring= "<tr><td class='weekend'>" . $in_time . "</td>
							<td class='weekend'>" . $out_time . "</td>
							<td class='weekend'> " . $punch['time_worked'] . "</td>
							<td class='weekend'> " . sprintf('%.2f', $friendly_this_time) . "</td></tr>";
		sum_time($diff_time,$punch['time_worked']);
		$friendly_diff_time = $friendly_diff_time + $friendly_this_time;
			
		}
		else
		{
		$rowstring= "<tr><td>" . $in_time . "</td>
							<td>" . $out_time . "</td>
							<td> " . $punch['time_worked'] . "</td>
							<td> " . sprintf('%.2f',$friendly_this_time) . "</td></tr>";
		sum_time($reg_time,$punch['time_worked']);
		$friendly_reg_time = $friendly_reg_time + $friendly_this_time;
		
		}
		
		$rows[] = $rowstring;
		
	}
if($clickable)
	echo "<center><b>Click on the Punch Id to choose that punch for editing.</center></b><br><br>";
?>
<div align=center><table class='shift_history'>
    <tr><? if($clickable) echo "<th>Punch Id</th>" ?><th>Punch In</th><th>Punch Out</th>
	<th>Time Worked</th>
	<? if(!($clickable))
			{
			echo "<th>Timesheet Time</tr>";
			}
			
    foreach ($rows as $row)
        echo $row;

	if(!($clickable))
	{
/*	echo "<tr><td colspan=3 align=right style=\"border: 0px\">Regular Time: </td><td style=\"border: 0px\">" . $reg_time . "</td></tr>" .
		"<tr><td colspan=3 align=right style=\"border: 0px\">Timesheet-Friendly Regular Time: </td><td style=\"border: 0px\">" . sprintf('%.2f',$friendly_reg_time) . "</td></tr>" .
		"<tr><td colspan=3 align=right class='weekend' style=\"border: 0px\">Weekend Time: </td><td style=\"border: 0px\">" . $diff_time . "</td></tr>" .
		"<tr><td colspan=3 align=right class='weekend' style=\"border: 0px\">Timesheet-Friendly Weekend Time: </td><td style=\"border: 0px\">" . sprintf('%.2f',$friendly_diff_time) . "</td></tr>";
	sum_time($reg_time,$diff_time);*/
	$friendly_total_time = $friendly_reg_time + $friendly_diff_time;
	echo "<tr><td colspan=3 align=right style=\"border: 0px\">Total Time Worked: </td><td style=\"border: 0px\">" . $reg_time . "</td></tr><tr><td colspan=3 align=right  class='weekend' style=\"border: 0px\">Total Weekend Time Worked: </td><td  class='weekend' style=\"border: 0px\">" . $diff_time . "</td></tr><tr><td colspan=3 align=right style=\"border: 0px\">Timesheet-Friendly Total Time Worked: </td><td style=\"border: 0px\"> " . sprintf('%.2f',$friendly_total_time) . "</td></tr>";
?>
</table></div><br>
<?
	echo <<<TXT_
<div align=center><table border=0 width=60%><tr><td colspan=4><ol> <li><div class=small>Record hours "in" and "out" daily. An "X" must be placed in these blocks when you do not work and the "Hours Worked" for the day should be entered manually as zero (when completing electronically).  Hours worked must be recorded in quarter hour units (e.g. 9:15 A, 12:30 P) in ink.</div></li>							
<li><div class=small>All hours worked on a holiday or hours which have been adjusted must be initialed by the supervisor before payment can be made.</div></li>											
<li><div class=small>Do not work in excess of 40 hours in any work week (Thursday through Wednesday).</div></li>										
<li><div class=small>A work period cannot extend beyond six hours without taking a lunch break of at least one-half hour, which must be shown on the time sheet.</div></li>											
<li><div class=small>Employee: Complete ALL blanks, sign and submit to your supervisor when you finish work for the pay period.  Late time sheets cannot be paid until the following pay period.</div></li>											
<li><div class=small>Supervisor: Review time sheet for accuracy, initial all approved holiday work and corrections made on the time sheet, sign certification and submit only the original copy to the Payroll Office for payment.  See "Pay Schedule" issued by Payroll Office for due dates.</div></li></td></tr>
<tr>
	<td colspan=2><div class=small>I certify that the days and hours worked as recorded above are correct.</div></td><td colspan=2><div class=small>I certify that the days and hours indicated above represent time worked by the employee including any holiday hours noted and initialed by me, and that the employee is entitled to payment thereof..</div></td>
</tr>
<tr>
<td colspan=4>&nbsp;</td>
</tr>
<tr>
	<td colspan=2>__________________________________________________</td><td colspan=2>__________________________________________________</td>
</tr>
<tr>
	<td>Employee's Signature</td><td>Date</td><td>Supervisor's Signature</td><td>Date</td>
</tr>
</table>
</div>
TXT_;
	
	}
	
	
}


function print_logout_report($start, $end)
{
	$punches = getUnusualPunchesForDateRange($start, $end);
	
	if(count($punches) == 0)
	{
        print "<div class='center'>None</div>\n";
        return;
    }
	
	$rows = array();
	foreach($punches as $punch)
	{
		$rows[] = "<tr><td>" . $punch['first'] . " " . $punch['last'] . "</td>
							<td> " . $punch['time_in'] . "</td>
							<td> " . $punch['login_ip'] . "</td>
							<td> " . $punch['time_out'] . "</td>
							<td> " . $punch['logout_ip'] . "</td></tr>";
		
	}
	?>
<table class='shift_history'>
    <tr><th>Name</th><th>Time In</th><th>Punch-In Location<th>Time Out</th><th>Punch-Out Location</th></tr>
	
<?
	if($clickable)
	{
		?> <tr class='d<?= $i++ % 2 ?>' onmouseover='javascript:highlight(this)'
        onmouseout='javascript:unhighlight(this)' <?
		}
	
    foreach ($rows as $row)
        echo $row;
?>
</table>
<?
}
	

/* A function to sum times.  Heavily based on code found at:
http://forums.devarticles.com/php-development-48/summing-sql-time-values-in-php-6529.html */
function sum_time(&$summed_time, $shift_time)
{
	
    // 0=HH, 1=MM, 2=SS
    $_summed_time = explode(":", $summed_time);
    $_shift_time = explode(":", $shift_time);  

    // Convert each time to seconds
    $summed_seconds = (($_summed_time[0] * 3600) + ($_summed_time[1] * 60) + ($_summed_time[2]));
    $shift_seconds = (($_shift_time[0] * 3600) + ($_shift_time[1] * 60) + ($_shift_time[2]));
    
    // Add to produce total
    $total = $summed_seconds + $shift_seconds;

    // Convert total from seconds to full time again
    $_total_time["hrs"] = floor(($total / 3600));
    $_total_time["mins"] = floor(($total - ($_total_time["hrs"] * 3600)) / 60);
    $_total_time["secs"] = floor(($total - ($_total_time["hrs"] * 3600) - ($_total_time["mins"] * 60)));

    // Prefix with 0s where necessary
    if (strlen($_total_time["hrs"]) == 1) 
      $_total_time["hrs"] = "0" . $_total_time["hrs"];
    if (strlen($_total_time["mins"]) == 1)
      $_total_time["mins"] = "0" . $_total_time["mins"];
    if (strlen($_total_time["secs"]) == 1)
      $_total_time["secs"] = "0" . $_total_time["secs"];

    // Format total time
    $summed_time = $_total_time["hrs"] . ":" . $_total_time["mins"] . ":" . $_total_time["secs"]; 

}

//Based on the above; returns a string with the result.  Now with 100% more obscure mathematical terms!
//It occurrs to me that I should write a function which essentially combines these two, and takes a third
//argument indicating addition or subtraction.  But I've got enough on my plate right now; being clever
//can wait for another day...
function subtract_time($minuend, $subtrahend)
{
	//cut off day & date bits, if necessary
	if(strlen($minuend) == 19)
		$minuend = substr($minuend, 11);
	if(strlen($subtrahend) == 19)
		$subtrahend = substr($subtrahend, 11);

	$m_array = explode(":", $minuend);
	$s_array = explode(":", $subtrahend);
	
	// Convert each time to seconds
   	$m_sum = (($m_array[0] * 3600) + ($m_array[1] * 60) + ($m_array[2]));
    	$s_sum = (($s_array[0] * 3600) + ($s_array[1] * 60) + ($s_array[2]));
	
	//Subtract
	$diff_seconds = $m_sum - $s_sum;
	
	//Rectify, if necessary
	if($diff_seconds < 0)
		$diff_seconds = $diff_seconds + (24 * 3600);

	//convert back
	$diff_array["hrs"] = floor(($diff_seconds / 3600));
   	$diff_array["mins"] = floor(($diff_seconds - ($diff_array["hrs"] * 3600)) / 60);
    	$diff_array["secs"] = floor(($diff_seconds - ($diff_array["hrs"] * 3600) - ($diff_array["mins"] * 60)));

	// Prefix with 0s where necessary
   	 if (strlen($diff_array["hrs"]) == 1) 
      		$diff_array["hrs"] = "0" . $diff_array["hrs"];
    	if (strlen($diff_array["mins"]) == 1)
      		$diff_array["mins"] = "0" . $diff_array["mins"];
    	if (strlen($diff_array["secs"]) == 1)
     		$diff_array["secs"] = "0" . $diff_array["secs"];

    	// Format total time
    	$difference = $diff_array["hrs"] . ":" . $diff_array["mins"] . ":" . $diff_array["secs"]; 
	return $difference;
}

/* A feature proposed by Bud, to display times in a timesheet-friendly format, just in case
   our students (or Bud!) has trouble with that whole 'big hand, little hand" thing.  :)  
	Note we are ignoring seconds.  Funk dat noise! */
function make_friendly_time($time_worked)
{
	$friendly_time = 0.00;
	$divided_time = explode(":", $time_worked);
	
	// if they've worked at least 8 hours, just return 8, since they can't work more than 8 hours after all... 
	//counterpoint: if they've worked more than 8 hours, it's (almost) certainly because they haven't 
	//punched out properly.  Bastards!  In that case, return an error
	if($divided_time[0] > 8)
	{
		return -1;
	}
	else
	{
		$friendly_time = $divided_time[0];
	}

	// now compute minutes to quarter hour blocks
	if(intval($divided_time[1]) <= 7)
	{
		return $friendly_time;
	}
	else if(intval($divided_time[1]) <= 22)
	{	
		$friendly_time = $friendly_time + 0.25;
		return $friendly_time;
	}
	else if(intval($divided_time[1]) <= 37)
	{	
		$friendly_time = $friendly_time + 0.50;
		return $friendly_time;
	}
	else if(intval($divided_time[1]) <= 52)
	{	
		$friendly_time = $friendly_time + 0.75;
		return $friendly_time;
	}
	else 
	{	
		$friendly_time = $friendly_time + 1.00;
		return $friendly_time;
	}
	
}	

//function responsible for returning an appropriate string for the row or rows 
//that should appear given a punch, as well as updating diff & reg times.  
//Walks through the different differential periods and sees if there's a match, and if there isn't
//print the punch as a regular punch.  
//ASSERT: We only overlap with a single differential shift!  If that's a bad assumption, this won't work.
function findDifferentialShifts($diff_shifts, $punch, &$diff_time, &$reg_time, &$friendly_reg_time, &$friendly_diff_time, $worked_time)
{
	$in_time = date("D, M j, g:i a", strtotime($punch['time_in']));
	$out_time = date("D, M j, g:i a", strtotime($punch['time_out']));
	$break_early = FALSE;
	foreach($diff_shifts as $a_diff)
	{
		if(USE_DIFF_SHIFTS == TRUE)
		{
			if(ALL_SHIFTS_ARE_DIFF == TRUE)
			{
				$case = 2;
			}
			else
			{
				$case = determineCase($punch, $a_diff);
			}
		//I chose to implement this with a switch because it seemed like a good idea at the time
		switch ($case) {
			//in the case there's no interaction			
			case 1:	
				break;
			//in the case the punch exists entirely within the diff
			case 2: 
				//build rowstring wrapped in weekend
				$rowstring= "<tr><td class='weekend'>" . $in_time . 
					"</td><td class='weekend'>" . $out_time . 
					"</td><td class='weekend'> " . $punch['time_worked'] . 
					"</td><td class='weekend'> " . sprintf('%.2f',$worked_time) . "</td></tr>";
				//update diff time & friendly diff time
				sum_time($diff_time,$punch['time_worked']);
				$friendly_diff_time = $friendly_diff_time + $worked_time;	
				break;	
			//in the case the punch is before the diff, and ends during it			
			case 3:
				//reg & f_reg are increased by diff_start - punch_in
				$diff1 = subtract_time($a_diff['start_time'],$punch['time_in']);
				$friendly_diff1 = make_friendly_time($diff1);
				sum_time($reg_time,$diff1);
				$friendly_reg_time = $friendly_reg_time + $friendly_diff1;
				//build rowstring1 regularly from punch_in until diff_start
				$rowstring1= "<tr><td>" . $in_time . "</td><td>" . $a_diff['start_time'] . "</td><td> " .
					$diff1 . "</td><td> " . sprintf('%.2f',$friendly_diff1) . "</td></tr>";
				//diff & f_diff increased by punch_out - diff_start
				$diff2 = subtract_time($punch['time_out'],$a_diff['start_time']);
				$friendly_diff2 = make_friendly_time($diff2);
				sum_time($diff_time,$diff2);
				$friendly_diff_time = $friendly_diff_time + $friendly_diff2;
				//build rowstring2 in weekend until punch_out
				$rowstring2= "<tr><td class='weekend'>" . $a_diff['start_time'] . 
					"</td><td class='weekend'>" . $out_time . "</td><td class='weekend'> " . $diff2 . 
					"</td><td class='weekend'> " . sprintf('%.2f',$friendly_diff2) . "</td></tr>";
				//concat two rowstrings
				$rowstring = $rowstring1 . $rowstring2;
				break;
			//in the case that the punch is during the diff, and ends after it
			case 4:
				//diff & f_diff increased by diff_end - punch_in
				$diff1 = subtract_time($a_diff['end_time'],$punch['time_in']);
				$friendly_diff1 = make_friendly_time($diff1);
				sum_time($diff_time,$diff1);
				$friendly_diff_time = $friendly_diff_time + $friendly_diff1;
				//build rowstring1 in weekend from punch_in until diff_end
				$rowstring1= "<tr><td class='weekend'>" . $in_time . 
					"</td><td class='weekend'>" . $a_diff['end_time'] . "</td><td class='weekend'> " . 
					$diff1 . "</td><td class='weekend'> " . sprintf('%.2f',$friendly_diff1) . "</td></tr>";
				//reg & f_reg are increased by punch_out - diff_end
				$diff2 = subtract_time($punch['time_out'],$a_diff['end_time']);
				$friendly_diff2 = make_friendly_time($diff2);
				sum_time($reg_time,$diff2);
				$friendly_reg_time = $friendly_reg_time + $friendly_diff2;
				//build rowstring2 regularly from diff_end to punch_out
				$rowstring2= "<tr><td>" . $a_diff['end_time'] . "</td><td>" . $out_time . "</td><td> " .
					$diff2 . "</td><td> " . sprintf('%.2f',$friendly_diff2) . "</td></tr>";
				//concat two rowstrings
				$rowstring = $rowstring1 . $rowstring2;
				break;
			//in the case the case the punch spans the whole differential shift			
			case 5:	
				//reg & f_reg are increased by diff_start - punch_in
				$diff1 = subtract_time($a_diff['start_time'],$punch['time_in']);
				$friendly_diff1 = make_friendly_time($diff1);
				sum_time($reg_time,$diff1);
				$friendly_reg_time = $friendly_reg_time + $friendly_diff1;
				//build rowstring1 regularly from punch_in until diff_start
				$rowstring1= "<tr><td>" . $in_time . "</td><td>" . $a_diff['start_time'] . "</td><td> " .
					$diff1 . "</td><td> " . sprintf('%.2f',$friendly_diff1) . "</td></tr>";
				//dif & f_diff increased by diff_end - diff_start
				$diff2 = subtract_time($a_diff['end_time'],$a_diff['start_time']);
				$friendly_diff2 = make_friendly_time($diff2);
				sum_time($diff_time,$diff2);
				$friendly_diff_time = $friendly_diff_time + $friendly_diff2;
				//build rowstring2 weekend from diff_start to diff_end
				$rowstring2= "<tr><td class='weekend'>" . $a_diff['start_time'] . 
					"</td><td class='weekend'>" . $a_diff['end_time'] . 
					"</td><td class='weekend'> " . $diff2 . 
					"</td><td class='weekend'> " . sprintf('%.2f',$friendly_diff2) . "</td></tr>";
				//reg & f_reg are increased by punch_out - diff_end
				$diff3 = subtract_time($punch['time_out'],$a_diff['end_time']);
				$friendly_diff3 = make_friendly_time($diff3);
				sum_time($reg_time,$diff3);
				$friendly_reg_time = $friendly_reg_time + $friendly_diff3;
				//build rowstring3 regularly from diff_end to punch_out
				$rowstring3= "<tr><td>" . $a_diff['end_time'] . "</td><td>" . $out_time . "</td><td> " .
					$diff3 . "</td><td> " . sprintf('%.2f',$friendly_diff3) . "</td></tr>";
				//concat three rowstrings
				$rowstring = $rowstring1 . $rowstring2 . $rowstring3;
				break;
		
		}//end switch
		}//end if(USE_DIFF_SHIFTS == TRUE)
		else{
			//Just set 
			$case = 1;
			$break_early = TRUE;

		}
		//if case is other than 1; we've found our punch/diff interacton, so break the foreach	
		if($case != 1 || $break_early==TRUE)
			break;
	}
	//If we reach this point, and case was 1 every time i.e. there are no diff periods that punch overlaps
	//then just display a normal output.  
	if($case == 1)
	{	
		$rowstring= "<tr><td>" . $in_time . "</td><td>" . $out_time . "</td><td> " . 
			$punch['time_worked'] . "</td><td> " . sprintf('%.2f',$worked_time) . "</td></tr>";
		sum_time($reg_time,$punch['time_worked']);
		$friendly_reg_time = $friendly_reg_time + $worked_time;
	}
	//in all cases...
	return $rowstring;
}

//function that returns an integer that's plugged into a switch statement
function determineCase($punch, $diff)
{
	//After spending a lot of time pulling my hair out about PHP's lack of handy time/date comparison 
	//and manipulation features, it occurred to me to create bogus punch values to make it simple to 
	//understand where they are in relation to each other, not unlike a regular Unix timestamp that counts
	//from Jan 1, 1970.  Getting one of those from a MySQL timestamp value (such as is used for punch records)
	//is no trouble, but as it turns out creating a synthetic timestamp that is in the same week as
	//the punch but is defined with a day of the week and a time has proved challenging.  So, I create my
	//own timestamps... 

	//first, determine our starting point.  
	$p_in_dow = date("N",strtotime($punch['time_in']));
	$p_out_dow = date("N",strtotime($punch['time_out']));

	//if end/out_d_o_w < start/in_d_o_w, add 7 to end/out_d_o_w
	if($p_out_dow < $p_in_dow)
	{
		$p_out_dow = $p_out_dow + 7;
	}

	if($diff['end_d_o_w'] < $diff['start_d_o_w'])
	{
		$diff['end_d_o_w'] = $diff['end_d_o_w'] + 7;
		if($p_out_dow < $diff['start_d_o_w'])
		{
			$p_in_dow = $p_in_dow +7;
			$p_out_dow = $p_out_dow + 7;			
		}
	}	

	//first, just do day_of_week comparisons - if there can't possibly be an overlap, return 1.
	//The things I'll do to save a few measly cycles...	
	if(($p_out_dow < $diff['start_d_o_w']) || ($p_in_dow > $diff['end_d_o_w']))
	{
		return 1;
	}

	//convert times to timestamp based on start of week.
	$diff_start = getTimestamp($diff['start_d_o_w'],$diff['start_time']);
	$diff_end = getTimestamp($diff['end_d_o_w'],$diff['end_time']);
	$punch_in = getTimestamp($p_in_dow, date("H:i:s",strtotime($punch['time_in'])));
	$punch_out = getTimestamp($p_out_dow, date("H:i:s",strtotime($punch['time_out'])));

	//and now, figure out where we're at and return the appropriate case
	//having done all of our homework before this, the logic is pretty straightforward...
	if(($diff_start <= $punch_in) && ($punch_in <= $diff_end))
	{	
		if(($diff_start <= $punch_out) && ($punch_out <= $diff_end))
		{
			return 2;
		}
		else
		{
			return 4;
		}
	}
	if(($diff_start <= $punch_out) && ($punch_out <= $diff_end))
	{
		return 3;
	}
	if(($punch_in <= $diff_start) && ($diff_start <= $punch_out))
	{
		return 5;
	}
	else
	{
		return 1;
	} 
}

//helper function for determineCase
function getTimestamp($d_o_w, $timestamp)
{
    $t_array = explode(":", $timestamp);
  
    // Convert each time to seconds, including days of week
    $result = (($d_o_w * 3600 * 24) + ($t_array[0] * 3600) + ($t_array[1] * 60) + ($t_array[2]));
   
   return $result; 
}

function print_add_edit_punch_form()
{
	echo "<h1 class='center'>Adding/Changing a Punch</h1>\n";

	echo "<br /><br /><b>So, you want to add (or edit!) a punch, eh?</b> Select a user (if adding) and a time to punch them in, and optionally a time to punch them out.  <br /><br />";

	/*create a value here to hold the Punch pid; if it's set to 0, we know not to 
	try and use already-existing values */
	$useExisting = FALSE;
	$timeIn = "0000-00-00 00:00:00";
	$timeOut = "0000-00-00 00:00:00";
	if (isset($_GET['pid']) && is_numeric($_GET['pid'])) 
	{
		$punchDetails = getPunchDetails($_GET['pid']);
		$useExisting = TRUE;
		$timeIn = $punchDetails['time_in'];
		$timeOut = $punchDetails['time_out'];
	}
	
	$users = sortUsersByName(getAllUserDetails()); 

	?>
	<form method='post' action='redirects/add_punch.php' id='modPunch'><div>
	<? 	
	if(!($useExisting))
	{ ?>
	<br /><label for='pid'>User: </label><p>
    <select name='pid' id='pid'><?
    	foreach ($users as $s) {
            echo "\n    <option value='".$s['pid']."'>".$s['name']."</option>";
    		}
	?>  
	</select>  <? 
	}
	//we don't want to select a user, but do want to keep the punch id number
	else
	{
		?> <input type='hidden' name='punch_pid' value='<?= $punchDetails['pid']?>' />
		<?
	}
	?>
	<br /><br />

	<label for 'leave_logged_in'>Leave the user logged in, and set no logout time?</label>
	<input type="checkbox" name="leave_logged_in" id="leave_logged_in" onchange="javascript:hideBlockIfChecked(this);">

	<br /><br />
	<label for 'time_in'>Time in: </label><p>
	<?
 	display_friendly_ymd_dropdowns("in", $timeIn);
	display_friendly_hm_box("in", $timeIn);
	?>
	
	<div id="time_out">
	<br /><br />
	<label for 'time_out'>Time out: </label><p>
	<?
	display_friendly_ymd_dropdowns("out", $timeOut);
	display_friendly_hm_box("out", $timeOut); 
	?>
	</div>

  <br /><br /><input type="submit" value="Add punch"/>
</div></form>

<?
}

function print_meeting_punch_form()
{
	//"prime" timeIn and timeOut to all zeros, so they'll use the current time
	$timeIn = "0000-00-00 00:00:00";
	$timeOut = "0000-00-00 00:00:00";

	?>
	<h1 class='center'>Mass-Punch Form</h1>
	<p>Select the users you want, and then the time in and out, and those users will be given punches that reflect their attendance during that time period.</p>
	<p>Click 'Mass Punch!' to apply your changes when you're done.</p>
	<form method='post' action='redirects/meeting_punch.php' onsubmit='selectDualsForMeeting()'>
	<div class='center'>
    	<h3>Users</h3>
	<?
    	$userIds = getUsers();
	//create an empty array, since no users will be selected by default
	$empty = array();
	
    	if (!$userIds) {
	?>  
	<p class='warn'>There are no users! Add some users and we'll talk. <br> 
   	<a href='register_users.php'>Add users</a></p>
	<?
    	} 
	else {
		 draw_dual_selects('users', $userIds, $empty,
                              'getUserDetails', 'sortUsersByName');	
   	 }
	?>

	<br />
	<br /><br />
	Time in:<br />
	<?
 	display_friendly_ymd_dropdowns("in", $timeIn);
	display_friendly_hm_box("in", $timeIn);
	?>
	<br /><br />
	Time out:<br />
	<?
 	display_friendly_ymd_dropdowns("out", $timeOut);
	display_friendly_hm_box("out", $timeOut);
	?>
	<br /><br />

	<input type='submit' name='mod_user' value='Mass Punch!' />&nbsp;&nbsp;
	<button onclick='javascript:window.location = "<?= BASE_URL ?>punch_tracking.php"; return false;'>Return to Punch Tracking</button>
	</div>
	</form>
	<br /><br />
	<?
}

function print_ip_form()
{
	$ip_list = getIPlist();	
	
	echo "<center>";
	echo "Use this form to delete IP addresses.<br /><br />";
	echo "</center>";
	echo "<table class='shift_history'>";
	
	if (!count($ip_list)) 
	{
        echo "<tr class='d0'><td class='center impt' colspan='3'>No IPs found in database.</td></tr>\n";
   	} 
	else {
    	foreach ($ip_list as $ip) {
            
		//supress displaying the 127.0.0.1 address here
		if(!($ip['addresses'] == "127.0.0.1"))
		{
           		echo "<tr><td>" . $ip['addresses'] . "</td><td>" .
                	 $ip['description'] . "</td>" .
                	 "<td class='noBorder'>".
                	    	"<a href='ip_delete.php?ip=".$ip['addresses']."'>".
               		  	"Delete</a></td>".
              		  	"</tr>\n";	
		}
	}//end foreach
    	}
	
    	echo "</table>";
	
	echo "<center><br /><br /><br />Are ye wantin' ta add an IP address?  'Ere's the place ta do it, lads and lasses!<br />";
	?>
	
	<form method='post' action='redirects/add_ip.php'>
	<label for='ip'>IP Address:</label>
    <input type='text' name='ip' id='ip' size='20' />
	<br /><label for='desc'>Description:</label>
    <input type='text' name='desc' id='desc' size='30' />
	<br /><input type='submit' name='add_ip' value='Add!' /><br /><br /></center>
	<?
	
}
Return current item: ConPortal