Location: PHPKode > projects > Timesheet Next Gen > timesheet.ng-1.5.0/simple.php
<?php
//$Header: /cvsroot/tsheet/timesheet.php/simple.php,v 1.7 2005/05/23 05:39:39 vexil Exp $
error_reporting(E_ALL);
ini_set('display_errors', true);

// Authenticate
require("class.AuthenticationManager.php");
require("class.CommandMenu.php");
require("class.Pair.php");
if (!$authenticationManager->isLoggedIn() || !$authenticationManager->hasAccess('aclSimple')) {
	Header("Location: login.php?redirect=$_SERVER[PHP_SELF]&clearanceRequired=" . get_acl_level('aclSimple'));
	exit;
}

// Connect to database.
$dbh = dbConnect();

//define the command menu & we get these variables from $_REQUEST:
//  $month $day $year $client_id $proj_id $task_id
include("timesheet_menu.inc");

$contextUser = strtolower($_SESSION['contextUser']);
$loggedInUser = strtolower($_SESSION['loggedInUser']);

if (empty($loggedInUser))
	errorPage("Could not determine the logged in user");

if (empty($contextUser))
	errorPage("Could not determine the context user");

//bug fix - we must display all projects
$proj_id = 0;
$task_id = 0;

//get the passed date (context date)
$todayStamp = mktime(0, 0, 0,$month, $day, $year);
$todayValues = getdate($todayStamp);
$curDayOfWeek = $todayValues["wday"];

//the day the week should start on: 0=Sunday, 1=Monday
$startDayOfWeek = getWeekStartDay();

$daysToMinus = $curDayOfWeek - $startDayOfWeek;
if ($daysToMinus < 0)
	$daysToMinus += 7;

$startDate = strtotime(date("d M Y H:i:s",$todayStamp) . " -$daysToMinus days");
$endDate = strtotime(date("d M Y H:i:s",$startDate) . " +7 days");

//get the configuration of timeformat and layout
list($qh2, $numq) = dbQuery("SELECT simpleTimesheetLayout FROM $CONFIG_TABLE WHERE config_set_id = '1'");
$configData = dbResult($qh2);
$layout = $configData['simpleTimesheetLayout'];

$post="";
?>
<html>
<head>
<title>Simple Weekly Timesheet for <?php echo "$contextUser" ?></title>
<?php
include ("header.inc");
?>
<script language="Javascript">
	//define the hash table
	var projectTasksHash = {};
<?php
//get all of the projects and put them into the hashtable
$getProjectsQuery = "SELECT $PROJECT_TABLE.proj_id, " .
							"$PROJECT_TABLE.title, " .
							"$PROJECT_TABLE.client_id, " .
							"$CLIENT_TABLE.client_id, " .
							"$CLIENT_TABLE.organisation " .
						"FROM $PROJECT_TABLE, $ASSIGNMENTS_TABLE, $CLIENT_TABLE " .
						"WHERE $PROJECT_TABLE.proj_id=$ASSIGNMENTS_TABLE.proj_id AND ".
							"$ASSIGNMENTS_TABLE.username='$contextUser' AND ".
							"$PROJECT_TABLE.client_id=$CLIENT_TABLE.client_id ".
						"ORDER BY $CLIENT_TABLE.organisation, $PROJECT_TABLE.title";

list($qh3, $num3) = dbQuery($getProjectsQuery);

//iterate through results
for ($i=0; $i<$num3; $i++) {
	//get the current record
	$data = dbResult($qh3, $i);
	print("projectTasksHash['" . $data["proj_id"] . "'] = {};\n");
	print("projectTasksHash['" . $data["proj_id"] . "']['name'] = '". addslashes($data["title"]) . "';\n");
	print("projectTasksHash['" . $data["proj_id"] . "']['clientId'] = '". $data["client_id"] . "';\n");
	print("projectTasksHash['" . $data["proj_id"] . "']['clientName'] = '". addslashes($data["organisation"]) . "';\n");
	print("projectTasksHash['" . $data["proj_id"] . "']['tasks'] = {};\n");
}

//get all of the tasks and put them into the hashtable
$getTasksQuery = "SELECT $TASK_TABLE.proj_id, " .
						"$TASK_TABLE.task_id, " .
						"$TASK_TABLE.name " .
					"FROM $TASK_TABLE, $TASK_ASSIGNMENTS_TABLE " .
					"WHERE $TASK_TABLE.task_id = $TASK_ASSIGNMENTS_TABLE.task_id AND ".
						"$TASK_ASSIGNMENTS_TABLE.username='$contextUser' ".
					"ORDER BY $TASK_TABLE.name";

list($qh4, $num4) = dbQuery($getTasksQuery);
//iterate through results
for ($i=0; $i<$num4; $i++) {
	//get the current record
	$data = dbResult($qh4, $i);
	print("if (projectTasksHash['" . $data["proj_id"] . "'] != null)\n");
	print("  projectTasksHash['" . $data["proj_id"] . "']['tasks']['" . $data["task_id"] . "'] = '" . addslashes($data["name"]) . "';\n");
}

