31require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobject.class.php";
32require_once DOL_DOCUMENT_ROOT.
'/fichinter/class/fichinter.class.php';
33require_once DOL_DOCUMENT_ROOT.
'/core/lib/ticket.lib.php';
49 public $element =
'ticket';
54 public $table_element =
'ticket';
59 public $fk_element =
'fk_ticket';
64 public $ismultientitymanaged = 1;
69 public $isextrafieldmanaged = 1;
74 public $picto =
'ticket';
101 public $origin_email;
106 public $fk_user_create;
111 public $fk_user_assign;
163 public $category_code;
168 public $severity_code;
203 public $date_read =
'';
208 public $date_last_msg_sent =
'';
213 public $date_close =
'';
218 public $cache_types_tickets;
223 public $cache_category_tickets;
228 public $cache_severity_tickets;
233 public $cache_msgs_ticket;
243 public $labelStatusShort;
248 public $notify_tiers_at_create;
279 public $regeximgext =
'\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm';
285 const STATUS_READ = 1;
286 const STATUS_ASSIGNED = 2;
287 const STATUS_IN_PROGRESS = 3;
288 const STATUS_NEED_MORE_INFO = 5;
289 const STATUS_WAITING = 7;
290 const STATUS_CLOSED = 8;
291 const STATUS_CANCELED = 9;
322 'rowid' => array(
'type'=>
'integer',
'label'=>
'TechnicalID',
'visible'=>-2,
'enabled'=>1,
'position'=>1,
'notnull'=>1,
'index'=>1,
'comment'=>
"Id"),
323 'entity' => array(
'type'=>
'integer',
'label'=>
'Entity',
'visible'=>0,
'enabled'=>1,
'position'=>5,
'notnull'=>1,
'index'=>1),
324 '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),
325 'track_id' => array(
'type'=>
'varchar(255)',
'label'=>
'TicketTrackId',
'visible'=>-2,
'enabled'=>1,
'position'=>11,
'notnull'=>-1,
'searchall'=>1,
'help'=>
"Help text"),
326 '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'),
327 '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'),
328 'subject' => array(
'type'=>
'varchar(255)',
'label'=>
'Subject',
'visible'=>1,
'enabled'=>1,
'position'=>18,
'notnull'=>-1,
'searchall'=>1,
'help'=>
"",
'css'=>
'maxwidth200 tdoverflowmax200',
'autofocusoncreate'=>1),
329 'type_code' => array(
'type'=>
'varchar(32)',
'label'=>
'Type',
'visible'=>1,
'enabled'=>1,
'position'=>20,
'notnull'=>-1,
'help'=>
"",
'csslist'=>
'maxwidth125 tdoverflowmax50'),
330 'category_code' => array(
'type'=>
'varchar(32)',
'label'=>
'TicketCategory',
'visible'=>-1,
'enabled'=>1,
'position'=>21,
'notnull'=>-1,
'help'=>
"",
'css'=>
'maxwidth100 tdoverflowmax200'),
331 'severity_code' => array(
'type'=>
'varchar(32)',
'label'=>
'Severity',
'visible'=>1,
'enabled'=>1,
'position'=>22,
'notnull'=>-1,
'help'=>
"",
'css'=>
'maxwidth100'),
332 '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'),
333 'notify_tiers_at_create' => array(
'type'=>
'integer',
'label'=>
'NotifyThirdparty',
'visible'=>-1,
'enabled'=>0,
'position'=>51,
'notnull'=>1,
'index'=>1),
334 '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"),
335 'fk_contract' => array(
'type'=>
'integer:Contrat:contrat/class/contrat.class.php',
'label'=>
'Contract',
'visible'=>-1,
'enabled'=>
'$conf->contract->enabled',
'position'=>53,
'notnull'=>-1,
'index'=>1,
'help'=>
"LinkToContract"),
337 'datec' => array(
'type'=>
'datetime',
'label'=>
'DateCreation',
'visible'=>1,
'enabled'=>1,
'position'=>500,
'notnull'=>1,
'csslist'=>
'nowraponall'),
338 'date_read' => array(
'type'=>
'datetime',
'label'=>
'TicketReadOn',
'visible'=>-1,
'enabled'=>1,
'position'=>501,
'notnull'=>1,
'csslist'=>
'nowraponall'),
339 'date_last_msg_sent' => array(
'type'=>
'datetime',
'label'=>
'TicketLastMessageDate',
'visible'=>0,
'enabled'=>1,
'position'=>502,
'notnull'=>-1),
340 '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'),
341 'date_close' => array(
'type'=>
'datetime',
'label'=>
'TicketCloseOn',
'visible'=>-1,
'enabled'=>1,
'position'=>510,
'notnull'=>1),
342 'tms' => array(
'type'=>
'timestamp',
'label'=>
'DateModification',
'visible'=>-1,
'enabled'=>1,
'position'=>520,
'notnull'=>1),
343 'message' => array(
'type'=>
'html',
'label'=>
'Message',
'visible'=>-2,
'enabled'=>1,
'position'=>540,
'notnull'=>-1,),
344 'email_msgid' => array(
'type'=>
'varchar(255)',
'label'=>
'EmailMsgID',
'visible'=>-2,
'enabled'=>1,
'position'=>540,
'notnull'=>-1,
'help'=>
'EmailMsgIDDesc',
'csslist'=>
'tdoverflowmax100'),
345 'email_date' => array(
'type'=>
'datetime',
'label'=>
'EmailDate',
'visible'=>-2,
'enabled'=>1,
'position'=>541),
346 'progress' => array(
'type'=>
'integer',
'label'=>
'Progression',
'visible'=>-1,
'enabled'=>1,
'position'=>540,
'notnull'=>-1,
'css'=>
'right',
'help'=>
"",
'isameasure'=>2,
'csslist'=>
'width50'),
347 'resolution' => array(
'type'=>
'integer',
'label'=>
'Resolution',
'visible'=>-1,
'enabled'=>
'getDolGlobalString("TICKET_ENABLE_RESOLUTION")',
'position'=>550,
'notnull'=>1),
348 'fk_statut' => array(
'type'=>
'integer',
'label'=>
'Status',
'visible'=>1,
'enabled'=>1,
'position'=>600,
'notnull'=>1,
'index'=>1,
'arrayofkeyval'=>array(0 =>
'Unread', 1 =>
'Read', 2 =>
'Assigned', 3 =>
'InProgress', 5 =>
'NeedMoreInformation', 7 =>
'OnHold', 8 =>
'SolvedClosed', 9 =>
'Deleted')),
349 'import_key' =>array(
'type'=>
'varchar(14)',
'label'=>
'ImportId',
'enabled'=>1,
'visible'=>-2,
'position'=>900),
365 $this->labelStatusShort = array(
366 self::STATUS_NOT_READ =>
'Unread',
367 self::STATUS_READ =>
'Read',
368 self::STATUS_ASSIGNED =>
'Assigned',
369 self::STATUS_IN_PROGRESS =>
'InProgress',
370 self::STATUS_WAITING =>
'OnHold',
371 self::STATUS_NEED_MORE_INFO =>
'NeedMoreInformationShort',
372 self::STATUS_CLOSED =>
'SolvedClosed',
373 self::STATUS_CANCELED =>
'Canceled'
375 $this->labelStatus = array(
376 self::STATUS_NOT_READ =>
'Unread',
377 self::STATUS_READ =>
'Read',
378 self::STATUS_ASSIGNED =>
'Assigned',
379 self::STATUS_IN_PROGRESS =>
'InProgress',
380 self::STATUS_WAITING =>
'OnHold',
381 self::STATUS_NEED_MORE_INFO =>
'NeedMoreInformation',
382 self::STATUS_CLOSED =>
'SolvedClosed',
383 self::STATUS_CANCELED =>
'Canceled'
395 $this->errors = array();
400 if (isset($this->
ref)) {
401 $this->
ref = trim($this->
ref);
404 if (isset($this->track_id)) {
405 $this->track_id = trim($this->track_id);
408 if (isset($this->fk_soc)) {
409 $this->fk_soc = (int) $this->fk_soc;
412 if (isset($this->fk_project)) {
413 $this->fk_project = (int) $this->fk_project;
416 if (isset($this->origin_email)) {
417 $this->origin_email = trim($this->origin_email);
420 if (isset($this->fk_user_create)) {
421 $this->fk_user_create = (int) $this->fk_user_create;
424 if (isset($this->fk_user_assign)) {
425 $this->fk_user_assign = (int) $this->fk_user_assign;
428 if (isset($this->subject)) {
429 $this->subject = trim($this->subject);
432 if (isset($this->message)) {
433 $this->message = trim($this->message);
435 $this->errors[] =
'ErrorFieldTooLong';
436 dol_syslog(get_class($this).
'::create error -1 message too long', LOG_ERR);
441 if (isset($this->fk_statut)) {
442 $this->fk_statut = (int) $this->fk_statut;
445 if (isset($this->resolution)) {
446 $this->resolution = trim($this->resolution);
449 if (isset($this->progress)) {
450 $this->progress = trim($this->progress);
453 if (isset($this->timing)) {
454 $this->timing = trim($this->timing);
457 if (isset($this->type_code)) {
458 $this->type_code = trim($this->type_code);
461 if (isset($this->category_code)) {
462 $this->category_code = trim($this->category_code);
465 if (isset($this->severity_code)) {
466 $this->severity_code = trim($this->severity_code);
469 if (empty($this->
ref)) {
470 $this->errors[] =
'ErrorTicketRefRequired';
471 dol_syslog(get_class($this).
"::create error -1 ref null", LOG_ERR);
485 public function create($user, $notrigger = 0)
493 if (empty($this->track_id)) {
499 $result = $this->
verify();
502 $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
505 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"ticket(";
509 $sql .=
"fk_project,";
510 $sql .=
"fk_contract,";
511 $sql .=
"origin_email,";
512 $sql .=
"fk_user_create,";
513 $sql .=
"fk_user_assign,";
514 $sql .=
"email_msgid,";
515 $sql .=
"email_date,";
518 $sql .=
"fk_statut,";
519 $sql .=
"resolution,";
522 $sql .=
"type_code,";
523 $sql .=
"category_code,";
524 $sql .=
"severity_code,";
526 $sql .=
"date_read,";
527 $sql .=
"date_close,";
529 $sql .=
"notify_tiers_at_create,";
531 $sql .=
") VALUES (";
532 $sql .=
" ".(!isset($this->
ref) ?
'' :
"'".$this->db->escape($this->
ref).
"'").
",";
533 $sql .=
" ".(!isset($this->track_id) ?
'NULL' :
"'".$this->db->escape($this->track_id).
"'").
",";
534 $sql .=
" ".($this->fk_soc > 0 ? $this->db->escape($this->fk_soc) :
"null").
",";
535 $sql .=
" ".($this->fk_project > 0 ? $this->db->escape($this->fk_project) :
"null").
",";
536 $sql .=
" ".($this->fk_contract > 0 ? $this->db->escape($this->fk_contract) :
"null").
",";
537 $sql .=
" ".(!isset($this->origin_email) ?
'NULL' :
"'".$this->db->escape($this->origin_email).
"'").
",";
538 $sql .=
" ".(!isset($this->fk_user_create) ? ($user->id > 0 ? $user->id :
'NULL') : ($this->fk_user_create > 0 ? $this->fk_user_create :
'NULL')).
",";
539 $sql .=
" ".($this->fk_user_assign > 0 ? $this->fk_user_assign :
'NULL').
",";
540 $sql .=
" ".(empty($this->email_msgid) ?
'NULL' :
"'".$this->db->escape($this->email_msgid).
"'").
",";
541 $sql .=
" ".(empty($this->email_date) ?
'NULL' :
"'".$this->db->idate($this->email_date).
"'").
",";
542 $sql .=
" ".(!isset($this->subject) ?
'NULL' :
"'".$this->db->escape($this->subject).
"'").
",";
543 $sql .=
" ".(!isset($this->message) ?
'NULL' :
"'".$this->db->escape($this->message).
"'").
",";
544 $sql .=
" ".(!isset($this->fk_statut) ?
'0' :
"'".$this->db->escape($this->fk_statut).
"'").
",";
545 $sql .=
" ".(!isset($this->resolution) ?
'NULL' :
"'".$this->db->escape($this->resolution).
"'").
",";
546 $sql .=
" ".(!isset($this->progress) ?
'0' :
"'".$this->db->escape($this->progress).
"'").
",";
547 $sql .=
" ".(!isset($this->timing) ?
'NULL' :
"'".$this->db->escape($this->timing).
"'").
",";
548 $sql .=
" ".(!isset($this->type_code) ?
'NULL' :
"'".$this->db->escape($this->type_code).
"'").
",";
549 $sql .=
" ".(empty($this->category_code) || $this->category_code ==
'-1' ?
'NULL' :
"'".$this->db->escape($this->category_code).
"'").
",";
550 $sql .=
" ".(!isset($this->severity_code) ?
'NULL' :
"'".$this->db->escape($this->severity_code).
"'").
",";
551 $sql .=
" ".(!isset($this->datec) ||
dol_strlen($this->datec) == 0 ?
'NULL' :
"'".$this->db->idate($this->datec).
"'").
",";
552 $sql .=
" ".(!isset($this->date_read) ||
dol_strlen($this->date_read) == 0 ?
'NULL' :
"'".$this->db->idate($this->date_read).
"'").
",";
553 $sql .=
" ".(!isset($this->date_close) ||
dol_strlen($this->date_close) == 0 ?
'NULL' :
"'".$this->db->idate($this->date_close).
"'");
554 $sql .=
", ".((int) $this->entity);
555 $sql .=
", ".(!isset($this->notify_tiers_at_create) ?
'1' :
"'".$this->db->escape($this->notify_tiers_at_create).
"'");
556 $sql .=
", ".(!isset($this->ip) ?
'NULL' :
"'".$this->db->escape($this->ip).
"'");
561 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
562 $resql = $this->db->query($sql);
565 $this->errors[] =
"Error ".$this->db->lasterror();
569 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"ticket");
574 if ($this->
add_contact($user->id,
'CONTRIBUTOR',
'internal') < 0) {
579 if (!$error && $this->fk_user_assign > 0) {
580 if ($this->
add_contact($this->fk_user_assign,
'SUPPORTTEC',
'internal') < 0) {
594 if (!$error && !$notrigger) {
605 foreach ($this->errors as $errmsg) {
606 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
607 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
609 $this->db->rollback();
616 $this->db->rollback();
617 dol_syslog(get_class($this).
"::Create fails verify ".join(
',', $this->errors), LOG_WARNING);
631 public function fetch($id =
'', $ref =
'', $track_id =
'', $email_msgid =
'')
636 if (empty($id) && empty($ref) && empty($track_id) && empty($email_msgid)) {
637 $this->error =
'ErrorWrongParameters';
644 $sql .=
" t.entity,";
646 $sql .=
" t.track_id,";
647 $sql .=
" t.fk_soc,";
648 $sql .=
" t.fk_project,";
649 $sql .=
" t.fk_contract,";
650 $sql .=
" t.origin_email,";
651 $sql .=
" t.fk_user_create,";
652 $sql .=
" t.fk_user_assign,";
653 $sql .=
" t.email_msgid,";
654 $sql .=
" t.email_date,";
655 $sql .=
" t.subject,";
656 $sql .=
" t.message,";
657 $sql .=
" t.fk_statut as status,";
658 $sql .=
" t.resolution,";
659 $sql .=
" t.progress,";
660 $sql .=
" t.timing,";
661 $sql .=
" t.type_code,";
662 $sql .=
" t.category_code,";
663 $sql .=
" t.severity_code,";
665 $sql .=
" t.date_read,";
666 $sql .=
" t.date_last_msg_sent,";
667 $sql .=
" t.date_close,";
670 $sql .=
" type.label as type_label, category.label as category_label, severity.label as severity_label";
671 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as t";
672 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_type as type ON type.code=t.type_code";
673 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as category ON category.code=t.category_code";
674 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_severity as severity ON severity.code=t.severity_code";
677 $sql .=
" WHERE t.rowid = ".((int) $id);
679 $sql .=
" WHERE t.entity IN (".getEntity($this->element, 1).
")";
681 $sql .=
" AND t.ref = '".$this->db->escape($ref).
"'";
682 } elseif ($track_id) {
683 $sql .=
" AND t.track_id = '".$this->db->escape($track_id).
"'";
685 $sql .=
" AND t.email_msgid = '".$this->db->escape($email_msgid).
"'";
689 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
690 $resql = $this->db->query($sql);
692 if ($this->db->num_rows($resql)) {
693 $obj = $this->db->fetch_object($resql);
695 $this->
id = $obj->rowid;
696 $this->entity = $obj->entity;
697 $this->
ref = $obj->ref;
698 $this->track_id = $obj->track_id;
699 $this->fk_soc = $obj->fk_soc;
700 $this->socid = $obj->fk_soc;
701 $this->fk_project = $obj->fk_project;
702 $this->fk_contract = $obj->fk_contract;
703 $this->origin_email = $obj->origin_email;
704 $this->fk_user_create = $obj->fk_user_create;
705 $this->fk_user_assign = $obj->fk_user_assign;
706 $this->email_msgid = $obj->email_msgid;
707 $this->email_date = $this->db->jdate($obj->email_date);
708 $this->subject = $obj->subject;
709 $this->message = $obj->message;
710 $this->ip = $obj->ip;
712 $this->
status = $obj->status;
713 $this->fk_statut = $this->status;
715 $this->resolution = $obj->resolution;
716 $this->progress = $obj->progress;
717 $this->timing = $obj->timing;
719 $this->type_code = $obj->type_code;
720 $label_type = ($langs->trans(
"TicketTypeShort".$obj->type_code) !=
"TicketTypeShort".$obj->type_code ? $langs->trans(
"TicketTypeShort".$obj->type_code) : ($obj->type_label !=
'-' ? $obj->type_label :
''));
721 $this->type_label = $label_type;
723 $this->category_code = $obj->category_code;
724 $label_category = ($langs->trans(
"TicketCategoryShort".$obj->category_code) !=
"TicketCategoryShort".$obj->category_code ? $langs->trans(
"TicketCategoryShort".$obj->category_code) : ($obj->category_label !=
'-' ? $obj->category_label :
''));
725 $this->category_label = $label_category;
727 $this->severity_code = $obj->severity_code;
728 $label_severity = ($langs->trans(
"TicketSeverityShort".$obj->severity_code) !=
"TicketSeverityShort".$obj->severity_code ? $langs->trans(
"TicketSeverityShort".$obj->severity_code) : ($obj->severity_label !=
'-' ? $obj->severity_label :
''));
729 $this->severity_label = $label_severity;
731 $this->datec = $this->db->jdate($obj->datec);
732 $this->date_creation = $this->db->jdate($obj->datec);
733 $this->date_read = $this->db->jdate($obj->date_read);
734 $this->date_validation = $this->db->jdate($obj->date_read);
735 $this->date_last_msg_sent = $this->db->jdate($obj->date_last_msg_sent);
736 $this->date_close = $this->db->jdate($obj->date_close);
737 $this->tms = $this->db->jdate($obj->tms);
738 $this->date_modification = $this->db->jdate($obj->tms);
742 $this->db->free($resql);
748 $this->error =
"Error ".$this->db->lasterror();
749 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
766 public function fetchAll($user, $sortorder =
'ASC', $sortfield =
't.datec', $limit =
'', $offset = 0, $arch =
'', $filter =
'')
768 global $langs, $extrafields;
771 $extrafields->fetch_name_optionals_label($this->table_element);
776 $sql .=
" t.track_id,";
777 $sql .=
" t.fk_soc,";
778 $sql .=
" t.fk_project,";
779 $sql .=
" t.fk_contract,";
780 $sql .=
" t.origin_email,";
781 $sql .=
" t.fk_user_create, uc.lastname as user_create_lastname, uc.firstname as user_create_firstname,";
782 $sql .=
" t.fk_user_assign, ua.lastname as user_assign_lastname, ua.firstname as user_assign_firstname,";
783 $sql .=
" t.subject,";
784 $sql .=
" t.message,";
785 $sql .=
" t.fk_statut as status,";
786 $sql .=
" t.resolution,";
787 $sql .=
" t.progress,";
788 $sql .=
" t.timing,";
789 $sql .=
" t.type_code,";
790 $sql .=
" t.category_code,";
791 $sql .=
" t.severity_code,";
793 $sql .=
" t.date_read,";
794 $sql .=
" t.date_last_msg_sent,";
795 $sql .=
" t.date_close,";
797 $sql .=
", type.label as type_label, category.label as category_label, severity.label as severity_label";
799 if ($extrafields->attributes[$this->table_element][
'count']> 0) {
800 foreach ($extrafields->attributes[$this->table_element][
'label'] as $key => $val) {
801 $sql .= ($extrafields->attributes[$this->table_element][
'type'][$key] !=
'separate' ?
",ef.".$key.
" as options_".$key :
'');
804 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as t";
805 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_type as type ON type.code=t.type_code";
806 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as category ON category.code=t.category_code";
807 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_severity as severity ON severity.code=t.severity_code";
808 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON s.rowid=t.fk_soc";
809 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as uc ON uc.rowid=t.fk_user_create";
810 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as ua ON ua.rowid=t.fk_user_assign";
811 if ($extrafields->attributes[$this->table_element][
'count']> 0) {
812 if (is_array($extrafields->attributes[$this->table_element][
'label']) && count($extrafields->attributes[$this->table_element][
'label'])) {
813 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"ticket_extrafields as ef on (t.rowid = ef.fk_object)";
816 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
817 $sql .=
", ".MAIN_DB_PREFIX.
"societe_commerciaux as sc";
820 $sql .=
" WHERE t.entity IN (".getEntity(
'ticket').
")";
823 if (!empty($filter)) {
824 foreach ($filter as $key => $value) {
825 if (strpos($key,
'date')) {
826 $sql .=
" AND ".$key.
" = '".$this->db->escape($value).
"'";
827 } elseif (($key ==
't.fk_user_assign') || ($key ==
't.type_code') || ($key ==
't.category_code') || ($key ==
't.severity_code') || ($key ==
't.fk_soc')) {
828 $sql .=
" AND ".$key.
" = '".$this->db->escape($value).
"'";
829 } elseif ($key ==
't.fk_statut') {
830 if (is_array($value) && count($value) > 0) {
831 $sql .=
" AND ".$key.
" IN (".$this->db->sanitize(implode(
',', $value)).
")";
833 $sql .=
" AND ".$key.
' = '.((int) $value);
835 } elseif ($key ==
't.fk_contract') {
836 $sql .=
" AND ".$key.
' = '.((int) $value);
838 $sql .=
" AND ".$key.
" LIKE '%".$this->db->escape($value).
"%'";
842 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
843 $sql .=
" AND t.fk_soc = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
844 } elseif ($user->socid) {
845 $sql .=
" AND t.fk_soc = ".((int) $user->socid);
848 $sql .= $this->db->order($sortfield, $sortorder);
849 if (!empty($limit)) {
850 $sql .= $this->db->plimit($limit + 1, $offset);
853 dol_syslog(get_class($this).
"::fetchAll", LOG_DEBUG);
854 $resql = $this->db->query($sql);
857 $this->lines = array();
859 $num = $this->db->num_rows($resql);
864 $obj = $this->db->fetch_object($resql);
866 $line =
new self($this->db);
868 $line->id = $obj->rowid;
870 $line->ref = $obj->ref;
871 $line->track_id = $obj->track_id;
872 $line->fk_soc = $obj->fk_soc;
873 $line->fk_project = $obj->fk_project;
874 $line->fk_contract = $obj->fk_contract;
875 $line->origin_email = $obj->origin_email;
877 $line->fk_user_create = $obj->fk_user_create;
878 $line->fk_user_assign = $obj->fk_user_assign;
880 $line->subject = $obj->subject;
881 $line->message = $obj->message;
882 $line->fk_statut = $obj->status;
883 $line->status = $obj->status;
884 $line->resolution = $obj->resolution;
885 $line->progress = $obj->progress;
886 $line->timing = $obj->timing;
888 $label_type = ($langs->trans(
"TicketTypeShort".$obj->type_code) !=
"TicketTypeShort".$obj->type_code ? $langs->trans(
"TicketTypeShort".$obj->type_code) : ($obj->type_label !=
'-' ? $obj->type_label :
''));
889 $line->type_label = $label_type;
891 $this->category_code = $obj->category_code;
892 $label_category = ($langs->trans(
"TicketCategoryShort".$obj->category_code) !=
"TicketCategoryShort".$obj->category_code ? $langs->trans(
"TicketCategoryShort".$obj->category_code) : ($obj->category_label !=
'-' ? $obj->category_label :
''));
893 $line->category_label = $label_category;
895 $this->severity_code = $obj->severity_code;
896 $label_severity = ($langs->trans(
"TicketSeverityShort".$obj->severity_code) !=
"TicketSeverityShort".$obj->severity_code ? $langs->trans(
"TicketSeverityShort".$obj->severity_code) : ($obj->severity_label !=
'-' ? $obj->severity_label :
''));
897 $line->severity_label = $label_severity;
899 $line->datec = $this->db->jdate($obj->datec);
900 $line->date_read = $this->db->jdate($obj->date_read);
901 $line->date_last_msg_sent = $this->db->jdate($obj->date_last_msg_sent);
902 $line->date_close = $this->db->jdate($obj->date_close);
905 if ($extrafields->attributes[$this->table_element][
'count']> 0) {
906 if (is_array($extrafields->attributes[$this->table_element][
'label']) && count($extrafields->attributes[$this->table_element][
'label'])) {
907 foreach ($extrafields->attributes[$this->table_element][
'label'] as $key => $val) {
908 $tmpkey =
'options_'.$key;
909 $line->{$tmpkey} = $obj->$tmpkey;
913 $this->lines[$i] = $line;
917 $this->db->free($resql);
920 $this->error =
"Error ".$this->db->lasterror();
921 dol_syslog(get_class($this).
"::fetchAll ".$this->error, LOG_ERR);
933 public function update($user, $notrigger = 0)
943 if (isset($this->
ref)) {
944 $this->
ref = trim($this->
ref);
947 if (isset($this->track_id)) {
948 $this->track_id = trim($this->track_id);
951 if (isset($this->fk_soc)) {
952 $this->fk_soc = (int) $this->fk_soc;
955 if (isset($this->fk_project)) {
956 $this->fk_project = (int) $this->fk_project;
959 if (isset($this->fk_contract)) {
960 $this->fk_contract = (int) $this->fk_contract;
963 if (isset($this->origin_email)) {
964 $this->origin_email = trim($this->origin_email);
967 if (isset($this->fk_user_create)) {
968 $this->fk_user_create = (int) $this->fk_user_create;
971 if (isset($this->fk_user_assign)) {
972 $this->fk_user_assign = (int) $this->fk_user_assign;
975 if (isset($this->subject)) {
976 $this->subject = trim($this->subject);
979 if (isset($this->message)) {
980 $this->message = trim($this->message);
982 $this->errors[] =
'ErrorFieldTooLong';
983 dol_syslog(get_class($this).
'::update error -1 message too long', LOG_ERR);
988 if (isset($this->fk_statut)) {
989 $this->fk_statut = (int) $this->fk_statut;
992 if (isset($this->resolution)) {
993 $this->resolution = trim($this->resolution);
996 if (isset($this->progress)) {
997 $this->progress = trim($this->progress);
1000 if (isset($this->timing)) {
1001 $this->timing = trim($this->timing);
1004 if (isset($this->type_code)) {
1005 $this->timing = trim($this->type_code);
1008 if (isset($this->category_code)) {
1009 $this->timing = trim($this->category_code);
1012 if (isset($this->severity_code)) {
1013 $this->timing = trim($this->severity_code);
1019 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket SET";
1020 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"").
",";
1021 $sql .=
" track_id=".(isset($this->track_id) ?
"'".$this->db->escape($this->track_id).
"'" :
"null").
",";
1022 $sql .=
" fk_soc=".(isset($this->fk_soc) ?
"'".$this->db->escape($this->fk_soc).
"'" :
"null").
",";
1023 $sql .=
" fk_project=".(isset($this->fk_project) ?
"'".$this->db->escape($this->fk_project).
"'" :
"null").
",";
1024 $sql .=
" fk_contract=".(isset($this->fk_contract) ?
"'".$this->db->escape($this->fk_contract).
"'" :
"null").
",";
1025 $sql .=
" origin_email=".(isset($this->origin_email) ?
"'".$this->db->escape($this->origin_email).
"'" :
"null").
",";
1026 $sql .=
" fk_user_create=".(isset($this->fk_user_create) ? $this->fk_user_create :
"null").
",";
1027 $sql .=
" fk_user_assign=".(isset($this->fk_user_assign) ? $this->fk_user_assign :
"null").
",";
1028 $sql .=
" subject=".(isset($this->subject) ?
"'".$this->db->escape($this->subject).
"'" :
"null").
",";
1029 $sql .=
" message=".(isset($this->message) ?
"'".$this->db->escape($this->message).
"'" :
"null").
",";
1030 $sql .=
" fk_statut=".(isset($this->fk_statut) ? $this->fk_statut :
"0").
",";
1031 $sql .=
" resolution=".(isset($this->resolution) ? $this->resolution :
"null").
",";
1032 $sql .=
" progress=".(isset($this->progress) ?
"'".$this->db->escape($this->progress).
"'" :
"null").
",";
1033 $sql .=
" timing=".(isset($this->timing) ?
"'".$this->db->escape($this->timing).
"'" :
"null").
",";
1034 $sql .=
" type_code=".(isset($this->type_code) ?
"'".$this->db->escape($this->type_code).
"'" :
"null").
",";
1035 $sql .=
" category_code=".(isset($this->category_code) ?
"'".$this->db->escape($this->category_code).
"'" :
"null").
",";
1036 $sql .=
" severity_code=".(isset($this->severity_code) ?
"'".$this->db->escape($this->severity_code).
"'" :
"null").
",";
1037 $sql .=
" datec=".(dol_strlen($this->datec) != 0 ?
"'".$this->db->idate($this->datec).
"'" :
'null').
",";
1038 $sql .=
" date_read=".(dol_strlen($this->date_read) != 0 ?
"'".$this->db->idate($this->date_read).
"'" :
'null').
",";
1039 $sql .=
" date_last_msg_sent=".(dol_strlen($this->date_last_msg_sent) != 0 ?
"'".$this->db->idate($this->date_last_msg_sent).
"'" :
'null').
",";
1040 $sql .=
" date_close=".(dol_strlen($this->date_close) != 0 ?
"'".$this->db->idate($this->date_close).
"'" :
'null');
1041 $sql .=
" WHERE rowid=".((int) $this->
id);
1045 $resql = $this->db->query($sql);
1048 $this->errors[] =
"Error ".$this->db->lasterror();
1053 $result = $this->insertExtraFields();
1059 if (!$error && !$notrigger) {
1061 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1070 foreach ($this->errors as $errmsg) {
1071 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1072 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1074 $this->db->rollback();
1077 $this->db->commit();
1089 public function delete($user, $notrigger = 0)
1091 global $conf, $langs;
1099 $result = $this->call_trigger(
'TICKET_DELETE', $user);
1109 $res = $this->delete_linked_contact();
1111 dol_syslog(get_class($this).
"::delete error", LOG_ERR);
1118 $res = $this->deleteObjectLinked();
1126 $result = $this->deleteExtraFields();
1129 dol_syslog(get_class($this).
"::delete error -3 ".$this->error, LOG_ERR);
1136 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"categorie_ticket";
1137 $sql .=
" WHERE fk_ticket = ".(int) $this->
id;
1139 $result = $this->db->query($sql);
1142 $this->errors[] = $this->db->lasterror();
1147 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"ticket";
1148 $sql .=
" WHERE rowid=".((int) $this->
id);
1150 dol_syslog(get_class($this).
"::delete sql=".$sql);
1151 $resql = $this->db->query($sql);
1154 $this->errors[] =
"Error ".$this->db->lasterror();
1160 foreach ($this->errors as $errmsg) {
1161 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
1162 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1164 $this->db->rollback();
1167 $this->db->commit();
1183 $object =
new Ticket($this->db);
1188 $object->fetch($fromid);
1190 $object->statut = 0;
1195 $object->context[
'createfromclone'] =
'createfromclone';
1196 $result = $object->create($user);
1200 $this->error = $object->error;
1207 unset($object->context[
'createfromclone']);
1211 $this->db->commit();
1214 $this->db->rollback();
1229 $this->
ref =
'TI0501-001';
1230 $this->track_id =
'XXXXaaaa';
1231 $this->origin_email =
'email@email.com';
1232 $this->fk_project = 1;
1233 $this->fk_user_create = 1;
1234 $this->fk_user_assign = 1;
1235 $this->subject =
'Subject of ticket';
1236 $this->message =
'Message of ticket';
1238 $this->resolution =
'1';
1239 $this->progress =
'10';
1241 $this->type_code =
'TYPECODE';
1242 $this->category_code =
'CATEGORYCODE';
1243 $this->severity_code =
'SEVERITYCODE';
1245 $this->date_read =
'';
1246 $this->date_last_msg_sent =
'';
1247 $this->date_close =
'';
1260 print
Form::selectarray(
'search_fk_statut', $this->labelStatusShort, $selected, $show_empty = 1, $key_in_label = 0, $value_as_key = 0, $option =
'', $translate = 1, $maxlen = 0, $disabled = 0, $sort =
'', $morecss =
'');
1273 if (!empty($this->cache_types_tickets) && count($this->cache_types_tickets)) {
1278 $sql =
"SELECT rowid, code, label, use_default, pos, description";
1279 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_type";
1280 $sql .=
" WHERE entity IN (".getEntity(
'c_ticket_type').
")";
1281 $sql .=
" AND active > 0";
1282 $sql .=
" ORDER BY pos";
1283 dol_syslog(get_class($this).
"::load_cache_type_tickets", LOG_DEBUG);
1284 $resql = $this->db->query($sql);
1286 $num = $this->db->num_rows($resql);
1289 $obj = $this->db->fetch_object($resql);
1290 $label = ($langs->trans(
"TicketTypeShort".$obj->code) !=
"TicketTypeShort".$obj->code ? $langs->trans(
"TicketTypeShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1291 $this->cache_types_tickets[$obj->rowid][
'code'] = $obj->code;
1292 $this->cache_types_tickets[$obj->rowid][
'label'] = $label;
1293 $this->cache_types_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1294 $this->cache_types_tickets[$obj->rowid][
'pos'] = $obj->pos;
1312 global $conf, $langs;
1314 if ($publicgroup == -1 && !empty($this->cache_category_ticket) && count($this->cache_category_tickets)) {
1319 $sql =
"SELECT rowid, code, label, use_default, pos, description, public, active, force_severity, fk_parent";
1320 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_category";
1321 $sql .=
" WHERE entity IN (".getEntity(
'c_ticket_category').
")";
1322 $sql .=
" AND active > 0";
1323 if ($publicgroup > -1) {
1324 $sql .=
" AND public = ".((int) $publicgroup);
1326 $sql .=
" ORDER BY pos";
1328 dol_syslog(get_class($this).
"::load_cache_categories_tickets", LOG_DEBUG);
1330 $resql = $this->db->query($sql);
1332 $num = $this->db->num_rows($resql);
1335 $obj = $this->db->fetch_object($resql);
1336 $this->cache_category_tickets[$obj->rowid][
'code'] = $obj->code;
1337 $this->cache_category_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1338 $this->cache_category_tickets[$obj->rowid][
'pos'] = $obj->pos;
1339 $this->cache_category_tickets[$obj->rowid][
'public'] = $obj->public;
1340 $this->cache_category_tickets[$obj->rowid][
'active'] = $obj->active;
1341 $this->cache_category_tickets[$obj->rowid][
'force_severity'] = $obj->force_severity;
1342 $this->cache_category_tickets[$obj->rowid][
'fk_parent'] = $obj->fk_parent;
1346 $label = ($langs->trans(
"TicketCategoryShort".$obj->code) !=
"TicketCategoryShort".$obj->code ? $langs->trans(
"TicketCategoryShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1347 $this->cache_category_tickets[$obj->rowid][
'label'] = $label;
1367 if (!empty($this->cache_severity_tickets) && count($this->cache_severity_tickets)) {
1372 $sql =
"SELECT rowid, code, label, use_default, pos, description";
1373 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_severity";
1374 $sql .=
" WHERE entity IN (".getEntity(
'c_ticket_severity').
")";
1375 $sql .=
" AND active > 0";
1376 $sql .=
" ORDER BY pos";
1377 dol_syslog(get_class($this).
"::loadCacheSeveritiesTickets", LOG_DEBUG);
1378 $resql = $this->db->query($sql);
1380 $num = $this->db->num_rows($resql);
1383 $obj = $this->db->fetch_object($resql);
1385 $this->cache_severity_tickets[$obj->rowid][
'code'] = $obj->code;
1386 $label = ($langs->trans(
"TicketSeverityShort".$obj->code) !=
"TicketSeverityShort".$obj->code ? $langs->trans(
"TicketSeverityShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1387 $this->cache_severity_tickets[$obj->rowid][
'label'] = $label;
1388 $this->cache_severity_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1389 $this->cache_severity_tickets[$obj->rowid][
'pos'] = $obj->pos;
1408 return $this->LibStatut($this->fk_statut, $mode, 0, $this->progress);
1422 public function LibStatut($status, $mode = 0, $notooltip = 0, $progress = 0)
1425 global $langs, $hookmanager;
1427 $labelStatus = (isset($status) && !empty($this->labelStatus[$status])) ? $this->labelStatus[$status] :
'';
1428 $labelStatusShort = (isset($status) && !empty($this->labelStatusShort[$status]))? $this->labelStatusShort[$status] :
'';
1431 case self::STATUS_NOT_READ:
1432 $statusType =
'status0';
1434 case self::STATUS_READ:
1435 $statusType =
'status1';
1437 case self::STATUS_ASSIGNED:
1438 $statusType =
'status2';
1440 case self::STATUS_IN_PROGRESS:
1441 $statusType =
'status4';
1443 case self::STATUS_WAITING:
1444 $statusType =
'status7';
1446 case self::STATUS_NEED_MORE_INFO:
1447 $statusType =
'status3';
1449 case self::STATUS_CANCELED:
1450 $statusType =
'status9';
1452 case self::STATUS_CLOSED:
1453 $statusType =
'status6';
1456 $labelStatus =
'Unknown';
1457 $labelStatusShort =
'Unknown';
1458 $statusType =
'status0';
1462 $parameters = array(
1463 'status' => $status,
1468 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
1471 return $hookmanager->resPrint;
1476 $params = array(
'tooltip' =>
'no');
1479 $labelStatus = $langs->transnoentitiesnoconv($labelStatus);
1480 $labelStatusShort = $langs->transnoentitiesnoconv($labelStatusShort);
1482 if ($status == self::STATUS_IN_PROGRESS && $progress > 0) {
1483 $labelStatus .=
' ('.round($progress).
'%)';
1484 $labelStatusShort .=
' ('.round($progress).
'%)';
1487 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode,
'', $params);
1501 $langs->load(
'ticket');
1502 $nofetch = !empty($params[
'nofetch']);
1505 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Ticket").
'</u>';
1506 $datas[
'picto'] .=
' '.$this->getLibStatut(4);
1507 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1508 $datas[
'track_id'] =
'<br><b>'.$langs->trans(
'TicketTrackId').
':</b> '.$this->track_id;
1509 $datas[
'subject'] =
'<br><b>'.$langs->trans(
'Subject').
':</b> '.$this->subject;
1510 if ($this->date_creation) {
1511 $datas[
'date_creation'] =
'<br><b>'.$langs->trans(
'DateCreation').
':</b> '.
dol_print_date($this->date_creation,
'dayhour');
1513 if ($this->date_modification) {
1514 $datas[
'date_modification'] =
'<br><b>'.$langs->trans(
'DateModification').
':</b> '.
dol_print_date($this->date_modification,
'dayhour');
1517 if (isModEnabled(
'categorie') && !$nofetch) {
1518 require_once DOL_DOCUMENT_ROOT .
'/categories/class/categorie.class.php';
1519 $form =
new Form($this->db);
1520 $datas[
'categories'] =
'<br>' . $form->showCategories($this->
id, Categorie::TYPE_TICKET, 1);
1536 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
1538 global $action, $conf, $hookmanager, $langs;
1540 if (!empty($conf->dol_no_mouse_hover)) {
1548 'objecttype' => $this->element,
1549 'option' => $option,
1552 $classfortooltip =
'classfortooltip';
1555 $classfortooltip =
'classforajaxtooltip';
1556 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1559 $label = implode($this->getTooltipContentArray($params));
1562 $url = DOL_URL_ROOT.
'/ticket/card.php?id='.$this->id;
1564 if ($option !=
'nolink') {
1566 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1567 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1568 $add_save_lastsearch_values = 1;
1570 if ($add_save_lastsearch_values) {
1571 $url .=
'&save_lastsearch_values=1';
1576 if (empty($notooltip)) {
1578 $label = $langs->trans(
"ShowTicket");
1579 $linkclose .=
' alt="'.dol_escape_htmltag($label, 1).
'"';
1581 $linkclose .= ($label ?
' title="'.dol_escape_htmltag($label, 1).
'"' :
' title="tocomplete"');
1582 $linkclose .= $dataparams.
' class="'.$classfortooltip.($morecss ?
' '.$morecss :
'').
'"';
1584 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1587 $linkstart =
'<a href="'.$url.
'"';
1588 $linkstart .= $linkclose.
'>';
1591 $result .= $linkstart;
1593 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ? $this->picto :
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
1595 if ($withpicto != 2) {
1596 $result .= $this->ref;
1598 $result .= $linkend;
1601 $hookmanager->initHooks(array(
'ticketdao'));
1602 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1603 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1605 $result = $hookmanager->resPrint;
1607 $result .= $hookmanager->resPrint;
1627 if ($this->
statut != self::STATUS_CANCELED) {
1629 $this->
status = Ticket::STATUS_READ;
1631 $oldStatus = $this->fk_statut;
1632 $this->fk_statut = Ticket::STATUS_READ;
1636 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1637 $sql .=
" SET fk_statut = ".$this->status .
", date_read = '".$this->db->idate(
dol_now()).
"'";
1638 $sql .=
" WHERE rowid = ".((int) $this->
id);
1641 $resql = $this->db->query($sql);
1643 $this->context[
'actionmsg'] = $langs->trans(
'TicketLogMesgReadBy', $this->
ref, $user->getFullName($langs));
1644 $this->context[
'actionmsg2'] = $langs->trans(
'TicketLogMesgReadBy', $this->
ref, $user->getFullName($langs));
1648 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1656 $this->db->commit();
1659 $this->fk_statut = $oldStatus;
1660 $this->
status = $this->oldcopy->status;
1662 $this->db->rollback();
1664 $this->error = implode(
',', $this->errors);
1666 dol_syslog(get_class($this).
"::markAsRead ".$this->error, LOG_ERR);
1670 $this->fk_statut = $oldStatus;
1671 $this->
status = $this->oldcopy->status;
1673 $this->db->rollback();
1674 $this->error = $this->db->lasterror();
1675 dol_syslog(get_class($this).
"::markAsRead ".$this->error, LOG_ERR);
1691 public function assignUser($user, $id_assign_user, $notrigger = 0)
1699 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1700 if ($id_assign_user > 0) {
1701 $sql .=
" SET fk_user_assign=".((int) $id_assign_user).
", fk_statut = ".Ticket::STATUS_ASSIGNED;
1703 $sql .=
" SET fk_user_assign=null, fk_statut = ".Ticket::STATUS_READ;
1705 $sql .=
" WHERE rowid = ".((int) $this->
id);
1707 dol_syslog(get_class($this).
"::assignUser sql=".$sql);
1708 $resql = $this->db->query($sql);
1710 $this->fk_user_assign = $id_assign_user;
1714 $result = $this->call_trigger(
'TICKET_ASSIGNED', $user);
1722 $this->db->commit();
1725 $this->db->rollback();
1726 $this->error = join(
',', $this->errors);
1727 dol_syslog(get_class($this).
"::assignUser ".$this->error, LOG_ERR);
1731 $this->db->rollback();
1732 $this->error = $this->db->lasterror();
1733 dol_syslog(get_class($this).
"::assignUser ".$this->error, LOG_ERR);
1750 public function createTicketMessage($user, $notrigger = 0, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $send_email =
false, $public_area = 0)
1752 global $conf, $langs;
1758 if (isset($this->fk_track_id)) {
1759 $this->fk_track_id = trim($this->fk_track_id);
1762 if (isset($this->message)) {
1763 $this->message = trim($this->message);
1769 include_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
1771 $actioncomm->type_code =
'AC_OTH_AUTO';
1772 $actioncomm->code =
'TICKET_MSG';
1773 if ($this->
private) {
1774 $actioncomm->code =
'TICKET_MSG_PRIVATE';
1777 $actioncomm->code .=
'_SENTBYMAIL';
1779 if ((empty($user->id) || $user->id == 0) && isset($_SESSION[
'email_customer'])) {
1780 $actioncomm->email_from = $_SESSION[
'email_customer'];
1782 $actioncomm->socid = $this->socid;
1783 $actioncomm->label = $this->subject;
1784 $actioncomm->note_private = $this->message;
1785 $actioncomm->userassigned = array($user->id);
1786 $actioncomm->userownerid = $user->id;
1787 $actioncomm->datep = $now;
1788 $actioncomm->percentage = -1;
1789 $actioncomm->elementtype =
'ticket';
1790 $actioncomm->fk_element = $this->id;
1791 $actioncomm->fk_project = $this->fk_project;
1794 if ($public_area && !empty($this->origin_email) &&
getDolGlobalString(
'TICKET_ASSIGN_CONTACT_TO_MESSAGE')) {
1795 $contacts = $this->searchContactByEmail($this->origin_email);
1796 if (!empty($contacts)) {
1798 foreach ($contacts as $contact) {
1799 if ((
int) $contact->statut == 1) {
1800 $actioncomm->contact_id = $contact->id;
1807 $attachedfiles = array();
1808 $attachedfiles[
'paths'] = $filename_list;
1809 $attachedfiles[
'names'] = $mimefilename_list;
1810 $attachedfiles[
'mimes'] = $mimetype_list;
1811 if (is_array($attachedfiles) && count($attachedfiles) > 0) {
1812 $actioncomm->attachedfiles = $attachedfiles;
1815 if (!empty($mimefilename_list) && is_array($mimefilename_list)) {
1816 $actioncomm->note_private =
dol_concatdesc($actioncomm->note_private,
"\n".$langs->transnoentities(
"AttachedFiles").
': '.join(
';', $mimefilename_list));
1819 $actionid = $actioncomm->create($user);
1820 if ($actionid <= 0) {
1822 $this->error = $actioncomm->error;
1823 $this->errors = $actioncomm->errors;
1828 $this->db->rollback();
1831 $this->db->commit();
1843 if (!empty($this->cache_msgs_ticket) && is_array($this->cache_msgs_ticket) && count($this->cache_msgs_ticket)) {
1849 $sql =
"SELECT id as rowid, fk_user_author, email_from, datec, datep, label, note as message, code";
1850 $sql .=
" FROM ".MAIN_DB_PREFIX.
"actioncomm";
1851 $sql .=
" WHERE fk_element = ".(int) $this->
id;
1852 $sql .=
" AND elementtype = 'ticket'";
1853 $sql .=
" ORDER BY datep DESC";
1855 dol_syslog(get_class($this).
"::load_cache_actions_ticket", LOG_DEBUG);
1856 $resql = $this->db->query($sql);
1858 $num = $this->db->num_rows($resql);
1861 $obj = $this->db->fetch_object($resql);
1862 $this->cache_msgs_ticket[$i][
'id'] = $obj->rowid;
1863 $this->cache_msgs_ticket[$i][
'fk_user_author'] = $obj->fk_user_author;
1864 if ($obj->code ==
'TICKET_MSG' && empty($obj->fk_user_author)) {
1865 $this->cache_msgs_ticket[$i][
'fk_contact_author'] = $obj->email_from;
1867 $this->cache_msgs_ticket[$i][
'datec'] = $this->db->jdate($obj->datec);
1868 $this->cache_msgs_ticket[$i][
'datep'] = $this->db->jdate($obj->datep);
1869 $this->cache_msgs_ticket[$i][
'subject'] = $obj->label;
1870 $this->cache_msgs_ticket[$i][
'message'] = $obj->message;
1871 $this->cache_msgs_ticket[$i][
'private'] = (preg_match(
'/^TICKET_MSG_PRIVATE/', $obj->code) ? 1 : 0);
1876 $this->error =
"Error ".$this->db->lasterror();
1877 dol_syslog(get_class($this).
"::load_cache_actions_ticket ".$this->error, LOG_ERR);
1893 if ($this->
status != Ticket::STATUS_CLOSED && $this->
status != Ticket::STATUS_CANCELED) {
1896 $this->
status = ($mode ? Ticket::STATUS_CANCELED : Ticket::STATUS_CLOSED);
1898 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1899 $sql .=
" SET fk_statut=".$this->status.
", progress=100, date_close='".$this->db->idate(
dol_now()).
"'";
1900 $sql .=
" WHERE rowid = ".((int) $this->
id);
1902 dol_syslog(get_class($this).
"::close mode=".$mode);
1903 $resql = $this->db->query($sql);
1908 if (isModEnabled(
'ficheinter') &&
getDolGlobalString(
'WORKFLOW_TICKET_CLOSE_INTERVENTION')) {
1909 dol_syslog(
"We have closed the ticket, so we close all linked interventions");
1910 $this->fetchObjectLinked($this->
id, $this->element,
null,
'fichinter');
1911 if ($this->linkedObjectsIds) {
1912 foreach ($this->linkedObjectsIds[
'fichinter'] as $fichinter_id) {
1914 $fichinter->fetch($fichinter_id);
1915 if ($fichinter->statut == 0) {
1916 $result = $fichinter->setValid($user);
1918 $this->errors[] = $fichinter->error;
1922 if ($fichinter->statut < 3) {
1923 $result = $fichinter->setStatut(3);
1925 $this->errors[] = $fichinter->error;
1934 $result = $this->call_trigger(
'TICKET_CLOSE', $user);
1941 $this->db->commit();
1944 $this->db->rollback();
1945 $this->error = join(
',', $this->errors);
1946 dol_syslog(get_class($this).
"::close ".$this->error, LOG_ERR);
1950 $this->db->rollback();
1951 $this->error = $this->db->lasterror();
1952 dol_syslog(get_class($this).
"::close ".$this->error, LOG_ERR);
1971 $thirdparties = array();
1975 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"societe";
1976 $sql .=
" WHERE entity IN (".getEntity(
'ticket', 1).
")";
1977 if (!empty($type)) {
1978 if ($type == 1 || $type == 2) {
1979 $sql .=
" AND client = ".((int) $type);
1980 } elseif ($type == 3) {
1981 $sql .=
" AND fournisseur = 1";
1984 if (!empty($email)) {
1985 if (empty($exact)) {
1987 if (preg_match(
'/^([\*])?[^*]+([\*])?$/', $email, $regs) && count($regs) > 1) {
1988 $email = str_replace(
'*',
'%', $email);
1990 $email =
'%'.$email.
'%';
1994 if (is_array($filters) && !empty($filters)) {
1998 $sql .=
"email LIKE '".$this->db->escape($email).
"'";
2000 if (is_array($filters) && !empty($filters)) {
2001 foreach ($filters as $field => $value) {
2002 $sql .=
" ".$clause.
" ".$field.
" LIKE '".$this->db->escape($value).
"'";
2004 if (!empty($email)) {
2009 $res = $this->db->query($sql);
2011 while ($rec = $this->db->fetch_array($res)) {
2012 $soc =
new Societe($this->db);
2013 $soc->fetch($rec[
'rowid']);
2014 $thirdparties[] = $soc;
2017 return $thirdparties;
2019 $this->error = $this->db->error().
' sql='.$sql;
2020 dol_syslog(get_class($this).
"::searchSocidByEmail ".$this->error, LOG_ERR);
2035 $contacts = array();
2038 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"socpeople";
2039 $sql .=
" WHERE entity IN (".getEntity(
'contact').
")";
2040 if (!empty($socid)) {
2041 $sql .=
" AND fk_soc = ".((int) $socid);
2043 if (!empty($email)) {
2046 $sql .=
"email = '".$this->db->escape($email).
"'";
2048 $sql .=
"email LIKE BINARY '".$this->db->escape($this->db->escapeforlike($email)).
"'";
2052 $res = $this->db->query($sql);
2054 while ($rec = $this->db->fetch_object($res)) {
2055 include_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
2056 $contactstatic =
new Contact($this->db);
2057 $contactstatic->fetch($rec->rowid);
2058 $contacts[] = $contactstatic;
2063 $this->error = $this->db->error().
' sql='.$sql;
2064 dol_syslog(get_class($this).
"::searchContactByEmail ".$this->error, LOG_ERR);
2078 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2079 $sql .=
" SET fk_soc = ".($id > 0 ? $id :
"null");
2080 $sql .=
" WHERE rowid = ".((int) $this->
id);
2081 dol_syslog(get_class($this).
'::setCustomer sql='.$sql);
2082 $resql = $this->db->query($sql);
2102 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2103 $sql .=
" SET progress = ".($percent > 0 ? $percent :
"null");
2104 $sql .=
" WHERE rowid = ".((int) $this->
id);
2105 dol_syslog(get_class($this).
'::set_progression sql='.$sql);
2106 $resql = $this->db->query($sql);
2126 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2127 $sql .=
" SET fk_contract = ".($contractid > 0 ? $contractid :
"null");
2128 $sql .=
" WHERE rowid = ".((int) $this->
id);
2129 dol_syslog(get_class($this).
'::setContract sql='.$sql);
2130 $resql = $this->db->query($sql);
2150 return $this->getIdContact(
'internal',
'SUPPORTTEC');
2161 return $this->listeContact(-1,
'internal', 0,
'', $status);
2171 return $this->getIdContact(
'external',
'SUPPORTCLI');
2182 return $this->listeContact(-1,
'external', 0,
'', $status);
2192 return $this->getIdContact(
'internal',
'CONTRIBUTOR');
2202 return $this->getIdContact(
'external',
'CONTRIBUTOR');
2212 $array_contact = array();
2214 $array_contact = $this->getIdTicketInternalContact();
2216 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact());
2218 $array_contact = array_merge($array_contact, $this->getIdTicketInternalInvolvedContact());
2220 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact());
2222 return $array_contact;
2232 $array_contact = array();
2234 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact());
2236 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact());
2238 return $array_contact;
2253 public function listeContact($statusoflink = -1, $source =
'external', $list = 0, $code =
'', $status = -1)
2259 $sql =
"SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact";
2260 if ($source ==
'internal') {
2261 $sql .=
", '-1' as socid, t.statut as statuscontact";
2264 if ($source ==
'external' || $source ==
'thirdparty') {
2265 $sql .=
", t.fk_soc as socid, t.statut as statuscontact";
2268 $sql .=
", t.civility, t.lastname as lastname, t.firstname, t.email";
2269 if ($source ==
'internal') {
2270 $sql .=
", t.office_phone as phone, t.user_mobile as phone_mobile";
2273 if ($source ==
'external') {
2274 $sql .=
", t.phone as phone, t.phone_mobile as phone_mobile, t.phone_perso as phone_perso";
2277 $sql .=
", tc.source, tc.element, tc.code, tc.libelle as type_contact_label";
2278 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_contact tc";
2279 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact ec";
2280 if ($source ==
'internal') {
2281 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user t on ec.fk_socpeople = t.rowid";
2284 if ($source ==
'external' || $source ==
'thirdparty') {
2285 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"socpeople t on ec.fk_socpeople = t.rowid";
2288 $sql .=
" WHERE ec.element_id = ".((int) $this->
id);
2289 $sql .=
" AND ec.fk_c_type_contact=tc.rowid";
2290 $sql .=
" AND tc.element='".$this->db->escape($this->element).
"'";
2291 if ($source ==
'internal') {
2292 $sql .=
" AND tc.source = 'internal'";
2294 $sql .=
" AND t.statut = ".((int) $status);
2298 if ($source ==
'external' || $source ==
'thirdparty') {
2299 $sql .=
" AND tc.source = 'external'";
2301 $sql .=
" AND t.statut = ".((int) $status);
2305 if (!empty($code)) {
2306 $sql .=
" AND tc.code = '".$this->db->escape($code).
"'";
2309 $sql .=
" AND tc.active=1";
2310 if ($statusoflink >= 0) {
2311 $sql .=
" AND ec.statut = ".((int) $statusoflink);
2314 $sql .=
" ORDER BY t.lastname ASC";
2316 $resql = $this->db->query($sql);
2318 $num = $this->db->num_rows($resql);
2321 $obj = $this->db->fetch_object($resql);
2324 $transkey =
"TypeContact_".$obj->element.
"_".$obj->source.
"_".$obj->code;
2325 $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_contact_label);
2327 'source' => $obj->source,
2328 'socid' => $obj->socid,
2330 'nom' => $obj->lastname,
2331 'civility' => $obj->civility,
2332 'lastname' => $obj->lastname,
2333 'firstname' => $obj->firstname,
2334 'email' => $obj->email,
2335 'rowid' => $obj->rowid,
2336 'code' => $obj->code,
2337 'libelle' => $libelle_type,
2338 'status' => $obj->statuslink,
2339 'statuscontact'=>$obj->statuscontact,
2340 'fk_c_type_contact' => $obj->fk_c_type_contact,
2341 'phone' => $obj->phone,
2342 'phone_mobile' => $obj->phone_mobile);
2344 $tab[$i] = $obj->id;
2352 $this->error = $this->db->error();
2375 $dirmodels = array_merge(array(
'/'), (array) $conf->modules_parts[
'models']);
2376 foreach ($dirmodels as $reldir) {
2377 $file =
dol_buildpath($reldir.
"core/modules/ticket/".$modele.
'.php', 0);
2378 if (file_exists($file)) {
2380 $classname = $modele;
2387 $modTicket =
new $classname();
2389 $defaultref = $modTicket->getNextValue($thirdparty, $this);
2392 if (is_numeric($defaultref) && $defaultref <= 0) {
2410 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2418 if (file_exists($dir_osencoded)) {
2419 $handle = opendir($dir_osencoded);
2420 if (is_resource($handle)) {
2421 while (($file = readdir($handle)) !==
false) {
2423 $file = mb_convert_encoding($file,
'UTF-8',
'ISO-8859-1');
2448 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
2449 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2450 include_once DOL_DOCUMENT_ROOT.
'/core/lib/images.lib.php';
2452 $maxwidthsmall = 270;
2453 $maxheightsmall = 150;
2454 $maxwidthmini = 128;
2455 $maxheightmini = 72;
2457 $formmail =
new FormMail($this->db);
2458 $formmail->trackid = (is_null($forcetrackid) ?
'tic'.$this->id :
'');
2459 $attachedfiles = $formmail->get_attached_files();
2461 $filepath = $attachedfiles[
'paths'];
2462 $filename = $attachedfiles[
'names'];
2463 $mimetype = $attachedfiles[
'mimes'];
2466 $destdir = $conf->ticket->dir_output.
'/'.$this->ref;
2472 $listofpaths = array();
2473 $listofnames = array();
2474 foreach ($filename as $i => $val) {
2475 $destfile = $destdir.
'/'.$filename[$i];
2477 if (is_file($destfile)) {
2478 $pathinfo = pathinfo($filename[$i]);
2480 $destfile = $destdir.
'/'.$pathinfo[
'filename'].
' - '.
dol_print_date($now,
'dayhourlog').
'.'.$pathinfo[
'extension'];
2483 $moreinfo = array(
'description'=>
'File saved by copyFilesForTicket',
'src_object_type' => $this->element,
'src_object_id' => $this->
id);
2484 $res =
dol_move($filepath[$i], $destfile, 0, 1, 0, 1, $moreinfo);
2487 $this->error =
"Failed to move file ".dirbasename($filepath[$i]).
" into ".
dirbasename($destfile);
2494 $imgThumbSmall =
vignette($destfile, $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
2497 $imgThumbMini =
vignette($destfile, $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
2502 $formmail->remove_attached_files($i);
2505 $listofpaths[$i] = $destfile;
2506 $listofnames[$i] = basename($destfile);
2509 return array(
'listofpaths'=>$listofpaths,
'listofnames'=>$listofnames,
'listofmimes'=>$mimetype);
2525 if (!is_array($categories)) {
2526 $categories = array($categories);
2530 include_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2532 $existing = $c->containing($this->
id, Categorie::TYPE_TICKET,
'id');
2535 if (is_array($existing)) {
2536 $to_del = array_diff($existing, $categories);
2537 $to_add = array_diff($categories, $existing);
2540 $to_add = $categories;
2544 foreach ($to_del as $del) {
2545 if ($c->fetch($del) > 0) {
2546 $c->del_type($this, Categorie::TYPE_TICKET);
2549 foreach ($to_add as $add) {
2550 if ($c->fetch($add) > 0) {
2551 $c->add_type($this, Categorie::TYPE_TICKET);
2570 public function newMessage($user, &$action, $private = 1, $public_area = 0)
2572 global $mysoc, $conf, $langs;
2576 $object =
new Ticket($this->db);
2578 $ret = $object->fetch(
'',
'',
GETPOST(
'track_id',
'alpha'));
2580 $object->socid = $object->fk_soc;
2581 $object->fetch_thirdparty();
2582 $object->fetch_project();
2586 array_push($this->errors, $langs->trans(
"ErrorTicketIsNotValid"));
2592 array_push($this->errors, $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"message")));
2593 $action =
'add_message';
2597 $object->subject =
GETPOST(
'subject',
'alphanohtml');
2598 $object->message =
GETPOST(
"message",
"restricthtml");
2599 $object->private =
GETPOST(
"private_message",
"alpha");
2601 $send_email =
GETPOST(
'send_email',
'int');
2604 $resarray = $object->copyFilesForTicket();
2605 if (is_numeric($resarray) && $resarray == -1) {
2610 $listofpaths = $resarray[
'listofpaths'];
2611 $listofnames = $resarray[
'listofnames'];
2612 $listofmimes = $resarray[
'listofmimes'];
2614 $id = $object->createTicketMessage($user, 0, $listofpaths, $listofmimes, $listofnames, $send_email, $public_area);
2617 $this->error = $object->error;
2618 $this->errors = $object->errors;
2619 $action =
'add_message';
2622 if (!$error && $id > 0) {
2623 setEventMessages($langs->trans(
'TicketMessageSuccessfullyAdded'),
null,
'mesgs');
2628 if (!empty($public_area)) {
2636 $internal_contacts = $object->getInfosTicketInternalContact(1);
2638 $assigned_user_dont_have_email =
'';
2642 if ($this->fk_user_assign > 0) {
2643 $assigned_user =
new User($this->db);
2644 $assigned_user->fetch($this->fk_user_assign);
2645 if (!empty($assigned_user->email)) {
2646 $sendto[$assigned_user->email] = $assigned_user->getFullName($langs).
" <".$assigned_user->email.
">";
2648 $assigned_user_dont_have_email = $assigned_user->getFullName($langs);
2653 foreach ($internal_contacts as $key => $info_sendto) {
2655 if ($info_sendto[
'id'] == $user->id) {
2660 if (!empty($info_sendto[
'email']) && $assigned_user->email != $info_sendto[
'email']) {
2661 $sendto[] =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2665 if (empty($sendto)) {
2680 if (!empty($sendto)) {
2683 $subject =
'['.$appli.
'- ticket #'.$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
2686 $message =
getDolGlobalString(
'TICKET_MESSAGE_MAIL_INTRO', $langs->trans(
'TicketMessageMailIntroText'));
2687 $message .=
'<br><br>';
2688 $messagePost =
GETPOST(
'message',
'restricthtml');
2692 $message .= $messagePost;
2695 $message .=
'<br><br>';
2696 $message .=
"==============================================";
2697 $message .= !empty($object->thirdparty->name) ?
'<br>'.$langs->trans(
'Thirdparty').
" : ".$object->thirdparty->name :
'';
2698 $message .= !empty($object->thirdparty->town) ?
'<br>'.$langs->trans(
'Town').
" : ".$object->thirdparty->town :
'';
2699 $message .= !empty($object->thirdparty->phone) ?
'<br>'.$langs->trans(
'Phone').
" : ".$object->thirdparty->phone :
'';
2702 $message .=
'<br><br>';
2703 if (!empty($assigned_user_dont_have_email)) {
2704 $message .=
'<br>'.$langs->trans(
'NoEMail').
' : '.$assigned_user_dont_have_email;
2706 foreach ($sendto as $val) {
2707 $message .=
'<br>'.$langs->trans(
'TicketNotificationRecipient').
' : '.$val;
2711 $url_internal_ticket =
dol_buildpath(
'/ticket/card.php', 2).
'?track_id='.$object->track_id;
2712 $message .=
'<br><br>';
2713 $message .= $langs->trans(
'TicketNotificationEmailBodyInfosTrackUrlinternal').
' : <a href="'.$url_internal_ticket.
'">'.$object->track_id.
'</a>';
2715 $this->sendTicketMessageByEmail($subject, $message,
'', $sendto, $listofpaths, $listofmimes, $listofnames);
2724 if ($send_email > 0) {
2726 $internal_contacts = $object->getInfosTicketInternalContact(1);
2729 if (is_array($internal_contacts) && count($internal_contacts) > 0) {
2733 $subject =
GETPOST(
'subject',
'alphanohtml') ?
GETPOST(
'subject',
'alphanohtml') :
'['.$appli.
' - '.$langs->trans(
"Ticket").
' #'.$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
2735 $message_intro = $langs->trans(
'TicketNotificationEmailBody',
"#".$object->id);
2738 $message =
getDolGlobalString(
'TICKET_MESSAGE_MAIL_INTRO', $langs->trans(
'TicketMessageMailIntroText'));
2739 $message .=
'<br><br>';
2740 $messagePost =
GETPOST(
'message',
'restricthtml');
2744 $message .= $messagePost;
2747 $message .=
'<br><br>';
2748 $message .=
"==============================================<br>";
2749 $message .= !empty($object->thirdparty->name) ? $langs->trans(
'Thirdparty').
" : ".$object->thirdparty->name :
'';
2750 $message .= !empty($object->thirdparty->town) ?
'<br>'.$langs->trans(
'Town').
" : ".$object->thirdparty->town :
'';
2751 $message .= !empty($object->thirdparty->phone) ?
'<br>'.$langs->trans(
'Phone').
" : ".$object->thirdparty->phone :
'';
2754 foreach ($internal_contacts as $key => $info_sendto) {
2756 if ($info_sendto[
'id'] == $user->id) {
2760 if ($info_sendto[
'email'] !=
'') {
2761 if (!empty($info_sendto[
'email'])) {
2762 $sendto[$info_sendto[
'email']] =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2766 $recipient =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname'],
'-1').
' ('.strtolower($info_sendto[
'libelle']).
')';
2767 $message .= (!empty($recipient) ? $langs->trans(
'TicketNotificationRecipient').
' : '.$recipient.
'<br>' :
'');
2772 $url_internal_ticket =
dol_buildpath(
'/ticket/card.php', 2).
'?track_id='.$object->track_id;
2775 $message .=
'<br>'.$langs->trans(
'TicketNotificationEmailBodyInfosTrackUrlinternal').
' : <a href="'.$url_internal_ticket.
'">'.$object->track_id.
'</a><br>';
2785 if (!empty($sendto)) {
2786 $this->sendTicketMessageByEmail($subject, $message,
'', $sendto, $listofpaths, $listofmimes, $listofnames);
2793 if (empty($object->private)) {
2795 $external_contacts = $object->getInfosTicketExternalContact(1);
2798 if (is_array($external_contacts) && count($external_contacts) === 0) {
2799 if (!empty($object->fk_soc)) {
2800 $object->fetch_thirdparty($object->fk_soc);
2801 $array_company = array(array(
'firstname' =>
'',
'lastname' => $object->thirdparty->name,
'email' => $object->thirdparty->email,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' => $object->thirdparty->id));
2802 $external_contacts = array_merge($external_contacts, $array_company);
2803 } elseif (empty($object->fk_soc) && !empty($object->origin_email)) {
2804 $array_external = array(array(
'firstname' =>
'',
'lastname' => $object->origin_email,
'email' => $object->thirdparty->email,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' => $object->thirdparty->id));
2805 $external_contacts = array_merge($external_contacts, $array_external);
2810 if (is_array($external_contacts) && count($external_contacts) > 0) {
2814 $subject =
GETPOST(
'subject') ?
GETPOST(
'subject') :
'['.$appli.
' - '.$langs->trans(
"Ticket").
' #'.$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
2819 $message_intro =
dol_nl2br($message_intro);
2822 $message_signature =
dol_nl2br($message_signature);
2826 $messagePost =
GETPOST(
'message',
'restricthtml');
2830 $message = $messagePost;
2831 $message .=
'<br><br>';
2833 foreach ($external_contacts as $key => $info_sendto) {
2835 if ($info_sendto[
'id'] == $user->contact_id) {
2839 if ($info_sendto[
'email'] !=
'' && $info_sendto[
'email'] != $object->origin_email) {
2840 if (!empty($info_sendto[
'email'])) {
2841 $sendto[$info_sendto[
'email']] = trim($info_sendto[
'firstname'].
" ".$info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2844 $recipient =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname'],
'-1').
' ('.strtolower($info_sendto[
'libelle']).
')';
2845 $message .= (!empty($recipient) ? $langs->trans(
'TicketNotificationRecipient').
' : '.$recipient.
'<br>' :
'');
2850 $url_public_ticket = (
getDolGlobalInt(
'TICKET_ENABLE_PUBLIC_INTERFACE') ?
2853 $message .=
'<br>'.$langs->trans(
'TicketNewEmailBodyInfosTrackUrlCustomer').
' : <a href="'.$url_public_ticket.
'">'.$object->track_id.
'</a><br>';
2856 $message = $message_intro.
'<br><br>'.$message;
2859 $message .=
'<br>'.$message_signature;
2861 if (!empty($object->origin_email)) {
2862 $sendto[$object->origin_email] = $object->origin_email;
2865 if ($object->fk_soc > 0 && !array_key_exists($object->origin_email, $sendto)) {
2866 $object->socid = $object->fk_soc;
2867 $object->fetch_thirdparty();
2868 if (!empty($object->thirdparty->email)) {
2869 $sendto[$object->thirdparty->email] = $object->thirdparty->email;
2881 if (!empty($sendto)) {
2882 $result = $this->sendTicketMessageByEmail($subject, $message,
'', $sendto, $listofpaths, $listofmimes, $listofnames);
2885 $this->date_last_msg_sent =
dol_now();
2886 $this->update($user, 1);
2897 if (($object->status < self::STATUS_IN_PROGRESS && !$user->socid && !$private) ||
2898 ($object->status > self::STATUS_IN_PROGRESS && $public_area)
2900 $object->setStatut($object::STATUS_IN_PROGRESS,
null,
'',
'TICKET_MODIFY');
2926 public function sendTicketMessageByEmail($subject, $message, $send_internal_cc = 0, $array_receiver = array(), $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array())
2928 global $conf, $langs, $user;
2931 dol_syslog(get_class($this).
'::sendTicketMessageByEmail: Emails are disable into ticket setup by option TICKET_DISABLE_ALL_MAILS', LOG_WARNING);
2935 $langs->load(
"mails");
2937 include_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
2941 if (!is_array($array_receiver) || !count($array_receiver) > 0) {
2942 $array_receiver = $this->getInfosTicketInternalContact(1);
2943 $array_receiver = array_merge($array_receiver, $this->getInfosTicketExternalContact(1));
2947 if ($send_internal_cc) {
2955 if (is_array($array_receiver) && count($array_receiver) > 0) {
2956 foreach ($array_receiver as $key => $receiver) {
2957 $deliveryreceipt = 0;
2958 $filepath = $filename_list;
2959 $filename = $mimefilename_list;
2960 $mimetype = $mimetype_list;
2966 $conf->global->MAIN_MAIL_AUTOCOPY_TO =
'';
2969 $upload_dir_tmp = $conf->user->dir_output.
"/".$user->id.
'/temp';
2971 include_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
2972 $trackid =
"tic".$this->id;
2974 $moreinheader =
'X-Dolibarr-Info: sendTicketMessageByEmail'.
"\r\n";
2975 if (!empty($this->email_msgid)) {
2977 $moreinheader .=
'In-Reply-To: <'.$this->email_msgid.
'>'.
"\r\n";
2980 $mailfile =
new CMailFile($subject, $receiver, $from, $message, $filepath, $mimetype, $filename, $sendtocc,
'', $deliveryreceipt, -1,
'',
'', $trackid, $moreinheader,
'ticket',
'', $upload_dir_tmp);
2982 if ($mailfile->error) {
2985 $result = $mailfile->sendfile();
2987 setEventMessages($langs->trans(
'MailSuccessfulySent', $mailfile->getValidAddress($from, 2), $mailfile->getValidAddress($receiver, 2)),
null,
'mesgs');
2990 $langs->load(
"other");
2991 if ($mailfile->error) {
2992 setEventMessages($langs->trans(
'ErrorFailedToSendMail', $from, $receiver),
null,
'errors');
2993 dol_syslog($langs->trans(
'ErrorFailedToSendMail', $from, $receiver).
' : '.$mailfile->error);
2995 setEventMessages(
'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS',
null,
'errors');
3001 $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
3005 $langs->load(
"other");
3006 setEventMessages($langs->trans(
'ErrorMailRecipientIsEmptyForSendTicketMessage'),
null,
'warnings');
3023 global $user, $langs;
3030 $sql =
"SELECT p.rowid, p.ref, p.datec as datec";
3031 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as p";
3032 if (isModEnabled(
'societe') && !$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3033 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3034 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3037 $sql .= $clause.
" p.entity IN (".
getEntity(
'ticket').
")";
3038 if ($mode ==
'opened') {
3039 $sql .=
" AND p.fk_statut NOT IN (".Ticket::STATUS_CLOSED.
", ".Ticket::STATUS_CANCELED.
")";
3042 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3045 $resql = $this->db->query($sql);
3047 $label = $labelShort =
'';
3049 if ($mode ==
'opened') {
3050 $status =
'openall';
3053 $label = $langs->trans(
"MenuListNonClosed");
3054 $labelShort = $langs->trans(
"MenuListNonClosed");
3059 $response->label = $label;
3060 $response->labelShort = $labelShort;
3061 $response->url = DOL_URL_ROOT.
'/ticket/list.php?search_fk_statut[]='.$status;
3065 while ($obj = $this->db->fetch_object($resql)) {
3066 $response->nbtodo++;
3067 if ($mode ==
'opened') {
3068 $datelimit = $this->db->jdate($obj->datec) + $delay_warning;
3069 if ($datelimit < $now) {
3076 $this->error = $this->db->lasterror();
3090 global $conf, $user;
3092 $this->nb = array();
3095 $sql =
"SELECT count(p.rowid) as nb";
3096 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as p";
3097 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3098 if (!$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3099 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3100 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3103 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'ticket').
")";
3105 $resql = $this->db->query($sql);
3108 while ($obj = $this->db->fetch_object($resql)) {
3109 $this->nb[
"ticket"] = $obj->nb;
3111 $this->db->free($resql);
3115 $this->error = $this->db->lasterror();
3130 $tables = array(
'ticket');
3146 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3148 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3149 $return .=
'<div class="info-box info-box-sm">';
3150 $return .=
'<span class="info-box-icon bg-infobox-action">';
3152 $return .=
'</span>';
3153 $return .=
'<div class="info-box-content">';
3154 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->getNomUrl(1) : $this->ref).
'</span>';
3155 if ($selected >= 0) {
3156 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
3158 if (!empty($arraydata[
'user_assignment'])) {
3159 $return .=
'<br><span class="info-box-label" title="'.dol_escape_htmltag($langs->trans(
"AssignedTo")).
'">'.$arraydata[
'user_assignment'].
'</span>';
3161 if (property_exists($this,
'type_code') && !empty($this->type_code)) {
3163 $return .=
'<div class="tdoverflowmax125 inline-block">'.$langs->getLabelFromKey($this->db,
'TicketTypeShort'.$this->type_code,
'c_ticket_type',
'code',
'label', $this->type_code).
'</div>';
3165 if (method_exists($this,
'getLibStatut')) {
3166 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
3168 $return .=
'</div>';
3169 $return .=
'</div>';
3170 $return .=
'</div>';
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Class to manage agenda events (actions)
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class to manage categories.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Class to manage interventions.
Class to manage third parties objects (customers, suppliers, prospects...)
$email_from
Email from user.
static replaceThirdparty($db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
fetch($id='', $ref='', $track_id='', $email_msgid='')
Load object in memory from the database.
listeContact($statusoflink=-1, $source='external', $list=0, $code='', $status=-1)
Get array of all contacts for a ticket Override method of file commonobject.class....
loadCacheMsgsTicket()
Load the list of event on ticket into ->cache_msgs_ticket.
setProgression($percent)
Define progression of current ticket.
loadCacheSeveritiesTickets()
Charge dans cache la liste des sévérité de tickets (paramétrable dans dictionnaire)
$fields
'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]',...
getInfosTicketExternalContact($status=-1)
Retrieve informations about external contacts.
searchContactByEmail($email, $socid='', $case='')
Search and fetch contacts by email.
getIdTicketCustomerInvolvedContact()
Return id des contacts clients des intervenants.
LibStatut($status, $mode=0, $notooltip=0, $progress=0)
Return status label of object.
setContract($contractid)
Link element with a contract.
getTicketAllContacts()
Return id of all contacts for ticket.
createFromClone(User $user, $fromid)
Load an object from its id and create a new one in database.
assignUser($user, $id_assign_user, $notrigger=0)
Set an assigned user to a ticket.
getTooltipContentArray($params)
getTooltipContentArray
load_state_board()
Load indicator this->nb of global stats widget.
getKanbanView($option='', $arraydata=null)
Return clicable link of object (with eventually picto)
printSelectStatus($selected="")
Print selected status.
is_photo_available($sdir)
Return if at least one photo is available.
getIdTicketInternalContact()
Return id des contacts interne de suivi.
update($user, $notrigger=0)
Update object into database.
fetchAll($user, $sortorder='ASC', $sortfield='t.datec', $limit='', $offset=0, $arch='', $filter='')
Load all objects in memory from database.
loadCacheCategoriesTickets($publicgroup=-1)
Load into a cache array, the list of ticket categories (setup done into dictionary)
setCustomer($id)
Define parent commany of current ticket.
markAsRead($user, $notrigger=0)
Mark a message as read.
getDefaultRef($thirdparty='')
Get a default reference.
sendTicketMessageByEmail($subject, $message, $send_internal_cc=0, $array_receiver=array(), $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array())
Send ticket by email to linked contacts.
const STATUS_NOT_READ
Status.
__construct($db)
Constructor.
getTicketAllCustomerContacts()
Return id of all contacts for ticket.
$category_label
Category label.
searchSocidByEmail($email, $type='0', $filters=array(), $clause='AND')
Search and fetch thirparties by email.
$severity_label
Severity label.
createTicketMessage($user, $notrigger=0, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $send_email=false, $public_area=0)
Add message into database.
verify()
Check properties of ticket are ok (like ref, track_id, ...).
setCategories($categories)
Sets object to supplied categories.
initAsSpecimen()
Initialise object with example values Id must be 0 if object instance is a specimen.
newMessage($user, &$action, $private=1, $public_area=0)
Add new message on a ticket (private/public area).
$subject
var string Ticket subject
getIdTicketCustomerContact()
Return id des contacts clients pour le suivi ticket.
loadCacheTypesTickets()
Load into a cache the types of tickets (setup done into dictionaries)
getLibStatut($mode=0)
Return status label of object.
close(User $user, $mode=0)
Close a ticket.
getIdTicketInternalInvolvedContact()
Return id des contacts clients des intervenants.
copyFilesForTicket($forcetrackid=null)
Copy files defined into $_SESSION array into the ticket directory of attached files.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionaly the picto)
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
getInfosTicketInternalContact($status=-1)
Retrieve informations about internal contacts.
create($user, $notrigger=0)
Create object into database.
Class to manage Dolibarr users.
dirbasename($pathfile)
Return the relative dirname (relative to DOL_DATA_ROOT) of a full path string.
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array())
Move a file into another name.
dol_is_file($pathoffile)
Return if path is a file.
dol_is_dir($folder)
Test if filename is a directory.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dol_nl2br($stringtoencode, $nl2brmode=0, $forxml=false)
Replace CRLF in string with a HTML BR tag.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
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_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)
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_clone($object, $native=0)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_concatdesc($text1, $text2, $forxml=false, $invert=false)
Concat 2 descriptions with a new line between them (second operand after first one with appropriate n...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
utf8_check($str)
Check if a string is in UTF8.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
vignette($file, $maxWidth=160, $maxHeight=120, $extName='_small', $quality=50, $outdir='thumbs', $targetformat=0)
Create a thumbnail from an image file (Supported extensions are gif, jpg, png and bmp).
image_format_supported($file, $acceptsvg=0)
Return if a filename is file name of a supported image format.
publicphonebutton2 phonegreen basiclayout basiclayout TotalHT VATCode TotalVAT TotalLT1 TotalLT2 TotalTTC TotalHT clearboth nowraponall right right takeposterminal SELECT e e e e e statut
Class to generate the form for creating a new ticket.
generate_random_id($car=16)
Generate a random id.