diff --git a/include/ajax.reports.php b/include/ajax.reports.php
index 9d002eb52c698a6788e33635f5576c22560d93df..7fbe19c89c81605725572e45433ef20ea374fdcf 100644
--- a/include/ajax.reports.php
+++ b/include/ajax.reports.php
@@ -35,6 +35,8 @@ class OverviewReportAjaxAPI extends AjaxController {
     }
 
     function getData() {
+        global $thisstaff;
+
         $start = $this->get('start', 'last month');
         $stop = $this->get('stop', 'now');
         if (substr($stop, 0, 1) == '+')
@@ -46,29 +48,40 @@ class OverviewReportAjaxAPI extends AjaxController {
             "dept" => array(
                 "table" => DEPT_TABLE,
                 "pk" => "dept_id",
-                "sort" => 'ORDER BY dept_name',
+                "sort" => 'T1.dept_name',
                 "fields" => 'T1.dept_name',
-                "headers" => array('Department')
+                "headers" => array('Department'),
+                "filter" => ('T1.dept_id IN ('.implode(',', db_input($thisstaff->getDepts())).')')
             ),
             "topic" => array(
                 "table" => TOPIC_TABLE,
                 "pk" => "topic_id",
-                "sort" => 'ORDER BY topic',
-                "fields" => "T1.topic",
-                "headers" => array('Help Topic')
+                "sort" => 'name',
+                "fields" => "CONCAT_WS(' / ',"
+                    ."(SELECT P.topic FROM ".TOPIC_TABLE." P WHERE P.topic_id = T1.topic_pid),"
+                    ."T1.topic) as name ",
+                "headers" => array('Help Topic'),
+                "filter" => '1'
             ),
-            # XXX: This will be relative to permissions based on the
-            # logged-in-staff
             "staff" => array(
                 "table" => STAFF_TABLE,
                 "pk" => 'staff_id',
-                "sort" => 'ORDER BY T1.lastname, T1.firstname',
-                "fields" => "CONCAT_WS(' ', T1.firstname, T1.lastname)",
-                "headers" => array('Staff Member')
+                "sort" => 'name',
+                "fields" => "CONCAT_WS(' ', T1.firstname, T1.lastname) as name",
+                "headers" => array('Staff Member'),
+                "filter" =>
+                    ('T1.staff_id=S1.staff_id
+                      AND 
+                      (T1.staff_id='.db_input($thisstaff->getDeptId())
+                        .(($depts=$thisstaff->getManagedDepartments())?
+                            (' OR T1.staff_id IN('.implode(',', db_input($depts)).')'):'')
+                     .')'
+                     ) 
             )
         );
         $group = $this->get('group', 'dept');
-        $info = $groups[$group];
+        $info = isset($groups[$group])?$groups[$group]:$groups['dept'];
+
         # XXX: Die if $group not in $groups
 
         $queries=array(
@@ -78,43 +91,62 @@ class OverviewReportAjaxAPI extends AjaxController {
                 COUNT(*)-COUNT(NULLIF(A1.state, "overdue")) AS Overdue,
                 COUNT(*)-COUNT(NULLIF(A1.state, "closed")) AS Closed,
                 COUNT(*)-COUNT(NULLIF(A1.state, "reopened")) AS Reopened
-            FROM '.$info['table'].' T1 LEFT JOIN '.TICKET_TABLE.' T2 USING ('.$info['pk'].')
-                LEFT JOIN '.TICKET_EVENT_TABLE.' A1 USING (ticket_id)
-            WHERE A1.timestamp BETWEEN '.$start.' AND '.$stop.'
-            GROUP BY '.$info['fields'].'
-            ORDER BY '.$info['fields']),
+            FROM '.$info['table'].' T1 
+                LEFT JOIN '.TICKET_EVENT_TABLE.' A1 
+                    ON (A1.'.$info['pk'].'=T1.'.$info['pk'].'
+                         AND NOT annulled 
+                         AND (A1.timestamp BETWEEN '.$start.' AND '.$stop.'))
+                LEFT JOIN '.STAFF_TABLE.' S1 ON (S1.staff_id=A1.staff_id)
+            WHERE '.$info['filter'].'
+            GROUP BY T1.'.$info['pk'].'
+            ORDER BY '.$info['sort']),
 
             array(1, 'SELECT '.$info['fields'].',
                 FORMAT(AVG(DATEDIFF(T2.closed, T2.created)),1) AS ServiceTime
-            FROM '.$info['table'].' T1 LEFT JOIN '.TICKET_TABLE.' T2 USING ('.$info['pk'].')
-            WHERE T2.closed BETWEEN '.$start.' AND '.$stop.'
-            GROUP BY '.$info['fields'].'
-            ORDER BY '.$info['fields']),
+            FROM '.$info['table'].' T1 
+                LEFT JOIN '.TICKET_TABLE.' T2 ON (T2.'.$info['pk'].'=T1.'.$info['pk'].')
+                LEFT JOIN '.STAFF_TABLE.' S1 ON (S1.staff_id=T2.staff_id)
+            WHERE '.$info['filter'].' AND T2.closed BETWEEN '.$start.' AND '.$stop.'
+            GROUP BY T1.'.$info['pk'].'
+            ORDER BY '.$info['sort']),
 
             array(1, 'SELECT '.$info['fields'].',
                 FORMAT(AVG(DATEDIFF(B2.created, B1.created)),1) AS ResponseTime
-            FROM '.$info['table'].' T1 LEFT JOIN '.TICKET_TABLE.' T2 USING ('.$info['pk'].')
+            FROM '.$info['table'].' T1 
+                LEFT JOIN '.TICKET_TABLE.' T2 ON (T2.'.$info['pk'].'=T1.'.$info['pk'].')
                 LEFT JOIN '.TICKET_THREAD_TABLE.' B2 ON (B2.ticket_id = T2.ticket_id
                     AND B2.thread_type="R")
                 LEFT JOIN '.TICKET_THREAD_TABLE.' B1 ON (B2.pid = B1.id)
-            WHERE B1.created BETWEEN '.$start.' AND '.$stop.'
-            GROUP BY '.$info['fields'].'
-            ORDER BY '.$info['fields'])
+                LEFT JOIN '.STAFF_TABLE.' S1 ON (S1.staff_id=B2.staff_id)
+            WHERE '.$info['filter'].' AND B1.created BETWEEN '.$start.' AND '.$stop.'
+            GROUP BY T1.'.$info['pk'].'
+            ORDER BY '.$info['sort'])
         );
         $rows = array();
+        $cols = 1;
         foreach ($queries as $q) {
             list($c, $sql) = $q;
             $res = db_query($sql);
-            $i = 0;
+            $cols += $c;
             while ($row = db_fetch_row($res)) {
-                if (count($rows) <= $i)
-                    $rows[] = array_slice($row, 0, count($row) - $c);
-                $rows[$i] = array_merge($rows[$i], array_slice($row, -$c));
-                $i++;
+                $found = false;
+                foreach ($rows as &$r) {
+                    if ($r[0] == $row[0]) {
+                        $r = array_merge($r, array_slice($row, -$c));
+                        $found = true;
+                        break;
+                    }
+                }
+                if (!$found)
+                    $rows[] = array_merge(array($row[0]), array_slice($row, -$c));
             }
+            # Make sure each row has the same number of items
+            foreach ($rows as &$r)
+                while (count($r) < $cols)
+                    $r[] = null;
         }
         return array("columns" => array_merge($info['headers'],
-                        array('Open','Assigned','Overdue','Closed','Reopened',
+                        array('Opened','Assigned','Overdue','Closed','Reopened',
                               'Service Time','Response Time')),
                      "data" => $rows);
     }
diff --git a/include/class.dept.php b/include/class.dept.php
index 13be8ff7e6551512f1e096b81d15f1dfd828a950..24ec3489db61ecc0aa5b41f392842d6ebb172e18 100644
--- a/include/class.dept.php
+++ b/include/class.dept.php
@@ -316,12 +316,15 @@ class Dept {
         return ($cfg && $cfg->getDefaultDeptId() && ($name=Dept::getNameById($cfg->getDefaultDeptId())))?$name:null;
     }
 
-    function getDepartments( $publiconly=false) {
+    function getDepartments( $criteria=null) {
         
         $depts=array();
-        $sql ='SELECT dept_id, dept_name FROM '.DEPT_TABLE;
-        if($publiconly)
-            $sql.=' WHERE ispublic=1';
+        $sql='SELECT dept_id, dept_name FROM '.DEPT_TABLE.' WHERE 1';
+        if($criteria['publiconly'])
+            $sql.=' AND  ispublic=1';
+
+        if(($manager=$criteria['manager']))
+            $sql.=' AND manager_id='.db_input(is_object($manager)?$manager->getId():$manager);
 
         if(($res=db_query($sql)) && db_num_rows($res)) {
             while(list($id, $name)=db_fetch_row($res))
@@ -332,7 +335,7 @@ class Dept {
     }
 
     function getPublicDepartments() {
-        return self::getDepartments(true);
+        return self::getDepartments(array('publiconly'=>true));
     }
 
     function create($vars, &$errors) {
diff --git a/include/class.staff.php b/include/class.staff.php
index 778041e7ca6fd707d16b91b5f3a9a4669fe3076a..89fdda1b362d9c82125f411d9231aca12216d5fe 100644
--- a/include/class.staff.php
+++ b/include/class.staff.php
@@ -214,6 +214,13 @@ class Staff {
     function getDepts() {
         return $this->getDepartments();
     }
+
+    function getManagedDepartments() {
+
+        return ($depts=Dept::getDepartments(
+                    array('manager' => $this->getId())
+                    ))?array_keys($depts):array();
+    }
      
     function getGroupId() {
         return $this->ht['group_id'];
diff --git a/include/class.ticket.php b/include/class.ticket.php
index 01f08e40c714e7877a8580a79880649d064b856a..bdb2655fb381b3b799c71a04eb7f2d8a923da038 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -804,15 +804,19 @@ class Ticket {
     function close(){
         global $thisstaff;
         
-        $sql='UPDATE '.TICKET_TABLE.' SET closed=NOW(), isoverdue=0, duedate=NULL, updated=NOW(), status='.db_input('closed');
-        
+        $sql='UPDATE '.TICKET_TABLE.' SET closed=NOW(),isoverdue=0, duedate=NULL, updated=NOW(), status='.db_input('closed');
         if($thisstaff) //Give the closing  staff credit. 
             $sql.=', staff_id='.db_input($thisstaff->getId());
 
         $sql.=' WHERE ticket_id='.db_input($this->getId());
 
+        if(!db_query($sql) || !db_affected_rows())
+            return false;
+
+        $this->reload();
         $this->logEvent('closed');
-        return (db_query($sql) && db_affected_rows());
+
+        return true;
     }
 
     //set status to open on a closed ticket.
diff --git a/scp/dashboard.php b/scp/dashboard.php
index 3b41ccfdfc1a2f4e123c501d8b0a1088584cffb3..2f4f1c42ffbe8e73f8f3da939fa1da22faec6e64 100644
--- a/scp/dashboard.php
+++ b/scp/dashboard.php
@@ -57,8 +57,7 @@ require(STAFFINC_DIR.'header.inc.php');
 
 <hr/>
 <h2>Statistics</h2>
-<p>Statistics of tickets organized by department, help topic, and staff
-member.</p>
+<p>Statistics of tickets organized by department, help topic, and staff.</p>
 <ul class="nav nav-tabs" id="tabular-navigation"></ul>
 
 <div id="table-here"></div>