?>

	//function to populate existing rows with project and task names and select the right one in each
	function populateExistingSelects() {
		//get the number of existing rows
		var existingRows = parseInt(document.getElementById('existingRows').value);
		//alert('There are ' + existingRows + ' existing rows');

		//iterate to plus one to do the additional row
		for (var i=0; i<=existingRows; i++) {
			//alert('existing row ' + i);

			//get the client, project and task id for this row
			var clientId = document.getElementById('client_row' + i).value;
			var projectId = document.getElementById('project_row' + i).value;
			var taskId = document.getElementById('task_row' + i).value;

			//get the selects
			var clientSelect = document.getElementById('clientSelect_row' + i);
			var projectSelect = document.getElementById('projectSelect_row' + i);
			var taskSelect = document.getElementById('taskSelect_row' + i);

			//add None to the selects
			clientSelect.options[clientSelect.options.length] = new Option('None', '-1');
			projectSelect.options[projectSelect.options.length] = new Option('None', '-1');
			taskSelect.options[taskSelect.options.length] = new Option('None', '-1');

			//add the clients
			//var clientId = -1;
			for (var key in projectTasksHash) {
				if (projectTasksHash[key]['clientId'] != clientId) {
					//projectSelect.options[projectSelect.options.length] = new Option('[' + projectTasksHash[key]['clientName'] + ']', -1);
					clientSelect.options[clientSelect.options.length] = new Option(projectTasksHash[key]['clientName'], projectTasksHash[key]['clientId']);
					clientId = projectTasksHash[key]['clientId'];
				}

				if (key == projectId && projectTasksHash[key]['clientId'] == clientId)
				{
					populateProjectSelect(i, clientId, key);
					clientSelect.options[clientSelect.options.length-1].selected = true;
				}
			}

			if (projectId != -1) {
				//add the tasks
				var thisProjectTasks = projectTasksHash[projectId]['tasks'];
				for (taskKey in thisProjectTasks) {
					taskSelect.options[taskSelect.options.length] = new Option(thisProjectTasks[taskKey], taskKey);

					if (taskKey == taskId)
						taskSelect.options[taskSelect.options.length-1].selected = true;
				}
			}
		}
	}

	function populateTaskSelect(row, projectId, selectedTaskId) {
		//get the task select for this row
		var taskSelect = document.getElementById('taskSelect_row' + row);

		//add the tasks
		var thisProjectTasks = projectTasksHash[projectId]['tasks'];
		for (var taskKey in thisProjectTasks) {
			taskSelect.options[taskSelect.options.length] = new Option(thisProjectTasks[taskKey], taskKey);

			if (taskKey == selectedTaskId)
				taskSelect.options[taskSelect.options.length-1].selected = true;
		}
	}

	function populateProjectSelect(row, clientId, selectedProjectId) {
		//get the project select for this row
		var projectSelect = document.getElementById('projectSelect_row' + row);

		//add the projects
		for (key in projectTasksHash) {
			if (projectTasksHash[key]['clientId'] == clientId) {
				projectSelect.options[projectSelect.options.length] = new Option(projectTasksHash[key]['name'], key);
				if (key == selectedProjectId)
				{
					projectSelect.options[projectSelect.options.length-1].selected = true;
				}
			}
		}
	}

	function clearTaskSelect(row) {
		taskSelect = document.getElementById('taskSelect_row' + row);
		for (var i=1; i<taskSelect.options.length; i++)
			taskSelect.options[i] = null;

		//set the length back to 1
		taskSelect.options.length = 1;

		//select the 'None' option
		taskSelect.options[0].selected = true;

		onChangeTaskSelectRow(row);
	}

	function clearProjectSelect(row) {
		projectSelect = document.getElementById('projectSelect_row' + row);
		for (i=1; i<projectSelect.options.length; i++) {
			projectSelect.options[i] = null;
		}

		projectSelect.options.length = 1;
		projectSelect.options[0].selected = true;
	}

	function clearWorkDescriptionField(row) {
		descField = document.getElementById("description_row" + row);
		descField.value = "";
	}

	function rowFromIdStr(idStr) {
		var pos1 = idStr.indexOf("row") + 3;
		var pos2 = idStr.indexOf('_', pos1);
		if (pos2 == -1)
			pos2 = idStr.length;
		return parseInt(idStr.substring(pos1, pos2));
	}

	function colFromIdStr(idStr) {
		var pos1 = idStr.indexOf("col") + 3;
		var pos2 = idStr.indexOf('_', pos1);
		if (pos2 == -1)
			pos2 = idStr.length;
		return parseInt(idStr.substring(pos1, pos2));
	}

	function onChangeProjectSelect(idStr) {
		row = rowFromIdStr(idStr);
		clearTaskSelect(row);

		//get the project id
		var projectSelect = document.getElementById('projectSelect_row' + row);
		var projectId = projectSelect.options[projectSelect.selectedIndex].value;

		if (projectId != -1)
			//populate the select with tasks for this project
			populateTaskSelect(row, projectId);

		setDirty();
	}

	function onChangeClientSelect(idStr) {
		row = rowFromIdStr(idStr);
		clearProjectSelect(row);
		clearTaskSelect(row);

		var clientSelect = document.getElementById('clientSelect_row' + row);
		var clientId = clientSelect.options[clientSelect.selectedIndex].value;

		if (clientId != -1) {
			populateProjectSelect(row, clientId);
		}
	}

	function onChangeTaskSelect(idStr) {
		var rowNum = rowFromIdStr(idStr);
		//alert('octs called for row ' + rowNum);
		onChangeTaskSelectRow(rowNum);
	}

	function onChangeTaskSelectRow(row) {
		taskSelect = document.getElementById('taskSelect_row' + row);
		//alert('octsr called for row ' + row);
		if (taskSelect.options[0].selected == true) {
			//disable fields
			for (var i=1; i<=7; i++) {
				document.getElementById('hours_row' + row + '_col' + i).disabled = true;
				document.getElementById('mins_row' + row + '_col' + i).disabled = true;
			}
		} 
		else {
			//get the total number of rows
			var totalRows = parseInt(document.getElementById('totalRows').value);
			//alert('change task droplist on row ' + row + ', totalRows=' + totalRows);

			if (row == (totalRows-1)) {
				//get the row to copy
				var tempNode = document.getElementById('row' + row);

				//clone the row
				var newNode = tempNode.cloneNode(true);

				//setup the pattern to match
				var rowRegex = new RegExp("row(\\d+)");

				//iterate through with dom and replace all name and id attributes with regexp
				replaceIdAndNameAttributes(newNode, rowRegex, totalRows);

				//increment totalRows by one
				//alert('totalRows was ' + document.getElementById('totalRows').value);
				document.getElementById('totalRows').value = parseInt(document.getElementById('totalRows').value) + 1;
				//alert('totalRows is now ' + document.getElementById('totalRows').value);

				//get the totals node
				var totalsNode = document.getElementById('totalsRow');

				//insert the new node before the totals node
				totalsNode.parentNode.insertBefore(newNode, totalsNode);

				//enable fields
				for (var i=1; i<=7; i++) {
					document.getElementById('hours_row' + row + '_col' + i).disabled = false;
					document.getElementById('mins_row' + row + '_col' + i).disabled = false;
				}

				//clear the task select
				clearTaskSelect(totalRows);

				// clear the work description field
				clearWorkDescriptionField(totalRows);

				clearProjectSelect(totalRows);

				/* //select default project
				var oldProjectSelect = document.getElementById('projectSelect_row' + row);
				var newProjectSelect = document.getElementById('projectSelect_row' + (row+1));
				newProjectSelect.options[oldProjectSelect.selectedIndex].selected = true;

				//repopulate task
				var projectId = newProjectSelect.options[newProjectSelect.selectedIndex].value;
				populateTaskSelect(row+1, projectId); */

			}

		}
		setDirty();
	}

	function onChangeWorkDescription(idStr) {
		setDirty();
	}

	//clear row and make it invisible
	function onDeleteRow(idStr) {
		var row = rowFromIdStr(idStr);
		var tr = document.getElementById('row' + row)

		// clear the task select
		clearTaskSelect(row);

		// clear the work description field
		clearWorkDescriptionField(row);

		// clear hours and minutes
		for (var i=1; i<=7; i++) {
			document.getElementById("hours_row" + row + "_col" + i).value = "";
			document.getElementById("mins_row" + row + "_col" + i).value = "";
			recalculateCol(i,idStr);
		}

		tr.style.display = "none";
	}

	function replaceIdAndNameAttributes(node, rowRegex, rowNumber) {
		while (node != null) {
			if (node.getAttribute != null && node.getAttribute("id") != null)
				node.setAttribute("id", node.getAttribute("id").replace(rowRegex, "row" + rowNumber));
			if (node.getAttribute != null && node.getAttribute("name") != null)
				node.setAttribute("name", node.getAttribute("name").replace(rowRegex, "row" + rowNumber));

			// call this function recursively for children
			// did not to work recursely with if statement like it was:
			// if (node.firstChild != null && node.firstChild.tagName != null)
			if (node.firstChild != null)
				replaceIdAndNameAttributes(node.firstChild, rowRegex, rowNumber);

			//do the same for the next sibling
			node = node.nextSibling;
		}
	}

	function recalculateRowCol(idStr) {
		recalculateRow(rowFromIdStr(idStr));
		recalculateCol(colFromIdStr(idStr),idStr);
		setDirty();
	}

	function recalculateRow(row) {
		var totalMins = 0;
		for (i=1; i<=7; i++) {
			minsinday = parseInt(document.getElementById("minsinday_" + i).value);
			//var hrsinday = minsinday/60;
			hours = parseInt(document.getElementById("hours_row" + row + "_col" + i).value);
			mins = parseInt(document.getElementById("mins_row" + row + "_col" + i).value);
			if (isNaN(hours)) {
				hours = 0;
			}
			if (isNaN(mins)) {
				mins = 0;
			}

			var minutes = hours * 60 + mins;

			if (minutes > minsinday) {
				alert("Too much time, date only has " + minsinday/60 + " hours in the day");
				document.getElementById("hours_row" + row + "_col" + i).value="";  //=true;
				document.getElementById("mins_row" + row + "_col" + i).value="";  //=true;
				document.getElementById("hours_row" + row + "_col" + i).select();  //=true;
				document.getElementById("mins_row" + row + "_col" + i).select();  //=true;
				document.getElementById("hours_row" + row + "_col" + i).select();  //=true;
				return false;
			}
			totalMins += minutes;
		}

		hours = Math.floor(totalMins / 60);
		mins = totalMins - (hours * 60);

		//get the total cell
		var totalCell = document.getElementById("subtotal_row" + row);
		totalCell.innerHTML = '' + hours + 'h&nbsp;' + mins + 'm';
	}

	function recalculateCol(col,idStr) {
		//get the total number of rows
		var totalRows = parseInt(document.getElementById('totalRows').value);
		var minsinday = parseInt(document.getElementById("minsinday_" + col).value);

		var totalMins = 0;
		var row="";
		for (var i=0; i<totalRows; i++) {
			hours = parseInt(document.getElementById("hours_row" + i + "_col" + col).value);
			mins = parseInt(document.getElementById("mins_row" + i + "_col" + col).value);
			if (isNaN(hours)) {
				hours = 0;
			}
			if (isNaN(mins)) {
				mins = 0;
			}

			var minutes = hours * 60 + mins;

			totalMins += minutes;
		}

		if (totalMins > minsinday) {
			alert("Too much time, only " + minsinday/60 + " hours in the day, check your column");
			row=rowFromIdStr(idStr);
			document.getElementById("hours_row" + row + "_col" + col).value="";  //=true;
			document.getElementById("mins_row" + row + "_col" + col).value="";  //=true;
			document.getElementById("hours_row" + row + "_col" + col).select();  //=true;
			document.getElementById("mins_row" + row + "_col" + col).select();  //=true;
			document.getElementById("hours_row" + row + "_col" + col).select();  //=true;
			return false;
		}

		hours = Math.floor(totalMins / 60);
		mins = totalMins - (hours * 60);

		//get the total cell
		var totalCell = document.getElementById("subtotal_col" + col);
		totalCell.innerHTML = '' + hours + 'h&nbsp;' + mins + 'm';

		recalculateGrandTotal();
	}

	function recalculateGrandTotal() {
		var totalMins = 0;
		for (var i=1; i<=7; i++) {
			var currentInnerHTML = document.getElementById("subtotal_col" + i).innerHTML;
			//get the hours
			hPos = currentInnerHTML.indexOf('h');
			hours = parseInt(currentInnerHTML.substring(0, hPos));
			if (!isNaN(hours))
				totalMins += hours * 60;

			//get the minutes
			mPos = currentInnerHTML.indexOf('m');
			mins = parseInt(currentInnerHTML.substring(hPos+7, mPos));
			if (!isNaN(mins))
				totalMins += mins;
		}

		hours = Math.floor(totalMins / 60);
		mins = totalMins - (hours * 60);

		//get the grand total cell
		var grandTotalCell = document.getElementById("grand_total");
		grandTotalCell.innerHTML = '' + hours + 'h&nbsp;' + mins + 'm';
	}

	function setDirty() {
		document.getElementById("saveButton").disabled = false;
	}

	function validate() {
		//get the total number of rows
		var totalRows = parseInt(document.getElementById('totalRows').value);

		//iterate through rows
		for (var i=0; i<totalRows; i++) {
			//iterate through cols
			for (var j=1; j<=7; j++) {
				hours = parseInt(document.getElementById("hours_row" + i + "_col" + j).value);
				mins = parseInt(document.getElementById("mins_row" + i + "_col" + j).value);
				if (isNaN(hours)) {
					hours = 0;
				}
				if (isNaN(mins)) {
					mins = 0;
				}

				var minsinday = parseInt(document.getElementById("minsinday_" + j).value);

				var minutes = hours * 60 + mins;

				if (minutes > minsinday) {
					alert("Too much time, date only has " + minsinday/60 + " hours in the day");
					document.getElementById("hours_row" + i + "_col" + j).value="";  //=true;
					document.getElementById("mins_row" + i + "_col" + j).value="";  //=true;
					document.getElementById("hours_row" + i + "_col" + j).select();  //=true;
					document.getElementById("mins_row" + i + "_col" + j).select();  //=true;
					document.getElementById("hours_row" + i + "_col" + j).select();  //=true;
					return false;
				}
			}
		}

		document.theForm.submit();
	}

