1<?php
2function task_list($pid, $status, $order) {
3    global $conn, $appconf, $smarty;
4    $tasks = array();
5    // print the nice indented list
6    $sql = "SELECT * FROM mgw_projects_tasks WHERE parent_id = 0 AND project_id='$pid' ORDER BY $order";
7    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
8    while($task = $res->FetchRow()) {
9	$sql2 = "SELECT ".$conn->Concat('lastname',"', '",'firstname')." AS uname FROM mgw_users WHERE id='".$task['assignee']."'";
10	if(($user = $conn->GetRow($sql2))===false) exit(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
11	$task['uname'] = $user['uname'];
12	if (get_decendents($task['task_id'],$status) || $task['status']==$status) {
13	    if ($task['status'] == "$status") {
14		if ($status==1) {
15		    if (get_children($task['task_id'],1)) {
16			$task['action']['url'][0] = "#";
17			$task['action']['img'][0] = "d-off.gif";
18			$task['action']['url'][1] = "#";
19			$task['action']['img'][1] = "f-off.gif";
20		    } else {
21			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
22			$task['action']['img'][0] = "d-on.gif";
23			$task['action']['url'][1] = "index.php?obj=task&amp;action=finish&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
24			$task['action']['img'][1] = "f-on.gif";
25		    }
26		} else {
27		    if (get_children($task['task_id'],0)) {
28			$task['action']['url'][0] = "#";
29			$task['action']['img'][0] = "d-off.gif";
30			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&pid=$pid&amp;".SID;
31			$task['action']['img'][1] = "r-on.gif";
32		    } else {
33			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
34			$task['action']['img'][0] = "d-on.gif";
35			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&amp;pid=$pid&amp;".SID;
36			$task['action']['img'][1] = "r-on.gif";
37		    }
38		}
39	    } else {
40		$task['class'] = 'tab';
41		$task['action']['url'][0] = "#";
42		$task['action']['img'][0] = "d-off.gif";
43		$task['action']['url'][1] = "#";
44		$task['action']['img'][1] = "f-off.gif";
45	    }
46	    $tasks[] = $task;
47	}
48	$tasks = print_tree($task['task_id'], 0, $status, $tasks);
49    }
50    $smarty->assign('tstatus', $status);
51    $smarty->assign('totalhours', ($status == 1) ? hours_todo($pid) : hours_done($pid));
52    $smarty->assign('totalusedhours', ($status == 1) ? usedhours_todo($pid) : usedhours_done($pid));
53    $smarty->assign('tasks', $tasks);
54    return $smarty->fetch('projects_tasklist.tpl');
55}
56
57function print_tree($task_id, $count, $status, $tasks) {
58    global $conn, $appconf;
59
60    $count++;
61    $result = get_children($task_id, 2);
62    for ($x=0; $x < sizeof($result); $x++) {
63	$task=get_task_info($result[$x]);
64	$task['indent'] = $count * 10;
65	$concat = $conn->Concat('lastname',"', '",'firstname');
66	$sql2 = "SELECT $concat AS uname FROM mgw_users WHERE id='".$task['assignee']."'";
67	if(($user = $conn->GetRow($sql2))===false) exit(showSQLerror($sql2, $conn->ErrorMsg(), __LINE__, __FILE__));
68	$task['uname'] = $user['uname'];
69	if ($task['status']==$status || get_decendents($task['task_id'],$status)) {
70	    if ($task['status'] == $status) {
71		if ($status==1) {
72		    if (get_children($task['task_id'],1)) {
73			$task['action']['url'][0] = "#";
74			$task['action']['img'][0] = "/d-off.gif";
75			$task['action']['url'][1] = "#";
76			$task['action']['img'][1] = "f-off.gif";
77		    } else {
78			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
79			$task['action']['img'][0] = "d-on.gif";
80			$task['action']['url'][1] = "index.php?obj=task&amp;action=finish&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
81			$task['action']['img'][1] = "f-on.gif";
82		    }
83		} else {
84		    if (get_children($task['task_id'],0)) {
85			$task['action']['url'][0] = "#";
86			$task['action']['img'][0] = "d-off.gif";
87			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
88			$task['action']['img'][1] = "r-on.gif";
89		    } else {
90			$task['action']['url'][0] = "index.php?obj=task&amp;view=delete&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
91			$task['action']['img'][0] = "d-on.gif";
92			$task['action']['url'][1] = "index.php?obj=task&amp;action=reset&amp;tid=$task[task_id]&amp;pid=$task[project_id]&amp;".SID;
93			$task['action']['img'][1] = "r-on.gif";
94		    }
95		}
96	    } else {
97		$task['class'] = 'tab';
98		$task['action']['url'][0] = "#";
99		$task['action']['img'][0] = "d-off.gif";
100		$task['action']['url'][1] = "#";
101		$task['action']['img'][1] = "f-off.gif";
102	    }
103	    $tasks[] = $task;
104	    $tasks = print_tree($result[$x], $count, $status, $tasks);
105	}
106    }
107    return $tasks;
108}
109
110function is_toplevel($task_id) {
111    global $conn;
112
113    $sql = "SELECT parent_id FROM mgw_projects_tasks WHERE task_id='$task_id'";
114    if(($parent = $conn->GetRow($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
115    return ($parent['parent_id']==0) ? true : false;
116}
117
118function get_children($task_id, $status) {
119    global $conn;
120
121    // returns the task_id's of all child tasks that are status=$status
122    $children = array();
123    $count = 0;
124    if (($status == 0) || ($status == 1)) {
125	$sql = "SELECT task_id FROM mgw_projects_tasks WHERE parent_id='$task_id' AND status='$status'";
126    } else {
127	$sql = "SELECT task_id FROM mgw_projects_tasks WHERE parent_id='$task_id'";
128    }
129    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
130    while($row = $res->FetchRow()) {
131	$children[] = $row["task_id"];
132    }
133
134    return $children;
135}
136
137function get_decendents($task_id, $status, $count = 0, $decendents=array()) {
138    $result = get_children($task_id, 2);
139    for ($x=0; $x<sizeof($result); $x++) {
140	$task=get_task_info($result[$x]);
141	if (get_children($task['task_id'], $status) || $status == $task['status']) {
142	    $decendents[$x] = $result[$x];
143	}
144	get_decendents($result[$x], $count, $status, $decendents);
145    }
146    return $decendents;
147}
148
149function get_task_info($task_id) {
150    global $conn;
151
152    // returns the data concerning a task
153    $sql = "SELECT * FROM mgw_projects_tasks WHERE task_id='$task_id'";
154    if(($row = $conn->GetRow($sql))===false) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
155    return $row;
156}
157
158//Create a task dropdown box
159// Allow for the dropdown to be parent_id or any other field
160function task_dropdown($pid, $tid=0, $field="parent_id") {
161    global $conn;
162
163    // return the nice indented HTML select list
164    $rstr = '<select name=' . $field . ' size="1">';
165    if($tid !=0 ){
166    // Do not allow a milestone to become a parent
167    $nomilestone = ($field == "parent_id" ? " AND a.milestone=0 " : " ");
168	$sql = "SELECT a.title,a.task_id FROM mgw_projects_tasks a, mgw_projects_tasks b WHERE a.task_id=b." . $field . " AND b.task_id=$tid " . $nomilestone ;
169	$rstr .= "\n<!-- $sql -->\n";
170	if(!($row = $conn->GetRow($sql))===false){
171	    $rstr .= '<option value="'.$row['task_id'].'" selected="selected">'.$row['title'].'</option>';
172	    $rstr .= '<option value="0">-------------------------------------</option>';
173	}
174	$rstr .= '<option value="0">'.Lang::getLanguageString('toplevel').'</option>';
175	$rstr .= '<option value="0">-------------------------------------</option>';
176    }
177    else{
178	$rstr .= '<option value="0" selected="selected">'.Lang::getLanguageString('toplevel').'</option>';
179	$rstr .= '<option value="0">-------------------------------------</option>';
180    }
181    // Do not allow a milestone to become a parent
182    $nomilestone = ($field == "parent_id" ? " AND milestone=0 " : " ");
183    $sql = "SELECT task_id,title FROM mgw_projects_tasks WHERE parent_id=0 AND project_id='$pid'" . $nomilestone;
184    $rstr .= "\n<!-- $sql -->\n";
185    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
186    while($task = $res->FetchRow()) {
187	$rstr .= "<option value=\"{$task['task_id']}\">{$task['title']}</option>\n";
188	$rstr = get_task_dropdown($task['task_id'], 0, $rstr, $field);
189    }
190    $rstr .= '</select>';
191    return $rstr;
192}
193
194function get_task_dropdown($task_id, $count, $rstr, $field="parent_id") {
195    $count++;
196    $indent=$count*3;
197    $spacing="";
198    for ($x=0; $x<$indent; $x++)
199	$spacing.="&nbsp;";
200
201    $result = get_children($task_id, 2);
202    for ($x=0; $x<sizeof($result); $x++) {
203	$task=get_task_info($result[$x]);
204	// Do not allow a milestone to become a parent
205	$rstr .= ( ($field == "parent_id") && $task['milestone']=='1'  ? "" : "<option value=\"{$task['task_id']}\">$spacing {$task['title']}</option>");
206	$rstr = get_task_dropdown($result[$x], $count, $rstr);
207    }
208    return $rstr;
209}
210
211//=================================================
212// Get Number of Tasks Per Project
213// *Added by Vikor Reign
214//=================================================
215function getNumTasks($pid){
216    global $conn;
217
218    $sql = "SELECT project_id, status FROM mgw_projects_tasks WHERE project_id=$pid";
219
220    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__,__FILE__));
221    $active_counter = 0;
222    $finished_counter = 0;
223    while($row = $res->FetchRow()) {
224	if ($row["status"] == "1") {
225	    $active_counter++;
226	}
227	if ($row["status"] == "0") {
228	    $finished_counter++;
229	}
230    }
231
232    $numarray = array("active" =>
233		      $active_counter, "finished" => $finished_counter); //
234
235    return $numarray;
236}
237
238// =================================================
239//	              Graph Tasks
240// =================================================
241function projectGraphTasks(&$graph, $parent, &$o, &$bar){
242    global $conn;
243
244    // First off get all the tasks with Parent_ID of $parent)
245    $sql = "SELECT a.task_id, a.milestone, a.constrain_id, a.title, a.startdate, a.targetdate, a.hours, a.usedhours, a.parent_id, b.lastname AS assignee FROM mgw_projects_tasks a LEFT JOIN mgw_users b ON a.assignee=b.id WHERE project_id=" . (int)$_GET['pid'] . " AND parent_id=" . $parent . " ORDER BY startdate";
246    if(!$res = $conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
247
248    while($row = $res->FetchRow()){
249
250        // The bars are now in an array,
251        //    with the key being their place on the graph
252        //    This allows us to backreference bars for
253        //    constraints and such.
254
255        $count = count($o);
256
257        // If the item is a Milestone
258        if ($row["milestone"]== '1') {
259            $bar[$count] = new MileStone ($count, $row["title"],$row["startdate"]);
260            $bar[$count]->caption->Set($row['assignee']);
261            $bar[$count]->caption->SetFont(FF_FONT1, FF_BOLD);
262            $bar[$count]->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."&amp;".SID);
263            $bar[$count]->SetCSIMAlt(Lang::getLanguageString('edit'));
264            $bar[$count]->title->SetColor("black");
265            $bar[$count]->title->SetFont(FF_FONT1, FF_BOLD);
266            // For some reason this screws things up??? It becomes /modules/projects/Array
267            //$bar[$count]->title->SetCSIMAlt(Lang::getLanguageString('edit'));
268            //$bar[$count]->title->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."amp;".SID);
269
270        } else {
271
272            $bar[$count] = new GanttBar($count,$row["title"],$row["startdate"],$row["targetdate"]);
273            $color = ($conn->Unixdate($row["targetdate"]) > time()) ? 'green' : 'red';
274            if(isset($row['status']) && $row['status'] == '0') $color = 'gray';
275            $bar[$count]->caption->Set($row['assignee']);
276            $bar[$count]->SetPattern(GANTT_SOLID, $color);
277            if($row['usedhours'] > 0)
278            $bar[$count]->progress->Set(min((1/($row['hours']/$row['usedhours'])),1));
279            $bar[$count]->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."&amp;".SID);
280            $bar[$count]->title->SetCSIMTarget("index.php?obj=task&view=edit&amp;tid=".$row['task_id']."&amp;".SID);
281            $bar[$count]->SetCSIMAlt(Lang::getLanguageString('edit'));
282            $bar[$count]->title->SetCSIMAlt(Lang::getLanguageString('edit'));
283
284            // If it has subtasks then make it look different
285            $tempsql = "SELECT task_id, project_id, parent_id FROM mgw_projects_tasks WHERE project_id=" . (int)$_GET['pid'] . " AND parent_id=" . $row["task_id"];
286            if(($temprow = $conn->GetRow($tempsql))===false) exit(showSQLerror($tempsql, $conn->ErrorMsg(), __LINE__, __FILE__));
287            if(count($temprow)){
288                $bar[$count]->leftMark->SetType(MARK_LEFTTRIANGLE);
289                $bar[$count]->leftMark->Show();
290                $bar[$count]->leftMark->SetWidth(8);
291                $bar[$count]->leftMark->SetColor('black');
292                $bar[$count]->leftMark->SetFillColor('black');
293                $bar[$count]->rightMark->SetType(MARK_RIGHTTRIANGLE);
294                $bar[$count]->rightMark->Show();
295                $bar[$count]->rightMark->SetWidth(8);
296                $bar[$count]->rightMark->SetColor('black');
297                $bar[$count]->rightMark->SetFillColor('black');
298            }
299        }
300        $graph->Add($bar[$count]);
301        $o[] = (int)$row['task_id'] ;
302
303        // Be recurrsive
304        if(count($temprow)){
305            projectGraphTasks($graph,$row['task_id'],$o,$bar);
306        }
307    }
308}
309
310function hours_todo($id) {
311    // input project id
312    // returns the ammount of hours left todo on a project
313    global $conn;
314
315    $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='1'";
316    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
317    return $r;
318}
319
320function usedhours_todo($id) {
321    // input project id
322    // returns the amount of used hours done on a project
323    global $conn;
324
325    $sql = "SELECT SUM(usedhours) AS usedtotal FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='1'";
326    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
327    return $r;
328}
329
330function hours_done($id) {
331    // input project id
332    // returns the ammount of hours done on a project
333    global $conn;
334
335    $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='0'";
336    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
337    return $r;
338}
339
340function usedhours_done($id) {
341    // input project id
342    // returns the amount of used hours done on a project
343    global $conn;
344
345    $sql = "SELECT SUM(usedhours) AS usedtotal FROM mgw_projects_tasks WHERE project_id='".(int)$id."' AND status='0'";
346    if(($r = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
347    return $r;
348}
349
350function percentTimeComplete($id) {
351    global $conn;
352
353    $sql = "SELECT startdate, targetdate FROM mgw_projects WHERE project_id = ".(int)$id;
354    if(!$res = $conn->Execute($sql)) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
355    $row = $res->FetchRow();
356    $elapsed = time() - $conn->UnixDate($row["startdate"]);
357    $total = $conn->UnixDate($row["targetdate"]) - $conn->UnixDate($row["startdate"]);
358    if ($total == 0) {
359	return 100;
360    }
361    else {
362	if ((100 * $elapsed / $total) == 0) {
363	    return 0;
364	}
365	else {
366	    return sprintf("%02d", 100 * $elapsed / $total);
367	}
368    }
369}
370
371function percentcomplete($id) {
372    global $conn;
373    // This function takes a project id and and compares the todo hours
374    // to the finished hours to make a percent done
375
376    /*
377     * For a proper calculation of Percent-to-complete:
378     *  For open tasks, use the usedhours if more than the planned hours
379     *  to calculate todo.
380     *  Percentage for closed tasks is always 100
381     * Use this for percentage calculation.
382     * OvE, 20050809
383     */
384
385    $Qopenpl  = 'SELECT SUM(hours) as openpl '
386              . 'FROM   mgw_projects_tasks '
387              . 'WHERE  project_id=' . (int)$id . ' '
388              . 'AND    status=1 '
389              . 'AND    usedhours <= hours';
390    $Qopenot  = 'SELECT SUM(usedhours) as openot '
391              . 'FROM   mgw_projects_tasks '
392              . 'WHERE  project_id=' . (int)$id . ' '
393              . 'AND    status=1 '
394              . 'AND    usedhours > hours';
395    $Qopendn  = 'SELECT SUM(usedhours) as opendn '
396              . 'FROM   mgw_projects_tasks '
397              . 'WHERE  project_id=' . (int)$id . ' '
398              . 'AND    status=1 ';
399    $Qclospl  = 'SELECT SUM(hours) as clospl '
400              . 'FROM   mgw_projects_tasks '
401              . 'WHERE  project_id=' . (int)$id . ' '
402              . 'AND    status=0';
403
404   // Open tasks
405    $Qopen_planned    = $conn->GetOne($Qopenpl); // On schedule
406    $Qopen_overtime   = $conn->GetOne($Qopenot); // Used more than planned so far
407    $Qopen_done       = $conn->GetOne($Qopendn); // Time spent
408    // Closed tasks
409    $Qclosed_planned  = $conn->GetOne($Qclospl); // On schedule
410    $Qclosed_done     = $Qclosed_planned;        // Ignore overtime
411
412    $todo = $Qopen_planned + $Qopen_overtime + $Qclosed_planned;
413    $done = $Qopen_done + $Qclosed_done;
414
415    if (($Qopen_planned + $Qopen_overtime) == 0) {
416	return 100; // No open tasks; done!
417    }
418    elseif ($done > 0) {
419	$PercDone = (($done / $todo) * 100);
420	if ($PercDone >= 100) {
421		return 95; // Used more than planned but not yet done
422	}
423	else {
424		return sprintf("%2d", $PercDone);
425	}
426    }
427    else {
428	return 0;
429    }
430}
431
432function draw_time_and_progress_bars($id) {
433    global $smarty;
434    $timedone = percentTimeComplete($id);
435    $wpercent = percentcomplete($id);
436
437    $safe_td = max(0, min(100, $timedone));
438    if (isset($completed) && $completed) { $safe_td = min(100, $safe_td); }
439    if ((isset($completed) && $completed) || $safe_td < $wpercent) {
440	// project complete or within schedule
441	$colour = "green";
442    } elseif ($timedone < 100) {
443	// within deadline but behind schedule
444	$colour = "yellow";
445    } else {
446	// project over deadline
447	$colour = "red";
448    }
449    if ($timedone <= 0) {
450	$timedone=Lang::getLanguageString('scheduled');
451    } elseif ($timedone >= 100) {
452	$timedone="<strong>".Lang::getLanguageString('overdue')."</strong>";
453    } else {
454	$timedone="$timedone%&nbsp;".Lang::getLanguageString('time');
455    }
456    if ($wpercent <= 0) {
457	$workdone=Lang::getLanguageString('notstarted');
458    } elseif ($wpercent >= 100) {
459	$workdone="<strong>".Lang::getLanguageString('complete')."</strong>";
460    } else {
461	$workdone="$wpercent%&nbsp;".Lang::getLanguageString('work');
462    }
463
464    $percent = max(0, min(100, $safe_td));
465    $l_colour = ($percent == 0   ? "grey" : $colour);
466    $r_colour = ($percent == 100 ? $colour : "grey");
467    // This is a hack to avoid bad browser behaviour from using <img width=0>
468    if ($percent == 0  ) { $percent = 1; }
469    if ($percent == 100) { $percent = 99; }
470    $smarty->assign("tpercent", $percent);
471    $smarty->assign("tl_colour",$l_colour);
472    $smarty->assign("tr_colour",$r_colour);
473
474    $percent = max(0, min(100, $wpercent));
475    $l_colour = ($percent == 0   ? "grey" : "green");
476    $r_colour = ($percent == 100 ? "green" : "grey");
477    // This is a hack to avoid bad browser behaviour from using <img width=0>
478    if ($percent == 0  ) { $percent = 1; }
479    if ($percent == 100) { $percent = 99; }
480    $smarty->assign("wpercent", $percent);
481    $smarty->assign("wl_colour",$l_colour);
482    $smarty->assign("wr_colour",$r_colour);
483
484    $smarty->assign("timedone",$timedone);
485    $smarty->assign("workdone",$workdone);
486
487    return $smarty->fetch("projects_tp_bar.tpl");
488}
489
490
491function projectCalcParentHours($tid){
492    global $conn;
493
494    // Does this task have children
495    $result = get_children($tid, 2);
496
497    // If so then go to town
498    if (sizeof($result)) {
499        // For each child (if any)
500        for ($x=0; $x<sizeof($result); $x++) {
501
502            // If sub children then be recursive
503            if (get_children($result[$x], 2)) {
504                projectCalcParentHours($result[$x]);
505
506            }
507
508
509        }
510
511        // Total hours of children
512        $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE parent_id='".(int)$tid."'";
513        if(($total_hours = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
514        // Total hours of children DONE
515        $sql = "SELECT SUM(hours) AS total FROM mgw_projects_tasks WHERE parent_id='".(int)$tid."' AND status=0";;
516        if(($total_donehours = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
517        // Total used hours of children not done
518        $sql = "SELECT SUM(usedhours) AS total FROM mgw_projects_tasks WHERE parent_id='".(int)$tid."' AND status=1";;
519        if(($total_usedhours = $conn->GetOne($sql))===false) exit(showSQLError($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
520
521        $total_completehours = $total_donehours + $total_usedhours;
522
523        // Perform the UPDATE
524        $sql = "UPDATE mgw_projects_tasks SET hours=$total_hours, usedhours=$total_completehours WHERE task_id='".(int)$tid."'";
525        if(!$conn->Execute($sql)) exit(showSQLerror($sql, $conn->ErrorMsg(), __LINE__, __FILE__));
526    }
527}
528
529
530
531?>
532