index.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. <?php
  2. /* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. /**
  18. * \file htdocs/ticket/history.php
  19. * \ingroup ticket
  20. */
  21. require '../main.inc.php';
  22. require_once DOL_DOCUMENT_ROOT . '/ticket/class/actions_ticket.class.php';
  23. require_once DOL_DOCUMENT_ROOT . '/ticket/class/ticketstats.class.php';
  24. require_once DOL_DOCUMENT_ROOT . '/core/class/dolgraph.class.php';
  25. // Load translation files required by the page
  26. $langs->loadLangs(array('companies', 'other', 'ticket'));
  27. $WIDTH = DolGraph::getDefaultGraphSizeForStats('width');
  28. $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height');
  29. // Get parameters
  30. $id = GETPOST('id', 'int');
  31. $msg_id = GETPOST('msg_id', 'int');
  32. $action = GETPOST('action', 'aZ09');
  33. if ($user->societe_id) {
  34. $socid = $user->societe_id;
  35. }
  36. // Security check
  37. $result = restrictedArea($user, 'ticket', 0, '', '', '', '');
  38. $nowyear = strftime("%Y", dol_now());
  39. $year = GETPOST('year') > 0 ? GETPOST('year') : $nowyear;
  40. //$startyear=$year-2;
  41. $startyear = $year - 1;
  42. $endyear = $year;
  43. $object = new Ticket($db);
  44. /*
  45. * Actions
  46. */
  47. // None
  48. /*
  49. * View
  50. */
  51. $form = new Form($db);
  52. $tickesupstatic = new Ticket($db);
  53. llxHeader('', $langs->trans('TicketsIndex'), '');
  54. $linkback='';
  55. print load_fiche_titre($langs->trans('TicketsIndex'),$linkback,'title_ticket.png');
  56. $dir = '';
  57. $filenamenb = $dir . "/" . $prefix . "ticketinyear-" . $endyear . ".png";
  58. $fileurlnb = DOL_URL_ROOT . '/viewimage.php?modulepart=ticket&amp;file=ticketinyear-' . $endyear . '.png';
  59. $stats = new TicketStats($db, $socid, $userid);
  60. $param_year = 'DOLUSERCOOKIE_ticket_by_status_year';
  61. $param_shownb = 'DOLUSERCOOKIE_ticket_by_status_shownb';
  62. $param_showtot = 'DOLUSERCOOKIE_ticket_by_status_showtot';
  63. $autosetarray = preg_split("/[,;:]+/", GETPOST('DOL_AUTOSET_COOKIE'));
  64. if (in_array('DOLUSERCOOKIE_ticket_by_status', $autosetarray)) {
  65. $endyear = GETPOST($param_year, 'int');
  66. $shownb = GETPOST($param_shownb, 'alpha');
  67. $showtot = GETPOST($param_showtot, 'alpha');
  68. } else {
  69. $tmparray = json_decode($_COOKIE['DOLUSERCOOKIE_ticket_by_status'], true);
  70. $endyear = $tmparray['year'];
  71. $shownb = $tmparray['shownb'];
  72. $showtot = $tmparray['showtot'];
  73. }
  74. if (empty($shownb) && empty($showtot)) {
  75. $showtot = 1;
  76. }
  77. $nowarray = dol_getdate(dol_now(), true);
  78. if (empty($endyear)) {
  79. $endyear = $nowarray['year'];
  80. }
  81. $startyear = $endyear - 1;
  82. $WIDTH = (($shownb && $showtot) || !empty($conf->dol_optimize_smallscreen)) ? '256' : '320';
  83. $HEIGHT = '192';
  84. print '<div class="fichecenter"><div class="fichethirdleft">';
  85. /*
  86. * Statistics area
  87. */
  88. $tick = array(
  89. 'unread' => 0,
  90. 'read' => 0,
  91. 'answered' => 0,
  92. 'assigned' => 0,
  93. 'inprogress' => 0,
  94. 'waiting' => 0,
  95. 'closed' => 0,
  96. 'deleted' => 0,
  97. );
  98. $total = 0;
  99. $sql = "SELECT t.fk_statut, COUNT(t.fk_statut) as nb";
  100. $sql .= " FROM " . MAIN_DB_PREFIX . "ticket as t";
  101. if (!$user->rights->societe->client->voir && !$socid) {
  102. $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
  103. }
  104. $sql .= ' WHERE t.entity IN (' . getEntity('ticket', 1) . ')';
  105. $sql .= " AND t.fk_statut IS NOT NULL";
  106. $sql .= " AND date_format(datec,'%Y') = '" . $endyear . "'";
  107. if (!$user->rights->societe->client->voir && !$socid) {
  108. $sql .= " AND t.fk_soc = sc.fk_soc AND sc.fk_user = " . $user->id;
  109. }
  110. // External users restriction
  111. if ($user->societe_id > 0) {
  112. $sql .= " AND t.fk_soc='" . $user->societe_id . "'";
  113. } else {
  114. // For internals users,
  115. if (!empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) && !$user->rights->ticket->manage) {
  116. $sql .= " AND t.fk_user_assign=" . $user->id;
  117. }
  118. }
  119. $sql .= " GROUP BY t.fk_statut";
  120. $result = $db->query($sql);
  121. if ($result) {
  122. while ($objp = $db->fetch_object($result)) {
  123. $found = 0;
  124. if ($objp->fk_statut == 0) {
  125. $tick['unread'] = $objp->nb;
  126. }
  127. if ($objp->fk_statut == 1) {
  128. $tick['read'] = $objp->nb;
  129. }
  130. if ($objp->fk_statut == 3) {
  131. $tick['answered'] = $objp->nb;
  132. }
  133. if ($objp->fk_statut == 4) {
  134. $tick['assigned'] = $objp->nb;
  135. }
  136. if ($objp->fk_statut == 5) {
  137. $tick['inprogress'] = $objp->nb;
  138. }
  139. if ($objp->fk_statut == 6) {
  140. $tick['waiting'] = $objp->nb;
  141. }
  142. if ($objp->fk_statut == 8) {
  143. $tick['closed'] = $objp->nb;
  144. }
  145. if ($objp->fk_statut == 9) {
  146. $tick['deleted'] = $objp->nb;
  147. }
  148. }
  149. if ((round($tick['unread']) ? 1 : 0) +(round($tick['read']) ? 1 : 0) +(round($tick['answered']) ? 1 : 0) +(round($tick['assigned']) ? 1 : 0) +(round($tick['inprogress']) ? 1 : 0) +(round($tick['waiting']) ? 1 : 0) +(round($tick['closed']) ? 1 : 0) +(round($tick['deleted']) ? 1 : 0) >= 2
  150. ) {
  151. $dataseries = array();
  152. $dataseries[] = array('label' => $langs->trans("Unread"), 'data' => round($tick['unread']));
  153. $dataseries[] = array('label' => $langs->trans("Read"), 'data' => round($tick['read']));
  154. $dataseries[] = array('label' => $langs->trans("Answered"), 'data' => round($tick['answered']));
  155. $dataseries[] = array('label' => $langs->trans("Assigned"), 'data' => round($tick['assigned']));
  156. $dataseries[] = array('label' => $langs->trans("InProgress"), 'data' => round($tick['inprogress']));
  157. $dataseries[] = array('label' => $langs->trans("Waiting"), 'data' => round($tick['waiting']));
  158. $dataseries[] = array('label' => $langs->trans("Closed"), 'data' => round($tick['closed']));
  159. $dataseries[] = array('label' => $langs->trans("Deleted"), 'data' => round($tick['deleted']));
  160. }
  161. } else {
  162. dol_print_error($db);
  163. }
  164. $stringtoshow = '<script type="text/javascript" language="javascript">
  165. jQuery(document).ready(function() {
  166. jQuery("#idsubimgDOLUSERCOOKIE_ticket_by_status").click(function() {
  167. jQuery("#idfilterDOLUSERCOOKIE_ticket_by_status").toggle();
  168. });
  169. });
  170. </script>';
  171. $stringtoshow .= '<div class="center hideobject" id="idfilterDOLUSERCOOKIE_ticket_by_status">'; // hideobject is to start hidden
  172. $stringtoshow .= '<form class="flat formboxfilter" method="POST" action="' . $_SERVER["PHP_SELF"] . '">';
  173. $stringtoshow .= '<input type="hidden" name="action" value="' . $refreshaction . '">';
  174. $stringtoshow .= '<input type="hidden" name="DOL_AUTOSET_COOKIE" value="DOLUSERCOOKIE_ticket_by_status:year,shownb,showtot">';
  175. $stringtoshow .= $langs->trans("Year") . ' <input class="flat" size="4" type="text" name="' . $param_year . '" value="' . $endyear . '">';
  176. $stringtoshow .= '<input type="image" alt="' . $langs->trans("Refresh") . '" src="' . img_picto($langs->trans("Refresh"), 'refresh.png', '', '', 1) . '">';
  177. $stringtoshow .= '</form>';
  178. $stringtoshow .= '</div>';
  179. print '<table class="noborder" width="100%">';
  180. print '<tr class="liste_titre"><th >' . $langs->trans("Statistics") . ' ' . img_picto('', 'filter.png', 'id="idsubimgDOLUSERCOOKIE_ticket_by_status" class="linkobject"') . '</th></tr>';
  181. print '<tr><td>';
  182. // don't display graph if no series
  183. if (! empty($dataseries) && count($dataseries) > 1) {
  184. $data = array();
  185. foreach ($dataseries as $key => $value) {
  186. $data[] = array($value['label'], $value['data']);
  187. }
  188. $px1 = new DolGraph();
  189. $mesg = $px1->isGraphKo();
  190. if (!$mesg) {
  191. $px1->SetData($data);
  192. unset($data1);
  193. $px1->SetPrecisionY(0);
  194. $i = $startyear;
  195. $legend = array();
  196. while ($i <= $endyear) {
  197. $legend[] = $i;
  198. $i++;
  199. }
  200. $px1->SetType(array('pie'));
  201. $px1->SetLegend($legend);
  202. $px1->SetMaxValue($px1->GetCeilMaxValue());
  203. $px1->SetWidth($WIDTH);
  204. $px1->SetHeight($HEIGHT);
  205. $px1->SetYLabel($langs->trans("TicketStatByStatus"));
  206. $px1->SetShading(3);
  207. $px1->SetHorizTickIncrement(1);
  208. $px1->SetPrecisionY(0);
  209. $px1->SetCssPrefix("cssboxes");
  210. $px1->mode = 'depth';
  211. //$px1->SetTitle($langs->trans("TicketStatByStatus"));
  212. $px1->draw($filenamenb, $fileurlnb);
  213. print $px1->show();
  214. }
  215. }
  216. print $stringtoshow;
  217. print '</td></tr>';
  218. print '</table>';
  219. // Build graphic number of object
  220. $data = $stats->getNbByMonth($endyear, $startyear);
  221. print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
  222. /*
  223. * Last tickets
  224. */
  225. $max = 15;
  226. $sql = "SELECT t.rowid, t.ref, t.track_id, t.datec, t.subject, t.type_code, t.category_code, t.severity_code, t.fk_statut, t.progress,";
  227. $sql .= " type.label as type_label, category.label as category_label, severity.label as severity_label";
  228. $sql .= " FROM " . MAIN_DB_PREFIX . "ticket as t";
  229. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticket_type as type ON type.code=t.type_code";
  230. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticket_category as category ON category.code=t.category_code";
  231. $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_ticket_severity as severity ON severity.code=t.severity_code";
  232. if (!$user->rights->societe->client->voir && !$socid) {
  233. $sql .= ", " . MAIN_DB_PREFIX . "societe_commerciaux as sc";
  234. }
  235. $sql .= ' WHERE t.entity IN (' . getEntity('ticket', 1) . ')';
  236. $sql .= " AND t.fk_statut=0";
  237. if (!$user->rights->societe->client->voir && !$socid) {
  238. $sql .= " AND t.fk_soc = sc.fk_soc AND sc.fk_user = " . $user->id;
  239. }
  240. if ($user->societe_id > 0) {
  241. $sql .= " AND t.fk_soc='" . $user->societe_id . "'";
  242. } else {
  243. // Restricted to assigned user only
  244. if ($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY && !$user->rights->ticket->manage) {
  245. $sql .= " AND t.fk_user_assign=" . $user->id;
  246. }
  247. }
  248. $sql .= $db->order("t.datec", "DESC");
  249. $sql .= $db->plimit($max, 0);
  250. //print $sql;
  251. $result = $db->query($sql);
  252. if ($result) {
  253. $num = $db->num_rows($result);
  254. $i = 0;
  255. $transRecordedType = $langs->trans("LatestNewTickets", $max);
  256. print '<div class="div-table-responsive-no-min">';
  257. print '<table class="noborder" width="100%">';
  258. print '<tr class="liste_titre"><th>' . $transRecordedType . '</th>';
  259. print '<th>' . $langs->trans('Date') . '</th>';
  260. print '<th>' . $langs->trans('Subject') . '</th>';
  261. print '<th>' . $langs->trans('Type') . '</th>';
  262. print '<th>' . $langs->trans('Category') . '</th>';
  263. print '<th>' . $langs->trans('Severity') . '</th>';
  264. print '<th></th>';
  265. print '</tr>';
  266. if ($num > 0) {
  267. while ($i < $num) {
  268. $objp = $db->fetch_object($result);
  269. $tickesupstatic->id = $objp->rowid;
  270. $tickesupstatic->ref = $objp->ref;
  271. $tickesupstatic->track_id = $objp->track_id;
  272. $tickesupstatic->fk_statut = $objp->fk_statut;
  273. $tickesupstatic->progress = $objp->progress;
  274. $tickesupstatic->subject = $objp->subject;
  275. print '<tr class="oddeven">';
  276. // Ref
  277. print '<td class="nowrap">';
  278. print $tickesupstatic->getNomUrl(1);
  279. print "</td>\n";
  280. // Creation date
  281. print '<td align="left">';
  282. print dol_print_date($db->jdate($objp->datec), 'dayhour');
  283. print "</td>";
  284. // Subject
  285. print '<td class="nowrap">';
  286. print '<a href="card.php?track_id=' . $objp->track_id . '">' . dol_trunc($objp->subject, 30) . '</a>';
  287. print "</td>\n";
  288. // Type
  289. print '<td class="nowrap">';
  290. print $objp->type_label;
  291. print '</td>';
  292. // Category
  293. print '<td class="nowrap">';
  294. print $objp->category_label;
  295. print "</td>";
  296. // Severity
  297. print '<td class="nowrap">';
  298. print $objp->severity_label;
  299. print "</td>";
  300. print '<td class="nowrap">';
  301. print $tickesupstatic->getLibStatut(3);
  302. print "</td>";
  303. print "</tr>\n";
  304. $i++;
  305. }
  306. $db->free();
  307. } else {
  308. print '<tr><td colspan="6" class="opacitymedium">' . $langs->trans('NoTicketsFound') . '</td></tr>';
  309. }
  310. print "</table>";
  311. print '</div>';
  312. } else {
  313. dol_print_error($db);
  314. }
  315. print '</div></div></div>';
  316. print '<div style="clear:both"></div>';
  317. print '<div class="tabsAction">';
  318. print '<div class="inline-block divButAction"><a class="butAction" href="new.php?action=create_ticket">' . $langs->trans('CreateTicket') . '</a></div>';
  319. print '<div class="inline-block divButAction"><a class="butAction" href="list.php">' . $langs->trans('TicketList') . '</a></div>';
  320. print '</div>';
  321. // End of page
  322. llxFooter('');
  323. $db->close();