</script>
</head>
<?php
echo "<body width=\"100%\" height=\"100%\" onLoad=\"populateExistingSelects();\"";
include ("body.inc");
if (isset($popup))
	echo "onLoad=window.open(\"clock_popup.php?proj_id=$proj_id&task_id=$task_id\",\"Popup\",\"location=0,directories=no,status=no,menubar=no,resizable=1,width=420,height=205\");";
echo ">\n";

include ("banner.inc");
include("navcal/navcalendars.inc");
?>

<form name="theForm" action="simple_action.php" method="post">
<input type="hidden" name="year" value=<?php echo $year; ?>>
<input type="hidden" name="month" value=<?php echo $month; ?>>
<input type="hidden" name="day" value=<?php echo $day; ?>>
<input type="hidden" name="startStamp" value=<?php echo $startDate; ?>>

<table width="100%" border="0" cellspacing="0" cellpadding="0">
	<tr>
		<td width="100%" class="face_padding_cell">

<!-- include the timesheet face up until the heading start section -->
<?php include("timesheet_face_part_1.inc"); ?>

				<table width="100%" border="0">
					<tr>
						<td align="left" nowrap class="outer_table_heading">
							Timesheet
						</td>
						<td align="middle" nowrap class="outer_table_heading">
							<?php
								$sdStr = date("M d, Y",$startDate);
								//just need to go back 1 second most of the time, but DST 
								//could mess things up, so go back 6 hours...
								$edStr = date("M d, Y",$endDate - 6*60*60); 
								echo "Week: $sdStr - $edStr"; 
							?>
						</td>
						<td align="right" nowrap>
							<!--prev / next buttons used to be here -->
						</td>
						<td align="right" nowrap>
							<input type="button" name="saveButton" id="saveButton" value="Save Changes" disabled="true" onClick="validate();" />
						</td>
					</tr>
				</table>

