dolibarr  19.0.0-dev
card.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2013-2016 Jean-François FERRY <hello@librethic.io>
3  * Copyright (C) 2016 Christophe Battarel <christophe@altairis.fr>
4  * Copyright (C) 2018 Laurent Destailleur <eldy@users.sourceforge.net>
5  * Copyright (C) 2021 Frédéric France <frederic.france@netlogic.fr>
6  * Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
7  * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
8  * Copyright (C) 2023 Benjamin Falière <benjamin.faliere@altairis.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
29 // Load Dolibarr environment
30 require '../main.inc.php';
31 require_once DOL_DOCUMENT_ROOT.'/ticket/class/actions_ticket.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formticket.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/core/lib/ticket.lib.php';
34 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
35 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
38 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
39 if (isModEnabled('project')) {
40  include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
41  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
42  include_once DOL_DOCUMENT_ROOT.'/core/lib/project.lib.php';
43 }
44 if (isModEnabled('contrat')) {
45  include_once DOL_DOCUMENT_ROOT.'/core/lib/contract.lib.php';
46  include_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
47  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formcontract.class.php';
48 }
49 
50 // Load translation files required by the page
51 $langs->loadLangs(array("companies", "other", "ticket"));
52 
53 // Get parameters
54 $id = GETPOST('id', 'int');
55 $socid = GETPOST('socid', 'int');
56 $track_id = GETPOST('track_id', 'alpha', 3);
57 $ref = GETPOST('ref', 'alpha');
58 $projectid = GETPOST('projectid', 'int');
59 $cancel = GETPOST('cancel', 'alpha');
60 $action = GETPOST('action', 'aZ09');
61 $backtopage = GETPOST('backtopage', 'alpha');
62 $backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
63 $contactid = GETPOST('contactid', 'int');
64 
65 $notifyTiers = GETPOST("notify_tiers_at_create", 'alpha');
66 
67 $sortfield = GETPOST('sortfield', 'aZ09comma') ? GETPOST('sortfield', 'aZ09comma') : "a.datep";
68 $sortorder = GETPOST('sortorder', 'aZ09comma') ? GETPOST('sortorder', 'aZ09comma') : "desc";
69 
70 if (GETPOST('actioncode', 'array')) {
71  $actioncode = GETPOST('actioncode', 'array', 3);
72  if (!count($actioncode)) {
73  $actioncode = '0';
74  }
75 } else {
76  $actioncode = GETPOST("actioncode", "alpha", 3) ?GETPOST("actioncode", "alpha", 3) : (GETPOST("actioncode") == '0' ? '0' : getDolGlobalString('AGENDA_DEFAULT_FILTER_TYPE_FOR_OBJECT'));
77 }
78 $search_rowid = GETPOST('search_rowid');
79 $search_agenda_label = GETPOST('search_agenda_label');
80 
81 // Initialize technical object to manage hooks of ticket. Note that conf->hooks_modules contains array array
82 $hookmanager->initHooks(array('ticketcard', 'globalcard'));
83 
84 $object = new Ticket($db);
85 $extrafields = new ExtraFields($db);
86 
87 // Fetch optionals attributes and labels
88 $extrafields->fetch_name_optionals_label($object->table_element);
89 
90 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
91 
92 // Initialize array of search criterias
93 $search_all = GETPOST("search_all", 'alpha');
94 $search = array();
95 foreach ($object->fields as $key => $val) {
96  if (GETPOST('search_'.$key, 'alpha')) {
97  $search[$key] = GETPOST('search_'.$key, 'alpha');
98  }
99 }
100 
101 if (empty($action) && empty($id) && empty($ref)) {
102  $action = 'view';
103 }
104 
105 //Select mail models is same action as add_message
106 if (GETPOST('modelselected', 'alpha')) {
107  $action = 'presend';
108 }
109 
110 // Load object
111 //include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals
112 if ($id || $track_id || $ref) {
113  $res = $object->fetch($id, $ref, $track_id);
114  if ($res >= 0) {
115  $id = $object->id;
116  $track_id = $object->track_id;
117  }
118 }
119 
120 $now = dol_now();
121 
122 $actionobject = new ActionsTicket($db);
123 
124 // Store current page url
125 $url_page_current = DOL_URL_ROOT.'/ticket/card.php';
126 
127 // Security check - Protection if external user
128 if ($user->socid > 0) $socid = $user->socid;
129 $result = restrictedArea($user, 'ticket', $object->id);
130 
131 $triggermodname = 'TICKET_MODIFY';
132 $permissiontoread = $user->hasRight('ticket', 'read');
133 $permissiontoadd = $user->hasRight('ticket', 'write');
134 $permissiontodelete = $user->hasRight('ticket', 'delete');
135 
136 $upload_dir = $conf->ticket->dir_output;
137 
138 
139 
140 /*
141  * Actions
142  */
143 
144 $parameters = array();
145 $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
146 if ($reshook < 0) {
147  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
148 }
149 
150 $error = 0;
151 if (empty($reshook)) {
152  // Purge search criteria
153  if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // All test are required to be compatible with all browsers{
154  $actioncode = '';
155  $search_agenda_label = '';
156  }
157 
158  $backurlforlist = DOL_URL_ROOT.'/ticket/list.php';
159 
160  if (empty($backtopage) || ($cancel && empty($id))) {
161  if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
162  if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
163  $backtopage = $backurlforlist;
164  } else {
165  $backtopage = DOL_URL_ROOT.'/ticket/card.php?id='.((!empty($id) && $id > 0) ? $id : '__ID__');
166  }
167  }
168  }
169 
170  if ($cancel) {
171  if (!empty($backtopageforcancel)) {
172  header("Location: ".$backtopageforcancel);
173  exit;
174  } elseif (!empty($backtopage)) {
175  header("Location: ".$backtopage);
176  exit;
177  }
178  $action = 'view';
179  }
180 
181  // Action to add an action (not a message)
182  if (GETPOST('save', 'alpha') && $permissiontoadd) {
183  $error = 0;
184 
185  if (!GETPOST("type_code", 'alpha')) {
186  $error++;
187  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketTypeRequest")), null, 'errors');
188  $action = 'create';
189  } elseif (!GETPOST("category_code", 'alpha')) {
190  $error++;
191  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketCategory")), null, 'errors');
192  $action = 'create';
193  } elseif (!GETPOST("severity_code", 'alpha')) {
194  $error++;
195  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketSeverity")), null, 'errors');
196  $action = 'create';
197  } elseif (!GETPOST("subject", 'alphanohtml')) {
198  $error++;
199  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")), null, 'errors');
200  $action = 'create';
201  } elseif (!GETPOST("message", 'restricthtml')) {
202  $error++;
203  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Message")), null, 'errors');
204  $action = 'create';
205  }
206  $ret = $extrafields->setOptionalsFromPost(null, $object);
207  if ($ret < 0) {
208  $error++;
209  }
210 
211  if (!$error) {
212  $db->begin();
213 
214  $getRef = GETPOST("ref", 'alphanohtml');
215  if ($object->fetch('', $getRef) > 0) {
216  $object->ref = $object->getDefaultRef();
217  $object->track_id = null;
218  setEventMessage($langs->trans('TicketRefAlreadyUsed', $getRef, $object->ref));
219  } else {
220  $object->ref = $getRef;
221  }
222 
223  $object->fk_soc = GETPOST("socid", 'int') > 0 ? GETPOST("socid", 'int') : 0;
224  $object->subject = GETPOST("subject", 'alphanohtml');
225  $object->message = GETPOST("message", 'restricthtml');
226 
227  $object->type_code = GETPOST("type_code", 'alpha');
228  $object->type_label = $langs->trans($langs->getLabelFromKey($db, $object->type_code, 'c_ticket_type', 'code', 'label'));
229  $object->category_code = GETPOST("category_code", 'alpha');
230  $object->category_label = $langs->trans($langs->getLabelFromKey($db, $object->category_code, 'c_ticket_category', 'code', 'label'));
231  $object->severity_code = GETPOST("severity_code", 'alpha');
232  $object->severity_label = $langs->trans($langs->getLabelFromKey($db, $object->severity_code, 'c_ticket_severity', 'code', 'label'));
233  $object->email_from = $user->email;
234  $notifyTiers = GETPOST("notify_tiers_at_create", 'alpha');
235  $object->notify_tiers_at_create = empty($notifyTiers) ? 0 : 1;
236  $fk_user_assign = GETPOST("fk_user_assign", 'int');
237  if ($fk_user_assign > 0) {
238  $object->fk_user_assign = $fk_user_assign;
239  $object->status = $object::STATUS_ASSIGNED;
240  }
241 
242  $object->fk_project = $projectid;
243 
244  $id = $object->create($user);
245  if ($id <= 0) {
246  $error++;
247  setEventMessages($object->error, $object->errors, 'errors');
248  $action = 'create';
249  }
250 
251  if (!$error) {
252  // Add contact
253  $contactid = GETPOST('contactid', 'int');
254  $type_contact = GETPOST("type", 'alpha');
255 
256  // Category association
257  $categories = GETPOST('categories', 'array');
258  $object->setCategories($categories);
259 
260  if ($contactid > 0 && $type_contact) {
261  $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
262  $result = $object->add_contact($contactid, $typeid, 'external');
263  }
264 
265  // Link ticket to project
266  if (GETPOST('origin', 'alpha') == 'projet') {
267  $projectid = GETPOST('originid', 'int');
268  } else {
269  $projectid = GETPOST('projectid', 'int');
270  }
271 
272  if ($projectid > 0) {
273  $object->setProject($projectid);
274  }
275 
276  // Auto mark as read if created from backend
277  if (!empty($conf->global->TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND) && $user->rights->ticket->write) {
278  if ( ! $object->markAsRead($user) > 0) {
279  setEventMessages($object->error, $object->errors, 'errors');
280  }
281  }
282 
283  // Auto assign user
284  if (!empty($conf->global->TICKET_AUTO_ASSIGN_USER_CREATE)) {
285  $result = $object->assignUser($user, $user->id, 1);
286  $object->add_contact($user->id, "SUPPORTTEC", 'internal');
287  }
288  }
289 
290  if (!$error) {
291  // File transfer
292  $object->copyFilesForTicket(''); // trackid is forced to '' because files were uploaded when no id for ticket exists yet and trackid was ''
293  }
294 
295  if (!$error) {
296  $db->commit();
297 
298  if (!empty($backtopage)) {
299  if (empty($id)) {
300  $url = $backtopage;
301  } else {
302  $url = 'card.php?track_id='.urlencode($object->track_id);
303  }
304  } else {
305  $url = 'card.php?track_id='.urlencode($object->track_id);
306  }
307 
308  header("Location: ".$url);
309  exit;
310  } else {
311  $db->rollback();
312  setEventMessages($object->error, $object->errors, 'errors');
313  }
314  } else {
315  setEventMessages($object->error, $object->errors, 'errors');
316  $action = 'create';
317  }
318  }
319 
320  if ($action == 'update' && $permissiontoadd && $object->status < Ticket::STATUS_CLOSED) {
321  $error = 0;
322 
323  $ret = $object->fetch(GETPOST('id', 'int'), GETPOST('ref', 'alpha'), GETPOST('track_id', 'alpha'));
324  if ($ret < 0) {
325  $error++;
326  array_push($object->errors, $langs->trans('ErrorTicketIsNotValid'));
327  }
328 
329  // check fields
330  if (!$error) {
331  if (!GETPOST('subject', 'alpha')) {
332  $error++;
333  array_push($object->errors, $langs->trans('ErrorFieldRequired', $langs->transnoentities('Subject')));
334  }
335  $ret = $extrafields->setOptionalsFromPost(null, $object);
336  if ($ret < 0) {
337  $error++;
338  }
339  }
340 
341  if (!$error) {
342  $db->begin();
343 
344  $object->subject = GETPOST('subject', 'alpha');
345  $object->type_code = GETPOST('type_code', 'alpha');
346  $object->category_code = GETPOST('category_code', 'alpha');
347  $object->severity_code = GETPOST('severity_code', 'alpha');
348 
349  $ret = $object->update($user);
350  if ($ret > 0) {
351  // Category association
352  $categories = GETPOST('categories', 'array');
353  $object->setCategories($categories);
354  } else {
355  $error++;
356  }
357 
358  if ($error) {
359  $db->rollback();
360  } else {
361  $db->commit();
362  }
363  }
364 
365  if ($error) {
366  setEventMessages($object->error, $object->errors, 'errors');
367  $action = 'edit';
368  } else {
369  if (!empty($backtopage)) {
370  if (empty($id)) {
371  $url = $backtopage;
372  } else {
373  $url = 'card.php?track_id='.urlencode($object->track_id);
374  }
375  } else {
376  $url = 'card.php?track_id='.urlencode($object->track_id);
377  }
378 
379  header('Location: '.$url);
380  exit();
381  }
382  }
383 
384  // Mark as Read
385  if ($action == "set_read" && $permissiontoadd) {
386  $object->fetch('', '', GETPOST("track_id", 'alpha'));
387 
388  if ($object->markAsRead($user) > 0) {
389  setEventMessages($langs->trans('TicketMarkedAsRead'), null, 'mesgs');
390 
391  header("Location: card.php?track_id=".$object->track_id);
392  exit;
393  } else {
394  setEventMessages($object->error, $object->errors, 'errors');
395  }
396  $action = 'view';
397  }
398 
399  // Assign to someone
400  if ($action == "assign_user" && GETPOST('btn_assign_user', 'alpha') && $permissiontoadd) {
401  $object->fetch('', '', GETPOST("track_id", 'alpha'));
402  $useroriginassign = $object->fk_user_assign;
403  $usertoassign = GETPOST('fk_user_assign', 'int');
404 
405  /*if (! ($usertoassign > 0)) {
406  $error++;
407  array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("AssignedTo")));
408  $action = 'view';
409  }*/
410 
411  if (!$error) {
412  $ret = $object->assignUser($user, $usertoassign);
413  if ($ret < 0) {
414  $error++;
415  }
416  }
417 
418  if (!$error) { // Update list of contacts
419  // Si déjà un user assigné on le supprime des contacts
420  if ($useroriginassign > 0) {
421  $internal_contacts = $object->listeContact(-1, 'internal', 0, 'SUPPORTTEC');
422  foreach ($internal_contacts as $key => $contact) {
423  if ($contact['id'] !== $usertoassign) {
424  $result = $object->delete_contact($contact['rowid']);
425  if ($result<0) {
426  $error++;
427  setEventMessages($object->error, $object->errors, 'errors');
428  }
429  }
430  }
431  }
432 
433  if ($usertoassign > 0 && $usertoassign!==$useroriginassign) {
434  $result = $object->add_contact($usertoassign, "SUPPORTTEC", 'internal', $notrigger = 0);
435  if ($result<0) {
436  $error++;
437  setEventMessages($object->error, $object->errors, 'errors');
438  }
439  }
440  }
441 
442  if (!$error) {
443  // Log action in ticket logs table
444  $object->fetch_user($usertoassign);
445  //$log_action = $langs->trans('TicketLogAssignedTo', $object->user->getFullName($langs));
446 
447 
448  setEventMessages($langs->trans('TicketAssigned'), null, 'mesgs');
449  header("Location: card.php?track_id=".$object->track_id);
450  exit;
451  } else {
452  array_push($object->errors, $object->error);
453  }
454  $action = 'view';
455  }
456 
457  // Action to add a message (private or not, with email or not).
458  // This may also send an email (concatenated with email_intro and email footer if checkbox was selected)
459  if ($action == 'add_message' && GETPOSTISSET('btn_add_message') && $permissiontoread) {
460  $ret = $object->newMessage($user, $action, (GETPOST('private_message', 'alpha') == "on" ? 1 : 0), 0);
461 
462  if ($ret > 0) {
463  if (!empty($backtopage)) {
464  $url = $backtopage;
465  } else {
466  $url = 'card.php?track_id='.urlencode($object->track_id);
467  }
468 
469  header("Location: ".$url);
470  exit;
471  } else {
472  setEventMessages($object->error, $object->errors, 'errors');
473  $action = 'presend';
474  }
475  }
476 
477  if (($action == "confirm_close" || $action == "confirm_abandon") && GETPOST('confirm', 'alpha') == 'yes' && $permissiontoadd) {
478  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
479 
480  if ($object->close($user, ($action == "confirm_abandon" ? 1 : 0))) {
481  setEventMessages($langs->trans('TicketMarkedAsClosed'), null, 'mesgs');
482 
483  $url = 'card.php?track_id='.GETPOST('track_id', 'alpha');
484  header("Location: ".$url);
485  } else {
486  $action = '';
487  setEventMessages($object->error, $object->errors, 'errors');
488  }
489  }
490 
491  if ($action == "confirm_public_close" && GETPOST('confirm', 'alpha') == 'yes' && $permissiontoadd) {
492  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
493  if ($_SESSION['email_customer'] == $object->origin_email || $_SESSION['email_customer'] == $object->thirdparty->email) {
494  $object->close($user);
495 
496  // Log action in ticket logs table
497  //$log_action = $langs->trans('TicketLogClosedBy', $_SESSION['email_customer']);
498 
499  setEventMessages('<div class="confirm">'.$langs->trans('TicketMarkedAsClosed').'</div>', null, 'mesgs');
500 
501  $url = 'card.php?track_id='.GETPOST('track_id', 'alpha');
502  header("Location: ".$url);
503  } else {
504  setEventMessages($object->error, $object->errors, 'errors');
505  $action = '';
506  }
507  }
508 
509  if ($action == 'confirm_delete_ticket' && GETPOST('confirm', 'alpha') == "yes" && $permissiontodelete) {
510  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
511  if ($object->delete($user) > 0) {
512  setEventMessages('<div class="confirm">'.$langs->trans('TicketDeletedSuccess').'</div>', null, 'mesgs');
513  Header("Location: ".DOL_URL_ROOT."/ticket/list.php");
514  exit;
515  } else {
516  $langs->load("errors");
517  $mesg = '<div class="error">'.$langs->trans($object->error).'</div>';
518  $action = '';
519  }
520  }
521  }
522 
523  // Set parent company
524  if ($action == 'set_thirdparty' && $user->rights->ticket->write) {
525  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
526  $result = $object->setCustomer(GETPOST('editcustomer', 'int'));
527  $url = $_SERVER["PHP_SELF"].'?track_id='.GETPOST('track_id', 'alpha');
528  header("Location: ".$url);
529  exit();
530  }
531  }
532 
533  if ($action == 'set_progression' && $user->rights->ticket->write) {
534  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
535  $result = $object->setProgression(GETPOST('progress', 'alpha'));
536 
537  $url = 'card.php?track_id='.$object->track_id;
538  header("Location: ".$url);
539  exit();
540  }
541  }
542 
543  if ($action == 'set_categories' && $user->rights->ticket->write) {
544  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
545  $result = $object->setCategories(GETPOST('categories', 'array'));
546 
547  $url = 'card.php?track_id='.$object->track_id;
548  header("Location: ".$url);
549  exit();
550  }
551  }
552 
553  if ($action == 'setsubject' && $user->rights->ticket->write) {
554  if ($object->fetch(GETPOST('id', 'int'))) {
555  if ($action == 'setsubject') {
556  $object->subject = GETPOST('subject', 'alphanohtml');
557  }
558 
559  if ($action == 'setsubject' && empty($object->subject)) {
560  $error++;
561  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")), null, 'errors');
562  }
563 
564  if (!$error) {
565  if ($object->update($user) >= 0) {
566  header("Location: ".$_SERVER['PHP_SELF']."?track_id=".$object->track_id);
567  exit;
568  } else {
569  $error++;
570  setEventMessages($object->error, $object->errors, 'errors');
571  }
572  }
573  }
574  }
575 
576  if ($action == 'confirm_reopen' && $user->rights->ticket->manage && !GETPOST('cancel')) {
577  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
578  // prevent browser refresh from reopening ticket several times
579  if ($object->status == Ticket::STATUS_CLOSED || $object->status == Ticket::STATUS_CANCELED) {
580  $res = $object->setStatut(Ticket::STATUS_ASSIGNED);
581  if ($res) {
582  // Log action in ticket logs table
583  //$log_action = $langs->trans('TicketLogReopen');
584 
585  $url = 'card.php?track_id='.$object->track_id;
586  header("Location: ".$url);
587  exit();
588  } else {
589  $error++;
590  setEventMessages($object->error, $object->errors, 'errors');
591  }
592  }
593  }
594  } elseif ($action == 'classin' && $permissiontoadd) {
595  // Categorisation dans projet
596  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
597  $object->setProject($projectid);
598  $url = 'card.php?track_id='.$object->track_id;
599  header("Location: ".$url);
600  exit();
601  }
602  } elseif ($action == 'setcontract' && $permissiontoadd) {
603  // Categorisation dans contrat
604  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
605  $object->setContract(GETPOST('contractid', 'int'));
606  $url = 'card.php?track_id='.$object->track_id;
607  header("Location: ".$url);
608  exit();
609  }
610  } elseif ($action == "set_message" && $user->rights->ticket->manage) {
611  if (!GETPOST('cancel')) {
612  $object->fetch('', '', GETPOST('track_id', 'alpha'));
613  $oldvalue_message = $object->message;
614  $fieldtomodify = GETPOST('message_initial', 'restricthtml');
615 
616  $object->message = $fieldtomodify;
617  $ret = $object->update($user);
618  if ($ret > 0) {
619  //$log_action = $langs->trans('TicketInitialMessageModified')." \n";
620  // include the Diff class
621  include_once DOL_DOCUMENT_ROOT.'/core/class/utils_diff.class.php';
622  // output the result of comparing two files as plain text
623  //$log_action .= Diff::toString(Diff::compare(strip_tags($oldvalue_message), strip_tags($object->message)));
624 
625  setEventMessages($langs->trans('TicketMessageSuccesfullyUpdated'), null, 'mesgs');
626  } else {
627  $error++;
628  setEventMessages($object->error, $object->errors, 'errors');
629  }
630  }
631 
632  $action = 'view';
633  } elseif ($action == 'confirm_set_status' && $permissiontoadd && !GETPOST('cancel')) {
634  // Reopen ticket
635  if ($object->fetch(GETPOST('id', 'int'), GETPOST('track_id', 'alpha')) >= 0) {
636  $new_status = GETPOST('new_status', 'int');
637  $old_status = $object->status;
638  $res = $object->setStatut($new_status);
639  if ($res) {
640  // Log action in ticket logs table
641  $log_action = $langs->trans('TicketLogStatusChanged', $langs->transnoentities($object->statuts_short[$old_status]), $langs->transnoentities($object->statuts_short[$new_status]));
642 
643  $url = 'card.php?track_id='.$object->track_id;
644  header("Location: ".$url);
645  exit();
646  } else {
647  $error++;
648  setEventMessages($object->error, $object->errors, 'errors');
649  }
650  }
651  }
652 
653  // Action to update one extrafield
654  if ($action == "update_extras" && $permissiontoadd) {
655  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
656 
657  $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
658  if ($ret < 0) {
659  $error++;
660  }
661 
662  if (!$error) {
663  $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
664  if ($result < 0) {
665  $error++;
666  }
667  }
668 
669  if ($error) {
670  setEventMessages($object->error, $object->errors, 'errors');
671  $action = 'edit_extras';
672  } else {
673  setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
674  $action = 'view';
675  }
676  }
677 
678  if ($action == "change_property" && GETPOST('btn_update_ticket_prop', 'alpha') && $permissiontoadd) {
679  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
680 
681  $object->type_code = GETPOST('update_value_type', 'aZ09');
682  $object->severity_code = GETPOST('update_value_severity', 'aZ09');
683  $object->category_code = GETPOST('update_value_category', 'aZ09');
684 
685  $ret = $object->update($user);
686  if ($ret > 0) {
687  //$log_action = $langs->trans('TicketLogPropertyChanged', $oldvalue_label, $newvalue_label);
688 
689  setEventMessages($langs->trans('TicketUpdated'), null, 'mesgs');
690  } else {
691  $error++;
692  setEventMessages($object->error, $object->errors, 'errors');
693  }
694  $action = 'view';
695  }
696 
697 
698  $permissiondellink = $user->rights->ticket->write;
699  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
700 
701  // Actions to build doc
702  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
703  //var_dump($action);exit;
704 
705  // Actions to send emails
706  $triggersendname = 'TICKET_SENTBYMAIL';
707  $paramname = 'id';
708  $autocopy = 'MAIN_MAIL_AUTOCOPY_TICKET_TO'; // used to know the automatic BCC to add
709  $trackid = 'tic'.$object->id;
710  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
711 
712  // Set $action to correct value for the case we used presend action to add a message
713  if (GETPOSTISSET('actionbis') && $action == 'presend') {
714  $action = 'presend_addmessage';
715  }
716 }
717 
718 
719 /*
720  * View
721  */
722 
723 $userstat = new User($db);
724 $form = new Form($db);
725 $formticket = new FormTicket($db);
726 if (isModEnabled('project')) {
727  $formproject = new FormProjets($db);
728 }
729 
730 $help_url = 'EN:Module_Ticket|FR:DocumentationModuleTicket';
731 
732 $title = $actionobject->getTitle($action);
733 
734 llxHeader('', $title, $help_url);
735 
736 if ($action == 'create' || $action == 'presend') {
737  $formticket = new FormTicket($db);
738 
739  print load_fiche_titre($langs->trans('NewTicket'), '', 'ticket');
740 
741  $formticket->trackid = ''; // TODO Use a unique key 'tic' to avoid conflict in upload file feature
742  $formticket->withfromsocid = $socid ? $socid : $user->socid;
743  $formticket->withfromcontactid = $contactid ? $contactid : '';
744  $formticket->withtitletopic = 1;
745  $formticket->withnotifytiersatcreate = ($notifyTiers ? 1 : (empty($conf->global->TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION) ? 0 : 1));
746  $formticket->withusercreate = 0;
747  $formticket->withref = 1;
748  $formticket->fk_user_create = $user->id;
749  $formticket->withfile = 2;
750  $formticket->withextrafields = 1;
751  $formticket->param = array('origin' => GETPOST('origin'), 'originid' => GETPOST('originid'));
752 
753  $formticket->withcancel = 1;
754 
755  $formticket->showForm(1, 'create', 0, null, $action);
756  /*} elseif ($action == 'edit' && $user->rights->ticket->write && $object->status < Ticket::STATUS_CLOSED) {
757  $formticket = new FormTicket($db);
758 
759  $head = ticket_prepare_head($object);
760 
761  print '<form method="POST" name="form_ticket" id="form_edit_ticket" action="'.$_SERVER['PHP_SELF'].'?track_id='.$object->track_id.'">';
762  print '<input type="hidden" name="token" value="'.newToken().'">';
763  print '<input type="hidden" name="action" value="update">';
764  print '<input type="hidden" name="tack_id" value="'.$object->track_id.'">';
765 
766  print dol_get_fiche_head($head, 'card', $langs->trans('Ticket'), 0, 'ticket');
767 
768  print '<div class="fichecenter2">';
769  print '<table class="border" width="100%">';
770 
771  // Type
772  print '<tr><td class="titlefield"><span class="fieldrequired"><label for="selecttype_code">'.$langs->trans("TicketTypeRequest").'</span></label></td><td>';
773  $formticket->selectTypesTickets((GETPOSTISSET('type_code') ? GETPOST('type_code') : $object->type_code), 'type_code', '', '2');
774  print '</td></tr>';
775 
776  // Severity
777  print '<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans("TicketSeverity").'</span></label></td><td>';
778  $formticket->selectSeveritiesTickets((GETPOSTISSET('severity_code') ? GETPOST('severity_code') : $object->severity_code), 'severity_code', '', '2');
779  print '</td></tr>';
780 
781  // Group
782  print '<tr><td><span class="fieldrequired"><label for="selectcategory_code">'.$langs->trans("TicketCategory").'</span></label></td><td>';
783  $formticket->selectGroupTickets((GETPOSTISSET('category_code') ? GETPOST('category_code') : $object->category_code), 'category_code', '', '2');
784  print '</td></tr>';
785 
786  // Subject
787  print '<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans("Subject").'</span></label></td><td>';
788  print '<input class="text minwidth200" id="subject" name="subject" value="'.dol_escape_htmltag(GETPOSTISSET('subject') ? GETPOST('subject', 'alpha') : $object->subject).'" />';
789  print '</td></tr>';
790 
791  // Other attributes
792  $parameters = array('colspan' => ' colspan="3"', 'colspanvalue' => '3');
793  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
794  print $hookmanager->resPrint;
795  if (empty($reshook)) {
796  print $object->showOptionals($extrafields, 'edit');
797  }
798 
799  print '</table>';
800  print '</div>';
801 
802  print dol_get_fiche_end();
803 
804  print $form->buttonsSaveCancel();
805 
806  print '</form>'; */
807 } elseif (empty($action) || $action == 'view' || $action == 'addlink' || $action == 'dellink' || $action == 'presend' || $action == 'presend_addmessage' || $action == 'close' || $action == 'abandon' || $action == 'delete' || $action == 'editcustomer' || $action == 'progression' || $action == 'categories' || $action == 'reopen'
808  || $action == 'editsubject' || $action == 'edit_extras' || $action == 'update_extras' || $action == 'edit_extrafields' || $action == 'set_extrafields' || $action == 'classify' || $action == 'sel_contract' || $action == 'edit_message_init' || $action == 'set_status' || $action == 'dellink') {
809  if ($res > 0) {
810  // or for unauthorized internals users
811  if (!$user->socid && (!empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY) && $object->fk_user_assign != $user->id) && !$user->rights->ticket->manage) {
812  accessforbidden('', 0, 1);
813  }
814 
815  // Confirmation close
816  if ($action == 'close') {
817  $thirdparty_contacts = $object->getInfosTicketExternalContact(1);
818  $contacts_select = array(
819  '-2' => $langs->trans('TicketNotifyAllTiersAtClose'),
820  '-3' => $langs->trans('TicketNotNotifyTiersAtClose')
821  );
822  foreach ($thirdparty_contacts as $thirdparty_contact) {
823  $contacts_select[$thirdparty_contact['id']] = $thirdparty_contact['civility'] . ' ' . $thirdparty_contact['lastname'] . ' ' . $thirdparty_contact['firstname'];
824  }
825 
826  // Default select all or no contact
827  $default = (!empty($conf->global->TICKET_NOTIFY_AT_CLOSING)) ? -2 : -3;
828  $formquestion = array(
829  array(
830  'name' => 'contactid',
831  'type' => 'select',
832  'label' => $langs->trans('NotifyThirdpartyOnTicketClosing'),
833  'values' => $contacts_select,
834  'default' => $default
835  ),
836  );
837 
838  print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_close", $formquestion, '', 1);
839  }
840  // Confirmation abandon
841  if ($action == 'abandon') {
842  print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("AbandonTicket"), $langs->trans("ConfirmAbandonTicket"), "confirm_abandon", '', '', 1);
843  }
844  // Confirmation delete
845  if ($action == 'delete') {
846  print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("Delete"), $langs->trans("ConfirmDeleteTicket"), "confirm_delete_ticket", '', '', 1);
847  }
848  // Confirm reopen
849  if ($action == 'reopen') {
850  print $form->formconfirm($url_page_current.'?track_id='.$object->track_id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenTicket'), 'confirm_reopen', '', '', 1);
851  }
852  // Confirmation status change
853  if ($action == 'set_status') {
854  $new_status = GETPOST('new_status');
855  //var_dump($url_page_current . "?track_id=" . $object->track_id);
856  print $form->formconfirm($url_page_current."?track_id=".$object->track_id."&new_status=".GETPOST('new_status'), $langs->trans("TicketChangeStatus"), $langs->trans("TicketConfirmChangeStatus", $langs->transnoentities($object->statuts_short[$new_status])), "confirm_set_status", '', '', 1);
857  }
858 
859  // project info
860  if ($projectid > 0) {
861  $projectstat = new Project($db);
862  if ($projectstat->fetch($projectid) > 0) {
863  $projectstat->fetch_thirdparty();
864 
865  // To verify role of users
866  //$userAccess = $object->restrictedProjectArea($user,'read');
867  $userWrite = $projectstat->restrictedProjectArea($user, 'write');
868  //$userDelete = $object->restrictedProjectArea($user,'delete');
869  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
870 
871  $head = project_prepare_head($projectstat);
872 
873  print dol_get_fiche_head($head, 'ticket', $langs->trans("Project"), 0, ($projectstat->public ? 'projectpub' : 'project'));
874 
875  print '<table class="border centpercent">';
876 
877  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
878 
879  // Ref
880  print '<tr><td width="30%">'.$langs->trans('Ref').'</td><td colspan="3">';
881  // Define a complementary filter for search of next/prev ref.
882  if (empty($user->rights->projet->all->lire)) {
883  $objectsListId = $projectstat->getProjectsAuthorizedForUser($user, $mine, 0);
884  $projectstat->next_prev_filter = " rowid IN (".$db->sanitize(count($objectsListId) ? join(',', array_keys($objectsListId)) : '0').")";
885  }
886  print $form->showrefnav($projectstat, 'ref', $linkback, 1, 'ref', 'ref', '');
887  print '</td></tr>';
888 
889  // Label
890  print '<tr><td>'.$langs->trans("Label").'</td><td>'.$projectstat->title.'</td></tr>';
891 
892  // Customer
893  print "<tr><td>".$langs->trans("ThirdParty")."</td>";
894  print '<td colspan="3">';
895  if ($projectstat->thirdparty->id > 0) {
896  print $projectstat->thirdparty->getNomUrl(1);
897  } else {
898  print '&nbsp;';
899  }
900 
901  print '</td></tr>';
902 
903  // Visibility
904  print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
905  if ($projectstat->public) {
906  print $langs->trans('SharedProject');
907  } else {
908  print $langs->trans('PrivateProject');
909  }
910 
911  print '</td></tr>';
912 
913  // Statut
914  print '<tr><td>'.$langs->trans("Status").'</td><td>'.$projectstat->getLibStatut(4).'</td></tr>';
915 
916  print "</table>";
917 
918  print dol_get_fiche_end();
919  } else {
920  print "ErrorRecordNotFound";
921  }
922  } elseif ($socid > 0) {
923  $object->fetch_thirdparty();
924  $head = societe_prepare_head($object->thirdparty);
925 
926  print dol_get_fiche_head($head, 'ticket', $langs->trans("ThirdParty"), 0, 'company');
927 
928  dol_banner_tab($object->thirdparty, 'socid', '', ($user->socid ? 0 : 1), 'rowid', 'nom');
929 
930  print dol_get_fiche_end();
931  }
932 
933  if (!$user->socid && !empty($conf->global->TICKET_LIMIT_VIEW_ASSIGNED_ONLY)) {
934  $object->next_prev_filter = "te.fk_user_assign = '".$user->id."'";
935  } elseif ($user->socid > 0) {
936  $object->next_prev_filter = "te.fk_soc = '".$user->socid."'";
937  }
938 
939  $head = ticket_prepare_head($object);
940 
941  print dol_get_fiche_head($head, 'tabTicket', $langs->trans("Ticket"), -1, 'ticket');
942 
943  $morehtmlref = '<div class="refidno">';
944  $morehtmlref .= $object->subject;
945  // Author
946  if ($object->fk_user_create > 0) {
947  $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
948 
949  $fuser = new User($db);
950  $fuser->fetch($object->fk_user_create);
951  $morehtmlref .= $fuser->getNomUrl(-1);
952  } elseif (!empty($object->email_msgid)) {
953  $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
954  $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"');
955  $htmltooltip = $langs->trans("EmailMsgID").': '.$object->email_msgid;
956  $htmltooltip .= '<br>'.$langs->trans("EmailDate").': '.dol_print_date($object->email_date, 'dayhour');
957  $morehtmlref .= dol_escape_htmltag($object->origin_email).' <small class="hideonsmartphone opacitymedium">- '.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $htmltooltip, 1, 'help', '', 0, 3, 'tooltip').'</small>';
958  } elseif (!empty($object->origin_email)) {
959  $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
960  $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"');
961  $htmltooptip = $langs->trans("IP").': '.$object->ip;
962  $morehtmlref .= dol_escape_htmltag($object->origin_email).' <small class="hideonsmartphone opacitymedium">- '.$form->textwithpicto($langs->trans("CreatedByPublicPortal"), $htmltooptip, 1, 'help', '', 0, 3, 'tooltip').'</small>';
963  }
964 
965  $permissiontoedit = $object->status < 8 && !$user->socid && $user->rights->ticket->write;
966  //$permissiontoedit = 0;
967 
968  // Thirdparty
969  if (isModEnabled("societe")) {
970  $morehtmlref .= '<br>';
971  $morehtmlref .= img_picto($langs->trans("ThirdParty"), 'company', 'class="pictofixedwidth"');
972  if ($action != 'editcustomer' && $permissiontoedit) {
973  $morehtmlref .= '<a class="editfielda" href="'.$url_page_current.'?action=editcustomer&token='.newToken().'&track_id='.$object->track_id.'">'.img_edit($langs->transnoentitiesnoconv('SetThirdParty'), 0).'</a> ';
974  }
975  $morehtmlref .= $form->form_thirdparty($url_page_current.'?track_id='.$object->track_id, $object->socid, $action == 'editcustomer' ? 'editcustomer' : 'none', '', 1, 0, 0, array(), 1);
976  if (!empty($object->socid)) {
977  $morehtmlref .= ' - <a href="'.DOL_URL_ROOT.'/ticket/list.php?socid='.$object->socid.'&sortfield=t.datec&sortorder=desc">'.img_picto($langs->trans("Tickets"), 'ticket', 'class="pictofixedwidth"').' '.$langs->trans("TicketHistory").'</a>';
978  }
979  }
980 
981  // Project
982  if (isModEnabled('project')) {
983  $langs->load("projects");
984  $morehtmlref .= '<br>';
985  if ($permissiontoedit) {
986  $object->fetch_project();
987  $morehtmlref .= img_picto($langs->trans("Project"), 'project'.((is_object($object->project) && $object->project->public) ? 'pub' : ''), 'class="pictofixedwidth"');
988  if ($action != 'classify') {
989  $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
990  }
991  $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
992  } else {
993  if (!empty($object->fk_project)) {
994  $object->fetch_project();
995  $morehtmlref .= $object->project->getNomUrl(1);
996  if ($object->project->title) {
997  $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($object->project->title).'</span>';
998  }
999  }
1000  }
1001  }
1002 
1003  $morehtmlref .= '</div>';
1004 
1005  $linkback = '<a href="'.DOL_URL_ROOT.'/ticket/list.php?restore_lastsearch_values=1"><strong>'.$langs->trans("BackToList").'</strong></a> ';
1006 
1007  dol_banner_tab($object, 'ref', $linkback, ($user->socid ? 0 : 1), 'ref', 'ref', $morehtmlref);
1008 
1009  print '<div class="fichecenter">';
1010  print '<div class="fichehalfleft">';
1011  print '<div class="underbanner clearboth"></div>';
1012 
1013  print '<table class="border tableforfield centpercent">';
1014 
1015  // Track ID
1016  print '<tr><td class="titlefield">'.$langs->trans("TicketTrackId").'</td><td>';
1017  if (!empty($object->track_id)) {
1018  if (empty($object->ref)) {
1019  $object->ref = $object->id;
1020  print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'track_id');
1021  } else {
1022  print $object->track_id;
1023  }
1024  } else {
1025  print $langs->trans('None');
1026  }
1027  print '</td></tr>';
1028 
1029  // Subject
1030  print '<tr><td>';
1031  print $form->editfieldkey("Subject", 'subject', $object->subject, $object, $user->rights->ticket->write && !$user->socid, 'string');
1032  print '</td><td>';
1033  print $form->editfieldval("Subject", 'subject', $object->subject, $object, $user->rights->ticket->write && !$user->socid, 'string');
1034  print '</td></tr>';
1035 
1036  // Creation date
1037  print '<tr><td>'.$langs->trans("DateCreation").'</td><td>';
1038  print dol_print_date($object->datec, 'dayhour', 'tzuser');
1039  print '<span class="opacitymedium"> - '.$langs->trans("TimeElapsedSince").': <i>'.convertSecondToTime(roundUpToNextMultiple($now - $object->datec, 60)).'</i></span>';
1040  print '</td></tr>';
1041 
1042  // Origin
1043  /*
1044  if ($object->email_msgid) {
1045  $texttoshow = $langs->trans("CreatedByEmailCollector");
1046  } elseif ($object->origin_email) {
1047  $texttoshow = $langs->trans("FromPublicEmail");
1048  }
1049  if ($texttoshow) {
1050  print '<tr><td class="titlefield fieldname_email_origin">';
1051  print $langs->trans("Origin");
1052  print '</td>';
1053  print '<td class="valuefield fieldname_email_origin">';
1054  print $texttoshow;
1055  print '</td></tr>';
1056  }
1057  */
1058 
1059  // Read date
1060  print '<tr><td>'.$langs->trans("TicketReadOn").'</td><td>';
1061  if (!empty($object->date_read)) {
1062  print dol_print_date($object->date_read, 'dayhour', 'tzuser');
1063  print '<span class="opacitymedium"> - '.$langs->trans("TicketTimeElapsedBeforeSince").': <i>'.convertSecondToTime(roundUpToNextMultiple($object->date_read - $object->datec, 60)).'</i>';
1064  print ' / <i>'.convertSecondToTime(roundUpToNextMultiple($now - $object->date_read, 60)).'</i></span>';
1065  }
1066  print '</td></tr>';
1067 
1068  // Close date
1069  print '<tr><td>'.$langs->trans("TicketCloseOn").'</td><td>';
1070  if (!empty($object->date_close)) {
1071  print dol_print_date($object->date_close, 'dayhour', 'tzuser');
1072  }
1073  print '</td></tr>';
1074 
1075  // User assigned
1076  print '<tr><td>';
1077  print '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
1078  print $langs->trans("AssignedTo");
1079  if (isset($object->status) && $object->status < $object::STATUS_CLOSED && GETPOST('set', 'alpha') != "assign_ticket" && $user->rights->ticket->manage) {
1080  print '</td><td class="right"><a class="editfielda" href="'.$url_page_current.'?track_id='.urlencode($object->track_id).'&set=assign_ticket">'.img_edit($langs->trans('Modify'), '').'</a>';
1081  }
1082  print '</td></tr></table>';
1083  print '</td><td>';
1084  if (GETPOST('set', 'alpha') != "assign_ticket" && $object->fk_user_assign > 0) {
1085  $userstat->fetch($object->fk_user_assign);
1086  print $userstat->getNomUrl(-1);
1087  }
1088 
1089  // Show user list to assignate one if status is "read"
1090  if (GETPOST('set', 'alpha') == "assign_ticket" && $object->status < 8 && !$user->socid && $user->rights->ticket->write) {
1091  print '<form method="post" name="ticket" enctype="multipart/form-data" action="'.$url_page_current.'">';
1092  print '<input type="hidden" name="token" value="'.newToken().'">';
1093  print '<input type="hidden" name="action" value="assign_user">';
1094  print '<input type="hidden" name="track_id" value="'.$object->track_id.'">';
1095  //print '<label for="fk_user_assign">'.$langs->trans("AssignUser").'</label> ';
1096  print $form->select_dolusers(empty($object->fk_user_assign)?$user->id:$object->fk_user_assign, 'fk_user_assign', 1);
1097  print ' <input type="submit" class="button small" name="btn_assign_user" value="'.$langs->trans("Validate").'" />';
1098  print '</form>';
1099  }
1100  print '</td></tr>';
1101 
1102  // Progression
1103  print '<tr><td>';
1104  print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
1105  print $langs->trans('Progression').'</td><td class="left">';
1106  print '</td>';
1107  if ($action != 'progression' && isset($object->status) && $object->status < $object::STATUS_CLOSED && !$user->socid) {
1108  print '<td class="right"><a class="editfielda" href="'.$url_page_current.'?action=progression&token='.newToken().'&track_id='.urlencode($object->track_id).'">'.img_edit($langs->trans('Modify')).'</a></td>';
1109  }
1110  print '</tr></table>';
1111  print '</td><td>';
1112  if ($user->rights->ticket->write && $action == 'progression') {
1113  print '<form action="'.$url_page_current.'" method="post">';
1114  print '<input type="hidden" name="token" value="'.newToken().'">';
1115  print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1116  print '<input type="hidden" name="action" value="set_progression">';
1117  print '<input type="text" class="flat width75" name="progress" value="'.$object->progress.'">';
1118  print ' <input type="submit" class="button button-edit small" value="'.$langs->trans('Modify').'">';
1119  print '</form>';
1120  } else {
1121  print($object->progress > 0 ? $object->progress : '0').'%';
1122  }
1123  print '</td>';
1124  print '</tr>';
1125 
1126  // Timing (Duration sum of linked fichinter)
1127  if (isModEnabled('ficheinter')) {
1128  $object->fetchObjectLinked();
1129  $num = count($object->linkedObjects);
1130  $timing = 0;
1131  $foundinter = 0;
1132  if ($num) {
1133  foreach ($object->linkedObjects as $objecttype => $objects) {
1134  if ($objecttype == "fichinter") {
1135  foreach ($objects as $fichinter) {
1136  $foundinter++;
1137  $timing += $fichinter->duration;
1138  }
1139  }
1140  }
1141  }
1142  print '<tr><td>';
1143  print $form->textwithpicto($langs->trans("TicketDurationAuto"), $langs->trans("TicketDurationAutoInfos"), 1);
1144  print '</td><td>';
1145  print $foundinter ? convertSecondToTime($timing, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY) : '';
1146  print '</td></tr>';
1147  }
1148 
1149  // Other attributes
1150  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1151 
1152  print '</table>';
1153 
1154 
1155  // Fin colonne gauche et début colonne droite
1156  print '</div><div class="fichehalfright">';
1157 
1158 
1159  print '<form method="post" name="formticketproperties" action="'.$url_page_current.'">';
1160  print '<input type="hidden" name="token" value="'.newToken().'">';
1161  print '<input type="hidden" name="action" value="change_property">';
1162  print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1163  print '<input type="hidden" name="trackid" value="'.$trackid.'">';
1164 
1165  print '<div class="underbanner clearboth"></div>';
1166 
1167  // Categories
1168  if (isModEnabled('categorie')) {
1169  print '<table class="border centpercent tableforfield">';
1170  print '<tr>';
1171  print '<td class="valignmiddle titlefield">';
1172  print '<table class="nobordernopadding centpercent"><tr><td class="titlefield">';
1173  print $langs->trans("Categories");
1174  if ($action != 'categories' && !$user->socid) {
1175  print '<td class="right"><a class="editfielda" href="'.$url_page_current.'?action=categories&amp;track_id='.$object->track_id.'">'.img_edit($langs->trans('Modify')).'</a></td>';
1176  }
1177  print '</table>';
1178  print '</td>';
1179 
1180  if ($user->rights->ticket->write && $action == 'categories') {
1181  $cate_arbo = $form->select_all_categories(Categorie::TYPE_TICKET, '', 'parent', 64, 0, 1);
1182  if (is_array($cate_arbo)) {
1183  // Categories
1184  print '<td colspan="3">';
1185  print '<form action="'.$url_page_current.'" method="post">';
1186  print '<input type="hidden" name="token" value="'.newToken().'">';
1187  print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1188  print '<input type="hidden" name="action" value="set_categories">';
1189 
1190  $category = new Categorie($db);
1191  $cats = $category->containing($object->id, 'ticket');
1192  $arrayselected = array();
1193  foreach ($cats as $cat) {
1194  $arrayselected[] = $cat->id;
1195  }
1196 
1197  print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
1198  print '<input type="submit" class="button button-edit small" value="'.$langs->trans('Save').'">';
1199  print '</form>';
1200  print "</td>";
1201  }
1202  } else {
1203  print '<td colspan="3">';
1204  print $form->showCategories($object->id, Categorie::TYPE_TICKET, 1);
1205  print "</td></tr>";
1206  }
1207 
1208  print '</table>';
1209  }
1210 
1211  // View Original message
1212  $actionobject->viewTicketOriginalMessage($user, $action, $object);
1213 
1214  // Classification of ticket
1215  print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you dont need reserved height for your table
1216  print '<table class="noborder tableforfield centpercent margintable">';
1217  print '<tr class="liste_titre">';
1218  print '<td>';
1219  print $langs->trans('TicketProperties');
1220  print '</td>';
1221  print '<td>';
1222  if (GETPOST('set', 'alpha') == 'properties' && $user->rights->ticket->write) {
1223  print '<input type="submit" class="button small" name="btn_update_ticket_prop" value="'.$langs->trans("Modify").'" />';
1224  } else {
1225  // Button to edit Properties
1226  if (isset($object->status) && $object->status < $object::STATUS_NEED_MORE_INFO && $user->rights->ticket->write) {
1227  print ' <a class="editfielda" href="card.php?track_id='.$object->track_id.'&set=properties">'.img_edit($langs->trans('Modify')).'</a>';
1228  }
1229  }
1230  print '</td>';
1231  print '</tr>';
1232 
1233  if (GETPOST('set', 'alpha') == 'properties' && $user->rights->ticket->write) {
1234  print '<tr>';
1235  // Type
1236  print '<td class="titlefield">';
1237  print $langs->trans('Type');
1238  print '</td><td>';
1239  $formticket->selectTypesTickets($object->type_code, 'update_value_type', '', 2);
1240  print '</td>';
1241  print '</tr>';
1242  // Group
1243  print '<tr>';
1244  print '<td>';
1245  print $langs->trans('TicketCategory');
1246  print '</td><td>';
1247  $formticket->selectGroupTickets($object->category_code, 'update_value_category', '', 2, 0, 0, 0, 'maxwidth500 widthcentpercentminusxx');
1248  print '</td>';
1249  print '</tr>';
1250  // Severity
1251  print '<tr>';
1252  print '<td>';
1253  print $langs->trans('TicketSeverity');
1254  print '</td><td>';
1255  $formticket->selectSeveritiesTickets($object->severity_code, 'update_value_severity', '', 2);
1256  print '</td>';
1257  print '</tr>';
1258  } else {
1259  // Type
1260  print '<tr><td class="titlefield">'.$langs->trans("Type").'</td><td>';
1261  if (!empty($object->type_code)) {
1262  print $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code);
1263  }
1264  print '</td></tr>';
1265  // Group
1266  $s = '';
1267  if (!empty($object->category_code)) {
1268  $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code);
1269  }
1270  print '<tr><td>'.$langs->trans("TicketCategory").'</td><td class="tdoverflowmax200" title="'.dol_escape_htmltag($s).'">';
1271  print dol_escape_htmltag($s);
1272  print '</td></tr>';
1273  // Severity
1274  print '<tr><td>'.$langs->trans("TicketSeverity").'</td><td>';
1275  if (!empty($object->severity_code)) {
1276  print $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code);
1277  }
1278  print '</td></tr>';
1279  }
1280  print '</table>'; // End table actions
1281  print '</div>';
1282 
1283  print '</form>';
1284 
1285  // Display navbar with links to change ticket status
1286  print '<!-- navbar with status -->';
1287  if (!$user->socid && $user->rights->ticket->write && isset($object->status) && $object->status < $object::STATUS_CLOSED && GETPOST('set') !== 'properties') {
1288  $actionobject->viewStatusActions($object);
1289  }
1290 
1291 
1292  if (!empty($conf->global->MAIN_DISABLE_CONTACTS_TAB)) {
1293  print load_fiche_titre($langs->trans('Contacts'), '', 'title_companies.png');
1294 
1295  print '<div class="div-table-responsive-no-min">';
1296  print '<div class="tagtable centpercent noborder allwidth">';
1297 
1298  print '<div class="tagtr liste_titre">';
1299  print '<div class="tagtd">'.$langs->trans("Source").'</div>
1300  <div class="tagtd">' . $langs->trans("Company").'</div>
1301  <div class="tagtd">' . $langs->trans("Contacts").'</div>
1302  <div class="tagtd">' . $langs->trans("ContactType").'</div>
1303  <div class="tagtd">' . $langs->trans("Phone").'</div>
1304  <div class="tagtd center">' . $langs->trans("Status").'</div>';
1305  print '</div><!-- tagtr -->';
1306 
1307  // Contact list
1308  $companystatic = new Societe($db);
1309  $contactstatic = new Contact($db);
1310  $userstatic = new User($db);
1311  $var = false;
1312  foreach (array('internal', 'external') as $source) {
1313  $tmpobject = $object;
1314  $tab = $tmpobject->listeContact(-1, $source);
1315  $num = count($tab);
1316  $i = 0;
1317  while ($i < $num) {
1318  $var = !$var;
1319  print '<div class="tagtr '.($var ? 'pair' : 'impair').'">';
1320 
1321  print '<div class="tagtd left">';
1322  if ($tab[$i]['source'] == 'internal') {
1323  echo $langs->trans("User");
1324  }
1325 
1326  if ($tab[$i]['source'] == 'external') {
1327  echo $langs->trans("ThirdPartyContact");
1328  }
1329 
1330  print '</div>';
1331  print '<div class="tagtd left">';
1332 
1333  if ($tab[$i]['socid'] > 0) {
1334  $companystatic->fetch($tab[$i]['socid']);
1335  echo $companystatic->getNomUrl(-1);
1336  }
1337  if ($tab[$i]['socid'] < 0) {
1338  echo $conf->global->MAIN_INFO_SOCIETE_NOM;
1339  }
1340  if (!$tab[$i]['socid']) {
1341  echo '&nbsp;';
1342  }
1343  print '</div>';
1344 
1345  print '<div class="tagtd">';
1346  if ($tab[$i]['source'] == 'internal') {
1347  if ($userstatic->fetch($tab[$i]['id'])) {
1348  print $userstatic->getNomUrl(-1);
1349  }
1350  }
1351  if ($tab[$i]['source'] == 'external') {
1352  if ($contactstatic->fetch($tab[$i]['id'])) {
1353  print $contactstatic->getNomUrl(-1);
1354  }
1355  }
1356  print ' </div>
1357  <div class="tagtd">' . $tab[$i]['libelle'].'</div>';
1358 
1359  print '<div class="tagtd">';
1360 
1361  print dol_print_phone($tab[$i]['phone'], '', '', '', 'AC_TEL').'<br>';
1362 
1363  if (!empty($tab[$i]['phone_perso'])) {
1364  //print img_picto($langs->trans('PhonePerso'),'object_phoning.png','',0,0,0).' ';
1365  print '<br>'.dol_print_phone($tab[$i]['phone_perso'], '', '', '', 'AC_TEL').'<br>';
1366  }
1367  if (!empty($tab[$i]['phone_mobile'])) {
1368  //print img_picto($langs->trans('PhoneMobile'),'object_phoning.png','',0,0,0).' ';
1369  print dol_print_phone($tab[$i]['phone_mobile'], '', '', '', 'AC_TEL').'<br>';
1370  }
1371  print '</div>';
1372 
1373  print '<div class="tagtd center">';
1374  if ($object->status >= 0) {
1375  echo '<a href="contact.php?track_id='.$object->track_id.'&amp;action=swapstatut&amp;ligne='.$tab[$i]['rowid'].'">';
1376  }
1377 
1378  if ($tab[$i]['source'] == 'internal') {
1379  $userstatic->id = $tab[$i]['id'];
1380  $userstatic->lastname = $tab[$i]['lastname'];
1381  $userstatic->firstname = $tab[$i]['firstname'];
1382  echo $userstatic->LibStatut($tab[$i]['statuscontact'], 3);
1383  }
1384  if ($tab[$i]['source'] == 'external') {
1385  $contactstatic->id = $tab[$i]['id'];
1386  $contactstatic->lastname = $tab[$i]['lastname'];
1387  $contactstatic->firstname = $tab[$i]['firstname'];
1388  echo $contactstatic->LibStatut($tab[$i]['statuscontact'], 3);
1389  }
1390  if ($object->status >= 0) {
1391  echo '</a>';
1392  }
1393 
1394  print '</div>';
1395 
1396  print '</div><!-- tagtr -->';
1397 
1398  $i++;
1399  }
1400  }
1401 
1402  print '</div><!-- contact list -->';
1403  print '</div>';
1404  }
1405 
1406  print '</div></div>';
1407  print '<div class="clearboth"></div>';
1408 
1409  print dol_get_fiche_end();
1410 
1411 
1412  // Buttons for actions
1413  if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'editline') {
1414  print '<div class="tabsAction">'."\n";
1415  $parameters = array();
1416  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1417  if ($reshook < 0) {
1418  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1419  }
1420 
1421  if (empty($reshook)) {
1422  // Email
1423  if (isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") {
1424  print dolGetButtonAction('', $langs->trans('SendMail'), 'default', $_SERVER["PHP_SELF"].'?action=presend_addmessage&send_email=1&private_message=0&mode=init&token='.newToken().'&track_id='.$object->track_id.'#formmailbeforetitle', '');
1425  }
1426 
1427  // Show link to add a message (if read and not closed)
1428  if (isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") {
1429  print dolGetButtonAction('', $langs->trans('TicketAddPrivateMessage'), 'default', $_SERVER["PHP_SELF"].'?action=presend_addmessage&mode=init&token='.newToken().'&track_id='.$object->track_id.'#formmailbeforetitle', '');
1430  }
1431 
1432  // Link to create an intervention
1433  // socid is needed otherwise fichinter ask it and forgot origin after form submit :\
1434  if (!$object->fk_soc && $user->hasRight("ficheinter", "creer")) {
1435  print dolGetButtonAction($langs->trans('UnableToCreateInterIfNoSocid'), $langs->trans('TicketAddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1436  }
1437  if ($object->fk_soc > 0 && isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $user->hasRight('ficheinter', 'creer')) {
1438  print dolGetButtonAction('', $langs->trans('TicketAddIntervention'), 'default', DOL_URL_ROOT.'/fichinter/card.php?action=create&token='.newToken().'&socid='. $object->fk_soc.'&origin=ticket_ticket&originid='. $object->id, '');
1439  }
1440 
1441  // Close ticket if statut is read
1442  if (isset($object->status) && $object->status > 0 && $object->status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) {
1443  print dolGetButtonAction('', $langs->trans('CloseTicket'), 'default', $_SERVER["PHP_SELF"].'?action=close&token='.newToken().'&track_id='.$object->track_id, '');
1444  }
1445 
1446  // Abadon ticket if statut is read
1447  if (isset($object->status) && $object->status > 0 && $object->status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) {
1448  print dolGetButtonAction('', $langs->trans('AbandonTicket'), 'default', $_SERVER["PHP_SELF"].'?action=abandon&token='.newToken().'&track_id='.$object->track_id, '');
1449  }
1450 
1451  // Re-open ticket
1452  if (!$user->socid && (isset($object->status) && ($object->status == Ticket::STATUS_CLOSED || $object->status == Ticket::STATUS_CANCELED)) && !$user->socid) {
1453  print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&track_id='.$object->track_id, '');
1454  }
1455 
1456  // Delete ticket
1457  if ($user->rights->ticket->delete && !$user->socid) {
1458  print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&track_id='.$object->track_id, '');
1459  }
1460  }
1461  print '</div>'."\n";
1462  } else {
1463  //print '<br>';
1464  }
1465 
1466  // Select mail models is same action as presend
1467  if (GETPOST('modelselected')) {
1468  $action = 'presend';
1469  }
1470  // Set $action to correct value for the case we used presend action to add a message
1471  if (GETPOSTISSET('actionbis') && $action == 'presend') {
1472  $action = 'presend_addmessage';
1473  }
1474 
1475  // add a message
1476  if ($action == 'presend' || $action == 'presend_addmessage') {
1477  if ($object->fk_soc > 0) {
1478  $object->fetch_thirdparty();
1479  }
1480 
1481  $outputlangs = $langs;
1482  $newlang = '';
1483  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1484  $newlang = GETPOST('lang_id', 'aZ09');
1485  } elseif (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && is_object($object->thirdparty)) {
1486  $newlang = $object->thirdparty->default_lang;
1487  }
1488  if (!empty($newlang)) {
1489  $outputlangs = new Translate("", $conf);
1490  $outputlangs->setDefaultLang($newlang);
1491  }
1492 
1493  $arrayoffamiliestoexclude = array('objectamount');
1494 
1495  $action = 'add_message'; // action to use to post the message
1496  $modelmail = 'ticket_send';
1497 
1498  // Substitution array
1499  $morehtmlright = '';
1500  $help = "";
1501  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, $arrayoffamiliestoexclude, $object);
1502  $morehtmlright .= $form->textwithpicto('<span class="opacitymedium">'.$langs->trans("TicketMessageSubstitutionReplacedByGenericValues").'</span>', $help, 1, 'helpclickable', '', 0, 3, 'helpsubstitution');
1503 
1504  print '<div>';
1505 
1506  print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>';
1507 
1508  print load_fiche_titre($langs->trans('TicketAddMessage'), $morehtmlright, 'messages@ticket');
1509 
1510  print '<hr>';
1511 
1512  $formticket = new FormTicket($db);
1513 
1514  $formticket->action = $action;
1515  $formticket->track_id = $object->track_id;
1516  $formticket->ref = $object->ref;
1517  $formticket->id = $object->id;
1518  $formticket->trackid = 'tic'.$object->id;
1519 
1520  $formticket->withfile = 2;
1521  $formticket->withcancel = 1;
1522  $formticket->param = array('fk_user_create' => $user->id);
1523  $formticket->param['langsmodels'] = (empty($newlang) ? $langs->defaultlang : $newlang);
1524 
1525  // Tableau des parametres complementaires du post
1526  $formticket->param['models'] = $modelmail;
1527  $formticket->param['models_id'] = GETPOST('modelmailselected', 'int');
1528  //$formticket->param['socid']=$object->fk_soc;
1529  $formticket->param['returnurl'] = $_SERVER["PHP_SELF"].'?track_id='.$object->track_id;
1530 
1531  $formticket->withsubstit = 1;
1532  $formticket->substit = $substitutionarray;
1533  $formticket->backtopage = $backtopage;
1534 
1535  $formticket->showMessageForm('100%');
1536  print '</div>';
1537  }
1538 
1539  // Show messages on card (Note: this is a duplicate of the view Events/Agenda but on the main tab)
1540  if (!empty($conf->global->TICKET_SHOW_MESSAGES_ON_CARD)) {
1541  $param = '&id='.$object->id;
1542  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
1543  $param .= '&contextpage='.$contextpage;
1544  }
1545  if ($limit > 0 && $limit != $conf->liste_limit) {
1546  $param .= '&limit='.$limit;
1547  }
1548  if ($actioncode) {
1549  $param .= '&actioncode='.urlencode($actioncode);
1550  }
1551  if ($search_agenda_label) {
1552  $param .= '&search_agenda_label='.urlencode($search_agenda_label);
1553  }
1554 
1555  $morehtmlright = '';
1556 
1557  $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id;
1558  $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 1);
1559 
1560  // Show link to add a message (if read and not closed)
1561  $btnstatus = $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage" && $action != "add_message";
1562  $url = 'card.php?track_id='.$object->track_id.'&action=presend_addmessage&mode=init';
1563  $morehtmlright .= dolGetButtonTitle($langs->trans('TicketAddMessage'), '', 'fa fa-comment-dots', $url, 'add-new-ticket-title-button', $btnstatus);
1564 
1565  // Show link to add event (if read and not closed)
1566  $btnstatus = $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage" && $action != "add_message";
1567  $url = dol_buildpath('/comm/action/card.php', 1).'?action=create&datep='.date('YmdHi').'&origin=ticket&originid='.$object->id.'&projectid='.$object->fk_project.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?track_id='.$object->track_id);
1568  $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', $url, 'add-new-ticket-even-button', $btnstatus);
1569 
1570  print_barre_liste($langs->trans("ActionsOnTicket"), 0, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
1571 
1572  // List of all actions
1573  $filters = array();
1574  $filters['search_agenda_label'] = $search_agenda_label;
1575  $filters['search_rowid'] = $search_rowid;
1576 
1577  show_actions_messaging($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder);
1578  }
1579 
1580  if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'add_message') {
1581  print '<div class="fichecenter"><div class="fichehalfleft">';
1582  print '<a name="builddoc"></a>'; // ancre
1583 
1584  // Show links to link elements
1585  $linktoelem = $form->showLinkToObjectBlock($object, null, array('ticket'));
1586  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1587 
1588  // Show direct link to public interface
1589  print '<br><!-- Link to public interface -->'."\n";
1590  print showDirectPublicLink($object).'<br>';
1591  print '</div>';
1592 
1593  if (empty($conf->global->TICKET_SHOW_MESSAGES_ON_CARD)) {
1594  print '<div class="fichehalfright">';
1595 
1596  $MAXEVENT = 10;
1597 
1598  $morehtmlcenter = '<div class="nowraponall">';
1599  $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/ticket/messaging.php?id='.$object->id);
1600  $morehtmlcenter .= ' ';
1601  $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/ticket/agenda.php?id='.$object->id);
1602  $morehtmlcenter .= '</div>';
1603 
1604  // List of actions on element
1605  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1606  $formactions = new FormActions($db);
1607  $somethingshown = $formactions->showactions($object, 'ticket', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter);
1608 
1609  print '</div>';
1610  }
1611 
1612  print '</div>';
1613  }
1614  }
1615 }
1616 
1617 // End of page
1618 llxFooter();
1619 $db->close();
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
Definition: agenda.php:118
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.
if(!defined('NOREQUIRESOC')) if(!defined('NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined('NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined('NOREQUIREAJAX')) llxHeader()
Empty header.
Definition: wrapper.php:56
llxFooter()
Empty footer.
Definition: wrapper.php:70
Class Actions of the module ticket.
Class to manage categories.
Class to manage contact/addresses.
Class to manage standard extra fields.
Class to manage building of HTML components.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage translations.
Class to manage Dolibarr users.
Definition: user.class.php:48
societe_prepare_head(Societe $object)
Return array of tabs to used on pages for third parties cards.
Definition: company.lib.php:42
$parameters
Actions.
Definition: card.php:83
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:239
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0)
Show tabs of a record.
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
roundUpToNextMultiple($n, $x=5)
Round to next multiple.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_phone($phone, $countrycode='', $cid=0, $socid=0, $addlink='', $separ="&nbsp;", $withpicto='', $titlealt='', $adddivfloat=0)
Format phone numbers according to country.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
show_actions_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 in messaging format.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
Class to generate the form for creating a new ticket.
project_prepare_head(Project $project, $moreparam='')
Prepare array with list of tabs.
Definition: project.lib.php:39
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
showDirectPublicLink($object)
Return string with full Url.
Definition: ticket.lib.php:157
ticket_prepare_head($object)
Build tabs for a Ticket object.
Definition: ticket.lib.php:83