dolibarr  18.0.6
actioncomm.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5  * Copyright (C) 2011-2017 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7  * Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
8  * Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <https://www.gnu.org/licenses/>.
22  */
23 
29 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
30 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
31 require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
33 
34 
38 class ActionComm extends CommonObject
39 {
43  public $element = 'action';
44 
48  public $table_element = 'actioncomm';
49 
53  public $table_rowid = 'id';
54 
58  public $picto = 'action';
59 
63  public $ismultientitymanaged = 1;
64 
70  public $restrictiononfksoc = 2;
71 
75  public $id;
76 
80  public $ref;
81 
86  public $type_id;
87 
92  public $type;
93 
98  public $type_code;
99 
103  public $type_label;
104 
108  public $type_color;
109 
113  public $type_picto;
114 
119  public $code;
120 
124  public $label;
125 
130  public $libelle;
131 
135  public $datec;
136 
140  public $duree;
141 
145  public $datem;
146 
152  public $author;
153 
159  public $usermod;
160 
164  public $authorid;
165 
169  public $usermodid;
170 
174  public $datep;
175 
179  public $datef;
180 
184  public $date_start_in_calendar;
185 
189  public $date_end_in_calendar;
190 
194  public $datep2;
195 
200  public $durationp = -1;
201 
205  public $fulldayevent = 0;
206 
210  public $ponctuel;
211 
215  public $percentage;
216 
220  public $location;
221 
225  public $transparency;
226 
230  public $priority;
231 
235  public $userassigned = array();
236 
240  public $userownerid;
241 
245  public $userdoneid;
246 
250  public $socpeopleassigned = array();
251 
255  public $otherassigned = array();
256 
260  public $reminders = array();
261 
265  public $socid;
266 
270  public $contact_id;
271 
272 
278  public $societe;
279 
285  public $contact;
286 
287  // Properties for links to other objects
291  public $fk_element; // Id of record
292 
296  public $elementid;
297 
301  public $elementtype;
302 
306  public $icalname;
307 
311  public $icalcolor;
312 
316  public $extraparams;
317 
321  public $actions = array();
322 
326  public $email_msgid;
327 
331  public $email_from;
332 
336  public $email_sender;
337 
341  public $email_to;
342 
346  public $email_tocc;
350  public $email_tobcc;
351 
355  public $email_subject;
356 
360  public $errors_to;
361 
365  public $num_vote;
366 
370  public $event_paid;
371 
375  public $status;
376 
380  public $recurid; /* A string YYYYMMDDHHMMSS shared by allevent of same serie */
381  public $recurrule; /* Rule of recurring */
382  public $recurdateend; /* Repeat until this date */
383 
384  public $calling_duration;
385 
386 
390  const EVENT_TODO = 0;
391 
395  const EVENT_IN_PROGRESS = 50;
396 
400  const EVENT_FINISHED = 100;
401 
402 
403  public $fields = array();
404 
405 
411  public function __construct(DoliDB $db)
412  {
413  $this->db = $db;
414  }
415 
424  public function create(User $user, $notrigger = 0)
425  {
426  global $langs, $conf;
427 
428  $error = 0;
429  $now = dol_now();
430 
431  // Check parameters
432  if (!isset($this->userownerid) || (string) $this->userownerid === '') { // $this->userownerid may be 0 (anonymous event) or > 0
433  dol_syslog("You tried to create an event but mandatory property ownerid was not defined", LOG_WARNING);
434  $this->errors[] = 'ErrorActionCommPropertyUserowneridNotDefined';
435  return -1;
436  }
437 
438  // Clean parameters
439  $this->label = dol_trunc(trim($this->label), 128);
440  $this->location = dol_trunc(trim($this->location), 128);
441  $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private));
442  if (empty($this->percentage)) {
443  $this->percentage = 0;
444  }
445  if (empty($this->priority) || !is_numeric($this->priority)) {
446  $this->priority = 0;
447  }
448  if (empty($this->fulldayevent)) {
449  $this->fulldayevent = 0;
450  }
451  if (empty($this->transparency)) {
452  $this->transparency = 0;
453  }
454  if ($this->percentage > 100) {
455  $this->percentage = 100;
456  }
457  if (empty($this->datep) && $this->datep != '0') { // We should not insert event in calendar without a start date
458  $this->datep = $now;
459  }
460  if (!empty($this->datep) && !empty($this->datef)) {
461  $this->durationp = ($this->datef - $this->datep); // deprecated
462  }
463  if (!empty($this->datep) && !empty($this->datef) && $this->datep > $this->datef) {
464  $this->datef = $this->datep;
465  }
466  if (!isset($this->fk_project) || $this->fk_project < 0) {
467  $this->fk_project = 0;
468  }
469  // For backward compatibility
470  if ($this->elementtype == 'facture') {
471  $this->elementtype = 'invoice';
472  }
473  if ($this->elementtype == 'commande') {
474  $this->elementtype = 'order';
475  }
476  if ($this->elementtype == 'contrat') {
477  $this->elementtype = 'contract';
478  }
479 
480  if (!is_array($this->userassigned) && !empty($this->userassigned)) { // For backward compatibility when userassigned was an int instead of an array
481  $tmpid = (int) $this->userassigned;
482  $this->userassigned = array();
483  $this->userassigned[$tmpid] = array('id'=>$tmpid, 'transparency'=>$this->transparency);
484  }
485 
486  $userownerid = $this->userownerid;
487  $userdoneid = $this->userdoneid;
488 
489  // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...).
490  if (empty($this->userassigned) || count($this->userassigned) == 0 || !is_array($this->userassigned)) {
491  $this->userassigned = array($userownerid=>array('id'=>$userownerid, 'transparency'=>$this->transparency));
492  }
493 
494  if (!$this->type_id || !$this->type_code) {
495  $key = empty($this->type_id) ? $this->type_code : $this->type_id;
496 
497  // Get id from code
498  $cactioncomm = new CActionComm($this->db);
499  $result = $cactioncomm->fetch($key);
500 
501  if ($result > 0) {
502  $this->type_id = $cactioncomm->id;
503  $this->type_code = $cactioncomm->code;
504  } elseif ($result == 0) {
505  $this->error = $langs->trans('ErrorActionCommBadType', $this->type_id, $this->type_code);
506  return -1;
507  } else {
508  $this->error = $cactioncomm->error;
509  return -1;
510  }
511  }
512  $code = empty($this->code) ? $this->type_code : $this->code;
513 
514  // Check parameters
515  if (!$this->type_id) {
516  $this->error = "ErrorWrongParameters";
517  return -1;
518  }
519 
520  $this->db->begin();
521 
522  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm";
523  $sql .= "(ref,";
524  $sql .= "datec,";
525  $sql .= "datep,";
526  $sql .= "datep2,";
527  $sql .= "durationp,"; // deprecated
528  $sql .= "fk_action,";
529  $sql .= "code,";
530  $sql .= "ref_ext,";
531  $sql .= "fk_soc,";
532  $sql .= "fk_project,";
533  $sql .= "note,";
534  $sql .= "fk_contact,";
535  $sql .= "fk_user_author,";
536  $sql .= "fk_user_action,";
537  $sql .= "fk_user_done,";
538  $sql .= "label,percent,priority,fulldayevent,location,";
539  $sql .= "transparency,";
540  $sql .= "fk_element,";
541  $sql .= "elementtype,";
542  $sql .= "entity,";
543  $sql .= "extraparams,";
544  // Fields emails
545  $sql .= "email_msgid,";
546  $sql .= "email_from,";
547  $sql .= "email_sender,";
548  $sql .= "email_to,";
549  $sql .= "email_tocc,";
550  $sql .= "email_tobcc,";
551  $sql .= "email_subject,";
552  $sql .= "errors_to,";
553  $sql .= "recurid,";
554  $sql .= "recurrule,";
555  $sql .= "recurdateend,";
556  $sql .= "num_vote,";
557  $sql .= "event_paid,";
558  $sql .= "status,";
559  $sql .= "ip";
560  $sql .= ") VALUES (";
561  $sql .= "'(PROV)', ";
562  $sql .= "'".$this->db->idate($now)."', "; // date creation
563  $sql .= "'".$this->db->idate($this->datep)."', "; // date start event
564  $sql .= (strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : "null").", ";
565  $sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated
566  $sql .= (isset($this->type_id) ? $this->type_id : "null").",";
567  $sql .= ($code ? ("'".$this->db->escape($code)."'") : "null").", ";
568  $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").", ";
569  $sql .= ((isset($this->socid) && $this->socid > 0) ? ((int) $this->socid) : "null").", ";
570  $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? ((int) $this->fk_project) : "null").", ";
571  $sql .= " '".$this->db->escape($this->note_private)."', ";
572  $sql .= ((isset($this->contact_id) && $this->contact_id > 0) ? ((int) $this->contact_id) : "null").", "; // deprecated, use ->socpeopleassigned
573  $sql .= (isset($user->id) && $user->id > 0 ? $user->id : "null").", ";
574  $sql .= ($userownerid > 0 ? $userownerid : "null").", ";
575  $sql .= ($userdoneid > 0 ? $userdoneid : "null").", ";
576  $sql .= "'".$this->db->escape($this->label)."', ";
577  $sql .= "'".$this->db->escape($this->percentage)."', ";
578  $sql .= "'".$this->db->escape($this->priority)."', ";
579  $sql .= "'".$this->db->escape($this->fulldayevent)."', ";
580  $sql .= "'".$this->db->escape($this->location)."', ";
581  $sql .= "'".$this->db->escape($this->transparency)."', ";
582  $sql .= (!empty($this->fk_element) ? ((int) $this->fk_element) : "null").", ";
583  $sql .= (!empty($this->elementtype) ? "'".$this->db->escape($this->elementtype)."'" : "null").", ";
584  $sql .= ((int) $conf->entity).",";
585  $sql .= (!empty($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").", ";
586  // Fields emails
587  $sql .= (!empty($this->email_msgid) ? "'".$this->db->escape($this->email_msgid)."'" : "null").", ";
588  $sql .= (!empty($this->email_from) ? "'".$this->db->escape($this->email_from)."'" : "null").", ";
589  $sql .= (!empty($this->email_sender) ? "'".$this->db->escape($this->email_sender)."'" : "null").", ";
590  $sql .= (!empty($this->email_to) ? "'".$this->db->escape($this->email_to)."'" : "null").", ";
591  $sql .= (!empty($this->email_tocc) ? "'".$this->db->escape($this->email_tocc)."'" : "null").", ";
592  $sql .= (!empty($this->email_tobcc) ? "'".$this->db->escape($this->email_tobcc)."'" : "null").", ";
593  $sql .= (!empty($this->email_subject) ? "'".$this->db->escape($this->email_subject)."'" : "null").", ";
594  $sql .= (!empty($this->errors_to) ? "'".$this->db->escape($this->errors_to)."'" : "null").", ";
595  $sql .= (!empty($this->recurid) ? "'".$this->db->escape($this->recurid)."'" : "null").", ";
596  $sql .= (!empty($this->recurrule) ? "'".$this->db->escape($this->recurrule)."'" : "null").", ";
597  $sql .= (!empty($this->recurdateend) ? "'".$this->db->idate($this->recurdateend)."'" : "null").", ";
598  $sql .= (!empty($this->num_vote) ? (int) $this->num_vote : "null").", ";
599  $sql .= (!empty($this->event_paid) ? (int) $this->event_paid : 0).", ";
600  $sql .= (!empty($this->status) ? (int) $this->status : "0").", ";
601  $sql .= (!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
602  $sql .= ")";
603 
604  dol_syslog(get_class($this)."::add", LOG_DEBUG);
605  $resql = $this->db->query($sql);
606  if ($resql) {
607  $this->ref = $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm", "id");
608  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm SET ref='".$this->db->escape($this->ref)."' WHERE id=".$this->id;
609  $resql = $this->db->query($sql);
610  if (!$resql) {
611  $error++;
612  dol_syslog('Error to process ref: '.$this->db->lasterror(), LOG_ERR);
613  $this->errors[] = $this->db->lasterror();
614  }
615  // Now insert assigned users
616  if (!$error) {
617  //dol_syslog(var_export($this->userassigned, true));
618  $already_inserted = array();
619  foreach ($this->userassigned as $key => $val) {
620  // Common value with new behavior is to have $val = array('id'=>iduser, 'transparency'=>0|1) and $this->userassigned is an array of iduser => $val.
621  if (!is_array($val)) { // For backward compatibility when $val='id'.
622  $val = array('id'=>$val);
623  }
624 
625  if ($val['id'] > 0) {
626  if (!empty($already_inserted[$val['id']])) {
627  continue;
628  }
629 
630  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
631  $sql .= " VALUES(".((int) $this->id).", 'user', ".((int) $val['id']).", ".(empty($val['mandatory']) ? '0' : ((int) $val['mandatory'])).", ".(empty($val['transparency']) ? '0' : ((int) $val['transparency'])).", ".(empty($val['answer_status']) ? '0' : ((int) $val['answer_status'])).")";
632 
633  $resql = $this->db->query($sql);
634  if (!$resql) {
635  $error++;
636  dol_syslog('Error to process userassigned: ' . $this->db->lasterror(), LOG_ERR);
637  $this->errors[] = $this->db->lasterror();
638  } else {
639  $already_inserted[$val['id']] = true;
640  }
641  //var_dump($sql);exit;
642  }
643  }
644  }
645 
646  if (!$error) {
647  if (!empty($this->socpeopleassigned)) {
648  $already_inserted = array();
649  foreach ($this->socpeopleassigned as $id => $val) {
650  // Common value with new behavior is to have $val = iduser and $this->socpeopleassigned is an array of iduser => $val.
651  if (!empty($already_inserted[$id])) {
652  continue;
653  }
654 
655  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
656  $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $id).", 0, 0, 0)";
657 
658  $resql = $this->db->query($sql);
659  if (!$resql) {
660  $error++;
661  dol_syslog('Error to process socpeopleassigned: ' . $this->db->lasterror(), LOG_ERR);
662  $this->errors[] = $this->db->lasterror();
663  } else {
664  $already_inserted[$id] = true;
665  }
666  }
667  }
668  }
669 
670  if (!$error) {
671  // Actions on extra fields
672  $result = $this->insertExtraFields();
673  if ($result < 0) {
674  $error++;
675  }
676  }
677 
678  if (!$error && !$notrigger) {
679  // Call trigger
680  $result = $this->call_trigger('ACTION_CREATE', $user);
681  if ($result < 0) {
682  $error++;
683  }
684  // End call triggers
685  }
686 
687  if (!$error) {
688  $this->db->commit();
689  return $this->id;
690  } else {
691  $this->db->rollback();
692  return -1;
693  }
694  } else {
695  $this->db->rollback();
696  $this->error = $this->db->lasterror();
697  return -1;
698  }
699  }
700 
708  public function createFromClone(User $fuser, $socid)
709  {
710  global $hookmanager;
711 
712  $error = 0;
713 
714  $this->db->begin();
715 
716  // Load source object
717  $objFrom = clone $this;
718 
719  // Retrieve all extrafield
720  // fetch optionals attributes and labels
721  $this->fetch_optionals();
722 
723  //$this->fetch_userassigned();
724  $this->fetchResources();
725 
726  $this->id = 0;
727  $this->recurid = '';
728  $this->recurrule = '';
729  $this->recurdateend = '';
730 
731  // Create clone
732  $this->context['createfromclone'] = 'createfromclone';
733  $result = $this->create($fuser);
734  if ($result < 0) {
735  $error++;
736  }
737 
738  if (!$error) {
739  // Hook of thirdparty module
740  if (is_object($hookmanager)) {
741  $parameters = array('objFrom'=>$objFrom);
742  $action = '';
743  $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
744  if ($reshook < 0) {
745  $this->setErrorsFromObject($hookmanager);
746  $error++;
747  }
748  }
749 
750  // Call trigger
751  $result = $this->call_trigger('ACTION_CLONE', $fuser);
752  if ($result < 0) {
753  $error++;
754  }
755  // End call triggers
756  }
757 
758  unset($this->context['createfromclone']);
759 
760  // End
761  if (!$error) {
762  $this->db->commit();
763  return $this->id;
764  } else {
765  $this->db->rollback();
766  return -1;
767  }
768  }
769 
780  public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '', $loadresources = 1)
781  {
782  global $langs;
783 
784  if (empty($id) && empty($ref) && empty($ref_ext) && empty($email_msgid)) {
785  dol_syslog(get_class($this)."::fetch Bad parameters", LOG_WARNING);
786  return -1;
787  }
788 
789  $sql = "SELECT a.id,";
790  $sql .= " a.ref as ref,";
791  $sql .= " a.entity,";
792  $sql .= " a.ref_ext,";
793  $sql .= " a.datep,";
794  $sql .= " a.datep2,";
795  $sql .= " a.durationp,"; // deprecated
796  $sql .= " a.datec,";
797  $sql .= " a.tms as datem,";
798  $sql .= " a.code, a.label, a.note as note_private,";
799  $sql .= " a.fk_soc,";
800  $sql .= " a.fk_project,";
801  $sql .= " a.fk_user_author, a.fk_user_mod,";
802  $sql .= " a.fk_user_action, a.fk_user_done,";
803  $sql .= " a.fk_contact, a.percent as percentage,";
804  $sql .= " a.fk_element as elementid, a.elementtype,";
805  $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
806  $sql .= " a.email_msgid, a.email_subject, a.email_from, a.email_sender, a.email_to, a.email_tocc, a.email_tobcc, a.errors_to,";
807  $sql .= " c.id as type_id, c.type as type_type, c.code as type_code, c.libelle as type_label, c.color as type_color, c.picto as type_picto,";
808  $sql .= " s.nom as socname,";
809  $sql .= " u.firstname, u.lastname as lastname,";
810  $sql .= " num_vote, event_paid, a.status";
811  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a ";
812  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action=c.id ";
813  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author";
814  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
815  $sql .= " WHERE ";
816  if ($ref) {
817  $sql .= " a.ref = '".$this->db->escape($ref)."'";
818  } elseif ($ref_ext) {
819  $sql .= " a.ref_ext = '".$this->db->escape($ref_ext)."'";
820  } elseif ($email_msgid) {
821  $sql .= " a.email_msgid = '".$this->db->escape($email_msgid)."'";
822  } else {
823  $sql .= " a.id = ".((int) $id);
824  }
825 
826  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
827  $resql = $this->db->query($sql);
828  if ($resql) {
829  $num = $this->db->num_rows($resql);
830  if ($num) {
831  $obj = $this->db->fetch_object($resql);
832 
833  $this->id = $obj->id;
834  $this->entity = $obj->entity;
835  $this->ref = $obj->ref;
836  $this->ref_ext = $obj->ref_ext;
837 
838  // Properties of parent table llx_c_actioncomm
839  $this->type_id = $obj->type_id;
840  $this->type_code = $obj->type_code;
841  $this->type_color = $obj->type_color;
842  $this->type_picto = $obj->type_picto;
843  $this->type = $obj->type_type;
844  /*$transcode = $langs->trans("Action".$obj->type_code);
845  $this->type = (($transcode != "Action".$obj->type_code) ? $transcode : $obj->type_label); */
846  $transcode = $langs->trans("Action".$obj->type_code.'Short');
847 
848  $this->code = $obj->code;
849  $this->label = $obj->label;
850  $this->datep = $this->db->jdate($obj->datep);
851  $this->datef = $this->db->jdate($obj->datep2);
852 
853  $this->datec = $this->db->jdate($obj->datec);
854  $this->datem = $this->db->jdate($obj->datem);
855 
856  $this->note = $obj->note_private; // deprecated
857  $this->note_private = $obj->note_private;
858  $this->percentage = $obj->percentage;
859 
860  $this->authorid = $obj->fk_user_author;
861  $this->usermodid = $obj->fk_user_mod;
862 
863  if (!is_object($this->author)) {
864  $this->author = new User($this->db); // To avoid warning
865  }
866  $this->author->id = $obj->fk_user_author; // deprecated
867  $this->author->firstname = $obj->firstname; // deprecated
868  $this->author->lastname = $obj->lastname; // deprecated
869  if (!is_object($this->usermod)) {
870  $this->usermod = new User($this->db); // To avoid warning
871  }
872  $this->usermod->id = $obj->fk_user_mod; // deprecated
873 
874  $this->userownerid = $obj->fk_user_action;
875  $this->priority = $obj->priority;
876  $this->fulldayevent = $obj->fulldayevent;
877  $this->location = $obj->location;
878  $this->transparency = $obj->transparency;
879 
880  $this->socid = $obj->fk_soc; // To have fetch_thirdparty method working
881  $this->contact_id = $obj->fk_contact; // To have fetch_contact method working
882  $this->fk_project = $obj->fk_project; // To have fetch_projet method working
883 
884  //$this->societe->id = $obj->fk_soc; // deprecated
885  //$this->contact->id = $obj->fk_contact; // deprecated
886 
887  $this->fk_element = $obj->elementid;
888  $this->elementid = $obj->elementid;
889  $this->elementtype = $obj->elementtype;
890 
891  $this->num_vote = $obj->num_vote;
892  $this->event_paid = $obj->event_paid;
893  $this->status = $obj->status;
894 
895  //email information
896  $this->email_msgid=$obj->email_msgid;
897  $this->email_from=$obj->email_from;
898  $this->email_sender=$obj->email_sender;
899  $this->email_to=$obj->email_to;
900  $this->email_tocc=$obj->email_tocc;
901  $this->email_tobcc=$obj->email_tobcc;
902  $this->email_subject=$obj->email_subject;
903  $this->errors_to=$obj->errors_to;
904 
905  $this->fetch_optionals();
906 
907  if ($loadresources) {
908  $this->fetchResources();
909  }
910  }
911 
912  $this->db->free($resql);
913  } else {
914  $this->error = $this->db->lasterror();
915  return -1;
916  }
917 
918  return $num;
919  }
920 
926  public function fetchResources()
927  {
928  $this->userassigned = array();
929  $this->socpeopleassigned = array();
930 
931  $sql = 'SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency';
932  $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm_resources';
933  $sql .= ' WHERE fk_actioncomm = '.((int) $this->id);
934  $sql .= " AND element_type IN ('user', 'socpeople')";
935  $resql = $this->db->query($sql);
936  if ($resql) {
937  // If owner is known, we must but id first into list
938  if ($this->userownerid > 0) {
939  $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid); // Set first so will be first into list.
940  }
941 
942  while ($obj = $this->db->fetch_object($resql)) {
943  if ($obj->fk_element > 0) {
944  switch ($obj->element_type) {
945  case 'user':
946  $this->userassigned[$obj->fk_element] = array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
947  if (empty($this->userownerid)) {
948  $this->userownerid = $obj->fk_element; // If not defined (should not happened, we fix this)
949  }
950  break;
951  case 'socpeople':
952  $this->socpeopleassigned[$obj->fk_element] = array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
953  break;
954  }
955  }
956  }
957 
958  return 1;
959  } else {
960  dol_print_error($this->db);
961  return -1;
962  }
963  }
964 
965  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
972  public function fetch_userassigned($override = true)
973  {
974  // phpcs:enable
975  $sql = "SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency";
976  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_resources";
977  $sql .= " WHERE element_type = 'user' AND fk_actioncomm = ".((int) $this->id);
978 
979  $resql2 = $this->db->query($sql);
980  if ($resql2) {
981  $this->userassigned = array();
982 
983  // If owner is known, we must but id first into list
984  if ($this->userownerid > 0) {
985  // Set first so will be first into list.
986  $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid);
987  }
988 
989  while ($obj = $this->db->fetch_object($resql2)) {
990  if ($obj->fk_element > 0) {
991  $this->userassigned[$obj->fk_element] = array('id'=>$obj->fk_element,
992  'mandatory'=>$obj->mandatory,
993  'answer_status'=>$obj->answer_status,
994  'transparency'=>$obj->transparency);
995  }
996 
997  if ($override === true) {
998  // If not defined (should not happened, we fix this)
999  if (empty($this->userownerid)) {
1000  $this->userownerid = $obj->fk_element;
1001  }
1002  }
1003  }
1004 
1005  return 1;
1006  } else {
1007  dol_print_error($this->db);
1008  return -1;
1009  }
1010  }
1011 
1018  public function delete($notrigger = 0)
1019  {
1020  global $user;
1021 
1022  $error = 0;
1023 
1024  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1025 
1026  $this->db->begin();
1027 
1028  // remove categorie association
1029  if (!$error) {
1030  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_actioncomm";
1031  $sql .= " WHERE fk_actioncomm=".((int) $this->id);
1032 
1033  $res = $this->db->query($sql);
1034  if (!$res) {
1035  $this->error = $this->db->lasterror();
1036  $error++;
1037  }
1038  }
1039 
1040  // remove actioncomm_resources
1041  if (!$error) {
1042  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources";
1043  $sql .= " WHERE fk_actioncomm=".((int) $this->id);
1044 
1045  $res = $this->db->query($sql);
1046  if (!$res) {
1047  $this->error = $this->db->lasterror();
1048  $error++;
1049  }
1050  }
1051 
1052  if (!$error) {
1053  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
1054  $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
1055 
1056  $res = $this->db->query($sql);
1057  if (!$res) {
1058  $this->error = $this->db->lasterror();
1059  $error++;
1060  }
1061  }
1062 
1063  // Removed extrafields
1064  if (!$error) {
1065  $result = $this->deleteExtraFields();
1066  if ($result < 0) {
1067  $error++;
1068  dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
1069  }
1070  }
1071 
1072  // remove actioncomm
1073  if (!$error) {
1074  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm";
1075  $sql .= " WHERE id=".((int) $this->id);
1076 
1077  $res = $this->db->query($sql);
1078  if (!$res) {
1079  $this->error = $this->db->lasterror();
1080  $error++;
1081  }
1082  }
1083 
1084  if (!$error) {
1085  if (!$notrigger) {
1086  // Call trigger
1087  $result = $this->call_trigger('ACTION_DELETE', $user);
1088  if ($result < 0) {
1089  $error++;
1090  }
1091  // End call triggers
1092  }
1093 
1094  if (!$error) {
1095  $this->db->commit();
1096  return 1;
1097  } else {
1098  $this->db->rollback();
1099  return -2;
1100  }
1101  } else {
1102  $this->db->rollback();
1103  $this->error = $this->db->lasterror();
1104  return -1;
1105  }
1106  }
1107 
1116  public function update(User $user, $notrigger = 0)
1117  {
1118  global $langs, $conf, $hookmanager;
1119 
1120  $error = 0;
1121 
1122  // Clean parameters
1123  $this->label = trim($this->label);
1124  $this->note_private = dol_htmlcleanlastbr(trim(!isset($this->note_private) ? $this->note : $this->note_private));
1125  if (empty($this->percentage)) {
1126  $this->percentage = 0;
1127  }
1128  if (empty($this->priority) || !is_numeric($this->priority)) {
1129  $this->priority = 0;
1130  }
1131  if (empty($this->transparency)) {
1132  $this->transparency = 0;
1133  }
1134  if (empty($this->fulldayevent)) {
1135  $this->fulldayevent = 0;
1136  }
1137  if ($this->percentage > 100) {
1138  $this->percentage = 100;
1139  }
1140  //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date;
1141  if ($this->datep && $this->datef) {
1142  $this->durationp = ($this->datef - $this->datep); // deprecated
1143  }
1144  //if ($this->date && $this->dateend) $this->durationa=($this->dateend - $this->date);
1145  if ($this->datep && $this->datef && $this->datep > $this->datef) {
1146  $this->datef = $this->datep;
1147  }
1148  //if ($this->date && $this->dateend && $this->date > $this->dateend) $this->dateend=$this->date;
1149  if ($this->fk_project < 0) {
1150  $this->fk_project = 0;
1151  }
1152 
1153  // Check parameters
1154  if ($this->percentage == 0 && $this->userdoneid > 0) {
1155  $this->error = "ErrorCantSaveADoneUserWithZeroPercentage";
1156  return -1;
1157  }
1158 
1159  $socid = (($this->socid > 0) ? $this->socid : 0);
1160  $contactid = (($this->contact_id > 0) ? $this->contact_id : 0);
1161  $userownerid = ($this->userownerid ? $this->userownerid : 0);
1162  $userdoneid = ($this->userdoneid ? $this->userdoneid : 0);
1163 
1164  // If a type_id is set, we must also have the type_code set
1165  if ($this->type_id > 0) {
1166  if (empty($this->type_code)) {
1167  $cactioncomm = new CActionComm($this->db);
1168  $result = $cactioncomm->fetch($this->type_id);
1169  if ($result >= 0 && !empty($cactioncomm->code)) {
1170  $this->type_code = $cactioncomm->code;
1171  }
1172  }
1173  }
1174 
1175  $code = $this->code;
1176  if (empty($code) || (!empty($this->oldcopy) && $this->oldcopy->type_code != $this->type_code)) { // If code unknown or if we change the type, we reset $code too
1177  $code = $this->type_code;
1178  }
1179 
1180  $this->db->begin();
1181 
1182  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm";
1183  $sql .= " SET percent = '".$this->db->escape($this->percentage)."'";
1184  $sql .= ", fk_action = ".(int) $this->type_id;
1185  $sql .= ", code = " . ($code ? "'".$this->db->escape($code)."'" : "null");
1186  $sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "null");
1187  $sql .= ", datep = ".(strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : 'null');
1188  $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null');
1189  $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated
1190  $sql .= ", note = '".$this->db->escape($this->note_private)."'";
1191  $sql .= ", fk_project =".($this->fk_project > 0 ? ((int) $this->fk_project) : "null");
1192  $sql .= ", fk_soc =".($socid > 0 ? ((int) $socid) : "null");
1193  $sql .= ", fk_contact =".($contactid > 0 ? ((int) $contactid) : "null");
1194  $sql .= ", priority = '".$this->db->escape($this->priority)."'";
1195  $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'";
1196  $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null");
1197  $sql .= ", transparency = '".$this->db->escape($this->transparency)."'";
1198  $sql .= ", fk_user_mod = ".((int) $user->id);
1199  $sql .= ", fk_user_action = ".($userownerid > 0 ? ((int) $userownerid) : "null");
1200  $sql .= ", fk_user_done = ".($userdoneid > 0 ? ((int) $userdoneid) : "null");
1201  if (!empty($this->fk_element)) {
1202  $sql .= ", fk_element=".($this->fk_element ? ((int) $this->fk_element) : "null");
1203  }
1204  if (!empty($this->elementtype)) {
1205  $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null");
1206  }
1207  if (!empty($this->num_vote)) {
1208  $sql .= ", num_vote=".($this->num_vote ? (int) $this->num_vote : null);
1209  }
1210  if (!empty($this->event_paid)) {
1211  $sql .= ", event_paid=".($this->event_paid ? (int) $this->event_paid : 0);
1212  }
1213  if (!empty($this->status)) {
1214  $sql .= ", status=".($this->status ? (int) $this->status : 0);
1215  }
1216  $sql .= " WHERE id=".((int) $this->id);
1217 
1218  dol_syslog(get_class($this)."::update", LOG_DEBUG);
1219  if ($this->db->query($sql)) {
1220  $action = 'update';
1221 
1222  // Actions on extra fields
1223  if (!$error) {
1224  $result = $this->insertExtraFields();
1225  if ($result < 0) {
1226  $error++;
1227  }
1228  }
1229 
1230  // Now insert assignedusers
1231  if (!$error) {
1232  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".((int) $this->id)." AND element_type = 'user'";
1233  $resql = $this->db->query($sql);
1234 
1235  $already_inserted = array();
1236  foreach ($this->userassigned as $key => $val) {
1237  if (!is_array($val)) { // For backward compatibility when val=id
1238  $val = array('id'=>$val);
1239  }
1240  if (!empty($already_inserted[$val['id']])) continue;
1241 
1242  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
1243  $sql .= " VALUES(".((int) $this->id).", 'user', ".((int) $val['id']).", ".(empty($val['mandatory']) ? '0' : ((int) $val['mandatory'])).", ".(empty($val['transparency']) ? '0' : ((int) $val['transparency'])).", ".(empty($val['answer_status']) ? '0' : ((int) $val['answer_status'])).")";
1244 
1245  $resql = $this->db->query($sql);
1246  if (!$resql) {
1247  $error++;
1248  $this->errors[] = $this->db->lasterror();
1249  } else {
1250  $already_inserted[$val['id']] = true;
1251  }
1252  //var_dump($sql);exit;
1253  }
1254  }
1255 
1256  if (!$error) {
1257  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".((int) $this->id)." AND element_type = 'socpeople'";
1258  $resql = $this->db->query($sql);
1259 
1260  if (!empty($this->socpeopleassigned)) {
1261  $already_inserted = array();
1262  foreach (array_keys($this->socpeopleassigned) as $key => $val) {
1263  if (!is_array($val)) { // For backward compatibility when val=id
1264  $val = array('id'=>$val);
1265  }
1266  if (!empty($already_inserted[$val['id']])) continue;
1267 
1268  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
1269  $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $val['id']).", 0, 0, 0)";
1270 
1271  $resql = $this->db->query($sql);
1272  if (!$resql) {
1273  $error++;
1274  $this->errors[] = $this->db->lasterror();
1275  } else {
1276  $already_inserted[$val['id']] = true;
1277  }
1278  }
1279  }
1280  }
1281 
1282  if (!$error && !$notrigger) {
1283  // Call trigger
1284  $result = $this->call_trigger('ACTION_MODIFY', $user);
1285  if ($result < 0) {
1286  $error++;
1287  }
1288  // End call triggers
1289  }
1290 
1291  if (!$error) {
1292  $this->db->commit();
1293  return 1;
1294  } else {
1295  $this->db->rollback();
1296  dol_syslog(get_class($this)."::update ".join(',', $this->errors), LOG_ERR);
1297  return -2;
1298  }
1299  } else {
1300  $this->db->rollback();
1301  $this->error = $this->db->lasterror();
1302  return -1;
1303  }
1304  }
1305 
1319  public function getActions($socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0)
1320  {
1321  global $conf, $langs, $hookmanager;
1322 
1323  $resarray = array();
1324 
1325  dol_syslog(get_class()."::getActions", LOG_DEBUG);
1326 
1327  // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1328  if (!is_object($hookmanager)) {
1329  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1330  $hookmanager = new HookManager($db);
1331  }
1332  $hookmanager->initHooks(array('agendadao'));
1333 
1334  $sql = "SELECT a.id";
1335  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
1336  // Fields from hook
1337  $parameters = array('sql' => &$sql, 'socid' => $socid, 'fk_element' => $fk_element, 'elementtype' => $elementtype);
1338  $reshook = $hookmanager->executeHooks('getActionsListFrom', $parameters); // Note that $action and $object may have been modified by hook
1339  if (!empty($hookmanager->resPrint)) $sql.= $hookmanager->resPrint;
1340  $sql .= " WHERE a.entity IN (".getEntity('agenda').")";
1341  if (!empty($socid)) {
1342  $sql .= " AND a.fk_soc = ".((int) $socid);
1343  }
1344  if (!empty($elementtype)) {
1345  if ($elementtype == 'project') {
1346  $sql .= ' AND a.fk_project = '.((int) $fk_element);
1347  } elseif ($elementtype == 'contact') {
1348  $sql .= ' AND a.id IN';
1349  $sql .= " (SELECT fk_actioncomm FROM ".MAIN_DB_PREFIX."actioncomm_resources WHERE";
1350  $sql .= " element_type = 'socpeople' AND fk_element = ".((int) $fk_element).')';
1351  } else {
1352  $sql .= " AND a.fk_element = ".((int) $fk_element)." AND a.elementtype = '".$this->db->escape($elementtype)."'";
1353  }
1354  }
1355  if (!empty($filter)) {
1356  $sql .= $filter;
1357  }
1358  // Fields where hook
1359  $parameters = array('sql' => &$sql, 'socid' => $socid, 'fk_element' => $fk_element, 'elementtype' => $elementtype);
1360  $reshook = $hookmanager->executeHooks('getActionsListWhere', $parameters); // Note that $action and $object may have been modified by hook
1361  if (!empty($hookmanager->resPrint)) $sql.= $hookmanager->resPrint;
1362  if ($sortorder && $sortfield) {
1363  $sql .= $this->db->order($sortfield, $sortorder);
1364  }
1365  $sql .= $this->db->plimit($limit, 0);
1366 
1367  $resql = $this->db->query($sql);
1368  if ($resql) {
1369  $num = $this->db->num_rows($resql);
1370 
1371  if ($num) {
1372  for ($i = 0; $i < $num; $i++) {
1373  $obj = $this->db->fetch_object($resql);
1374  $actioncommstatic = new ActionComm($this->db);
1375  $actioncommstatic->fetch($obj->id);
1376  $resarray[$i] = $actioncommstatic;
1377  }
1378  }
1379  $this->db->free($resql);
1380  return $resarray;
1381  } else {
1382  return $this->db->lasterror();
1383  }
1384  }
1385 
1386  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1394  public function load_board($user, $load_state_board = 0)
1395  {
1396  // phpcs:enable
1397  global $conf, $langs;
1398 
1399  if (empty($load_state_board)) {
1400  $sql = "SELECT a.id, a.datep as dp";
1401  } else {
1402  $this->nb = array();
1403  $sql = "SELECT count(a.id) as nb";
1404  }
1405  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
1406  if (empty($user->rights->societe->client->voir) && !$user->socid) {
1407  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc";
1408  }
1409  if (!$user->hasRight('agenda', 'allactions', 'read')) {
1410  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."actioncomm_resources AS ar ON a.id = ar.fk_actioncomm AND ar.element_type ='user' AND ar.fk_element = ".((int) $user->id);
1411  }
1412  $sql .= " WHERE 1 = 1";
1413  if (empty($load_state_board)) {
1414  $sql .= " AND a.percent >= 0 AND a.percent < 100";
1415  }
1416  $sql .= " AND a.entity IN (".getEntity('agenda').")";
1417  if (empty($user->rights->societe->client->voir) && !$user->socid) {
1418  $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")";
1419  }
1420  if ($user->socid) {
1421  $sql .= " AND a.fk_soc = ".((int) $user->socid);
1422  }
1423  if (!$user->hasRight('agenda', 'allactions', 'read')) {
1424  $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id)." OR a.fk_user_done = ".((int) $user->id);
1425  $sql .= " OR ar.fk_element = ".((int) $user->id);
1426  $sql .= ")";
1427  }
1428 
1429  $resql = $this->db->query($sql);
1430  if ($resql) {
1431  if (empty($load_state_board)) {
1432  $agenda_static = new ActionComm($this->db);
1433  $response = new WorkboardResponse();
1434  $response->warning_delay = $conf->agenda->warning_delay / 60 / 60 / 24;
1435  $response->label = $langs->trans("ActionsToDo");
1436  $response->labelShort = $langs->trans("ActionsToDoShort");
1437  $response->url = DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&actioncode=0&status=todo&mainmenu=agenda';
1438  if ($user->hasRight("agenda", "allactions", "read")) {
1439  $response->url .= '&filtert=-1';
1440  }
1441  $response->img = img_object('', "action", 'class="inline-block valigntextmiddle"');
1442  }
1443  // This assignment in condition is not a bug. It allows walking the results.
1444  while ($obj = $this->db->fetch_object($resql)) {
1445  if (empty($load_state_board)) {
1446  $response->nbtodo++;
1447  $agenda_static->datep = $this->db->jdate($obj->dp);
1448  if ($agenda_static->hasDelay()) {
1449  $response->nbtodolate++;
1450  }
1451  } else {
1452  $this->nb["actionscomm"] = $obj->nb;
1453  }
1454  }
1455 
1456  $this->db->free($resql);
1457  if (empty($load_state_board)) {
1458  return $response;
1459  } else {
1460  return 1;
1461  }
1462  } else {
1463  dol_print_error($this->db);
1464  $this->error = $this->db->error();
1465  return -1;
1466  }
1467  }
1468 
1469 
1476  public function info($id)
1477  {
1478  $sql = 'SELECT ';
1479  $sql .= ' a.id,';
1480  $sql .= ' datec,';
1481  $sql .= ' tms as datem,';
1482  $sql .= ' fk_user_author,';
1483  $sql .= ' fk_user_mod';
1484  $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a';
1485  $sql .= ' WHERE a.id = '.((int) $id);
1486 
1487  dol_syslog(get_class($this)."::info", LOG_DEBUG);
1488  $result = $this->db->query($sql);
1489  if ($result) {
1490  if ($this->db->num_rows($result)) {
1491  $obj = $this->db->fetch_object($result);
1492  $this->id = $obj->id;
1493  $this->user_creation_id = $obj->fk_user_author;
1494  $this->user_modification_id = $obj->fk_user_mod;
1495  $this->date_creation = $this->db->jdate($obj->datec);
1496  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1497  }
1498  $this->db->free($result);
1499  } else {
1500  dol_print_error($this->db);
1501  }
1502  }
1503 
1504 
1512  public function getLibStatut($mode, $hidenastatus = 0)
1513  {
1514  return $this->LibStatut($this->percentage, $mode, $hidenastatus, $this->datep);
1515  }
1516 
1517  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1527  public function LibStatut($percent, $mode, $hidenastatus = 0, $datestart = '')
1528  {
1529  // phpcs:enable
1530  global $langs;
1531 
1532  $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable');
1533  if ($percent == -1 && !$hidenastatus) {
1534  $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable');
1535  } elseif ($percent == 0) {
1536  $labelStatus = $langs->transnoentitiesnoconv('StatusActionToDo').' (0%)';
1537  } elseif ($percent > 0 && $percent < 100) {
1538  $labelStatus = $langs->transnoentitiesnoconv('StatusActionInProcess').' ('.$percent.'%)';
1539  } elseif ($percent >= 100) {
1540  $labelStatus = $langs->transnoentitiesnoconv('StatusActionDone').' (100%)';
1541  }
1542 
1543  $labelStatusShort = $langs->transnoentitiesnoconv('StatusNotApplicable');
1544  if ($percent == -1 && !$hidenastatus) {
1545  $labelStatusShort = $langs->trans('NA');
1546  } elseif ($percent == 0) {
1547  $labelStatusShort = '0%';
1548  } elseif ($percent > 0 && $percent < 100) {
1549  $labelStatusShort = $percent.'%';
1550  } elseif ($percent >= 100) {
1551  $labelStatusShort = '100%';
1552  }
1553 
1554  $statusType = 'status9';
1555  if ($percent == -1 && !$hidenastatus) {
1556  $statusType = 'status9';
1557  }
1558  if ($percent == 0) {
1559  $statusType = 'status1';
1560  }
1561  if ($percent > 0 && $percent < 100) {
1562  $statusType = 'status3';
1563  }
1564  if ($percent >= 100) {
1565  $statusType = 'status6';
1566  }
1567 
1568  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1569  }
1570 
1577  public function getTooltipContentArray($params)
1578  {
1579  global $conf, $langs, $user;
1580  $langs->load('agenda');
1581 
1582  $datas = array();
1583  $nofetch = !empty($params['nofetch']);
1584 
1585  // Set label of type
1586  $labeltype = '';
1587  if ($this->type_code) {
1588  $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label;
1589  }
1590  if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
1591  if ($this->type_code != 'AC_OTH_AUTO') {
1592  $labeltype = $langs->trans('ActionAC_MANUAL');
1593  }
1594  }
1595 
1596  $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans('Action').'</u>';
1597  if (!empty($this->ref)) {
1598  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
1599  }
1600  if (!empty($this->label)) {
1601  $datas['title'] = '<br><b>'.$langs->trans('Title').':</b> '.dol_escape_htmltag($this->label);
1602  }
1603  if (!empty($labeltype)) {
1604  $datas['labeltype'] = '<br><b>'.$langs->trans('Type').':</b> '.dol_escape_htmltag($labeltype);
1605  }
1606  if (!empty($this->location)) {
1607  $datas['location'] = '<br><b>'.$langs->trans('Location').':</b> '.dol_escape_htmltag($this->location);
1608  }
1609  if (isset($this->transparency)) {
1610  $datas['transparency'] = '<br><b>'.$langs->trans('Busy').':</b> '.yn($this->transparency);
1611  }
1612  if (!empty($this->email_msgid)) {
1613  $langs->load("mails");
1614  $datas['space'] = '<br>';
1615  // $datas['email'] = '<br><b>'.img_picto('', 'email').' '.$langs->trans("Email").'</b>';
1616  $datas['mailtopic'] = '<br><b>'.$langs->trans('MailTopic').':</b> '.dol_escape_htmltag($this->email_subject);
1617  $datas['mailfrom'] = '<br><b>'.$langs->trans('MailFrom').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_from);
1618  $datas['mailto'] = '<br><b>'.$langs->trans('MailTo').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_to);
1619  if (!empty($this->email_tocc)) {
1620  $datas['mailcc'] = '<br><b>'.$langs->trans('MailCC').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_tocc);
1621  }
1622  /* Disabled because bcc must remain by defintion not visible
1623  if (!empty($this->email_tobcc)) {
1624  $datas['mailccc'] = '<br><b>'.$langs->trans('MailCCC').':</b> '.$this->email_tobcc;
1625  } */
1626  }
1627  if (!empty($this->note_private)) {
1628  $datas['description'] = '<br><b>'.$langs->trans('Description').':</b><br>';
1629  // Try to limit length of content
1630  $texttoshow = dolGetFirstLineOfText($this->note_private, 10);
1631  // Restrict height of content into the tooltip
1632  $datas['note'] = '<div class="tenlinesmax">';
1633  $datas['note'] .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
1634  $datas['note'] .= '</div>';
1635  }
1636  // show categories for this record only in ajax to not overload lists
1637  if (isModEnabled('categorie') && !$nofetch) {
1638  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1639  $form = new Form($this->db);
1640  $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACTIONCOMM, 1);
1641  }
1642 
1643  return $datas;
1644  }
1645 
1659  public function getNomUrl($withpicto = 0, $maxlength = 0, $classname = '', $option = '', $overwritepicto = 0, $notooltip = 0, $save_lastsearch_value = -1)
1660  {
1661  global $conf, $langs, $user, $hookmanager, $action;
1662 
1663  if (!empty($conf->dol_no_mouse_hover)) {
1664  $notooltip = 1; // Force disable tooltips
1665  }
1666 
1667  $canread = 0;
1668  if ($user->hasRight('agenda', 'myactions', 'read') && ($this->authorid == $user->id || $this->userownerid == $user->id)) {
1669  $canread = 1; // Can read my event
1670  }
1671  if ($user->hasRight('agenda', 'myactions', 'read') && array_key_exists($user->id, $this->userassigned)) {
1672  $canread = 1; // Can read my event i am assigned
1673  }
1674  if ($user->hasRight('agenda', 'allactions', 'read')) {
1675  $canread = 1; // Can read all event of other
1676  }
1677  if (!$canread) {
1678  $option = 'nolink';
1679  }
1680 
1681  $label = $this->label;
1682  if (empty($label)) {
1683  $label = $this->libelle; // For backward compatibility
1684  }
1685 
1686  $result = '';
1687 
1688  // Set label of type
1689  $labeltype = '';
1690  if ($this->type_code) {
1691  $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label;
1692  }
1693  if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
1694  if ($this->type_code != 'AC_OTH_AUTO') {
1695  $labeltype = $langs->trans('ActionAC_MANUAL');
1696  }
1697  }
1698 
1699  $tooltip = img_picto('', $this->picto).' <u>'.$langs->trans('Action').'</u>';
1700  if (!empty($this->ref)) {
1701  $tooltip .= '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
1702  }
1703  if (!empty($label)) {
1704  $tooltip .= '<br><b>'.$langs->trans('Title').':</b> '.dol_escape_htmltag($label);
1705  }
1706  if (!empty($labeltype)) {
1707  $tooltip .= '<br><b>'.$langs->trans('Type').':</b> '.dol_escape_htmltag($labeltype);
1708  }
1709  if (!empty($this->location)) {
1710  $tooltip .= '<br><b>'.$langs->trans('Location').':</b> '.dol_escape_htmltag($this->location);
1711  }
1712  if (isset($this->transparency)) {
1713  $tooltip .= '<br><b>'.$langs->trans('Busy').':</b> '.yn($this->transparency);
1714  }
1715  if (!empty($this->email_msgid)) {
1716  $langs->load("mails");
1717  $tooltip .= '<br>';
1718  //$tooltip .= '<br><b>'.img_picto('', 'email').' '.$langs->trans("Email").'</b>';
1719  $tooltip .= '<br><b>'.$langs->trans('MailTopic').':</b> '.dol_escape_htmltag($this->email_subject);
1720  $tooltip .= '<br><b>'.$langs->trans('MailFrom').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), !empty($this->email_from) ? $this->email_from : '');
1721  $tooltip .= '<br><b>'.$langs->trans('MailTo').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), !empty($this->email_to) ? $this->email_to : '');
1722  if (!empty($this->email_tocc)) {
1723  $tooltip .= '<br><b>'.$langs->trans('MailCC').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_tocc);
1724  }
1725  /* Disabled because bcc must remain by defintion not visible
1726  if (!empty($this->email_tobcc)) {
1727  $tooltip .= '<br><b>'.$langs->trans('MailCCC').':</b> '.$this->email_tobcc;
1728  } */
1729  }
1730  if (!empty($this->note_private)) {
1731  $tooltip .= '<br><br><b>'.$langs->trans('Description').':</b><br>';
1732  $texttoshow = dolGetFirstLineOfText($this->note_private, 8); // Try to limit length of content
1733  $tooltip .= '<div class="tenlinesmax">'; // Restrict height of content into the tooltip
1734  $tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
1735  $tooltip .= '</div>';
1736  }
1737  $linkclose = '';
1738  $classfortooltip = 'classfortooltip';
1739  $dataparams = '';
1740  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1741  $params = [
1742  'id' => $this->id,
1743  'objecttype' => $this->element,
1744  'option' => $option,
1745  'nofetch' => 1,
1746  ];
1747  $classfortooltip = 'classforajaxtooltip';
1748  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1749  $tooltip = '';
1750  }
1751  //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color)
1752  // $linkclose = ' style="background-color:#'.$this->type_color.'"';
1753  if (empty($notooltip)) {
1754  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1755  $label = $langs->trans("ShowAction");
1756  $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"';
1757  }
1758  $linkclose .= ($tooltip ? ' title="'.dol_escape_htmltag($tooltip, 1).'"' : ' title="tocomplete"');
1759  $linkclose .= $dataparams.' class="'.$classname.' '.$classfortooltip.'"';
1760  } else {
1761  $linkclose .= ' class="'.$classname.'"';
1762  }
1763 
1764  $url = '';
1765  if ($option == 'birthday') {
1766  $url = DOL_URL_ROOT.'/contact/perso.php?id='.$this->id;
1767  } elseif ($option == 'holiday') {
1768  $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1769  } else {
1770  $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id;
1771  }
1772 
1773  if ($option !== 'nolink') {
1774  // Add param to save lastsearch_values or not
1775  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1776  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1777  $add_save_lastsearch_values = 1;
1778  }
1779  if ($add_save_lastsearch_values) {
1780  $url .= '&save_lastsearch_values=1';
1781  }
1782  }
1783 
1784  $linkstart = '<a href="'.$url.'"';
1785  $linkstart .= $linkclose.'>';
1786  $linkend = '</a>';
1787 
1788  if ($option == 'nolink') {
1789  $linkstart = '';
1790  $linkend = '';
1791  }
1792 
1793  if ($withpicto == 2) {
1794  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
1795  $label = $labeltype;
1796  }
1797  $labelshort = '';
1798  } else {
1799  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($label)) {
1800  $label = $labeltype;
1801  }
1802  if ($maxlength < 0) {
1803  $labelshort = $this->ref;
1804  } else {
1805  $labelshort = dol_trunc($label, $maxlength);
1806  }
1807  }
1808 
1809  if ($withpicto) {
1810  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { // Add code into ()
1811  if ($labeltype) {
1812  $label .= (preg_match('/'.preg_quote($labeltype, '/').'/', $label) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')');
1813  }
1814  }
1815  }
1816 
1817  $result .= $linkstart;
1818  if ($withpicto) {
1819  $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$label), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : ' class="'.(($withpicto != 2) ? 'paddingright ' : '').'"'), 0, 0, $notooltip ? 0 : 1);
1820  }
1821  $result .= dol_escape_htmltag($labelshort);
1822  $result .= $linkend;
1823 
1824  global $action;
1825  $hookmanager->initHooks(array('actiondao'));
1826  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1827  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1828  if ($reshook > 0) {
1829  $result = $hookmanager->resPrint;
1830  } else {
1831  $result .= $hookmanager->resPrint;
1832  }
1833 
1834  return $result;
1835  }
1836 
1842  public function getTypePicto()
1843  {
1844  global $conf;
1845 
1846  $imgpicto = '';
1847  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
1848  $color = '';
1849  if ($this->type_color) {
1850  $color = 'style="color: #'.$this->type_color.' !important;"';
1851  }
1852  if ($this->type_picto) {
1853  $imgpicto = img_picto('', $this->type_picto, 'class="paddingright"');
1854  } else {
1855  if ($this->type_code == 'AC_RDV') {
1856  $imgpicto = img_picto('', 'meeting', $color, false, 0, 0, '', 'paddingright');
1857  } elseif ($this->type_code == 'AC_TEL') {
1858  $imgpicto = img_picto('', 'object_phoning', $color, false, 0, 0, '', 'paddingright');
1859  } elseif ($this->type_code == 'AC_FAX') {
1860  $imgpicto = img_picto('', 'object_phoning_fax', $color, false, 0, 0, '', 'paddingright');
1861  } elseif ($this->type_code == 'AC_EMAIL' || $this->type_code == 'AC_EMAIL_IN' || (!empty($this->code) && preg_match('/_SENTBYMAIL/', $this->code))) {
1862  $imgpicto = img_picto('', 'object_email', $color, false, 0, 0, '', 'paddingright');
1863  } elseif ($this->type_code == 'AC_INT') {
1864  $imgpicto = img_picto('', 'object_intervention', $color, false, 0, 0, '', 'paddingright');
1865  } elseif (!empty($this->code) && preg_match('/^TICKET_MSG/', $this->code)) {
1866  $imgpicto = img_picto('', 'object_conversation', $color, false, 0, 0, '', 'paddingright');
1867  } elseif ($this->type != 'systemauto') {
1868  $imgpicto = img_picto('', 'user-cog', $color, false, 0, 0, '', 'paddingright');
1869  } else {
1870  $imgpicto = img_picto('', 'cog', $color, false, 0, 0, '', 'paddingright');
1871  }
1872  }
1873  } else {
1874  // 2 picto: 1 for auto, 1 for manual
1875  if ($this->type != 'systemauto') {
1876  $imgpicto = img_picto('', 'user-cog', '', false, 0, 0, '', 'paddingright');
1877  } else {
1878  $imgpicto = img_picto('', 'cog', '', false, 0, 0, '', 'paddingright');
1879  }
1880  }
1881  return $imgpicto;
1882  }
1883 
1884 
1895  public function setCategories($categories)
1896  {
1897  // Handle single category
1898  if (!is_array($categories)) {
1899  $categories = array($categories);
1900  }
1901 
1902  // Get current categories
1903  include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1904  $c = new Categorie($this->db);
1905  $existing = $c->containing($this->id, Categorie::TYPE_ACTIONCOMM, 'id');
1906 
1907  // Diff
1908  if (is_array($existing)) {
1909  $to_del = array_diff($existing, $categories);
1910  $to_add = array_diff($categories, $existing);
1911  } else {
1912  $to_del = array(); // Nothing to delete
1913  $to_add = $categories;
1914  }
1915 
1916  // Process
1917  foreach ($to_del as $del) {
1918  if ($c->fetch($del) > 0) {
1919  $c->del_type($this, Categorie::TYPE_ACTIONCOMM);
1920  }
1921  }
1922  foreach ($to_add as $add) {
1923  if ($c->fetch($add) > 0) {
1924  $c->add_type($this, Categorie::TYPE_ACTIONCOMM);
1925  }
1926  }
1927  return 1;
1928  }
1929 
1930  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1942  public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0)
1943  {
1944  global $hookmanager;
1945 
1946  // phpcs:enable
1947  global $conf, $langs, $dolibarr_main_url_root, $mysoc;
1948 
1949  require_once DOL_DOCUMENT_ROOT."/core/lib/xcal.lib.php";
1950  require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
1951  require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
1952 
1953  dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG);
1954 
1955  // Check parameters
1956  if (empty($format)) {
1957  return -1;
1958  }
1959 
1960  // Clean parameters
1961  if (!$filename) {
1962  $extension = 'vcs';
1963  if ($format == 'ical') {
1964  $extension = 'ics';
1965  }
1966  $filename = $format.'.'.$extension;
1967  }
1968 
1969  // Create dir and define output file (definitive and temporary)
1970  $result = dol_mkdir($conf->agenda->dir_temp);
1971  $outputfile = $conf->agenda->dir_temp.'/'.$filename;
1972 
1973  $result = 0;
1974 
1975  $buildfile = true;
1976  $login = ''; $logina = ''; $logind = ''; $logint = '';
1977 
1978  $now = dol_now();
1979 
1980  if ($cachedelay) {
1981  $nowgmt = dol_now();
1982  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1983  if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay)) {
1984  dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled");
1985  $buildfile = false;
1986  }
1987  }
1988 
1989  if ($buildfile) {
1990  // Build event array
1991  $eventarray = array();
1992 
1993  $sql = "SELECT a.id,";
1994  $sql .= " a.datep,"; // Start
1995  $sql .= " a.datep2,"; // End
1996  $sql .= " a.durationp,"; // deprecated
1997  $sql .= " a.datec, a.tms as datem,";
1998  $sql .= " a.label, a.code, a.note as note_private, a.fk_action as type_id,";
1999  $sql .= " a.fk_soc,";
2000  $sql .= " a.fk_user_author, a.fk_user_mod,";
2001  $sql .= " a.fk_user_action,";
2002  $sql .= " a.fk_contact, a.percent as percentage,";
2003  $sql .= " a.fk_element, a.elementtype,";
2004  $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
2005  $sql .= " u.firstname, u.lastname, u.email,";
2006  $sql .= " s.nom as socname,";
2007  $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label,";
2008  $sql .= " num_vote, event_paid, a.status";
2009  $sql .= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)";
2010  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export
2011  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
2012 
2013  $parameters = array('filters' => $filters);
2014  $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
2015  $sql .= $hookmanager->resPrint;
2016 
2017  // We must filter on assignement table
2018  if ($filters['logint']) {
2019  $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar";
2020  }
2021  $sql .= " WHERE a.fk_action=c.id";
2022  $sql .= " AND a.entity IN (".getEntity('agenda').")";
2023  foreach ($filters as $key => $value) {
2024  if ($key == 'notolderthan' && $value != '') {
2025  $sql .= " AND a.datep >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'";
2026  }
2027  if ($key == 'year') {
2028  $sql .= " AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'";
2029  }
2030  if ($key == 'id') {
2031  $sql .= " AND a.id=".(is_numeric($value) ? $value : 0);
2032  }
2033  if ($key == 'idfrom') {
2034  $sql .= " AND a.id >= ".(is_numeric($value) ? $value : 0);
2035  }
2036  if ($key == 'idto') {
2037  $sql .= " AND a.id <= ".(is_numeric($value) ? $value : 0);
2038  }
2039  if ($key == 'project') {
2040  $sql .= " AND a.fk_project=".(is_numeric($value) ? $value : 0);
2041  }
2042  if ($key == 'actiontype') {
2043  $sql .= " AND c.type = '".$this->db->escape($value)."'";
2044  }
2045  if ($key == 'notactiontype') {
2046  $sql .= " AND c.type <> '".$this->db->escape($value)."'";
2047  }
2048  // We must filter on assignement table
2049  if ($key == 'logint') {
2050  $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
2051  }
2052  if ($key == 'logina') {
2053  $logina = $value;
2054  $condition = '=';
2055  if (preg_match('/^!/', $logina)) {
2056  $logina = preg_replace('/^!/', '', $logina);
2057  $condition = '<>';
2058  }
2059  $userforfilter = new User($this->db);
2060  $result = $userforfilter->fetch('', $logina);
2061  if ($result > 0) {
2062  $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id;
2063  } elseif ($result < 0 || $condition == '=') {
2064  $sql .= " AND a.fk_user_author = 0";
2065  }
2066  }
2067  if ($key == 'logint') {
2068  $logint = $value;
2069  $condition = '=';
2070  if (preg_match('/^!/', $logint)) {
2071  $logint = preg_replace('/^!/', '', $logint);
2072  $condition = '<>';
2073  }
2074  $userforfilter = new User($this->db);
2075  $result = $userforfilter->fetch('', $logint);
2076  if ($result > 0) {
2077  $sql .= " AND ar.fk_element = ".((int) $userforfilter->id);
2078  } elseif ($result < 0 || $condition == '=') {
2079  $sql .= " AND ar.fk_element = 0";
2080  }
2081  }
2082  if ($key == 'module') {
2083  $sql .= " AND c.module LIKE '%".$this->db->escape($value)."'";
2084  }
2085  if ($key == 'status') {
2086  $sql .= " AND a.status =".((int) $value);
2087  }
2088  }
2089 
2090  $sql .= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import
2091 
2092  $parameters = array('filters' => $filters);
2093  $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
2094  $sql .= $hookmanager->resPrint;
2095 
2096  $sql .= " ORDER by datep";
2097  //print $sql;exit;
2098 
2099  dol_syslog(get_class($this)."::build_exportfile select events", LOG_DEBUG);
2100  $resql = $this->db->query($sql);
2101  if ($resql) {
2102  $diff = 0;
2103  while ($obj = $this->db->fetch_object($resql)) {
2104  $qualified = true;
2105 
2106  // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author'
2107  $event = array();
2108  $event['uid'] = 'dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"];
2109  $event['type'] = $type;
2110 
2111  $datestart = $this->db->jdate($obj->datep) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2112 
2113  // fix for -> Warning: A non-numeric value encountered
2114  if (is_numeric($this->db->jdate($obj->datep2))) {
2115  $dateend = $this->db->jdate($obj->datep2) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2116  } else {
2117  // use start date as fall-back to avoid pb with empty end date on ICS readers
2118  $dateend = $datestart;
2119  }
2120 
2121  $duration = ($datestart && $dateend) ? ($dateend - $datestart) : 0;
2122  $event['summary'] = $obj->label.($obj->socname ? " (".$obj->socname.")" : "");
2123 
2124  $event['desc'] = $obj->note_private;
2125  $event['startdate'] = $datestart;
2126  $event['enddate'] = $dateend; // Not required with type 'journal'
2127  $event['duration'] = $duration; // Not required with type 'journal'
2128  $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2129  $event['priority'] = $obj->priority;
2130  $event['fulldayevent'] = $obj->fulldayevent;
2131  $event['location'] = $obj->location;
2132  $event['transparency'] = (($obj->transparency > 0) ? 'OPAQUE' : 'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy)
2133  $event['category'] = $obj->type_label;
2134  $event['email'] = $obj->email;
2135  // Define $urlwithroot
2136  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2137  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
2138  //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
2139  $url = $urlwithroot.'/comm/action/card.php?id='.$obj->id;
2140  $event['url'] = $url;
2141  $event['created'] = $this->db->jdate($obj->datec) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2142  $event['modified'] = $this->db->jdate($obj->datem) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2143  $event['num_vote'] = $this->num_vote;
2144  $event['event_paid'] = $this->event_paid;
2145  $event['status'] = $this->status;
2146 
2147  // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties
2148  $this->id = $obj->id;
2149  $this->fetch_userassigned(false);
2150 
2151  $assignedUserArray = array();
2152 
2153  foreach ($this->userassigned as $key => $value) {
2154  $assignedUser = new User($this->db);
2155  $assignedUser->fetch($value['id']);
2156 
2157  $assignedUserArray[$key] = $assignedUser;
2158  }
2159 
2160  $event['assignedUsers'] = $assignedUserArray;
2161 
2162  if ($qualified && $datestart) {
2163  $eventarray[] = $event;
2164  }
2165  $diff++;
2166  }
2167 
2168  $parameters = array('filters' => $filters, 'eventarray' => &$eventarray);
2169  $reshook = $hookmanager->executeHooks('addMoreEventsExport', $parameters); // Note that $action and $object may have been modified by hook
2170  if ($reshook > 0) {
2171  $eventarray = $hookmanager->resArray;
2172  }
2173  } else {
2174  $this->error = $this->db->lasterror();
2175  return -1;
2176  }
2177 
2178  if ($exportholiday == 1) {
2179  $langs->load("holiday");
2180  $title = $langs->transnoentities("Holidays");
2181 
2182  $sql = "SELECT u.rowid as uid, u.lastname, u.firstname, u.email, u.statut, x.rowid, x.date_debut as date_start, x.date_fin as date_end, x.halfday, x.statut as status";
2183  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u";
2184  $sql .= " WHERE u.rowid = x.fk_user";
2185  $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user)
2186  $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved)
2187 
2188  $resql = $this->db->query($sql);
2189  if ($resql) {
2190  $num = $this->db->num_rows($resql);
2191  $i = 0;
2192 
2193  while ($i < $num) {
2194  $obj = $this->db->fetch_object($resql);
2195  $event = array();
2196 
2197  if ($obj->halfday == 1) {
2198  $event['fulldayevent'] = false;
2199 
2200  $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2201  $timestampEnd = dol_stringtotime($obj->date_end." 12:00:00", 0);
2202  } elseif ($obj->halfday == -1) {
2203  $event['fulldayevent'] = false;
2204 
2205  $timestampStart = dol_stringtotime($obj->date_start." 12:00:00", 0);
2206  $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2207  } else {
2208  $event['fulldayevent'] = true;
2209 
2210  $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2211  $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2212  }
2213 
2214  if (!empty($conf->global->AGENDA_EXPORT_FIX_TZ)) {
2215  $timestampStart = $timestampStart - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2216  $timestampEnd = $timestampEnd - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2217  }
2218 
2219  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2220  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
2221  $url = $urlwithroot.'/holiday/card.php?id='.$obj->rowid;
2222 
2223  $event['uid'] = 'dolibarrholiday-'.$this->db->database_name.'-'.$obj->rowid."@".$_SERVER["SERVER_NAME"];
2224  $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2225  $event['type'] = 'event';
2226  $event['category'] = "Holiday";
2227  $event['transparency'] = 'OPAQUE';
2228  $event['email'] = $obj->email;
2229  $event['created'] = $timestampStart;
2230  $event['modified'] = $timestampStart;
2231  $event['startdate'] = $timestampStart;
2232  $event['enddate'] = $timestampEnd;
2233  $event['duration'] = $timestampEnd - $timestampStart;
2234  $event['url'] = $url;
2235 
2236  if ($obj->status == 2) {
2237  // 2 = leave wait for approval
2238  $event['summary'] = $title." - ".$obj->lastname." (wait for approval)";
2239  } else {
2240  // 3 = leave approved
2241  $event['summary'] = $title." - ".$obj->lastname;
2242  }
2243 
2244  $eventarray[] = $event;
2245 
2246  $i++;
2247  }
2248  }
2249  }
2250 
2251  $langs->load("agenda");
2252 
2253  // Define title and desc
2254  $more = '';
2255  if ($login) {
2256  $more = $langs->transnoentities("User").' '.$login;
2257  }
2258  if ($logina) {
2259  $more = $langs->transnoentities("ActionsAskedBy").' '.$logina;
2260  }
2261  if ($logint) {
2262  $more = $langs->transnoentities("ActionsToDoBy").' '.$logint;
2263  }
2264  if ($logind) {
2265  $more = $langs->transnoentities("ActionsDoneBy").' '.$logind;
2266  }
2267  if ($more) {
2268  $title = 'Dolibarr actions '.$mysoc->name.' - '.$more;
2269  $desc = $more;
2270  $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2271  } else {
2272  $title = 'Dolibarr actions '.$mysoc->name;
2273  $desc = $langs->transnoentities('ListOfActions');
2274  $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2275  }
2276 
2277  // Create temp file
2278  $outputfiletmp = tempnam($conf->agenda->dir_temp, 'tmp'); // Temporary file (allow call of function by different threads
2279  dolChmod($outputfiletmp);
2280 
2281  // Write file
2282  if ($format == 'vcal') {
2283  $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2284  } elseif ($format == 'ical') {
2285  $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2286  } elseif ($format == 'rss') {
2287  $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp);
2288  }
2289 
2290  if ($result >= 0) {
2291  if (dol_move($outputfiletmp, $outputfile, 0, 1, 0, 0)) {
2292  $result = 1;
2293  } else {
2294  $this->error = 'Failed to rename '.$outputfiletmp.' into '.$outputfile;
2295  dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR);
2296  dol_delete_file($outputfiletmp, 0, 1);
2297  $result = -1;
2298  }
2299  } else {
2300  dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR);
2301  dol_delete_file($outputfiletmp, 0, 1);
2302  $langs->load("errors");
2303  $this->error = $langs->trans("ErrorFailToCreateFile", $outputfile);
2304  }
2305  }
2306 
2307  return $result;
2308  }
2309 
2317  public function initAsSpecimen()
2318  {
2319  global $user;
2320 
2321  $now = dol_now();
2322 
2323  // Initialise parametres
2324  $this->id = 0;
2325  $this->specimen = 1;
2326 
2327  $this->type_code = 'AC_OTH';
2328  $this->code = 'AC_SPECIMEN_CODE';
2329  $this->label = 'Label of event Specimen';
2330  $this->datec = $now;
2331  $this->datem = $now;
2332  $this->datep = $now;
2333  $this->datef = $now;
2334  $this->fulldayevent = 0;
2335  $this->percentage = 0;
2336  $this->status = 0;
2337  $this->location = 'Location';
2338  $this->transparency = 1; // 1 means opaque
2339  $this->priority = 1;
2340  //$this->note_public = "This is a 'public' note.";
2341  $this->note_private = "This is a 'private' note.";
2342 
2343  $this->userownerid = $user->id;
2344  $this->userassigned[$user->id] = array('id'=>$user->id, 'transparency'=> 1);
2345  return 1;
2346  }
2347 
2356  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2357  {
2358  $tables = array(
2359  'actioncomm'
2360  );
2361 
2362  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
2363  }
2364 
2373  public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id)
2374  {
2375  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id);
2376  // using $dbs, not $this->db because function is static
2377  if (!$dbs->query($sql)) {
2378  //$this->errors = $dbs->lasterror();
2379  return false;
2380  }
2381 
2382  return true;
2383  }
2384 
2390  public function hasDelay()
2391  {
2392  global $conf;
2393 
2394  $now = dol_now();
2395 
2396  return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay));
2397  }
2398 
2399 
2408  public function loadReminders($type = '', $fk_user = 0, $onlypast = true)
2409  {
2410  global $conf, $langs, $user;
2411 
2412  $error = 0;
2413 
2414  $this->reminders = array();
2415 
2416  //Select all action comm reminders for event
2417  $sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user, fk_email_template, lasterror";
2418  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2419  $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
2420  if ($onlypast) {
2421  $sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'";
2422  }
2423  if ($type) {
2424  $sql .= " AND typeremind = '".$this->db->escape($type)."'";
2425  }
2426  if ($fk_user > 0) {
2427  $sql .= " AND fk_user = ".((int) $fk_user);
2428  }
2429  if (empty($conf->global->AGENDA_REMINDER_EMAIL)) {
2430  $sql .= " AND typeremind <> 'email'";
2431  }
2432  if (empty($conf->global->AGENDA_REMINDER_BROWSER)) {
2433  $sql .= " AND typeremind <> 'browser'";
2434  }
2435 
2436  $sql .= $this->db->order("dateremind", "ASC");
2437  $resql = $this->db->query($sql);
2438 
2439  if ($resql) {
2440  while ($obj = $this->db->fetch_object($resql)) {
2441  $tmpactioncommreminder = new ActionCommReminder($this->db);
2442  $tmpactioncommreminder->id = $obj->id;
2443  $tmpactioncommreminder->typeremind = $obj->typeremind;
2444  $tmpactioncommreminder->dateremind = $obj->dateremind;
2445  $tmpactioncommreminder->offsetvalue = $obj->offsetvalue;
2446  $tmpactioncommreminder->offsetunit = $obj->offsetunit;
2447  $tmpactioncommreminder->status = $obj->status;
2448  $tmpactioncommreminder->fk_user = $obj->fk_user;
2449  $tmpactioncommreminder->fk_email_template = $obj->fk_email_template;
2450  $tmpactioncommreminder->lasterror = $obj->lasterror;
2451 
2452  $this->reminders[$obj->id] = $tmpactioncommreminder;
2453  }
2454  } else {
2455  $this->error = $this->db->lasterror();
2456  $error++;
2457  }
2458 
2459  return count($this->reminders);
2460  }
2461 
2462 
2469  public function sendEmailsReminder()
2470  {
2471  global $conf, $langs, $user;
2472 
2473  $error = 0;
2474  $this->output = '';
2475  $this->error = '';
2476  $nbMailSend = 0;
2477  $errorsMsg = array();
2478 
2479  if (!isModEnabled('agenda')) { // Should not happen. If module disabled, cron job should not be visible.
2480  $langs->load("agenda");
2481  $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2482  return 0;
2483  }
2484  if (empty($conf->global->AGENDA_REMINDER_EMAIL)) {
2485  $langs->load("agenda");
2486  $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2487  return 0;
2488  }
2489 
2490  $now = dol_now();
2491  $actionCommReminder = new ActionCommReminder($this->db);
2492 
2493  dol_syslog(__METHOD__." start", LOG_INFO);
2494 
2495  $this->db->begin();
2496 
2497  //Select all action comm reminders
2498  $sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2499  $sql .= " WHERE typeremind = 'email'";
2500  $sql .= " AND status = 0"; // 0=No yet sent, -1=Error. TODO Include reminder in error once we can count number of error, so we can try 5 times and not more on errors.
2501  $sql .= " AND dateremind <= '".$this->db->idate($now)."'";
2502  $sql .= " AND entity IN (".getEntity('actioncomm').")";
2503  $sql .= $this->db->order("dateremind", "ASC");
2504  $resql = $this->db->query($sql);
2505 
2506  if ($resql) {
2507  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2508  $formmail = new FormMail($this->db);
2509 
2510  while ($obj = $this->db->fetch_object($resql)) {
2511  $res = $actionCommReminder->fetch($obj->id);
2512  if ($res < 0) {
2513  $error++;
2514  $errorsMsg[] = "Failed to load invoice ActionComm Reminder";
2515  }
2516 
2517  if (!$error) {
2518  //Select email template
2519  $arraymessage = $formmail->getEMailTemplate($this->db, 'actioncomm_send', $user, $langs, (!empty($actionCommReminder->fk_email_template)) ? $actionCommReminder->fk_email_template : -1, 1);
2520 
2521  // Load event
2522  $res = $this->fetch($actionCommReminder->fk_actioncomm);
2523  if ($res > 0) {
2524  // PREPARE EMAIL
2525  $errormesg = '';
2526 
2527  // Make substitution in email content
2528  $substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this);
2529 
2530  complete_substitutions_array($substitutionarray, $langs, $this);
2531 
2532  // Content
2533  $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
2534 
2535  //Topic
2536  $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder'));
2537 
2538  // Recipient
2539  $recipient = new User($this->db);
2540  $res = $recipient->fetch($actionCommReminder->fk_user);
2541  if ($res > 0) {
2542  if (!empty($recipient->email)) {
2543  $to = $recipient->email;
2544  } else {
2545  $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user.";
2546  $error++;
2547  }
2548  } else {
2549  $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user;
2550  $error++;
2551  }
2552 
2553  // Sender
2554  $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
2555  if (empty($from)) {
2556  $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
2557  $error++;
2558  }
2559 
2560  if (!$error) {
2561  // Errors Recipient
2562  $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');
2563 
2564  // Mail Creation
2565  $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
2566 
2567  // Sending Mail
2568  if ($cMailFile->sendfile()) {
2569  $nbMailSend++;
2570  } else {
2571  $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.join(',', $cMailFile->errors);
2572  $error++;
2573  }
2574  }
2575 
2576  if (!$error) {
2577  $actionCommReminder->status = $actionCommReminder::STATUS_DONE;
2578 
2579  $res = $actionCommReminder->update($user);
2580  if ($res < 0) {
2581  $errorsMsg[] = "Failed to update status to done of ActionComm Reminder";
2582  $error++;
2583  break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
2584  }
2585  } else {
2586  $actionCommReminder->status = $actionCommReminder::STATUS_ERROR;
2587  $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1);
2588 
2589  $res = $actionCommReminder->update($user);
2590  if ($res < 0) {
2591  $errorsMsg[] = "Failed to update status to error of ActionComm Reminder";
2592  $error++;
2593  break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
2594  } else {
2595  $errorsMsg[] = $errormesg;
2596  }
2597  }
2598  } else {
2599  $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm;
2600  $error++;
2601  }
2602  }
2603  }
2604  } else {
2605  $error++;
2606  }
2607 
2608  if (!$error) {
2609  // Delete also very old past events (we do not keep more than 1 month record in past)
2610  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2611  $sql .= " WHERE dateremind < '".$this->db->idate($now - (3600 * 24 * 32))."'";
2612  $sql .= " AND status = ".((int) $actionCommReminder::STATUS_DONE);
2613  $resql = $this->db->query($sql);
2614 
2615  if (!$resql) {
2616  $errorsMsg[] = 'Failed to delete old reminders';
2617  //$error++; // If this fails, we must not rollback other SQL requests already done. Never mind.
2618  }
2619  }
2620 
2621  if (!$error) {
2622  $this->output = 'Nb of emails sent : '.$nbMailSend;
2623  $this->db->commit();
2624 
2625  dol_syslog(__METHOD__." end - ".$this->output, LOG_INFO);
2626 
2627  return 0;
2628  } else {
2629  $this->db->commit(); // We commit also on error, to have the error message recorded.
2630  $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error;
2631 
2632  dol_syslog(__METHOD__." end - ".$this->error, LOG_INFO);
2633 
2634  return $error;
2635  }
2636  }
2637 
2646  public function updatePercent($id, $percent, $usermodid = 0)
2647  {
2648  $this->db->begin();
2649 
2650  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm ";
2651  $sql .= " SET percent = ".(int) $percent;
2652  if ($usermodid > 0) $sql .= ", fk_user_mod = ".$usermodid;
2653  $sql .= " WHERE id = ".((int) $id);
2654 
2655  if ($this->db->query($sql)) {
2656  $this->db->commit();
2657  return 1;
2658  } else {
2659  $this->db->rollback();
2660  $this->error = $this->db->lasterror();
2661  return -1;
2662  }
2663  }
2664 }
$object ref
Definition: info.php:78
Class to manage agenda events (actions)
const EVENT_FINISHED
Typical value for a event that is in a finished state.
hasDelay()
Is the action delayed?
build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday=0)
Export events from database into a cal file.
getTooltipContentArray($params)
getTooltipContentArray
update(User $user, $notrigger=0)
Update action into database If percentage = 100, on met a jour date 100%.
fetch_userassigned($override=true)
Initialize this->userassigned array with list of id of user assigned to event.
info($id)
Charge les informations d'ordre info dans l'objet facture.
static replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.
const EVENT_IN_PROGRESS
Typical value for a event that is in a progress state.
getNomUrl($withpicto=0, $maxlength=0, $classname='', $option='', $overwritepicto=0, $notooltip=0, $save_lastsearch_value=-1)
Return URL of event Use $this->id, $this->type_code, $this->label and $this->type_label.
sendEmailsReminder()
Send reminders by emails CAN BE A CRON TASK.
create(User $user, $notrigger=0)
Add an action/event into database.
const EVENT_TODO
Typical value for a event that is in a todo state.
setCategories($categories)
Sets object to supplied categories.
createFromClone(User $fuser, $socid)
Load an object from its id and create a new one in database.
$recurid
Properties to manage the recurring events.
getTypePicto()
Return Picto of type of event.
LibStatut($percent, $mode, $hidenastatus=0, $datestart='')
Return label of action status.
getActions($socid=0, $fk_element=0, $elementtype='', $filter='', $sortfield='a.datep', $sortorder='DESC', $limit=0)
Load all objects with filters.
load_board($user, $load_state_board=0)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
fetch($id, $ref='', $ref_ext='', $email_msgid='', $loadresources=1)
Load object from database.
updatePercent($id, $percent, $usermodid=0)
Udpate the percent value of a event with the given id.
loadReminders($type='', $fk_user=0, $onlypast=true)
Load event reminder of events.
fetchResources()
Initialize $this->userassigned & this->socpeopleassigned array with list of id of user and contact as...
static replaceProduct(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a product id with another one.
__construct(DoliDB $db)
Constructor.
initAsSpecimen()
Initialise an instance with random values.
getLibStatut($mode, $hidenastatus=0)
Return the label of the status.
Class for ActionCommReminder.
Class to manage different types of events.
Class to send emails (with attachments or not) Usage: $mailfile = new CMailFile($subject,...
Class to manage categories.
Parent class of all other business classes (invoices, contracts, proposals, orders,...
fetch_optionals($rowid=null, $optionsArray=null)
Function to get extra fields of an object into $this->array_options This method is in most cases call...
setErrorsFromObject($object)
setErrorsFromObject
deleteExtraFields()
Delete all extra fields values for the current object.
static commonReplaceThirdparty(DoliDB $dbs, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
call_trigger($triggerName, $user)
Call trigger based on this instance.
Class to manage Dolibarr database access.
Class to manage generation of HTML components Only common components must be here.
Classe permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new For...
Class to manage hooks.
Class to manage Dolibarr users.
Definition: user.class.php:48
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition: date.lib.php:577
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition: date.lib.php:409
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:596
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array())
Move a file into another name.
Definition: files.lib.php:948
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:599
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
Definition: files.lib.php:1356
dolGetFirstLineOfText($text, $nboflines=1, $charset='UTF-8')
Return first line of text.
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
dolGetStatus($statusLabel='', $statusLabelShort='', $html='', $statusType='status0', $displayMode=0, $url='', $params=array())
Output the badge of a status.
make_substitutions($text, $substitutionarray, $outputlangs=null, $converttextinhtmlifnecessary=0)
Make substitution into a text string, replacing keys with vals from $substitutionarray (oldval=>newva...
dol_textishtml($msg, $option=0)
Return if a text is a html content.
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
query($query, $usesavepoint=0, $type='auto', $result_mode=0)
Execute a SQL request and return the resultset.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
print *****$script_file(".$version.") pid code
! Closing after partial payment: discount_vat, badcustomer or badsupplier, bankcharge,...
build_calfile($format, $title, $desc, $events_array, $outputfile)
Build a file from an array of events All input params and data must be encoded in $conf->charset_outp...
Definition: xcal.lib.php:35
build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter='', $url='', $langcode='')
Build a file from an array of events.
Definition: xcal.lib.php:325