<!-- include the timesheet face up until the heading start section -->
<?php include("timesheet_face_part_2.inc"); ?>

	<table width="100%" align="center" border="0" cellpadding="0" cellspacing="0" class="outer_table">
		<tr>
			<td>
				<table width="100%" border="0" cellspacing="0" cellpadding="0" class="table_body">
					<tr class="inner_table_head">
						<td class="inner_table_column_heading" align="center">
							Client / Project / Task<?php if(strstr($layout, 'no work description') == '') echo ' / Work Description'; ?>
						</td>
						<td align="center" width="2">&nbsp;</td>
						<?php
						//print the days of the week
						$currentDayDate = $startDate;
						$dstadj=array();
						for ($i=0; $i<7; $i++) {
							$currentDayStr = strftime("%a", $currentDayDate);
							$dst_adjustment = get_dst_adjustment($currentDayDate);
							$dstadj[]=$dst_adjustment;
							$minsinday = ((24*60*60) - $dst_adjustment)/60;
							print "<input type=\"hidden\" id=\"minsinday_".($i+1)."\" value=\"$minsinday\">";
							print
								"<td align=\"center\" width=\"65\">" .
								"<table width=\"65\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr>" .
								"<td class=\"inner_table_column_heading\" align=\"center\">" .
								"$currentDayStr<br>" .
								//Output the numerical date in the form of day of the month
								date("d", $currentDayDate) .
								"</td></tr></table></td>\n";
							$currentDayDate = strtotime(date("d M Y H:i:s",$currentDayDate) . " +1 days");
						}
						?>
						<td align="center" width="2">&nbsp;</td>
						<td class="inner_table_column_heading" align="center" width="50">Total</td>
						<td align="center" width="2">&nbsp;</td>
						<td class="inner_table_column_heading" align="center" width="50">delete</td>
					</tr>
					<tr>
