28 require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobject.class.php";
29 require_once DOL_DOCUMENT_ROOT.
'/fichinter/class/fichinter.class.php';
30 require_once DOL_DOCUMENT_ROOT.
'/core/lib/ticket.lib.php';
41 public $element =
'ticket';
46 public $table_element =
'ticket';
51 public $fk_element =
'fk_ticket';
56 public $ismultientitymanaged = 1;
61 public $isextrafieldmanaged = 1;
66 public $picto =
'ticket';
92 public $fk_user_create;
97 public $fk_user_assign;
144 public $category_code;
149 public $severity_code;
179 public $date_read =
'';
184 public $date_last_msg_sent =
'';
189 public $date_close =
'';
194 public $cache_types_tickets;
199 public $cache_category_tickets;
204 public $cache_severity_tickets;
209 public $cache_msgs_ticket;
219 public $statuts_short;
224 public $notify_tiers_at_create;
255 public $regeximgext =
'\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm';
261 const STATUS_READ = 1;
262 const STATUS_ASSIGNED = 2;
263 const STATUS_IN_PROGRESS = 3;
264 const STATUS_NEED_MORE_INFO = 5;
265 const STATUS_WAITING = 7;
266 const STATUS_CLOSED = 8;
267 const STATUS_CANCELED = 9;
298 'rowid' => array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'visible'=>-2,
'enabled'=>1,
'position'=>1,
'notnull'=>1,
'index'=>1,
'comment'=>
"Id"),
299 'entity' => array(
'type'=>
'integer',
'label'=>
'Entity',
'visible'=>0,
'enabled'=>1,
'position'=>5,
'notnull'=>1,
'index'=>1),
300 'ref' => array(
'type'=>
'varchar(128)',
'label'=>
'Ref',
'visible'=>1,
'enabled'=>1,
'position'=>10,
'notnull'=>1,
'index'=>1,
'searchall'=>1,
'comment'=>
"Reference of object",
'css'=>
'',
'showoncombobox'=>1),
301 'track_id' => array(
'type'=>
'varchar(255)',
'label'=>
'TicketTrackId',
'visible'=>-2,
'enabled'=>1,
'position'=>11,
'notnull'=>-1,
'searchall'=>1,
'help'=>
"Help text"),
302 'fk_user_create' => array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'Author',
'visible'=>1,
'enabled'=>1,
'position'=>15,
'notnull'=>1,
'csslist'=>
'tdoverflowmax100 maxwidth150onsmartphone'),
303 'origin_email' => array(
'type'=>
'mail',
'label'=>
'OriginEmail',
'visible'=>-2,
'enabled'=>1,
'position'=>16,
'notnull'=>1,
'index'=>1,
'searchall'=>1,
'comment'=>
"Reference of object",
'csslist'=>
'tdoverflowmax150'),
304 'subject' => array(
'type'=>
'varchar(255)',
'label'=>
'Subject',
'visible'=>1,
'enabled'=>1,
'position'=>18,
'notnull'=>-1,
'searchall'=>1,
'help'=>
"",
'css'=>
'maxwidth200 tdoverflowmax200',
'autofocusoncreate'=>1),
305 'type_code' => array(
'type'=>
'varchar(32)',
'label'=>
'Type',
'visible'=>1,
'enabled'=>1,
'position'=>20,
'notnull'=>-1,
'help'=>
"",
'csslist'=>
'maxwidth125 tdoverflowmax50'),
306 'category_code' => array(
'type'=>
'varchar(32)',
'label'=>
'TicketCategory',
'visible'=>-1,
'enabled'=>1,
'position'=>21,
'notnull'=>-1,
'help'=>
"",
'css'=>
'maxwidth100 tdoverflowmax200'),
307 'severity_code' => array(
'type'=>
'varchar(32)',
'label'=>
'Severity',
'visible'=>1,
'enabled'=>1,
'position'=>22,
'notnull'=>-1,
'help'=>
"",
'css'=>
'maxwidth100'),
308 'fk_soc' => array(
'type'=>
'integer:Societe:societe/class/societe.class.php',
'label'=>
'ThirdParty',
'visible'=>1,
'enabled'=>
'isModEnabled("societe")',
'position'=>50,
'notnull'=>-1,
'index'=>1,
'searchall'=>1,
'help'=>
"OrganizationEventLinkToThirdParty",
'css'=>
'tdoverflowmax150 maxwidth150onsmartphone'),
309 'notify_tiers_at_create' => array(
'type'=>
'integer',
'label'=>
'NotifyThirdparty',
'visible'=>-1,
'enabled'=>0,
'position'=>51,
'notnull'=>1,
'index'=>1),
310 'fk_project' => array(
'type'=>
'integer:Project:projet/class/project.class.php',
'label'=>
'Project',
'visible'=>-1,
'enabled'=>
'$conf->project->enabled',
'position'=>52,
'notnull'=>-1,
'index'=>1,
'help'=>
"LinkToProject"),
312 'datec' => array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'visible'=>1,
'enabled'=>1,
'position'=>500,
'notnull'=>1,
'csslist'=>
'nowraponall'),
313 'date_read' => array(
'type'=>
'datetime',
'label'=>
'TicketReadOn',
'visible'=>-1,
'enabled'=>1,
'position'=>501,
'notnull'=>1),
314 'date_last_msg_sent' => array(
'type'=>
'datetime',
'label'=>
'TicketLastMessageDate',
'visible'=>0,
'enabled'=>1,
'position'=>502,
'notnull'=>-1),
315 'fk_user_assign' => array(
'type'=>
'integer:User:user/class/user.class.php',
'label'=>
'AssignedTo',
'visible'=>1,
'enabled'=>1,
'position'=>505,
'notnull'=>1,
'csslist'=>
'tdoverflowmax100 maxwidth150onsmartphone'),
316 'date_close' => array(
'type'=>
'datetime',
'label'=>
'TicketCloseOn',
'visible'=>-1,
'enabled'=>1,
'position'=>510,
'notnull'=>1),
317 'tms' => array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'visible'=>-1,
'enabled'=>1,
'position'=>520,
'notnull'=>1),
318 'message' => array(
'type'=>
'html',
'label'=>
'Message',
'visible'=>-2,
'enabled'=>1,
'position'=>540,
'notnull'=>-1,),
319 'email_msgid' => array(
'type'=>
'varchar(255)',
'label'=>
'EmailMsgID',
'visible'=>-2,
'enabled'=>1,
'position'=>540,
'notnull'=>-1,
'help'=>
'EmailMsgIDDesc',
'csslist'=>
'tdoverflowmax100'),
320 'email_date' => array(
'type'=>
'datetime',
'label'=>
'EmailDate',
'visible'=>-2,
'enabled'=>1,
'position'=>541),
321 'progress' => array(
'type'=>
'integer',
'label'=>
'Progression',
'visible'=>-1,
'enabled'=>1,
'position'=>540,
'notnull'=>-1,
'css'=>
'right',
'help'=>
"",
'isameasure'=>2,
'csslist'=>
'width50'),
322 'resolution' => array(
'type'=>
'integer',
'label'=>
'Resolution',
'visible'=>-1,
'enabled'=>
'getDolGlobalString("TICKET_ENABLE_RESOLUTION")',
'position'=>550,
'notnull'=>1),
323 'fk_statut' => array(
'type'=>
'integer',
'label'=>
'Status',
'visible'=>1,
'enabled'=>1,
'position'=>600,
'notnull'=>1,
'index'=>1,
'arrayofkeyval'=>array(0 =>
'Unread', 1 =>
'Read', 3 =>
'Answered', 4 =>
'Assigned', 5 =>
'InProgress', 6 =>
'Waiting', 8 =>
'SolvedClosed', 9 =>
'Deleted')),
324 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
340 $this->statuts_short = array(
341 self::STATUS_NOT_READ =>
'Unread',
342 self::STATUS_READ =>
'Read',
343 self::STATUS_ASSIGNED =>
'Assigned',
344 self::STATUS_IN_PROGRESS =>
'InProgress',
345 self::STATUS_WAITING =>
'OnHold',
346 self::STATUS_NEED_MORE_INFO =>
'NeedMoreInformationShort',
347 self::STATUS_CLOSED =>
'SolvedClosed',
348 self::STATUS_CANCELED =>
'Canceled'
350 $this->statuts = array(
351 self::STATUS_NOT_READ =>
'Unread',
352 self::STATUS_READ =>
'Read',
353 self::STATUS_ASSIGNED =>
'Assigned',
354 self::STATUS_IN_PROGRESS =>
'InProgress',
355 self::STATUS_WAITING =>
'OnHold',
356 self::STATUS_NEED_MORE_INFO =>
'NeedMoreInformation',
357 self::STATUS_CLOSED =>
'SolvedClosed',
358 self::STATUS_CANCELED =>
'Canceled'
370 $this->errors = array();
375 if (isset($this->
ref)) {
376 $this->
ref = trim($this->
ref);
379 if (isset($this->track_id)) {
380 $this->track_id = trim($this->track_id);
383 if (isset($this->fk_soc)) {
384 $this->fk_soc = (int) $this->fk_soc;
387 if (isset($this->fk_project)) {
388 $this->fk_project = (int) $this->fk_project;
391 if (isset($this->origin_email)) {
392 $this->origin_email = trim($this->origin_email);
395 if (isset($this->fk_user_create)) {
396 $this->fk_user_create = (int) $this->fk_user_create;
399 if (isset($this->fk_user_assign)) {
400 $this->fk_user_assign = (int) $this->fk_user_assign;
403 if (isset($this->subject)) {
404 $this->subject = trim($this->subject);
407 if (isset($this->message)) {
408 $this->message = trim($this->message);
410 $this->errors[] =
'ErrorFieldTooLong';
411 dol_syslog(get_class($this).
'::create error -1 message too long', LOG_ERR);
416 if (isset($this->fk_statut)) {
417 $this->fk_statut = (int) $this->fk_statut;
420 if (isset($this->resolution)) {
421 $this->resolution = trim($this->resolution);
424 if (isset($this->progress)) {
425 $this->progress = trim($this->progress);
428 if (isset($this->timing)) {
429 $this->timing = trim($this->timing);
432 if (isset($this->type_code)) {
433 $this->type_code = trim($this->type_code);
436 if (isset($this->category_code)) {
437 $this->category_code = trim($this->category_code);
440 if (isset($this->severity_code)) {
441 $this->severity_code = trim($this->severity_code);
444 if (empty($this->
ref)) {
445 $this->errors[] =
'ErrorTicketRefRequired';
446 dol_syslog(get_class($this).
"::create error -1 ref null", LOG_ERR);
460 public function create($user, $notrigger = 0)
462 global $conf, $langs;
467 if (empty($this->track_id)) {
473 $result = $this->
verify();
477 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"ticket(";
481 $sql .=
"fk_project,";
482 $sql .=
"origin_email,";
483 $sql .=
"fk_user_create,";
484 $sql .=
"fk_user_assign,";
485 $sql .=
"email_msgid,";
486 $sql .=
"email_date,";
489 $sql .=
"fk_statut,";
490 $sql .=
"resolution,";
493 $sql .=
"type_code,";
494 $sql .=
"category_code,";
495 $sql .=
"severity_code,";
497 $sql .=
"date_read,";
498 $sql .=
"date_close,";
500 $sql .=
"notify_tiers_at_create,";
502 $sql .=
") VALUES (";
503 $sql .=
" ".(!isset($this->
ref) ?
'' :
"'".$this->db->escape($this->
ref).
"'").
",";
504 $sql .=
" ".(!isset($this->track_id) ?
'NULL' :
"'".$this->db->escape($this->track_id).
"'").
",";
505 $sql .=
" ".($this->fk_soc > 0 ? $this->db->escape($this->fk_soc) :
"null").
",";
506 $sql .=
" ".($this->fk_project > 0 ? $this->db->escape($this->fk_project) :
"null").
",";
507 $sql .=
" ".(!isset($this->origin_email) ?
'NULL' :
"'".$this->db->escape($this->origin_email).
"'").
",";
508 $sql .=
" ".(!isset($this->fk_user_create) ? ($user->id > 0 ? $user->id :
'NULL') : ($this->fk_user_create > 0 ? $this->fk_user_create :
'NULL')).
",";
509 $sql .=
" ".($this->fk_user_assign > 0 ? $this->fk_user_assign :
'NULL').
",";
510 $sql .=
" ".(empty($this->email_msgid) ?
'NULL' :
"'".$this->db->escape($this->email_msgid).
"'").
",";
511 $sql .=
" ".(empty($this->email_date) ?
'NULL' :
"'".$this->db->idate($this->email_date).
"'").
",";
512 $sql .=
" ".(!isset($this->subject) ?
'NULL' :
"'".$this->db->escape($this->subject).
"'").
",";
513 $sql .=
" ".(!isset($this->message) ?
'NULL' :
"'".$this->db->escape($this->message).
"'").
",";
514 $sql .=
" ".(!isset($this->fk_statut) ?
'0' :
"'".$this->db->escape($this->fk_statut).
"'").
",";
515 $sql .=
" ".(!isset($this->resolution) ?
'NULL' :
"'".$this->db->escape($this->resolution).
"'").
",";
516 $sql .=
" ".(!isset($this->progress) ?
'0' :
"'".$this->db->escape($this->progress).
"'").
",";
517 $sql .=
" ".(!isset($this->timing) ?
'NULL' :
"'".$this->db->escape($this->timing).
"'").
",";
518 $sql .=
" ".(!isset($this->type_code) ?
'NULL' :
"'".$this->db->escape($this->type_code).
"'").
",";
519 $sql .=
" ".(empty($this->category_code) || $this->category_code ==
'-1' ?
'NULL' :
"'".$this->db->escape($this->category_code).
"'").
",";
520 $sql .=
" ".(!isset($this->severity_code) ?
'NULL' :
"'".$this->db->escape($this->severity_code).
"'").
",";
521 $sql .=
" ".(!isset($this->datec) ||
dol_strlen($this->datec) == 0 ?
'NULL' :
"'".$this->db->idate($this->datec).
"'").
",";
522 $sql .=
" ".(!isset($this->date_read) ||
dol_strlen($this->date_read) == 0 ?
'NULL' :
"'".$this->db->idate($this->date_read).
"'").
",";
523 $sql .=
" ".(!isset($this->date_close) ||
dol_strlen($this->date_close) == 0 ?
'NULL' :
"'".$this->db->idate($this->date_close).
"'");
524 $sql .=
", ".((int) $conf->entity);
525 $sql .=
", ".(!isset($this->notify_tiers_at_create) ?
'1' :
"'".$this->db->escape($this->notify_tiers_at_create).
"'");
526 $sql .=
", ".(!isset($this->ip) ?
'NULL' :
"'".$this->db->escape($this->ip).
"'");
531 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
532 $resql = $this->db->query(
$sql);
535 $this->errors[] =
"Error ".$this->db->lasterror();
539 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"ticket");
542 if (!$error && !empty($conf->global->TICKET_ADD_AUTHOR_AS_CONTACT)) {
544 if ($this->
add_contact($user->id,
'CONTRIBUTOR',
'internal') < 0) {
549 if (!$error && $this->fk_user_assign > 0) {
550 if ($this->
add_contact($this->fk_user_assign,
'SUPPORTTEC',
'internal') < 0) {
564 if (!$error && !$notrigger) {
575 foreach ($this->errors as $errmsg) {
576 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
577 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
579 $this->db->rollback();
586 $this->db->rollback();
587 dol_syslog(get_class($this).
"::Create fails verify ".join(
',', $this->errors), LOG_WARNING);
601 public function fetch($id =
'', $ref =
'', $track_id =
'', $email_msgid =
'')
606 if (empty($id) && empty($ref) && empty($track_id) && empty($email_msgid)) {
607 $this->error =
'ErrorWrongParameters';
614 $sql .=
" t.entity,";
616 $sql .=
" t.track_id,";
617 $sql .=
" t.fk_soc,";
618 $sql .=
" t.fk_project,";
619 $sql .=
" t.origin_email,";
620 $sql .=
" t.fk_user_create,";
621 $sql .=
" t.fk_user_assign,";
622 $sql .=
" t.email_msgid,";
623 $sql .=
" t.email_date,";
624 $sql .=
" t.subject,";
625 $sql .=
" t.message,";
626 $sql .=
" t.fk_statut as status,";
627 $sql .=
" t.resolution,";
628 $sql .=
" t.progress,";
629 $sql .=
" t.timing,";
630 $sql .=
" t.type_code,";
631 $sql .=
" t.category_code,";
632 $sql .=
" t.severity_code,";
634 $sql .=
" t.date_read,";
635 $sql .=
" t.date_last_msg_sent,";
636 $sql .=
" t.date_close,";
639 $sql .=
" type.label as type_label, category.label as category_label, severity.label as severity_label";
640 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as t";
641 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_type as type ON type.code=t.type_code";
642 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as category ON category.code=t.category_code";
643 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_severity as severity ON severity.code=t.severity_code";
646 $sql .=
" WHERE t.rowid = ".((int) $id);
648 $sql .=
" WHERE t.entity IN (".getEntity($this->element, 1).
")";
650 $sql .=
" AND t.ref = '".$this->db->escape($ref).
"'";
651 } elseif ($track_id) {
652 $sql .=
" AND t.track_id = '".$this->db->escape($track_id).
"'";
654 $sql .=
" AND t.email_msgid = '".$this->db->escape($email_msgid).
"'";
658 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
659 $resql = $this->db->query(
$sql);
661 if ($this->db->num_rows($resql)) {
662 $obj = $this->db->fetch_object($resql);
664 $this->
id = $obj->rowid;
665 $this->entity = $obj->entity;
666 $this->
ref = $obj->ref;
667 $this->track_id = $obj->track_id;
668 $this->fk_soc = $obj->fk_soc;
669 $this->socid = $obj->fk_soc;
670 $this->fk_project = $obj->fk_project;
671 $this->origin_email = $obj->origin_email;
672 $this->fk_user_create = $obj->fk_user_create;
673 $this->fk_user_assign = $obj->fk_user_assign;
674 $this->email_msgid = $obj->email_msgid;
675 $this->email_date = $this->db->jdate($obj->email_date);
676 $this->subject = $obj->subject;
677 $this->message = $obj->message;
678 $this->ip = $obj->ip;
680 $this->status = $obj->status;
681 $this->fk_statut = $this->status;
683 $this->resolution = $obj->resolution;
684 $this->progress = $obj->progress;
685 $this->timing = $obj->timing;
687 $this->type_code = $obj->type_code;
688 $label_type = ($langs->trans(
"TicketTypeShort".$obj->type_code) != (
"TicketTypeShort".$obj->type_code) ? $langs->trans(
"TicketTypeShort".$obj->type_code) : ($obj->type_label !=
'-' ? $obj->type_label :
''));
689 $this->type_label = $label_type;
691 $this->category_code = $obj->category_code;
692 $label_category = ($langs->trans(
"TicketCategoryShort".$obj->category_code) != (
"TicketCategoryShort".$obj->category_code) ? $langs->trans(
"TicketCategoryShort".$obj->category_code) : ($obj->category_label !=
'-' ? $obj->category_label :
''));
693 $this->category_label = $label_category;
695 $this->severity_code = $obj->severity_code;
696 $label_severity = ($langs->trans(
"TicketSeverityShort".$obj->severity_code) != (
"TicketSeverityShort".$obj->severity_code) ? $langs->trans(
"TicketSeverityShort".$obj->severity_code) : ($obj->severity_label !=
'-' ? $obj->severity_label :
''));
697 $this->severity_label = $label_severity;
699 $this->datec = $this->db->jdate($obj->datec);
700 $this->date_creation = $this->db->jdate($obj->datec);
701 $this->date_read = $this->db->jdate($obj->date_read);
702 $this->date_validation = $this->db->jdate($obj->date_read);
703 $this->date_last_msg_sent = $this->db->jdate($obj->date_last_msg_sent);
704 $this->date_close = $this->db->jdate($obj->date_close);
705 $this->tms = $this->db->jdate($obj->tms);
706 $this->date_modification = $this->db->jdate($obj->tms);
710 $this->db->free($resql);
716 $this->error =
"Error ".$this->db->lasterror();
717 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
735 public function fetchAll($user, $sortorder =
'ASC', $sortfield =
't.datec', $limit =
'', $offset = 0, $arch =
'', $filter =
'')
742 $extrafields->fetch_name_optionals_label($this->table_element);
747 $sql .=
" t.track_id,";
748 $sql .=
" t.fk_soc,";
749 $sql .=
" t.fk_project,";
750 $sql .=
" t.origin_email,";
751 $sql .=
" t.fk_user_create, uc.lastname as user_create_lastname, uc.firstname as user_create_firstname,";
752 $sql .=
" t.fk_user_assign, ua.lastname as user_assign_lastname, ua.firstname as user_assign_firstname,";
753 $sql .=
" t.subject,";
754 $sql .=
" t.message,";
755 $sql .=
" t.fk_statut,";
756 $sql .=
" t.resolution,";
757 $sql .=
" t.progress,";
758 $sql .=
" t.timing,";
759 $sql .=
" t.type_code,";
760 $sql .=
" t.category_code,";
761 $sql .=
" t.severity_code,";
763 $sql .=
" t.date_read,";
764 $sql .=
" t.date_last_msg_sent,";
765 $sql .=
" t.date_close,";
767 $sql .=
", type.label as type_label, category.label as category_label, severity.label as severity_label";
769 foreach ($extrafields->attributes[$this->table_element][
'label'] as $key => $val) {
770 $sql .= ($extrafields->attributes[$this->table_element][
'type'][$key] !=
'separate' ?
",ef.".$key.
" as options_".$key :
'');
772 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as t";
773 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_type as type ON type.code=t.type_code";
774 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as category ON category.code=t.category_code";
775 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_severity as severity ON severity.code=t.severity_code";
776 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON s.rowid=t.fk_soc";
777 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as uc ON uc.rowid=t.fk_user_create";
778 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as ua ON ua.rowid=t.fk_user_assign";
779 if (is_array($extrafields->attributes[$this->table_element][
'label']) && count($extrafields->attributes[$this->table_element][
'label'])) {
780 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"ticket_extrafields as ef on (t.rowid = ef.fk_object)";
782 if (empty($user->rights->societe->client->voir) && !$user->socid) {
783 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
786 $sql .=
" WHERE t.entity IN (".getEntity(
'ticket').
")";
789 if (!empty($filter)) {
790 foreach ($filter as $key => $value) {
791 if (strpos($key,
'date')) {
792 $sql .=
" AND ".$key.
" = '".$this->db->escape($value).
"'";
793 } elseif (($key ==
't.fk_user_assign') || ($key ==
't.type_code') || ($key ==
't.category_code') || ($key ==
't.severity_code') || ($key ==
't.fk_soc')) {
794 $sql .=
" AND ".$key.
" = '".$this->db->escape($value).
"'";
795 } elseif ($key ==
't.fk_statut') {
796 if (is_array($value) && count($value) > 0) {
797 $sql .=
" AND ".$key.
" IN (".$this->db->sanitize(implode(
',', $value)).
")";
799 $sql .=
" AND ".$key.
' = '.((int) $value);
802 $sql .=
" AND ".$key.
" LIKE '%".$this->db->escape($value).
"%'";
806 if (empty($user->rights->societe->client->voir) && !$user->socid) {
807 $sql .=
" AND t.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
808 } elseif ($user->socid) {
809 $sql .=
" AND t.fk_soc = ".((int) $user->socid);
812 $sql .= $this->db->order($sortfield, $sortorder);
813 if (!empty($limit)) {
814 $sql .= $this->db->plimit($limit + 1, $offset);
817 dol_syslog(get_class($this).
"::fetchAll", LOG_DEBUG);
818 $resql = $this->db->query(
$sql);
821 $this->lines = array();
823 $num = $this->db->num_rows($resql);
828 $obj = $this->db->fetch_object($resql);
832 $line->id = $obj->rowid;
833 $line->rowid = $obj->rowid;
834 $line->ref = $obj->ref;
835 $line->track_id = $obj->track_id;
836 $line->fk_soc = $obj->fk_soc;
837 $line->fk_project = $obj->fk_project;
838 $line->origin_email = $obj->origin_email;
840 $line->fk_user_create = $obj->fk_user_create;
841 $line->user_create_lastname = $obj->user_create_lastname;
842 $line->user_create_firstname = $obj->user_create_firstname;
844 $line->fk_user_assign = $obj->fk_user_assign;
845 $line->user_assign_lastname = $obj->user_assign_lastname;
846 $line->user_assign_firstname = $obj->user_assign_firstname;
848 $line->subject = $obj->subject;
849 $line->message = $obj->message;
850 $line->fk_statut = $obj->fk_statut;
851 $line->resolution = $obj->resolution;
852 $line->progress = $obj->progress;
853 $line->timing = $obj->timing;
855 $label_type = ($langs->trans(
"TicketTypeShort".$obj->type_code) != (
"TicketTypeShort".$obj->type_code) ? $langs->trans(
"TicketTypeShort".$obj->type_code) : ($obj->type_label !=
'-' ? $obj->type_label :
''));
856 $line->type_label = $label_type;
858 $this->category_code = $obj->category_code;
859 $label_category = ($langs->trans(
"TicketCategoryShort".$obj->category_code) != (
"TicketCategoryShort".$obj->category_code) ? $langs->trans(
"TicketCategoryShort".$obj->category_code) : ($obj->category_label !=
'-' ? $obj->category_label :
''));
860 $line->category_label = $label_category;
862 $this->severity_code = $obj->severity_code;
863 $label_severity = ($langs->trans(
"TicketSeverityShort".$obj->severity_code) != (
"TicketSeverityShort".$obj->severity_code) ? $langs->trans(
"TicketSeverityShort".$obj->severity_code) : ($obj->severity_label !=
'-' ? $obj->severity_label :
''));
864 $line->severity_label = $label_severity;
866 $line->datec = $this->db->jdate($obj->datec);
867 $line->date_read = $this->db->jdate($obj->date_read);
868 $line->date_last_msg_sent = $this->db->jdate($obj->date_last_msg_sent);
869 $line->date_close = $this->db->jdate($obj->date_close);
872 if (is_array($extrafields->attributes[$this->table_element][
'label']) && count($extrafields->attributes[$this->table_element][
'label'])) {
873 foreach ($extrafields->attributes[$this->table_element][
'label'] as $key => $val) {
874 $tmpkey =
'options_'.$key;
875 $line->{$tmpkey} = $obj->$tmpkey;
879 $this->lines[$i] = $line;
883 $this->db->free($resql);
886 $this->error =
"Error ".$this->db->lasterror();
887 dol_syslog(get_class($this).
"::fetchAll ".$this->error, LOG_ERR);
899 public function update($user = 0, $notrigger = 0)
901 global $conf, $langs, $hookmanager;
910 if (isset($this->
ref)) {
911 $this->
ref = trim($this->
ref);
914 if (isset($this->track_id)) {
915 $this->track_id = trim($this->track_id);
918 if (isset($this->fk_soc)) {
919 $this->fk_soc = (int) $this->fk_soc;
922 if (isset($this->fk_project)) {
923 $this->fk_project = (int) $this->fk_project;
926 if (isset($this->origin_email)) {
927 $this->origin_email = trim($this->origin_email);
930 if (isset($this->fk_user_create)) {
931 $this->fk_user_create = (int) $this->fk_user_create;
934 if (isset($this->fk_user_assign)) {
935 $this->fk_user_assign = (int) $this->fk_user_assign;
938 if (isset($this->subject)) {
939 $this->subject = trim($this->subject);
942 if (isset($this->message)) {
943 $this->message = trim($this->message);
945 $this->errors[] =
'ErrorFieldTooLong';
946 dol_syslog(get_class($this).
'::update error -1 message too long', LOG_ERR);
951 if (isset($this->fk_statut)) {
952 $this->fk_statut = (int) $this->fk_statut;
955 if (isset($this->resolution)) {
956 $this->resolution = trim($this->resolution);
959 if (isset($this->progress)) {
960 $this->progress = trim($this->progress);
963 if (isset($this->timing)) {
964 $this->timing = trim($this->timing);
967 if (isset($this->type_code)) {
968 $this->timing = trim($this->type_code);
971 if (isset($this->category_code)) {
972 $this->timing = trim($this->category_code);
975 if (isset($this->severity_code)) {
976 $this->timing = trim($this->severity_code);
982 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket SET";
983 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"").
",";
984 $sql .=
" track_id=".(isset($this->track_id) ?
"'".$this->db->escape($this->track_id).
"'" :
"null").
",";
985 $sql .=
" fk_soc=".(isset($this->fk_soc) ?
"'".$this->db->escape($this->fk_soc).
"'" :
"null").
",";
986 $sql .=
" fk_project=".(isset($this->fk_project) ?
"'".$this->db->escape($this->fk_project).
"'" :
"null").
",";
987 $sql .=
" origin_email=".(isset($this->origin_email) ?
"'".$this->db->escape($this->origin_email).
"'" :
"null").
",";
988 $sql .=
" fk_user_create=".(isset($this->fk_user_create) ? $this->fk_user_create :
"null").
",";
989 $sql .=
" fk_user_assign=".(isset($this->fk_user_assign) ? $this->fk_user_assign :
"null").
",";
990 $sql .=
" subject=".(isset($this->subject) ?
"'".$this->db->escape($this->subject).
"'" :
"null").
",";
991 $sql .=
" message=".(isset($this->message) ?
"'".$this->db->escape($this->message).
"'" :
"null").
",";
992 $sql .=
" fk_statut=".(isset($this->fk_statut) ? $this->fk_statut :
"null").
",";
993 $sql .=
" resolution=".(isset($this->resolution) ? $this->resolution :
"null").
",";
994 $sql .=
" progress=".(isset($this->progress) ?
"'".$this->db->escape($this->progress).
"'" :
"null").
",";
995 $sql .=
" timing=".(isset($this->timing) ?
"'".$this->db->escape($this->timing).
"'" :
"null").
",";
996 $sql .=
" type_code=".(isset($this->type_code) ?
"'".$this->db->escape($this->type_code).
"'" :
"null").
",";
997 $sql .=
" category_code=".(isset($this->category_code) ?
"'".$this->db->escape($this->category_code).
"'" :
"null").
",";
998 $sql .=
" severity_code=".(isset($this->severity_code) ?
"'".$this->db->escape($this->severity_code).
"'" :
"null").
",";
999 $sql .=
" datec=".(dol_strlen($this->datec) != 0 ?
"'".$this->db->idate($this->datec).
"'" :
'null').
",";
1000 $sql .=
" date_read=".(dol_strlen($this->date_read) != 0 ?
"'".$this->db->idate($this->date_read).
"'" :
'null').
",";
1001 $sql .=
" date_last_msg_sent=".(dol_strlen($this->date_last_msg_sent) != 0 ?
"'".$this->db->idate($this->date_last_msg_sent).
"'" :
'null').
",";
1002 $sql .=
" date_close=".(dol_strlen($this->date_close) != 0 ?
"'".$this->db->idate($this->date_close).
"'" :
'null');
1003 $sql .=
" WHERE rowid=".((int) $this->
id);
1007 $resql = $this->db->query(
$sql);
1010 $this->errors[] =
"Error ".$this->db->lasterror();
1015 $result = $this->insertExtraFields();
1021 if (!$error && !$notrigger) {
1023 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1032 foreach ($this->errors as $errmsg) {
1033 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1034 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1036 $this->db->rollback();
1039 $this->db->commit();
1051 public function delete($user, $notrigger = 0)
1053 global $conf, $langs;
1061 $result = $this->call_trigger(
'TICKET_DELETE', $user);
1071 $res = $this->delete_linked_contact();
1073 dol_syslog(get_class($this).
"::delete error", LOG_ERR);
1080 $res = $this->deleteObjectLinked();
1088 $result = $this->deleteExtraFields();
1091 dol_syslog(get_class($this).
"::delete error -3 ".$this->error, LOG_ERR);
1098 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"categorie_ticket";
1099 $sql .=
" WHERE fk_ticket = ".(int) $this->
id;
1101 $result = $this->db->query(
$sql);
1104 $this->errors[] = $this->db->lasterror();
1109 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"ticket";
1110 $sql .=
" WHERE rowid=".((int) $this->
id);
1113 $resql = $this->db->query(
$sql);
1116 $this->errors[] =
"Error ".$this->db->lasterror();
1122 foreach ($this->errors as $errmsg) {
1123 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
1124 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1126 $this->db->rollback();
1129 $this->db->commit();
1145 $object =
new Ticket($this->db);
1150 $object->fetch($fromid);
1152 $object->statut = 0;
1157 $object->context[
'createfromclone'] =
'createfromclone';
1158 $result = $object->create($user);
1162 $this->error = $object->error;
1169 unset($object->context[
'createfromclone']);
1173 $this->db->commit();
1176 $this->db->rollback();
1191 $this->
ref =
'TI0501-001';
1192 $this->track_id =
'XXXXaaaa';
1193 $this->origin_email =
'email@email.com';
1194 $this->fk_project = 1;
1195 $this->fk_user_create = 1;
1196 $this->fk_user_assign = 1;
1197 $this->subject =
'Subject of ticket';
1198 $this->message =
'Message of ticket';
1200 $this->resolution =
'1';
1201 $this->progress =
'10';
1203 $this->type_code =
'TYPECODE';
1204 $this->category_code =
'CATEGORYCODE';
1205 $this->severity_code =
'SEVERITYCODE';
1207 $this->date_read =
'';
1208 $this->date_last_msg_sent =
'';
1209 $this->date_close =
'';
1222 print
Form::selectarray(
'search_fk_statut', $this->statuts_short, $selected, $show_empty = 1, $key_in_label = 0, $value_as_key = 0, $option =
'', $translate = 1, $maxlen = 0, $disabled = 0, $sort =
'', $morecss =
'');
1235 if (!empty($this->cache_types_tickets) && count($this->cache_types_tickets)) {
1240 $sql =
"SELECT rowid, code, label, use_default, pos, description";
1241 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_type";
1242 $sql .=
" WHERE active > 0";
1243 $sql .=
" ORDER BY pos";
1244 dol_syslog(get_class($this).
"::load_cache_type_tickets", LOG_DEBUG);
1245 $resql = $this->db->query(
$sql);
1247 $num = $this->db->num_rows($resql);
1250 $obj = $this->db->fetch_object($resql);
1251 $label = ($langs->trans(
"TicketTypeShort".$obj->code) != (
"TicketTypeShort".$obj->code) ? $langs->trans(
"TicketTypeShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1252 $this->cache_types_tickets[$obj->rowid][
'code'] = $obj->code;
1253 $this->cache_types_tickets[$obj->rowid][
'label'] = $label;
1254 $this->cache_types_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1255 $this->cache_types_tickets[$obj->rowid][
'pos'] = $obj->pos;
1273 global $conf, $langs;
1275 if ($publicgroup == -1 && !empty($this->cache_category_ticket) && count($this->cache_category_tickets)) {
1280 $sql =
"SELECT rowid, code, label, use_default, pos, description, public, active, force_severity, fk_parent";
1281 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_category";
1282 $sql .=
" WHERE active > 0 AND entity = ".((int) $conf->entity);
1283 if ($publicgroup > -1) {
1284 $sql .=
" AND public = ".((int) $publicgroup);
1286 $sql .=
" ORDER BY pos";
1288 dol_syslog(get_class($this).
"::load_cache_categories_tickets", LOG_DEBUG);
1290 $resql = $this->db->query(
$sql);
1292 $num = $this->db->num_rows($resql);
1295 $obj = $this->db->fetch_object($resql);
1296 $this->cache_category_tickets[$obj->rowid][
'code'] = $obj->code;
1297 $this->cache_category_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1298 $this->cache_category_tickets[$obj->rowid][
'pos'] = $obj->pos;
1299 $this->cache_category_tickets[$obj->rowid][
'public'] = $obj->public;
1300 $this->cache_category_tickets[$obj->rowid][
'active'] = $obj->active;
1301 $this->cache_category_tickets[$obj->rowid][
'force_severity'] = $obj->force_severity;
1302 $this->cache_category_tickets[$obj->rowid][
'fk_parent'] = $obj->fk_parent;
1306 $label = ($langs->trans(
"TicketCategoryShort".$obj->code) != (
"TicketCategoryShort".$obj->code) ? $langs->trans(
"TicketCategoryShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1307 $this->cache_category_tickets[$obj->rowid][
'label'] = $label;
1327 if (!empty($this->cache_severity_tickets) && count($this->cache_severity_tickets)) {
1332 $sql =
"SELECT rowid, code, label, use_default, pos, description";
1333 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_severity";
1334 $sql .=
" WHERE active > 0";
1335 $sql .=
" ORDER BY pos";
1336 dol_syslog(get_class($this).
"::loadCacheSeveritiesTickets", LOG_DEBUG);
1337 $resql = $this->db->query(
$sql);
1339 $num = $this->db->num_rows($resql);
1342 $obj = $this->db->fetch_object($resql);
1344 $this->cache_severity_tickets[$obj->rowid][
'code'] = $obj->code;
1345 $label = ($langs->trans(
"TicketSeverityShort".$obj->code) != (
"TicketSeverityShort".$obj->code) ? $langs->trans(
"TicketSeverityShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1346 $this->cache_severity_tickets[$obj->rowid][
'label'] = $label;
1347 $this->cache_severity_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1348 $this->cache_severity_tickets[$obj->rowid][
'pos'] = $obj->pos;
1367 return $this->libStatut($this->fk_statut, $mode, 0, $this->progress);
1381 public function LibStatut($status, $mode = 0, $notooltip = 0, $progress = 0)
1384 global $langs, $hookmanager;
1386 $labelStatus = $this->statuts[$status];
1387 $labelStatusShort = $this->statuts_short[$status];
1389 if ($status == self::STATUS_NOT_READ) {
1390 $statusType =
'status0';
1391 } elseif ($status == self::STATUS_READ) {
1392 $statusType =
'status1';
1393 } elseif ($status == self::STATUS_ASSIGNED) {
1394 $statusType =
'status2';
1395 } elseif ($status == self::STATUS_IN_PROGRESS) {
1396 $statusType =
'status4';
1397 } elseif ($status == self::STATUS_WAITING) {
1398 $statusType =
'status7';
1399 } elseif ($status == self::STATUS_NEED_MORE_INFO) {
1400 $statusType =
'status3';
1401 } elseif ($status == self::STATUS_CANCELED) {
1402 $statusType =
'status9';
1403 } elseif ($status == self::STATUS_CLOSED) {
1404 $statusType =
'status6';
1406 $labelStatus =
'Unknown';
1407 $labelStatusShort =
'Unknown';
1408 $statusType =
'status0';
1412 $parameters = array(
1413 'status' => $status,
1418 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
1421 return $hookmanager->resPrint;
1426 $params = array(
'tooltip' =>
'no');
1429 $labelStatus = $langs->transnoentitiesnoconv($labelStatus);
1430 $labelStatusShort = $langs->transnoentitiesnoconv($labelStatusShort);
1432 if ($status == self::STATUS_IN_PROGRESS && $progress > 0) {
1433 $labelStatus .=
' ('.round($progress).
'%)';
1434 $labelStatusShort .=
' ('.round($progress).
'%)';
1437 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode,
'', $params);
1451 $langs->load(
'ticket');
1452 $nofetch = !empty($params[
'nofetch']);
1455 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Ticket").
'</u>';
1456 $datas[
'picto'] .=
' '.$this->getLibStatut(4);
1457 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1458 $datas[
'track_id'] =
'<br><b>'.$langs->trans(
'TicketTrackId').
':</b> '.$this->track_id;
1459 $datas[
'subject'] =
'<br><b>'.$langs->trans(
'Subject').
':</b> '.$this->subject;
1460 if ($this->date_creation) {
1461 $datas[
'date_creation'] =
'<br><b>'.$langs->trans(
'DateCreation').
':</b> '.
dol_print_date($this->date_creation,
'dayhour');
1463 if ($this->date_modification) {
1464 $datas[
'date_modification'] =
'<br><b>'.$langs->trans(
'DateModification').
':</b> '.
dol_print_date($this->date_modification,
'dayhour');
1468 require_once DOL_DOCUMENT_ROOT .
'/categories/class/categorie.class.php';
1470 $datas[
'categories'] =
'<br>' .
$form->showCategories($this->
id, Categorie::TYPE_TICKET, 1);
1486 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
1488 global $db, $conf, $langs;
1489 global $dolibarr_main_authentication, $dolibarr_main_demo;
1490 global $menumanager;
1492 if (!empty($conf->dol_no_mouse_hover)) {
1500 'objecttype' => $this->element,
1501 'option' => $option,
1504 $classfortooltip =
'classfortooltip';
1507 $classfortooltip =
'classforajaxtooltip';
1508 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1511 $label = implode($this->getTooltipContentArray($params));
1514 $url = DOL_URL_ROOT.
'/ticket/card.php?id='.$this->id;
1516 if ($option !=
'nolink') {
1518 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1519 if ($save_lastsearch_value == -1 && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1520 $add_save_lastsearch_values = 1;
1522 if ($add_save_lastsearch_values) {
1523 $url .=
'&save_lastsearch_values=1';
1528 if (empty($notooltip)) {
1529 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1530 $label = $langs->trans(
"ShowTicket");
1531 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1533 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1534 $linkclose .= $dataparams.
' class="'.$classfortooltip.($morecss ?
' '.$morecss :
'').
'"';
1536 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1539 $linkstart =
'<a href="'.$url.
'"';
1540 $linkstart .= $linkclose.
'>';
1543 $result .= $linkstart;
1545 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), ($notooltip ? (($withpicto != 2) ?
'class="paddingright"' :
'') : $dataparams.
' class="'.(($withpicto != 2) ?
'paddingright ' :
'').$classfortooltip.
'"'), 0, 0, $notooltip ? 0 : 1);
1547 if ($withpicto != 2) {
1548 $result .= $this->ref;
1550 $result .= $linkend;
1570 if ($this->statut != self::STATUS_CANCELED) {
1575 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1576 $sql .=
" SET fk_statut = ".Ticket::STATUS_READ.
", date_read = '".$this->db->idate(
dol_now()).
"'";
1577 $sql .=
" WHERE rowid = ".((int) $this->
id);
1580 $resql = $this->db->query(
$sql);
1582 $this->actionmsg = $langs->trans(
'TicketLogMesgReadBy', $this->
ref, $user->getFullName($langs));
1583 $this->actionmsg2 = $langs->trans(
'TicketLogMesgReadBy', $this->
ref, $user->getFullName($langs));
1585 if (!$error && !$notrigger) {
1587 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1595 $this->db->commit();
1598 $this->db->rollback();
1599 $this->error = join(
',', $this->errors);
1600 dol_syslog(get_class($this).
"::markAsRead ".$this->error, LOG_ERR);
1604 $this->db->rollback();
1605 $this->error = $this->db->lasterror();
1606 dol_syslog(get_class($this).
"::markAsRead ".$this->error, LOG_ERR);
1622 public function assignUser($user, $id_assign_user, $notrigger = 0)
1624 global $conf, $langs;
1632 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1633 if ($id_assign_user > 0) {
1634 $sql .=
" SET fk_user_assign=".((int) $id_assign_user).
", fk_statut = ".Ticket::STATUS_ASSIGNED;
1636 $sql .=
" SET fk_user_assign=null, fk_statut = ".Ticket::STATUS_READ;
1638 $sql .=
" WHERE rowid = ".((int) $this->
id);
1641 $resql = $this->db->query(
$sql);
1643 $this->fk_user_assign = $id_assign_user;
1647 $result = $this->call_trigger(
'TICKET_ASSIGNED', $user);
1655 $this->db->commit();
1658 $this->db->rollback();
1659 $this->error = join(
',', $this->errors);
1660 dol_syslog(get_class($this).
"::assignUser ".$this->error, LOG_ERR);
1664 $this->db->rollback();
1665 $this->error = $this->db->lasterror();
1666 dol_syslog(get_class($this).
"::assignUser ".$this->error, LOG_ERR);
1682 public function createTicketMessage($user, $notrigger = 0, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $send_email =
false)
1684 global $conf, $langs;
1690 if (isset($this->fk_track_id)) {
1691 $this->fk_track_id = trim($this->fk_track_id);
1694 if (isset($this->message)) {
1695 $this->message = trim($this->message);
1701 include_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
1703 $actioncomm->type_code =
'AC_OTH_AUTO';
1704 $actioncomm->code =
'TICKET_MSG';
1705 if ($this->
private) {
1706 $actioncomm->code =
'TICKET_MSG_PRIVATE';
1709 $actioncomm->code .=
'_SENTBYMAIL';
1711 if ((empty($user->id) || $user->id == 0) && isset($_SESSION[
'email_customer'])) {
1712 $actioncomm->email_from = $_SESSION[
'email_customer'];
1714 $actioncomm->socid = $this->socid;
1715 $actioncomm->label = $this->subject;
1716 $actioncomm->note_private = $this->message;
1717 $actioncomm->userassigned = array($user->id);
1718 $actioncomm->userownerid = $user->id;
1719 $actioncomm->datep = $now;
1720 $actioncomm->percentage = -1;
1721 $actioncomm->elementtype =
'ticket';
1722 $actioncomm->fk_element = $this->id;
1723 $actioncomm->fk_project = $this->fk_project;
1725 $attachedfiles = array();
1726 $attachedfiles[
'paths'] = $filename_list;
1727 $attachedfiles[
'names'] = $mimefilename_list;
1728 $attachedfiles[
'mimes'] = $mimetype_list;
1729 if (is_array($attachedfiles) && count($attachedfiles) > 0) {
1730 $actioncomm->attachedfiles = $attachedfiles;
1733 if (!empty($mimefilename_list) && is_array($mimefilename_list)) {
1734 $actioncomm->note_private =
dol_concatdesc($actioncomm->note_private,
"\n".$langs->transnoentities(
"AttachedFiles").
': '.join(
';', $mimefilename_list));
1737 $actionid = $actioncomm->create($user);
1738 if ($actionid <= 0) {
1740 $this->error = $actioncomm->error;
1741 $this->errors = $actioncomm->errors;
1746 $this->db->rollback();
1749 $this->db->commit();
1761 if (!empty($this->cache_msgs_ticket) && is_array($this->cache_msgs_ticket) && count($this->cache_msgs_ticket)) {
1767 $sql =
"SELECT id as rowid, fk_user_author, email_from, datec, label, note as message, code";
1768 $sql .=
" FROM ".MAIN_DB_PREFIX.
"actioncomm";
1769 $sql .=
" WHERE fk_element = ".(int) $this->
id;
1770 $sql .=
" AND elementtype = 'ticket'";
1771 $sql .=
" ORDER BY datec DESC";
1773 dol_syslog(get_class($this).
"::load_cache_actions_ticket", LOG_DEBUG);
1774 $resql = $this->db->query(
$sql);
1776 $num = $this->db->num_rows($resql);
1779 $obj = $this->db->fetch_object($resql);
1780 $this->cache_msgs_ticket[$i][
'id'] = $obj->rowid;
1781 $this->cache_msgs_ticket[$i][
'fk_user_author'] = $obj->fk_user_author;
1782 if ($obj->code ==
'TICKET_MSG' && empty($obj->fk_user_author)) {
1783 $this->cache_msgs_ticket[$i][
'fk_contact_author'] = $obj->email_from;
1785 $this->cache_msgs_ticket[$i][
'datec'] = $this->db->jdate($obj->datec);
1786 $this->cache_msgs_ticket[$i][
'subject'] = $obj->label;
1787 $this->cache_msgs_ticket[$i][
'message'] = $obj->message;
1788 $this->cache_msgs_ticket[$i][
'private'] = (preg_match(
'/^TICKET_MSG_PRIVATE/', $obj->code) ? 1 : 0);
1793 $this->error =
"Error ".$this->db->lasterror();
1794 dol_syslog(get_class($this).
"::load_cache_actions_ticket ".$this->error, LOG_ERR);
1810 if ($this->status != Ticket::STATUS_CLOSED && $this->status != Ticket::STATUS_CANCELED) {
1813 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1814 $sql .=
" SET fk_statut=".($mode ? Ticket::STATUS_CANCELED : Ticket::STATUS_CLOSED).
", progress=100, date_close='".$this->db->idate(
dol_now()).
"'";
1815 $sql .=
" WHERE rowid = ".((int) $this->
id);
1817 dol_syslog(get_class($this).
"::close mode=".$mode);
1818 $resql = $this->db->query(
$sql);
1823 if (
isModEnabled(
'ficheinter') && !empty($conf->global->WORKFLOW_TICKET_CLOSE_INTERVENTION)) {
1824 dol_syslog(
"We have closed the ticket, so we close all linked interventions");
1825 $this->fetchObjectLinked($this->
id, $this->element,
null,
'fichinter');
1826 if ($this->linkedObjectsIds) {
1827 foreach ($this->linkedObjectsIds[
'fichinter'] as $fichinter_id) {
1829 $fichinter->fetch($fichinter_id);
1830 if ($fichinter->statut == 0) {
1831 $result = $fichinter->setValid($user);
1833 $this->errors[] = $fichinter->error;
1837 if ($fichinter->statut < 3) {
1838 $result = $fichinter->setStatut(3);
1840 $this->errors[] = $fichinter->error;
1849 $result = $this->call_trigger(
'TICKET_CLOSE', $user);
1856 $this->db->commit();
1859 $this->db->rollback();
1860 $this->error = join(
',', $this->errors);
1861 dol_syslog(get_class($this).
"::close ".$this->error, LOG_ERR);
1865 $this->db->rollback();
1866 $this->error = $this->db->lasterror();
1867 dol_syslog(get_class($this).
"::close ".$this->error, LOG_ERR);
1886 $thirdparties = array();
1890 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"societe";
1891 $sql .=
" WHERE entity IN (".getEntity(
'ticket', 1).
")";
1892 if (!empty($type)) {
1893 if ($type == 1 || $type == 2) {
1894 $sql .=
" AND client = ".((int) $type);
1895 } elseif ($type == 3) {
1896 $sql .=
" AND fournisseur = 1";
1899 if (!empty($email)) {
1900 if (empty($exact)) {
1902 if (preg_match(
'/^([\*])?[^*]+([\*])?$/', $email, $regs) && count($regs) > 1) {
1903 $email = str_replace(
'*',
'%', $email);
1905 $email =
'%'.$email.
'%';
1909 if (is_array($filters) && !empty($filters)) {
1913 $sql .=
"email LIKE '".$this->db->escape($email).
"'";
1915 if (is_array($filters) && !empty($filters)) {
1916 foreach ($filters as $field => $value) {
1917 $sql .=
" ".$clause.
" ".$field.
" LIKE '".$this->db->escape($value).
"'";
1919 if (!empty($email)) {
1924 $res = $this->db->query(
$sql);
1926 while ($rec = $this->db->fetch_array($res)) {
1927 $soc =
new Societe($this->db);
1928 $soc->fetch($rec[
'rowid']);
1929 $thirdparties[] = $soc;
1932 return $thirdparties;
1934 $this->error = $this->db->error().
' sql='.
$sql;
1935 dol_syslog(get_class($this).
"::searchSocidByEmail ".$this->error, LOG_ERR);
1950 $contacts = array();
1953 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"socpeople";
1954 $sql .=
" WHERE entity IN (".getEntity(
'contact').
")";
1955 if (!empty($socid)) {
1956 $sql .=
" AND fk_soc = ".((int) $socid);
1958 if (!empty($email)) {
1961 $sql .=
"email = '".$this->db->escape($email).
"'";
1963 $sql .=
"email LIKE BINARY '".$this->db->escape($this->db->escapeforlike($email)).
"'";
1967 $res = $this->db->query(
$sql);
1969 while ($rec = $this->db->fetch_object($res)) {
1970 include_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
1971 $contactstatic =
new Contact($this->db);
1972 $contactstatic->fetch($rec->rowid);
1973 $contacts[] = $contactstatic;
1978 $this->error = $this->db->error().
' sql='.
$sql;
1979 dol_syslog(get_class($this).
"::searchContactByEmail ".$this->error, LOG_ERR);
1993 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1994 $sql .=
" SET fk_soc = ".($id > 0 ? $id :
"null");
1995 $sql .=
" WHERE rowid = ".((int) $this->
id);
1997 $resql = $this->db->query(
$sql);
2017 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2018 $sql .=
" SET progress = ".($percent > 0 ? $percent :
"null");
2019 $sql .=
" WHERE rowid = ".((int) $this->
id);
2021 $resql = $this->db->query(
$sql);
2040 if (!$this->table_element) {
2041 dol_syslog(get_class($this).
"::setContract was called on objet with property table_element not defined", LOG_ERR);
2045 $result = $this->add_object_linked(
'contrat', $contractid);
2047 $this->fk_contract = $contractid;
2064 return $this->getIdContact(
'internal',
'SUPPORTTEC');
2075 return $this->listeContact(-1,
'internal', 0,
'', $status);
2085 return $this->getIdContact(
'external',
'SUPPORTCLI');
2096 return $this->listeContact(-1,
'external', 0,
'', $status);
2106 return $this->getIdContact(
'internal',
'CONTRIBUTOR');
2116 return $this->getIdContact(
'external',
'CONTRIBUTOR');
2126 $array_contact = array();
2128 $array_contact = $this->getIdTicketInternalContact();
2130 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact());
2132 $array_contact = array_merge($array_contact, $this->getIdTicketInternalInvolvedContact());
2134 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact());
2136 return $array_contact;
2146 $array_contact = array();
2148 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact());
2150 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact());
2152 return $array_contact;
2167 public function listeContact($statusoflink = -1, $source =
'external', $list = 0, $code =
'', $status = -1)
2173 $sql =
"SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact";
2174 if ($source ==
'internal') {
2175 $sql .=
", '-1' as socid, t.statut as statuscontact";
2178 if ($source ==
'external' || $source ==
'thirdparty') {
2179 $sql .=
", t.fk_soc as socid, t.statut as statuscontact";
2182 $sql .=
", t.civility, t.lastname as lastname, t.firstname, t.email";
2183 if ($source ==
'internal') {
2184 $sql .=
", t.office_phone as phone, t.user_mobile as phone_mobile";
2187 if ($source ==
'external') {
2188 $sql .=
", t.phone as phone, t.phone_mobile as phone_mobile, t.phone_perso as phone_perso";
2191 $sql .=
", tc.source, tc.element, tc.code, tc.libelle as type_contact_label";
2192 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_contact tc";
2193 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact ec";
2194 if ($source ==
'internal') {
2195 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user t on ec.fk_socpeople = t.rowid";
2198 if ($source ==
'external' || $source ==
'thirdparty') {
2199 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"socpeople t on ec.fk_socpeople = t.rowid";
2202 $sql .=
" WHERE ec.element_id = ".((int) $this->
id);
2203 $sql .=
" AND ec.fk_c_type_contact=tc.rowid";
2204 $sql .=
" AND tc.element='".$this->db->escape($this->element).
"'";
2205 if ($source ==
'internal') {
2206 $sql .=
" AND tc.source = 'internal'";
2208 $sql .=
" AND t.statut = ".((int) $status);
2212 if ($source ==
'external' || $source ==
'thirdparty') {
2213 $sql .=
" AND tc.source = 'external'";
2215 $sql .=
" AND t.statut = ".((int) $status);
2219 if (!empty($code)) {
2220 $sql .=
" AND tc.code = '".$this->db->escape($code).
"'";
2223 $sql .=
" AND tc.active=1";
2224 if ($statusoflink >= 0) {
2225 $sql .=
" AND ec.statut = ".((int) $statusoflink);
2228 $sql .=
" ORDER BY t.lastname ASC";
2230 $resql = $this->db->query(
$sql);
2232 $num = $this->db->num_rows($resql);
2235 $obj = $this->db->fetch_object($resql);
2238 $transkey =
"TypeContact_".$obj->element.
"_".$obj->source.
"_".$obj->code;
2239 $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_contact_label);
2241 'source' => $obj->source,
2242 'socid' => $obj->socid,
2244 'nom' => $obj->lastname,
2245 'civility' => $obj->civility,
2246 'lastname' => $obj->lastname,
2247 'firstname' => $obj->firstname,
2248 'email' => $obj->email,
2249 'rowid' => $obj->rowid,
2250 'code' => $obj->code,
2251 'libelle' => $libelle_type,
2252 'status' => $obj->statuslink,
2253 'statuscontact'=>$obj->statuscontact,
2254 'fk_c_type_contact' => $obj->fk_c_type_contact,
2255 'phone' => $obj->phone,
2256 'phone_mobile' => $obj->phone_mobile);
2258 $tab[$i] = $obj->id;
2266 $this->error = $this->db->error();
2283 $modele = empty($conf->global->TICKET_ADDON) ?
'mod_ticket_simple' : $conf->global->TICKET_ADDON;
2289 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
2290 foreach ($dirmodels as $reldir) {
2291 $file =
dol_buildpath($reldir.
"core/modules/ticket/".$modele.
'.php', 0);
2292 if (file_exists($file)) {
2294 $classname = $modele;
2301 $modTicket =
new $classname;
2303 $defaultref = $modTicket->getNextValue($thirdparty, $this);
2306 if (is_numeric($defaultref) && $defaultref <= 0) {
2324 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2332 if (file_exists($dir_osencoded)) {
2333 $handle = opendir($dir_osencoded);
2334 if (is_resource($handle)) {
2335 while (($file = readdir($handle)) !==
false) {
2337 $file = utf8_encode($file);
2362 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
2363 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2364 include_once DOL_DOCUMENT_ROOT.
'/core/lib/images.lib.php';
2366 $maxwidthsmall = 270;
2367 $maxheightsmall = 150;
2368 $maxwidthmini = 128;
2369 $maxheightmini = 72;
2371 $formmail =
new FormMail($this->db);
2372 $formmail->trackid = (is_null($forcetrackid) ?
'tic'.$this->id :
'');
2373 $attachedfiles = $formmail->get_attached_files();
2375 $filepath = $attachedfiles[
'paths'];
2376 $filename = $attachedfiles[
'names'];
2377 $mimetype = $attachedfiles[
'mimes'];
2380 $destdir = $conf->ticket->dir_output.
'/'.$this->ref;
2386 $listofpaths = array();
2387 $listofnames = array();
2388 foreach ($filename as $i => $val) {
2389 $destfile = $destdir.
'/'.$filename[$i];
2391 if (is_file($destfile)) {
2392 $pathinfo = pathinfo($filename[$i]);
2394 $destfile = $destdir.
'/'.$pathinfo[
'filename'].
' - '.
dol_print_date($now,
'dayhourlog').
'.'.$pathinfo[
'extension'];
2397 $res =
dol_move($filepath[$i], $destfile, 0, 1, 0, 1);
2400 $this->error =
"Failed to move file ".dirbasename($filepath[$i]).
" into ".
dirbasename($destfile);
2407 $imgThumbSmall =
vignette($destfile, $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
2410 $imgThumbMini =
vignette($destfile, $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
2415 $formmail->remove_attached_files($i);
2418 $listofpaths[$i] = $destfile;
2419 $listofnames[$i] = basename($destfile);
2422 return array(
'listofpaths'=>$listofpaths,
'listofnames'=>$listofnames,
'listofmimes'=>$mimetype);
2438 if (!is_array($categories)) {
2439 $categories = array($categories);
2443 include_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2445 $existing = $c->containing($this->
id, Categorie::TYPE_TICKET,
'id');
2448 if (is_array($existing)) {
2449 $to_del = array_diff($existing, $categories);
2450 $to_add = array_diff($categories, $existing);
2453 $to_add = $categories;
2457 foreach ($to_del as $del) {
2458 if ($c->fetch($del) > 0) {
2459 $c->del_type($this, Categorie::TYPE_TICKET);
2462 foreach ($to_add as $add) {
2463 if ($c->fetch($add) > 0) {
2464 $c->add_type($this, Categorie::TYPE_TICKET);
2481 public function newMessage($user, &$action, $private = 1, $public_area = 0)
2483 global $mysoc, $conf, $langs;
2487 $object =
new Ticket($this->db);
2489 $ret = $object->fetch(
'',
'',
GETPOST(
'track_id',
'alpha'));
2491 $object->socid = $object->fk_soc;
2492 $object->fetch_thirdparty();
2493 $object->fetch_project();
2497 array_push($this->errors, $langs->trans(
"ErrorTicketIsNotValid"));
2503 array_push($this->errors, $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"message")));
2504 $action =
'add_message';
2508 $object->subject =
GETPOST(
'subject',
'alphanohtml');
2509 $object->message =
GETPOST(
"message",
"restricthtml");
2510 $object->private =
GETPOST(
"private_message",
"alpha");
2512 $send_email =
GETPOST(
'send_email',
'int');
2515 $resarray = $object->copyFilesForTicket();
2516 if (is_numeric($resarray) && $resarray == -1) {
2521 $listofpaths = $resarray[
'listofpaths'];
2522 $listofnames = $resarray[
'listofnames'];
2523 $listofmimes = $resarray[
'listofmimes'];
2525 $id = $object->createTicketMessage($user, 0, $listofpaths, $listofmimes, $listofnames, $send_email);
2528 $this->error = $object->error;
2529 $this->errors = $object->errors;
2530 $action =
'add_message';
2533 if (!$error && $id > 0) {
2534 setEventMessages($langs->trans(
'TicketMessageSuccessfullyAdded'),
null,
'mesgs');
2539 if (!empty($public_area)) {
2545 if (!empty($conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_ENABLED)) {
2547 $internal_contacts = $object->getInfosTicketInternalContact(1);
2549 $assigned_user_dont_have_email =
'';
2553 if ($this->fk_user_assign > 0) {
2554 $assigned_user =
new User($this->db);
2555 $assigned_user->fetch($this->fk_user_assign);
2556 if (!empty($assigned_user->email)) {
2557 $sendto[$assigned_user->email] = $assigned_user->getFullName($langs).
" <".$assigned_user->email.
">";
2559 $assigned_user_dont_have_email = $assigned_user->getFullName($langs);
2564 foreach ($internal_contacts as $key => $info_sendto) {
2566 if ($info_sendto[
'id'] == $user->id) {
2570 if ($info_sendto[
'email'] !=
'') {
2571 if (!empty($info_sendto[
'email'])) {
2572 $sendto[] =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2577 if (empty($sendto)) {
2578 if (!empty($conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL)) {
2579 $sendto[$conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL] = $conf->global->TICKET_PUBLIC_NOTIFICATION_NEW_MESSAGE_DEFAULT_EMAIL;
2580 } elseif (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) {
2581 $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
2586 if (!empty($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS) &&
2587 !empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO) && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)
2589 $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
2592 if (!empty($sendto)) {
2593 $label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE;
2594 $subject =
'['.$label_title.
'- ticket #'.$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
2597 $message = $langs->trans(
'TicketMessageMailIntroText');
2598 $message .=
'<br><br>';
2599 $messagePost =
GETPOST(
'message',
'restricthtml');
2603 $message .= $messagePost;
2606 $message .=
'<br><br>';
2607 $message .=
"==============================================";
2608 $message .= !empty($object->thirdparty->name) ?
'<br>'.$langs->trans(
'Thirdparty').
" : ".$object->thirdparty->name :
'';
2609 $message .= !empty($object->thirdparty->town) ?
'<br>'.$langs->trans(
'Town').
" : ".$object->thirdparty->town :
'';
2610 $message .= !empty($object->thirdparty->phone) ?
'<br>'.$langs->trans(
'Phone').
" : ".$object->thirdparty->phone :
'';
2613 $message .=
'<br><br>';
2614 if (!empty($assigned_user_dont_have_email)) {
2615 $message .=
'<br>'.$langs->trans(
'NoEMail').
' : '.$assigned_user_dont_have_email;
2617 foreach ($sendto as $val) {
2618 $message .=
'<br>'.$langs->trans(
'TicketNotificationRecipient').
' : '.$val;
2622 $url_internal_ticket =
dol_buildpath(
'/ticket/card.php', 2).
'?track_id='.$object->track_id;
2623 $message .=
'<br><br>';
2624 $message .= $langs->trans(
'TicketNotificationEmailBodyInfosTrackUrlinternal').
' : <a href="'.$url_internal_ticket.
'">'.$object->track_id.
'</a>';
2626 $this->sendTicketMessageByEmail($subject, $message,
'', $sendto, $listofpaths, $listofmimes, $listofnames);
2635 if ($send_email > 0) {
2637 $internal_contacts = $object->getInfosTicketInternalContact(1);
2640 if (is_array($internal_contacts) && count($internal_contacts) > 0) {
2642 $label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE;
2643 $appli = $label_title;
2644 $subject =
GETPOST(
'subject',
'alphanohtml') ?
GETPOST(
'subject',
'alphanohtml') :
'['.$appli.
' - '.$langs->trans(
"Ticket").
' #'.$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
2646 $message_intro = $langs->trans(
'TicketNotificationEmailBody',
"#".$object->id);
2649 $message = $langs->trans(
'TicketMessageMailIntroText');
2650 $message .=
'<br><br>';
2651 $messagePost =
GETPOST(
'message',
'restricthtml');
2655 $message .= $messagePost;
2658 $message .=
'<br><br>';
2659 $message .=
"==============================================<br>";
2660 $message .= !empty($object->thirdparty->name) ? $langs->trans(
'Thirdparty').
" : ".$object->thirdparty->name :
'';
2661 $message .= !empty($object->thirdparty->town) ?
'<br>'.$langs->trans(
'Town').
" : ".$object->thirdparty->town :
'';
2662 $message .= !empty($object->thirdparty->phone) ?
'<br>'.$langs->trans(
'Phone').
" : ".$object->thirdparty->phone :
'';
2665 foreach ($internal_contacts as $key => $info_sendto) {
2667 if ($info_sendto[
'id'] == $user->id) {
2671 if ($info_sendto[
'email'] !=
'') {
2672 if (!empty($info_sendto[
'email'])) {
2673 $sendto[$info_sendto[
'email']] =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2677 $recipient =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname'],
'-1').
' ('.strtolower($info_sendto[
'libelle']).
')';
2678 $message .= (!empty($recipient) ? $langs->trans(
'TicketNotificationRecipient').
' : '.$recipient.
'<br>' :
'');
2683 $url_internal_ticket =
dol_buildpath(
'/ticket/card.php', 2).
'?track_id='.$object->track_id;
2686 $message .=
'<br>'.$langs->trans(
'TicketNotificationEmailBodyInfosTrackUrlinternal').
' : <a href="'.$url_internal_ticket.
'">'.$object->track_id.
'</a><br>';
2689 if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) {
2690 if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) {
2691 $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
2696 if (!empty($sendto)) {
2697 $this->sendTicketMessageByEmail($subject, $message,
'', $sendto, $listofpaths, $listofmimes, $listofnames);
2704 if (empty($object->private)) {
2706 $external_contacts = $object->getInfosTicketExternalContact(1);
2709 if (is_array($external_contacts) && count($external_contacts) === 0) {
2710 if (!empty($object->fk_soc)) {
2711 $object->fetch_thirdparty($object->fk_soc);
2712 $array_company = array(array(
'firstname' =>
'',
'lastname' => $object->thirdparty->name,
'email' => $object->thirdparty->email,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' => $object->thirdparty->id));
2713 $external_contacts = array_merge($external_contacts, $array_company);
2714 } elseif (empty($object->fk_soc) && !empty($object->origin_email)) {
2715 $array_external = array(array(
'firstname' =>
'',
'lastname' => $object->origin_email,
'email' => $object->thirdparty->email,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' => $object->thirdparty->id));
2716 $external_contacts = array_merge($external_contacts, $array_external);
2721 if (is_array($external_contacts) && count($external_contacts) > 0) {
2723 $label_title = empty($conf->global->MAIN_APPLICATION_TITLE) ? $mysoc->name : $conf->global->MAIN_APPLICATION_TITLE;
2724 $appli = $mysoc->name;
2725 $subject =
GETPOST(
'subject') ?
GETPOST(
'subject') :
'['.$appli.
' - '.$langs->trans(
"Ticket").
' #'.$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
2730 $message_intro =
dol_nl2br($message_intro);
2733 $message_signature =
dol_nl2br($message_signature);
2737 $messagePost =
GETPOST(
'message',
'restricthtml');
2741 $message = $messagePost;
2742 $message .=
'<br><br>';
2744 foreach ($external_contacts as $key => $info_sendto) {
2746 if ($info_sendto[
'id'] == $user->contact_id) {
2750 if ($info_sendto[
'email'] !=
'' && $info_sendto[
'email'] != $object->origin_email) {
2751 if (!empty($info_sendto[
'email'])) {
2752 $sendto[$info_sendto[
'email']] = trim($info_sendto[
'firstname'].
" ".$info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2755 $recipient =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname'],
'-1').
' ('.strtolower($info_sendto[
'libelle']).
')';
2756 $message .= (!empty($recipient) ? $langs->trans(
'TicketNotificationRecipient').
' : '.$recipient.
'<br>' :
'');
2761 $url_public_ticket = (!empty($conf->global->TICKET_ENABLE_PUBLIC_INTERFACE) ?
2762 (!empty($conf->global->TICKET_URL_PUBLIC_INTERFACE) ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.
'/view.php' :
dol_buildpath(
'/public/ticket/view.php', 2)) :
dol_buildpath(
'/ticket/card.php', 2)).
'?track_id='.$object->track_id;
2763 $message .=
'<br>'.$langs->trans(
'TicketNewEmailBodyInfosTrackUrlCustomer').
' : <a href="'.$url_public_ticket.
'">'.$object->track_id.
'</a><br>';
2766 $message = $message_intro.
'<br><br>'.$message;
2769 $message .=
'<br>'.$message_signature;
2771 if (!empty($object->origin_email)) {
2772 $sendto[$object->origin_email] = $object->origin_email;
2775 if ($object->fk_soc > 0 && !array_key_exists($object->origin_email, $sendto)) {
2776 $object->socid = $object->fk_soc;
2777 $object->fetch_thirdparty();
2778 if (!empty($object->thirdparty->email)) {
2779 $sendto[$object->thirdparty->email] = $object->thirdparty->email;
2784 if ($conf->global->TICKET_NOTIFICATION_ALSO_MAIN_ADDRESS && !array_key_exists($conf->global->TICKET_NOTIFICATION_EMAIL_TO, $sendto)) {
2785 if (!empty($conf->global->TICKET_NOTIFICATION_EMAIL_TO)) {
2786 $sendto[$conf->global->TICKET_NOTIFICATION_EMAIL_TO] = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
2791 if (!empty($sendto)) {
2792 $result = $this->sendTicketMessageByEmail($subject, $message,
'', $sendto, $listofpaths, $listofmimes, $listofnames);
2795 $this->date_last_msg_sent =
dol_now();
2796 $this->update($user, 1);
2806 if (($object->status < self::STATUS_IN_PROGRESS && !$user->socid && !$private) ||
2807 ($object->status > self::STATUS_IN_PROGRESS && $public_area)
2809 $object->setStatut(3);
2835 public function sendTicketMessageByEmail($subject, $message, $send_internal_cc = 0, $array_receiver = array(), $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array())
2837 global $conf, $langs;
2839 if ($conf->global->TICKET_DISABLE_ALL_MAILS) {
2840 dol_syslog(get_class($this).
'::sendTicketMessageByEmail: Emails are disable into ticket setup by option TICKET_DISABLE_ALL_MAILS', LOG_WARNING);
2844 $langs->load(
"mails");
2846 include_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
2850 if (!is_array($array_receiver) || !count($array_receiver) > 0) {
2851 $array_receiver = $this->getInfosTicketInternalContact(1);
2852 $array_receiver = array_merge($array_receiver, $this->getInfosTicketExternalContact(1));
2855 if ($send_internal_cc) {
2856 $sendtocc = $conf->global->TICKET_NOTIFICATION_EMAIL_FROM;
2859 $from = $conf->global->TICKET_NOTIFICATION_EMAIL_FROM;
2861 if (is_array($array_receiver) && count($array_receiver) > 0) {
2862 foreach ($array_receiver as $key => $receiver) {
2863 $deliveryreceipt = 0;
2864 $filepath = $filename_list;
2865 $filename = $mimefilename_list;
2866 $mimetype = $mimetype_list;
2872 if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
2873 $conf->global->MAIN_MAIL_AUTOCOPY_TO =
'';
2876 $upload_dir_tmp = $conf->user->dir_output.
"/".$user->id.
'/temp';
2878 include_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
2879 $trackid =
"tic".$this->id;
2881 $moreinheader =
'X-Dolibarr-Info: sendTicketMessageByEmail'.
"\r\n";
2882 if (!empty($this->email_msgid)) {
2883 $moreinheader .=
'References <'.$this->email_msgid.
'>'.
"\r\n";
2886 $mailfile =
new CMailFile($subject, $receiver, $from, $message, $filepath, $mimetype, $filename, $sendtocc,
'', $deliveryreceipt, -1,
'',
'', $trackid, $moreinheader,
'ticket',
'', $upload_dir_tmp);
2887 if ($mailfile->error) {
2890 $result = $mailfile->sendfile();
2892 setEventMessages($langs->trans(
'MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($receiver, 2)),
null,
'mesgs');
2895 $langs->load(
"other");
2896 if ($mailfile->error) {
2897 setEventMessages($langs->trans(
'ErrorFailedToSendMail', $from, $receiver),
null,
'errors');
2898 dol_syslog($langs->trans(
'ErrorFailedToSendMail', $from, $receiver).
' : '.$mailfile->error);
2900 setEventMessages(
'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS',
null,
'errors');
2905 if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
2906 $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
2910 $langs->load(
"other");
2911 setEventMessages($langs->trans(
'ErrorMailRecipientIsEmptyForSendTicketMessage'),
null,
'warnings');
2928 global $conf, $user, $langs;
2933 $this->nbtodo = $this->nbtodolate = 0;
2936 $sql =
"SELECT p.rowid, p.ref, p.datec as datec";
2937 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as p";
2938 if (
isModEnabled(
'societe') && empty($user->rights->societe->client->voir) && !$user->socid) {
2939 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
2940 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
2944 if ($mode ==
'opened') {
2945 $sql .=
" AND p.fk_statut NOT IN (".Ticket::STATUS_CLOSED.
", ".Ticket::STATUS_CANCELED.
")";
2948 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
2951 $resql = $this->db->query(
$sql);
2953 $label = $labelShort =
'';
2955 if ($mode ==
'opened') {
2956 $status =
'openall';
2959 $label = $langs->trans(
"MenuListNonClosed");
2960 $labelShort = $langs->trans(
"MenuListNonClosed");
2965 $response->label = $label;
2966 $response->labelShort = $labelShort;
2967 $response->url = DOL_URL_ROOT.
'/ticket/list.php?search_fk_statut[]='.$status;
2971 while ($obj = $this->db->fetch_object($resql)) {
2972 $response->nbtodo++;
2973 if ($mode ==
'opened') {
2974 $datelimit = $this->db->jdate($obj->datec) + $delay_warning;
2975 if ($datelimit < $now) {
2982 $this->error = $this->db->lasterror();
2996 global $conf, $user;
2998 $this->nb = array();
3001 $sql =
"SELECT count(p.rowid) as nb";
3002 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as p";
3003 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3004 if (empty($user->rights->societe->client->voir) && !$user->socid) {
3005 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3006 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3009 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'ticket').
")";
3011 $resql = $this->db->query(
$sql);
3014 while ($obj = $this->db->fetch_object($resql)) {
3015 $this->nb[
"ticket"] = $obj->nb;
3017 $this->db->free($resql);
3021 $this->error = $this->db->lasterror();
3036 $tables = array(
'ticket');
3052 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3054 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3055 $return .=
'<div class="info-box info-box-sm">';
3056 $return .=
'<span class="info-box-icon bg-infobox-action">';
3058 $return .=
'</span>';
3059 $return .=
'<div class="info-box-content">';
3060 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->getNomUrl(1) : $this->ref).
'</span>';
3061 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
3062 if (!empty($arraydata[
'user_assignment'])) {
3063 $return .=
'<br><span class="info-box-label" title="'.dol_escape_htmltag($langs->trans(
"AssignedTo")).
'">'.$arraydata[
'user_assignment'].
'</span>';
3065 if (property_exists($this,
'type_code') && !empty($this->type_code)) {
3067 $return .=
'<div class="tdoverflowmax125 inline-block">'.$langs->getLabelFromKey($this->db,
'TicketTypeShort'.$this->type_code,
'c_ticket_type',
'code',
'label', $this->type_code).
'</div>';
3069 if (method_exists($this,
'getLibStatut')) {
3070 $return .=
'<br><div class="info-box-status margintoponly">'.$this->getLibStatut(3).
'</div>';
3072 $return .=
'</div>';
3073 $return .=
'</div>';
3074 $return .=
'</div>';
3204 public $date_last_msg_sent =
'';