dolibarr 19.0.4
card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2013-2016 Jean-François FERRY <hello@librethic.io>
3 * Copyright (C) 2016 Christophe Battarel <christophe@altairis.fr>
4 * Copyright (C) 2018 Laurent Destailleur <eldy@users.sourceforge.net>
5 * Copyright (C) 2021 Frédéric France <frederic.france@netlogic.fr>
6 * Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
7 * Copyright (C) 2022-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, GETPOSTINT('private_message'), 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
646 $res = $object->setStatut($new_status, null, '', 'TICKET_MODIFY');
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
746 if (GETPOST("mode", "aZ09") == 'init' && empty($_POST)) {
747 $formticket->clear_attached_files();
748 }
749
750 $formticket->withfromsocid = $socid ? $socid : $user->socid;
751 $formticket->withfromcontactid = $contactid ? $contactid : '';
752 $formticket->withtitletopic = 1;
753 $formticket->withnotifytiersatcreate = ($notifyTiers ? 1 : (getDolGlobalString('TICKET_CHECK_NOTIFY_THIRDPARTY_AT_CREATION') ? 1 : 0));
754 $formticket->withusercreate = 0;
755 $formticket->withref = 1;
756 $formticket->fk_user_create = $user->id;
757 $formticket->withfile = 2;
758 $formticket->withextrafields = 1;
759 $formticket->param = array('origin' => GETPOST('origin'), 'originid' => GETPOST('originid'));
760
761 $formticket->withcancel = 1;
762
763 // Init list of files
764 if (GETPOST("mode", "aZ09") == 'init') {
765 $formticket->clear_attached_files();
766 }
767 $formticket->showForm(1, 'create', 0, null, $action);
768 /*} elseif ($action == 'edit' && $user->rights->ticket->write && $object->status < Ticket::STATUS_CLOSED) {
769 $formticket = new FormTicket($db);
770
771 $head = ticket_prepare_head($object);
772
773 print '<form method="POST" name="form_ticket" id="form_edit_ticket" action="'.$_SERVER['PHP_SELF'].'?track_id='.$object->track_id.'">';
774 print '<input type="hidden" name="token" value="'.newToken().'">';
775 print '<input type="hidden" name="action" value="update">';
776 print '<input type="hidden" name="tack_id" value="'.$object->track_id.'">';
777
778 print dol_get_fiche_head($head, 'card', $langs->trans('Ticket'), 0, 'ticket');
779
780 print '<div class="fichecenter2">';
781 print '<table class="border" width="100%">';
782
783 // Type
784 print '<tr><td class="titlefield"><span class="fieldrequired"><label for="selecttype_code">'.$langs->trans("TicketTypeRequest").'</span></label></td><td>';
785 $formticket->selectTypesTickets((GETPOSTISSET('type_code') ? GETPOST('type_code') : $object->type_code), 'type_code', '', '2');
786 print '</td></tr>';
787
788 // Severity
789 print '<tr><td><span class="fieldrequired"><label for="selectseverity_code">'.$langs->trans("TicketSeverity").'</span></label></td><td>';
790 $formticket->selectSeveritiesTickets((GETPOSTISSET('severity_code') ? GETPOST('severity_code') : $object->severity_code), 'severity_code', '', '2');
791 print '</td></tr>';
792
793 // Group
794 print '<tr><td><span class="fieldrequired"><label for="selectcategory_code">'.$langs->trans("TicketCategory").'</span></label></td><td>';
795 $formticket->selectGroupTickets((GETPOSTISSET('category_code') ? GETPOST('category_code') : $object->category_code), 'category_code', '', '2');
796 print '</td></tr>';
797
798 // Subject
799 print '<tr><td><label for="subject"><span class="fieldrequired">'.$langs->trans("Subject").'</span></label></td><td>';
800 print '<input class="text minwidth200" id="subject" name="subject" value="'.dol_escape_htmltag(GETPOSTISSET('subject') ? GETPOST('subject', 'alpha') : $object->subject).'" />';
801 print '</td></tr>';
802
803 // Other attributes
804 $parameters = array('colspan' => ' colspan="3"', 'colspanvalue' => '3');
805 $reshook = $hookmanager->executeHooks('formObjectOptions', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
806 print $hookmanager->resPrint;
807 if (empty($reshook)) {
808 print $object->showOptionals($extrafields, 'edit');
809 }
810
811 print '</table>';
812 print '</div>';
813
814 print dol_get_fiche_end();
815
816 print $form->buttonsSaveCancel();
817
818 print '</form>'; */
819} 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'
820 || $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') {
821 if ($res > 0) {
822 // or for unauthorized internals users
823 if (!$user->socid && (getDolGlobalString('TICKET_LIMIT_VIEW_ASSIGNED_ONLY') && $object->fk_user_assign != $user->id) && !$user->hasRight('ticket', 'manage')) {
824 accessforbidden('', 0, 1);
825 }
826
827 // Confirmation close
828 if ($action == 'close') {
829 $thirdparty_contacts = $object->getInfosTicketExternalContact(1);
830 $contacts_select = array(
831 '-2' => $langs->trans('TicketNotifyAllTiersAtClose'),
832 '-3' => $langs->trans('TicketNotNotifyTiersAtClose')
833 );
834 foreach ($thirdparty_contacts as $thirdparty_contact) {
835 $contacts_select[$thirdparty_contact['id']] = $thirdparty_contact['civility'] . ' ' . $thirdparty_contact['lastname'] . ' ' . $thirdparty_contact['firstname'];
836 }
837
838 // Default select all or no contact
839 $default = (getDolGlobalString('TICKET_NOTIFY_AT_CLOSING') ? -2 : -3);
840 $formquestion = array(
841 array(
842 'name' => 'contactid',
843 'type' => 'select',
844 'label' => $langs->trans('NotifyThirdpartyOnTicketClosing'),
845 'values' => $contacts_select,
846 'default' => $default
847 ),
848 );
849
850 print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("CloseATicket"), $langs->trans("ConfirmCloseAticket"), "confirm_close", $formquestion, '', 1);
851 }
852 // Confirmation abandon
853 if ($action == 'abandon') {
854 print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("AbandonTicket"), $langs->trans("ConfirmAbandonTicket"), "confirm_abandon", '', '', 1);
855 }
856 // Confirmation delete
857 if ($action == 'delete') {
858 print $form->formconfirm($url_page_current."?track_id=".$object->track_id, $langs->trans("Delete"), $langs->trans("ConfirmDeleteTicket"), "confirm_delete_ticket", '', '', 1);
859 }
860 // Confirm reopen
861 if ($action == 'reopen') {
862 print $form->formconfirm($url_page_current.'?track_id='.$object->track_id, $langs->trans('ReOpen'), $langs->trans('ConfirmReOpenTicket'), 'confirm_reopen', '', '', 1);
863 }
864 // Confirmation status change
865 if ($action == 'set_status') {
866 $new_status = GETPOST('new_status');
867 //var_dump($url_page_current . "?track_id=" . $object->track_id);
868 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);
869 }
870
871 // project info
872 if ($projectid > 0) {
873 $projectstat = new Project($db);
874 if ($projectstat->fetch($projectid) > 0) {
875 $projectstat->fetch_thirdparty();
876
877 // To verify role of users
878 //$userAccess = $object->restrictedProjectArea($user,'read');
879 $userWrite = $projectstat->restrictedProjectArea($user, 'write');
880 //$userDelete = $object->restrictedProjectArea($user,'delete');
881 //print "userAccess=".$userAccess." userWrite=".$userWrite." userDelete=".$userDelete;
882
883 $head = project_prepare_head($projectstat);
884
885 print dol_get_fiche_head($head, 'ticket', $langs->trans("Project"), 0, ($projectstat->public ? 'projectpub' : 'project'));
886
887 print '<table class="border centpercent">';
888
889 $linkback = '<a href="'.DOL_URL_ROOT.'/projet/list.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
890
891 // Ref
892 print '<tr><td width="30%">'.$langs->trans('Ref').'</td><td colspan="3">';
893 // Define a complementary filter for search of next/prev ref.
894 if (!$user->hasRight('projet', 'all', 'lire')) {
895 $objectsListId = $projectstat->getProjectsAuthorizedForUser($user, $mine, 0);
896 $projectstat->next_prev_filter = "rowid IN (".$db->sanitize(count($objectsListId) ? join(',', array_keys($objectsListId)) : '0').")";
897 }
898 print $form->showrefnav($projectstat, 'ref', $linkback, 1, 'ref', 'ref', '');
899 print '</td></tr>';
900
901 // Label
902 print '<tr><td>'.$langs->trans("Label").'</td><td>'.$projectstat->title.'</td></tr>';
903
904 // Customer
905 print "<tr><td>".$langs->trans("ThirdParty")."</td>";
906 print '<td colspan="3">';
907 if ($projectstat->thirdparty->id > 0) {
908 print $projectstat->thirdparty->getNomUrl(1);
909 } else {
910 print '&nbsp;';
911 }
912
913 print '</td></tr>';
914
915 // Visibility
916 print '<tr><td>'.$langs->trans("Visibility").'</td><td>';
917 if ($projectstat->public) {
918 print $langs->trans('SharedProject');
919 } else {
920 print $langs->trans('PrivateProject');
921 }
922
923 print '</td></tr>';
924
925 // Status
926 print '<tr><td>'.$langs->trans("Status").'</td><td>'.$projectstat->getLibStatut(4).'</td></tr>';
927
928 print "</table>";
929
930 print dol_get_fiche_end();
931 } else {
932 print "ErrorRecordNotFound";
933 }
934 } elseif ($socid > 0) {
935 $object->fetch_thirdparty();
936 $head = societe_prepare_head($object->thirdparty);
937
938 print dol_get_fiche_head($head, 'ticket', $langs->trans("ThirdParty"), 0, 'company');
939
940 dol_banner_tab($object->thirdparty, 'socid', '', ($user->socid ? 0 : 1), 'rowid', 'nom');
941
942 print dol_get_fiche_end();
943 }
944
945 if (!$user->socid && getDolGlobalString('TICKET_LIMIT_VIEW_ASSIGNED_ONLY')) {
946 $object->next_prev_filter = "te.fk_user_assign = ".((int) $user->id);
947 } elseif ($user->socid > 0) {
948 $object->next_prev_filter = "te.fk_soc = ".((int) $user->socid);
949 }
950
951 $head = ticket_prepare_head($object);
952
953 print dol_get_fiche_head($head, 'tabTicket', $langs->trans("Ticket"), -1, 'ticket');
954
955 $morehtmlref = '<div class="refidno">';
956 $morehtmlref .= $object->subject;
957 // Author
958 if ($object->fk_user_create > 0) {
959 $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
960
961 $fuser = new User($db);
962 $fuser->fetch($object->fk_user_create);
963 $morehtmlref .= $fuser->getNomUrl(-1);
964 } elseif (!empty($object->email_msgid)) {
965 $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
966 $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"');
967 $htmltooltip = $langs->trans("EmailMsgID").': '.$object->email_msgid;
968 $htmltooltip .= '<br>'.$langs->trans("EmailDate").': '.dol_print_date($object->email_date, 'dayhour');
969 $morehtmlref .= dol_escape_htmltag($object->origin_email).' <small class="hideonsmartphone opacitymedium">- '.$form->textwithpicto($langs->trans("CreatedByEmailCollector"), $htmltooltip, 1, 'help', '', 0, 3, 'tooltip').'</small>';
970 } elseif (!empty($object->origin_email)) {
971 $morehtmlref .= '<br>'.$langs->trans("CreatedBy").' : ';
972 $morehtmlref .= img_picto('', 'email', 'class="paddingrightonly"');
973 $htmltooptip = $langs->trans("IP").': '.$object->ip;
974 $morehtmlref .= dol_escape_htmltag($object->origin_email).' <small class="hideonsmartphone opacitymedium">- '.$form->textwithpicto($langs->trans("CreatedByPublicPortal"), $htmltooptip, 1, 'help', '', 0, 3, 'tooltip').'</small>';
975 }
976
977 $permissiontoedit = $object->status < 8 && !$user->socid && $user->rights->ticket->write;
978 //$permissiontoedit = 0;
979
980 // Thirdparty
981 if (isModEnabled("societe")) {
982 $morehtmlref .= '<br>';
983 $morehtmlref .= img_picto($langs->trans("ThirdParty"), 'company', 'class="pictofixedwidth"');
984 if ($action != 'editcustomer' && $permissiontoedit) {
985 $morehtmlref .= '<a class="editfielda" href="'.$url_page_current.'?action=editcustomer&token='.newToken().'&track_id='.$object->track_id.'">'.img_edit($langs->transnoentitiesnoconv('SetThirdParty'), 0).'</a> ';
986 }
987 $morehtmlref .= $form->form_thirdparty($url_page_current.'?track_id='.$object->track_id, $object->socid, $action == 'editcustomer' ? 'editcustomer' : 'none', '', 1, 0, 0, array(), 1);
988 if (!empty($object->socid)) {
989 $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>';
990 }
991 }
992
993 // Project
994 if (isModEnabled('project')) {
995 $langs->load("projects");
996 $morehtmlref .= '<br>';
997 if ($permissiontoedit) {
998 $object->fetch_project();
999 $morehtmlref .= img_picto($langs->trans("Project"), 'project'.((is_object($object->project) && $object->project->public) ? 'pub' : ''), 'class="pictofixedwidth"');
1000 if ($action != 'classify') {
1001 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
1002 }
1003 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
1004 } else {
1005 if (!empty($object->fk_project)) {
1006 $object->fetch_project();
1007 $morehtmlref .= $object->project->getNomUrl(1);
1008 if ($object->project->title) {
1009 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($object->project->title).'</span>';
1010 }
1011 }
1012 }
1013 }
1014
1015 // Contract
1016 if (getDolGlobalString('TICKET_LINK_TO_CONTRACT_WITH_HARDLINK')) {
1017 // Deprecated. Duplicate feature. Ticket can already be linked to contract with the generic "Link to" feature.
1018 if (isModEnabled('contrat')) {
1019 $langs->load('contracts');
1020 $morehtmlref .= '<br>';
1021 if ($permissiontoedit) {
1022 $morehtmlref .= img_picto($langs->trans("Contract"), 'contract', 'class="pictofixedwidth"');
1023 if ($action == 'edit_contrat') {
1024 $formcontract = new FormContract($db);
1025 $morehtmlref .= $formcontract->formSelectContract($_SERVER["PHP_SELF"].'?id='.$object->id, $object->socid, $object->fk_contract, 'contratid', 0, 1, 1, 1);
1026 } else {
1027 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER["PHP_SELF"].'?action=edit_contrat&token='.newToken().'&id='.$object->id.'">';
1028 $morehtmlref .= img_edit($langs->trans('SetContract'));
1029 $morehtmlref .= '</a>';
1030 }
1031 } else {
1032 if (!empty($object->fk_contract)) {
1033 $contratstatic = new Contrat($db);
1034 $contratstatic->fetch($object->fk_contract);
1035 //print '<a href="'.DOL_URL_ROOT.'/projet/card.php?id='.$selected.'">'.$projet->title.'</a>';
1036 $morehtmlref .= $contratstatic->getNomUrl(0, '', 1);
1037 }
1038 }
1039 }
1040 }
1041
1042 $morehtmlref .= '</div>';
1043
1044 $linkback = '<a href="'.DOL_URL_ROOT.'/ticket/list.php?restore_lastsearch_values=1"><strong>'.$langs->trans("BackToList").'</strong></a> ';
1045
1046 dol_banner_tab($object, 'ref', $linkback, ($user->socid ? 0 : 1), 'ref', 'ref', $morehtmlref);
1047
1048 print '<div class="fichecenter">';
1049 print '<div class="fichehalfleft">';
1050 print '<div class="underbanner clearboth"></div>';
1051
1052 print '<table class="border tableforfield centpercent">';
1053
1054 // Track ID
1055 print '<tr><td class="titlefield">'.$langs->trans("TicketTrackId").'</td><td>';
1056 if (!empty($object->track_id)) {
1057 if (empty($object->ref)) {
1058 $object->ref = $object->id;
1059 print $form->showrefnav($object, 'id', $linkback, 1, 'rowid', 'track_id');
1060 } else {
1061 print dolPrintLabel($object->track_id);
1062 }
1063 } else {
1064 print $langs->trans('None');
1065 }
1066 print '</td></tr>';
1067
1068 // Subject
1069 print '<tr><td>';
1070 print $form->editfieldkey("Subject", 'subject', $object->subject, $object, $user->hasRight('ticket', 'write') && !$user->socid, 'string');
1071 print '</td><td>';
1072 print $form->editfieldval("Subject", 'subject', $object->subject, $object, $user->hasRight('ticket', 'write') && !$user->socid, 'string');
1073 print '</td></tr>';
1074
1075 // Creation date
1076 print '<tr><td>'.$langs->trans("DateCreation").'</td><td>';
1077 print dol_print_date($object->datec, 'dayhour', 'tzuser');
1078 print '<span class="opacitymedium"> - '.$langs->trans("TimeElapsedSince").': <i>'.convertSecondToTime(roundUpToNextMultiple($now - $object->datec, 60)).'</i></span>';
1079 print '</td></tr>';
1080
1081 // Origin
1082 /*
1083 if ($object->email_msgid) {
1084 $texttoshow = $langs->trans("CreatedByEmailCollector");
1085 } elseif ($object->origin_email) {
1086 $texttoshow = $langs->trans("FromPublicEmail");
1087 }
1088 if ($texttoshow) {
1089 print '<tr><td class="titlefield fieldname_email_origin">';
1090 print $langs->trans("Origin");
1091 print '</td>';
1092 print '<td class="valuefield fieldname_email_origin">';
1093 print $texttoshow;
1094 print '</td></tr>';
1095 }
1096 */
1097
1098 // Read date
1099 print '<tr><td>'.$langs->trans("TicketReadOn").'</td><td>';
1100 if (!empty($object->date_read)) {
1101 print dol_print_date($object->date_read, 'dayhour', 'tzuser');
1102 print '<span class="opacitymedium"> - '.$langs->trans("TicketTimeElapsedBeforeSince").': <i>'.convertSecondToTime(roundUpToNextMultiple($object->date_read - $object->datec, 60)).'</i>';
1103 print ' / <i>'.convertSecondToTime(roundUpToNextMultiple($now - $object->date_read, 60)).'</i></span>';
1104 }
1105 print '</td></tr>';
1106
1107 // Close date
1108 print '<tr><td>'.$langs->trans("TicketCloseOn").'</td><td>';
1109 if (!empty($object->date_close)) {
1110 print dol_print_date($object->date_close, 'dayhour', 'tzuser');
1111 }
1112 print '</td></tr>';
1113
1114 // User assigned
1115 print '<tr><td>';
1116 print '<table class="nobordernopadding" width="100%"><tr><td class="nowrap">';
1117 print $langs->trans("AssignedTo");
1118 if (isset($object->status) && $object->status < $object::STATUS_CLOSED && GETPOST('set', 'alpha') != "assign_ticket" && $user->hasRight('ticket', 'manage')) {
1119 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>';
1120 }
1121 print '</td></tr></table>';
1122 print '</td><td>';
1123 if (GETPOST('set', 'alpha') != "assign_ticket" && $object->fk_user_assign > 0) {
1124 $userstat->fetch($object->fk_user_assign);
1125 print $userstat->getNomUrl(-1);
1126 }
1127
1128 // Show user list to assignate one if status is "read"
1129 if (GETPOST('set', 'alpha') == "assign_ticket" && $object->status < 8 && !$user->socid && $user->hasRight('ticket', 'write')) {
1130 print '<form method="post" name="ticket" enctype="multipart/form-data" action="'.$url_page_current.'">';
1131 print '<input type="hidden" name="token" value="'.newToken().'">';
1132 print '<input type="hidden" name="action" value="assign_user">';
1133 print '<input type="hidden" name="track_id" value="'.$object->track_id.'">';
1134 //print '<label for="fk_user_assign">'.$langs->trans("AssignUser").'</label> ';
1135 print $form->select_dolusers(empty($object->fk_user_assign) ? $user->id : $object->fk_user_assign, 'fk_user_assign', 1);
1136 print ' <input type="submit" class="button small" name="btn_assign_user" value="'.$langs->trans("Validate").'" />';
1137 print '</form>';
1138 }
1139 print '</td></tr>';
1140
1141 // Progression
1142 print '<tr><td>';
1143 print '<table class="nobordernopadding centpercent"><tr><td class="nowrap">';
1144 print $langs->trans('Progression').'</td><td class="left">';
1145 print '</td>';
1146 if ($action != 'progression' && isset($object->status) && $object->status < $object::STATUS_CLOSED && !$user->socid) {
1147 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>';
1148 }
1149 print '</tr></table>';
1150 print '</td><td>';
1151 if ($user->hasRight('ticket', 'write') && $action == 'progression') {
1152 print '<form action="'.$url_page_current.'" method="post">';
1153 print '<input type="hidden" name="token" value="'.newToken().'">';
1154 print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1155 print '<input type="hidden" name="action" value="set_progression">';
1156 print '<input type="text" class="flat width75" name="progress" value="'.$object->progress.'">';
1157 print ' <input type="submit" class="button button-edit small" value="'.$langs->trans('Modify').'">';
1158 print '</form>';
1159 } else {
1160 print($object->progress > 0 ? $object->progress : '0').'%';
1161 }
1162 print '</td>';
1163 print '</tr>';
1164
1165 // Timing (Duration sum of linked fichinter)
1166 if (isModEnabled('ficheinter')) {
1167 $object->fetchObjectLinked();
1168 $num = count($object->linkedObjects);
1169 $timing = 0;
1170 $foundinter = 0;
1171 if ($num) {
1172 foreach ($object->linkedObjects as $objecttype => $objects) {
1173 if ($objecttype == "fichinter") {
1174 foreach ($objects as $fichinter) {
1175 $foundinter++;
1176 $timing += $fichinter->duration;
1177 }
1178 }
1179 }
1180 }
1181 print '<tr><td>';
1182 print $form->textwithpicto($langs->trans("TicketDurationAuto"), $langs->trans("TicketDurationAutoInfos"), 1);
1183 print '</td><td>';
1184 print $foundinter ? convertSecondToTime($timing, 'all', getDolGlobalString('MAIN_DURATION_OF_WORKDAY')) : '';
1185 print '</td></tr>';
1186 }
1187
1188 // Other attributes
1189 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
1190
1191 print '</table>';
1192
1193
1194 // End of left column and beginning of right column
1195 print '</div><div class="fichehalfright">';
1196
1197
1198 print '<form method="post" name="formticketproperties" action="'.$url_page_current.'">';
1199 print '<input type="hidden" name="token" value="'.newToken().'">';
1200 print '<input type="hidden" name="action" value="change_property">';
1201 print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1202 print '<input type="hidden" name="trackid" value="'.$trackid.'">';
1203
1204 // Categories
1205 if (isModEnabled('categorie')) {
1206 print '<div class="underbanner clearboth"></div>';
1207 print '<table class="border centpercent tableforfield">';
1208 print '<tr>';
1209 print '<td class="valignmiddle titlefield">';
1210 print '<table class="nobordernopadding centpercent"><tr><td class="titlefield">';
1211 print $langs->trans("Categories");
1212 if ($action != 'categories' && !$user->socid) {
1213 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>';
1214 }
1215 print '</table>';
1216 print '</td>';
1217
1218 if ($user->hasRight('ticket', 'write') && $action == 'categories') {
1219 $cate_arbo = $form->select_all_categories(Categorie::TYPE_TICKET, '', 'parent', 64, 0, 1);
1220 if (is_array($cate_arbo)) {
1221 // Categories
1222 print '<td colspan="3">';
1223 print '<form action="'.$url_page_current.'" method="post">';
1224 print '<input type="hidden" name="token" value="'.newToken().'">';
1225 print '<input type="hidden" name="track_id" value="'.$track_id.'">';
1226 print '<input type="hidden" name="action" value="set_categories">';
1227
1228 $category = new Categorie($db);
1229 $cats = $category->containing($object->id, 'ticket');
1230 $arrayselected = array();
1231 foreach ($cats as $cat) {
1232 $arrayselected[] = $cat->id;
1233 }
1234
1235 print img_picto('', 'category', 'class="pictofixedwidth"').$form->multiselectarray('categories', $cate_arbo, $arrayselected, '', 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0);
1236 print '<input type="submit" class="button button-edit small" value="'.$langs->trans('Save').'">';
1237 print '</form>';
1238 print "</td>";
1239 }
1240 } else {
1241 print '<td colspan="3">';
1242 print $form->showCategories($object->id, Categorie::TYPE_TICKET, 1);
1243 print "</td></tr>";
1244 }
1245
1246 print '</table>';
1247 }
1248
1249 // View Original message
1250 $actionobject->viewTicketOriginalMessage($user, $action, $object);
1251
1252 // Classification of ticket
1253 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
1254 print '<table class="noborder tableforfield centpercent margintable">';
1255 print '<tr class="liste_titre">';
1256 print '<td>';
1257 print $langs->trans('TicketProperties');
1258 print '</td>';
1259 print '<td>';
1260 if (GETPOST('set', 'alpha') == 'properties' && $user->hasRight('ticket', 'write')) {
1261 print '<input type="submit" class="button small" name="btn_update_ticket_prop" value="'.$langs->trans("Modify").'" />';
1262 } else {
1263 // Button to edit Properties
1264 if (isset($object->status) && ($object->status < $object::STATUS_NEED_MORE_INFO || getDolGlobalString('TICKET_ALLOW_CLASSIFICATION_MODIFICATION_EVEN_IF_CLOSED')) && $user->hasRight('ticket', 'write')) {
1265 print ' <a class="editfielda" href="card.php?track_id='.$object->track_id.'&set=properties">'.img_edit($langs->trans('Modify')).'</a>';
1266 }
1267 }
1268 print '</td>';
1269 print '</tr>';
1270
1271 if (GETPOST('set', 'alpha') == 'properties' && $user->hasRight('ticket', 'write')) {
1272 print '<tr>';
1273 // Type
1274 print '<td class="titlefield">';
1275 print $langs->trans('Type');
1276 print '</td><td>';
1277 $formticket->selectTypesTickets($object->type_code, 'update_value_type', '', 2);
1278 print '</td>';
1279 print '</tr>';
1280 // Group
1281 print '<tr>';
1282 print '<td>';
1283 print $langs->trans('TicketCategory');
1284 print '</td><td>';
1285 $formticket->selectGroupTickets($object->category_code, 'update_value_category', '', 2, 0, 0, 0, 'maxwidth500 widthcentpercentminusxx');
1286 print '</td>';
1287 print '</tr>';
1288 // Severity
1289 print '<tr>';
1290 print '<td>';
1291 print $langs->trans('TicketSeverity');
1292 print '</td><td>';
1293 $formticket->selectSeveritiesTickets($object->severity_code, 'update_value_severity', '', 2);
1294 print '</td>';
1295 print '</tr>';
1296 } else {
1297 // Type
1298 print '<tr><td class="titlefield">'.$langs->trans("Type").'</td><td>';
1299 if (!empty($object->type_code)) {
1300 print $langs->getLabelFromKey($db, 'TicketTypeShort'.$object->type_code, 'c_ticket_type', 'code', 'label', $object->type_code);
1301 }
1302 print '</td></tr>';
1303 // Group
1304 $s = '';
1305 if (!empty($object->category_code)) {
1306 $s = $langs->getLabelFromKey($db, 'TicketCategoryShort'.$object->category_code, 'c_ticket_category', 'code', 'label', $object->category_code);
1307 }
1308 print '<tr><td>'.$langs->trans("TicketCategory").'</td><td class="tdoverflowmax200" title="'.dol_escape_htmltag($s).'">';
1309 print dol_escape_htmltag($s);
1310 print '</td></tr>';
1311 // Severity
1312 print '<tr><td>'.$langs->trans("TicketSeverity").'</td><td>';
1313 if (!empty($object->severity_code)) {
1314 print $langs->getLabelFromKey($db, 'TicketSeverityShort'.$object->severity_code, 'c_ticket_severity', 'code', 'label', $object->severity_code);
1315 }
1316 print '</td></tr>';
1317 }
1318 print '</table>'; // End table actions
1319 print '</div>';
1320
1321 print '</form>';
1322
1323 // Display navbar with links to change ticket status
1324 print '<!-- navbar with status -->';
1325 if (!$user->socid && $user->hasRight('ticket', 'write') && isset($object->status) && $object->status < $object::STATUS_CLOSED && GETPOST('set') !== 'properties') {
1326 $actionobject->viewStatusActions($object);
1327 }
1328
1329
1330 if (getDolGlobalString('MAIN_DISABLE_CONTACTS_TAB')) {
1331 print load_fiche_titre($langs->trans('Contacts'), '', 'title_companies.png');
1332
1333 print '<div class="div-table-responsive-no-min">';
1334 print '<div class="tagtable centpercent noborder allwidth">';
1335
1336 print '<div class="tagtr liste_titre">';
1337 print '<div class="tagtd">'.$langs->trans("Source").'</div>
1338 <div class="tagtd">' . $langs->trans("Company").'</div>
1339 <div class="tagtd">' . $langs->trans("Contacts").'</div>
1340 <div class="tagtd">' . $langs->trans("ContactType").'</div>
1341 <div class="tagtd">' . $langs->trans("Phone").'</div>
1342 <div class="tagtd center">' . $langs->trans("Status").'</div>';
1343 print '</div><!-- tagtr -->';
1344
1345 // Contact list
1346 $companystatic = new Societe($db);
1347 $contactstatic = new Contact($db);
1348 $userstatic = new User($db);
1349 $var = false;
1350 foreach (array('internal', 'external') as $source) {
1351 $tmpobject = $object;
1352 $tab = $tmpobject->listeContact(-1, $source);
1353 $num = count($tab);
1354 $i = 0;
1355 while ($i < $num) {
1356 $var = !$var;
1357 print '<div class="tagtr '.($var ? 'pair' : 'impair').'">';
1358
1359 print '<div class="tagtd left">';
1360 if ($tab[$i]['source'] == 'internal') {
1361 echo $langs->trans("User");
1362 }
1363
1364 if ($tab[$i]['source'] == 'external') {
1365 echo $langs->trans("ThirdPartyContact");
1366 }
1367
1368 print '</div>';
1369 print '<div class="tagtd left">';
1370
1371 if ($tab[$i]['socid'] > 0) {
1372 $companystatic->fetch($tab[$i]['socid']);
1373 echo $companystatic->getNomUrl(-1);
1374 }
1375 if ($tab[$i]['socid'] < 0) {
1376 echo getDolGlobalString('MAIN_INFO_SOCIETE_NOM');
1377 }
1378 if (!$tab[$i]['socid']) {
1379 echo '&nbsp;';
1380 }
1381 print '</div>';
1382
1383 print '<div class="tagtd">';
1384 if ($tab[$i]['source'] == 'internal') {
1385 if ($userstatic->fetch($tab[$i]['id'])) {
1386 print $userstatic->getNomUrl(-1);
1387 }
1388 }
1389 if ($tab[$i]['source'] == 'external') {
1390 if ($contactstatic->fetch($tab[$i]['id'])) {
1391 print $contactstatic->getNomUrl(-1);
1392 }
1393 }
1394 print ' </div>
1395 <div class="tagtd">' . $tab[$i]['libelle'].'</div>';
1396
1397 print '<div class="tagtd">';
1398
1399 print dol_print_phone($tab[$i]['phone'], '', '', '', 'AC_TEL').'<br>';
1400
1401 if (!empty($tab[$i]['phone_perso'])) {
1402 //print img_picto($langs->trans('PhonePerso'),'object_phoning.png','',0,0,0).' ';
1403 print '<br>'.dol_print_phone($tab[$i]['phone_perso'], '', '', '', 'AC_TEL').'<br>';
1404 }
1405 if (!empty($tab[$i]['phone_mobile'])) {
1406 //print img_picto($langs->trans('PhoneMobile'),'object_phoning.png','',0,0,0).' ';
1407 print dol_print_phone($tab[$i]['phone_mobile'], '', '', '', 'AC_TEL').'<br>';
1408 }
1409 print '</div>';
1410
1411 print '<div class="tagtd center">';
1412 if ($object->status >= 0) {
1413 echo '<a href="contact.php?track_id='.$object->track_id.'&amp;action=swapstatut&amp;ligne='.$tab[$i]['rowid'].'">';
1414 }
1415
1416 if ($tab[$i]['source'] == 'internal') {
1417 $userstatic->id = $tab[$i]['id'];
1418 $userstatic->lastname = $tab[$i]['lastname'];
1419 $userstatic->firstname = $tab[$i]['firstname'];
1420 echo $userstatic->LibStatut($tab[$i]['statuscontact'], 3);
1421 }
1422 if ($tab[$i]['source'] == 'external') {
1423 $contactstatic->id = $tab[$i]['id'];
1424 $contactstatic->lastname = $tab[$i]['lastname'];
1425 $contactstatic->firstname = $tab[$i]['firstname'];
1426 echo $contactstatic->LibStatut($tab[$i]['statuscontact'], 3);
1427 }
1428 if ($object->status >= 0) {
1429 echo '</a>';
1430 }
1431
1432 print '</div>';
1433
1434 print '</div><!-- tagtr -->';
1435
1436 $i++;
1437 }
1438 }
1439
1440 print '</div><!-- contact list -->';
1441 print '</div>';
1442 }
1443
1444 print '</div></div>';
1445 print '<div class="clearboth"></div>';
1446
1447 print dol_get_fiche_end();
1448
1449
1450 // Buttons for actions
1451 if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'editline') {
1452 print '<div class="tabsAction">'."\n";
1453 $parameters = array();
1454 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
1455 if ($reshook < 0) {
1456 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1457 }
1458
1459 if (empty($reshook)) {
1460 // Email
1461 if (isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") {
1462 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', '');
1463 }
1464
1465 // Show link to add a message (if read and not closed)
1466 if (isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage") {
1467 print dolGetButtonAction('', $langs->trans('TicketAddPrivateMessage'), 'default', $_SERVER["PHP_SELF"].'?action=presend_addmessage&mode=init&token='.newToken().'&track_id='.$object->track_id.'#formmailbeforetitle', '');
1468 }
1469
1470 // Link to create an intervention
1471 // socid is needed otherwise fichinter ask it and forgot origin after form submit :\
1472 if (!$object->fk_soc && $user->hasRight("ficheinter", "creer")) {
1473 print dolGetButtonAction($langs->trans('UnableToCreateInterIfNoSocid'), $langs->trans('TicketAddIntervention'), 'default', $_SERVER['PHP_SELF']. '#', '', false);
1474 }
1475 if ($object->fk_soc > 0 && isset($object->status) && $object->status < Ticket::STATUS_CLOSED && $user->hasRight('ficheinter', 'creer')) {
1476 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, '');
1477 }
1478
1479 // Close 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('CloseTicket'), 'default', $_SERVER["PHP_SELF"].'?action=close&token='.newToken().'&track_id='.$object->track_id, '');
1482 }
1483
1484 // Abandon ticket if status is read
1485 if (isset($object->status) && $object->status > 0 && $object->status < Ticket::STATUS_CLOSED && $user->hasRight('ticket', 'write')) {
1486 print dolGetButtonAction('', $langs->trans('AbandonTicket'), 'default', $_SERVER["PHP_SELF"].'?action=abandon&token='.newToken().'&track_id='.$object->track_id, '');
1487 }
1488
1489 // Re-open ticket
1490 if (!$user->socid && (isset($object->status) && ($object->status == Ticket::STATUS_CLOSED || $object->status == Ticket::STATUS_CANCELED)) && !$user->socid) {
1491 print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&track_id='.$object->track_id, '');
1492 }
1493
1494 // Delete ticket
1495 if ($user->hasRight('ticket', 'delete') && !$user->socid) {
1496 print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&track_id='.$object->track_id, '');
1497 }
1498 }
1499 print '</div>'."\n";
1500 } else {
1501 //print '<br>';
1502 }
1503
1504 // Select mail models is same action as presend
1505 if (GETPOST('modelselected')) {
1506 $action = 'presend';
1507 }
1508 // Set $action to correct value for the case we used presend action to add a message
1509 if (GETPOSTISSET('actionbis') && $action == 'presend') {
1510 $action = 'presend_addmessage';
1511 }
1512
1513 // add a message
1514 if ($action == 'presend' || $action == 'presend_addmessage') {
1515 if ($object->fk_soc > 0) {
1516 $object->fetch_thirdparty();
1517 }
1518
1519 $outputlangs = $langs;
1520 $newlang = '';
1521 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && GETPOST('lang_id', 'aZ09')) {
1522 $newlang = GETPOST('lang_id', 'aZ09');
1523 } elseif (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang) && is_object($object->thirdparty)) {
1524 $newlang = $object->thirdparty->default_lang;
1525 }
1526 if (!empty($newlang)) {
1527 $outputlangs = new Translate("", $conf);
1528 $outputlangs->setDefaultLang($newlang);
1529 }
1530
1531 $arrayoffamiliestoexclude = array('objectamount');
1532
1533 $action = 'add_message'; // action to use to post the message
1534 $modelmail = 'ticket_send';
1535
1536 // Substitution array
1537 $morehtmlright = '';
1538 $help = "";
1539 $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, $arrayoffamiliestoexclude, $object);
1540 $morehtmlright .= $form->textwithpicto('<span class="opacitymedium">'.$langs->trans("TicketMessageSubstitutionReplacedByGenericValues").'</span>', $help, 1, 'helpclickable', '', 0, 3, 'helpsubstitution');
1541
1542 print '<div>';
1543
1544 print '<div id="formmailbeforetitle" name="formmailbeforetitle"></div>';
1545
1546 print load_fiche_titre($langs->trans('TicketAddMessage'), $morehtmlright, 'messages@ticket');
1547
1548 print '<hr>';
1549
1550 $formticket = new FormTicket($db);
1551
1552 $formticket->action = $action;
1553 $formticket->track_id = $object->track_id;
1554 $formticket->ref = $object->ref;
1555 $formticket->id = $object->id;
1556 $formticket->trackid = 'tic'.$object->id;
1557
1558 $formticket->withfile = 2;
1559 $formticket->withcancel = 1;
1560 $formticket->param = array('fk_user_create' => $user->id);
1561 $formticket->param['langsmodels'] = (empty($newlang) ? $langs->defaultlang : $newlang);
1562
1563 // Table of additional post parameters
1564 $formticket->param['models'] = $modelmail;
1565 $formticket->param['models_id'] = GETPOST('modelmailselected', 'int');
1566 //$formticket->param['socid']=$object->fk_soc;
1567 $formticket->param['returnurl'] = $_SERVER["PHP_SELF"].'?track_id='.$object->track_id;
1568
1569 $formticket->withsubstit = 1;
1570 $formticket->substit = $substitutionarray;
1571 $formticket->backtopage = $backtopage;
1572
1573 $formticket->showMessageForm('100%');
1574 print '</div>';
1575 }
1576
1577 // Show messages on card (Note: this is a duplicate of the view Events/Agenda but on the main tab)
1578 if (getDolGlobalString('TICKET_SHOW_MESSAGES_ON_CARD')) {
1579 $param = '&id='.$object->id;
1580 if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) {
1581 $param .= '&contextpage='.$contextpage;
1582 }
1583 if ($limit > 0 && $limit != $conf->liste_limit) {
1584 $param .= '&limit='.$limit;
1585 }
1586 if ($actioncode) {
1587 $param .= '&actioncode='.urlencode($actioncode);
1588 }
1589 if ($search_agenda_label) {
1590 $param .= '&search_agenda_label='.urlencode($search_agenda_label);
1591 }
1592
1593 $morehtmlright = '';
1594
1595 $messagingUrl = DOL_URL_ROOT.'/ticket/agenda.php?track_id='.$object->track_id;
1596 $morehtmlright .= dolGetButtonTitle($langs->trans('MessageListViewType'), '', 'fa fa-bars imgforviewmode', $messagingUrl, '', 1);
1597
1598 // Show link to add a message (if read and not closed)
1599 $btnstatus = $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage" && $action != "add_message";
1600 $url = 'card.php?track_id='.$object->track_id.'&action=presend_addmessage&mode=init';
1601 $morehtmlright .= dolGetButtonTitle($langs->trans('TicketAddMessage'), '', 'fa fa-comment-dots', $url, 'add-new-ticket-title-button', $btnstatus);
1602
1603 // Show link to add event (if read and not closed)
1604 $btnstatus = $object->status < Ticket::STATUS_CLOSED && $action != "presend" && $action != "presend_addmessage" && $action != "add_message";
1605 $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);
1606 $morehtmlright .= dolGetButtonTitle($langs->trans('AddAction'), '', 'fa fa-plus-circle', $url, 'add-new-ticket-even-button', $btnstatus);
1607
1608 print_barre_liste($langs->trans("ActionsOnTicket"), 0, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', 0, -1, '', 0, $morehtmlright, '', 0, 1, 1);
1609
1610 // List of all actions
1611 $filters = array();
1612 $filters['search_agenda_label'] = $search_agenda_label;
1613 $filters['search_rowid'] = $search_rowid;
1614
1615 show_actions_messaging($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder);
1616 }
1617
1618 if ($action != 'presend' && $action != 'presend_addmessage' && $action != 'add_message') {
1619 print '<div class="fichecenter"><div class="fichehalfleft">';
1620 print '<a name="builddoc"></a>'; // ancre
1621
1622 // Show links to link elements
1623 $linktoelem = $form->showLinkToObjectBlock($object, null, array('ticket'));
1624 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem);
1625
1626 // Show direct link to public interface
1627 print '<br><!-- Link to public interface -->'."\n";
1628 print showDirectPublicLink($object).'<br>';
1629 print '</div>';
1630
1631 if (getDolGlobalString('TICKET_SHOW_MESSAGES_ON_CARD')) {
1632 print '<div class="fichehalfright">';
1633
1634 $MAXEVENT = 10;
1635
1636 $morehtmlcenter = '<div class="nowraponall">';
1637 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullConversation'), '', 'fa fa-comments imgforviewmode', DOL_URL_ROOT.'/ticket/messaging.php?id='.$object->id);
1638 $morehtmlcenter .= dolGetButtonTitle($langs->trans('FullList'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/ticket/agenda.php?id='.$object->id);
1639 $morehtmlcenter .= '</div>';
1640
1641 // List of actions on element
1642 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1643 $formactions = new FormActions($db);
1644 $somethingshown = $formactions->showactions($object, 'ticket', $socid, 1, 'listactions', $MAXEVENT, '', $morehtmlcenter);
1645
1646 print '</div>';
1647 }
1648
1649 print '</div>';
1650 }
1651 }
1652}
1653
1654// End of page
1655llxFooter();
1656$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.
GETPOSTINT($paramname, $method=0)
Return value of a param into GET or POST supervariable.
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:587
showDirectPublicLink($object)
Return string with full Url.
ticket_prepare_head($object)
Build tabs for a Ticket object.