<?php

	//debug
	//$startDateStr = strftime("%D", $startDate);
	//$endDateStr = strftime("%D", $endDate);
	//print "<p>WEEK start: $startDateStr WEEK end: $endDateStr</p>";


	class TaskInfo extends Pair {
		var $clientId;
		var $projectId;
		var $projectTitle;
		var $taskName;
		var $workDescription;

		function TaskInfo($value1, $value2, $projectId, $projectTitle, $taskName, $workDescription) {
			parent::Pair($value1, $value2);
			$this->projectId = $projectId;
			$this->projectTitle = $projectTitle;
			$this->taskName = $taskName;
			$this->workDescription = $workDescription;
		}
	}

	function printSpaceColumn() {
		print "<td class=\"calendar_cell_disabled_middle\" width=\"2\">&nbsp;</td>";
	}

	/*=======================================================================
	 ==================== Function PrintFormRow =============================
	 =======================================================================*/

	// taskId = $matchedPair->value1, daysArray = $matchedPair->value2
	// $allTasksDayTotals = int[7] and sums up the minutes for all tasks at one day
	// usage: provide an index to generate an empty row or ALL parameters to prefill the row
	function printFormRow($rowIndex, $layout, $projectId = "", $taskId = "", $workDescription = "", $startDate = null, $daysArray = NULL) {
		// print project, task and optionally work description
		global $allTasksDayTotals; //global because of PHP4 thing about passing by reference?
		?>
		<tr id="row<?php echo $rowIndex; ?>">
			<td class="calendar_cell_middle" valign="top">
			<table width="100%" border="0" cellspacing="0" cellpadding="0">
				<tr>
				<?php
					switch ($layout) {
						case "no work description field":
							?>
							<td align="left" style="width:33%;">
								<input type="hidden" id="client_row<?php echo $rowIndex; ?>" name="client_row<?php echo $rowIndex; ?>" value="<?php echo $clientId; ?>" />
								<select id="clientSelect_row<?php echo $rowIndex; ?>" name="clientSelect_row<?php echo $rowIndex; ?>" onChange="onChangeClientSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:33%;">
								<input type="hidden" id="project_row<?php echo $rowIndex; ?>" name="project_row<?php echo $rowIndex; ?>" value="<?php echo $projectId; ?>" />
								<select id="projectSelect_row<?php echo $rowIndex; ?>" name="projectSelect_row<?php echo $rowIndex; ?>" onChange="onChangeProjectSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:33%;">
								<input type="hidden" id="task_row<?php echo $rowIndex; ?>" name="task_row<?php echo $rowIndex; ?>" value="<?php echo $taskId; ?>" />
								<select id="taskSelect_row<?php echo $rowIndex; ?>" name="taskSelect_row<?php echo $rowIndex; ?>" onChange="onChangeTaskSelect(this.id);" style="width: 100%;" />
							</td>
							<?php
							break;

						case "big work description field":
							// big work description field
							?>
							<td align="left" style="width:100px;">
								<input type="hidden" id="client_row<?php echo $rowIndex; ?>" name="client_row<?php echo $rowIndex; ?>" value="<?php echo $clientId; ?>" />
								<select id="clientSelect_row<?php echo $rowIndex; ?>" name="clientSelect_row<?php echo $rowIndex; ?>" onChange="onChangeClientSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:160px;">
								<input type="hidden" id="project_row<?php echo $rowIndex; ?>" name="project_row<?php echo $rowIndex; ?>" value="<?php echo $projectId; ?>" />
								<select id="projectSelect_row<?php echo $rowIndex; ?>" name="projectSelect_row<?php echo $rowIndex; ?>" onChange="onChangeProjectSelect(this.id);" style="width: 100%;" />
								<br/>
								<input type="hidden" id="task_row<?php echo $rowIndex; ?>" name="task_row<?php echo $rowIndex; ?>" value="<?php echo $taskId; ?>" />
								<select id="taskSelect_row<?php echo $rowIndex; ?>" name="taskSelect_row<?php echo $rowIndex; ?>" onChange="onChangeTaskSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:auto;">
								<textarea rows="2" style="width:100%;" id="description_row<?php echo $rowIndex; ?>" name="description_row<?php echo $rowIndex; ?>" onKeyUp="onChangeWorkDescription(this.id);"><?php echo $workDescription; ?></textarea>
							</td>
							<?php
							break;

						case "small work description field":
						default:
							// small work description field = default layout
							?>
							<td align="left" style="width:100px;">
								<input type="hidden" id="client_row<?php echo $rowIndex; ?>" name="client_row<?php echo $rowIndex; ?>" value="<?php echo $clientId; ?>" />
								<select id="clientSelect_row<?php echo $rowIndex; ?>" name="clientSelect_row<?php echo $rowIndex; ?>" onChange="onChangeClientSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:100px;">
								<input type="hidden" id="project_row<?php echo $rowIndex; ?>" name="project_row<?php echo $rowIndex; ?>" value="<?php echo $projectId; ?>" />
								<select id="projectSelect_row<?php echo $rowIndex; ?>" name="projectSelect_row<?php echo $rowIndex; ?>" onChange="onChangeProjectSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:140px;">
								<input type="hidden" id="task_row<?php echo $rowIndex; ?>" name="task_row<?php echo $rowIndex; ?>" value="<?php echo $taskId; ?>" />
								<select id="taskSelect_row<?php echo $rowIndex; ?>" name="taskSelect_row<?php echo $rowIndex; ?>" onChange="onChangeTaskSelect(this.id);" style="width: 100%;" />
							</td>
							<td align="left" style="width:auto;">
								<input type="text" id="description_row<?php echo $rowIndex; ?>" name="description_row<?php echo $rowIndex; ?>" onChange="onChangeWorkDescription(this.id);" value="<?php echo $workDescription; ?>" style="width: 100%;" />
							</td>
							<?php
							break;
					}

				?>
				</tr>
			</table>
		</td>
		<?php

		printSpaceColumn();

		$weeklyTotal = 0;
		$isEmptyRow = ($daysArray == null);

		//print_r($daysArray); print "<br>";

		//print hours and minutes input field for each day

		for ($currentDay = 0; $currentDay < 7; $currentDay++) {
			//open the column
			print "<td class=\"calendar_cell_middle\" valign=\"top\" align=\"left\">";

			//while we are printing times set the style
			print "<span class=\"task_time_small\">";

			//declare current days vars
			$curDaysTotal = 0;
			$curDaysHours = "";
			$curDaysMinutes = "";

			// if there is an $daysArray calculate current day's minutes and hours

			if (!$isEmptyRow) {
				$currentDayArray = $daysArray[$currentDay];

				foreach ($currentDayArray as $taskDuration) {
					$curDaysTotal += $taskDuration;
				}
				$curDaysHours = floor($curDaysTotal / 60 );
				$curDaysMinutes = $curDaysTotal - ($curDaysHours * 60);
			}

			// write summary and totals of this row

			//create a string to be used in form input names
			$rowCol = "_row" . $rowIndex . "_col" . ($currentDay+1);
			$disabled = $isEmptyRow?'disabled="true" ':'';

			print "<span nowrap><input type=\"text\" id=\"hours" . $rowCol . "\" name=\"hours" . $rowCol . "\" size=\"1\" value=\"$curDaysHours\" onChange=\"recalculateRowCol(this.id)\" onKeyDown=\"setDirty()\" $disabled/>h</span>";
			print "<span nowrap><input type=\"text\" id=\"mins" . $rowCol . "\" name=\"mins" . $rowCol . "\" size=\"1\" value=\"$curDaysMinutes\" onChange=\"recalculateRowCol(this.id)\" onKeyDown=\"setDirty()\" $disabled/>m</span>";

			//close the times class
			print "</span>";

			//end the column
			print "</td>";

			//add this days total to the weekly total
			$weeklyTotal += $curDaysTotal;

			// add this days total to the all tasks total for this day
			// if an array is provided by the caller
			if ($allTasksDayTotals != null) {
				$allTasksDayTotals[$currentDay] += $curDaysTotal;
			}
		}

		printSpaceColumn();

		//format the weekly total
		$weeklyTotalStr = formatMinutes($weeklyTotal);

		//print the total column
		print "<td class=\"calendar_totals_line_weekly\" valign=\"bottom\" align=\"right\" class=\"subtotal\">";
		print "<span class=\"calendar_total_value_weekly\" align=\"right\" id=\"subtotal_row" . $rowIndex . "\">$weeklyTotalStr</span></td>";

		printSpaceColumn();

		// print delete button
		print "<td class=\"calendar_delete_cell\" class=\"subtotal\">";
		print "<a id=\"delete_row$rowIndex\" href=\"#\" onclick=\"onDeleteRow(this.id); return false;\">x</a></td>";

		//end the row
		print "</tr>";
	}

	/*=======================================================================
	 ================ end Function PrintFormRow =============================
	 =======================================================================*/

	// Get the Weekly user data.
	$startStr = date("Y-m-d H:i:s",$startDate);
	$endStr = date("Y-m-d H:i:s",$endDate);
	$order_by_str = "$CLIENT_TABLE.organisation, $PROJECT_TABLE.title, $TASK_TABLE.name";
	list($num5, $qh5) = get_time_records($startStr, $endStr, $contextUser, 0, 0, $order_by_str);

	//we're going to put the data into an array of
	//different (unique) TASKS
	//which has an array of DAYS (7) which has
	//an array of task durations for that day

	$structuredArray = array();
	$previousTaskId = -1;
	$currentTaskId = -1;

	//iterate through results
	for ($i=0; $i<$num5; $i++) {
		//get the record for this task entry
		$data = dbResult($qh5,$i);

		//There are several potential problems with the date/time data comming from the database
		//because this application hasn't taken care to cast the time data into a consistent TZ.
		//See: http://jokke.dk/blog/2007/07/timezones_in_mysql_and_php & read comments
		//So, we handle it as best we can for now...
		fixStartEndDuration($data);

		//get the current task properties
		$currentTaskId = $data["task_id"];
		$currentTaskStartDate = $data["start_stamp"];
		$currentTaskEndDate = $data["end_stamp"];
		$currentTaskName = stripslashes($data["taskName"]);
		$currentProjectTitle = stripslashes($data["projectTitle"]);
		$currentProjectId = $data["proj_id"];
		$currentWorkDescription = $data["log_message"];

		//debug
		//print "<p>taskId:$currentTaskId '$data[taskName]', start time:$data[start_time_str], end time:$data[end_time_str]</p>";

		// Combine multiple entries for a given project/task & description into a single line
		// look for the current task id in the array
		$taskCount = count($structuredArray);
		unset($matchedPair);
		for ($j=0; $j<$taskCount; $j++) {
			// does(taskID [value1] && workDescription) match?
			if ($structuredArray[$j]->value1 == $currentTaskId && $structuredArray[$j]->workDescription == $currentWorkDescription) {
				//store the pair we matched with
				$matchedPair = &$structuredArray[$j];

				//debug
				//print "<p> found existing matched pair so adding to that one </p>";

				//break since it matched
				break;
			}
		}

		//was it not matched
		if (!isset($matchedPair)) {

			//debug
			//print "<p> creating a new matched pair for this task </p>";

			//create a new days array
			$daysArray = array();

			for ($j=0; $j<7; $j++) {
				//create a task event types array
				$taskEventTypes = array();

				//add the task event types array to the days array for this day
				$daysArray[] = $taskEventTypes;
			}

			//create a new pair
			$matchedPair = new TaskInfo($currentTaskId, $daysArray,
										$currentProjectId, $currentProjectTitle,
										$currentTaskName, $currentWorkDescription
										);

			//add the matched pair to the structured array
			$structuredArray[] = $matchedPair;

			//make matchedPair be a reference to where we copied it to
			$matchedPair = &$structuredArray[count($structuredArray)-1];

			//print "<p> added matched pair with task '$matchedPair->taskName'</p>";
		}

		//iterate through the days array  
		$currentDayDate = $startDate;
		for ($k=0; $k<7; $k++) {
			$tomorrowDate = strtotime(date("d M Y H:i:s",$currentDayDate) . " +1 days");

			$duration = 0;
			if(isset($data["duration"]) && ($data["duration"] > 0) ) {
				$duration = $data["duration"];
			}

			$startsToday = (($currentTaskStartDate >= $currentDayDate ) && ( $currentTaskStartDate < $tomorrowDate ));
			$endsToday =   (($currentTaskEndDate > $currentDayDate) && ($currentTaskEndDate <= $tomorrowDate));
			$startsBeforeToday = ($currentTaskStartDate < $currentDayDate);
			$endsAfterToday = ($currentTaskEndDate > $tomorrowDate);

			if($startsToday && $endsToday ) {
				$matchedPair->value2[$k][] = $duration;
			} else if($startsToday && $endsAfterToday) {
				$matchedPair->value2[$k][] = get_duration($currentTaskStartDate, $tomorrowDate);
			} else if( $startsBeforeToday && $endsToday ) {
				$matchedPair->value2[$k][] = get_duration($currentDayDate, $currentTaskEndDate);
			} else if( $startsBeforeToday && $endsAfterToday ) {
				$matchedPair->value2[$k][] = get_duration($currentDayDate, $tomorrowDate);
			}

			$currentDayDate = $tomorrowDate;
		}
	}

	//by now we should have our results structured in such a way that it it easy to output it

	//set vars
	$previousProjectId = -1;
	$allTasksDayTotals = array(0,0,0,0,0,0,0); //totals for each day

