33require_once DOL_DOCUMENT_ROOT.
"/core/class/commonobject.class.php";
34require_once DOL_DOCUMENT_ROOT.
'/fichinter/class/fichinter.class.php';
35require_once DOL_DOCUMENT_ROOT.
'/core/lib/ticket.lib.php';
51 public $element =
'ticket';
56 public $table_element =
'ticket';
61 public $fk_element =
'fk_ticket';
66 public $picto =
'ticket';
96 public $fk_user_create;
101 public $fk_user_assign;
153 public $category_code;
158 public $severity_code;
168 public $category_label;
173 public $severity_label;
183 public $origin_replyto;
188 public $origin_references;
203 public $date_last_msg_sent;
213 public $cache_types_tickets;
218 public $cache_msgs_ticket;
223 public $notify_tiers_at_create;
248 public $regeximgext =
'\.gif|\.jpg|\.jpeg|\.png|\.bmp|\.webp|\.xpm|\.xbm';
254 const STATUS_READ = 1;
255 const STATUS_ASSIGNED = 2;
256 const STATUS_IN_PROGRESS = 3;
257 const STATUS_NEED_MORE_INFO = 5;
258 const STATUS_WAITING = 7;
259 const STATUS_CLOSED = 8;
260 const STATUS_CANCELED = 9;
291 'rowid' => array(
'type' =>
'integer',
'label' =>
'TechnicalID',
'visible' => -2,
'enabled' => 1,
'position' => 1,
'notnull' => 1,
'index' => 1,
'comment' =>
"Id"),
292 'entity' => array(
'type' =>
'integer',
'label' =>
'Entity',
'visible' => 0,
'enabled' => 1,
'position' => 5,
'notnull' => 1,
'index' => 1),
293 '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),
294 'track_id' => array(
'type' =>
'varchar(255)',
'label' =>
'TicketTrackId',
'visible' => -2,
'enabled' => 1,
'position' => 11,
'notnull' => -1,
'searchall' => 1,
'help' =>
"Help text"),
295 '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'),
296 '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'),
297 'origin_replyto' => array(
'type' =>
'mail',
'label' =>
'EmailReplyto',
'visible' => -2,
'enabled' => 1,
'position' => 17,
'notnull' => 1,
'index' => 1,
'searchall' => 1,
'comment' =>
"Email to reply to",
'csslist' =>
'tdoverflowmax150'),
298 'origin_references' => array(
'type' =>
'text',
'label' =>
'EmailReferences',
'visible' => -2,
'enabled' => 1,
'position' => 18,
'notnull' => 1,
'index' => 1,
'searchall' => 1,
'comment' =>
"References from origin email",
'csslist' =>
'tdoverflowmax150'),
299 'subject' => array(
'type' =>
'varchar(255)',
'label' =>
'Subject',
'visible' => 1,
'enabled' => 1,
'position' => 19,
'notnull' => -1,
'searchall' => 1,
'help' =>
"",
'css' =>
'maxwidth200 tdoverflowmax200',
'csslist' =>
'tdoverflowmax250',
'autofocusoncreate' => 1),
300 'type_code' => array(
'type' =>
'varchar(32)',
'label' =>
'Type',
'visible' => 1,
'enabled' => 1,
'position' => 20,
'notnull' => -1,
'help' =>
"",
'csslist' =>
'tdoverflowmax100'),
301 'category_code' => array(
'type' =>
'varchar(32)',
'label' =>
'TicketCategory',
'visible' => -1,
'enabled' => 1,
'position' => 21,
'notnull' => -1,
'help' =>
"",
'css' =>
'maxwidth100 tdoverflowmax200'),
302 'severity_code' => array(
'type' =>
'varchar(32)',
'label' =>
'Severity',
'visible' => 1,
'enabled' => 1,
'position' => 22,
'notnull' => -1,
'help' =>
"",
'css' =>
'maxwidth100 tdoverflowmax100'),
303 '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'),
304 'notify_tiers_at_create' => array(
'type' =>
'integer',
'label' =>
'NotifyThirdparty',
'visible' => -1,
'enabled' => 0,
'position' => 51,
'notnull' => 1,
'index' => 1),
305 'fk_project' => array(
'type' =>
'integer:Project:projet/class/project.class.php',
'label' =>
'Project',
'visible' => -1,
'enabled' =>
'isModEnabled("project")',
'position' => 52,
'notnull' => -1,
'index' => 1,
'help' =>
"LinkToProject"),
306 'fk_contract' => array(
'type' =>
'integer:Contrat:contrat/class/contrat.class.php',
'label' =>
'Contract',
'visible' => -1,
'enabled' =>
'isModEnabled("contract")',
'position' => 53,
'notnull' => -1,
'index' => 1,
'help' =>
"LinkToContract"),
308 'datec' => array(
'type' =>
'datetime',
'label' =>
'DateCreation',
'visible' => 1,
'enabled' => 1,
'position' => 500,
'notnull' => 1,
'csslist' =>
'nowraponall'),
309 'tms' => array(
'type' =>
'timestamp',
'label' =>
'DateModification',
'visible' => -1,
'enabled' => 1,
'position' => 501,
'notnull' => 1),
310 'date_read' => array(
'type' =>
'datetime',
'label' =>
'DateReading',
'visible' => -1,
'enabled' => 1,
'position' => 505,
'notnull' => 1,
'csslist' =>
'nowraponall'),
311 'date_last_msg_sent' => array(
'type' =>
'datetime',
'label' =>
'TicketLastMessageDate',
'visible' => 0,
'enabled' => 1,
'position' => 506,
'notnull' => -1),
312 'fk_user_assign' => array(
'type' =>
'integer:User:user/class/user.class.php',
'label' =>
'AssignedTo',
'visible' => 1,
'enabled' => 1,
'position' => 507,
'notnull' => 1,
'csslist' =>
'tdoverflowmax100 maxwidth150onsmartphone'),
313 'date_close' => array(
'type' =>
'datetime',
'label' =>
'TicketCloseOn',
'visible' => -1,
'enabled' => 1,
'position' => 510,
'notnull' => 1),
314 'message' => array(
'type' =>
'html',
'label' =>
'Message',
'visible' => -2,
'enabled' => 1,
'position' => 540,
'notnull' => -1,),
315 'note_private' => array(
'type' =>
'html',
'label' =>
'NotePrivate',
'enabled' => 1,
'visible' => 0,
'position' => 110),
316 'note_public' => array(
'type' =>
'html',
'label' =>
'NotePublic',
'enabled' => 1,
'visible' => 0,
'position' => 115),
317 'email_msgid' => array(
'type' =>
'varchar(255)',
'label' =>
'EmailMsgID',
'visible' => -2,
'enabled' => 1,
'position' => 540,
'notnull' => -1,
'help' =>
'EmailMsgIDDesc',
'csslist' =>
'tdoverflowmax100'),
318 'email_date' => array(
'type' =>
'datetime',
'label' =>
'EmailDate',
'visible' => -2,
'enabled' => 1,
'position' => 541),
319 'progress' => array(
'type' =>
'integer',
'label' =>
'Progression',
'visible' => -1,
'enabled' => 1,
'position' => 540,
'notnull' => -1,
'css' =>
'right',
'help' =>
"",
'isameasure' => 1,
'csslist' =>
'width50'),
320 'resolution' => array(
'type' =>
'integer',
'label' =>
'Resolution',
'visible' => -1,
'enabled' =>
'getDolGlobalString("TICKET_ENABLE_RESOLUTION")',
'position' => 550,
'notnull' => 1),
321 'model_pdf' => array(
'type' =>
'varchar(255)',
'label' =>
'PDFTemplate',
'enabled' => 1,
'visible' => 0,
'position' => 560),
322 'extraparams' => array(
'type' =>
'varchar(255)',
'label' =>
'Extraparams',
'enabled' => 1,
'visible' => 0,
'position' => 570),
323 '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')),
324 'import_key' => array(
'type' =>
'varchar(14)',
'label' =>
'ImportId',
'enabled' => 1,
'visible' => -2,
'position' => 900),
338 $this->ismultientitymanaged = 1;
339 $this->isextrafieldmanaged = 1;
341 $this->labelStatusShort = array(
342 self::STATUS_NOT_READ =>
'Unread',
343 self::STATUS_READ =>
'Read',
344 self::STATUS_ASSIGNED =>
'Assigned',
345 self::STATUS_IN_PROGRESS =>
'InProgress',
346 self::STATUS_NEED_MORE_INFO =>
'NeedMoreInformationShort',
347 self::STATUS_WAITING =>
'OnHold',
348 self::STATUS_CLOSED =>
'SolvedClosed',
349 self::STATUS_CANCELED =>
'Canceled'
351 $this->labelStatus = array(
352 self::STATUS_NOT_READ =>
'Unread',
353 self::STATUS_READ =>
'Read',
354 self::STATUS_ASSIGNED =>
'Assigned',
355 self::STATUS_IN_PROGRESS =>
'InProgress',
356 self::STATUS_NEED_MORE_INFO =>
'NeedMoreInformation',
357 self::STATUS_WAITING =>
'OnHold',
358 self::STATUS_CLOSED =>
'SolvedClosed',
359 self::STATUS_CANCELED =>
'Canceled'
363 unset($this->fields[
'fk_statut'][
'arrayofkeyval'][self::STATUS_WAITING]);
364 unset($this->labelStatusShort[self::STATUS_WAITING]);
365 unset($this->labelStatus[self::STATUS_WAITING]);
377 $this->errors = array();
382 if (isset($this->
ref)) {
383 $this->
ref = trim($this->
ref);
386 if (isset($this->track_id)) {
387 $this->track_id = trim($this->track_id);
390 if (isset($this->fk_soc)) {
391 $this->fk_soc = (int) $this->fk_soc;
394 if (isset($this->fk_project)) {
395 $this->fk_project = (int) $this->fk_project;
398 if (isset($this->origin_email)) {
399 $this->origin_email = trim($this->origin_email);
402 if (isset($this->fk_user_create)) {
403 $this->fk_user_create = (int) $this->fk_user_create;
406 if (isset($this->fk_user_assign)) {
407 $this->fk_user_assign = (int) $this->fk_user_assign;
410 if (isset($this->subject)) {
411 $this->subject = trim($this->subject);
414 if (isset($this->message)) {
415 $this->message = trim($this->message);
418 $langs->loadLangs(array(
'errors',
'ticket'));
419 $this->errors[] = $langs->trans(
'ErrorFieldTooLong', $langs->transnoentitiesnoconv(
'InitialMessage'));
420 dol_syslog(get_class($this).
'::create error -1 message too long', LOG_ERR);
425 if (isset($this->
status)) {
429 if (isset($this->resolution)) {
430 $this->resolution = (int) $this->resolution;
433 if (isset($this->progress)) {
434 $this->progress = (int) $this->progress;
437 if (isset($this->timing)) {
438 $this->timing = trim($this->timing);
441 if (isset($this->type_code)) {
442 $this->type_code = trim($this->type_code);
445 if (isset($this->category_code)) {
446 $this->category_code = trim($this->category_code);
449 if (isset($this->severity_code)) {
450 $this->severity_code = trim($this->severity_code);
453 if (empty($this->
ref)) {
454 $this->errors[] =
'ErrorTicketRefRequired';
455 dol_syslog(get_class($this).
"::create error -1 ref null", LOG_ERR);
473 if ($test->fetch(0, $getRef) > 0) {
474 if (($action ==
'add') || ($action ==
'update' && $this->
ref != $getRef)) {
479 $this->
ref = $getRef;
490 public function create($user, $notrigger = 0)
497 if (empty($this->datec)) {
500 if (empty($this->track_id)) {
506 $result = $this->
verify();
513 $sql =
"INSERT INTO ".MAIN_DB_PREFIX.
"ticket(";
517 $sql .=
"fk_project,";
518 $sql .=
"fk_contract,";
519 $sql .=
"origin_email,";
520 $sql .=
"origin_replyto,";
521 $sql .=
"origin_references,";
522 $sql .=
"fk_user_create,";
523 $sql .=
"fk_user_assign,";
524 $sql .=
"email_msgid,";
525 $sql .=
"email_date,";
528 $sql .=
"note_private,";
529 $sql .=
"note_public,";
530 $sql .=
"fk_statut,";
531 $sql .=
"resolution,";
534 $sql .=
"type_code,";
535 $sql .=
"category_code,";
536 $sql .=
"severity_code,";
538 $sql .=
"date_read,";
539 $sql .=
"date_close,";
541 $sql .=
"notify_tiers_at_create,";
542 $sql .=
"model_pdf,";
544 $sql .=
") VALUES (";
545 $sql .=
" ".(!isset($this->
ref) ?
'' :
"'".$this->db->escape($this->
ref).
"'").
",";
546 $sql .=
" ".(!isset($this->track_id) ?
'NULL' :
"'".$this->db->escape($this->track_id).
"'").
",";
547 $sql .=
" ".($this->fk_soc > 0 ? ((int) $this->fk_soc) :
"null").
",";
548 $sql .=
" ".($this->fk_project > 0 ? ((int) $this->fk_project) :
"null").
",";
549 $sql .=
" ".($this->fk_contract > 0 ? ((int) $this->fk_contract) :
"null").
",";
550 $sql .=
" ".(!isset($this->origin_email) ?
'NULL' :
"'".$this->db->escape($this->origin_email).
"'").
",";
551 $sql .=
" ".(!isset($this->origin_replyto) ?
'NULL' :
"'".$this->db->escape($this->origin_replyto).
"'").
",";
552 $sql .=
" ".(!isset($this->origin_references) ?
'NULL' :
"'".$this->db->escape($this->origin_references).
"'").
",";
553 $sql .=
" ".(!isset($this->fk_user_create) ? ($user->id > 0 ? ((int) $user->id) :
'NULL') : ($this->fk_user_create > 0 ? ((int) $this->fk_user_create) :
'NULL')).
",";
554 $sql .=
" ".($this->fk_user_assign > 0 ? ((int) $this->fk_user_assign) :
'NULL').
",";
555 $sql .=
" ".(empty($this->email_msgid) ?
'NULL' :
"'".$this->db->escape($this->email_msgid).
"'").
",";
556 $sql .=
" ".(!
isDolTms($this->email_date) ?
'NULL' :
"'".$this->db->idate($this->email_date).
"'").
",";
557 $sql .=
" ".(!isset($this->subject) ?
'NULL' :
"'".$this->db->escape($this->subject).
"'").
",";
558 $sql .=
" ".(!isset($this->message) ?
'NULL' :
"'".$this->db->escape($this->message).
"'").
",";
559 $sql .=
" ".(!isset($this->note_private) ?
'NULL' :
"'".$this->db->escape($this->note_private).
"'").
",";
560 $sql .=
" ".(!isset($this->note_public) ?
'NULL' :
"'".$this->db->escape($this->note_public).
"'").
",";
561 $sql .=
" ".(!isset($this->
status) ?
'0' : ((int) $this->
status)).
",";
562 $sql .=
" ".(!isset($this->resolution) ?
'NULL' : ((int) $this->resolution)).
",";
563 $sql .=
" ".(!isset($this->progress) ?
'0' : ((int) $this->progress)).
",";
564 $sql .=
" ".(!isset($this->timing) ?
'NULL' :
"'".$this->db->escape($this->timing).
"'").
",";
565 $sql .=
" ".(!isset($this->type_code) ?
'NULL' :
"'".$this->db->escape($this->type_code).
"'").
",";
566 $sql .=
" ".(empty($this->category_code) || $this->category_code ==
'-1' ?
'NULL' :
"'".$this->db->escape($this->category_code).
"'").
",";
567 $sql .=
" ".(!isset($this->severity_code) ?
'NULL' :
"'".$this->db->escape($this->severity_code).
"'").
",";
568 $sql .=
" ".(!
isDolTms($this->datec) ?
'NULL' :
"'".$this->db->idate($this->datec).
"'").
",";
569 $sql .=
" ".(!isset($this->date_read) ||
dol_strlen((
string) $this->date_read) == 0 ?
'NULL' :
"'".$this->db->idate($this->date_read).
"'").
",";
570 $sql .=
" ".(!isset($this->date_close) ||
dol_strlen((
string) $this->date_close) == 0 ?
'NULL' :
"'".$this->db->idate($this->date_close).
"'");
571 $sql .=
", ".((int) $this->entity);
572 $sql .=
", ".(!isset($this->notify_tiers_at_create) ? 1 : ((int) $this->notify_tiers_at_create));
573 $sql .=
", '".$this->db->escape($this->model_pdf).
"'";
574 $sql .=
", ".(!isset($this->ip) ?
'NULL' :
"'".$this->db->escape($this->ip).
"'");
579 dol_syslog(get_class($this).
"::create", LOG_DEBUG);
580 $resql = $this->db->query($sql);
583 $this->errors[] =
"Error ".$this->db->lasterror();
587 $this->
id = $this->db->last_insert_id(MAIN_DB_PREFIX.
"ticket");
590 if (!$error &&
getDolGlobalString(
'TICKET_ADD_AUTHOR_AS_CONTACT') && empty($this->context[
"createdfrompublicinterface"])) {
594 if (!empty($user->socid) && !empty($user->contact_id) &&
getDolGlobalInt(
'TICKET_ADD_AUTHOR_AS_CONTACT') == 2) {
595 $contact_type =
'external';
596 $contributor_id = $user->contact_id;
598 $contact_type =
'internal';
599 $contributor_id = $user->id;
603 if ($this->
add_contact($contributor_id,
'CONTRIBUTOR', $contact_type) < 0) {
608 if (!$error && $this->fk_user_assign > 0) {
609 if ($this->
add_contact($this->fk_user_assign,
'SUPPORTTEC',
'internal') < 0) {
623 if (!$error && !$notrigger) {
625 $result = $this->call_trigger(
'TICKET_CREATE', $user);
634 foreach ($this->errors as $errmsg) {
635 dol_syslog(get_class($this).
"::create ".$errmsg, LOG_ERR);
636 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
638 $this->db->rollback();
645 $this->db->rollback();
646 dol_syslog(get_class($this).
"::Create fails verify ".implode(
',', $this->errors), LOG_WARNING);
660 public function fetch(
$id = 0, $ref =
'', $track_id =
'', $email_msgid =
'')
665 if (empty(
$id) && empty($ref) && empty($track_id) && empty($email_msgid)) {
666 $this->error =
'ErrorWrongParameters';
673 $sql .=
" t.entity,";
675 $sql .=
" t.track_id,";
676 $sql .=
" t.fk_soc,";
677 $sql .=
" t.fk_project,";
678 $sql .=
" t.fk_contract,";
679 $sql .=
" t.origin_email,";
680 $sql .=
" t.origin_replyto,";
681 $sql .=
" t.origin_references,";
682 $sql .=
" t.fk_user_create,";
683 $sql .=
" t.fk_user_assign,";
684 $sql .=
" t.email_msgid,";
685 $sql .=
" t.email_date,";
686 $sql .=
" t.subject,";
687 $sql .=
" t.message,";
688 $sql .=
" t.note_private,";
689 $sql .=
" t.note_public,";
690 $sql .=
" t.fk_statut as status,";
691 $sql .=
" t.resolution,";
692 $sql .=
" t.progress,";
693 $sql .=
" t.timing,";
694 $sql .=
" t.type_code,";
695 $sql .=
" t.category_code,";
696 $sql .=
" t.severity_code,";
698 $sql .=
" t.date_read,";
699 $sql .=
" t.date_last_msg_sent,";
700 $sql .=
" t.date_close,";
702 $sql .=
" t.model_pdf,";
703 $sql .=
" t.extraparams,";
705 $sql .=
" type.label as type_label, category.label as category_label, severity.label as severity_label";
706 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as t";
707 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_type as type ON type.code=t.type_code";
708 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as category ON category.code=t.category_code";
709 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_severity as severity ON severity.code=t.severity_code";
712 $sql .=
" WHERE t.rowid = ".((int)
$id);
714 $sql .=
" WHERE t.entity IN (".getEntity($this->element, 1).
")";
716 $sql .=
" AND t.ref = '".$this->db->escape($ref).
"'";
717 } elseif ($track_id) {
718 $sql .=
" AND t.track_id = '".$this->db->escape($track_id).
"'";
720 $sql .=
" AND t.email_msgid = '".$this->db->escape($email_msgid).
"'";
724 dol_syslog(get_class($this).
"::fetch", LOG_DEBUG);
725 $resql = $this->db->query($sql);
727 if ($this->db->num_rows($resql)) {
728 $obj = $this->db->fetch_object($resql);
730 $this->
id = $obj->rowid;
731 $this->entity = $obj->entity;
732 $this->
ref = $obj->ref;
733 $this->track_id = $obj->track_id;
734 $this->fk_soc = $obj->fk_soc;
735 $this->socid = $obj->fk_soc;
736 $this->fk_project = $obj->fk_project;
737 $this->fk_contract = $obj->fk_contract;
738 $this->origin_email = $obj->origin_email;
739 $this->origin_replyto = $obj->origin_replyto;
740 $this->origin_references = $obj->origin_references;
741 $this->fk_user_create = $obj->fk_user_create;
742 $this->fk_user_assign = $obj->fk_user_assign;
743 $this->email_msgid = $obj->email_msgid;
744 $this->email_date = $this->db->jdate($obj->email_date);
745 $this->subject = $obj->subject;
746 $this->message = $obj->message;
747 $this->note_private = $obj->note_private;
748 $this->note_public = $obj->note_public;
749 $this->model_pdf = $obj->model_pdf;
750 $this->extraparams = !empty($obj->extraparams) ? (array) json_decode($obj->extraparams,
true) : array();
751 $this->ip = $obj->ip;
753 $this->
status = $obj->status;
754 $this->fk_statut = $this->status;
756 $this->resolution = $obj->resolution;
757 $this->progress = $obj->progress;
758 $this->timing = $obj->timing;
760 $this->type_code = $obj->type_code;
761 $label_type = ($langs->trans(
"TicketTypeShort".$obj->type_code) !=
"TicketTypeShort".$obj->type_code ? $langs->trans(
"TicketTypeShort".$obj->type_code) : ($obj->type_label !=
'-' ? $obj->type_label :
''));
762 $this->type_label = $label_type;
764 $this->category_code = $obj->category_code;
765 $label_category = ($langs->trans(
"TicketCategoryShort".$obj->category_code) !=
"TicketCategoryShort".$obj->category_code ? $langs->trans(
"TicketCategoryShort".$obj->category_code) : ($obj->category_label !=
'-' ? $obj->category_label :
''));
766 $this->category_label = $label_category;
768 $this->severity_code = $obj->severity_code;
769 $label_severity = ($langs->trans(
"TicketSeverityShort".$obj->severity_code) !=
"TicketSeverityShort".$obj->severity_code ? $langs->trans(
"TicketSeverityShort".$obj->severity_code) : ($obj->severity_label !=
'-' ? $obj->severity_label :
''));
770 $this->severity_label = $label_severity;
772 $this->datec = $this->db->jdate($obj->datec);
773 $this->date_creation = $this->db->jdate($obj->datec);
774 $this->date_read = $this->db->jdate($obj->date_read);
775 $this->date_validation = $this->db->jdate($obj->date_read);
776 $this->date_last_msg_sent = $this->db->jdate($obj->date_last_msg_sent);
777 $this->date_close = $this->db->jdate($obj->date_close);
778 $this->tms = $this->db->jdate($obj->tms);
779 $this->date_modification = $this->db->jdate($obj->tms);
783 $this->db->free($resql);
789 $this->error =
"Error ".$this->db->lasterror();
790 dol_syslog(get_class($this).
"::fetch ".$this->error, LOG_ERR);
807 public function fetchAll($user, $sortorder =
'ASC', $sortfield =
't.datec', $limit = 0, $offset = 0, $arch = 0, $filter =
'')
809 global $langs, $extrafields;
812 $extrafields->fetch_name_optionals_label($this->table_element);
817 $sql .=
" t.track_id,";
818 $sql .=
" t.fk_soc,";
819 $sql .=
" t.fk_project,";
820 $sql .=
" t.fk_contract,";
821 $sql .=
" t.origin_email,";
822 $sql .=
" t.origin_replyto,";
823 $sql .=
" t.origin_references,";
824 $sql .=
" t.fk_user_create, uc.lastname as user_create_lastname, uc.firstname as user_create_firstname,";
825 $sql .=
" t.fk_user_assign, ua.lastname as user_assign_lastname, ua.firstname as user_assign_firstname,";
826 $sql .=
" t.subject,";
827 $sql .=
" t.message,";
828 $sql .=
" t.note_private,";
829 $sql .=
" t.note_public,";
830 $sql .=
" t.fk_statut as status,";
831 $sql .=
" t.resolution,";
832 $sql .=
" t.progress,";
833 $sql .=
" t.timing,";
834 $sql .=
" t.type_code,";
835 $sql .=
" t.category_code,";
836 $sql .=
" t.severity_code,";
838 $sql .=
" t.date_read,";
839 $sql .=
" t.date_last_msg_sent,";
840 $sql .=
" t.date_close,";
842 $sql .=
" type.label as type_label, category.label as category_label, severity.label as severity_label";
844 if ($extrafields->attributes[$this->table_element][
'count'] > 0) {
845 foreach ($extrafields->attributes[$this->table_element][
'label'] as $key => $val) {
846 $sql .= ($extrafields->attributes[$this->table_element][
'type'][$key] !=
'separate' ?
",ef.".$key.
" as options_".$key :
'');
849 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as t";
850 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_type as type ON type.code = t.type_code";
851 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_category as category ON category.code = t.category_code";
852 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"c_ticket_severity as severity ON severity.code = t.severity_code";
853 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON s.rowid = t.fk_soc";
854 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as uc ON uc.rowid = t.fk_user_create";
855 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user as ua ON ua.rowid = t.fk_user_assign";
856 if ($extrafields->attributes[$this->table_element][
'count'] > 0) {
857 if (is_array($extrafields->attributes[$this->table_element][
'label']) && count($extrafields->attributes[$this->table_element][
'label'])) {
858 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"ticket_extrafields as ef on (t.rowid = ef.fk_object)";
861 $sql .=
" WHERE t.entity IN (".getEntity(
'ticket').
")";
864 if (is_array($filter)) {
865 foreach ($filter as $key => $value) {
866 if (strpos($key,
'date')) {
867 $sql .=
" AND ".$this->db->sanitize($key).
" = '".$this->db->escape((
string) $value).
"'";
868 } elseif (($key ==
't.fk_user_assign') || ($key ==
't.type_code') || ($key ==
't.category_code') || ($key ==
't.severity_code') || ($key ==
't.fk_soc')) {
869 $sql .=
" AND ".$this->db->sanitize($key).
" = '".$this->db->escape((
string) $value).
"'";
870 } elseif ($key ==
't.fk_statut') {
871 if (is_array($value) && count($value) > 0) {
872 $sql .=
" AND ".$this->db->sanitize($key).
" IN (".$this->db->sanitize(implode(
',', $value)).
")";
874 $sql .=
" AND ".$this->db->sanitize($key).
' = '.((int) $value);
876 } elseif ($key ==
't.fk_contract') {
877 $sql .=
" AND ".$this->db->sanitize($key).
' = '.((int) $value);
879 $sql .=
" AND ".$this->db->sanitize($key).
" LIKE '%".$this->db->escape($this->db->escapeforlike((
string) $value)).
"%'";
890 $this->errors[] = $errormessage;
891 dol_syslog(__METHOD__.
' '.implode(
',', $this->errors), LOG_ERR);
896 $socid = $user->socid ?: 0;
899 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
900 $search_sale = $user->id;
903 if ($search_sale && $search_sale !=
'-1') {
904 if ($search_sale == -2) {
905 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
906 } elseif ($search_sale > 0) {
907 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
912 $sql .=
" AND t.fk_soc = ".((int) $socid);
915 $sql .= $this->db->order($sortfield, $sortorder);
916 if (!empty($limit)) {
917 $sql .= $this->db->plimit($limit + 1, $offset);
920 dol_syslog(get_class($this).
"::fetchAll", LOG_DEBUG);
921 $resql = $this->db->query($sql);
924 $this->lines = array();
926 $num = $this->db->num_rows($resql);
931 $obj = $this->db->fetch_object($resql);
935 $line->id = $obj->rowid;
937 $line->ref = $obj->ref;
938 $line->track_id = $obj->track_id;
939 $line->fk_soc = $obj->fk_soc;
940 $line->fk_project = $obj->fk_project;
941 $line->fk_contract = $obj->fk_contract;
942 $line->origin_email = $obj->origin_email;
943 $line->origin_replyto = $obj->origin_replyto;
944 $line->origin_references = $obj->origin_references;
946 $line->fk_user_create = $obj->fk_user_create;
947 $line->fk_user_assign = $obj->fk_user_assign;
949 $line->subject = $obj->subject;
950 $line->message = $obj->message;
951 $line->note_private = $obj->note_private;
952 $line->note_public = $obj->note_public;
953 $line->fk_statut = $obj->status;
954 $line->status = $obj->status;
955 $line->resolution = $obj->resolution;
956 $line->progress = $obj->progress;
957 $line->timing = $obj->timing;
959 $label_type = ($langs->trans(
"TicketTypeShort".$obj->type_code) !=
"TicketTypeShort".$obj->type_code ? $langs->trans(
"TicketTypeShort".$obj->type_code) : ($obj->type_label !=
'-' ? $obj->type_label :
''));
960 $line->type_label = $label_type;
962 $this->category_code = $obj->category_code;
963 $label_category = ($langs->trans(
"TicketCategoryShort".$obj->category_code) !=
"TicketCategoryShort".$obj->category_code ? $langs->trans(
"TicketCategoryShort".$obj->category_code) : ($obj->category_label !=
'-' ? $obj->category_label :
''));
964 $line->category_label = $label_category;
966 $this->severity_code = $obj->severity_code;
967 $label_severity = ($langs->trans(
"TicketSeverityShort".$obj->severity_code) !=
"TicketSeverityShort".$obj->severity_code ? $langs->trans(
"TicketSeverityShort".$obj->severity_code) : ($obj->severity_label !=
'-' ? $obj->severity_label :
''));
968 $line->severity_label = $label_severity;
970 $line->datec = $this->db->jdate($obj->datec);
971 $line->date_read = $this->db->jdate($obj->date_read);
972 $line->date_last_msg_sent = $this->db->jdate($obj->date_last_msg_sent);
973 $line->date_close = $this->db->jdate($obj->date_close);
976 if ($extrafields->attributes[$this->table_element][
'count'] > 0) {
977 if (is_array($extrafields->attributes[$this->table_element][
'label']) && count($extrafields->attributes[$this->table_element][
'label'])) {
978 foreach ($extrafields->attributes[$this->table_element][
'label'] as $key => $val) {
979 $tmpkey =
'options_'.$key;
980 $line->{$tmpkey} = $obj->$tmpkey;
984 $this->lines[$i] = $line;
988 $this->db->free($resql);
991 $this->error =
"Error ".$this->db->lasterror();
992 dol_syslog(get_class($this).
"::fetchAll ".$this->error, LOG_ERR);
1004 public function update($user, $notrigger = 0)
1015 if (isset($this->
ref)) {
1016 $this->
ref = trim($this->
ref);
1019 if (isset($this->track_id)) {
1020 $this->track_id = trim($this->track_id);
1023 if (isset($this->fk_soc)) {
1024 $this->fk_soc = (int) $this->fk_soc;
1027 if (isset($this->fk_project)) {
1028 $this->fk_project = (int) $this->fk_project;
1031 if (isset($this->fk_contract)) {
1032 $this->fk_contract = (int) $this->fk_contract;
1035 if (isset($this->origin_email)) {
1036 $this->origin_email = trim($this->origin_email);
1039 if (isset($this->fk_user_create)) {
1040 $this->fk_user_create = (int) $this->fk_user_create;
1043 if (isset($this->fk_user_assign)) {
1044 $this->fk_user_assign = (int) $this->fk_user_assign;
1047 if (isset($this->subject)) {
1048 $this->subject = trim($this->subject);
1051 if (isset($this->message)) {
1052 $this->message = trim($this->message);
1055 $langs->loadLangs(array(
'errors',
'ticket'));
1056 $this->errors[] = $langs->trans(
'ErrorFieldTooLong', $langs->transnoentitiesnoconv(
'InitialMessage'));
1057 dol_syslog(get_class($this).
'::update error -1 message too long', LOG_ERR);
1062 if (isset($this->
status)) {
1066 if (isset($this->resolution)) {
1067 $this->resolution = (int) $this->resolution;
1070 if (isset($this->progress)) {
1071 $this->progress = (int) $this->progress;
1074 if (isset($this->timing)) {
1075 $this->timing = trim($this->timing);
1078 if (isset($this->type_code)) {
1079 $this->timing = trim($this->type_code);
1082 if (isset($this->category_code)) {
1083 $this->timing = trim($this->category_code);
1086 if (isset($this->severity_code)) {
1087 $this->timing = trim($this->severity_code);
1089 if (isset($this->model_pdf)) {
1090 $this->model_pdf = trim($this->model_pdf);
1095 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket SET";
1096 $sql .=
" ref=".(isset($this->
ref) ?
"'".$this->db->escape($this->
ref).
"'" :
"").
",";
1097 $sql .=
" track_id=".(isset($this->track_id) ?
"'".$this->db->escape($this->track_id).
"'" :
"null").
",";
1098 $sql .=
" fk_soc=".(isset($this->fk_soc) ? (int) $this->fk_soc :
"null").
",";
1099 $sql .=
" fk_project=".(isset($this->fk_project) ? (int) $this->fk_project :
"null").
",";
1100 $sql .=
" fk_contract=".(isset($this->fk_contract) ? (int) $this->fk_contract :
"null").
",";
1101 $sql .=
" origin_email=".(isset($this->origin_email) ?
"'".$this->db->escape($this->origin_email).
"'" :
"null").
",";
1102 $sql .=
" origin_replyto=".(isset($this->origin_replyto) ?
"'".$this->db->escape($this->origin_replyto).
"'" :
"null").
",";
1103 $sql .=
" origin_references=".(isset($this->origin_references) ?
"'".$this->db->escape($this->origin_references).
"'" :
"null").
",";
1104 $sql .=
" fk_user_create=".(isset($this->fk_user_create) ? (int) $this->fk_user_create :
"null").
",";
1105 $sql .=
" fk_user_assign=".(isset($this->fk_user_assign) ? (int) $this->fk_user_assign :
"null").
",";
1106 $sql .=
" subject=".(isset($this->subject) ?
"'".$this->db->escape($this->subject).
"'" :
"null").
",";
1107 $sql .=
" message=".(isset($this->message) ?
"'".$this->db->escape($this->message).
"'" :
"null").
",";
1108 $sql .=
" note_private=".(isset($this->note_private) ?
"'".$this->db->escape($this->note_private).
"'" :
"null").
",";
1109 $sql .=
" note_public=".(isset($this->note_public) ?
"'".$this->db->escape($this->note_public).
"'" :
"null").
",";
1110 $sql .=
" fk_statut=".(isset($this->
status) ? (int) $this->
status :
"0").
",";
1111 $sql .=
" resolution=".(isset($this->resolution) ? (int) $this->resolution :
"null").
",";
1112 $sql .=
" progress=".(isset($this->progress) ?
"'".$this->db->escape((
string) $this->progress).
"'" :
"null").
",";
1113 $sql .=
" timing=".(isset($this->timing) ?
"'".$this->db->escape($this->timing).
"'" :
"null").
",";
1114 $sql .=
" type_code=".(isset($this->type_code) ?
"'".$this->db->escape($this->type_code).
"'" :
"null").
",";
1115 $sql .=
" category_code=".(isset($this->category_code) ?
"'".$this->db->escape($this->category_code).
"'" :
"null").
",";
1116 $sql .=
" severity_code=".(isset($this->severity_code) ?
"'".$this->db->escape($this->severity_code).
"'" :
"null").
",";
1117 $sql .=
" datec=".(isDolTms($this->datec) ?
"'".$this->db->idate($this->datec).
"'" :
'null').
",";
1118 $sql .=
" date_read=".(dol_strlen((
string) $this->date_read) != 0 ?
"'".$this->db->idate($this->date_read).
"'" :
'null').
",";
1119 $sql .=
" date_last_msg_sent=".(dol_strlen((
string) $this->date_last_msg_sent) != 0 ?
"'".$this->db->idate($this->date_last_msg_sent).
"'" :
'null').
",";
1120 $sql .=
" model_pdf=".(isset($this->model_pdf) ?
"'".$this->db->escape($this->model_pdf).
"'" :
"null").
",";
1121 $sql .=
" date_close=".(dol_strlen((
string) $this->date_close) != 0 ?
"'".$this->db->idate($this->date_close).
"'" :
'null');
1122 $sql .=
" WHERE rowid=".((int) $this->
id);
1126 $resql = $this->db->query($sql);
1129 $this->errors[] =
"Error ".$this->db->lasterror();
1134 $result = $this->insertExtraFields();
1140 if (!$error && !$notrigger) {
1142 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1151 foreach ($this->errors as $errmsg) {
1152 dol_syslog(get_class($this).
"::update ".$errmsg, LOG_ERR);
1153 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1155 $this->db->rollback();
1158 $this->db->commit();
1170 public function delete($user, $notrigger = 0)
1178 $result = $this->call_trigger(
'TICKET_DELETE', $user);
1187 $res = $this->delete_linked_contact();
1189 dol_syslog(get_class($this).
"::delete error", LOG_ERR);
1196 $res = $this->deleteObjectLinked();
1204 $result = $this->deleteExtraFields();
1207 dol_syslog(get_class($this).
"::delete error -3 ".$this->error, LOG_ERR);
1214 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"categorie_ticket";
1215 $sql .=
" WHERE fk_ticket = ".(int) $this->
id;
1217 $result = $this->db->query($sql);
1220 $this->errors[] = $this->db->lasterror();
1225 $sql =
"DELETE FROM ".MAIN_DB_PREFIX.
"ticket";
1226 $sql .=
" WHERE rowid=".((int) $this->
id);
1228 dol_syslog(get_class($this).
"::delete sql=".$sql);
1229 $resql = $this->db->query($sql);
1232 $this->errors[] =
"Error ".$this->db->lasterror();
1235 $this->deleteEcmFiles(1);
1237 $dir = DOL_DATA_ROOT.
'/'.$this->element.
'/'.$this->ref;
1241 $this->errors[] = $this->error;
1249 foreach ($this->errors as $errmsg) {
1250 dol_syslog(get_class($this).
"::delete ".$errmsg, LOG_ERR);
1251 $this->error .= ($this->error ?
', '.$errmsg : $errmsg);
1253 $this->db->rollback();
1256 $this->db->commit();
1301 $object->context[
'createfromclone'] =
'createfromclone';
1302 $result =
$object->create($user);
1306 $this->error =
$object->error;
1310 unset(
$object->context[
'createfromclone']);
1314 $this->db->commit();
1317 $this->db->rollback();
1332 $this->
ref =
'TI0501-001';
1333 $this->track_id =
'XXXXaaaa';
1334 $this->origin_email =
'email@email.com';
1335 $this->fk_project = 1;
1336 $this->fk_user_create = 1;
1337 $this->fk_user_assign = 1;
1338 $this->subject =
'Subject of ticket';
1339 $this->message =
'Message of ticket';
1341 $this->resolution = 1;
1342 $this->progress = 10;
1344 $this->type_code =
'TYPECODE';
1345 $this->category_code =
'CATEGORYCODE';
1346 $this->severity_code =
'SEVERITYCODE';
1349 $this->date_last_msg_sent =
dol_now();
1350 $this->date_close =
dol_now();
1364 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 =
'');
1375 global $langs, $hookmanager;
1377 if (!empty($this->cache_types_tickets) && count($this->cache_types_tickets)) {
1384 $sql =
"SELECT rowid, entity, code, label, use_default, pos, description";
1385 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_type";
1386 $sql .=
" WHERE entity IN (".getEntity(
'c_ticket_type').
")";
1387 $sql .=
" AND active > 0";
1388 $sql .=
" ORDER BY pos";
1389 dol_syslog(get_class($this).
"::load_cache_type_tickets", LOG_DEBUG);
1390 $resql = $this->db->query($sql);
1392 $num = $this->db->num_rows($resql);
1395 $obj = $this->db->fetch_object($resql);
1396 $label = ($langs->trans(
"TicketTypeShort".$obj->code) !=
"TicketTypeShort".$obj->code ? $langs->trans(
"TicketTypeShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1397 $this->cache_types_tickets[$obj->rowid][
'code'] = $obj->code;
1398 $this->cache_types_tickets[$obj->rowid][
'label'] = $label;
1399 $this->cache_types_tickets[$obj->rowid][
'use_default'] = $obj->use_default;
1400 $this->cache_types_tickets[$obj->rowid][
'pos'] = $obj->pos;
1401 $this->cache_types_tickets[$obj->rowid][
'entity'] = (int) $obj->entity;
1405 $parameters = array(
'dictionary' =>
'tickettype');
1406 $reshook = $hookmanager->executeHooks(
'loadDictionaryCache', $parameters, $this);
1407 if (empty($reshook)) {
1408 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
1409 $this->cache_types_tickets = array_merge($this->cache_types_tickets, $hookmanager->resArray);
1412 $this->cache_types_tickets = $hookmanager->resArray;
1415 return count($this->cache_types_tickets);
1430 global
$conf, $langs, $hookmanager;
1432 if ($publicgroup == -1 && !empty(
$conf->cache[
'category_tickets']) && count(
$conf->cache[
'category_tickets'])) {
1439 $sql =
"SELECT rowid, entity, code, label, use_default, pos, description, public, active, force_severity, fk_parent";
1440 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_category";
1441 $sql .=
" WHERE entity IN (".getEntity(
'c_ticket_category').
")";
1442 $sql .=
" AND active > 0";
1443 if ($publicgroup > -1) {
1444 $sql .=
" AND public = ".((int) $publicgroup);
1446 $sql .=
" ORDER BY pos";
1448 dol_syslog(get_class($this).
"::load_cache_categories_tickets", LOG_DEBUG);
1450 $resql = $this->db->query($sql);
1452 $num = $this->db->num_rows($resql);
1454 $categorytickets = array();
1455 '@phan-var-force array<int,array{code:string,label:string,use_default:int,pos:int,public:int,active:int,force_severity:?string,fk_parent:int}> $categorytickets';
1457 $obj = $this->db->fetch_object($resql);
1458 $categorytickets[$obj->rowid][
'code'] = $obj->code;
1459 $categorytickets[$obj->rowid][
'use_default'] = $obj->use_default;
1460 $categorytickets[$obj->rowid][
'pos'] = $obj->pos;
1461 $categorytickets[$obj->rowid][
'public'] = $obj->public;
1462 $categorytickets[$obj->rowid][
'active'] = $obj->active;
1463 $categorytickets[$obj->rowid][
'force_severity'] = $obj->force_severity;
1464 $categorytickets[$obj->rowid][
'fk_parent'] = $obj->fk_parent;
1468 $label = ($langs->trans(
"TicketCategoryShort".$obj->code) !=
"TicketCategoryShort".$obj->code ? $langs->trans(
"TicketCategoryShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1469 $categorytickets[$obj->rowid][
'label'] = $label;
1470 $categorytickets[$obj->rowid][
'entity'] = (int) $obj->entity;
1474 $conf->cache[
'category_tickets'] = $categorytickets;
1476 $parameters = array(
'dictionary' =>
'ticketcategory',
'publicgroup' => $publicgroup);
1477 $reshook = $hookmanager->executeHooks(
'loadDictionaryCache', $parameters, $this);
1478 if (empty($reshook)) {
1479 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
1480 $conf->cache[
'category_tickets'] = array_merge(
$conf->cache[
'category_tickets'], $hookmanager->resArray);
1483 $conf->cache[
'category_tickets'] = $hookmanager->resArray;
1486 return count(
$conf->cache[
'category_tickets']);
1500 global
$conf, $langs, $hookmanager;
1502 if (!empty(
$conf->cache[
'severity_tickets']) && count(
$conf->cache[
'severity_tickets'])) {
1509 $sql =
"SELECT rowid, entity, code, label, use_default, pos, description";
1510 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_ticket_severity";
1511 $sql .=
" WHERE entity IN (".getEntity(
'c_ticket_severity').
")";
1512 $sql .=
" AND active > 0";
1513 $sql .=
" ORDER BY pos";
1514 dol_syslog(get_class($this).
"::loadCacheSeveritiesTickets", LOG_DEBUG);
1515 $resql = $this->db->query($sql);
1517 $num = $this->db->num_rows($resql);
1519 $severitytickets = array();
1520 '@phan-var-force array<int,array{code:string,label:string,use_default:int,pos:int}> $severitytickets';
1522 $obj = $this->db->fetch_object($resql);
1524 $severitytickets[$obj->rowid][
'code'] = $obj->code;
1525 $label = ($langs->trans(
"TicketSeverityShort".$obj->code) !=
"TicketSeverityShort".$obj->code ? $langs->trans(
"TicketSeverityShort".$obj->code) : ($obj->label !=
'-' ? $obj->label :
''));
1526 $severitytickets[$obj->rowid][
'label'] = $label;
1527 $severitytickets[$obj->rowid][
'use_default'] = $obj->use_default;
1528 $severitytickets[$obj->rowid][
'pos'] = $obj->pos;
1529 $severitytickets[$obj->rowid][
'entity'] = (int) $obj->entity;
1532 $conf->cache[
'severity_tickets'] = $severitytickets;
1534 $parameters = array(
'dictionary' =>
'ticketseverity');
1535 $reshook = $hookmanager->executeHooks(
'loadDictionaryCache', $parameters, $this);
1536 if (empty($reshook)) {
1537 if (is_array($hookmanager->resArray) && count($hookmanager->resArray)) {
1538 $conf->cache[
'severity_tickets'] = array_merge(
$conf->cache[
'severity_tickets'], $hookmanager->resArray);
1541 $conf->cache[
'severity_tickets'] = $hookmanager->resArray;
1544 return count(
$conf->cache[
'severity_tickets']);
1560 return $this->LibStatut($this->
status, $mode, 0, $this->progress);
1574 public function LibStatut($status, $mode = 0, $notooltip = 0, $progress = 0)
1577 global $langs, $hookmanager;
1579 $labelStatus = (isset($status) && !empty($this->labelStatus[$status])) ? $this->labelStatus[$status] :
'';
1580 $labelStatusShort = (isset($status) && !empty($this->labelStatusShort[$status])) ? $this->labelStatusShort[$status] :
'';
1585 case self::STATUS_NOT_READ:
1586 $statusType =
'status0';
1588 case self::STATUS_READ:
1589 $statusType =
'status1';
1591 case self::STATUS_ASSIGNED:
1592 $statusType =
'status2';
1594 case self::STATUS_IN_PROGRESS:
1595 $statusType =
'status4';
1597 case self::STATUS_WAITING:
1598 $statusType =
'status7';
1600 case self::STATUS_NEED_MORE_INFO:
1601 $statusType =
'status3';
1603 case self::STATUS_CANCELED:
1604 $statusType =
'status9';
1606 case self::STATUS_CLOSED:
1607 $statusType =
'status6';
1614 $parameters = array(
1615 'status' => $status,
1620 $reshook = $hookmanager->executeHooks(
'LibStatut', $parameters, $this);
1623 return $hookmanager->resPrint;
1627 $labelStatus =
'Unknown';
1628 $labelStatusShort =
'Unknown';
1629 $statusType =
'status0';
1635 $params = array(
'tooltip' =>
'no');
1638 $labelStatus = $langs->transnoentitiesnoconv($labelStatus);
1639 $labelStatusShort = $langs->transnoentitiesnoconv($labelStatusShort);
1641 if ($status == self::STATUS_IN_PROGRESS && $progress > 0) {
1642 $labelStatus .=
' ('.round($progress).
'%)';
1643 $labelStatusShort .=
' ('.round($progress).
'%)';
1646 return dolGetStatus($labelStatus, $labelStatusShort,
'', $statusType, $mode,
'', $params);
1659 $langs->load(
'ticket');
1660 $nofetch = !empty($params[
'nofetch']);
1663 $datas[
'picto'] =
img_picto(
'', $this->picto).
' <u class="paddingrightonly">'.$langs->trans(
"Ticket").
'</u>';
1664 $datas[
'picto'] .=
' '.$this->getLibStatut(4);
1665 $datas[
'ref'] =
'<br><b>'.$langs->trans(
'Ref').
':</b> '.$this->ref;
1666 $datas[
'track_id'] =
'<br><b>'.$langs->trans(
'TicketTrackId').
':</b> '.$this->track_id;
1667 $datas[
'subject'] =
'<br><b>'.$langs->trans(
'Subject').
':</b> '.$this->subject;
1668 if ($this->date_creation) {
1669 $datas[
'date_creation'] =
'<br><b>'.$langs->trans(
'DateCreation').
':</b> '.
dol_print_date($this->date_creation,
'dayhour');
1671 if ($this->date_modification) {
1672 $datas[
'date_modification'] =
'<br><b>'.$langs->trans(
'DateModification').
':</b> '.
dol_print_date($this->date_modification,
'dayhour');
1676 require_once DOL_DOCUMENT_ROOT .
'/categories/class/categorie.class.php';
1677 $form =
new Form($this->db);
1678 $datas[
'categories'] =
'<br>' . $form->showCategories($this->
id, Categorie::TYPE_TICKET, 1);
1694 public function getNomUrl($withpicto = 0, $option =
'', $notooltip = 0, $morecss =
'', $save_lastsearch_value = -1)
1696 global $action,
$conf, $hookmanager, $langs;
1698 if (!empty(
$conf->dol_no_mouse_hover)) {
1706 'objecttype' => $this->element,
1707 'option' => $option,
1710 $classfortooltip =
'classfortooltip';
1713 $classfortooltip =
'classforajaxtooltip';
1714 $dataparams =
' data-params="'.dol_escape_htmltag(json_encode($params)).
'"';
1717 $label = implode($this->getTooltipContentArray($params));
1720 $url = DOL_URL_ROOT.
'/ticket/card.php?id='.
$this->id;
1722 if ($option !=
'nolink') {
1724 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1725 if ($save_lastsearch_value == -1 && isset($_SERVER[
"PHP_SELF"]) && preg_match(
'/list\.php/', $_SERVER[
"PHP_SELF"])) {
1726 $add_save_lastsearch_values = 1;
1728 if ($add_save_lastsearch_values) {
1729 $url .=
'&save_lastsearch_values=1';
1734 if (empty($notooltip)) {
1736 $label = $langs->trans(
"ShowTicket");
1737 $linkclose .=
' alt="'.dolPrintHTMLForAttribute($label).
'"';
1739 $linkclose .= ($label ?
' title="'.dolPrintHTMLForAttribute($label).
'"' :
' title="tocomplete"');
1740 $linkclose .= $dataparams.
' class="'.$classfortooltip.($morecss ?
' '.$morecss :
'').
'"';
1742 $linkclose = ($morecss ?
' class="'.$morecss.
'"' :
'');
1745 $linkstart =
'<a href="'.$url.
'"';
1746 $linkstart .= $linkclose.
'>';
1749 $result .= $linkstart;
1751 $result .=
img_object(($notooltip ?
'' : $label), ($this->picto ?:
'generic'), (($withpicto != 2) ?
'class="paddingright"' :
''), 0, 0, $notooltip ? 0 : 1);
1753 if ($withpicto != 2) {
1754 $result .= $this->ref;
1756 $result .= $linkend;
1759 $hookmanager->initHooks(array(
'ticketdao'));
1760 $parameters = array(
'id' => $this->
id,
'getnomurl' => &$result);
1761 $reshook = $hookmanager->executeHooks(
'getNomUrl', $parameters, $this, $action);
1763 $result = $hookmanager->resPrint;
1765 $result .= $hookmanager->resPrint;
1785 if ($this->
status != self::STATUS_CANCELED) {
1790 $this->
status = Ticket::STATUS_READ;
1792 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1793 $sql .=
" SET fk_statut = ".((int) $this->
status) .
", date_read = '".$this->db->idate(
dol_now()).
"'";
1794 $sql .=
" WHERE rowid = ".((int) $this->
id);
1797 $resql = $this->db->query($sql);
1799 $this->context[
'actionmsg'] = $langs->trans(
'TicketLogMesgReadBy', $this->
ref, $user->getFullName($langs));
1800 $this->context[
'actionmsg2'] = $langs->trans(
'TicketLogMesgReadBy', $this->
ref, $user->getFullName($langs));
1804 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1812 $this->db->commit();
1815 $this->
status = $this->oldcopy->status;
1817 $this->db->rollback();
1819 $this->error = implode(
',', $this->errors);
1821 dol_syslog(get_class($this).
"::markAsRead ".$this->error, LOG_ERR);
1825 $this->
status = $this->oldcopy->status;
1827 $this->db->rollback();
1828 $this->error = $this->db->lasterror();
1829 dol_syslog(get_class($this).
"::markAsRead ".$this->error, LOG_ERR);
1848 if (!empty($this->date_read)) {
1856 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1857 $sql .=
" SET date_read = '".$this->db->idate(
dol_now()).
"'";
1858 $sql .=
", fk_user_modif = ".((int) $user->id);
1859 $sql .=
" WHERE rowid = ".((int) $this->
id);
1861 dol_syslog(get_class($this).
"::setReadDate");
1863 $resql = $this->db->query($sql);
1866 $this->db->rollback();
1867 $this->date_read = $this->oldcopy->date_read;
1868 $this->error = $this->db->lasterror();
1870 dol_syslog(get_class($this).
"::setReadDate ".$this->error, LOG_ERR);
1875 $result = $this->call_trigger(
'TICKET_MODIFY', $user);
1877 $this->db->rollback();
1878 $this->date_read = $this->oldcopy->date_read;
1879 $this->error = implode(
',', $this->errors);
1881 dol_syslog(get_class($this).
"::setReadDate ".$this->error, LOG_ERR);
1886 $this->db->commit();
1889 $this->fk_user_modif = $user->id;
1890 $this->user_modification_id = $user->id;
1903 public function assignUser($user, $id_assign_user, $notrigger = 0)
1911 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
1912 if ($id_assign_user > 0) {
1913 $newstatus = Ticket::STATUS_ASSIGNED;
1915 $newstatus = Ticket::STATUS_READ;
1917 $sql .=
" SET fk_user_assign=".((int) $id_assign_user).
", fk_statut = ".((int) $newstatus);
1919 $sql .=
" SET fk_user_assign=null, fk_statut = ".Ticket::STATUS_READ;
1921 $sql .=
" WHERE rowid = ".((int) $this->
id);
1923 dol_syslog(get_class($this).
"::assignUser sql=".$sql);
1924 $resql = $this->db->query($sql);
1926 $this->fk_user_assign = $id_assign_user;
1930 $result = $this->call_trigger(
'TICKET_ASSIGNED', $user);
1938 $this->db->commit();
1941 $this->db->rollback();
1942 $this->error = implode(
',', $this->errors);
1943 dol_syslog(get_class($this).
"::assignUser ".$this->error, LOG_ERR);
1947 $this->db->rollback();
1948 $this->error = $this->db->lasterror();
1949 dol_syslog(get_class($this).
"::assignUser ".$this->error, LOG_ERR);
1968 public function createTicketMessage($user, $notrigger = 0, $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $send_email =
false, $public_area = 0, $summary =
'', $external_contacts = [])
1970 global
$conf, $langs, $hookmanager;
1976 if (isset($this->track_id)) {
1977 $this->track_id = trim($this->track_id);
1980 if (isset($this->message)) {
1981 $this->message = trim($this->message);
1987 include_once DOL_DOCUMENT_ROOT.
'/comm/action/class/actioncomm.class.php';
1989 $actioncomm->type_code =
'AC_OTH_AUTO';
1990 $actioncomm->code =
'TICKET_MSG';
1991 if ($this->
private) {
1992 $actioncomm->code =
'TICKET_MSG_PRIVATE';
1995 $actioncomm->code .=
'_SENTBYMAIL';
1997 if ((empty($user->id) || $user->id == 0) && isset($_SESSION[
'email_customer'])) {
1998 $actioncomm->email_from = $_SESSION[
'email_customer'];
2000 $actioncomm->socid = $this->socid;
2001 $actioncomm->label = $this->subject;
2003 $actioncomm->label = preg_replace(
'/(\[[^\]]*\]).*$/',
'\1', $actioncomm->label);
2004 if ($actioncomm->label) {
2005 $actioncomm->label .=
' ';
2007 $actioncomm->label .= (
string) $summary;
2010 $actioncomm->note_private = $this->message;
2011 $actioncomm->userassigned = array($user->id => array(
'id' => $user->id,
'transparency' => 0));
2013 $parameters = array();
2014 $reshook = $hookmanager->executeHooks(
'createTicketMessageExternalContacts', $parameters, $actioncomm);
2016 $actioncomm->socpeopleassigned = $external_contacts;
2017 } elseif ($reshook == 0) {
2018 $actioncomm->socpeopleassigned += $external_contacts;
2021 $actioncomm->userownerid = $user->id;
2022 $actioncomm->datep = $now;
2023 $actioncomm->percentage = -1;
2024 $actioncomm->elementtype =
'ticket';
2027 $actioncomm->elementtype =
'ticket';
2028 $actioncomm->fk_project = $this->fk_project;
2034 if ($public_area && !empty($this->origin_email) &&
getDolGlobalString(
'TICKET_ASSIGN_CONTACT_TO_MESSAGE')) {
2035 $contacts = $this->searchContactByEmail($this->origin_email);
2036 if (!empty($contacts)) {
2038 foreach ($contacts as $contact) {
2039 if ((
int) $contact->status == 1) {
2040 $actioncomm->contact_id = $contact->id;
2047 $attachedfiles = array();
2048 $attachedfiles[
'paths'] = $filename_list;
2049 $attachedfiles[
'names'] = $mimefilename_list;
2050 $attachedfiles[
'mimes'] = $mimetype_list;
2051 if (is_array($attachedfiles) && count($attachedfiles) > 0) {
2052 $actioncomm->attachedfiles = $attachedfiles;
2058 $actionid = $actioncomm->create($user);
2059 if ($actionid <= 0) {
2061 $this->error = $actioncomm->error;
2062 $this->errors = $actioncomm->errors;
2065 if ($actionid > 0) {
2066 if (is_array($attachedfiles) && array_key_exists(
'paths', $attachedfiles) && count($attachedfiles[
'paths']) > 0) {
2068 foreach ($attachedfiles[
'paths'] as $key => $filespath) {
2070 $destdir =
$conf->ticket->dir_output.
'/'.$this->ref;
2075 if (in_array($actioncomm->code, array(
'TICKET_MSG',
'TICKET_MSG_SENTBYMAIL',
'TICKET_MSG_PRIVATE'))) {
2076 $ecmfile =
new EcmFiles($this->db);
2077 $destdir = preg_replace(
'/^'.preg_quote(DOL_DATA_ROOT,
'/').
'/',
'', $destdir);
2078 $destdir = preg_replace(
'/[\\/]$/',
'', $destdir);
2079 $destdir = preg_replace(
'/^[\\/]/',
'', $destdir);
2081 $result = $ecmfile->fetch(0,
'', $destdir.
'/'.$attachedfiles[
'names'][$key]);
2084 $ecmfile->agenda_id = $actionid;
2087 $result = $ecmfile->update($user);
2100 $this->db->rollback();
2103 $this->db->commit();
2115 if (!empty($this->cache_msgs_ticket) && is_array($this->cache_msgs_ticket) && count($this->cache_msgs_ticket)) {
2121 $sql =
"SELECT id as rowid, fk_user_author, fk_user_action, email_from, datec, datep, label, note as message, code";
2122 $sql .=
" FROM ".MAIN_DB_PREFIX.
"actioncomm";
2123 $sql .=
" WHERE fk_element = ".(int) $this->
id;
2124 $sql .=
" AND elementtype = 'ticket'";
2125 $sql .=
" ORDER BY datep DESC";
2127 dol_syslog(get_class($this).
"::load_cache_actions_ticket", LOG_DEBUG);
2128 $resql = $this->db->query($sql);
2130 $num = $this->db->num_rows($resql);
2133 $obj = $this->db->fetch_object($resql);
2134 $this->cache_msgs_ticket[$i][
'id'] = $obj->rowid;
2135 $this->cache_msgs_ticket[$i][
'fk_user_author'] = $obj->fk_user_author;
2136 $this->cache_msgs_ticket[$i][
'fk_user_action'] = $obj->fk_user_action;
2137 if (in_array($obj->code, array(
'TICKET_MSG',
'AC_TICKET_CREATE')) && empty($obj->fk_user_author)) {
2138 $this->cache_msgs_ticket[$i][
'fk_contact_author'] = $obj->email_from;
2140 $this->cache_msgs_ticket[$i][
'datec'] = $this->db->jdate($obj->datec);
2141 $this->cache_msgs_ticket[$i][
'datep'] = $this->db->jdate($obj->datep);
2142 $this->cache_msgs_ticket[$i][
'subject'] = $obj->label;
2143 $this->cache_msgs_ticket[$i][
'message'] = $obj->message;
2144 $this->cache_msgs_ticket[$i][
'private'] = (preg_match(
'/^TICKET_MSG_PRIVATE/', $obj->code) ? 1 : 0);
2149 $this->error =
"Error ".$this->db->lasterror();
2150 dol_syslog(get_class($this).
"::load_cache_actions_ticket ".$this->error, LOG_ERR);
2165 if ($this->
status != Ticket::STATUS_CLOSED && $this->
status != Ticket::STATUS_CANCELED) {
2169 $this->
status = ($mode ? Ticket::STATUS_CANCELED : Ticket::STATUS_CLOSED);
2171 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2172 $sql .=
" SET fk_statut = ".((int) $this->
status).
", progress=100, date_close='".$this->db->idate(
dol_now()).
"'";
2173 $sql .=
" WHERE rowid = ".((int) $this->
id);
2175 dol_syslog(get_class($this).
"::close mode=".$mode);
2176 $resql = $this->db->query($sql);
2182 dol_syslog(
"We have closed the ticket, so we close all linked interventions");
2183 $this->fetchObjectLinked($this->
id, $this->element,
null,
'fichinter');
2184 if ($this->linkedObjectsIds) {
2185 foreach ($this->linkedObjectsIds[
'fichinter'] as $fichinter_id) {
2187 $fichinter->fetch($fichinter_id);
2188 if ($fichinter->statut == 0) {
2189 $result = $fichinter->setValid($user);
2191 $this->errors[] = $fichinter->error;
2195 if ($fichinter->statut < 3) {
2196 $result = $fichinter->setStatut(3);
2198 $this->errors[] = $fichinter->error;
2207 $result = $this->call_trigger(
'TICKET_CLOSE', $user);
2214 $this->db->commit();
2217 $this->db->rollback();
2218 $this->error = implode(
',', $this->errors);
2219 dol_syslog(get_class($this).
"::close ".$this->error, LOG_ERR);
2223 $this->db->rollback();
2224 $this->error = $this->db->lasterror();
2225 dol_syslog(get_class($this).
"::close ".$this->error, LOG_ERR);
2244 $thirdparties = array();
2248 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"societe";
2249 $sql .=
" WHERE entity IN (".getEntity(
'ticket', 1).
")";
2250 if (!empty($type)) {
2251 if ($type == 1 || $type == 2) {
2252 $sql .=
" AND client = ".((int) $type);
2253 } elseif ($type == 3) {
2254 $sql .=
" AND fournisseur = 1";
2257 if (!empty($email)) {
2258 if (empty($exact)) {
2260 if (preg_match(
'/^([\*])?[^*]+([\*])?$/', $email, $regs) && count($regs) > 1) {
2261 $email = str_replace(
'*',
'%', $email);
2263 $email =
'%'.$email.
'%';
2267 if (is_array($filters) && !empty($filters)) {
2271 $sql .=
"email LIKE '".$this->db->escape($email).
"'";
2273 if (is_array($filters) && !empty($filters)) {
2274 foreach ($filters as $field => $value) {
2275 $sql .=
" ".$clause.
" ".$this->db->sanitize($field).
" LIKE '".$this->db->escape($value).
"'";
2277 if (!empty($email)) {
2282 $res = $this->db->query($sql);
2284 while ($rec = $this->db->fetch_array($res)) {
2285 $soc =
new Societe($this->db);
2286 $soc->fetch($rec[
'rowid']);
2287 $thirdparties[] = $soc;
2290 return $thirdparties;
2292 $this->error = $this->db->error().
' sql='.$sql;
2293 dol_syslog(get_class($this).
"::searchSocidByEmail ".$this->error, LOG_ERR);
2308 $contacts = array();
2311 $sql =
"SELECT rowid FROM ".MAIN_DB_PREFIX.
"socpeople";
2312 $sql .=
" WHERE entity IN (".getEntity(
'contact').
")";
2313 if (!empty($socid)) {
2314 $sql .=
" AND fk_soc = ".((int) $socid);
2316 if (!empty($email)) {
2319 $sql .=
"email = '".$this->db->escape($email).
"'";
2321 $sql .=
"email LIKE BINARY '".$this->db->escape($this->db->escapeforlike($email)).
"'";
2325 $res = $this->db->query($sql);
2327 while ($rec = $this->db->fetch_object($res)) {
2328 include_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
2329 $contactstatic =
new Contact($this->db);
2330 $contactstatic->fetch($rec->rowid);
2331 $contacts[] = $contactstatic;
2336 $this->error = $this->db->error().
' sql='.$sql;
2337 dol_syslog(get_class($this).
"::searchContactByEmail ".$this->error, LOG_ERR);
2351 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2352 $sql .=
" SET fk_soc = ".($id > 0 ? (int)
$id :
"null");
2353 $sql .=
" WHERE rowid = ".((int) $this->
id);
2354 dol_syslog(get_class($this).
'::setCustomer sql='.$sql);
2355 $resql = $this->db->query($sql);
2375 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2376 $sql .=
" SET progress = ".($percent > 0 ? (float) $percent :
"null");
2377 $sql .=
" WHERE rowid = ".((int) $this->
id);
2378 dol_syslog(get_class($this).
'::set_progression sql='.$sql);
2379 $resql = $this->db->query($sql);
2399 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"ticket";
2400 $sql .=
" SET fk_contract = ".($contractid > 0 ? (int) $contractid :
"null");
2401 $sql .=
" WHERE rowid = ".((int) $this->
id);
2402 dol_syslog(get_class($this).
'::setContract sql='.$sql);
2403 $resql = $this->db->query($sql);
2423 return $this->getIdContact(
'internal',
'SUPPORTTEC');
2434 return $this->listeContact(-1,
'internal', 0,
'', $status);
2444 return $this->getIdContact(
'external',
'SUPPORTCLI');
2455 return $this->listeContact(-1,
'external', 0,
'', $status);
2465 return $this->getIdContact(
'internal',
'CONTRIBUTOR');
2475 return $this->getIdContact(
'external',
'CONTRIBUTOR');
2485 $array_contact = $this->getIdTicketInternalContact();
2487 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact());
2489 $array_contact = array_merge($array_contact, $this->getIdTicketInternalInvolvedContact());
2491 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact());
2493 return $array_contact;
2503 $array_contact = array();
2505 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerContact());
2507 $array_contact = array_merge($array_contact, $this->getIdTicketCustomerInvolvedContact());
2509 return $array_contact;
2524 public function listeContact($statusoflink = -1, $source =
'external', $list = 0, $code =
'', $status = -1)
2530 $sql =
"SELECT ec.rowid, ec.statut as statuslink, ec.fk_socpeople as id, ec.fk_c_type_contact";
2531 if ($source ==
'internal') {
2532 $sql .=
", '-1' as socid, t.statut as statuscontact";
2535 if ($source ==
'external' || $source ==
'thirdparty') {
2536 $sql .=
", t.fk_soc as socid, t.statut as statuscontact";
2539 $sql .=
", t.civility, t.lastname as lastname, t.firstname, t.email";
2540 if ($source ==
'internal') {
2541 $sql .=
", t.office_phone as phone, t.user_mobile as phone_mobile";
2544 if ($source ==
'external') {
2545 $sql .=
", t.phone as phone, t.phone_mobile as phone_mobile, t.phone_perso as phone_perso";
2548 $sql .=
", tc.source, tc.element, tc.code, tc.libelle as type_contact_label";
2549 $sql .=
" FROM ".MAIN_DB_PREFIX.
"c_type_contact tc";
2550 $sql .=
", ".MAIN_DB_PREFIX.
"element_contact ec";
2551 if ($source ==
'internal') {
2552 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"user t on ec.fk_socpeople = t.rowid";
2555 if ($source ==
'external' || $source ==
'thirdparty') {
2556 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"socpeople t on ec.fk_socpeople = t.rowid";
2559 $sql .=
" WHERE ec.element_id = ".((int) $this->
id);
2560 $sql .=
" AND ec.fk_c_type_contact=tc.rowid";
2561 $sql .=
" AND tc.element='".$this->db->escape($this->element).
"'";
2562 if ($source ==
'internal') {
2563 $sql .=
" AND tc.source = 'internal'";
2565 $sql .=
" AND t.statut = ".((int) $status);
2569 if ($source ==
'external' || $source ==
'thirdparty') {
2570 $sql .=
" AND tc.source = 'external'";
2572 $sql .=
" AND t.statut = ".((int) $status);
2576 if (!empty($code)) {
2577 $sql .=
" AND tc.code = '".$this->db->escape($code).
"'";
2580 $sql .=
" AND tc.active=1";
2581 if ($statusoflink >= 0) {
2582 $sql .=
" AND ec.statut = ".((int) $statusoflink);
2585 $sql .=
" ORDER BY t.lastname ASC";
2587 $resql = $this->db->query($sql);
2589 $num = $this->db->num_rows($resql);
2592 $obj = $this->db->fetch_object($resql);
2595 $transkey =
"TypeContact_".$obj->element.
"_".$obj->source.
"_".$obj->code;
2596 $labelType = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_contact_label);
2598 'source' => $obj->source,
2599 'socid' => (
int) $obj->socid,
2600 'id' => (
int) $obj->id,
2601 'nom' => $obj->lastname,
2602 'civility' => $obj->civility,
2603 'lastname' => $obj->lastname,
2604 'firstname' => $obj->firstname,
2605 'email' => $obj->email,
2606 'rowid' => (
int) $obj->rowid,
2607 'code' => $obj->code,
2608 'libelle' => $labelType,
2609 'labeltype' => $labelType,
2610 'status' => $obj->statuslink,
2611 'statuscontact' => (
int) $obj->statuscontact,
2612 'fk_c_type_contact' => (
int) $obj->fk_c_type_contact,
2613 'phone' => $obj->phone,
2614 'phone_mobile' => $obj->phone_mobile);
2615 if ($source ==
'external') {
2616 $tab[$i][
'phone_perso'] = $obj->phone_perso;
2619 $tab[$i] = $obj->id;
2627 $this->error = $this->db->error();
2650 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
2651 foreach ($dirmodels as $reldir) {
2652 $file =
dol_buildpath($reldir.
"core/modules/ticket/".$modele.
'.php', 0);
2653 if (file_exists($file)) {
2654 $classname = $modele;
2659 if ($classname !==
'') {
2661 $modTicket =
new $classname();
2662 '@phan-var-force ModeleNumRefTicket $modTicket';
2664 $defaultref = $modTicket->getNextValue($thirdparty, $this);
2667 if (is_numeric($defaultref) && $defaultref <= 0) {
2685 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2690 if (file_exists($dir_osencoded)) {
2691 $handle = opendir($dir_osencoded);
2692 if (is_resource($handle)) {
2693 while (($file = readdir($handle)) !==
false) {
2695 $file = mb_convert_encoding($file,
'UTF-8',
'ISO-8859-1');
2720 include_once DOL_DOCUMENT_ROOT.
'/core/class/html.formmail.class.php';
2721 include_once DOL_DOCUMENT_ROOT.
'/core/lib/files.lib.php';
2722 include_once DOL_DOCUMENT_ROOT.
'/core/lib/images.lib.php';
2724 $maxwidthsmall = 270;
2725 $maxheightsmall = 150;
2726 $maxwidthmini = 128;
2727 $maxheightmini = 72;
2729 $formmail =
new FormMail($this->db);
2730 $formmail->trackid = (is_null($forcetrackid) ?
'tic'.$this->id :
'');
2731 $attachedfiles = $formmail->get_attached_files();
2733 $filepath = $attachedfiles[
'paths'];
2734 $filename = $attachedfiles[
'names'];
2735 $mimetype = $attachedfiles[
'mimes'];
2738 $destdir =
$conf->ticket->dir_output.
'/'.$this->ref;
2744 $listofpaths = array();
2745 $listofnames = array();
2746 foreach ($filename as $i => $val) {
2747 $destfile = $destdir.
'/'.$filename[$i];
2749 if (is_file($destfile)) {
2750 $pathinfo = pathinfo($filename[$i]);
2752 $destfile = $destdir.
'/'.$pathinfo[
'filename'].
' - '.
dol_print_date($now,
'dayhourlog').
'.'.$pathinfo[
'extension'];
2756 'description' =>
'File saved by copyFilesForTicket',
2757 'src_object_type' => $this->element,
2758 'src_object_id' => $this->
id,
2759 'gen_or_uploaded' =>
'uploaded'
2762 $res =
dol_move($filepath[$i], $destfile,
'0', 1, 0, 1, $moreinfo);
2766 $this->error =
"Failed to move file ".dirbasename($filepath[$i]).
" into ".
dirbasename($destfile);
2773 $imgThumbSmall =
vignette($destfile, $maxwidthsmall, $maxheightsmall,
'_small', 50,
"thumbs");
2776 $imgThumbMini =
vignette($destfile, $maxwidthmini, $maxheightmini,
'_mini', 50,
"thumbs");
2781 $formmail->remove_attached_files($i);
2784 $listofpaths[$i] = $destfile;
2785 $listofnames[$i] = basename($destfile);
2788 return array(
'listofpaths' => $listofpaths,
'listofnames' => $listofnames,
'listofmimes' => $mimetype);
2804 if (!is_array($categories)) {
2805 $categories = array($categories);
2809 include_once DOL_DOCUMENT_ROOT.
'/categories/class/categorie.class.php';
2811 $existing =
$c->containing($this->
id, Categorie::TYPE_TICKET,
'id');
2814 if (is_array($existing)) {
2815 $to_del = array_diff($existing, $categories);
2816 $to_add = array_diff($categories, $existing);
2819 $to_add = $categories;
2823 foreach ($to_del as $del) {
2824 if (
$c->fetch($del) > 0) {
2825 $c->del_type($this, Categorie::TYPE_TICKET);
2828 foreach ($to_add as $add) {
2829 if (
$c->fetch($add) > 0) {
2830 $c->add_type($this, Categorie::TYPE_TICKET);
2849 public function newMessage($user, &$action, $private = 1, $public_area = 0)
2851 global
$mysoc, $langs, $hookmanager;
2865 array_push($this->errors, $langs->trans(
"ErrorTicketIsNotValid"));
2871 array_push($this->errors, $langs->trans(
"ErrorFieldRequired", $langs->transnoentities(
"Message")));
2872 $action =
'add_message';
2876 $summary = mb_strcut(
GETPOST(
'summary',
'alphanohtml'), 0, 42,
'UTF-8');
2881 $send_email = (bool)
GETPOSTINT(
'send_email');
2884 $resarray =
$object->copyFilesForTicket();
2885 if (is_numeric($resarray) && $resarray == -1) {
2890 $listofpaths = $resarray[
'listofpaths'];
2891 $listofnames = $resarray[
'listofnames'];
2892 $listofmimes = $resarray[
'listofmimes'];
2895 $external_contacts =
$object->getInfosTicketExternalContact(1);
2896 $external_resources = [];
2897 if (!empty($external_contacts)) {
2898 foreach ($external_contacts as $eContact) {
2899 $external_resources[$eContact[
'id']] = $eContact;
2906 $id =
$object->createTicketMessage($user, 0, $listofpaths, $listofmimes, $listofnames, $send_email, $public_area, $summary, $external_resources);
2910 $this->error =
$object->error;
2911 $this->errors =
$object->errors;
2912 $action =
'add_message';
2915 if (!$error &&
$id > 0) {
2916 setEventMessages($langs->trans(
'TicketMessageSuccessfullyAdded'),
null,
'mesgs');
2919 if (!empty($public_area)) {
2927 $internal_contacts =
$object->getInfosTicketInternalContact(1);
2929 $assigned_user_dont_have_email =
'';
2933 if ($this->fk_user_assign > 0) {
2934 $assigned_user =
new User($this->db);
2935 $assigned_user->fetch($this->fk_user_assign);
2936 if (!empty($assigned_user->email)) {
2937 $sendto[$assigned_user->email] = $assigned_user->getFullName($langs).
" <".$assigned_user->email.
">";
2939 $assigned_user_dont_have_email = $assigned_user->getFullName($langs);
2942 $assigned_user =
null;
2946 foreach ($internal_contacts as $key => $info_sendto) {
2948 if ($info_sendto[
'id'] == $user->id) {
2953 if (!empty($info_sendto[
'email']) && ($assigned_user ===
null || $assigned_user->email != $info_sendto[
'email'])) {
2954 $sendto[] =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
2958 if (empty($sendto)) {
2973 $parameters = array(
'sendto' => $sendto);
2974 $reshook = $hookmanager->executeHooks(
'updateSendtoTicketMessage', $parameters,
$object, $action);
2975 if (empty($reshook)) {
2976 $sendto = array_merge($sendto, $hookmanager->resArray);
2977 } elseif ($reshook > 0) {
2978 $sendto = $hookmanager->resArray;
2981 if (!empty($sendto)) {
2984 $subject =
'['.$appli.
'- ticket #'.
$object->track_id.
'] '.$this->subject;
2987 $message =
getDolGlobalString(
'TICKET_MESSAGE_MAIL_INTRO', $langs->trans(
'TicketMessageMailIntroText'));
2988 $message .=
'<br><br>';
2989 $messagePost =
GETPOST(
'message',
'restricthtml');
2993 $message .= $messagePost;
2996 $message .=
'<br><br>';
2997 $message .=
"==============================================";
2998 $message .= !empty(
$object->thirdparty->name) ?
'<br>'.$langs->trans(
'ThirdParty').
" : ".
$object->thirdparty->name :
'';
2999 $message .= !empty(
$object->thirdparty->town) ?
'<br>'.$langs->trans(
'Town').
" : ".
$object->thirdparty->town :
'';
3000 $message .= !empty(
$object->thirdparty->phone) ?
'<br>'.$langs->trans(
'Phone').
" : ".
$object->thirdparty->phone :
'';
3003 $message .=
'<br><br>';
3004 if (!empty($assigned_user_dont_have_email)) {
3005 $message .=
'<br>'.$langs->trans(
'NoEMail').
' : '.$assigned_user_dont_have_email;
3007 foreach ($sendto as $val) {
3008 $message .=
'<br>'.$langs->trans(
'TicketNotificationRecipient').
' : '.$val;
3013 $message .=
'<br><br>';
3014 $message .= $langs->trans(
'TicketNotificationEmailBodyInfosTrackUrlinternal').
' : <a href="'.$url_internal_ticket.
'">'.
$object->track_id.
'</a>';
3021 $this->sendTicketMessageByEmail($subject, $message, 0, $sendto, $listofpaths, $listofmimes, $listofnames, array(), $email_from, $replyto);
3030 if ((
int) $send_email > 0) {
3032 $internal_contacts =
$object->getInfosTicketInternalContact(1);
3035 if (is_array($internal_contacts) && count($internal_contacts) > 0) {
3039 $subject =
GETPOST(
'subject',
'alphanohtml') ?
GETPOST(
'subject',
'alphanohtml') :
'['.$appli.
' - '.$langs->trans(
"Ticket").
' #'.
$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
3041 $message_intro = $langs->trans(
'TicketNotificationEmailBody',
"#".
$object->id);
3044 $message =
getDolGlobalString(
'TICKET_MESSAGE_MAIL_INTRO', $langs->trans(
'TicketMessageMailIntroText'));
3045 $message .=
'<br><br>';
3046 $messagePost =
GETPOST(
'message',
'restricthtml');
3050 $message .= $messagePost;
3053 $message .=
'<br><br>';
3054 $message .=
"==============================================<br>";
3055 $message .= !empty(
$object->thirdparty->name) ? $langs->trans(
'ThirdParty').
" : ".
$object->thirdparty->name :
'';
3056 $message .= !empty(
$object->thirdparty->town) ?
'<br>'.$langs->trans(
'Town').
" : ".
$object->thirdparty->town :
'';
3057 $message .= !empty(
$object->thirdparty->phone) ?
'<br>'.$langs->trans(
'Phone').
" : ".
$object->thirdparty->phone :
'';
3060 foreach ($internal_contacts as $key => $info_sendto) {
3062 if ($info_sendto[
'id'] == $user->id) {
3063 dol_syslog(
"We cancel sending email to internal user ".$info_sendto[
'email'].
" because it is current user", LOG_DEBUG);
3067 if ($info_sendto[
'email'] !=
'') {
3068 $email = $info_sendto[
'email'];
3069 if ($email !=
null) {
3070 $sendto[$email] =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
3074 $recipient =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname'], -1).
' ('.strtolower((
string) $info_sendto[
'libelle']).
')';
3075 $message .= (!empty($recipient) ?
'<br>'.$langs->trans(
'TicketNotificationRecipient').
' : '.$recipient.
'<br>' :
'');
3083 $message .=
'<br>'.$langs->trans(
'TicketNotificationEmailBodyInfosTrackUrlinternal').
' : <a href="'.$url_internal_ticket.
'">'.
$object->track_id.
'</a><br>';
3092 $parameters = array(
'sendto' => $sendto);
3093 $reshook = $hookmanager->executeHooks(
'updateSendtoTicketMessage', $parameters,
$object, $action);
3094 if (empty($reshook)) {
3095 $sendto = array_merge($sendto, $hookmanager->resArray);
3096 } elseif ($reshook > 0) {
3097 $sendto = $hookmanager->resArray;
3100 $sendtocc = array();
3110 if (!empty($sendto)) {
3111 $this->sendTicketMessageByEmail($subject, $message, 0, $sendto, $listofpaths, $listofmimes, $listofnames, $sendtocc, $email_from, $replyto);
3118 if (empty(
$object->private)) {
3120 if (is_array($external_contacts) && count($external_contacts) === 0) {
3121 if (!empty(
$object->fk_soc)) {
3123 $array_company = array(array(
'id' => -1,
'firstname' =>
'',
'lastname' =>
$object->thirdparty->name,
'email' =>
$object->thirdparty->email,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' =>
$object->thirdparty->id));
3124 $external_contacts = array_merge($external_contacts, $array_company);
3125 } elseif (empty(
$object->fk_soc) && !empty(
$object->origin_replyto)) {
3126 $array_external = array(array(
'id' => -1,
'firstname' =>
'',
'lastname' =>
$object->origin_replyto,
'email' =>
$object->origin_replyto,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' => 0));
3127 $external_contacts = array_merge($external_contacts, $array_external);
3128 } elseif (empty(
$object->fk_soc) && !empty(
$object->origin_email)) {
3129 $array_external = array(array(
'id' => -1,
'firstname' =>
'',
'lastname' =>
$object->origin_email,
'email' =>
$object->origin_email,
'libelle' => $langs->transnoentities(
'Customer'),
'socid' => 0));
3130 $external_contacts = array_merge($external_contacts, $array_external);
3135 if (is_array($external_contacts) && count($external_contacts) > 0) {
3139 $subject =
GETPOST(
'subject') ?
GETPOST(
'subject') :
'['.$appli.
' - '.$langs->trans(
"Ticket").
' #'.
$object->track_id.
'] '.$langs->trans(
'TicketNewMessage');
3144 $message_intro =
dol_nl2br($message_intro);
3147 $message_signature =
dol_nl2br($message_signature);
3151 $messagePost =
GETPOST(
'message',
'restricthtml');
3155 $message = $messagePost;
3156 $message .=
'<br><br>';
3158 foreach ($external_contacts as $key => $info_sendto) {
3160 if ($info_sendto[
'id'] == $user->contact_id) {
3164 if ($info_sendto[
'email'] !=
'' && $info_sendto[
'email'] !=
$object->origin_email) {
3165 $email = $info_sendto[
'email'];
3166 if ($email !=
null) {
3167 $sendto[$email] = trim($info_sendto[
'firstname'].
" ".$info_sendto[
'lastname']).
" <".$info_sendto[
'email'].
">";
3170 $recipient =
dolGetFirstLastname($info_sendto[
'firstname'], $info_sendto[
'lastname'], -1).
' ('.strtolower((
string) $info_sendto[
'libelle']).
')';
3171 $message .= (!empty($recipient) ?
'<br>'.$langs->trans(
'TicketNotificationRecipient').
' : '.$recipient.
'<br>' :
'');
3176 $url_public_ticket = (
getDolGlobalInt(
'TICKET_ENABLE_PUBLIC_INTERFACE') ?
3179 if (
getDolGlobalInt(
'TICKET_INCLUDE_LINK_TO_PUBLIC_INTERFACE_IN_MESSAGE')) {
3180 $message .=
'<br>' . $langs->trans(
'TicketNewEmailBodyInfosTrackUrlCustomer') .
' : <a href="' . $url_public_ticket .
'">' .
$object->track_id .
'</a><br>';
3184 $message = $message_intro.
'<br><br>'.$message;
3187 $message .=
'<br>'.$message_signature;
3189 if (!empty(
$object->origin_replyto)) {
3191 } elseif (!empty(
$object->origin_email)) {
3195 if (
$object->fk_soc > 0 && !array_key_exists(
$object->origin_replyto, $sendto) && !array_key_exists(
$object->origin_email, $sendto)) {
3198 if (!empty(
$object->thirdparty->email)) {
3199 $sendto[
$object->thirdparty->email] =
$object->thirdparty->email;
3210 $parameters = array(
'sendto' => $sendto);
3211 $reshook = $hookmanager->executeHooks(
'updateSendtoTicketMessage', $parameters,
$object, $action);
3212 if (empty($reshook)) {
3213 $sendto = array_merge($sendto, $hookmanager->resArray);
3214 } elseif ($reshook > 0) {
3215 $sendto = $hookmanager->resArray;
3219 if (GETPOSTISSET(
'receiver_multiselect')) {
3220 $sendto_manual = array();
3222 $receiver_selected =
GETPOST(
'receiver',
'array');
3223 if (is_array($receiver_selected)) {
3224 foreach ($receiver_selected as $email) {
3225 $email = trim((
string) $email);
3226 if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
3227 $sendto_manual[$email] = $email;
3233 $sendto_free =
GETPOST(
'sendto',
'alphawithlgt');
3234 if ($sendto_free !==
'') {
3235 foreach (explode(
',', $sendto_free) as $entry) {
3236 $entry = trim($entry);
3237 if ($entry ===
'') {
3240 if (preg_match(
'/.*<\s*([^>]+)\s*>/', $entry, $matches)) {
3241 $email = trim($matches[1]);
3245 if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
3246 $sendto_manual[$email] = $entry;
3251 $sendto = $sendto_manual;
3255 $sendtocc = array();
3256 $sendtocc_emails = array();
3259 $cc_entry = trim($cc_entry);
3264 if (preg_match(
'/<\s*([^>]+)\s*>/', $cc_entry, $m)) {
3265 $cc_email = strtolower(trim($m[1]));
3267 $cc_email = strtolower($cc_entry);
3269 if (!in_array($cc_email, $sendtocc_emails)) {
3270 $sendtocc[] = $cc_entry;
3271 $sendtocc_emails[] = $cc_email;
3276 if (GETPOSTISSET(
'receivercc_multiselect')) {
3277 $receivercc_selected =
GETPOST(
'receivercc',
'array');
3278 if (is_array($receivercc_selected)) {
3279 foreach ($receivercc_selected as $email) {
3280 $email = trim((
string) $email);
3281 if ($email && filter_var($email, FILTER_VALIDATE_EMAIL) && !in_array(strtolower($email), $sendtocc_emails)) {
3282 $sendtocc[] = $email;
3283 $sendtocc_emails[] = strtolower($email);
3289 $sendtocc_free =
GETPOST(
'sendtocc',
'alphawithlgt');
3290 if ($sendtocc_free !==
'') {
3291 foreach (explode(
',', $sendtocc_free) as $entry) {
3292 $entry = trim($entry);
3293 if ($entry ===
'') {
3296 if (preg_match(
'/.*<\s*([^>]+)\s*>/', $entry, $matches)) {
3297 $email = trim($matches[1]);
3301 if ($email && filter_var($email, FILTER_VALIDATE_EMAIL) && !in_array(strtolower($email), $sendtocc_emails)) {
3302 $sendtocc[] = $email;
3303 $sendtocc_emails[] = strtolower($email);
3310 if (!empty($sendto)) {
3315 $result = $this->sendTicketMessageByEmail($subject, $message, 0, $sendto, $listofpaths, $listofmimes, $listofnames, $sendtocc, $email_from, $replyto);
3318 $this->date_last_msg_sent =
dol_now();
3319 $this->update($user, 1);
3323 $sql =
"UPDATE ".MAIN_DB_PREFIX.
"actioncomm";
3324 $sql .=
" SET email_msgid = '".$this->db->escape($this->email_msgid).
"',";
3325 $sql .=
" email_subject = '".$this->db->escape($subject).
"',";
3326 $sql .=
" email_from = '".$this->db->escape($email_from).
"',";
3327 $sql .=
" email_to = '".$this->db->escape(implode(
',', $sendto)).
"',";
3328 $sql .=
" email_tocc = '".$this->db->escape(implode(
',', $sendtocc)).
"',";
3329 $sql .=
" reply_to = '".$this->db->escape($replyto).
"'";
3330 $sql .=
" WHERE id = ".((int)
$id);
3332 $resql = $this->db->query($sql);
3345 && (
$object->status < self::STATUS_IN_PROGRESS && !$user->socid && !$private))
3346 || (
$object->status > self::STATUS_IN_PROGRESS && $public_area)) {
3348 $object->setStatut($object::STATUS_IN_PROGRESS,
null,
'',
'TICKET_MODIFY');
3349 } elseif (
getDolGlobalInt(
'TICKET_SET_STATUS_ON_ANSWER', -1) >= 0 && empty($user->socid) && empty($private)) {
3381 public function sendTicketMessageByEmail($subject, $message, $send_internal_cc = 0, $array_receiver = array(), $filename_list = array(), $mimetype_list = array(), $mimefilename_list = array(), $array_receiver_cc = array(), $email_from =
'', $replyto =
'')
3383 global
$conf, $langs, $user, $hookmanager;
3386 dol_syslog(get_class($this).
'::sendTicketMessageByEmail: Emails are disable into ticket setup by option TICKET_DISABLE_ALL_MAILS', LOG_WARNING);
3390 $langs->load(
"mails");
3392 include_once DOL_DOCUMENT_ROOT.
'/contact/class/contact.class.php';
3396 if (!is_array($array_receiver) || !count($array_receiver) > 0) {
3397 $array_receiver = $this->getInfosTicketInternalContact(1);
3398 $array_receiver = array_merge($array_receiver, $this->getInfosTicketExternalContact(1));
3401 dol_syslog(
"sendTicketMessageByEmail array_receiver=".json_encode($array_receiver), LOG_DEBUG);
3402 dol_syslog(
"sendTicketMessageByEmail array_receiver_cc=".json_encode($array_receiver_cc), LOG_DEBUG);
3405 if ($send_internal_cc) {
3408 if (!empty($array_receiver_cc) && is_array($array_receiver_cc)) {
3409 $sendtocc .= ($sendtocc ?
',' :
'').implode(
',', $array_receiver_cc);
3412 if (empty($email_from)) {
3416 $parameters = array(
'from' => $email_from);
3418 $reshook = $hookmanager->executeHooks(
'getTicketMessageEmailFrom', $parameters, $this, $action);
3419 if ($reshook && !empty($hookmanager->resArray[
'from'])) {
3420 $email_from = $hookmanager->resArray[
'from'];
3424 $this->email_msgids = array();
3426 if (is_array($array_receiver) && count($array_receiver) > 0) {
3428 $deliveryreceipt = 0;
3429 $filepath = $filename_list;
3430 $filename = $mimefilename_list;
3431 $mimetype = $mimetype_list;
3437 $conf->global->MAIN_MAIL_AUTOCOPY_TO =
'';
3440 $upload_dir_tmp =
$conf->user->dir_output.
"/".$user->id.
'/temp';
3442 include_once DOL_DOCUMENT_ROOT.
'/core/class/CMailFile.class.php';
3443 $trackid =
"tic".$this->id;
3445 $moreinheader =
'X-Dolibarr-Info: sendTicketMessageByEmail'.
"\r\n";
3446 if (!empty($this->email_msgid)) {
3448 $moreinheader .=
'In-Reply-To: <'.$this->email_msgid.
'>'.
"\r\n";
3456 if (!empty($this->origin_references)) {
3457 $references .= (empty($references) ?
'' :
' ').$this->origin_references;
3459 if (!empty($this->email_msgid) && !preg_match(
'/'.preg_quote($this->email_msgid,
'/').
'/', $references)) {
3460 $references .= (empty($references) ?
'' :
' ').
'<'.$this->email_msgid.
'>';
3463 $moreinheader .=
'References: '.$references.
"\r\n";
3467 $receiverstring =
'';
3468 foreach ($array_receiver as $key => $receiver) {
3469 $receiverstring .= ($receiverstring ?
',' :
'').$receiver;
3472 $sendcontext =
'ticket';
3475 $mailfile =
new CMailFile($subject, $receiverstring, $email_from, $message, $filepath, $mimetype, $filename, $sendtocc,
'', $deliveryreceipt, -1,
'',
'', $trackid, $moreinheader, $sendcontext, $replyto, $upload_dir_tmp);
3478 if ($mailfile->error) {
3481 $result = $mailfile->sendfile();
3484 setEventMessages($langs->trans(
'MailSuccessfulySent', $mailfile->getValidAddress($email_from, 2), $mailfile->getValidAddress($receiverstring, 2)),
null,
'mesgs');
3487 $this->email_msgid = $mailfile->msgid;
3489 $langs->load(
"other");
3490 if ($mailfile->error) {
3491 setEventMessages($langs->trans(
'ErrorFailedToSendMail', $email_from, $receiverstring),
null,
'errors');
3492 dol_syslog(
'ErrorFailedToSendMail from='.$email_from.
' to='.$receiverstring.
' : '.$mailfile->error);
3494 setEventMessages(
'No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS',
null,
'errors');
3496 setEventMessages($langs->trans(
'ErrorFailedToSendMail', $email_from, $receiverstring),
null,
'errors');
3497 dol_syslog(
'ErrorFailedToSendMail from='.$email_from.
' to='.$receiverstring.
' : (no error details)', LOG_WARNING);
3503 $conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
3507 $langs->load(
"other");
3508 setEventMessages($langs->trans(
'ErrorMailRecipientIsEmptyForSendTicketMessage'),
null,
'warnings');
3525 global $user, $langs;
3532 $sql =
"SELECT p.rowid, p.ref, p.datec as datec";
3533 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as p";
3534 if (empty($user->socid) &&
isModEnabled(
'societe') && !$user->hasRight(
'societe',
'client',
'voir') && !$user->socid) {
3535 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON p.fk_soc = sc.fk_soc";
3536 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3539 $sql .= $clause.
" p.entity IN (".
getEntity(
'ticket').
")";
3540 if ($mode ==
'opened') {
3541 $sql .=
" AND p.fk_statut NOT IN (".Ticket::STATUS_CLOSED.
", ".Ticket::STATUS_CANCELED.
")";
3544 $sql .=
" AND p.fk_soc = ".((int) $user->socid);
3547 $resql = $this->db->query($sql);
3549 $label = $labelShort =
'';
3551 if ($mode ==
'opened') {
3552 $status =
'openall';
3555 $label = $langs->trans(
"MenuListNonClosed");
3556 $labelShort = $langs->trans(
"MenuListNonClosed");
3561 $response->label = $label;
3562 $response->labelShort = $labelShort;
3563 $response->url = DOL_URL_ROOT.
'/ticket/list.php?search_fk_statut[]='.$status;
3567 while ($obj = $this->db->fetch_object($resql)) {
3568 $response->nbtodo++;
3569 if ($mode ==
'opened') {
3570 $datelimit = (int) $this->db->jdate($obj->datec) + (int) $delay_warning;
3571 if ($datelimit < $now) {
3578 $this->error = $this->db->lasterror();
3592 $this->nb = array();
3595 $sql =
"SELECT count(p.rowid) as nb";
3596 $sql .=
" FROM ".MAIN_DB_PREFIX.
"ticket as p";
3597 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe as s ON p.fk_soc = s.rowid";
3598 if (empty($user->socid) && !$user->hasRight(
'societe',
'client',
'voir')) {
3599 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe_commerciaux as sc ON s.rowid = sc.fk_soc";
3600 $sql .=
" WHERE sc.fk_user = ".((int) $user->id);
3603 $sql .=
" ".$clause.
" p.entity IN (".
getEntity(
'ticket').
")";
3605 $resql = $this->db->query($sql);
3608 while ($obj = $this->db->fetch_object($resql)) {
3609 $this->nb[
"ticket"] = $obj->nb;
3611 $this->db->free($resql);
3615 $this->error = $this->db->lasterror();
3630 $tables = array(
'ticket');
3646 $selected = (empty($arraydata[
'selected']) ? 0 : $arraydata[
'selected']);
3648 $return =
'<div class="box-flex-item box-flex-grow-zero">';
3649 $return .=
'<div class="info-box info-box-sm">';
3650 $return .=
'<span class="info-box-icon bg-infobox-action">';
3652 $return .=
'</span>';
3653 $return .=
'<div class="info-box-content">';
3654 $return .=
'<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">'.(method_exists($this,
'getNomUrl') ? $this->getNomUrl(1) : $this->ref).
'</span>';
3655 if ($selected >= 0) {
3656 $return .=
'<input id="cb'.$this->id.
'" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="'.$this->
id.
'"'.($selected ?
' checked="checked"' :
'').
'>';
3658 if (!empty($arraydata[
'user_assignment'])) {
3659 $return .=
'<br><span class="info-box-label" title="'.dol_escape_htmltag($langs->trans(
"AssignedTo")).
'">'.$arraydata[
'user_assignment'].
'</span>';
3661 if (property_exists($this,
'type_code') && !empty($this->type_code)) {
3663 $return .=
'<div class="tdoverflowmax125 inline-block">'.$langs->getLabelFromKey($this->db,
'TicketTypeShort'.$this->type_code,
'c_ticket_type',
'code',
'label', $this->type_code).
'</div>';
3665 if (method_exists($this,
'getLibStatut')) {
3666 $return .=
'<br><div class="info-box-status">'.$this->getLibStatut(3).
'</div>';
3668 $return .=
'</div>';
3669 $return .=
'</div>';
3670 $return .=
'</div>';
3686 public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams =
null)
3690 $langs->load(
"ticket");
3691 $outputlangs->load(
"ticket");
3694 $modele =
'generic_ticket_odt';
3696 if (!empty($this->model_pdf)) {
3697 $modele = $this->model_pdf;
3703 $modelpath =
"core/modules/ticket/doc/";
3705 return $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
Class to manage agenda events (actions)
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class to manage categories.
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.
add_contact($fk_socpeople, $type_contact, $source='external', $notrigger=0)
Add a link between element $this->element and a contact.
Class to manage Dolibarr database access.
Class to manage ECM files.
Class to manage third parties objects (customers, suppliers, prospects...)
fetch($id=0, $ref='', $track_id='', $email_msgid='')
Load object in memory from the database.
fetchAll($user, $sortorder='ASC', $sortfield='t.datec', $limit=0, $offset=0, $arch=0, $filter='')
Load all objects in memory from database.
static replaceThirdparty($db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
createTicketMessage($user, $notrigger=0, $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $send_email=false, $public_area=0, $summary='', $external_contacts=[])
Add message into 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.
searchSocidByEmail($email, $type=0, $filters=array(), $clause='AND')
Search and fetch thirparties by email.
loadCacheSeveritiesTickets()
Load into cache the list of ticket severities (configurable in the dictionary)
$fields
'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]',...
getInfosTicketExternalContact($status=-1)
Retrieve information about external contacts.
searchContactByEmail($email, $socid=0, $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.
setReadDate($user, $notrigger=0)
Set read date if not already set.
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.
loadStateBoard()
Load indicator this->nb of global stats widget.
getTooltipContentArray($params)
getTooltipContentArray
getKanbanView($option='', $arraydata=null)
Return clickable 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.
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=null)
Get a default reference.
const STATUS_NOT_READ
Status.
sendTicketMessageByEmail($subject, $message, $send_internal_cc=0, $array_receiver=array(), $filename_list=array(), $mimetype_list=array(), $mimefilename_list=array(), $array_receiver_cc=array(), $email_from='', $replyto='')
Send ticket by email to linked contacts.
getTicketAllCustomerContacts()
Return id of all contacts for ticket.
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).
getIdTicketCustomerContact()
Return id des contacts clients pour le suivi ticket.
checkExistingRef(string $action, string $getRef)
Check if ref exists or not.
__construct(DoliDB $db)
Constructor.
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.
generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
Create a document onto disk according to template module.
getNomUrl($withpicto=0, $option='', $notooltip=0, $morecss='', $save_lastsearch_value=-1)
Return a link to the object card (with optionally the picto)
load_board($user, $mode)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
getInfosTicketInternalContact($status=-1)
Retrieve information about internal contacts.
create($user, $notrigger=0)
Create object into database.
Class to manage Dolibarr users.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
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(), $entity=null)
Move a file into another name.
dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0, $indexdatabase=1, $nolog=0, $level=0)
Remove a directory $dir and its subdirectories (or only files and subdirectories)
dol_is_file($pathoffile)
Return if path is a file.
dol_is_dir($folder)
Test if filename is a directory.
dol_now($mode='gmt')
Return date for now.
setEntity($currentobject)
Set entity id to use when to create an object.
dol_osencode($str)
Return a string encoded into OS filesystem encoding.
isDolTms($timestamp)
isDolTms check if a timestamp is valid.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0, $forbiddenfields=array())
forgeSQLFromUniversalSearchCriteria
dol_textishtml($msg, $option=0)
Return if a text is a html content.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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)
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
Class to generate the form for creating a new ticket.
generate_random_id($car=16)
Generate a random id.