dolibarr  16.0.5
ticket.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2013-2018 Jean-François FERRY <hello@librethic.io>
3  * Copyright (C) 2016 Christophe Battarel <christophe@altairis.fr>
4  * Copyright (C) 2019-2020 Frédéric France <frederic.france@netlogic.fr>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
32 {
33  global $langs, $conf;
34 
35  $langs->load("ticket");
36 
37  $h = 0;
38  $head = array();
39 
40  $head[$h][0] = DOL_URL_ROOT.'/admin/ticket.php';
41  $head[$h][1] = $langs->trans("TicketSettings");
42  $head[$h][2] = 'settings';
43  $h++;
44 
45  $head[$h][0] = DOL_URL_ROOT.'/admin/ticket_extrafields.php';
46  $head[$h][1] = $langs->trans("ExtraFieldsTicket");
47  $head[$h][2] = 'attributes';
48  $h++;
49 
50  $head[$h][0] = DOL_URL_ROOT.'/admin/ticket_public.php';
51  $head[$h][1] = $langs->trans("PublicInterface");
52  $head[$h][2] = 'public';
53  $h++;
54 
55  // Show more tabs from modules
56  // Entries must be declared in modules descriptor with line
57  //$this->tabs = array(
58  // 'entity:+tabname:Title:@ticket:/ticket/mypage.php?id=__ID__'
59  //); // to add new tab
60  //$this->tabs = array(
61  // 'entity:-tabname:Title:@ticket:/ticket/mypage.php?id=__ID__'
62  //); // to remove a tab
63  complete_head_from_modules($conf, $langs, null, $head, $h, 'ticketadmin');
64 
65  complete_head_from_modules($conf, $langs, null, $head, $h, 'ticketadmin', 'remove');
66 
67  return $head;
68 }
69 
76 function ticket_prepare_head($object)
77 {
78  global $db, $langs, $conf, $user;
79 
80  $h = 0;
81  $head = array();
82  $head[$h][0] = DOL_URL_ROOT.'/ticket/card.php?action=view&track_id='.$object->track_id;
83  $head[$h][1] = $langs->trans("Ticket");
84  $head[$h][2] = 'tabTicket';
85  $h++;
86 
87  if (empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && empty($user->socid) && isModEnabled("societe")) {
88  $nbContact = count($object->liste_contact(-1, 'internal')) + count($object->liste_contact(-1, 'external'));
89  $head[$h][0] = DOL_URL_ROOT.'/ticket/contact.php?track_id='.$object->track_id;
90  $head[$h][1] = $langs->trans('ContactsAddresses');
91  if ($nbContact > 0) {
92  $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbContact.'</span>';
93  }
94  $head[$h][2] = 'contact';
95  $h++;
96  }
97 
98  complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticket');
99 
100  // Attached files
101  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
102  $upload_dir = $conf->ticket->dir_output."/".$object->ref;
103  $nbFiles = count(dol_dir_list($upload_dir, 'files'));
104  $head[$h][0] = DOL_URL_ROOT.'/ticket/document.php?id='.$object->id;
105  $head[$h][1] = $langs->trans("Documents");
106  if ($nbFiles > 0) {
107  $head[$h][1] .= '<span class="badge marginleftonlyshort">'.$nbFiles.'</span>';
108  }
109 
110  $head[$h][2] = 'tabTicketDocument';
111  $h++;
112 
113 
114  // History
115  $ticketViewType = "messaging";
116  if (empty($_SESSION['ticket-view-type'])) {
117  $_SESSION['ticket-view-type'] = $ticketViewType;
118  } else {
119  $ticketViewType = $_SESSION['ticket-view-type'];
120  }
121 
122  if ($ticketViewType == "messaging") {
123  $head[$h][0] = DOL_URL_ROOT.'/ticket/messaging.php?track_id='.$object->track_id;
124  } else {
125  // $ticketViewType == "list"
126  $head[$h][0] = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id;
127  }
128  $head[$h][1] = $langs->trans('Events');
129  if (isModEnabled('agenda') && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read))) {
130  $head[$h][1] .= '/';
131  $head[$h][1] .= $langs->trans("Agenda");
132  }
133  $head[$h][2] = 'tabTicketLogs';
134  $h++;
135 
136  complete_head_from_modules($conf, $langs, $object, $head, $h, 'ticket', 'remove');
137 
138  return $head;
139 }
140 
147 function showDirectPublicLink($object)
148 {
149  global $conf, $langs;
150 
151  require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
152  $email = CMailFile::getValidAddress($object->origin_email, 2);
153  $url = '';
154  if ($email) {
155  $url = dol_buildpath('/public/ticket/view.php', 3).'?track_id='.$object->track_id.'&email='.$email;
156  }
157 
158  $out = '';
159  if (empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE)) {
160  $langs->load('errors');
161  $out .= '<span class="opacitymedium">'.$langs->trans("ErrorPublicInterfaceNotEnabled").'</span>';
162  } else {
163  $out .= img_picto('', 'object_globe.png').' <span class="opacitymedium">'.$langs->trans("TicketPublicAccess").'</span><br>';
164  if ($url) {
165  $out .= '<div class="urllink">';
166  $out .= '<input type="text" id="directpubliclink" class="quatrevingtpercentminusx" value="'.$url.'">';
167  $out .= '<a href="'.$url.'" target="_blank" rel="noopener noreferrer">'.img_picto('', 'object_globe.png', 'class="paddingleft"').'</a>';
168  $out .= '</div>';
169  $out .= ajax_autoselect("directpubliclink", 0);
170  } else {
171  $out .= '<span class="opacitymedium">'.$langs->trans("TicketNotCreatedFromPublicInterface").'</span>';
172  }
173  }
174 
175  return $out;
176 }
177 
184 function generate_random_id($car = 16)
185 {
186  $string = "";
187  $chaine = "abcdefghijklmnopqrstuvwxyz123456789";
188  mt_srand((double) microtime() * 1000000);
189  for ($i = 0; $i < $car; $i++) {
190  $string .= $chaine[mt_rand() % strlen($chaine)];
191  }
192  return $string;
193 }
194 
206 function llxHeaderTicket($title, $head = "", $disablejs = 0, $disablehead = 0, $arrayofjs = '', $arrayofcss = '')
207 {
208  global $user, $conf, $langs, $mysoc;
209 
210  top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss, 0, 1); // Show html headers
211 
212  print '<body id="mainbody" class="publicnewticketform">';
213  print '<div class="center">';
214 
215  // Define urllogo
216  if (!empty($conf->global->TICKET_SHOW_COMPANY_LOGO) || !empty($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC)) {
217  // Print logo
218  if (!empty($conf->global->TICKET_SHOW_COMPANY_LOGO)) {
219  $urllogo = DOL_URL_ROOT.'/theme/common/login_logo.png';
220 
221  if (!empty($mysoc->logo_small) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small)) {
222  $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$mysoc->logo_small);
223  } elseif (!empty($mysoc->logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$mysoc->logo)) {
224  $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$mysoc->logo);
225  } elseif (is_readable(DOL_DOCUMENT_ROOT.'/theme/dolibarr_logo.svg')) {
226  $urllogo = DOL_URL_ROOT.'/theme/dolibarr_logo.svg';
227  }
228  }
229  }
230 
231  // Output html code for logo
232  if ($urllogo || !empty($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC)) {
233  print '<div class="backgreypublicpayment">';
234  print '<div class="logopublicpayment">';
235  if ($urllogo) {
236  print '<a href="'.($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE : dol_buildpath('/public/ticket/index.php?entity='.$conf->entity, 1)).'">';
237  print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
238  print '>';
239  print '</a>';
240  }
241  if (!empty($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC)) {
242  print '<div class="clearboth"></div><strong>'.($conf->global->TICKET_PUBLIC_INTERFACE_TOPIC ? $conf->global->TICKET_PUBLIC_INTERFACE_TOPIC : $langs->trans("TicketSystem")).'</strong>';
243  }
244  print '</div>';
245  if (empty($conf->global->MAIN_HIDE_POWERED_BY)) {
246  print '<div class="poweredbypublicpayment opacitymedium right"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
247  }
248  print '</div>';
249  }
250 
251  if (!empty($conf->global->TICKET_IMAGE_PUBLIC_INTERFACE)) {
252  print '<div class="backimagepublicticket">';
253  print '<img id="idRECRUITMENT_IMAGE_PUBLIC_INTERFACE" src="'.$conf->global->MEMBER_IMAGE_PUBLIC_REGISTRATION.'">';
254  print '</div>';
255  }
256 
257  print '</div>';
258 
259  print '<div class="ticketlargemargin">';
260 }
261 
262 
263 
281 function show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon = '', $noprint = 0, $actioncode = '', $donetodo = 'done', $filters = array(), $sortfield = 'a.datep,a.id', $sortorder = 'DESC')
282 {
283  global $user, $conf;
284  global $form;
285 
286  global $param, $massactionbutton;
287 
288  dol_include_once('/comm/action/class/actioncomm.class.php');
289 
290  // Check parameters
291  if (!is_object($filterobj) && !is_object($objcon)) {
292  dol_print_error('', 'BadParameter');
293  }
294 
295  $histo = array();
296  $numaction = 0;
297  $now = dol_now();
298 
299  $sortfield_list = explode(',', $sortfield);
300  $sortfield_label_list = array('a.id' => 'id', 'a.datep' => 'dp', 'a.percent' => 'percent');
301  $sortfield_new_list = array();
302  foreach ($sortfield_list as $sortfield_value) {
303  $sortfield_new_list[] = $sortfield_label_list[trim($sortfield_value)];
304  }
305  $sortfield_new = implode(',', $sortfield_new_list);
306 
307  if (isModEnabled('agenda')) {
308  // Search histo on actioncomm
309  if (is_object($objcon) && $objcon->id > 0) {
310  $sql = "SELECT DISTINCT a.id, a.label as label,";
311  } else {
312  $sql = "SELECT a.id, a.label as label,";
313  }
314  $sql .= " a.datep as dp,";
315  $sql .= " a.note as message,";
316  $sql .= " a.datep2 as dp2,";
317  $sql .= " a.percent as percent, 'action' as type,";
318  $sql .= " a.fk_element, a.elementtype,";
319  $sql .= " a.fk_contact,";
320  $sql .= " c.code as acode, c.libelle as alabel, c.picto as apicto,";
321  $sql .= " u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname";
322  if (is_object($filterobj) && get_class($filterobj) == 'Societe') {
323  $sql .= ", sp.lastname, sp.firstname";
324  } elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') {
325  $sql .= ", m.lastname, m.firstname";
326  } elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') {
327  $sql .= ", o.ref";
328  } elseif (is_object($filterobj) && get_class($filterobj) == 'Product') {
329  $sql .= ", o.ref";
330  } elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') {
331  $sql .= ", o.ref";
332  } elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') {
333  $sql .= ", o.ref";
334  } elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') {
335  $sql .= ", o.ref";
336  }
337  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
338  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_action";
339  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id";
340 
341  $force_filter_contact = false;
342  if (is_object($objcon) && $objcon->id > 0) {
343  $force_filter_contact = true;
344  $sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as r ON a.id = r.fk_actioncomm";
345  $sql .= " AND r.element_type = '".$db->escape($objcon->table_element)."' AND r.fk_element = ".((int) $objcon->id);
346  }
347 
348  if (is_object($filterobj) && get_class($filterobj) == 'Societe') {
349  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid";
350  } elseif (is_object($filterobj) && get_class($filterobj) == 'Dolresource') {
351  $sql .= " INNER JOIN ".MAIN_DB_PREFIX."element_resources as er";
352  $sql .= " ON er.resource_type = 'dolresource'";
353  $sql .= " AND er.element_id = a.id";
354  $sql .= " AND er.resource_id = ".((int) $filterobj->id);
355  } elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') {
356  $sql .= ", ".MAIN_DB_PREFIX."adherent as m";
357  } elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') {
358  $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseur as o";
359  } elseif (is_object($filterobj) && get_class($filterobj) == 'Product') {
360  $sql .= ", ".MAIN_DB_PREFIX."product as o";
361  } elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') {
362  $sql .= ", ".MAIN_DB_PREFIX."ticket as o";
363  } elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') {
364  $sql .= ", ".MAIN_DB_PREFIX."bom_bom as o";
365  } elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') {
366  $sql .= ", ".MAIN_DB_PREFIX."contrat as o";
367  }
368 
369  $sql .= " WHERE a.entity IN (".getEntity('agenda').")";
370  if ($force_filter_contact === false) {
371  if (is_object($filterobj) && in_array(get_class($filterobj), array('Societe', 'Client', 'Fournisseur')) && $filterobj->id) {
372  $sql .= " AND a.fk_soc = ".((int) $filterobj->id);
373  } elseif (is_object($filterobj) && get_class($filterobj) == 'Project' && $filterobj->id) {
374  $sql .= " AND a.fk_project = ".((int) $filterobj->id);
375  } elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') {
376  $sql .= " AND a.fk_element = m.rowid AND a.elementtype = 'member'";
377  if ($filterobj->id) {
378  $sql .= " AND a.fk_element = ".((int) $filterobj->id);
379  }
380  } elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') {
381  $sql .= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'";
382  if ($filterobj->id) {
383  $sql .= " AND a.fk_element = ".((int) $filterobj->id);
384  }
385  } elseif (is_object($filterobj) && get_class($filterobj) == 'Product') {
386  $sql .= " AND a.fk_element = o.rowid AND a.elementtype = 'product'";
387  if ($filterobj->id) {
388  $sql .= " AND a.fk_element = ".((int) $filterobj->id);
389  }
390  } elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') {
391  $sql .= " AND a.fk_element = o.rowid AND a.elementtype = 'ticket'";
392  if ($filterobj->id) {
393  $sql .= " AND a.fk_element = ".((int) $filterobj->id);
394  }
395  } elseif (is_object($filterobj) && get_class($filterobj) == 'BOM') {
396  $sql .= " AND a.fk_element = o.rowid AND a.elementtype = 'bom'";
397  if ($filterobj->id) {
398  $sql .= " AND a.fk_element = ".((int) $filterobj->id);
399  }
400  } elseif (is_object($filterobj) && get_class($filterobj) == 'Contrat') {
401  $sql .= " AND a.fk_element = o.rowid AND a.elementtype = 'contract'";
402  if ($filterobj->id) {
403  $sql .= " AND a.fk_element = ".((int) $filterobj->id);
404  }
405  }
406  }
407 
408  // Condition on actioncode
409  if (!empty($actioncode)) {
410  if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
411  if ($actioncode == 'AC_NON_AUTO') {
412  $sql .= " AND c.type != 'systemauto'";
413  } elseif ($actioncode == 'AC_ALL_AUTO') {
414  $sql .= " AND c.type = 'systemauto'";
415  } else {
416  if ($actioncode == 'AC_OTH') {
417  $sql .= " AND c.type != 'systemauto'";
418  } elseif ($actioncode == 'AC_OTH_AUTO') {
419  $sql .= " AND c.type = 'systemauto'";
420  }
421  }
422  } else {
423  if ($actioncode == 'AC_NON_AUTO') {
424  $sql .= " AND c.type != 'systemauto'";
425  } elseif ($actioncode == 'AC_ALL_AUTO') {
426  $sql .= " AND c.type = 'systemauto'";
427  } else {
428  $sql .= " AND c.code = '".$db->escape($actioncode)."'";
429  }
430  }
431  }
432  if ($donetodo == 'todo') {
433  $sql .= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
434  } elseif ($donetodo == 'done') {
435  $sql .= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
436  }
437  if (is_array($filters) && $filters['search_agenda_label']) {
438  $sql .= natural_search('a.label', $filters['search_agenda_label']);
439  }
440  }
441 
442  // Add also event from emailings. TODO This should be replaced by an automatic event ? May be it's too much for very large emailing.
443  if (!empty($conf->mailing->enabled) && !empty($objcon->email)
444  && (empty($actioncode) || $actioncode == 'AC_OTH_AUTO' || $actioncode == 'AC_EMAILING')) {
445  $langs->load("mails");
446 
447  $sql2 = "SELECT m.rowid as id, m.titre as label, mc.date_envoi as dp, mc.date_envoi as dp2, '100' as percent, 'mailing' as type";
448  $sql2 .= ", null as fk_element, '' as elementtype, null as contact_id";
449  $sql2 .= ", 'AC_EMAILING' as acode, '' as alabel, '' as apicto";
450  $sql2 .= ", u.rowid as user_id, u.login as user_login, u.photo as user_photo, u.firstname as user_firstname, u.lastname as user_lastname"; // User that valid action
451  if (is_object($filterobj) && get_class($filterobj) == 'Societe') {
452  $sql2 .= ", '' as lastname, '' as firstname";
453  } elseif (is_object($filterobj) && get_class($filterobj) == 'Adherent') {
454  $sql2 .= ", '' as lastname, '' as firstname";
455  } elseif (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') {
456  $sql2 .= ", '' as ref";
457  } elseif (is_object($filterobj) && get_class($filterobj) == 'Product') {
458  $sql2 .= ", '' as ref";
459  } elseif (is_object($filterobj) && get_class($filterobj) == 'Ticket') {
460  $sql2 .= ", '' as ref";
461  }
462  $sql2 .= " FROM ".MAIN_DB_PREFIX."mailing as m, ".MAIN_DB_PREFIX."mailing_cibles as mc, ".MAIN_DB_PREFIX."user as u";
463  $sql2 .= " WHERE mc.email = '".$db->escape($objcon->email)."'"; // Search is done on email.
464  $sql2 .= " AND mc.statut = 1";
465  $sql2 .= " AND u.rowid = m.fk_user_valid";
466  $sql2 .= " AND mc.fk_mailing=m.rowid";
467  }
468 
469  if (!empty($sql) && !empty($sql2)) {
470  $sql = $sql." UNION ".$sql2;
471  } elseif (empty($sql) && !empty($sql2)) {
472  $sql = $sql2;
473  }
474 
475  // TODO Add limit in nb of results
476  if ($sql) { // May not be defined if module Agenda is not enabled and mailing module disabled too
477  $sql .= $db->order($sortfield_new, $sortorder);
478 
479  dol_syslog("ticket.lib::show_ticket_messaging", LOG_DEBUG);
480  $resql = $db->query($sql);
481  if ($resql) {
482  $i = 0;
483  $num = $db->num_rows($resql);
484 
485  while ($i < $num) {
486  $obj = $db->fetch_object($resql);
487 
488  if ($obj->type == 'action') {
489  $contactaction = new ActionComm($db);
490  $contactaction->id = $obj->id;
491  $result = $contactaction->fetchResources();
492  if ($result < 0) {
493  dol_print_error($db);
494  setEventMessage("ticket.lib::show_ticket_messaging Error fetch ressource", 'errors');
495  }
496 
497  //if ($donetodo == 'todo') $sql.= " AND ((a.percent >= 0 AND a.percent < 100) OR (a.percent = -1 AND a.datep > '".$db->idate($now)."'))";
498  //elseif ($donetodo == 'done') $sql.= " AND (a.percent = 100 OR (a.percent = -1 AND a.datep <= '".$db->idate($now)."'))";
499  $tododone = '';
500  if (($obj->percent >= 0 and $obj->percent < 100) || ($obj->percent == -1 && $obj->datep > $now)) {
501  $tododone = 'todo';
502  }
503 
504  $histo[$numaction] = array(
505  'type'=>$obj->type,
506  'tododone'=>$tododone,
507  'id'=>$obj->id,
508  'datestart'=>$db->jdate($obj->dp),
509  'dateend'=>$db->jdate($obj->dp2),
510  'note'=>$obj->label,
511  'message'=>$obj->message,
512  'percent'=>$obj->percent,
513 
514  'userid'=>$obj->user_id,
515  'login'=>$obj->user_login,
516  'userfirstname'=>$obj->user_firstname,
517  'userlastname'=>$obj->user_lastname,
518  'userphoto'=>$obj->user_photo,
519 
520  'contact_id'=>$obj->fk_contact,
521  'socpeopleassigned' => $contactaction->socpeopleassigned,
522  'lastname'=>$obj->lastname,
523  'firstname'=>$obj->firstname,
524  'fk_element'=>$obj->fk_element,
525  'elementtype'=>$obj->elementtype,
526  // Type of event
527  'acode'=>$obj->acode,
528  'alabel'=>$obj->alabel,
529  'libelle'=>$obj->alabel, // deprecated
530  'apicto'=>$obj->apicto
531  );
532  } else {
533  $histo[$numaction] = array(
534  'type'=>$obj->type,
535  'tododone'=>'done',
536  'id'=>$obj->id,
537  'datestart'=>$db->jdate($obj->dp),
538  'dateend'=>$db->jdate($obj->dp2),
539  'note'=>$obj->label,
540  'message'=>$obj->message,
541  'percent'=>$obj->percent,
542  'acode'=>$obj->acode,
543 
544  'userid'=>$obj->user_id,
545  'login'=>$obj->user_login,
546  'userfirstname'=>$obj->user_firstname,
547  'userlastname'=>$obj->user_lastname,
548  'userphoto'=>$obj->user_photo
549  );
550  }
551 
552  $numaction++;
553  $i++;
554  }
555  } else {
556  dol_print_error($db);
557  }
558  }
559 
560  // Set $out to sow events
561  $out = '';
562 
563  if (empty($conf->agenda->enabled)) {
564  $langs->loadLangs(array("admin", "errors"));
565  $out = info_admin($langs->trans("WarningModuleXDisabledSoYouMayMissEventHere", $langs->transnoentitiesnoconv("Module2400Name")), 0, 0, 'warning');
566  }
567 
568  if (isModEnabled('agenda') || (!empty($conf->mailing->enabled) && !empty($objcon->email))) {
569  $delay_warning = $conf->global->MAIN_DELAY_ACTIONS_TODO * 24 * 60 * 60;
570 
571  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
572  include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
573  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
574  require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
575 
576  $formactions = new FormActions($db);
577 
578  $actionstatic = new ActionComm($db);
579  $userstatic = new User($db);
580  $contactstatic = new Contact($db);
581  $userGetNomUrlCache = array();
582 
583  $out .= '<div class="filters-container" >';
584  $out .= '<form name="listactionsfilter" class="listactionsfilter" action="'.$_SERVER["PHP_SELF"].'" method="POST">';
585  $out .= '<input type="hidden" name="token" value="'.newToken().'">';
586 
587  if ($objcon && get_class($objcon) == 'Contact' &&
588  (is_null($filterobj) || get_class($filterobj) == 'Societe')) {
589  $out .= '<input type="hidden" name="id" value="'.$objcon->id.'" />';
590  } else {
591  $out .= '<input type="hidden" name="id" value="'.$filterobj->id.'" />';
592  }
593  if ($filterobj && get_class($filterobj) == 'Societe') {
594  $out .= '<input type="hidden" name="socid" value="'.$filterobj->id.'" />';
595  }
596 
597  $out .= "\n";
598 
599  $out .= '<div class="div-table-responsive-no-min">';
600  $out .= '<table class="noborder borderbottom centpercent">';
601 
602  $out .= '<tr class="liste_titre">';
603 
604  $out .= getTitleFieldOfList('Date', 0, $_SERVER["PHP_SELF"], 'a.datep', '', $param, '', $sortfield, $sortorder, '')."\n";
605 
606  $out .= '<th class="liste_titre"><strong class="hideonsmartphone">'.$langs->trans("Search").' : </strong></th>';
607  if ($donetodo) {
608  $out .= '<th class="liste_titre"></th>';
609  }
610  $out .= '<th class="liste_titre">';
611  $out .= '<span class="fas fa-square inline-block fawidth30" style=" color: #ddd;" title="'.$langs->trans("ActionType").'"></span>';
612  //$out .= img_picto($langs->trans("Type"), 'type');
613  $out .= $formactions->select_type_actions($actioncode, "actioncode", '', empty($conf->global->AGENDA_USE_EVENT_TYPE) ? 1 : -1, 0, 0, 1, 'minwidth200imp');
614  $out .= '</th>';
615  $out .= '<th class="liste_titre maxwidth100onsmartphone">';
616  $out .= '<input type="text" class="maxwidth100onsmartphone" name="search_agenda_label" value="'.$filters['search_agenda_label'].'" placeholder="'.$langs->trans("Label").'">';
617  $out .= '</th>';
618 
619  $out .= '<th class="liste_titre width50 middle">';
620  $searchpicto = $form->showFilterAndCheckAddButtons($massactionbutton ? 1 : 0, 'checkforselect', 1);
621  $out .= $searchpicto;
622  $out .= '</th>';
623  $out .= '</tr>';
624 
625 
626  $out .= '</table>';
627 
628  $out .= '</form>';
629  $out .= '</div>';
630 
631  $out .= "\n";
632 
633  $out .= '<ul class="timeline">';
634 
635  if ($donetodo) {
636  $tmp = '';
637  if (get_class($filterobj) == 'Societe') {
638  $tmp .= '<a href="'.DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&socid='.$filterobj->id.'&status=done">';
639  }
640  $tmp .= ($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : '');
641  $tmp .= ($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : '');
642  $tmp .= ($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : '');
643  //$out.=$langs->trans("ActionsToDoShort").' / '.$langs->trans("ActionsDoneShort");
644  if (get_class($filterobj) == 'Societe') {
645  $tmp .= '</a>';
646  }
647  $out .= getTitleFieldOfList($tmp);
648  }
649 
650 
651  //require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
652  //$caction=new CActionComm($db);
653  //$arraylist=$caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0), '', 1);
654 
655  $actualCycleDate = false;
656 
657  foreach ($histo as $key => $value) {
658  $actionstatic->fetch($histo[$key]['id']); // TODO Do we need this, we already have a lot of data of line into $histo
659 
660  $actionstatic->type_picto = $histo[$key]['apicto'];
661  $actionstatic->type_code = $histo[$key]['acode'];
662 
663  $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$histo[$key]['id'];
664 
665  $tmpa = dol_getdate($histo[$key]['datestart'], false);
666  if ($actualCycleDate !== $tmpa['year'].'-'.$tmpa['yday']) {
667  $actualCycleDate = $tmpa['year'].'-'.$tmpa['yday'];
668  $out .= '<!-- timeline time label -->';
669  $out .= '<li class="time-label">';
670  $out .= '<span class="timeline-badge-date">';
671  $out .= dol_print_date($histo[$key]['datestart'], 'daytext', 'tzuserrel', $langs);
672  $out .= '</span>';
673  $out .= '</li>';
674  $out .= '<!-- /.timeline-label -->';
675  }
676 
677 
678  $out .= '<!-- timeline item -->'."\n";
679  $out .= '<li class="timeline-code-'.strtolower($actionstatic->code).'">';
680 
681  $out .= getTicketTimelineIcon($actionstatic, $histo, $key);
682 
683  $out .= '<div class="timeline-item">'."\n";
684 
685  $out .= '<span class="timeline-header-action">';
686 
687  if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'mailing') {
688  $out .= '<a class="timeline-btn" href="'.DOL_URL_ROOT.'/comm/mailing/card.php?id='.$histo[$key]['id'].'">'.img_object($langs->trans("ShowEMailing"), "email").' ';
689  $out .= $histo[$key]['id'];
690  $out .= '</a> ';
691  } else {
692  $out .= $actionstatic->getNomUrl(1, -1, 'valignmiddle').' ';
693  }
694 
695  //if ($user->rights->agenda->allactions->read || $actionstatic->authorid == $user->id)
696  //{
697  // $out.='<a href="'.$url.'" class="timeline-btn" title="'.$langs->trans('Show').'" ><i class="fa fa-calendar" ></i>'.$langs->trans('Show').'</a>';
698  //}
699 
700  if ($user->rights->agenda->allactions->create ||
701  (($actionstatic->authorid == $user->id || $actionstatic->userownerid == $user->id) && $user->rights->agenda->myactions->create)) {
702  $out .= '<a class="timeline-btn" href="'.DOL_MAIN_URL_ROOT.'/comm/action/card.php?action=edit&token='.newToken().'&id='.$actionstatic->id.'"><i class="fa fa-pencil" title="'.$langs->trans("Modify").'" ></i></a>';
703  }
704 
705  $out .= '</span>';
706  // Date
707  $out .= '<span class="time"><i class="fa fa-clock-o"></i> ';
708  $out .= dol_print_date($histo[$key]['datestart'], 'dayhour', 'tzuserrel');
709  if ($histo[$key]['dateend'] && $histo[$key]['dateend'] != $histo[$key]['datestart']) {
710  $tmpa = dol_getdate($histo[$key]['datestart'], true);
711  $tmpb = dol_getdate($histo[$key]['dateend'], true);
712  if ($tmpa['mday'] == $tmpb['mday'] && $tmpa['mon'] == $tmpb['mon'] && $tmpa['year'] == $tmpb['year']) {
713  $out .= '-'.dol_print_date($histo[$key]['dateend'], 'hour', 'tzuserrel');
714  } else {
715  $out .= '-'.dol_print_date($histo[$key]['dateend'], 'dayhour', 'tzuserrel');
716  }
717  }
718  $late = 0;
719  if ($histo[$key]['percent'] == 0 && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) {
720  $late = 1;
721  }
722  if ($histo[$key]['percent'] == 0 && !$histo[$key]['datestart'] && $histo[$key]['dateend'] && $histo[$key]['datestart'] < ($now - $delay_warning)) {
723  $late = 1;
724  }
725  if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && $histo[$key]['dateend'] && $histo[$key]['dateend'] < ($now - $delay_warning)) {
726  $late = 1;
727  }
728  if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && !$histo[$key]['dateend'] && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) {
729  $late = 1;
730  }
731  if ($late) {
732  $out .= img_warning($langs->trans("Late")).' ';
733  }
734  $out .= "</span>\n";
735 
736  // Ref
737  $out .= '<h3 class="timeline-header">';
738 
739  // Author of event
740  $out .= '<span class="messaging-author">';
741  if ($histo[$key]['userid'] > 0) {
742  if (!isset($userGetNomUrlCache[$histo[$key]['userid']])) { // is in cache ?
743  $userstatic->fetch($histo[$key]['userid']);
744  $userGetNomUrlCache[$histo[$key]['userid']] = $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, 'firstelselast', '');
745  }
746  $out .= $userGetNomUrlCache[$histo[$key]['userid']];
747  }
748  $out .= '</span>';
749 
750  // Title
751  $out .= ' <span class="messaging-title">';
752 
753  if ($actionstatic->code == 'TICKET_MSG') {
754  $out .= $langs->trans('TicketNewMessage');
755  } elseif ($actionstatic->code == 'TICKET_MSG_PRIVATE') {
756  $out .= $langs->trans('TicketNewMessage').' <em>('.$langs->trans('Private').')</em>';
757  } else {
758  if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'action') {
759  $transcode = $langs->trans("Action".$histo[$key]['acode']);
760  $libelle = ($transcode != "Action".$histo[$key]['acode'] ? $transcode : $histo[$key]['alabel']);
761  $libelle = $histo[$key]['note'];
762  $actionstatic->id = $histo[$key]['id'];
763  $out .= dol_trunc($libelle, 120);
764  }
765  if (isset($histo[$key]['type']) && $histo[$key]['type'] == 'mailing') {
766  $out .= '<a href="'.DOL_URL_ROOT.'/comm/mailing/card.php?id='.$histo[$key]['id'].'">'.img_object($langs->trans("ShowEMailing"), "email").' ';
767  $transcode = $langs->trans("Action".$histo[$key]['acode']);
768  $libelle = ($transcode != "Action".$histo[$key]['acode'] ? $transcode : 'Send mass mailing');
769  $out .= dol_trunc($libelle, 120);
770  }
771  }
772 
773  $out .= '</span>';
774 
775  $out .= '</h3>';
776 
777  if (!empty($histo[$key]['message'])
778  && $actionstatic->code != 'AC_TICKET_CREATE'
779  && $actionstatic->code != 'AC_TICKET_MODIFY'
780  ) {
781  $out .= '<div class="timeline-body">';
782  $out .= $histo[$key]['message'];
783  $out .= '</div>';
784  }
785 
786  // Timeline footer
787  $footer = '';
788 
789  // Contact for this action
790  if (isset($histo[$key]['socpeopleassigned']) && is_array($histo[$key]['socpeopleassigned']) && count($histo[$key]['socpeopleassigned']) > 0) {
791  $contactList = '';
792  foreach ($histo[$key]['socpeopleassigned'] as $cid => $Tab) {
793  $contact = new Contact($db);
794  $result = $contact->fetch($cid);
795 
796  if ($result < 0) {
797  dol_print_error($db, $contact->error);
798  }
799 
800  if ($result > 0) {
801  $contactList .= !empty($contactList) ? ', ' : '';
802  $contactList .= $contact->getNomUrl(1);
803  if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
804  if (!empty($contact->phone_pro)) {
805  $contactList .= '('.dol_print_phone($contact->phone_pro).')';
806  }
807  }
808  }
809  }
810 
811  $footer .= $langs->trans('ActionOnContact').' : '.$contactList;
812  } elseif (empty($objcon->id) && isset($histo[$key]['contact_id']) && $histo[$key]['contact_id'] > 0) {
813  $contact = new Contact($db);
814  $result = $contact->fetch($histo[$key]['contact_id']);
815 
816  if ($result < 0) {
817  dol_print_error($db, $contact->error);
818  }
819 
820  if ($result > 0) {
821  $footer .= $contact->getNomUrl(1);
822  if (isset($histo[$key]['acode']) && $histo[$key]['acode'] == 'AC_TEL') {
823  if (!empty($contact->phone_pro)) {
824  $footer .= '('.dol_print_phone($contact->phone_pro).')';
825  }
826  }
827  }
828  }
829 
830  $documents = getTicketActionCommEcmList($actionstatic);
831  if (!empty($documents)) {
832  $footer .= '<div class="timeline-documents-container">';
833  foreach ($documents as $doc) {
834  $footer .= '<span id="document_'.$doc->id.'" class="timeline-documents" ';
835  $footer .= ' data-id="'.$doc->id.'" ';
836  $footer .= ' data-path="'.$doc->filepath.'"';
837  $footer .= ' data-filename="'.dol_escape_htmltag($doc->filename).'" ';
838  $footer .= '>';
839 
840  $filePath = DOL_DATA_ROOT.'/'.$doc->filepath.'/'.$doc->filename;
841  $mime = dol_mimetype($filePath);
842  $file = $actionstatic->id.'/'.$doc->filename;
843  $thumb = $actionstatic->id.'/thumbs/'.substr($doc->filename, 0, strrpos($doc->filename, '.')).'_mini'.substr($doc->filename, strrpos($doc->filename, '.'));
844  $doclink = dol_buildpath('document.php', 1).'?modulepart=actions&attachment=0&file='.urlencode($file).'&entity='.$conf->entity;
845  $viewlink = dol_buildpath('viewimage.php', 1).'?modulepart=actions&file='.urlencode($thumb).'&entity='.$conf->entity;
846 
847  $mimeAttr = ' mime="'.$mime.'" ';
848  $class = '';
849  if (in_array($mime, array('image/png', 'image/jpeg', 'application/pdf'))) {
850  $class .= ' documentpreview';
851  }
852 
853  $footer .= '<a href="'.$doclink.'" class="btn-link '.$class.'" target="_blank" rel="noopener noreferrer" '.$mimeAttr.' >';
854  $footer .= img_mime($filePath).' '.$doc->filename;
855  $footer .= '</a>';
856 
857  $footer .= '</span>';
858  }
859  $footer .= '</div>';
860  }
861 
862  if (!empty($footer)) {
863  $out .= '<div class="timeline-footer">'.$footer.'</div>';
864  }
865 
866  $out .= '</div>'."\n"; // end timeline-item
867 
868  $out .= '</li>';
869  $out .= '<!-- END timeline item -->';
870 
871  $i++;
872  }
873  $out .= "</ul>\n";
874  }
875 
876  if ($noprint) {
877  return $out;
878  } else {
879  print $out;
880  }
881 }
882 
890 function getTicketTimelineIcon($actionstatic, &$histo, $key)
891 {
892  global $conf, $langs;
893  $out = '<!-- timeline icon -->'."\n";
894  $iconClass = 'fa fa-comments';
895  $img_picto = '';
896  $colorClass = '';
897  $pictoTitle = '';
898 
899  if ($histo[$key]['percent'] == -1) {
900  $colorClass = 'timeline-icon-not-applicble';
901  $pictoTitle = $langs->trans('StatusNotApplicable');
902  } elseif ($histo[$key]['percent'] == 0) {
903  $colorClass = 'timeline-icon-todo';
904  $pictoTitle = $langs->trans('StatusActionToDo').' (0%)';
905  } elseif ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100) {
906  $colorClass = 'timeline-icon-in-progress';
907  $pictoTitle = $langs->trans('StatusActionInProcess').' ('.$histo[$key]['percent'].'%)';
908  } elseif ($histo[$key]['percent'] >= 100) {
909  $colorClass = 'timeline-icon-done';
910  $pictoTitle = $langs->trans('StatusActionDone').' (100%)';
911  }
912 
913  if ($actionstatic->code == 'AC_TICKET_CREATE') {
914  $iconClass = 'fa fa-ticket';
915  } elseif ($actionstatic->code == 'AC_TICKET_MODIFY') {
916  $iconClass = 'fa fa-pencilxxx';
917  } elseif ($actionstatic->code == 'TICKET_MSG') {
918  $iconClass = 'fa fa-comments';
919  } elseif ($actionstatic->code == 'TICKET_MSG_PRIVATE') {
920  $iconClass = 'fa fa-mask';
921  } elseif (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
922  if ($actionstatic->type_picto) {
923  $img_picto = img_picto('', $actionstatic->type_picto);
924  } else {
925  if ($actionstatic->type_code == 'AC_RDV') {
926  $iconClass = 'fa fa-handshake';
927  } elseif ($actionstatic->type_code == 'AC_TEL') {
928  $iconClass = 'fa fa-phone';
929  } elseif ($actionstatic->type_code == 'AC_FAX') {
930  $iconClass = 'fa fa-fax';
931  } elseif ($actionstatic->type_code == 'AC_EMAIL') {
932  $iconClass = 'fa fa-envelope';
933  } elseif ($actionstatic->type_code == 'AC_INT') {
934  $iconClass = 'fa fa-shipping-fast';
935  } elseif ($actionstatic->type_code == 'AC_OTH_AUTO') {
936  $iconClass = 'fa fa-robot';
937  } elseif (!preg_match('/_AUTO/', $actionstatic->type_code)) {
938  $iconClass = 'fa fa-robot';
939  }
940  }
941  }
942 
943  $out .= '<i class="'.$iconClass.' '.$colorClass.'" title="'.$pictoTitle.'">'.$img_picto.'</i>'."\n";
944  return $out;
945 }
946 
953 function getTicketActionCommEcmList($object)
954 {
955  global $conf, $db;
956 
957  $documents = array();
958 
959  $sql = 'SELECT ecm.rowid as id, ecm.src_object_type, ecm.src_object_id, ecm.filepath, ecm.filename';
960  $sql .= ' FROM '.MAIN_DB_PREFIX.'ecm_files ecm';
961  $sql .= " WHERE ecm.filepath = 'agenda/".((int) $object->id)."'";
962  //$sql.= " ecm.src_object_type = '".$db->escape($object->element)."' AND ecm.src_object_id = ".((int) $object->id); // Old version didn't add object_type during upload
963  $sql .= ' ORDER BY ecm.position ASC';
964 
965  $resql = $db->query($sql);
966  if ($resql) {
967  if ($db->num_rows($resql)) {
968  while ($obj = $db->fetch_object($resql)) {
969  $documents[$obj->id] = $obj;
970  }
971  }
972  }
973 
974  return $documents;
975 }
dol_getdate
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
Definition: functions.lib.php:2713
dol_trunc
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
Definition: functions.lib.php:3805
ActionComm
Class to manage agenda events (actions)
Definition: actioncomm.class.php:38
ticket_prepare_head
ticket_prepare_head($object)
Build tabs for a Ticket object.
Definition: ticket.lib.php:76
getTitleFieldOfList
getTitleFieldOfList($name, $thead=0, $file="", $field="", $begin="", $moreparam="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $disablesortlink=0, $tooltip='', $forcenowrapcolumntitle=0)
Get title line of an array.
Definition: functions.lib.php:5049
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4844
FormActions
Class to manage building of HTML components.
Definition: html.formactions.class.php:30
dol_include_once
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
Definition: functions.lib.php:1033
dol_buildpath
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
Definition: functions.lib.php:1062
img_warning
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
Definition: functions.lib.php:4521
top_htmlhead
top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $disableforlogin=0, $disablenofollow=0, $disablenoindex=0)
Ouput html header of a page.
Definition: main.inc.php:1482
dol_mimetype
dol_mimetype($file, $default='application/octet-stream', $mode=0)
Return MIME type of a file from its name with extension.
Definition: functions.lib.php:9741
llxHeaderTicket
llxHeaderTicket($title, $head="", $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='')
Show header for public pages.
Definition: ticket.lib.php:206
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
dol_dir_list
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:60
complete_head_from_modules
complete_head_from_modules($conf, $langs, $object, &$head, &$h, $type, $mode='add')
Complete or removed entries into a head array (used to build tabs).
Definition: functions.lib.php:9038
CMailFile\getValidAddress
static getValidAddress($address, $format, $encode=0, $maxnumberofemail=0)
Return a formatted address string for SMTP protocol.
Definition: CMailFile.class.php:1570
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2514
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:3880
getTicketTimelineIcon
getTicketTimelineIcon($actionstatic, &$histo, $key)
Get timeline icon.
Definition: ticket.lib.php:890
$formactions
if(preg_match('/set_([a-z0-9_\-]+)/i', $action, $reg)) if(preg_match('/del_([a-z0-9_\-]+)/i', $action, $reg)) if($action=='set') elseif($action=='specimen') elseif($action=='setmodel') elseif($action=='del') elseif($action=='setdoc') $formactions
View.
Definition: agenda_other.php:178
getTicketActionCommEcmList
getTicketActionCommEcmList($object)
getTicketActionCommEcmList
Definition: ticket.lib.php:953
ticketAdminPrepareHead
ticketAdminPrepareHead()
Build tabs for admin page.
Definition: ticket.lib.php:31
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1603
setEventMessage
setEventMessage($mesgs, $style='mesgs')
Set event message in dol_events session object.
Definition: functions.lib.php:8108
Contact
Class to manage contact/addresses.
Definition: contact.class.php:40
generate_random_id
generate_random_id($car=16)
Generate a random id.
Definition: ticket.lib.php:184
info_admin
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='')
Show information for admin users or standard users.
Definition: functions.lib.php:4800
newToken
newToken()
Return the value of token currently saved into session with name 'newtoken'.
Definition: functions.lib.php:10878
show_ticket_messaging
show_ticket_messaging($conf, $langs, $db, $filterobj, $objcon='', $noprint=0, $actioncode='', $donetodo='done', $filters=array(), $sortfield='a.datep, a.id', $sortorder='DESC')
Show html area with actions for ticket messaging.
Definition: ticket.lib.php:281
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:105
User
Class to manage Dolibarr users.
Definition: user.class.php:44
showDirectPublicLink
showDirectPublicLink($object)
Return string with full Url.
Definition: ticket.lib.php:147
natural_search
natural_search($fields, $value, $mode=0, $nofirstand=0)
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
Definition: functions.lib.php:9420
img_mime
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
Definition: functions.lib.php:4726
img_object
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
Definition: functions.lib.php:4211
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2845
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
ajax_autoselect
ajax_autoselect($htmlname, $addlink='', $textonlink='Link')
Make content of an input box selected when we click into input field.
Definition: functions.lib.php:9681