Bootswatch, Summernote, and Captcheck mods for Mods for HESK (mods-for-hesk.com). In use at support.netsyms.com.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

reports.php 44KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929
  1. <?php
  2. /**
  3. *
  4. * This file is part of HESK - PHP Help Desk Software.
  5. *
  6. * (c) Copyright Klemen Stirn. All rights reserved.
  7. * https://www.hesk.com
  8. *
  9. * For the full copyright and license agreement information visit
  10. * https://www.hesk.com/eula.php
  11. *
  12. */
  13. define('IN_SCRIPT', 1);
  14. define('HESK_PATH', '../');
  15. define('PAGE_TITLE', 'ADMIN_REPORTS');
  16. define('MFH_PAGE_LAYOUT', 'TOP_ONLY');
  17. /* Get all the required files and functions */
  18. require(HESK_PATH . 'hesk_settings.inc.php');
  19. require(HESK_PATH . 'inc/common.inc.php');
  20. require(HESK_PATH . 'inc/admin_functions.inc.php');
  21. require(HESK_PATH . 'inc/reporting_functions.inc.php');
  22. require(HESK_PATH . 'inc/mail_functions.inc.php');
  23. hesk_load_database_functions();
  24. hesk_session_start();
  25. hesk_dbConnect();
  26. hesk_isLoggedIn();
  27. // Check permissions for this feature
  28. hesk_checkPermission('can_run_reports');
  29. // Should reports be full or limited to own tickets?
  30. $can_run_reports_full = hesk_checkPermission('can_run_reports_full', 0);
  31. // Set default values
  32. define('CALENDAR', 1);
  33. define('MAIN_PAGE', 1);
  34. define('LOAD_TABS', 1);
  35. $selected = array(
  36. 'w' => array(0 => '', 1 => ''),
  37. 'time' => array(1 => '', 2 => '', 3 => '', 4 => '', 5 => '', 6 => '', 7 => '', 8 => '', 9 => '', 10 => '', 11 => '', 12 => ''),
  38. 'type' => array(1 => '', 2 => '', 3 => '', 4 => ''),
  39. );
  40. $is_all_time = 0;
  41. /* Default this month to date */
  42. $date_from = date('Y-m-d', mktime(0, 0, 0, date("m"), 1, date("Y")));
  43. $date_to = date('Y-m-d');
  44. $input_datefrom = date('Y-m-d', strtotime('last month'));
  45. $input_dateto = date('Y-m-d');
  46. /* Date */
  47. if (!empty($_GET['w'])) {
  48. $df = preg_replace('/[^0-9]/', '', hesk_GET('datefrom'));
  49. if (strlen($df) == 8) {
  50. $date_from = substr($df, 0, 4) . '-' . substr($df, 4, 2) . '-' . substr($df, 6, 2);
  51. $input_datefrom = $date_from;
  52. } else {
  53. $date_from = date('Y-m-d', strtotime('last month'));
  54. }
  55. $dt = preg_replace('/[^0-9]/', '', hesk_GET('dateto'));
  56. if (strlen($dt) == 8) {
  57. $date_to = substr($dt, 0, 4) . '-' . substr($dt, 4, 2) . '-' . substr($dt, 6, 2);
  58. $input_dateto = $date_to;
  59. } else {
  60. $date_to = date('Y-m-d');
  61. }
  62. if ($date_from > $date_to) {
  63. $tmp = $date_from;
  64. $tmp2 = $input_datefrom;
  65. $date_from = $date_to;
  66. $input_datefrom = $input_dateto;
  67. $date_to = $tmp;
  68. $input_dateto = $tmp2;
  69. $note_buffer = $hesklang['datetofrom'];
  70. }
  71. if ($date_to > date('Y-m-d')) {
  72. $date_to = date('Y-m-d');
  73. $input_dateto = date('m/d/Y');
  74. }
  75. $query_string = 'reports.php?w=1&amp;datefrom=' . urlencode($input_datefrom) . '&amp;dateto=' . urlencode($input_dateto);
  76. $selected['w'][1] = 'checked="checked"';
  77. $selected['time'][3] = 'selected="selected"';
  78. } else {
  79. $selected['w'][0] = 'checked="checked"';
  80. $_GET['time'] = intval(hesk_GET('time', 3));
  81. switch ($_GET['time']) {
  82. case 1:
  83. /* Today */
  84. $date_from = date('Y-m-d');
  85. $date_to = $date_from;
  86. $selected['time'][1] = 'selected="selected"';
  87. $is_all_time = 1;
  88. break;
  89. case 2:
  90. /* Yesterday */
  91. $date_from = date('Y-m-d', mktime(0, 0, 0, date("m"), date("d") - 1, date("Y")));
  92. $date_to = $date_from;
  93. $selected['time'][2] = 'selected="selected"';
  94. $is_all_time = 1;
  95. break;
  96. case 4:
  97. /* Last month */
  98. $date_from = date('Y-m-d', mktime(0, 0, 0, date("m") - 1, 1, date("Y")));
  99. $date_to = date('Y-m-d', mktime(0, 0, 0, date("m"), 0, date("Y")));
  100. $selected['time'][4] = 'selected="selected"';
  101. break;
  102. case 5:
  103. /* Last 30 days */
  104. $date_from = date('Y-m-d', mktime(0, 0, 0, date("m") - 1, date("d"), date("Y")));
  105. $date_to = date('Y-m-d');
  106. $selected['time'][5] = 'selected="selected"';
  107. break;
  108. case 6:
  109. /* This week */
  110. list($date_from, $date_to) = dateweek(0);
  111. $date_to = date('Y-m-d');
  112. $selected['time'][6] = 'selected="selected"';
  113. break;
  114. case 7:
  115. /* Last week */
  116. list($date_from, $date_to) = dateweek(-1);
  117. $selected['time'][7] = 'selected="selected"';
  118. break;
  119. case 8:
  120. /* This business week */
  121. list($date_from, $date_to) = dateweek(0, 1);
  122. $date_to = date('Y-m-d');
  123. $selected['time'][8] = 'selected="selected"';
  124. break;
  125. case 9:
  126. /* Last business week */
  127. list($date_from, $date_to) = dateweek(-1, 1);
  128. $selected['time'][9] = 'selected="selected"';
  129. break;
  130. case 10:
  131. /* This year */
  132. $date_from = date('Y') . '-01-01';
  133. $date_to = date('Y-m-d');
  134. $selected['time'][10] = 'selected="selected"';
  135. break;
  136. case 11:
  137. /* Last year */
  138. $date_from = date('Y') - 1 . '-01-01';
  139. $date_to = date('Y') - 1 . '-12-31';
  140. $selected['time'][11] = 'selected="selected"';
  141. break;
  142. case 12:
  143. /* All time */
  144. $date_from = hesk_getOldestDate();
  145. $date_to = date('Y-m-d');
  146. $selected['time'][12] = 'selected="selected"';
  147. $is_all_time = 1;
  148. break;
  149. default:
  150. $_GET['time'] = 3;
  151. $selected['time'][3] = 'selected="selected"';
  152. }
  153. $query_string = 'reports.php?w=0&amp;time=' . $_GET['time'];
  154. }
  155. unset($tmp);
  156. /* Type */
  157. $type = intval(hesk_GET('type', 1));
  158. if (isset($selected['type'][$type])) {
  159. $selected['type'][$type] = 'selected="selected"';
  160. }
  161. // Setup date SQL so we don't have to call functions several times
  162. $hesk_settings['dt_sql'] = " `dt` BETWEEN '" . hesk_dbEscape($date_from) . " 00:00:00' AND '" . hesk_dbEscape($date_to) . " 23:59:59' ";
  163. /* Print header */
  164. require_once(HESK_PATH . 'inc/headerAdmin.inc.php');
  165. /* Print main manage users page */
  166. require_once(HESK_PATH . 'inc/show_admin_nav.inc.php');
  167. ?>
  168. <div class="content-wrapper">
  169. <section class="content">
  170. <div class="box">
  171. <?php if (hesk_checkPermission('can_export', 0)) {
  172. $canExport = true;
  173. $panelMargin = '-15px';
  174. } else {
  175. $canExport = false;
  176. }
  177. ?>
  178. <div class="box-header">
  179. <h1 class="box-title">
  180. <?php echo $hesklang['reports_tab']; ?> <a href="#"
  181. onclick="javascript:alert('<?php echo hesk_makeJsString($hesklang['reports_intro']); ?>')"><i
  182. class="fa fa-question-circle settingsquestionmark"></i></a>
  183. </h1>
  184. <?php
  185. // Show a link to export.php if user has permission to do so
  186. if ($canExport) {
  187. echo '<br><small><a title="' . $hesklang['export'] . '" href="export.php">' . $hesklang['export'] . '</a></small><div class="blankSpace"></div>';
  188. }
  189. ?>
  190. <div class="box-tools pull-right">
  191. <button type="button" class="btn btn-box-tool" data-widget="collapse">
  192. <i class="fa fa-minus"></i>
  193. </button>
  194. </div>
  195. </div>
  196. <div class="box-body">
  197. <form action="reports.php" method="get" name="form1" role="form">
  198. <div class="form-group">
  199. <label for="dtrg" class="control-label"><?php echo $hesklang['dtrg']; ?>:</label>
  200. <div class="radio form-inline move-right-20">
  201. <input type="radio" name="w" value="0" id="w0" <?php echo $selected['w'][0]; ?> style="position: relative">
  202. <select name="time" onclick="document.getElementById('w0').checked = true"
  203. class="form-control"
  204. onfocus="document.getElementById('w0').checked = true"
  205. style="margin-top:5px;margin-bottom:5px;">
  206. <option value="1" <?php echo $selected['time'][1]; ?>><?php echo $hesklang['r1']; ?>
  207. (<?php echo $hesklang['d' . date('w')]; ?>)
  208. </option>
  209. <option value="2" <?php echo $selected['time'][2]; ?>><?php echo $hesklang['r2']; ?>
  210. (<?php echo $hesklang['d' . date('w', mktime(0, 0, 0, date('m'), date('d') - 1, date('Y')))]; ?>
  211. )
  212. </option>
  213. <option value="3" <?php echo $selected['time'][3]; ?>><?php echo $hesklang['r3']; ?>
  214. (<?php echo $hesklang['m' . date('n')]; ?>)
  215. </option>
  216. <option value="4" <?php echo $selected['time'][4]; ?>><?php echo $hesklang['r4']; ?>
  217. (<?php echo $hesklang['m' . date('n', mktime(0, 0, 0, date('m') - 1, 1, date('Y')))]; ?>
  218. )
  219. </option>
  220. <option
  221. value="5" <?php echo $selected['time'][5]; ?>><?php echo $hesklang['r5']; ?></option>
  222. <option
  223. value="6" <?php echo $selected['time'][6]; ?>><?php echo $hesklang['r6']; ?></option>
  224. <option
  225. value="7" <?php echo $selected['time'][7]; ?>><?php echo $hesklang['r7']; ?></option>
  226. <option
  227. value="8" <?php echo $selected['time'][8]; ?>><?php echo $hesklang['r8']; ?></option>
  228. <option
  229. value="9" <?php echo $selected['time'][9]; ?>><?php echo $hesklang['r9']; ?></option>
  230. <option
  231. value="10" <?php echo $selected['time'][10]; ?>><?php echo $hesklang['r10']; ?>
  232. (<?php echo date('Y'); ?>)
  233. </option>
  234. <option
  235. value="11" <?php echo $selected['time'][11]; ?>><?php echo $hesklang['r11']; ?>
  236. (<?php echo date('Y', mktime(0, 0, 0, date('m'), date('d'), date('Y') - 1)); ?>)
  237. </option>
  238. <option
  239. value="12" <?php echo $selected['time'][12]; ?>><?php echo $hesklang['r12']; ?></option>
  240. </select>
  241. </div>
  242. <div class="radio form-inline move-right-20">
  243. <input type="radio" name="w" value="1" id="w1" <?php echo $selected['w'][1]; ?> style="position: relative">
  244. <?php echo $hesklang['from']; ?> <input type="text" name="datefrom"
  245. value="<?php echo $input_datefrom; ?>"
  246. id="datefrom" class="datepicker form-control" size="10"
  247. onclick="document.getElementById('w1').checked = true"
  248. onfocus="document.getElementById('w1').checked = true;this.focus;"/>
  249. <?php echo $hesklang['to']; ?> <input type="text" name="dateto"
  250. value="<?php echo $input_dateto; ?>" id="dateto"
  251. class="datepicker form-control" size="10"
  252. onclick="document.getElementById('w1').checked = true"
  253. onfocus="document.getElementById('w1').checked = true; this.focus;"/>
  254. </div>
  255. </div>
  256. <div class="form-group">
  257. <label for="type" class="control-label"><?php echo $hesklang['crt']; ?></b>:</label>
  258. <select name="type" class="form-control">
  259. <option
  260. value="1" <?php echo $selected['type'][1]; ?>><?php echo $hesklang['t1']; ?></option>
  261. <option
  262. value="2" <?php echo $selected['type'][2]; ?>><?php echo $hesklang['t2']; ?></option>
  263. <option
  264. value="3" <?php echo $selected['type'][3]; ?>><?php echo $hesklang['t3']; ?></option>
  265. <option
  266. value="4" <?php echo $selected['type'][4]; ?>><?php echo $hesklang['t4']; ?></option>
  267. </select>
  268. </div>
  269. <div class="form-group">
  270. <input type="submit" value="<?php echo $hesklang['dire']; ?>" class="btn btn-default"/>
  271. <input type="hidden" name="token" value="<?php hesk_token_echo(); ?>"/>
  272. </div>
  273. </form>
  274. </div>
  275. </div>
  276. <div class="box">
  277. <div class="box-header">
  278. <h1 class="box-title">
  279. <?php
  280. if ($date_from == $date_to) {
  281. echo hesk_dateToString($date_from, 0);
  282. } else {
  283. echo hesk_dateToString($date_from, 0) . ' - ' . hesk_dateToString($date_to, 0);
  284. }
  285. ?>
  286. </h1>
  287. <div class="box-tools pull-right">
  288. <button type="button" class="btn btn-box-tool" data-widget="collapse">
  289. <i class="fa fa-minus"></i>
  290. </button>
  291. </div>
  292. </div>
  293. <div class="box-body">
  294. <?php
  295. /* This will handle error, success and notice messages */
  296. hesk_handle_messages();
  297. ?>
  298. <?php
  299. // Show a note if reports are limited
  300. if (!$can_run_reports_full) {
  301. echo "<p>{$hesklang['roo']}</p>";
  302. }
  303. /* Report type */
  304. switch ($type) {
  305. case 2:
  306. hesk_ticketsByMonth();
  307. break;
  308. case 3:
  309. hesk_ticketsByUser();
  310. break;
  311. case 4:
  312. hesk_ticketsByCategory();
  313. break;
  314. default:
  315. hesk_ticketsByDay();
  316. }
  317. /*** START FUNCTIONS ***/
  318. function hesk_ticketsByCategory()
  319. {
  320. global $hesk_settings, $hesklang, $date_from, $date_to, $can_run_reports_full;
  321. /* List of categories */
  322. $cat = array();
  323. $res = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "categories` WHERE " . ($can_run_reports_full ? '1' : hesk_myCategories('id')) . " ORDER BY `id` ASC");
  324. while ($row = hesk_dbFetchAssoc($res)) {
  325. $cat[$row['id']] = $row['name'];
  326. }
  327. $tickets = array();
  328. $totals = array('num_tickets' => 0, 'resolved' => 0, 'all_replies' => 0, 'staff_replies' => 0, 'worked' => 0);
  329. /* Populate category counts */
  330. foreach ($cat as $id => $name) {
  331. $tickets[$id] = array(
  332. 'num_tickets' => 0,
  333. 'resolved' => 0,
  334. 'all_replies' => 0,
  335. 'staff_replies' => 0,
  336. 'worked' => '',
  337. );
  338. }
  339. /* SQL query for category stats */
  340. $res = hesk_dbQuery("SELECT `category`, COUNT(*) AS `num_tickets`, " . ($hesk_settings['time_worked'] ? "SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`," : '') . " SUM(`replies`) AS `all_replies`, SUM(staffreplies) AS `staff_replies` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE {$hesk_settings['dt_sql']} " . ($can_run_reports_full ? "" : " AND `t1`.`owner` = '" . intval($_SESSION['id']) . "'") . " GROUP BY `category`");
  341. /* Update ticket values */
  342. while ($row = hesk_dbFetchAssoc($res)) {
  343. if (!$hesk_settings['time_worked']) {
  344. $row['seconds_worked'] = 0;
  345. }
  346. if (isset($cat[$row['category']])) {
  347. $tickets[$row['category']]['num_tickets'] += $row['num_tickets'];
  348. $tickets[$row['category']]['all_replies'] += $row['all_replies'];
  349. $tickets[$row['category']]['staff_replies'] += $row['staff_replies'];
  350. $tickets[$row['category']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
  351. } else {
  352. /* Category deleted */
  353. if (!isset($tickets[9999])) {
  354. $cat[9999] = $hesklang['catd'];
  355. $tickets[9999] = array('num_tickets' => $row['num_tickets'], 'resolved' => 0, 'all_replies' => $row['all_replies'], 'staff_replies' => $row['staff_replies'], 'worked' => $row['seconds_worked']);
  356. } else {
  357. $tickets[9999]['num_tickets'] += $row['num_tickets'];
  358. $tickets[9999]['all_replies'] += $row['all_replies'];
  359. $tickets[9999]['staff_replies'] += $row['staff_replies'];
  360. $tickets[9999]['worked'] += $row['seconds_worked'];
  361. }
  362. }
  363. $totals['num_tickets'] += $row['num_tickets'];
  364. $totals['all_replies'] += $row['all_replies'];
  365. $totals['staff_replies'] += $row['staff_replies'];
  366. $totals['worked'] += $row['seconds_worked'];
  367. }
  368. // Get number of resolved tickets
  369. $res = hesk_dbQuery("SELECT COUNT(*) AS `num_tickets` , `category` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `status` IN (SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 1) " . ($can_run_reports_full ? "" : " AND `owner` = '" . intval($_SESSION['id']) . "'") . " AND {$hesk_settings['dt_sql']} GROUP BY `category`");
  370. // Update number of open and resolved tickets
  371. while ($row = hesk_dbFetchAssoc($res)) {
  372. if (isset($cat[$row['category']])) {
  373. $tickets[$row['category']]['resolved'] += $row['num_tickets'];
  374. } else {
  375. // Category deleted
  376. $tickets[9999]['resolved'] += $row['num_tickets'];
  377. }
  378. $totals['resolved'] += $row['num_tickets'];
  379. }
  380. // Convert total seconds worked to HH:MM:SS
  381. $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
  382. if (isset($tickets[9999])) {
  383. $tickets[9999]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($tickets[9999]['worked']) : 0;
  384. }
  385. ?>
  386. <table class="table table-striped table-condensed">
  387. <tr>
  388. <th><?php echo $hesklang['category']; ?></th>
  389. <th><?php echo $hesklang['tickets']; ?></th>
  390. <th><?php echo $hesklang['topen']; ?></th>
  391. <th><?php echo $hesklang['closed_title']; ?></th>
  392. <th><?php echo $hesklang['replies'] . ' (' . $hesklang['all'] . ')'; ?></th>
  393. <th><?php echo $hesklang['replies'] . ' (' . $hesklang['staff'] . ')'; ?></th>
  394. <?php
  395. if ($hesk_settings['time_worked']) {
  396. echo '<th>' . $hesklang['ts'] . '</th>';
  397. }
  398. ?>
  399. </tr>
  400. <?php
  401. $num_tickets = count($tickets);
  402. if ($num_tickets > 10) {
  403. ?>
  404. <tr>
  405. <td><b><?php echo $hesklang['totals']; ?></b></td>
  406. <td><b><?php echo $totals['num_tickets']; ?></b></td>
  407. <td><b><?php echo $totals['num_tickets'] - $totals['resolved']; ?></b></td>
  408. <td><b><?php echo $totals['resolved']; ?></b></td>
  409. <td><b><?php echo $totals['all_replies']; ?></b></td>
  410. <td><b><?php echo $totals['staff_replies']; ?></b></td>
  411. <?php
  412. if ($hesk_settings['time_worked']) {
  413. echo '<td><b>' . $totals['worked'] . '</b></td>';
  414. }
  415. ?>
  416. </tr>
  417. <?php
  418. }
  419. foreach ($tickets as $k => $d) {
  420. ?>
  421. <tr>
  422. <td><?php echo $cat[$k]; ?></td>
  423. <td><?php echo $d['num_tickets']; ?></td>
  424. <td><?php echo $d['num_tickets'] - $d['resolved']; ?></td>
  425. <td><?php echo $d['resolved']; ?></td>
  426. <td><?php echo $d['all_replies']; ?></td>
  427. <td><?php echo $d['staff_replies']; ?></td>
  428. <?php
  429. if ($hesk_settings['time_worked']) {
  430. echo '<td>' . $d['worked'] . '</td>';
  431. }
  432. ?>
  433. </tr>
  434. <?php
  435. }
  436. ?>
  437. <tr>
  438. <td><b><?php echo $hesklang['totals']; ?></b></td>
  439. <td><b><?php echo $totals['num_tickets']; ?></b></td>
  440. <td><b><?php echo $totals['num_tickets'] - $totals['resolved']; ?></b></td>
  441. <td><b><?php echo $totals['resolved']; ?></b></td>
  442. <td><b><?php echo $totals['all_replies']; ?></b></td>
  443. <td><b><?php echo $totals['staff_replies']; ?></b></td>
  444. <?php
  445. if ($hesk_settings['time_worked']) {
  446. echo '<td><b>' . $totals['worked'] . '</b></td>';
  447. }
  448. ?>
  449. </tr>
  450. </table>
  451. <?php
  452. } // END hesk_ticketsByCategory
  453. function hesk_ticketsByUser()
  454. {
  455. global $hesk_settings, $hesklang, $date_from, $date_to;
  456. // Some variables we will need
  457. $tickets = array();
  458. $totals = array('asstickets' => 0, 'resolved' => 0, 'tickets' => 0, 'replies' => 0, 'worked' => 0, 'openedby' => 0);
  459. // Get list of users
  460. $admins = array();
  461. // I. ADMINISTRATORS can view all users
  462. if ($_SESSION['isadmin'] || hesk_checkPermission('can_run_reports_full', 0)) {
  463. // -> get list of users
  464. $res = hesk_dbQuery("SELECT `id`,`name` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` ORDER BY `name` ASC");
  465. // -> populate $admins and $tickets arrays
  466. while ($row = hesk_dbFetchAssoc($res)) {
  467. $admins[$row['id']] = $row['name'];
  468. $tickets[$row['id']] = array(
  469. 'asstickets' => 0,
  470. 'resolved' => 0,
  471. 'tickets' => 0,
  472. 'replies' => 0,
  473. 'worked' => '',
  474. 'openedby' => 0,
  475. );
  476. }
  477. // -> get list of tickets
  478. $res = hesk_dbQuery("SELECT `owner`, COUNT(*) AS `cnt`" . ($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '') . " FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `owner` IN ('" . implode("','", array_keys($admins)) . "') AND {$hesk_settings['dt_sql']} GROUP BY `owner`");
  479. // -> update ticket list values
  480. while ($row = hesk_dbFetchAssoc($res)) {
  481. if (!$hesk_settings['time_worked']) {
  482. $row['seconds_worked'] = 0;
  483. }
  484. $tickets[$row['owner']]['asstickets'] += $row['cnt'];
  485. $totals['asstickets'] += $row['cnt'];
  486. $tickets[$row['owner']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
  487. $totals['worked'] += $row['seconds_worked'];
  488. }
  489. // -> get list of resolved tickets
  490. $res = hesk_dbQuery("SELECT `owner`, COUNT(*) AS `cnt` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `owner` IN ('" . implode("','", array_keys($admins)) . "') AND `status` IN (SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']} GROUP BY `owner`");
  491. // -> update resolved ticket list values
  492. while ($row = hesk_dbFetchAssoc($res)) {
  493. $tickets[$row['owner']]['resolved'] += $row['cnt'];
  494. $totals['resolved'] += $row['cnt'];
  495. }
  496. // -> get number of replies
  497. $res = hesk_dbQuery("SELECT `staffid`, COUNT(*) AS `cnt`, COUNT(DISTINCT `replyto`) AS `tcnt` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `staffid` IN ('" . implode("','", array_keys($admins)) . "') AND {$hesk_settings['dt_sql']} GROUP BY `staffid`");
  498. // -> update number of replies values
  499. while ($row = hesk_dbFetchAssoc($res)) {
  500. $tickets[$row['staffid']]['tickets'] += $row['tcnt'];
  501. $tickets[$row['staffid']]['replies'] += $row['cnt'];
  502. $totals['tickets'] += $row['tcnt'];
  503. $totals['replies'] += $row['cnt'];
  504. }
  505. } // II. OTHER STAFF may only see their own stats
  506. else {
  507. $admins[$_SESSION['id']] = $_SESSION['name'];
  508. // -> get list of tickets
  509. $res = hesk_dbQuery("SELECT COUNT(*) AS `cnt`" . ($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '') . " FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `owner` = '" . intval($_SESSION['id']) . "' AND {$hesk_settings['dt_sql']}");
  510. $row = hesk_dbFetchAssoc($res);
  511. // -> update ticket values
  512. $tickets[$_SESSION['id']]['asstickets'] = $row['cnt'];
  513. $totals['asstickets'] = $row['cnt'];
  514. $tickets[$_SESSION['id']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
  515. $totals['worked'] += $row['seconds_worked'];
  516. // -> get list of resolved tickets
  517. $res = hesk_dbQuery("SELECT COUNT(*) AS `cnt` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE `owner` = '" . intval($_SESSION['id']) . "' AND `status` IN (SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']}");
  518. $row = hesk_dbFetchAssoc($res);
  519. // -> update resolved ticket values
  520. $tickets[$_SESSION['id']]['resolved'] = $row['cnt'];
  521. $totals['resolved'] = $row['cnt'];
  522. // -> get number of replies
  523. $res = hesk_dbQuery("SELECT COUNT(*) AS `cnt`, COUNT(DISTINCT `replyto`) AS `tcnt` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "replies` WHERE `staffid` = '" . intval($_SESSION['id']) . "' AND {$hesk_settings['dt_sql']}");
  524. $row = hesk_dbFetchAssoc($res);
  525. $tickets[$_SESSION['id']]['tickets'] = $row['tcnt'];
  526. $tickets[$_SESSION['id']]['replies'] = $row['cnt'];
  527. $totals['tickets'] = $row['tcnt'];
  528. $totals['replies'] = $row['cnt'];
  529. }
  530. // Convert total seconds worked to HH:MM:SS
  531. $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
  532. // Get total opened by tickets
  533. $res = hesk_dbQuery("SELECT `openedby`, COUNT(*) AS `cnt` FROM `".hesk_dbEscape($hesk_settings['db_pfix'])."tickets` WHERE `openedby` IN ('" . implode("','", array_keys($admins) ) . "') AND DATE(`dt`) BETWEEN '" . hesk_dbEscape($date_from) . "' AND '" . hesk_dbEscape($date_to) . "' GROUP BY `openedby`");
  534. // -> update ticket list values
  535. while ($row = hesk_dbFetchAssoc($res))
  536. {
  537. $tickets[$row['openedby']]['openedby'] += $row['cnt'];
  538. $totals['openedby'] += $row['cnt'];
  539. }
  540. ?>
  541. <table class="table table-striped table-condensed">
  542. <tr>
  543. <th><?php echo $hesklang['user']; ?></th>
  544. <th><?php echo $hesklang['numsub']; ?></th>
  545. <th><?php echo $hesklang['ticass']; ?></th>
  546. <th><?php echo $hesklang['topen']; ?></th>
  547. <th><?php echo $hesklang['closed_title']; ?></th>
  548. <th><?php echo $hesklang['ticall']; ?></th>
  549. <th><?php echo $hesklang['replies']; ?></th>
  550. <?php
  551. if ($hesk_settings['time_worked']) {
  552. echo '<th>' . $hesklang['ts'] . '</th>';
  553. }
  554. ?>
  555. </tr>
  556. <?php
  557. $num_tickets = count($tickets);
  558. if ($num_tickets > 10) {
  559. ?>
  560. <tr>
  561. <td><b><?php echo $hesklang['totals']; ?></b></td>
  562. <td><b><?php echo $totals['openedby']; ?></b></td>
  563. <td><b><?php echo $totals['asstickets']; ?></b></td>
  564. <td><b><?php echo $totals['asstickets'] - $totals['resolved']; ?></b></td>
  565. <td><b><?php echo $totals['resolved']; ?></b></td>
  566. <td><b><?php echo $totals['tickets']; ?></b></td>
  567. <td><b><?php echo $totals['replies']; ?></b></td>
  568. <?php
  569. if ($hesk_settings['time_worked']) {
  570. echo '<td><b>' . $totals['worked'] . '</b></td>';
  571. }
  572. ?>
  573. </tr>
  574. <?php
  575. }
  576. foreach ($tickets as $k => $d) {
  577. ?>
  578. <tr>
  579. <td><?php echo $admins[$k]; ?></td>
  580. <td><?php echo $d['openedby']; ?></td>
  581. <td><?php echo $d['asstickets']; ?></td>
  582. <td><?php echo $d['asstickets'] - $d['resolved']; ?></td>
  583. <td><?php echo $d['resolved']; ?></td>
  584. <td><?php echo $d['tickets']; ?></td>
  585. <td><?php echo $d['replies']; ?></td>
  586. <?php
  587. if ($hesk_settings['time_worked']) {
  588. echo '<td>' . $d['worked'] . '</td>';
  589. }
  590. ?>
  591. </tr>
  592. <?php
  593. }
  594. ?>
  595. <tr>
  596. <td><b><?php echo $hesklang['totals']; ?></b></td>
  597. <td><b><?php echo $totals['openedby']; ?></b></td>
  598. <td><b><?php echo $totals['asstickets']; ?></b></td>
  599. <td><b><?php echo $totals['asstickets'] - $totals['resolved']; ?></b></td>
  600. <td><b><?php echo $totals['resolved']; ?></b></td>
  601. <td><b><?php echo $totals['tickets']; ?></b></td>
  602. <td><b><?php echo $totals['replies']; ?></b></td>
  603. <?php
  604. if ($hesk_settings['time_worked']) {
  605. echo '<td><b>' . $totals['worked'] . '</b></td>';
  606. }
  607. ?>
  608. </tr>
  609. </table>
  610. <?php
  611. } // END hesk_ticketsByUser
  612. function hesk_ticketsByMonth()
  613. {
  614. global $hesk_settings, $hesklang, $date_from, $date_to, $can_run_reports_full;
  615. $tickets = array();
  616. $totals = array('all' => 0, 'resolved' => 0, 'worked' => 0);
  617. $dt = MonthsArray($date_from, $date_to);
  618. // Pre-populate date values
  619. foreach ($dt as $month) {
  620. $tickets[$month] = array(
  621. 'all' => 0,
  622. 'resolved' => 0,
  623. 'worked' => '',
  624. );
  625. }
  626. // SQL query for all
  627. $res = hesk_dbQuery("SELECT YEAR(`dt`) AS `myyear`, MONTH(`dt`) AS `mymonth`, COUNT(*) AS `cnt`" . ($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '') . " FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE " . ($can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'") . " AND {$hesk_settings['dt_sql']} GROUP BY `myyear`,`mymonth`");
  628. // Update ticket values
  629. while ($row = hesk_dbFetchAssoc($res)) {
  630. if (!$hesk_settings['time_worked']) {
  631. $row['seconds_worked'] = 0;
  632. }
  633. $row['mymonth'] = sprintf('%02d', $row['mymonth']);
  634. $tickets[$row['myyear'] . '-' . $row['mymonth'] . '-01']['all'] += $row['cnt'];
  635. $tickets[$row['myyear'] . '-' . $row['mymonth'] . '-01']['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
  636. $totals['all'] += $row['cnt'];
  637. $totals['worked'] += $row['seconds_worked'];
  638. }
  639. // SQL query for resolved
  640. $res = hesk_dbQuery("SELECT YEAR(`dt`) AS `myyear`, MONTH(`dt`) AS `mymonth`, COUNT(*) AS `cnt` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE " . ($can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'") . " AND `status` IN (SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']} GROUP BY `myyear`,`mymonth`");
  641. // Update ticket values
  642. while ($row = hesk_dbFetchAssoc($res)) {
  643. $row['mymonth'] = sprintf('%02d', $row['mymonth']);
  644. $tickets[$row['myyear'] . '-' . $row['mymonth'] . '-01']['resolved'] += $row['cnt'];
  645. $totals['resolved'] += $row['cnt'];
  646. }
  647. // Convert total seconds worked to HH:MM:SS
  648. $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
  649. ?>
  650. <table class="table table-striped table-condensed">
  651. <tr>
  652. <th><?php echo $hesklang['month']; ?></th>
  653. <th><?php echo $hesklang['atik']; ?></th>
  654. <th><?php echo $hesklang['topen']; ?></th>
  655. <th><?php echo $hesklang['closed_title']; ?></th>
  656. <?php
  657. if ($hesk_settings['time_worked']) {
  658. echo '<th>' . $hesklang['ts'] . '</th>';
  659. }
  660. ?>
  661. </tr>
  662. <?php
  663. $num_tickets = count($tickets);
  664. if ($num_tickets > 10) {
  665. ?>
  666. <tr>
  667. <th><b><?php echo $hesklang['totals']; ?></b></th>
  668. <th><b><?php echo $totals['all']; ?></b></th>
  669. <th><b><?php echo $totals['all'] - $totals['resolved']; ?></b></th>
  670. <th><b><?php echo $totals['resolved']; ?></b></th>
  671. <?php
  672. if ($hesk_settings['time_worked']) {
  673. echo '<th><b>' . $totals['worked'] . '</b></th>';
  674. }
  675. ?>
  676. </tr>
  677. <?php
  678. }
  679. foreach ($tickets as $k => $d) {
  680. ?>
  681. <tr>
  682. <td><?php echo hesk_dateToString($k, 0, 0, 1); ?></td>
  683. <td><?php echo $d['all']; ?></td>
  684. <td><?php echo $d['all'] - $d['resolved']; ?></td>
  685. <td><?php echo $d['resolved']; ?></td>
  686. <?php
  687. if ($hesk_settings['time_worked']) {
  688. echo '<td>' . $d['worked'] . '</td>';
  689. }
  690. ?>
  691. </tr>
  692. <?php
  693. }
  694. ?>
  695. <tr>
  696. <td><b><?php echo $hesklang['totals']; ?></b></td>
  697. <td><b><?php echo $totals['all']; ?></b></td>
  698. <td><b><?php echo $totals['all'] - $totals['resolved']; ?></b></td>
  699. <td><b><?php echo $totals['resolved']; ?></b></td>
  700. <?php
  701. if ($hesk_settings['time_worked']) {
  702. echo '<td><b>' . $d['worked'] . '</b></td>';
  703. }
  704. ?>
  705. </tr>
  706. </table>
  707. <?php
  708. } // END hesk_ticketsByMonth
  709. function hesk_ticketsByDay()
  710. {
  711. global $hesk_settings, $hesklang, $date_from, $date_to, $can_run_reports_full;
  712. $tickets = array();
  713. $totals = array('all' => 0, 'resolved' => 0, 'worked' => 0);
  714. $dt = DateArray($date_from, $date_to);
  715. // Pre-populate date values
  716. foreach ($dt as $day) {
  717. $tickets[$day] = array(
  718. 'all' => 0,
  719. 'resolved' => 0,
  720. 'worked' => '',
  721. );
  722. }
  723. // SQL query for all
  724. $res = hesk_dbQuery("SELECT DATE(`dt`) AS `mydt`, COUNT(*) AS `cnt`" . ($hesk_settings['time_worked'] ? ", SUM( TIME_TO_SEC(`time_worked`) ) AS `seconds_worked`" : '') . " FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE " . ($can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'") . " AND {$hesk_settings['dt_sql']} GROUP BY `mydt`");
  725. // Update ticket values
  726. while ($row = hesk_dbFetchAssoc($res)) {
  727. if (!$hesk_settings['time_worked']) {
  728. $row['seconds_worked'] = 0;
  729. }
  730. $tickets[$row['mydt']]['all'] += $row['cnt'];
  731. $tickets[$row['mydt']]['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($row['seconds_worked']) : 0;
  732. $totals['all'] += $row['cnt'];
  733. $totals['worked'] += $row['seconds_worked'];
  734. }
  735. // SQL query for resolved
  736. $res = hesk_dbQuery("SELECT DATE(`dt`) AS `mydt`, COUNT(*) AS `cnt` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` WHERE " . ($can_run_reports_full ? '1' : "`owner` = '" . intval($_SESSION['id']) . "'") . " AND `status` IN (SELECT `ID` FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "statuses` WHERE `IsClosed` = 1) AND {$hesk_settings['dt_sql']} GROUP BY `mydt`");
  737. // Update ticket values
  738. while ($row = hesk_dbFetchAssoc($res)) {
  739. $tickets[$row['mydt']]['resolved'] += $row['cnt'];
  740. $totals['resolved'] += $row['cnt'];
  741. }
  742. // Convert total seconds worked to HH:MM:SS
  743. $totals['worked'] = $hesk_settings['time_worked'] ? hesk_SecondsToHHMMSS($totals['worked']) : 0;
  744. ?>
  745. <table class="table table-striped table-condensed">
  746. <tr>
  747. <th><?php echo $hesklang['date']; ?></th>
  748. <th><?php echo $hesklang['atik']; ?></th>
  749. <th><?php echo $hesklang['topen']; ?></th>
  750. <th><?php echo $hesklang['closed_title']; ?></th>
  751. <?php
  752. if ($hesk_settings['time_worked']) {
  753. echo '<th>' . $hesklang['ts'] . '</th>';
  754. }
  755. ?>
  756. </tr>
  757. <?php
  758. $num_tickets = count($tickets);
  759. if ($num_tickets > 10) {
  760. ?>
  761. <tr>
  762. <td><b><?php echo $hesklang['totals']; ?></b></td>
  763. <td><b><?php echo $totals['all']; ?></b></td>
  764. <td><b><?php echo $totals['all'] - $totals['resolved']; ?></b></td>
  765. <td><b><?php echo $totals['resolved']; ?></b></td>
  766. <?php
  767. if ($hesk_settings['time_worked']) {
  768. echo '<td><b>' . $totals['worked'] . '</b></td>';
  769. }
  770. ?>
  771. </tr>
  772. <?php
  773. }
  774. foreach ($tickets as $k => $d) {
  775. ?>
  776. <tr>
  777. <td><?php echo hesk_dateToString($k); ?></td>
  778. <td><?php echo $d['all']; ?></td>
  779. <td><?php echo $d['all'] - $d['resolved']; ?></td>
  780. <td><?php echo $d['resolved']; ?></td>
  781. <?php
  782. if ($hesk_settings['time_worked']) {
  783. echo '<td>' . $d['worked'] . '</td>';
  784. }
  785. ?>
  786. </tr>
  787. <?php
  788. }
  789. ?>
  790. <tr>
  791. <td><b><?php echo $hesklang['totals']; ?></b></td>
  792. <td><b><?php echo $totals['all']; ?></b></td>
  793. <td><b><?php echo $totals['all'] - $totals['resolved']; ?></b></td>
  794. <td><b><?php echo $totals['resolved']; ?></b></td>
  795. <?php
  796. if ($hesk_settings['time_worked']) {
  797. echo '<td><b>' . $totals['worked'] . '</b></td>';
  798. }
  799. ?>
  800. </tr>
  801. </table>
  802. <?php
  803. } // END hesk_ticketsByDay
  804. ?>
  805. </div>
  806. </div>
  807. </section>
  808. </div>
  809. <?php
  810. require_once(HESK_PATH . 'inc/footer.inc.php');
  811. exit();