Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
/*********************************************************************
ajax.reports.php
AJAX interface for reports -- both plot and tabular data are retrievable
in JSON format from this utility. Please put plumbing in /scp/ajax.php
pattern rules.
Jared Hancock <jared@osticket.com>
Copyright (c) 2006-2012 osTicket
http://www.osticket.com
Released under the GNU General Public License WITHOUT ANY WARRANTY.
See LICENSE.TXT for details.
vim: expandtab sw=4 ts=4 sts=4:
**********************************************************************/
if(!defined('INCLUDE_DIR')) die('403');
include_once(INCLUDE_DIR.'class.ticket.php');
/**
* Overview Report
*
* The overview report allows for the display of basic ticket statistics in
* both graphical and tabular formats.
*/
class OverviewReportAjaxAPI extends AjaxController {
function enumTabularGroups() {
return $this->encode(array("dept"=>"Department", "topic"=>"Topics",
"staff"=>"Staff"));
}
function getData() {
$start = $this->get('start', strtotime('last month'));
$stop = $this->get('stop', time());
$groups = array(
"dept" => array(
"table" => DEPT_TABLE,
"pk" => "dept_id",
"sort" => 'ORDER BY dept_name',
"fields" => 'T1.dept_name',
"headers" => array('Department')
),
"topic" => array(
"table" => TOPIC_TABLE,
"pk" => "topic_id",
"sort" => 'ORDER BY topic',
"fields" => "T1.topic",
"headers" => array('Help Topic')
),
"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')
)
);
$group = $this->get('group', 'dept');
$info = $groups[$group];
# XXX: Die if $group not in $groups
$res = db_query(
'SELECT ' . $info['fields'] . ','
.' COUNT(A1.ticket_id) AS Opened,'
.' COUNT(A2.ticket_id) AS Closed,'
.' COUNT(A3.ticket_id) AS Reopened'
.' FROM ' . $info['table'] . ' T1'
.' LEFT JOIN ' . TICKET_EVENT_TABLE
. ' A1 ON (T1.' . $info['pk'] . ' = A1.' . $info['pk']
.' AND A1.state=\'opened\' AND NOT A1.annulled)'
.' LEFT JOIN ' . TICKET_EVENT_TABLE
. ' A2 ON (T1.' . $info['pk'] . ' = A2.' . $info['pk']
.' AND A2.state=\'closed\' AND NOT A2.annulled)'
.' LEFT JOIN ' . TICKET_EVENT_TABLE
. ' A3 ON (T1.' . $info['pk'] . ' = A3.' . $info['pk']
.' AND A3.state=\'reopened\' AND NOT A3.annulled)'
.' GROUP BY '.$info['fields']
);
$rows = array();
while ($row = db_fetch_row($res)) {
$rows[] = $row;
}
return array("columns" => array_merge($info['headers'],
array('Opened','Closed','Reopened')),
"data" => $rows);
}
function getTabularData() {
return $this->encode($this->getData());
}
function downloadTabularData() {
$data = $this->getData();
$csv = array($data['columns']);
$csv = array_merge($csv, $data['data']);
Http::download(
sprintf('%s-report.csv', $this->get('group', 'Department')),
Format::implode_array(',', "\n", $csv));
}
function getPlotData() {
$start = $this->get('start', strtotime('last month'));
$stop = $this->get('stop', time());
# Fetch all types of events over the timeframe
$res = db_query('SELECT DISTINCT(state) FROM '.TICKET_EVENT_TABLE
.' WHERE timestamp BETWEEN FROM_UNIXTIME('.db_input($start)
.') AND FROM_UNIXTIME('.db_input($stop).')');
$events = array();
while ($row = db_fetch_row($res)) $events[] = $row[0];
# TODO: Handle user => db timezone offset
# XXX: Implement annulled column from the %ticket_event table
$res = db_query('SELECT state, DATE_FORMAT(timestamp, \'%Y-%m-%d\'), '
.'COUNT(ticket_id)'
.' FROM '.TICKET_EVENT_TABLE
.' WHERE timestamp BETWEEN FROM_UNIXTIME('.db_input($start)
.') AND FROM_UNIXTIME('.db_input($stop)
.') GROUP BY state, DATE_FORMAT(timestamp, \'%Y-%m-%d\')');
# Initialize array of plot values
$plots = array();
foreach ($events as $e) { $plots[$e] = array(); }
$time = null; $times = array();
# Iterate over result set, adding zeros for missing ticket events
while ($row = db_fetch_row($res)) {
$row_time = strtotime($row[1]);
if ($time != $row_time) {
# New time (and not the first), figure out which events did
# not have any tickets associated for this time slot
if ($time !== null) {
# Not the first record
foreach (array_diff($events, $slots) as $slot) {
$plots[$slot][] = 0;
}
}
$slots = array();
$times[] = $time = $row_time;
}
# Keep track of states for this timeframe
if (!in_array($row[0], $slots)) $slots[] = $row[0];
$plots[$row[0]][] = (int)$row[2];
}
return $this->encode(array("times" => $times, "plots" => $plots));
}
}