/*	$previousTaskId = -1;
	$thisTaskId = -1;
	$columnDay = -1;
	$columnStartDate = $startDate;*/


//iterate through the structured array
	$count = count($structuredArray);
	unset($matchedPair);
	for ($rowIndex = 0; $rowIndex<$count; $rowIndex++) {
		$matchedPair = &$structuredArray[$rowIndex];

		printFormRow($rowIndex, $layout,
					 $matchedPair->projectId,
					 $matchedPair->value1,
					 $matchedPair->workDescription,
					 $startDate,
					 $matchedPair->value2,
					 $allTasksDayTotals);


		//store the previous task and project ids
		$previousTaskId = $matchedPair->value1;
		$previousProjectId = $matchedPair->projectId;
	}

	/////////////////////////////////////////
	//add an extra row for new data entry
	/////////////////////////////////////////

	printFormRow($count, $layout, -1, -1);

	//store a hidden form field containing the number of existing rows
	print "<input type=\"hidden\" id=\"existingRows\" name=\"existingRows\" value=\"" . $count . "\" />";

	//store a hidden form field containing the total number of rows
	print "<input type=\"hidden\" id=\"totalRows\" name=\"totalRows\" value=\"" . ($count+1) . "\" />";

	////////////////////////////////////////////////////
	//Changes reequired to enter data on form -define 10 entry rows

