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