dolibarr  13.0.2
index.php
1 <?php
2 /* Copyright (C) - 2013-2016 Jean-François FERRY <hello@librethic.io>
3  * Copyright (C) - 2019 Nicolas ZABOURI <info@inovea-conseil.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
24 require '../main.inc.php';
25 require_once DOL_DOCUMENT_ROOT.'/ticket/class/actions_ticket.class.php';
26 require_once DOL_DOCUMENT_ROOT.'/ticket/class/ticketstats.class.php';
27 require_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
29 
30 $hookmanager = new HookManager($db);
31 
32 // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array
33 $hookmanager->initHooks(array('ticketsindex'));
34 
35 // Load translation files required by the page
36 $langs->loadLangs(array('companies', 'other', 'ticket'));
37 
39 $HEIGHT = DolGraph::getDefaultGraphSizeForStats('height');
40 
41 // Get parameters
42 $id = GETPOST('id', 'int');
43 $msg_id = GETPOST('msg_id', 'int');
44 
45 $action = GETPOST('action', 'aZ09');
46 
47 if ($user->socid) {
48  $socid = $user->socid;
49 }
50 
51 // Security check
52 $result = restrictedArea($user, 'ticket', 0, '', '', '', '');
53 
54 $nowyear = strftime("%Y", dol_now());
55 $year = GETPOST('year') > 0 ? GETPOST('year') : $nowyear;
56 //$startyear=$year-2;
57 $startyear = $year - 1;
58 $endyear = $year;
59 
60 $object = new Ticket($db);
61 
62 
63 /*
64  * Actions
65  */
66 
67 // None
68 
69 
70 /*
71  * View
72  */
73 
74 $form = new Form($db);
75 $tickesupstatic = new Ticket($db);
76 
77 llxHeader('', $langs->trans('TicketsIndex'), '');
78 
79 $linkback = '';
80 print load_fiche_titre($langs->trans('TicketsIndex'), $linkback, 'ticket');
81 
82 
83 $dir = '';
84 $filenamenb = $dir."/".$prefix."ticketinyear-".$endyear.".png";
85 $fileurlnb = DOL_URL_ROOT.'/viewimage.php?modulepart=ticket&amp;file=ticketinyear-'.$endyear.'.png';
86 
87 $stats = new TicketStats($db, $socid, $userid);
88 $param_year = 'DOLUSERCOOKIE_ticket_by_status_year';
89 $param_shownb = 'DOLUSERCOOKIE_ticket_by_status_shownb';
90 $param_showtot = 'DOLUSERCOOKIE_ticket_by_status_showtot';
91 $autosetarray = preg_split("/[,;:]+/", GETPOST('DOL_AUTOSET_COOKIE'));
92 if (in_array('DOLUSERCOOKIE_ticket_by_status', $autosetarray)) {
93  $endyear = GETPOST($param_year, 'int');
94  $shownb = GETPOST($param_shownb, 'alpha');
95  $showtot = GETPOST($param_showtot, 'alpha');
96 } else {
97  $tmparray = json_decode($_COOKIE['DOLUSERCOOKIE_ticket_by_status'], true);
98  $endyear = $tmparray['year'];
99  $shownb = $tmparray['shownb'];
100  $showtot = $tmparray['showtot'];
101 }
102 if (empty($shownb) && empty($showtot)) {
103  $showtot = 1;
104 }
105 
106 $nowarray = dol_getdate(dol_now(), true);
107 if (empty($endyear)) {
108  $endyear = $nowarray['year'];
109 }
110 
111 $startyear = $endyear - 1;
112 $WIDTH = (($shownb && $showtot) || !empty($conf->dol_optimize_smallscreen)) ? '100%' : '80%';
113 $HEIGHT = '200';
114 
115 print '<div class="fichecenter"><div class="fichethirdleft">';
116 
117 /*
118  * Statistics area
119  */
120 $tick = array(
121  'unread' => 0,
122  'read' => 0,
123  'answered' => 0,
124  'assigned' => 0,
125  'inprogress' => 0,
126  'waiting' => 0,
127  'closed' => 0,
128  'deleted' => 0,
129 );
130 
131 $sql = "SELECT t.fk_statut, COUNT(t.fk_statut) as nb";
132 $sql .= " FROM ".MAIN_DB_PREFIX."ticket as t";
133 if (!$user->rights->societe->client->voir && !$socid) {
134  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
135 }
136 $sql .= ' WHERE t.entity IN ('.getEntity('ticket').')';
137 $sql .= dolSqlDateFilter('datec', 0, 0, $endyear);
138 
139 if (!$user->rights->societe->client->voir && !$socid) {
140  $sql .= " AND t.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id;
141 }
142 
143 // External users restriction
144 if ($user->socid > 0) {
145  $sql .= " AND t.fk_soc= ".((int) $user->socid);
146 } else {
147  // For internals users,
148  if (!empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) && !$user->rights->ticket->manage) {
149  $sql .= " AND t.fk_user_assign = ".$user->id;
150  }
151 }
152 $sql .= " GROUP BY t.fk_statut";
153 
154 $result = $db->query($sql);
155 if ($result) {
156  while ($objp = $db->fetch_object($result)) {
157  $found = 0;
158  if ($objp->fk_statut == Ticket::STATUS_NOT_READ) {
159  $tick['unread'] = $objp->nb;
160  }
161  if ($objp->fk_statut == Ticket::STATUS_READ) {
162  $tick['read'] = $objp->nb;
163  }
164  if ($objp->fk_statut == Ticket::STATUS_NEED_MORE_INFO) {
165  $tick['needmoreinfo'] = $objp->nb;
166  }
167  if ($objp->fk_statut == Ticket::STATUS_ASSIGNED) {
168  $tick['assigned'] = $objp->nb;
169  }
170  if ($objp->fk_statut == Ticket::STATUS_IN_PROGRESS) {
171  $tick['inprogress'] = $objp->nb;
172  }
173  if ($objp->fk_statut == Ticket::STATUS_WAITING) {
174  $tick['waiting'] = $objp->nb;
175  }
176  if ($objp->fk_statut == Ticket::STATUS_CLOSED) {
177  $tick['closed'] = $objp->nb;
178  }
179  if ($objp->fk_statut == Ticket::STATUS_CANCELED) {
180  $tick['canceled'] = $objp->nb;
181  }
182  }
183 
184  include_once DOL_DOCUMENT_ROOT.'/theme/'.$conf->theme.'/theme_vars.inc.php';
185 
186  $dataseries = array();
187  $colorseries = array();
188 
189  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_NOT_READ]), 'data' => round($tick['unread']));
190  $colorseries[Ticket::STATUS_NOT_READ] = '-'.$badgeStatus0;
191  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_READ]), 'data' => round($tick['read']));
192  $colorseries[Ticket::STATUS_READ] = $badgeStatus1;
193  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_ASSIGNED]), 'data' => round($tick['assigned']));
194  $colorseries[Ticket::STATUS_ASSIGNED] = $badgeStatus3;
195  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_IN_PROGRESS]), 'data' => round($tick['inprogress']));
196  $colorseries[Ticket::STATUS_IN_PROGRESS] = $badgeStatus4;
197  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_WAITING]), 'data' => round($tick['waiting']));
198  $colorseries[Ticket::STATUS_WAITING] = '-'.$badgeStatus4;
199  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_NEED_MORE_INFO]), 'data' => round($tick['needmoreinfo']));
200  $colorseries[Ticket::STATUS_NEED_MORE_INFO] = '-'.$badgeStatus3;
201  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_CANCELED]), 'data' => round($tick['canceled']));
202  $colorseries[Ticket::STATUS_CANCELED] = $badgeStatus9;
203  $dataseries[] = array('label' => $langs->transnoentitiesnoconv($tickesupstatic->statuts_short[Ticket::STATUS_CLOSED]), 'data' => round($tick['closed']));
204  $colorseries[Ticket::STATUS_CLOSED] = $badgeStatus6;
205 } else {
206  dol_print_error($db);
207 }
208 
209 $stringtoshow = '<script type="text/javascript" language="javascript">
210  jQuery(document).ready(function() {
211  jQuery("#idsubimgDOLUSERCOOKIE_ticket_by_status").click(function() {
212  jQuery("#idfilterDOLUSERCOOKIE_ticket_by_status").toggle();
213  });
214  });
215  </script>';
216 $stringtoshow .= '<div class="center hideobject" id="idfilterDOLUSERCOOKIE_ticket_by_status">'; // hideobject is to start hidden
217 $stringtoshow .= '<form class="flat formboxfilter" method="POST" action="'.$_SERVER["PHP_SELF"].'">';
218 $stringtoshow .= '<input type="hidden" name="token" value="'.newToken().'">';
219 $stringtoshow .= '<input type="hidden" name="action" value="refresh">';
220 $stringtoshow .= '<input type="hidden" name="DOL_AUTOSET_COOKIE" value="DOLUSERCOOKIE_ticket_by_status:year,shownb,showtot">';
221 $stringtoshow .= $langs->trans("Year").' <input class="flat" size="4" type="text" name="'.$param_year.'" value="'.$endyear.'">';
222 $stringtoshow .= '<input type="image" alt="'.$langs->trans("Refresh").'" src="'.img_picto($langs->trans("Refresh"), 'refresh.png', '', '', 1).'">';
223 $stringtoshow .= '</form>';
224 $stringtoshow .= '</div>';
225 
226 print '<div class="div-table-responsive-no-min">';
227 print '<table class="noborder centpercent">';
228 print '<tr class="liste_titre"><th >'.$langs->trans("Statistics").' '.$endyear.' '.img_picto('', 'filter.png', 'id="idsubimgDOLUSERCOOKIE_ticket_by_status" class="linkobject"').'</th></tr>';
229 
230 print '<tr><td class="center">';
231 print $stringtoshow;
232 
233 // don't display graph if no series
234 if (!empty($dataseries) && count($dataseries) > 1) {
235  $totalnb = 0;
236  foreach ($dataseries as $key => $value) {
237  $totalnb += $value['data'];
238  }
239 
240  $data = array();
241  foreach ($dataseries as $key => $value) {
242  $data[] = array($value['label'], $value['data']);
243  }
244  $px1 = new DolGraph();
245  $mesg = $px1->isGraphKo();
246  if (!$mesg) {
247  $px1->SetData($data);
248  $px1->SetDataColor(array_values($colorseries));
249 
250  unset($data1);
251  $i = $startyear;
252  $legend = array();
253  while ($i <= $endyear) {
254  $legend[] = $i;
255  $i++;
256  }
257  $px1->setShowLegend(2);
258  $px1->SetType(array('pie'));
259  $px1->SetLegend($legend);
260  $px1->SetMaxValue($px1->GetCeilMaxValue());
261  //$px1->SetWidth($WIDTH);
262  $px1->SetHeight($HEIGHT);
263  $px1->SetYLabel($langs->trans("TicketStatByStatus"));
264  $px1->SetShading(3);
265  $px1->SetHorizTickIncrement(1);
266  $px1->SetCssPrefix("cssboxes");
267  $px1->mode = 'depth';
268  //$px1->SetTitle($langs->trans("TicketStatByStatus"));
269 
270  $px1->draw($filenamenb, $fileurlnb);
271  print $px1->show($totalnb ? 0 : 1);
272  }
273 }
274 print '</td></tr>';
275 
276 print '</table>';
277 print '</div>';
278 
279 // Build graphic number of object
280 $data = $stats->getNbByMonthWithPrevYear($endyear, $startyear);
281 
282 print '</div><div class="fichetwothirdright"><div class="ficheaddleft">';
283 
284 
285 /*
286  * Latest tickets
287  */
288 
289 $max = 10;
290 
291 $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,";
292 $sql .= " type.code as type_code, type.label as type_label,";
293 $sql .= " category.code as category_code, category.label as category_label,";
294 $sql .= " severity.code as severity_code, severity.label as severity_label";
295 $sql .= " FROM ".MAIN_DB_PREFIX."ticket as t";
296 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticket_type as type ON type.code=t.type_code";
297 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticket_category as category ON category.code=t.category_code";
298 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_ticket_severity as severity ON severity.code=t.severity_code";
299 if (!$user->rights->societe->client->voir && !$socid) {
300  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
301 }
302 
303 $sql .= ' WHERE t.entity IN ('.getEntity('ticket').')';
304 $sql .= " AND t.fk_statut=0";
305 if (!$user->rights->societe->client->voir && !$socid) {
306  $sql .= " AND t.fk_soc = sc.fk_soc AND sc.fk_user = ".$user->id;
307 }
308 
309 if ($user->socid > 0) {
310  $sql .= " AND t.fk_soc= ".((int) $user->socid);
311 } else {
312  // Restricted to assigned user only
313  if ($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY && !$user->rights->ticket->manage) {
314  $sql .= " AND t.fk_user_assign=".$user->id;
315  }
316 }
317 $sql .= $db->order("t.datec", "DESC");
318 $sql .= $db->plimit($max, 0);
319 
320 //print $sql;
321 $result = $db->query($sql);
322 if ($result) {
323  $num = $db->num_rows($result);
324 
325  $i = 0;
326 
327  $transRecordedType = $langs->trans("LatestNewTickets", $max);
328 
329  print '<div class="div-table-responsive-no-min">';
330  print '<table class="noborder centpercent">';
331  print '<tr class="liste_titre"><th colspan="5">'.$transRecordedType.'</th>';
332  print '<th class="right" colspan="2"><a href="'.DOL_URL_ROOT.'/ticket/list.php?search_fk_statut[]='.Ticket::STATUS_NOT_READ.'">'.$langs->trans("FullList").'</th>';
333  print '</tr>';
334  if ($num > 0) {
335  while ($i < $num) {
336  $objp = $db->fetch_object($result);
337 
338  $tickesupstatic->id = $objp->rowid;
339  $tickesupstatic->ref = $objp->ref;
340  $tickesupstatic->track_id = $objp->track_id;
341  $tickesupstatic->fk_statut = $objp->fk_statut;
342  $tickesupstatic->progress = $objp->progress;
343  $tickesupstatic->subject = $objp->subject;
344 
345  print '<tr class="oddeven">';
346 
347  // Ref
348  print '<td class="nowraponall">';
349  print $tickesupstatic->getNomUrl(1);
350  print "</td>\n";
351 
352  // Creation date
353  print '<td class="left">';
354  print dol_print_date($db->jdate($objp->datec), 'dayhour');
355  print "</td>";
356 
357  // Subject
358  print '<td class="nowrap">';
359  print '<a href="card.php?track_id='.$objp->track_id.'">'.dol_trunc($objp->subject, 30).'</a>';
360  print "</td>\n";
361 
362  // Type
363  print '<td class="nowrap tdoverflowmax100">';
364  $s = $langs->getLabelFromKey($db, 'TicketTypeShort'.$objp->type_code, 'c_ticket_type', 'code', 'label', $objp->type_code);
365  print '<span title="'.dol_escape_htmltag($s).'">'.$s.'</span>';
366  print '</td>';
367 
368  // Category
369  print '<td class="nowrap">';
370  $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$objp->category_code, 'c_ticket_category', 'code', 'label', $objp->category_code);
371  print '<span title="'.dol_escape_htmltag($s).'">'.$s.'</span>';
372  //print $objp->category_label;
373  print "</td>";
374 
375  // Severity
376  print '<td class="nowrap">';
377  $s = $langs->getLabelFromKey($db, 'TicketSeverityShort'.$objp->severity_code, 'c_ticket_severity', 'code', 'label', $objp->severity_code);
378  print '<span title="'.dol_escape_htmltag($s).'">'.$s.'</span>';
379  //print $objp->severity_label;
380  print "</td>";
381 
382  print '<td class="nowraponall right">';
383  print $tickesupstatic->getLibStatut(5);
384  print "</td>";
385 
386  print "</tr>\n";
387  $i++;
388  }
389 
390  $db->free($result);
391  } else {
392  print '<tr><td colspan="6" class="opacitymedium">'.$langs->trans('NoUnreadTicketsFound').'</td></tr>';
393  }
394 
395  print "</table>";
396  print '</div>';
397 } else {
398  dol_print_error($db);
399 }
400 
401 print '</div></div></div>';
402 print '<div style="clear:both"></div>';
403 
404 $parameters = array('user' => $user);
405 $reshook = $hookmanager->executeHooks('dashboardTickets', $parameters, $object); // Note that $action and $object may have been modified by hook
406 
407 // End of page
408 llxFooter('');
409 $db->close();
GETPOST($paramname, $check= 'alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Classe permettant la gestion des stats des deplacements et notes de frais.
dol_now($mode= 'auto')
Return date for now.
Class to manage ticket.
llxHeader()
Empty header.
Definition: wrapper.php:45
Class to manage hooks.
Class to manage generation of HTML components Only common components must be here.
load_fiche_titre($titre, $morehtmlright= '', $picto= 'generic', $pictoisfullpath=0, $id= '', $morecssontable= '', $morehtmlcenter= '')
Load a title with picto.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
dol_getdate($timestamp, $fast=false, $forcetimezone= '')
Return an array with locale date info.
restrictedArea($user, $features, $objectid=0, $tableandshare= '', $feature2= '', $dbt_keyfield= 'fk_soc', $dbt_select= 'rowid', $isdraft=0)
Check permissions of a user to show a page and an object.
dolSqlDateFilter($datefield, $day_date, $month_date, $year_date, $excludefirstand=0)
Generate a SQL string to make a filter into a range (for second of date until last second of date) ...
Definition: date.lib.php:281
print
Draft customers invoices.
Definition: index.php:89
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Class to build graphs.
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
static getDefaultGraphSizeForStats($direction, $defaultsize= '')
getDefaultGraphSizeForStats
dol_trunc($string, $size=40, $trunc= 'right', $stringencoding= 'UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding &#39;...&#39; if string larger than length.
const STATUS_NOT_READ
Status.
llxFooter()
Empty footer.
Definition: wrapper.php:59