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>