dolibarr  19.0.0-dev
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, 10); // 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 
1754  if (empty($notooltip)) {
1755  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
1756  $label = $langs->trans("ShowAction");
1757  $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"';
1758  }
1759  $linkclose .= ($label ? ' title="'.dol_escape_htmltag($label, 1).'"' : ' title="tocomplete"');
1760  $linkclose .= $dataparams.' class="'.$classname.' '.$classfortooltip.'"';
1761  } else {
1762  $linkclose .= ' class="'.$classname.'"';
1763  }
1764 
1765  $url = '';
1766  if ($option == 'birthday') {
1767  $url = DOL_URL_ROOT.'/contact/perso.php?id='.$this->id;
1768  } elseif ($option == 'holiday') {
1769  $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1770  } else {
1771  $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id;
1772  }
1773 
1774  if ($option !== 'nolink') {
1775  // Add param to save lastsearch_values or not
1776  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1777  if ($save_lastsearch_value == -1 && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1778  $add_save_lastsearch_values = 1;
1779  }
1780  if ($add_save_lastsearch_values) {
1781  $url .= '&save_lastsearch_values=1';
1782  }
1783  }
1784 
1785  $linkstart = '<a href="'.$url.'"';
1786  $linkstart .= $linkclose.'>';
1787  $linkend = '</a>';
1788 
1789  if ($option == 'nolink') {
1790  $linkstart = '';
1791  $linkend = '';
1792  }
1793 
1794  if ($withpicto == 2) {
1795  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
1796  $label = $labeltype;
1797  }
1798  $labelshort = '';
1799  } else {
1800  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($label)) {
1801  $label = $labeltype;
1802  }
1803  if ($maxlength < 0) {
1804  $labelshort = $this->ref;
1805  } else {
1806  $labelshort = dol_trunc($label, $maxlength);
1807  }
1808  }
1809 
1810  if ($withpicto) {
1811  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) { // Add code into ()
1812  if ($labeltype) {
1813  $label .= (preg_match('/'.preg_quote($labeltype, '/').'/', $label) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')');
1814  }
1815  }
1816  }
1817 
1818  $result .= $linkstart;
1819  if ($withpicto) {
1820  $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$label), ($overwritepicto ? $overwritepicto : 'action'), (($this->type_color && $overwritepicto) ? 'style="color: #'.$this->type_color.' !important;" ' : '').($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : $dataparams.' class="'.(($withpicto != 2) ? 'paddingright ' : '').$classfortooltip.'"'), 0, 0, $notooltip ? 0 : 1);
1821  }
1822  $result .= dol_escape_htmltag($labelshort);
1823  $result .= $linkend;
1824 
1825  global $action;
1826  $hookmanager->initHooks(array('actiondao'));
1827  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1828  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1829  if ($reshook > 0) {
1830  $result = $hookmanager->resPrint;
1831  } else {
1832  $result .= $hookmanager->resPrint;
1833  }
1834 
1835  return $result;
1836  }
1837 
1843  public function getTypePicto()
1844  {
1845  global $conf;
1846 
1847  $imgpicto = '';
1848  if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
1849  $color = '';
1850  if ($this->type_color) {
1851  $color = 'style="color: #'.$this->type_color.' !important;"';
1852  }
1853  if ($this->type_picto) {
1854  $imgpicto = img_picto('', $this->type_picto, 'class="paddingright"');
1855  } else {
1856  if ($this->type_code == 'AC_RDV') {
1857  $imgpicto = img_picto('', 'meeting', $color, false, 0, 0, '', 'paddingright');
1858  } elseif ($this->type_code == 'AC_TEL') {
1859  $imgpicto = img_picto('', 'object_phoning', $color, false, 0, 0, '', 'paddingright');
1860  } elseif ($this->type_code == 'AC_FAX') {
1861  $imgpicto = img_picto('', 'object_phoning_fax', $color, false, 0, 0, '', 'paddingright');
1862  } elseif ($this->type_code == 'AC_EMAIL' || $this->type_code == 'AC_EMAIL_IN' || (!empty($this->code) && preg_match('/_SENTBYMAIL/', $this->code))) {
1863  $imgpicto = img_picto('', 'object_email', $color, false, 0, 0, '', 'paddingright');
1864  } elseif ($this->type_code == 'AC_INT') {
1865  $imgpicto = img_picto('', 'object_intervention', $color, false, 0, 0, '', 'paddingright');
1866  } elseif (!empty($this->code) && preg_match('/^TICKET_MSG/', $this->code)) {
1867  $imgpicto = img_picto('', 'object_conversation', $color, false, 0, 0, '', 'paddingright');
1868  } elseif ($this->type != 'systemauto') {
1869  $imgpicto = img_picto('', 'user-cog', $color, false, 0, 0, '', 'paddingright');
1870  } else {
1871  $imgpicto = img_picto('', 'cog', $color, false, 0, 0, '', 'paddingright');
1872  }
1873  }
1874  } else {
1875  // 2 picto: 1 for auto, 1 for manual
1876  if ($this->type != 'systemauto') {
1877  $imgpicto = img_picto('', 'user-cog', '', false, 0, 0, '', 'paddingright');
1878  } else {
1879  $imgpicto = img_picto('', 'cog', '', false, 0, 0, '', 'paddingright');
1880  }
1881  }
1882  return $imgpicto;
1883  }
1884 
1885 
1896  public function setCategories($categories)
1897  {
1898  // Handle single category
1899  if (!is_array($categories)) {
1900  $categories = array($categories);
1901  }
1902 
1903  // Get current categories
1904  include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1905  $c = new Categorie($this->db);
1906  $existing = $c->containing($this->id, Categorie::TYPE_ACTIONCOMM, 'id');
1907 
1908  // Diff
1909  if (is_array($existing)) {
1910  $to_del = array_diff($existing, $categories);
1911  $to_add = array_diff($categories, $existing);
1912  } else {
1913  $to_del = array(); // Nothing to delete
1914  $to_add = $categories;
1915  }
1916 
1917  // Process
1918  foreach ($to_del as $del) {
1919  if ($c->fetch($del) > 0) {
1920  $c->del_type($this, Categorie::TYPE_ACTIONCOMM);
1921  }
1922  }
1923  foreach ($to_add as $add) {
1924  if ($c->fetch($add) > 0) {
1925  $c->add_type($this, Categorie::TYPE_ACTIONCOMM);
1926  }
1927  }
1928  return 1;
1929  }
1930 
1931  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1943  public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0)
1944  {
1945  global $hookmanager;
1946 
1947  // phpcs:enable
1948  global $conf, $langs, $dolibarr_main_url_root, $mysoc;
1949 
1950  require_once DOL_DOCUMENT_ROOT."/core/lib/xcal.lib.php";
1951  require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
1952  require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
1953 
1954  dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG);
1955 
1956  // Check parameters
1957  if (empty($format)) {
1958  return -1;
1959  }
1960 
1961  // Clean parameters
1962  if (!$filename) {
1963  $extension = 'vcs';
1964  if ($format == 'ical') {
1965  $extension = 'ics';
1966  }
1967  $filename = $format.'.'.$extension;
1968  }
1969 
1970  // Create dir and define output file (definitive and temporary)
1971  $result = dol_mkdir($conf->agenda->dir_temp);
1972  $outputfile = $conf->agenda->dir_temp.'/'.$filename;
1973 
1974  $result = 0;
1975 
1976  $buildfile = true;
1977  $login = ''; $logina = ''; $logind = ''; $logint = '';
1978 
1979  $now = dol_now();
1980 
1981  if ($cachedelay) {
1982  $nowgmt = dol_now();
1983  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1984  if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay)) {
1985  dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled");
1986  $buildfile = false;
1987  }
1988  }
1989 
1990  if ($buildfile) {
1991  // Build event array
1992  $eventarray = array();
1993 
1994  $sql = "SELECT a.id,";
1995  $sql .= " a.datep,"; // Start
1996  $sql .= " a.datep2,"; // End
1997  $sql .= " a.durationp,"; // deprecated
1998  $sql .= " a.datec, a.tms as datem,";
1999  $sql .= " a.label, a.code, a.note as note_private, a.fk_action as type_id,";
2000  $sql .= " a.fk_soc,";
2001  $sql .= " a.fk_user_author, a.fk_user_mod,";
2002  $sql .= " a.fk_user_action,";
2003  $sql .= " a.fk_contact, a.percent as percentage,";
2004  $sql .= " a.fk_element, a.elementtype,";
2005  $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
2006  $sql .= " u.firstname, u.lastname, u.email,";
2007  $sql .= " s.nom as socname,";
2008  $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label,";
2009  $sql .= " num_vote, event_paid, a.status";
2010  $sql .= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)";
2011  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export
2012  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
2013 
2014  $parameters = array('filters' => $filters);
2015  $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
2016  $sql .= $hookmanager->resPrint;
2017 
2018  // We must filter on assignement table
2019  if ($filters['logint']) {
2020  $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar";
2021  }
2022  $sql .= " WHERE a.fk_action=c.id";
2023  $sql .= " AND a.entity IN (".getEntity('agenda').")";
2024  foreach ($filters as $key => $value) {
2025  if ($key == 'notolderthan' && $value != '') {
2026  $sql .= " AND a.datep >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'";
2027  }
2028  if ($key == 'year') {
2029  $sql .= " AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'";
2030  }
2031  if ($key == 'id') {
2032  $sql .= " AND a.id=".(is_numeric($value) ? $value : 0);
2033  }
2034  if ($key == 'idfrom') {
2035  $sql .= " AND a.id >= ".(is_numeric($value) ? $value : 0);
2036  }
2037  if ($key == 'idto') {
2038  $sql .= " AND a.id <= ".(is_numeric($value) ? $value : 0);
2039  }
2040  if ($key == 'project') {
2041  $sql .= " AND a.fk_project=".(is_numeric($value) ? $value : 0);
2042  }
2043  if ($key == 'actiontype') {
2044  $sql .= " AND c.type = '".$this->db->escape($value)."'";
2045  }
2046  if ($key == 'notactiontype') {
2047  $sql .= " AND c.type <> '".$this->db->escape($value)."'";
2048  }
2049  // We must filter on assignement table
2050  if ($key == 'logint') {
2051  $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
2052  }
2053  if ($key == 'logina') {
2054  $logina = $value;
2055  $condition = '=';
2056  if (preg_match('/^!/', $logina)) {
2057  $logina = preg_replace('/^!/', '', $logina);
2058  $condition = '<>';
2059  }
2060  $userforfilter = new User($this->db);
2061  $result = $userforfilter->fetch('', $logina);
2062  if ($result > 0) {
2063  $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id;
2064  } elseif ($result < 0 || $condition == '=') {
2065  $sql .= " AND a.fk_user_author = 0";
2066  }
2067  }
2068  if ($key == 'logint') {
2069  $logint = $value;
2070  $condition = '=';
2071  if (preg_match('/^!/', $logint)) {
2072  $logint = preg_replace('/^!/', '', $logint);
2073  $condition = '<>';
2074  }
2075  $userforfilter = new User($this->db);
2076  $result = $userforfilter->fetch('', $logint);
2077  if ($result > 0) {
2078  $sql .= " AND ar.fk_element = ".((int) $userforfilter->id);
2079  } elseif ($result < 0 || $condition == '=') {
2080  $sql .= " AND ar.fk_element = 0";
2081  }
2082  }
2083  if ($key == 'module') {
2084  $sql .= " AND c.module LIKE '%".$this->db->escape($value)."'";
2085  }
2086  if ($key == 'status') {
2087  $sql .= " AND a.status =".((int) $value);
2088  }
2089  }
2090 
2091  $sql .= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import
2092 
2093  $parameters = array('filters' => $filters);
2094  $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
2095  $sql .= $hookmanager->resPrint;
2096 
2097  $sql .= " ORDER by datep";
2098  //print $sql;exit;
2099 
2100  dol_syslog(get_class($this)."::build_exportfile select events", LOG_DEBUG);
2101  $resql = $this->db->query($sql);
2102  if ($resql) {
2103  $diff = 0;
2104  while ($obj = $this->db->fetch_object($resql)) {
2105  $qualified = true;
2106 
2107  // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author'
2108  $event = array();
2109  $event['uid'] = 'dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"];
2110  $event['type'] = $type;
2111 
2112  $datestart = $this->db->jdate($obj->datep) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2113 
2114  // fix for -> Warning: A non-numeric value encountered
2115  if (is_numeric($this->db->jdate($obj->datep2))) {
2116  $dateend = $this->db->jdate($obj->datep2) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2117  } else {
2118  // use start date as fall-back to avoid pb with empty end date on ICS readers
2119  $dateend = $datestart;
2120  }
2121 
2122  $duration = ($datestart && $dateend) ? ($dateend - $datestart) : 0;
2123  $event['summary'] = $obj->label.($obj->socname ? " (".$obj->socname.")" : "");
2124 
2125  $event['desc'] = $obj->note_private;
2126  $event['startdate'] = $datestart;
2127  $event['enddate'] = $dateend; // Not required with type 'journal'
2128  $event['duration'] = $duration; // Not required with type 'journal'
2129  $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2130  $event['priority'] = $obj->priority;
2131  $event['fulldayevent'] = $obj->fulldayevent;
2132  $event['location'] = $obj->location;
2133  $event['transparency'] = (($obj->transparency > 0) ? 'OPAQUE' : 'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy)
2134  $event['category'] = $obj->type_label;
2135  $event['email'] = $obj->email;
2136  // Define $urlwithroot
2137  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2138  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
2139  //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
2140  $url = $urlwithroot.'/comm/action/card.php?id='.$obj->id;
2141  $event['url'] = $url;
2142  $event['created'] = $this->db->jdate($obj->datec) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2143  $event['modified'] = $this->db->jdate($obj->datem) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2144  $event['num_vote'] = $this->num_vote;
2145  $event['event_paid'] = $this->event_paid;
2146  $event['status'] = $this->status;
2147 
2148  // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties
2149  $this->id = $obj->id;
2150  $this->fetch_userassigned(false);
2151 
2152  $assignedUserArray = array();
2153 
2154  foreach ($this->userassigned as $key => $value) {
2155  $assignedUser = new User($this->db);
2156  $assignedUser->fetch($value['id']);
2157 
2158  $assignedUserArray[$key] = $assignedUser;
2159  }
2160 
2161  $event['assignedUsers'] = $assignedUserArray;
2162 
2163  if ($qualified && $datestart) {
2164  $eventarray[] = $event;
2165  }
2166  $diff++;
2167  }
2168 
2169  $parameters = array('filters' => $filters, 'eventarray' => &$eventarray);
2170  $reshook = $hookmanager->executeHooks('addMoreEventsExport', $parameters); // Note that $action and $object may have been modified by hook
2171  if ($reshook > 0) {
2172  $eventarray = $hookmanager->resArray;
2173  }
2174  } else {
2175  $this->error = $this->db->lasterror();
2176  return -1;
2177  }
2178 
2179  if ($exportholiday == 1) {
2180  $langs->load("holiday");
2181  $title = $langs->transnoentities("Holidays");
2182 
2183  $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";
2184  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u";
2185  $sql .= " WHERE u.rowid = x.fk_user";
2186  $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user)
2187  $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved)
2188 
2189  $resql = $this->db->query($sql);
2190  if ($resql) {
2191  $num = $this->db->num_rows($resql);
2192  $i = 0;
2193 
2194  while ($i < $num) {
2195  $obj = $this->db->fetch_object($resql);
2196  $event = array();
2197 
2198  if ($obj->halfday == 1) {
2199  $event['fulldayevent'] = false;
2200 
2201  $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2202  $timestampEnd = dol_stringtotime($obj->date_end." 12:00:00", 0);
2203  } elseif ($obj->halfday == -1) {
2204  $event['fulldayevent'] = false;
2205 
2206  $timestampStart = dol_stringtotime($obj->date_start." 12:00:00", 0);
2207  $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2208  } else {
2209  $event['fulldayevent'] = true;
2210 
2211  $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2212  $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2213  }
2214 
2215  if (!empty($conf->global->AGENDA_EXPORT_FIX_TZ)) {
2216  $timestampStart = $timestampStart - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2217  $timestampEnd = $timestampEnd - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2218  }
2219 
2220  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2221  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
2222  $url = $urlwithroot.'/holiday/card.php?id='.$obj->rowid;
2223 
2224  $event['uid'] = 'dolibarrholiday-'.$this->db->database_name.'-'.$obj->rowid."@".$_SERVER["SERVER_NAME"];
2225  $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2226  $event['type'] = 'event';
2227  $event['category'] = "Holiday";
2228  $event['transparency'] = 'OPAQUE';
2229  $event['email'] = $obj->email;
2230  $event['created'] = $timestampStart;
2231  $event['modified'] = $timestampStart;
2232  $event['startdate'] = $timestampStart;
2233  $event['enddate'] = $timestampEnd;
2234  $event['duration'] = $timestampEnd - $timestampStart;
2235  $event['url'] = $url;
2236 
2237  if ($obj->status == 2) {
2238  // 2 = leave wait for approval
2239  $event['summary'] = $title." - ".$obj->lastname." (wait for approval)";
2240  } else {
2241  // 3 = leave approved
2242  $event['summary'] = $title." - ".$obj->lastname;
2243  }
2244 
2245  $eventarray[] = $event;
2246 
2247  $i++;
2248  }
2249  }
2250  }
2251 
2252  $langs->load("agenda");
2253 
2254  // Define title and desc
2255  $more = '';
2256  if ($login) {
2257  $more = $langs->transnoentities("User").' '.$login;
2258  }
2259  if ($logina) {
2260  $more = $langs->transnoentities("ActionsAskedBy").' '.$logina;
2261  }
2262  if ($logint) {
2263  $more = $langs->transnoentities("ActionsToDoBy").' '.$logint;
2264  }
2265  if ($logind) {
2266  $more = $langs->transnoentities("ActionsDoneBy").' '.$logind;
2267  }
2268  if ($more) {
2269  $title = 'Dolibarr actions '.$mysoc->name.' - '.$more;
2270  $desc = $more;
2271  $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2272  } else {
2273  $title = 'Dolibarr actions '.$mysoc->name;
2274  $desc = $langs->transnoentities('ListOfActions');
2275  $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2276  }
2277 
2278  // Create temp file
2279  $outputfiletmp = tempnam($conf->agenda->dir_temp, 'tmp'); // Temporary file (allow call of function by different threads
2280  dolChmod($outputfiletmp);
2281 
2282  // Write file
2283  if ($format == 'vcal') {
2284  $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2285  } elseif ($format == 'ical') {
2286  $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2287  } elseif ($format == 'rss') {
2288  $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp);
2289  }
2290 
2291  if ($result >= 0) {
2292  if (dol_move($outputfiletmp, $outputfile, 0, 1, 0, 0)) {
2293  $result = 1;
2294  } else {
2295  $this->error = 'Failed to rename '.$outputfiletmp.' into '.$outputfile;
2296  dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR);
2297  dol_delete_file($outputfiletmp, 0, 1);
2298  $result = -1;
2299  }
2300  } else {
2301  dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR);
2302  dol_delete_file($outputfiletmp, 0, 1);
2303  $langs->load("errors");
2304  $this->error = $langs->trans("ErrorFailToCreateFile", $outputfile);
2305  }
2306  }
2307 
2308  return $result;
2309  }
2310 
2318  public function initAsSpecimen()
2319  {
2320  global $user;
2321 
2322  $now = dol_now();
2323 
2324  // Initialise parametres
2325  $this->id = 0;
2326  $this->specimen = 1;
2327 
2328  $this->type_code = 'AC_OTH';
2329  $this->code = 'AC_SPECIMEN_CODE';
2330  $this->label = 'Label of event Specimen';
2331  $this->datec = $now;
2332  $this->datem = $now;
2333  $this->datep = $now;
2334  $this->datef = $now;
2335  $this->fulldayevent = 0;
2336  $this->percentage = 0;
2337  $this->status = 0;
2338  $this->location = 'Location';
2339  $this->transparency = 1; // 1 means opaque
2340  $this->priority = 1;
2341  //$this->note_public = "This is a 'public' note.";
2342  $this->note_private = "This is a 'private' note.";
2343 
2344  $this->userownerid = $user->id;
2345  $this->userassigned[$user->id] = array('id'=>$user->id, 'transparency'=> 1);
2346  return 1;
2347  }
2348 
2357  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2358  {
2359  $tables = array(
2360  'actioncomm'
2361  );
2362 
2363  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
2364  }
2365 
2374  public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id)
2375  {
2376  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id);
2377  // using $dbs, not $this->db because function is static
2378  if (!$dbs->query($sql)) {
2379  //$this->errors = $dbs->lasterror();
2380  return false;
2381  }
2382 
2383  return true;
2384  }
2385 
2391  public function hasDelay()
2392  {
2393  global $conf;
2394 
2395  $now = dol_now();
2396 
2397  return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay));
2398  }
2399 
2400 
2409  public function loadReminders($type = '', $fk_user = 0, $onlypast = true)
2410  {
2411  global $conf, $langs, $user;
2412 
2413  $error = 0;
2414 
2415  $this->reminders = array();
2416 
2417  //Select all action comm reminders for event
2418  $sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user";
2419  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2420  $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
2421  if ($onlypast) {
2422  $sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'";
2423  }
2424  if ($type) {
2425  $sql .= " AND typeremind ='".$this->db->escape($type)."'";
2426  }
2427  if ($fk_user > 0) {
2428  $sql .= " AND fk_user = ".((int) $fk_user);
2429  }
2430  if (empty($conf->global->AGENDA_REMINDER_EMAIL)) {
2431  $sql .= " AND typeremind != 'email'";
2432  }
2433  if (empty($conf->global->AGENDA_REMINDER_BROWSER)) {
2434  $sql .= " AND typeremind != 'browser'";
2435  }
2436 
2437  $sql .= $this->db->order("dateremind", "ASC");
2438  $resql = $this->db->query($sql);
2439 
2440  if ($resql) {
2441  while ($obj = $this->db->fetch_object($resql)) {
2442  $tmpactioncommreminder = new ActionCommReminder($this->db);
2443  $tmpactioncommreminder->id = $obj->id;
2444  $tmpactioncommreminder->typeremind = $obj->typeremind;
2445  $tmpactioncommreminder->dateremind = $obj->dateremind;
2446  $tmpactioncommreminder->offsetvalue = $obj->offsetvalue;
2447  $tmpactioncommreminder->offsetunit = $obj->offsetunit;
2448  $tmpactioncommreminder->status = $obj->status;
2449  $tmpactioncommreminder->fk_user = $obj->fk_user;
2450 
2451  $this->reminders[$obj->id] = $tmpactioncommreminder;
2452  }
2453  } else {
2454  $this->error = $this->db->lasterror();
2455  $error++;
2456  }
2457 
2458  return count($this->reminders);
2459  }
2460 
2461 
2468  public function sendEmailsReminder()
2469  {
2470  global $conf, $langs, $user;
2471 
2472  $error = 0;
2473  $this->output = '';
2474  $this->error = '';
2475  $nbMailSend = 0;
2476  $errorsMsg = array();
2477 
2478  if (!isModEnabled('agenda')) { // Should not happen. If module disabled, cron job should not be visible.
2479  $langs->load("agenda");
2480  $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2481  return 0;
2482  }
2483  if (empty($conf->global->AGENDA_REMINDER_EMAIL)) {
2484  $langs->load("agenda");
2485  $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2486  return 0;
2487  }
2488 
2489  $now = dol_now();
2490  $actionCommReminder = new ActionCommReminder($this->db);
2491 
2492  dol_syslog(__METHOD__, LOG_DEBUG);
2493 
2494  $this->db->begin();
2495 
2496  //Select all action comm reminders
2497  $sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2498  $sql .= " WHERE typeremind = 'email' AND status = 0";
2499  $sql .= " AND dateremind <= '".$this->db->idate($now)."'";
2500  $sql .= " AND entity IN (".getEntity('actioncomm').")";
2501  $sql .= $this->db->order("dateremind", "ASC");
2502  $resql = $this->db->query($sql);
2503 
2504  if ($resql) {
2505  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2506  $formmail = new FormMail($this->db);
2507 
2508  while ($obj = $this->db->fetch_object($resql)) {
2509  $res = $actionCommReminder->fetch($obj->id);
2510  if ($res < 0) {
2511  $error++;
2512  $errorsMsg[] = "Failed to load invoice ActionComm Reminder";
2513  }
2514 
2515  if (!$error) {
2516  //Select email template
2517  $arraymessage = $formmail->getEMailTemplate($this->db, 'actioncomm_send', $user, $langs, (!empty($actionCommReminder->fk_email_template)) ? $actionCommReminder->fk_email_template : -1, 1);
2518 
2519  // Load event
2520  $res = $this->fetch($actionCommReminder->fk_actioncomm);
2521  if ($res > 0) {
2522  // PREPARE EMAIL
2523  $errormesg = '';
2524 
2525  // Make substitution in email content
2526  $substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this);
2527 
2528  complete_substitutions_array($substitutionarray, $langs, $this);
2529 
2530  // Content
2531  $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
2532 
2533  //Topic
2534  $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder'));
2535 
2536  // Recipient
2537  $recipient = new User($this->db);
2538  $res = $recipient->fetch($actionCommReminder->fk_user);
2539  if ($res > 0) {
2540  if (!empty($recipient->email)) {
2541  $to = $recipient->email;
2542  } else {
2543  $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user.";
2544  $error++;
2545  }
2546  } else {
2547  $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user;
2548  $error++;
2549  }
2550 
2551  // Sender
2552  $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
2553  if (empty($from)) {
2554  $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
2555  $error++;
2556  }
2557 
2558  if (!$error) {
2559  // Errors Recipient
2560  $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');
2561 
2562  // Mail Creation
2563  $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
2564 
2565  // Sending Mail
2566  if ($cMailFile->sendfile()) {
2567  $nbMailSend++;
2568  } else {
2569  $errormesg = $cMailFile->error.' : '.$to;
2570  $error++;
2571  }
2572  }
2573 
2574  if (!$error) {
2575  $actionCommReminder->status = $actionCommReminder::STATUS_DONE;
2576 
2577  $res = $actionCommReminder->update($user);
2578  if ($res < 0) {
2579  $errorsMsg[] = "Failed to update status to done of ActionComm Reminder";
2580  $error++;
2581  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.
2582  }
2583  } else {
2584  $actionCommReminder->status = $actionCommReminder::STATUS_ERROR;
2585  $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1);
2586 
2587  $res = $actionCommReminder->update($user);
2588  if ($res < 0) {
2589  $errorsMsg[] = "Failed to update status to error of ActionComm Reminder";
2590  $error++;
2591  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.
2592  } else {
2593  $errorsMsg[] = $errormesg;
2594  }
2595  }
2596  } else {
2597  $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm;
2598  $error++;
2599  }
2600  }
2601  }
2602  } else {
2603  $error++;
2604  }
2605 
2606  if (!$error) {
2607  // Delete also very old past events (we do not keep more than 1 month record in past)
2608  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2609  $sql .= " WHERE dateremind < '".$this->db->idate($now - (3600 * 24 * 32))."'";
2610  $sql .= " AND status = ".((int) $actionCommReminder::STATUS_DONE);
2611  $resql = $this->db->query($sql);
2612 
2613  if (!$resql) {
2614  $errorsMsg[] = 'Failed to delete old reminders';
2615  //$error++; // If this fails, we must not rollback other SQL requests already done. Never mind.
2616  }
2617  }
2618 
2619  if (!$error) {
2620  $this->output = 'Nb of emails sent : '.$nbMailSend;
2621  $this->db->commit();
2622  return 0;
2623  } else {
2624  $this->db->commit(); // We commit also on error, to have the error message recorded.
2625  $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error;
2626  return $error;
2627  }
2628  }
2629 
2638  public function updatePercent($id, $percent, $usermodid = 0)
2639  {
2640  $this->db->begin();
2641 
2642  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm ";
2643  $sql .= " SET percent = ".(int) $percent;
2644  if ($usermodid > 0) $sql .= ", fk_user_mod = ".$usermodid;
2645  $sql .= " WHERE id = ".((int) $id);
2646 
2647  if ($this->db->query($sql)) {
2648  $this->db->commit();
2649  return 1;
2650  } else {
2651  $this->db->rollback();
2652  $this->error = $this->db->lasterror();
2653  return -1;
2654  }
2655  }
2656 }
$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:576
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:408
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:595
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:1334
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1)
Move a file into another name.
Definition: files.lib.php:947
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