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