//	for ($i=0; $i<10; $i

	////////////////////////////////////////////////////

	//create a new totals row
	print "<tr id=\"totalsRow\">\n";
	print "<td class=\"calendar_cell_disabled_middle\" align=\"right\">Total Hours:</td>\n";
	print "<td class=\"calendar_cell_disabled_middle\" width=\"2\">&nbsp;</td>\n";

	//iterate through day totals for all tasks
	$grandTotal = 0;
	$col = 0;
	foreach ($allTasksDayTotals as $currentAllTasksDayTotal) {
		$col++;
		$grandTotal += $currentAllTasksDayTotal;
		$formattedTotal = formatMinutes($currentAllTasksDayTotal);
		print "<td class=\"calendar_totals_line_weekly_right\" align=\"right\">\n";
		print "<span class=\"calendar_total_value_weekly\" id=\"subtotal_col" . $col . "\">$formattedTotal</span></td>";
	}

	//print grand total
	$formattedGrandTotal = formatMinutes($grandTotal);
	print "<td class=\"calendar_cell_disabled_middle\" width=\"2\">&nbsp;</td>\n";
	print "<td class=\"calendar_totals_line_monthly\" align=\"right\">\n";
	print "<span class=\"calendar_total_value_monthly\" id=\"grand_total\">$formattedGrandTotal</span></td>";
	print "</tr>";

?>

				</table>
			</td>
		</tr>
	</table>

<!-- include the timesheet face up until the end -->
<?php include("timesheet_face_part_3.inc"); ?>

		</td>
	</tr>
</table>

</form>
<?php
include ("footer.inc");
?>
</body>
</html>
<?php
// vim:ai:ts=4:sw=4
?>
Return current item: Timesheet Next Gen