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