dolibarr  18.0.6
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  $refcheck_object = new Ticket($db);
216  if ($refcheck_object->fetch('', $getRef) > 0) {
217  $object->ref = $object->getDefaultRef();
218  $object->track_id = null;
219  setEventMessage($langs->trans('TicketRefAlreadyUsed', $getRef, $object->ref));
220  } else {
221  $object->ref = $getRef;
222  }
223 
224  $object->fk_soc = GETPOST("socid", 'int') > 0 ? GETPOST("socid", 'int') : 0;
225  $object->subject = GETPOST("subject", 'alphanohtml');
226  $object->message = GETPOST("message", 'restricthtml');
227 
228  $object->type_code = GETPOST("type_code", 'alpha');
229  $object->type_label = $langs->trans($langs->getLabelFromKey($db, $object->type_code, 'c_ticket_type', 'code', 'label'));
230  $object->category_code = GETPOST("category_code", 'alpha');
231  $object->category_label = $langs->trans($langs->getLabelFromKey($db, $object->category_code, 'c_ticket_category', 'code', 'label'));
232  $object->severity_code = GETPOST("severity_code", 'alpha');
233  $object->severity_label = $langs->trans($langs->getLabelFromKey($db, $object->severity_code, 'c_ticket_severity', 'code', 'label'));
234  $object->email_from = $user->email;
235  $notifyTiers = GETPOST("notify_tiers_at_create", 'alpha');
236  $object->notify_tiers_at_create = empty($notifyTiers) ? 0 : 1;
237  $fk_user_assign = GETPOST("fk_user_assign", 'int');
238  if ($fk_user_assign > 0) {
239  $object->fk_user_assign = $fk_user_assign;
240  $object->status = $object::STATUS_ASSIGNED;
241  }
242 
243  $object->fk_project = $projectid;
244 
245  $id = $object->create($user);
246  if ($id <= 0) {
247  $error++;
248  setEventMessages($object->error, $object->errors, 'errors');
249  $action = 'create';
250  }
251 
252  if (!$error) {
253  // Add contact
254  $contactid = GETPOST('contactid', 'int');
255  $type_contact = GETPOST("type", 'alpha');
256 
257  // Category association
258  $categories = GETPOST('categories', 'array');
259  $object->setCategories($categories);
260 
261  if ($contactid > 0 && $type_contact) {
262  $typeid = (GETPOST('typecontact') ? GETPOST('typecontact') : GETPOST('type'));
263  $result = $object->add_contact($contactid, $typeid, 'external');
264  }
265 
266  // Link ticket to project
267  if (GETPOST('origin', 'alpha') == 'projet') {
268  $projectid = GETPOST('originid', 'int');
269  } else {
270  $projectid = GETPOST('projectid', 'int');
271  }
272 
273  if ($projectid > 0) {
274  $object->setProject($projectid);
275  }
276 
277  // Auto mark as read if created from backend
278  if (getDolGlobalString('TICKET_AUTO_READ_WHEN_CREATED_FROM_BACKEND') && $user->rights->ticket->write) {
279  if ( ! $object->markAsRead($user) > 0) {
280  setEventMessages($object->error, $object->errors, 'errors');
281  }
282  }
283 
284  // Auto assign user
285  if (getDolGlobalString('TICKET_AUTO_ASSIGN_USER_CREATE')) {
286  $result = $object->assignUser($user, $user->id, 1);
287  $object->add_contact($user->id, "SUPPORTTEC", 'internal');
288  }
289  }
290 
291  if (!$error) {
292  // File transfer
293  $object->copyFilesForTicket(''); // trackid is forced to '' because files were uploaded when no id for ticket exists yet and trackid was ''
294  }
295 
296  if (!$error) {
297  $db->commit();
298 
299  if (!empty($backtopage)) {
300  if (empty($id)) {
301  $url = $backtopage;
302  } else {
303  $url = 'card.php?track_id='.urlencode($object->track_id);
304  }
305  } else {
306  $url = 'card.php?track_id='.urlencode($object->track_id);
307  }
308 
309  header("Location: ".$url);
310  exit;
311  } else {
312  $db->rollback();
313  setEventMessages($object->error, $object->errors, 'errors');
314  }
315  } else {
316  setEventMessages($object->error, $object->errors, 'errors');
317  $action = 'create';
318  }
319  }
320 
321  if ($action == 'update' && $permissiontoadd && $object->status < Ticket::STATUS_CLOSED) {
322  $error = 0;
323 
324  $ret = $object->fetch(GETPOST('id', 'int'), GETPOST('ref', 'alpha'), GETPOST('track_id', 'alpha'));
325  if ($ret < 0) {
326  $error++;
327  array_push($object->errors, $langs->trans('ErrorTicketIsNotValid'));
328  }
329 
330  // check fields
331  if (!$error) {
332  if (!GETPOST('subject', 'alpha')) {
333  $error++;
334  array_push($object->errors, $langs->trans('ErrorFieldRequired', $langs->transnoentities('Subject')));
335  }
336  $ret = $extrafields->setOptionalsFromPost(null, $object);
337  if ($ret < 0) {
338  $error++;
339  }
340  }
341 
342  if (!$error) {
343  $db->begin();
344 
345  $object->subject = GETPOST('subject', 'alpha');
346  $object->type_code = GETPOST('type_code', 'alpha');
347  $object->category_code = GETPOST('category_code', 'alpha');
348  $object->severity_code = GETPOST('severity_code', 'alpha');
349 
350  $ret = $object->update($user);
351  if ($ret > 0) {
352  // Category association
353  $categories = GETPOST('categories', 'array');
354  $object->setCategories($categories);
355  } else {
356  $error++;
357  }
358 
359  if ($error) {
360  $db->rollback();
361  } else {
362  $db->commit();
363  }
364  }
365 
366  if ($error) {
367  setEventMessages($object->error, $object->errors, 'errors');
368  $action = 'edit';
369  } else {
370  if (!empty($backtopage)) {
371  if (empty($id)) {
372  $url = $backtopage;
373  } else {
374  $url = 'card.php?track_id='.urlencode($object->track_id);
375  }
376  } else {
377  $url = 'card.php?track_id='.urlencode($object->track_id);
378  }
379 
380  header('Location: '.$url);
381  exit();
382  }
383  }
384 
385  // Mark as Read
386  if ($action == "set_read" && $permissiontoadd) {
387  $object->fetch('', '', GETPOST("track_id", 'alpha'));
388 
389  if ($object->markAsRead($user) > 0) {
390  setEventMessages($langs->trans('TicketMarkedAsRead'), null, 'mesgs');
391 
392  header("Location: card.php?track_id=".$object->track_id);
393  exit;
394  } else {
395  setEventMessages($object->error, $object->errors, 'errors');
396  }
397  $action = 'view';
398  }
399 
400  // Assign to someone
401  if ($action == "assign_user" && GETPOST('btn_assign_user', 'alpha') && $permissiontoadd) {
402  $object->fetch('', '', GETPOST("track_id", 'alpha'));
403  $useroriginassign = $object->fk_user_assign;
404  $usertoassign = GETPOST('fk_user_assign', 'int');
405 
406  /*if (! ($usertoassign > 0)) {
407  $error++;
408  array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("AssignedTo")));
409  $action = 'view';
410  }*/
411 
412  if (!$error) {
413  $ret = $object->assignUser($user, $usertoassign);
414  if ($ret < 0) {
415  $error++;
416  }
417  }
418 
419  if (!$error) { // Update list of contacts
420  // Si déjà un user assigné on le supprime des contacts
421  if ($useroriginassign > 0) {
422  $internal_contacts = $object->listeContact(-1, 'internal', 0, 'SUPPORTTEC');
423  foreach ($internal_contacts as $key => $contact) {
424  if ($contact['id'] !== $usertoassign) {
425  $result = $object->delete_contact($contact['rowid']);
426  if ($result<0) {
427  $error++;
428  setEventMessages($object->error, $object->errors, 'errors');
429  }
430  }
431  }
432  }
433 
434  if ($usertoassign > 0 && $usertoassign!==$useroriginassign) {
435  $result = $object->add_contact($usertoassign, "SUPPORTTEC", 'internal', $notrigger = 0);
436  if ($result<0) {
437  $error++;
438  setEventMessages($object->error, $object->errors, 'errors');
439  }
440  }
441  }
442 
443  if (!$error) {
444  // Log action in ticket logs table
445  $object->fetch_user($usertoassign);
446  //$log_action = $langs->trans('TicketLogAssignedTo', $object->user->getFullName($langs));
447 
448 
449  setEventMessages($langs->trans('TicketAssigned'), null, 'mesgs');
450  header("Location: card.php?track_id=".$object->track_id);
451  exit;
452  } else {
453  array_push($object->errors, $object->error);
454  }
455  $action = 'view';
456  }
457 
458  // Action to add a message (private or not, with email or not).
459  // This may also send an email (concatenated with email_intro and email footer if checkbox was selected)
460  if ($action == 'add_message' && GETPOSTISSET('btn_add_message') && $permissiontoread) {
461  $ret = $object->newMessage($user, $action, (GETPOST('private_message', 'alpha') == "on" ? 1 : 0), 0);
462 
463  if ($ret > 0) {
464  if (!empty($backtopage)) {
465  $url = $backtopage;
466  } else {
467  $url = 'card.php?track_id='.urlencode($object->track_id);
468  }
469 
470  header("Location: ".$url);
471  exit;
472  } else {
473  setEventMessages($object->error, $object->errors, 'errors');
474  $action = 'presend';
475  }
476  }
477 
478  if (($action == "confirm_close" || $action == "confirm_abandon") && GETPOST('confirm', 'alpha') == 'yes' && $permissiontoadd) {
479  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
480 
481  if ($object->close($user, ($action == "confirm_abandon" ? 1 : 0))) {
482  setEventMessages($langs->trans('TicketMarkedAsClosed'), null, 'mesgs');
483 
484  $url = 'card.php?track_id='.GETPOST('track_id', 'alpha');
485  header("Location: ".$url);
486  } else {
487  $action = '';
488  setEventMessages($object->error, $object->errors, 'errors');
489  }
490  }
491 
492  if ($action == "confirm_public_close" && GETPOST('confirm', 'alpha') == 'yes' && $permissiontoadd) {
493  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
494  if ($_SESSION['email_customer'] == $object->origin_email || $_SESSION['email_customer'] == $object->thirdparty->email) {
495  $object->close($user);
496 
497  // Log action in ticket logs table
498  //$log_action = $langs->trans('TicketLogClosedBy', $_SESSION['email_customer']);
499 
500  setEventMessages('<div class="confirm">'.$langs->trans('TicketMarkedAsClosed').'</div>', null, 'mesgs');
501 
502  $url = 'card.php?track_id='.GETPOST('track_id', 'alpha');
503  header("Location: ".$url);
504  } else {
505  setEventMessages($object->error, $object->errors, 'errors');
506  $action = '';
507  }
508  }
509 
510  if ($action == 'confirm_delete_ticket' && GETPOST('confirm', 'alpha') == "yes" && $permissiontodelete) {
511  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
512  if ($object->delete($user) > 0) {
513  setEventMessages('<div class="confirm">'.$langs->trans('TicketDeletedSuccess').'</div>', null, 'mesgs');
514  Header("Location: ".DOL_URL_ROOT."/ticket/list.php");
515  exit;
516  } else {
517  $langs->load("errors");
518  $mesg = '<div class="error">'.$langs->trans($object->error).'</div>';
519  $action = '';
520  }
521  }
522  }
523 
524  // Set parent company
525  if ($action == 'set_thirdparty' && $user->rights->ticket->write) {
526  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
527  $result = $object->setCustomer(GETPOST('editcustomer', 'int'));
528  $url = $_SERVER["PHP_SELF"].'?track_id='.GETPOST('track_id', 'alpha');
529  header("Location: ".$url);
530  exit();
531  }
532  }
533 
534  if ($action == 'set_progression' && $user->rights->ticket->write) {
535  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
536  $result = $object->setProgression(GETPOST('progress', 'alpha'));
537 
538  $url = 'card.php?track_id='.$object->track_id;
539  header("Location: ".$url);
540  exit();
541  }
542  }
543 
544  if ($action == 'set_categories' && $user->rights->ticket->write) {
545  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
546  $result = $object->setCategories(GETPOST('categories', 'array'));
547 
548  $url = 'card.php?track_id='.$object->track_id;
549  header("Location: ".$url);
550  exit();
551  }
552  }
553 
554  if ($action == 'setsubject' && $user->rights->ticket->write) {
555  if ($object->fetch(GETPOST('id', 'int'))) {
556  if ($action == 'setsubject') {
557  $object->subject = GETPOST('subject', 'alphanohtml');
558  }
559 
560  if ($action == 'setsubject' && empty($object->subject)) {
561  $error++;
562  setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")), null, 'errors');
563  }
564 
565  if (!$error) {
566  if ($object->update($user) >= 0) {
567  header("Location: ".$_SERVER['PHP_SELF']."?track_id=".$object->track_id);
568  exit;
569  } else {
570  $error++;
571  setEventMessages($object->error, $object->errors, 'errors');
572  }
573  }
574  }
575  }
576 
577  if ($action == 'confirm_reopen' && $user->rights->ticket->manage && !GETPOST('cancel')) {
578  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
579  // prevent browser refresh from reopening ticket several times
580  if ($object->status == Ticket::STATUS_CLOSED || $object->status == Ticket::STATUS_CANCELED) {
581  $res = $object->setStatut(Ticket::STATUS_ASSIGNED);
582  if ($res) {
583  // Log action in ticket logs table
584  //$log_action = $langs->trans('TicketLogReopen');
585 
586  $url = 'card.php?track_id='.$object->track_id;
587  header("Location: ".$url);
588  exit();
589  } else {
590  $error++;
591  setEventMessages($object->error, $object->errors, 'errors');
592  }
593  }
594  }
595  } elseif ($action == 'classin' && $permissiontoadd) {
596  // Categorisation dans projet
597  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
598  $object->setProject($projectid);
599  $url = 'card.php?track_id='.$object->track_id;
600  header("Location: ".$url);
601  exit();
602  }
603  } elseif ($action == 'setcontract' && $permissiontoadd) {
604  // Categorisation dans contrat
605  if ($object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha')) >= 0) {
606  $object->setContract(GETPOST('contractid', 'int'));
607  $url = 'card.php?track_id='.$object->track_id;
608  header("Location: ".$url);
609  exit();
610  }
611  } elseif ($action == "set_message" && $user->rights->ticket->manage) {
612  if (!GETPOST('cancel')) {
613  $object->fetch('', '', GETPOST('track_id', 'alpha'));
614  $oldvalue_message = $object->message;
615  $fieldtomodify = GETPOST('message_initial', 'restricthtml');
616 
617  $object->message = $fieldtomodify;
618  $ret = $object->update($user);
619  if ($ret > 0) {
620  //$log_action = $langs->trans('TicketInitialMessageModified')." \n";
621  // include the Diff class
622  include_once DOL_DOCUMENT_ROOT.'/core/class/utils_diff.class.php';
623  // output the result of comparing two files as plain text
624  //$log_action .= Diff::toString(Diff::compare(strip_tags($oldvalue_message), strip_tags($object->message)));
625 
626  setEventMessages($langs->trans('TicketMessageSuccesfullyUpdated'), null, 'mesgs');
627  } else {
628  $error++;
629  setEventMessages($object->error, $object->errors, 'errors');
630  }
631  }
632 
633  $action = 'view';
634  } elseif ($action == 'confirm_set_status' && $permissiontoadd && !GETPOST('cancel')) {
635  // Reopen ticket
636  if ($object->fetch(GETPOST('id', 'int'), GETPOST('track_id', 'alpha')) >= 0) {
637  $new_status = GETPOST('new_status', 'int');
638  $old_status = $object->status;
639  $res = $object->setStatut($new_status);
640  if ($res) {
641  // Log action in ticket logs table
642  $log_action = $langs->trans('TicketLogStatusChanged', $langs->transnoentities($object->statuts_short[$old_status]), $langs->transnoentities($object->statuts_short[$new_status]));
643 
644  $url = 'card.php?track_id='.$object->track_id;
645  header("Location: ".$url);
646  exit();
647  } else {
648  $error++;
649  setEventMessages($object->error, $object->errors, 'errors');
650  }
651  }
652  }
653 
654  // Action to update one extrafield
655  if ($action == "update_extras" && $permissiontoadd) {
656  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
657 
658  $ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
659  if ($ret < 0) {
660  $error++;
661  }
662 
663  if (!$error) {
664  $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user);
665  if ($result < 0) {
666  $error++;
667  }
668  }
669 
670  if ($error) {
671  setEventMessages($object->error, $object->errors, 'errors');
672  $action = 'edit_extras';
673  } else {
674  setEventMessages($langs->trans('RecordSaved'), null, 'mesgs');
675  $action = 'view';
676  }
677  }
678 
679  if ($action == "change_property" && GETPOST('btn_update_ticket_prop', 'alpha') && $permissiontoadd) {
680  $object->fetch(GETPOST('id', 'int'), '', GETPOST('track_id', 'alpha'));
681 
682  $object->type_code = GETPOST('update_value_type', 'aZ09');
683  $object->severity_code = GETPOST('update_value_severity', 'aZ09');
684  $object->category_code = GETPOST('update_value_category', 'aZ09');
685 
686  $ret = $object->update($user);
687  if ($ret > 0) {
688  //$log_action = $langs->trans('TicketLogPropertyChanged', $oldvalue_label, $newvalue_label);
689 
690  setEventMessages($langs->trans('TicketUpdated'), null, 'mesgs');
691  } else {
692  $error++;
693  setEventMessages($object->error, $object->errors, 'errors');
694  }
695  $action = 'view';
696  }
697 
698 
699  $permissiondellink = $user->rights->ticket->write;
700  include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once
701 
702  // Actions to build doc
703  include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
704  //var_dump($action);exit;
705 
706  // Actions to send emails
707  $triggersendname = 'TICKET_SENTBYMAIL';
708  $paramname = 'id';
709  $autocopy = 'MAIN_MAIL_AUTOCOPY_TICKET_TO'; // used to know the automatic BCC to add
710  $trackid = 'tic'.$object->id;
711  include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
712 
713  // Set $action to correct value for the case we used presend action to add a message
714  if (GETPOSTISSET('actionbis') && $action == 'presend') {
715  $action = 'presend_addmessage';
716  }
717 }
718 
719 
720 /*
721  * View
722  */
723 
724 $userstat = new User($db);
725 $form = new Form($db);
726 $formticket = new FormTicket($db);
727 if (isModEnabled('project')) {
728  $formproject = new FormProjets($db);
729 }
730 
731 $help_url = 'EN:Module_Ticket|FR:DocumentationModuleTicket';
732 
733 $title = $actionobject->getTitle($action);
734 
735 llxHeader('', $title, $help_url);
736 
737 if ($action == 'create' || $action == 'presend') {
738  $formticket = new FormTicket($db);
739 
740  print load_fiche_titre($langs->trans('NewTicket'), '', 'ticket');
741 
742  $formticket->trackid = ''; // TODO Use a unique key 'tic' to avoid conflict in upload file feature
743  $formticket->withfromsocid = $socid ? $socid : $user->socid;
744  $formticket->withfromcontactid = $contactid ? $contactid : '';
745  $formticket->withtitletopic = 1;
746  $formticket->withnotifytiersatcreate = ($notifyTiers ? 1 : (getDolGlobalString('TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION') ? 1 : 0));
747  $formticket->withusercreate = 0;
748  $formticket->withref = 1;
749  $formticket->fk_user_create = $user->id;
750  $formticket->withfile = 2;
751  $formticket->withextrafields = 1;
752  $formticket->param = array('origin' => GETPOST('origin'), 'originid' => GETPOST('originid'));
753 
754  $formticket->withcancel = 1;
755 
756  $formticket->showForm(1, 'create', 0, null, $action);
757  /*} elseif ($action == 'edit' && $user->rights->ticket->write && $object->status < Ticket::STATUS_CLOSED) {
758  $formticket = new FormTicket($db);
759 
760  $head = ticket_prepare_head($object);
761 
762  print '<form method="POST" name="form_ticket" id="form_edit_ticket" action="'.$_SERVER['PHP_SELF'].'?track_id='.$object->track_id.'">';
763  print '<input type="hidden" name="token" value="'.newToken().'">';
764  print '<input type="hidden" name="action" value="update">';
765  print '<input type="hidden" name="tack_id" value="'.$object->track_id.'">';
766 
767  print dol_get_fiche_head($head, 'card', $langs->trans('Ticket'), 0, 'ticket');
768 
769  print '<div class="fichecenter2">';
770  print '<table class="border" width="100%">';
771 
772  // Type
773  print '<tr><td class="titlefield"><span class="fieldrequired"><label for="selecttype_code">'.$langs->trans("TicketTypeRequest").'</span></label></td><td>';
774  $formticket->selectTypesTickets((GETPOSTISSET('type_code') ? GETPOST('type_code') : $object->type_code), 'type_code', '', '2');
775  print '</td></tr>';
776 
777  // Severity
778  print '<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans("TicketSeverity").'</span></label></td><td>';
779  $formticket->selectSeveritiesTickets((GETPOSTISSET('severity_code') ? GETPOST('severity_code') : $object->severity_code), 'severity_code', '', '2');
780  print '</td></tr>';
781 
782  // Group
783  print '<tr><td><span class="fieldrequired"><label for="selectcategory_code">'.$langs->trans("TicketCategory").'</span></label></td><td>';
784  $formticket->selectGroupTickets((GETPOSTISSET('category_code') ? GETPOST('category_code') : $object->category_code), 'category_code', '', '2');
785  print '</td></tr>';
786 
787  // Subject
788  print '<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans("Subject").'</span></label></td><td>';
789  print '<input class="text minwidth200" id="subject" name="subject" value="'.dol_escape_htmltag(GETPOSTISSET('subject') ? GETPOST('subject', 'alpha') : $object->subject).'" />';
790  print '</td></tr>';
791 
792  // Other attributes
793  $parameters = array('colspan' => ' colspan="3"', 'colspanvalue' => '3');
794  $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
795  print $hookmanager->resPrint;
796  if (empty($reshook)) {
797  print $object->showOptionals($extrafields, 'edit');
798  }
799 
800  print '</table>';
801  print '</div>';
802 
803  print dol_get_fiche_end();
804 
805  print $form->buttonsSaveCancel();
806 
807  print '</form>'; */
808 } 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'
809  || $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') {
810  if ($res > 0) {
811  // or for unauthorized internals users
812  if (!$user->socid && (getDolGlobalString('TICKET_LIMIT_VIEW_ASSIGNED_ONLY') && $object->fk_user_assign != $user->id) && !$user->rights->ticket->manage) {
813  accessforbidden('', 0, 1);
814  }
815 
816  // Confirmation close
817  if ($action == 'close') {
818  $thirdparty_contacts = $object->getInfosTicketExternalContact(1);
819  $contacts_select = array(
820  '-2' => $langs->trans('TicketNotifyAllTiersAtClose'),
821  '-3' => $langs->trans('TicketNotNotifyTiersAtClose')
822  );
823  foreach ($thirdparty_contacts as $thirdparty_contact) {
824  $contacts_select[$thirdparty_contact['id']] = $thirdparty_contact['civility'] . ' ' . $thirdparty_contact['lastname'] . ' ' . $thirdparty_contact['firstname'];
825  }
826 
827  // Default select all or no contact
828  $default = (getDolGlobalString('TICKET_NOTIFY_AT_CLOSING') ? -2 : -3);
829  $formquestion = array(
830  array(
831  'name' => 'contactid',
832  'type' => 'select',
833  'label' => $langs->trans('NotifyThirdpartyOnTicketClosing'),
834  'values' => $contacts_select,
835  'default' => $default
836  ),
837  );
838 
839  print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_close", $formquestion, '', 1);
840  }
841  // Confirmation abandon
842  if ($action == 'abandon') {
843  print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("AbandonTicket"), $langs->trans("ConfirmAbandonTicket"), "confirm_abandon", '', '', 1);
844  }
845  // Confirmation delete
846  if ($action == 'delete') {
847  print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("Delete"), $langs->trans("ConfirmDeleteTicket"), "confirm_delete_ticket", '', '', 1);
848  }
849  // Confirm reopen
850  if ($action == 'reopen') {
851  print $form->formconfirm($url_page_current.'?track_id='.$object->track_id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenTicket'), 'confirm_reopen', '', '', 1);
852  }
853  // Confirmation status change
854  if ($action == 'set_status') {
855  $new_status = GETPOST('new_status');
856  //var_dump($url_page_current . "?track_id=" . $object->track_id);
857  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);
858  }
859 
860  // project info
861  if ($projectid > 0) {
862  $projectstat = new Project($db);
863  if ($projectstat->fetch($projectid) > 0) {
864  $projectstat->fetch_thirdparty();
865 
866  // To verify role of users
867  //$userAccess = $object->restrictedProjectArea($user,'read');
868  $userWrite = $projectstat->restrictedProjectArea($user, 'write');
869  //$userDelete = $object->restrictedProjectArea($user,'delete');
870  //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
871 
872  $head = project_prepare_head($projectstat);
873 
874  print dol_get_fiche_head($head, 'ticket', $langs->trans("Project"), 0, ($projectstat->public ? 'projectpub' : 'project'));
875 
876  print '<table class="border centpercent">';
877 
878  $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
879 
880  // Ref
881  print '<tr><td width="30%">'.$langs->trans('Ref').'</td><td colspan="3">';
882  // Define a complementary filter for search of next/prev ref.
883  if (empty($user->rights->projet->all->lire)) {
884  $objectsListId = $projectstat->getProjectsAuthorizedForUser($user, $mine, 0);
885  $projectstat->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? join(',', array_keys($objectsListId)) : '0').")";
886  }
887  print $form->showrefnav($projectstat, 'ref', $linkback, 1, 'ref', 'ref', '');
888  print '</td></tr>';
889 
890  // Label
891  print '<tr><td>'.$langs->trans("Label").'</td><td>'.$projectstat->title.'</td></tr>';
892 
893  // Customer
894  print "<tr><td>".$langs->trans("ThirdParty")."</td>";
895  print '<td colspan="3">';
896  if ($projectstat->thirdparty->id > 0) {
897  print $projectstat->thirdparty->getNomUrl(1);
898  } else {
899  print '&nbsp;';
900  }
901 
902  print '</td></tr>';
903 
904  // Visibility
905  print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
906  if ($projectstat->public) {
907  print $langs->trans('SharedProject');
908  } else {
909  print $langs->trans('PrivateProject');
910  }
911 
912  print '</td></tr>';
913 
914  // Statut
915  print '<tr><td>'.$langs->trans("Status").'</td><td>'.$projectstat->getLibStatut(4).'</td></tr>';
916 
917  print "</table>";
918 
919  print dol_get_fiche_end();
920  } else {
921  print "ErrorRecordNotFound";
922  }
923  } elseif ($socid > 0) {
924  $object->fetch_thirdparty();
925  $head = societe_prepare_head($object->thirdparty);
926 
927  print dol_get_fiche_head($head, 'ticket', $langs->trans("ThirdParty"), 0, 'company');
928 
929  dol_banner_tab($object->thirdparty, 'socid', '', ($user->socid ? 0 : 1), 'rowid', 'nom');
930 
931  print dol_get_fiche_end();
932  }
933 
934  if (!$user->socid && getDolGlobalString('TICKET_LIMIT_VIEW_ASSIGNED_ONLY')) {
935  $object->next_prev_filter = "te.fk_user_assign = ".((int) $user->id);
936  } elseif ($user->socid > 0) {
937  $object->next_prev_filter = "te.fk_soc = ".((int) $user->socid);
938  }
939 
940  $head = ticket_prepare_head($object);
941 
942  print dol_get_fiche_head($head, 'tabTicket', $langs->trans("Ticket"), -1, 'ticket');
943 
944  $morehtmlref = '<div class="refidno">';
945  $morehtmlref .= $object->subject;
946  // Author
947  if ($object->fk_user_create > 0) {
948  $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
949 
950  $fuser = new User($db);
951  $fuser->fetch($object->fk_user_create);
952  $morehtmlref .= $fuser->getNomUrl(-1);
953  } elseif (!empty($object->email_msgid)) {
954  $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
955  $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"');
956  $htmltooltip = $langs->trans("EmailMsgID").': '.$object->email_msgid;
957  $htmltooltip .= '<br>'.$langs->trans("EmailDate").': '.dol_print_date($object->email_date, 'dayhour');
958  $morehtmlref .= dol_escape_htmltag($object->origin_email).' <small class="hideonsmartphone opacitymedium">- '.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $htmltooltip, 1, 'help', '', 0, 3, 'tooltip').'</small>';
959  } elseif (!empty($object->origin_email)) {
960  $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
961  $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"');
962  $htmltooptip = $langs->trans("IP").': '.$object->ip;
963  $morehtmlref .= dol_escape_htmltag($object->origin_email).' <small class="hideonsmartphone opacitymedium">- '.$form->textwithpicto($langs->trans("CreatedByPublicPortal"), $htmltooptip, 1, 'help', '', 0, 3, 'tooltip').'</small>';
964  }
965 
966  $permissiontoedit = $object->status < 8 && !$user->socid && $user->rights->ticket->write;
967  //$permissiontoedit = 0;
968 
969  // Thirdparty
970  if (isModEnabled("societe")) {
971  $morehtmlref .= '<br>';
972  $morehtmlref .= img_picto($langs->trans("ThirdParty"), 'company', 'class="pictofixedwidth"');
973  if ($action != 'editcustomer' && $permissiontoedit) {
974  $morehtmlref .= '<a class="editfielda" href="'.$url_page_current.'?action=editcustomer&token='.newToken().'&track_id='.$object->track_id.'">'.img_edit($langs->transnoentitiesnoconv('SetThirdParty'), 0).'</a> ';
975  }
976  $morehtmlref .= $form->form_thirdparty($url_page_current.'?track_id='.$object->track_id, $object->socid, $action == 'editcustomer' ? 'editcustomer' : 'none', '', 1, 0, 0, array(), 1);
977  if (!empty($object->socid)) {
978  $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>';
979  }
980  }
981 
982  // Project
983  if (isModEnabled('project')) {
984  $langs->load("projects");
985  $morehtmlref .= '<br>';
986  if ($permissiontoedit) {
987  $object->fetch_project();
988  $morehtmlref .= img_picto($langs->trans("Project"), 'project'.((is_object($object->project) && $object->project->public) ? 'pub' : ''), 'class="pictofixedwidth"');
989  if ($action != 'classify') {
990  $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
991  }
992  $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
993  } else {
994  if (!empty($object->fk_project)) {
995  $object->fetch_project();
996  $morehtmlref .= $object->project->getNomUrl(1);
997  if ($object->project->title) {
998  $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($object->project->title).'</span>';
999  }
1000  }
1001  }
1002  }
1003 
1004  $morehtmlref .= '</div>';
1005 
1006  $linkback = '<a href="'.DOL_URL_ROOT.'/ticket/list.php?restore_lastsearch_values=1"><strong>'.$langs->trans("BackToList").'</strong></a> ';
1007 
1008  dol_banner_tab($object, 'ref', $linkback, ($user->socid ? 0 : 1), 'ref', 'ref', $morehtmlref);
1009 
1010  print '<div class="fichecenter">';
1011  print '<div class="fichehalfleft">';
1012  print '<div class="underbanner clearboth"></div>';
1013 
1014  print '<table class="border tableforfield centpercent">';
1015 
1016  // Track ID
1017  print '<tr><td class="titlefield">'.$langs->trans("TicketTrackId").'</td><td>';
1018  if (!empty($object->track_id)) {
1019  if (empty($object->ref)) {
1020  $object->ref = $object->id;
1021  print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'track_id');
1022  } else {
1023  print $object->track_id;
1024  }
1025  } else {
1026  print $langs->trans('None');
1027  }
1028  print '</td></tr>';
1029 
1030  // Subject
1031  print '<tr><td>';
1032  print $form->editfieldkey("Subject", 'subject', $object->subject, $object, $user->rights->ticket->write && !$user->socid, 'string');
1033  print '</td><td>';
1034  print $form->editfieldval("Subject", 'subject', $object->subject, $object, $user->rights->ticket->write && !$user->socid, 'string');
1035  print '</td></tr>';
1036 
1037  // Creation date
1038  print '<tr><td>'.$langs->trans("DateCreation").'</td><td>';
1039  print dol_print_date($object->datec, 'dayhour', 'tzuser');
1040  print '<span class="opacitymedium"> - '.$langs->trans("TimeElapsedSince").': <i>'.convertSecondToTime(roundUpToNextMultiple($now - $object->datec, 60)).'</i></span>';
1041  print '</td></tr>';
1042 
1043  // Origin
1044  /*
1045  if ($object->email_msgid) {
1046  $texttoshow = $langs->trans("CreatedByEmailCollector");
1047  } elseif ($object->origin_email) {
1048  $texttoshow = $langs->trans("FromPublicEmail");
1049  }
1050  if ($texttoshow) {
1051  print '<tr><td class="titlefield fieldname_email_origin">';
1052  print $langs->trans("Origin");
1053  print '</td>';
1054  print '<td class="valuefield fieldname_email_origin">';
1055  print $texttoshow;
1056  print '</td></tr>';
1057  }
1058  */
1059 
1060  // Read date
1061  print '<tr><td>'.$langs->trans("TicketReadOn").'</td><td>';
1062  if (!empty($object->date_read)) {
1063  print dol_print_date($object->date_read, 'dayhour', 'tzuser');
1064  print '<span class="opacitymedium"> - '.$langs->trans("TicketTimeElapsedBeforeSince").': <i>'.convertSecondToTime(roundUpToNextMultiple($object->date_read - $object->datec, 60)).'</i>';
1065  print ' / <i>'.convertSecondToTime(roundUpToNextMultiple($now - $object->date_read, 60)).'</i></span>';
1066  }
1067  print '</td></tr>';
1068 
1069  // Close date
1070  print '<tr><td>'.$langs->trans("TicketCloseOn").'</td><td>';
1071  if (!empty($object->date_close)) {
1072  print dol_print_date($object->date_close, 'dayhour', 'tzuser');
1073  }
1074  print '</td></tr>';
1075 
1076  // User assigned
1077  print '<tr><td>';
1078  print '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
1079  print $langs->trans("AssignedTo");
1080  if (isset($object->status) && $object->status < $object::STATUS_CLOSED && GETPOST('set', 'alpha') != "assign_ticket" && $user->rights->ticket->manage) {
1081  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>';
1082  }
1083  print '</td></tr></table>';
1084  print '</td><td>';
1085  if (GETPOST('set', 'alpha') != "assign_ticket" && $object->fk_user_assign > 0) {
1086  $userstat->fetch($object->fk_user_assign);
1087  print $userstat->getNomUrl(-1);
1088  }
1089 
1090  // Show user list to assignate one if status is "read"
1091  if (GETPOST('set', 'alpha') == "assign_ticket" && $object->status < 8 && !$user->socid && $user->rights->ticket->write) {
1092  print '<form method="post" name="ticket" enctype="multipart/form-data" action="'.$url_page_current.'">';
1093  print '<input type="hidden" name="token" value="'.newToken().'">';
1094  print '<input type="hidden" name="action" value="assign_user">';
1095  print '<input type="hidden" name="track_id" value="'.$object->track_id.'">';
1096  //print '<label for="fk_user_assign">'.$langs->trans("AssignUser").'</label> ';
1097  print $form->select_dolusers(empty($object->fk_user_assign)?$user->id:$object->fk_user_assign, 'fk_user_assign', 1);
1098  print ' <input type="submit" class="button small" name="btn_assign_user" value="'.$langs->trans("Validate").'" />';
1099  print '</form>';
1100  }
1101  print '</td></tr>';
1102 
1103  // Progression
1104  print '<tr><td>';
1105  print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
1106  print $langs->trans('Progression').'</td><td class="left">';
1107  print '</td>';
1108  if ($action != 'progression' && isset($object->status) && $object->status < $object::STATUS_CLOSED && !$user->socid) {
1109  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>';
1110  }
1111  print '</tr></table>';
1112  print '</td><td>';
1113  if ($user->rights->ticket->write && $action == 'progression') {
1114  print '<form action="'.$url_page_current.'" method="post">';
1115  print '<input type="hidden" name="token" value="'.newToken().'">';
1116  print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1117  print '<input type="hidden" name="action" value="set_progression">';
1118  print '<input type="text" class="flat width75" name="progress" value="'.$object->progress.'">';
1119  print ' <input type="submit" class="button button-edit small" value="'.$langs->trans('Modify').'">';
1120  print '</form>';
1121  } else {
1122  print($object->progress > 0 ? $object->progress : '0').'%';
1123  }
1124  print '</td>';
1125  print '</tr>';
1126 
1127  // Timing (Duration sum of linked fichinter)
1128  if (isModEnabled('ficheinter')) {
1129  $object->fetchObjectLinked();
1130  $num = count($object->linkedObjects);
1131  $timing = 0;
1132  $foundinter = 0;
1133  if ($num) {
1134  foreach ($object->linkedObjects as $objecttype => $objects) {
1135  if ($objecttype == "fichinter") {
1136  foreach ($objects as $fichinter) {
1137  $foundinter++;
1138  $timing += $fichinter->duration;
1139  }
1140  }
1141  }
1142  }
1143  print '<tr><td>';
1144  print $form->textwithpicto($langs->trans("TicketDurationAuto"), $langs->trans("TicketDurationAutoInfos"), 1);
1145  print '</td><td>';
1146  print $foundinter ? convertSecondToTime($timing, 'all', getDolGlobalString('MAIN_DURATION_OF_WORKDAY')) : '';
1147  print '</td></tr>';
1148  }
1149 
1150  // Other attributes
1151  include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1152 
1153  print '</table>';
1154 
1155 
1156  // Fin colonne gauche et début colonne droite
1157  print '</div><div class="fichehalfright">';
1158 
1159 
1160  print '<form method="post" name="formticketproperties" action="'.$url_page_current.'">';
1161  print '<input type="hidden" name="token" value="'.newToken().'">';
1162  print '<input type="hidden" name="action" value="change_property">';
1163  print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1164  print '<input type="hidden" name="trackid" value="'.$trackid.'">';
1165 
1166  print '<div class="underbanner clearboth"></div>';
1167 
1168  // Categories
1169  if (isModEnabled('categorie')) {
1170  print '<table class="border centpercent tableforfield">';
1171  print '<tr>';
1172  print '<td class="valignmiddle titlefield">';
1173  print '<table class="nobordernopadding centpercent"><tr><td class="titlefield">';
1174  print $langs->trans("Categories");
1175  if ($action != 'categories' && !$user->socid) {
1176  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>';
1177  }
1178  print '</table>';
1179  print '</td>';
1180 
1181  if ($user->rights->ticket->write && $action == 'categories') {
1182  $cate_arbo = $form->select_all_categories(Categorie::TYPE_TICKET, '', 'parent', 64, 0, 1);
1183  if (is_array($cate_arbo)) {
1184  // Categories
1185  print '<td colspan="3">';
1186  print '<form action="'.$url_page_current.'" method="post">';
1187  print '<input type="hidden" name="token" value="'.newToken().'">';
1188  print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1189  print '<input type="hidden" name="action" value="set_categories">';
1190 
1191  $category = new Categorie($db);
1192  $cats = $category->containing($object->id, 'ticket');
1193  $arrayselected = array();
1194  foreach ($cats as $cat) {
1195  $arrayselected[] = $cat->id;
1196  }
1197 
1198  print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
1199  print '<input type="submit" class="button button-edit small" value="'.$langs->trans('Save').'">';
1200  print '</form>';
1201  print "</td>";
1202  }
1203  } else {
1204  print '<td colspan="3">';
1205  print $form->showCategories($object->id, Categorie::TYPE_TICKET, 1);
1206  print "</td></tr>";
1207  }
1208 
1209  print '</table>';
1210  }
1211 
1212  // View Original message
1213  $actionobject->viewTicketOriginalMessage($user, $action, $object);
1214 
1215  // Classification of ticket
1216  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
1217  print '<table class="noborder tableforfield centpercent margintable">';
1218  print '<tr class="liste_titre">';
1219  print '<td>';
1220  print $langs->trans('TicketProperties');
1221  print '</td>';
1222  print '<td>';
1223  if (GETPOST('set', 'alpha') == 'properties' && $user->rights->ticket->write) {
1224  print '<input type="submit" class="button small" name="btn_update_ticket_prop" value="'.$langs->trans("Modify").'" />';
1225  } else {
1226  // Button to edit Properties
1227  if (isset($object->status) && $object->status < $object::STATUS_NEED_MORE_INFO && $user->rights->ticket->write) {
1228  print ' <a class="editfielda" href="card.php?track_id='.$object->track_id.'&set=properties">'.img_edit($langs->trans('Modify')).'</a>';
1229  }
1230  }
1231  print '</td>';
1232  print '</tr>';
1233 
1234  if (GETPOST('set', 'alpha') == 'properties' && $user->rights->ticket->write) {
1235  print '<tr>';
1236  // Type
1237  print '<td class="titlefield">';
1238  print $langs->trans('Type');
1239  print '</td><td>';
1240  $formticket->selectTypesTickets($object->type_code, 'update_value_type', '', 2);
1241  print '</td>';
1242  print '</tr>';
1243  // Group
1244  print '<tr>';
1245  print '<td>';
1246  print $langs->trans('TicketCategory');
1247  print '</td><td>';
1248  $formticket->selectGroupTickets($object->category_code, 'update_value_category', '', 2, 0, 0, 0, 'maxwidth500 widthcentpercentminusxx');
1249  print '</td>';
1250  print '</tr>';
1251  // Severity
1252  print '<tr>';
1253  print '<td>';
1254  print $langs->trans('TicketSeverity');
1255  print '</td><td>';
1256  $formticket->selectSeveritiesTickets($object->severity_code, 'update_value_severity', '', 2);
1257  print '</td>';
1258  print '</tr>';
1259  } else {
1260  // Type
1261  print '<tr><td class="titlefield">'.$langs->trans("Type").'</td><td>';
1262  if (!empty($object->type_code)) {
1263  print $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code);
1264  }
1265  print '</td></tr>';
1266  // Group
1267  $s = '';
1268  if (!empty($object->category_code)) {
1269  $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code);
1270  }
1271  print '<tr><td>'.$langs->trans("TicketCategory").'</td><td class="tdoverflowmax200" title="'.dol_escape_htmltag($s).'">';
1272  print dol_escape_htmltag($s);
1273  print '</td></tr>';
1274  // Severity
1275  print '<tr><td>'.$langs->trans("TicketSeverity").'</td><td>';
1276  if (!empty($object->severity_code)) {
1277  print $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code);
1278  }
1279  print '</td></tr>';
1280  }
1281  print '</table>'; // End table actions
1282  print '</div>';
1283 
1284  print '</form>';
1285 
1286  // Display navbar with links to change ticket status
1287  print '<!-- navbar with status -->';
1288  if (!$user->socid && $user->rights->ticket->write && isset($object->status) && $object->status < $object::STATUS_CLOSED && GETPOST('set') !== 'properties') {
1289  $actionobject->viewStatusActions($object);
1290  }
1291 
1292 
1293  if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1294  print load_fiche_titre($langs->trans('Contacts'), '', 'title_companies.png');
1295 
1296  print '<div class="div-table-responsive-no-min">';
1297  print '<div class="tagtable centpercent noborder allwidth">';
1298 
1299  print '<div class="tagtr liste_titre">';
1300  print '<div class="tagtd">'.$langs->trans("Source").'</div>
1301  <div class="tagtd">' . $langs->trans("Company").'</div>
1302  <div class="tagtd">' . $langs->trans("Contacts").'</div>
1303  <div class="tagtd">' . $langs->trans("ContactType").'</div>
1304  <div class="tagtd">' . $langs->trans("Phone").'</div>
1305  <div class="tagtd center">' . $langs->trans("Status").'</div>';
1306  print '</div><!-- tagtr -->';
1307 
1308  // Contact list
1309  $companystatic = new Societe($db);
1310  $contactstatic = new Contact($db);
1311  $userstatic = new User($db);
1312  $var = false;
1313  foreach (array('internal', 'external') as $source) {
1314  $tmpobject = $object;
1315  $tab = $tmpobject->listeContact(-1, $source);
1316  $num = count($tab);
1317  $i = 0;
1318  while ($i < $num) {
1319  $var = !$var;
1320  print '<div class="tagtr '.($var ? 'pair' : 'impair').'">';
1321 
1322  print '<div class="tagtd left">';
1323  if ($tab[$i]['source'] == 'internal') {
1324  echo $langs->trans("User");
1325  }
1326 
1327  if ($tab[$i]['source'] == 'external') {
1328  echo $langs->trans("ThirdPartyContact");
1329  }
1330 
1331  print '</div>';
1332  print '<div class="tagtd left">';
1333 
1334  if ($tab[$i]['socid'] > 0) {
1335  $companystatic->fetch($tab[$i]['socid']);
1336  echo $companystatic->getNomUrl(-1);
1337  }
1338  if ($tab[$i]['socid'] < 0) {
1339  echo getDolGlobalString('MAIN_INFO_SOCIETE_NOM');
1340  }
1341  if (!$tab[$i]['socid']) {
1342  echo '&nbsp;';
1343  }
1344  print '</div>';
1345 
1346  print '<div class="tagtd">';
1347  if ($tab[$i]['source'] == 'internal') {
1348  if ($userstatic->fetch($tab[$i]['id'])) {
1349  print $userstatic->getNomUrl(-1);
1350  }
1351  }
1352  if ($tab[$i]['source'] == 'external') {
1353  if ($contactstatic->fetch($tab[$i]['id'])) {
1354  print $contactstatic->getNomUrl(-1);
1355  }
1356  }
1357  print ' </div>
1358  <div class="tagtd">' . $tab[$i]['libelle'].'</div>';
1359 
1360  print '<div class="tagtd">';
1361 
1362  print dol_print_phone($tab[$i]['phone'], '', '', '', 'AC_TEL').'<br>';
1363 
1364  if (!empty($tab[$i]['phone_perso'])) {
1365  //print img_picto($langs->trans('PhonePerso'),'object_phoning.png','',0,0,0).' ';
1366  print '<br>'.dol_print_phone($tab[$i]['phone_perso'], '', '', '', 'AC_TEL').'<br>';
1367  }
1368  if (!empty($tab[$i]['phone_mobile'])) {
1369  //print img_picto($langs->trans('PhoneMobile'),'object_phoning.png','',0,0,0).' ';
1370  print dol_print_phone($tab[$i]['phone_mobile'], '', '', '', 'AC_TEL').'<br>';
1371  }
1372  print '</div>';
1373 
1374  print '<div class="tagtd center">';
1375  if ($object->status >= 0) {
1376  echo '<a href="contact.php?track_id='.$object->track_id.'&amp;action=swapstatut&amp;ligne='.$tab[$i]['rowid'].'">';
1377  }
1378 
1379  if ($tab[$i]['source'] == 'internal') {
1380  $userstatic->id = $tab[$i]['id'];
1381  $userstatic->lastname = $tab[$i]['lastname'];
1382  $userstatic->firstname = $tab[$i]['firstname'];
1383  echo $userstatic->LibStatut($tab[$i]['statuscontact'], 3);
1384  }
1385  if ($tab[$i]['source'] == 'external') {
1386  $contactstatic->id = $tab[$i]['id'];
1387  $contactstatic->lastname = $tab[$i]['lastname'];
1388  $contactstatic->firstname = $tab[$i]['firstname'];
1389  echo $contactstatic->LibStatut($tab[$i]['statuscontact'], 3);
1390  }
1391  if ($object->status >= 0) {
1392  echo '</a>';
1393  }
1394 
1395  print '</div>';
1396 
1397  print '</div><!-- tagtr -->';
1398 
1399  $i++;
1400  }
1401  }
1402 
1403  print '</div><!-- contact list -->';
1404  print '</div>';
1405  }
1406 
1407  print '</div></div>';
1408  print '<div class="clearboth"></div>';
1409 
1410  print dol_get_fiche_end();
1411 
1412 
1413  // Buttons for actions
1414  if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'editline') {
1415  print '<div class="tabsAction">'."\n";
1416  $parameters = array();
1417  $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1418  if ($reshook < 0) {
1419  setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1420  }
1421 
1422  if (empty($reshook)) {
1423  // Email
1424  if (isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") {
1425  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', '');
1426  }
1427 
1428  // Show link to add a message (if read and not closed)
1429  if (isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") {
1430  print dolGetButtonAction('', $langs->trans('TicketAddPrivateMessage'), 'default', $_SERVER["PHP_SELF"].'?action=presend_addmessage&mode=init&token='.newToken().'&track_id='.$object->track_id.'#formmailbeforetitle', '');
1431  }
1432 
1433  // Link to create an intervention
1434  // socid is needed otherwise fichinter ask it and forgot origin after form submit :\
1435  if (!$object->fk_soc && $user->hasRight("ficheinter", "creer")) {
1436  print dolGetButtonAction($langs->trans('UnableToCreateInterIfNoSocid'), $langs->trans('TicketAddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1437  }
1438  if ($object->fk_soc > 0 && isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $user->hasRight('ficheinter', 'creer')) {
1439  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, '');
1440  }
1441 
1442  // Close ticket if statut is read
1443  if (isset($object->status) && $object->status > 0 && $object->status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) {
1444  print dolGetButtonAction('', $langs->trans('CloseTicket'), 'default', $_SERVER["PHP_SELF"].'?action=close&token='.newToken().'&track_id='.$object->track_id, '');
1445  }
1446 
1447  // Abadon ticket if statut is read
1448  if (isset($object->status) && $object->status > 0 && $object->status < Ticket::STATUS_CLOSED && $user->rights->ticket->write) {
1449  print dolGetButtonAction('', $langs->trans('AbandonTicket'), 'default', $_SERVER["PHP_SELF"].'?action=abandon&token='.newToken().'&track_id='.$object->track_id, '');
1450  }
1451 
1452  // Re-open ticket
1453  if (!$user->socid && (isset($object->status) && ($object->status == Ticket::STATUS_CLOSED || $object->status == Ticket::STATUS_CANCELED)) && !$user->socid) {
1454  print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&track_id='.$object->track_id, '');
1455  }
1456 
1457  // Delete ticket
1458  if ($user->rights->ticket->delete && !$user->socid) {
1459  print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&track_id='.$object->track_id, '');
1460  }
1461  }
1462  print '</div>'."\n";
1463  } else {
1464  //print '<br>';
1465  }
1466 
1467  // Select mail models is same action as presend
1468  if (GETPOST('modelselected')) {
1469  $action = 'presend';
1470  }
1471  // Set $action to correct value for the case we used presend action to add a message
1472  if (GETPOSTISSET('actionbis') && $action == 'presend') {
1473  $action = 'presend_addmessage';
1474  }
1475 
1476  // add a message
1477  if ($action == 'presend' || $action == 'presend_addmessage') {
1478  if ($object->fk_soc > 0) {
1479  $object->fetch_thirdparty();
1480  }
1481 
1482  $outputlangs = $langs;
1483  $newlang = '';
1484  if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1485  $newlang = GETPOST('lang_id', 'aZ09');
1486  } elseif (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && is_object($object->thirdparty)) {
1487  $newlang = $object->thirdparty->default_lang;
1488  }
1489  if (!empty($newlang)) {
1490  $outputlangs = new Translate("", $conf);
1491  $outputlangs->setDefaultLang($newlang);
1492  }
1493 
1494  $arrayoffamiliestoexclude = array('objectamount');
1495 
1496  $action = 'add_message'; // action to use to post the message
1497  $modelmail = 'ticket_send';
1498 
1499  // Substitution array
1500  $morehtmlright = '';
1501  $help = "";
1502  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, $arrayoffamiliestoexclude, $object);
1503  $morehtmlright .= $form->textwithpicto('<span class="opacitymedium">'.$langs->trans("TicketMessageSubstitutionReplacedByGenericValues").'</span>', $help, 1, 'helpclickable', '', 0, 3, 'helpsubstitution');
1504 
1505  print '<div>';
1506 
1507  print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>';
1508 
1509  print load_fiche_titre($langs->trans('TicketAddMessage'), $morehtmlright, 'messages@ticket');
1510 
1511  print '<hr>';
1512 
1513  $formticket = new FormTicket($db);
1514 
1515  $formticket->action = $action;
1516  $formticket->track_id = $object->track_id;
1517  $formticket->ref = $object->ref;
1518  $formticket->id = $object->id;
1519  $formticket->trackid = 'tic'.$object->id;
1520 
1521  $formticket->withfile = 2;
1522  $formticket->withcancel = 1;
1523  $formticket->param = array('fk_user_create' => $user->id);
1524  $formticket->param['langsmodels'] = (empty($newlang) ? $langs->defaultlang : $newlang);
1525 
1526  // Tableau des parametres complementaires du post
1527  $formticket->param['models'] = $modelmail;
1528  $formticket->param['models_id'] = GETPOST('modelmailselected', 'int');
1529  //$formticket->param['socid']=$object->fk_soc;
1530  $formticket->param['returnurl'] = $_SERVER["PHP_SELF"].'?track_id='.$object->track_id;
1531 
1532  $formticket->withsubstit = 1;
1533  $formticket->substit = $substitutionarray;
1534  $formticket->backtopage = $backtopage;
1535 
1536  $formticket->showMessageForm('100%');
1537  print '</div>';
1538  }
1539 
1540  // Show messages on card (Note: this is a duplicate of the view Events/Agenda but on the main tab)
1541  if (getDolGlobalString('TICKET_SHOW_MESSAGES_ON_CARD')) {
1542  $param = '&id='.$object->id;
1543  if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
1544  $param .= '&contextpage='.$contextpage;
1545  }
1546  if ($limit > 0 && $limit != $conf->liste_limit) {
1547  $param .= '&limit='.$limit;
1548  }
1549  if ($actioncode) {
1550  $param .= '&actioncode='.urlencode($actioncode);
1551  }
1552  if ($search_agenda_label) {
1553  $param .= '&search_agenda_label='.urlencode($search_agenda_label);
1554  }
1555 
1556  $morehtmlright = '';
1557 
1558  $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id;
1559  $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 1);
1560 
1561  // Show link to add a message (if read and not closed)
1562  $btnstatus = $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage" && $action != "add_message";
1563  $url = 'card.php?track_id='.$object->track_id.'&action=presend_addmessage&mode=init';
1564  $morehtmlright .= dolGetButtonTitle($langs->trans('TicketAddMessage'), '', 'fa fa-comment-dots', $url, 'add-new-ticket-title-button', $btnstatus);
1565 
1566  // Show link to add event (if read and not closed)
1567  $btnstatus = $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage" && $action != "add_message";
1568  $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);
1569  $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', $url, 'add-new-ticket-even-button', $btnstatus);
1570 
1571  print_barre_liste($langs->trans("ActionsOnTicket"), 0, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
1572 
1573  // List of all actions
1574  $filters = array();
1575  $filters['search_agenda_label'] = $search_agenda_label;
1576  $filters['search_rowid'] = $search_rowid;
1577 
1578  show_actions_messaging($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder);
1579  }
1580 
1581  if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'add_message') {
1582  print '<div class="fichecenter"><div class="fichehalfleft">';
1583  print '<a name="builddoc"></a>'; // ancre
1584 
1585  // Show links to link elements
1586  $linktoelem = $form->showLinkToObjectBlock($object, null, array('ticket'));
1587  $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1588 
1589  // Show direct link to public interface
1590  print '<br><!-- Link to public interface -->'."\n";
1591  print showDirectPublicLink($object).'<br>';
1592  print '</div>';
1593 
1594  if (getDolGlobalString('TICKET_SHOW_MESSAGES_ON_CARD')) {
1595  print '<div class="fichehalfright">';
1596 
1597  $MAXEVENT = 10;
1598 
1599  $morehtmlcenter = '<div class="nowraponall">';
1600  $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/ticket/messaging.php?id='.$object->id);
1601  $morehtmlcenter .= ' ';
1602  $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/ticket/agenda.php?id='.$object->id);
1603  $morehtmlcenter .= '</div>';
1604 
1605  // List of actions on element
1606  include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1607  $formactions = new FormActions($db);
1608  $somethingshown = $formactions->showactions($object, 'ticket', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter);
1609 
1610  print '</div>';
1611  }
1612 
1613  print '</div>';
1614  }
1615  }
1616 }
1617 
1618 // End of page
1619 llxFooter();
1620 $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:240
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