dolibarr  19.0.1
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 $fk_bookcal_calendar;
307 
311  public $icalname;
312 
316  public $icalcolor;
317 
321  public $extraparams;
322 
326  public $actions = array();
327 
331  public $email_msgid;
332 
336  public $email_from;
337 
341  public $email_sender;
342 
346  public $email_to;
347 
351  public $email_tocc;
355  public $email_tobcc;
356 
360  public $email_subject;
361 
365  public $errors_to;
366 
370  public $num_vote;
371 
375  public $event_paid;
376 
380  public $status;
381 
385  public $recurid; /* A string YYYYMMDDHHMMSS shared by allevent of same serie */
386  public $recurrule; /* Rule of recurring */
387  public $recurdateend; /* Repeat until this date */
388 
389  public $calling_duration;
390 
391 
395  const EVENT_TODO = 0;
396 
400  const EVENT_IN_PROGRESS = 50;
401 
405  const EVENT_FINISHED = 100;
406 
407 
408  public $fields = array();
409 
410 
416  public function __construct(DoliDB $db)
417  {
418  $this->db = $db;
419  }
420 
429  public function create(User $user, $notrigger = 0)
430  {
431  global $langs, $conf;
432 
433  $error = 0;
434  $now = dol_now();
435 
436  // Check parameters
437  if (!isset($this->userownerid) || (string) $this->userownerid === '') { // $this->userownerid may be 0 (anonymous event) or > 0
438  dol_syslog("You tried to create an event but mandatory property userownerid was empty (you can define it to 0 for anonymous event)", LOG_WARNING);
439  $this->errors[] = 'ErrorActionCommPropertyUserowneridNotDefined';
440  return -1;
441  }
442 
443  // Clean parameters
444  $this->label = dol_trunc(trim($this->label), 128);
445  $this->location = dol_trunc(trim($this->location), 128);
446  $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private));
447  if (empty($this->percentage)) {
448  $this->percentage = 0;
449  }
450  if (empty($this->priority) || !is_numeric($this->priority)) {
451  $this->priority = 0;
452  }
453  if (empty($this->fulldayevent)) {
454  $this->fulldayevent = 0;
455  }
456  if (empty($this->transparency)) {
457  $this->transparency = 0;
458  }
459  if ($this->percentage > 100) {
460  $this->percentage = 100;
461  }
462  if (empty($this->datep) && $this->datep != '0') { // We should not insert event in calendar without a start date
463  $this->datep = $now;
464  }
465  if (!empty($this->datep) && !empty($this->datef)) {
466  $this->durationp = ($this->datef - $this->datep); // deprecated
467  }
468  if (!empty($this->datep) && !empty($this->datef) && $this->datep > $this->datef) {
469  $this->datef = $this->datep;
470  }
471  if (!isset($this->fk_project) || $this->fk_project < 0) {
472  $this->fk_project = 0;
473  }
474  // For backward compatibility
475  if ($this->elementtype == 'facture') {
476  $this->elementtype = 'invoice';
477  }
478  if ($this->elementtype == 'commande') {
479  $this->elementtype = 'order';
480  }
481  if ($this->elementtype == 'contrat') {
482  $this->elementtype = 'contract';
483  }
484  if (empty($this->fk_element) && !empty($this->elementid)) {
485  $this->fk_element = $this->elementid;
486  }
487 
488  if (!is_array($this->userassigned) && !empty($this->userassigned)) { // For backward compatibility when userassigned was an int instead of an array
489  $tmpid = (int) $this->userassigned;
490  $this->userassigned = array();
491  $this->userassigned[$tmpid] = array('id'=>$tmpid, 'transparency'=>$this->transparency);
492  }
493 
494  $userownerid = $this->userownerid;
495  $userdoneid = $this->userdoneid;
496 
497  // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...).
498  if (empty($this->userassigned) || count($this->userassigned) == 0 || !is_array($this->userassigned)) {
499  $this->userassigned = array($userownerid=>array('id'=>$userownerid, 'transparency'=>$this->transparency));
500  }
501 
502  if (!$this->type_id || !$this->type_code) {
503  $key = empty($this->type_id) ? $this->type_code : $this->type_id;
504 
505  // Get id from code
506  $cactioncomm = new CActionComm($this->db);
507  $result = $cactioncomm->fetch($key);
508 
509  if ($result > 0) {
510  $this->type_id = $cactioncomm->id;
511  $this->type_code = $cactioncomm->code;
512  } elseif ($result == 0) {
513  $this->error = $langs->trans('ErrorActionCommBadType', $this->type_id, $this->type_code);
514  return -1;
515  } else {
516  $this->error = $cactioncomm->error;
517  return -1;
518  }
519  }
520  $code = empty($this->code) ? $this->type_code : $this->code;
521 
522  // Check parameters
523  if (!$this->type_id) {
524  $this->error = "ErrorWrongParameters";
525  return -1;
526  }
527 
528  $this->db->begin();
529 
530  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm";
531  $sql .= "(ref,";
532  $sql .= "datec,";
533  $sql .= "datep,";
534  $sql .= "datep2,";
535  $sql .= "durationp,"; // deprecated
536  $sql .= "fk_action,";
537  $sql .= "code,";
538  $sql .= "ref_ext,";
539  $sql .= "fk_soc,";
540  $sql .= "fk_project,";
541  $sql .= "note,";
542  $sql .= "fk_contact,";
543  $sql .= "fk_user_author,";
544  $sql .= "fk_user_action,";
545  $sql .= "fk_user_done,";
546  $sql .= "label,percent,priority,fulldayevent,location,";
547  $sql .= "transparency,";
548  $sql .= "fk_element,";
549  $sql .= "elementtype,";
550  $sql .= "fk_bookcal_calendar,";
551  $sql .= "entity,";
552  $sql .= "extraparams,";
553  // Fields emails
554  $sql .= "email_msgid,";
555  $sql .= "email_from,";
556  $sql .= "email_sender,";
557  $sql .= "email_to,";
558  $sql .= "email_tocc,";
559  $sql .= "email_tobcc,";
560  $sql .= "email_subject,";
561  $sql .= "errors_to,";
562  $sql .= "recurid,";
563  $sql .= "recurrule,";
564  $sql .= "recurdateend,";
565  $sql .= "num_vote,";
566  $sql .= "event_paid,";
567  $sql .= "status,";
568  $sql .= "ip";
569  $sql .= ") VALUES (";
570  $sql .= "'(PROV)', ";
571  $sql .= "'".$this->db->idate($now)."', "; // date creation
572  $sql .= "'".$this->db->idate($this->datep)."', "; // date start event
573  $sql .= (strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : "null").", ";
574  $sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated
575  $sql .= (isset($this->type_id) ? $this->type_id : "null").",";
576  $sql .= ($code ? ("'".$this->db->escape($code)."'") : "null").", ";
577  $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").", ";
578  $sql .= ((isset($this->socid) && $this->socid > 0) ? ((int) $this->socid) : "null").", ";
579  $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? ((int) $this->fk_project) : "null").", ";
580  $sql .= " '".$this->db->escape($this->note_private)."', ";
581  $sql .= ((isset($this->contact_id) && $this->contact_id > 0) ? ((int) $this->contact_id) : "null").", "; // deprecated, use ->socpeopleassigned
582  $sql .= (isset($user->id) && $user->id > 0 ? $user->id : "null").", ";
583  $sql .= ($userownerid > 0 ? $userownerid : "null").", ";
584  $sql .= ($userdoneid > 0 ? $userdoneid : "null").", ";
585  $sql .= "'".$this->db->escape($this->label)."', ";
586  $sql .= "'".$this->db->escape($this->percentage)."', ";
587  $sql .= "'".$this->db->escape($this->priority)."', ";
588  $sql .= "'".$this->db->escape($this->fulldayevent)."', ";
589  $sql .= "'".$this->db->escape($this->location)."', ";
590  $sql .= "'".$this->db->escape($this->transparency)."', ";
591  $sql .= (!empty($this->fk_element) ? ((int) $this->fk_element) : "null").", ";
592  $sql .= (!empty($this->elementtype) ? "'".$this->db->escape($this->elementtype)."'" : "null").", ";
593  $sql .= (!empty($this->fk_bookcal_calendar) ? "'".$this->db->escape($this->fk_bookcal_calendar)."'" : "null").", ";
594  $sql .= ((int) $conf->entity).",";
595  $sql .= (!empty($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").", ";
596  // Fields emails
597  $sql .= (!empty($this->email_msgid) ? "'".$this->db->escape($this->email_msgid)."'" : "null").", ";
598  $sql .= (!empty($this->email_from) ? "'".$this->db->escape($this->email_from)."'" : "null").", ";
599  $sql .= (!empty($this->email_sender) ? "'".$this->db->escape($this->email_sender)."'" : "null").", ";
600  $sql .= (!empty($this->email_to) ? "'".$this->db->escape($this->email_to)."'" : "null").", ";
601  $sql .= (!empty($this->email_tocc) ? "'".$this->db->escape($this->email_tocc)."'" : "null").", ";
602  $sql .= (!empty($this->email_tobcc) ? "'".$this->db->escape($this->email_tobcc)."'" : "null").", ";
603  $sql .= (!empty($this->email_subject) ? "'".$this->db->escape($this->email_subject)."'" : "null").", ";
604  $sql .= (!empty($this->errors_to) ? "'".$this->db->escape($this->errors_to)."'" : "null").", ";
605  $sql .= (!empty($this->recurid) ? "'".$this->db->escape($this->recurid)."'" : "null").", ";
606  $sql .= (!empty($this->recurrule) ? "'".$this->db->escape($this->recurrule)."'" : "null").", ";
607  $sql .= (!empty($this->recurdateend) ? "'".$this->db->idate($this->recurdateend)."'" : "null").", ";
608  $sql .= (!empty($this->num_vote) ? (int) $this->num_vote : "null").", ";
609  $sql .= (!empty($this->event_paid) ? (int) $this->event_paid : 0).", ";
610  $sql .= (!empty($this->status) ? (int) $this->status : "0").", ";
611  $sql .= (!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
612  $sql .= ")";
613 
614  dol_syslog(get_class($this)."::add", LOG_DEBUG);
615  $resql = $this->db->query($sql);
616  if ($resql) {
617  $this->ref = $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm", "id");
618  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm SET ref='".$this->db->escape($this->ref)."' WHERE id=".$this->id;
619  $resql = $this->db->query($sql);
620  if (!$resql) {
621  $error++;
622  dol_syslog('Error to process ref: '.$this->db->lasterror(), LOG_ERR);
623  $this->errors[] = $this->db->lasterror();
624  }
625  // Now insert assigned users
626  if (!$error) {
627  //dol_syslog(var_export($this->userassigned, true));
628  $already_inserted = array();
629  foreach ($this->userassigned as $key => $val) {
630  // Common value with new behavior is to have $val = array('id'=>iduser, 'transparency'=>0|1) and $this->userassigned is an array of iduser => $val.
631  if (!is_array($val)) { // For backward compatibility when $val='id'.
632  $val = array('id'=>$val);
633  }
634 
635  if ($val['id'] > 0) {
636  if (!empty($already_inserted[$val['id']])) {
637  continue;
638  }
639 
640  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
641  $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'])).")";
642 
643  $resql = $this->db->query($sql);
644  if (!$resql) {
645  $error++;
646  dol_syslog('Error to process userassigned: ' . $this->db->lasterror(), LOG_ERR);
647  $this->errors[] = $this->db->lasterror();
648  } else {
649  $already_inserted[$val['id']] = true;
650  }
651  //var_dump($sql);exit;
652  }
653  }
654  }
655 
656  if (!$error) {
657  if (!empty($this->socpeopleassigned)) {
658  $already_inserted = array();
659  foreach ($this->socpeopleassigned as $id => $val) {
660  // Common value with new behavior is to have $this->socpeopleassigned an array of idcontact => dummyvalue
661  if (!empty($already_inserted[$id])) {
662  continue;
663  }
664 
665  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
666  $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $id).", 0, 0, 0)";
667 
668  $resql = $this->db->query($sql);
669  if (!$resql) {
670  $error++;
671  dol_syslog('Error to process socpeopleassigned: ' . $this->db->lasterror(), LOG_ERR);
672  $this->errors[] = $this->db->lasterror();
673  } else {
674  $already_inserted[$id] = true;
675  }
676  }
677  }
678  }
679 
680  if (!$error) {
681  // Actions on extra fields
682  $result = $this->insertExtraFields();
683  if ($result < 0) {
684  $error++;
685  }
686  }
687 
688  if (!$error && !$notrigger) {
689  // Call trigger
690  $result = $this->call_trigger('ACTION_CREATE', $user);
691  if ($result < 0) {
692  $error++;
693  }
694  // End call triggers
695  }
696 
697  if (!$error) {
698  $this->db->commit();
699  return $this->id;
700  } else {
701  $this->db->rollback();
702  return -1;
703  }
704  } else {
705  $this->db->rollback();
706  $this->error = $this->db->lasterror();
707  return -1;
708  }
709  }
710 
718  public function createFromClone(User $fuser, $socid)
719  {
720  global $hookmanager;
721 
722  $error = 0;
723 
724  $this->db->begin();
725 
726  // Load source object
727  $objFrom = clone $this;
728 
729  // Retrieve all extrafield
730  // fetch optionals attributes and labels
731  $this->fetch_optionals();
732 
733  //$this->fetch_userassigned();
734  $this->fetchResources();
735 
736  $this->id = 0;
737  $this->recurid = '';
738  $this->recurrule = '';
739  $this->recurdateend = '';
740 
741  // Create clone
742  $this->context['createfromclone'] = 'createfromclone';
743  $result = $this->create($fuser);
744  if ($result < 0) {
745  $error++;
746  }
747 
748  if (!$error) {
749  // Hook of thirdparty module
750  if (is_object($hookmanager)) {
751  $parameters = array('objFrom'=>$objFrom);
752  $action = '';
753  $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
754  if ($reshook < 0) {
755  $this->setErrorsFromObject($hookmanager);
756  $error++;
757  }
758  }
759 
760  // Call trigger
761  $result = $this->call_trigger('ACTION_CLONE', $fuser);
762  if ($result < 0) {
763  $error++;
764  }
765  // End call triggers
766  }
767 
768  unset($this->context['createfromclone']);
769 
770  // End
771  if (!$error) {
772  $this->db->commit();
773  return $this->id;
774  } else {
775  $this->db->rollback();
776  return -1;
777  }
778  }
779 
790  public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '', $loadresources = 1)
791  {
792  global $langs;
793 
794  if (empty($id) && empty($ref) && empty($ref_ext) && empty($email_msgid)) {
795  dol_syslog(get_class($this)."::fetch Bad parameters", LOG_WARNING);
796  return -1;
797  }
798 
799  $sql = "SELECT a.id,";
800  $sql .= " a.ref as ref,";
801  $sql .= " a.entity,";
802  $sql .= " a.ref_ext,";
803  $sql .= " a.datep,";
804  $sql .= " a.datep2,";
805  $sql .= " a.durationp,"; // deprecated
806  $sql .= " a.datec,";
807  $sql .= " a.tms as datem,";
808  $sql .= " a.code, a.label, a.note as note_private,";
809  $sql .= " a.fk_soc,";
810  $sql .= " a.fk_project,";
811  $sql .= " a.fk_user_author, a.fk_user_mod,";
812  $sql .= " a.fk_user_action, a.fk_user_done,";
813  $sql .= " a.fk_contact, a.percent as percentage,";
814  $sql .= " a.fk_element as elementid, a.elementtype,";
815  $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
816  $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,";
817  $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,";
818  $sql .= " s.nom as socname,";
819  $sql .= " u.firstname, u.lastname as lastname,";
820  $sql .= " num_vote, event_paid, a.status";
821  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a ";
822  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action=c.id ";
823  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author";
824  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
825  $sql .= " WHERE ";
826  if ($ref) {
827  $sql .= " a.ref = '".$this->db->escape($ref)."'";
828  } elseif ($ref_ext) {
829  $sql .= " a.ref_ext = '".$this->db->escape($ref_ext)."'";
830  } elseif ($email_msgid) {
831  $sql .= " a.email_msgid = '".$this->db->escape($email_msgid)."'";
832  } else {
833  $sql .= " a.id = ".((int) $id);
834  }
835 
836  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
837  $resql = $this->db->query($sql);
838  if ($resql) {
839  $num = $this->db->num_rows($resql);
840  if ($num) {
841  $obj = $this->db->fetch_object($resql);
842 
843  $this->id = $obj->id;
844  $this->entity = $obj->entity;
845  $this->ref = $obj->ref;
846  $this->ref_ext = $obj->ref_ext;
847 
848  // Properties of parent table llx_c_actioncomm
849  $this->type_id = $obj->type_id;
850  $this->type_code = $obj->type_code;
851  $this->type_color = $obj->type_color;
852  $this->type_picto = $obj->type_picto;
853  $this->type = $obj->type_type;
854  /*$transcode = $langs->trans("Action".$obj->type_code);
855  $this->type = (($transcode != "Action".$obj->type_code) ? $transcode : $obj->type_label); */
856  $transcode = $langs->trans("Action".$obj->type_code.'Short');
857 
858  $this->code = $obj->code;
859  $this->label = $obj->label;
860  $this->datep = $this->db->jdate($obj->datep);
861  $this->datef = $this->db->jdate($obj->datep2);
862 
863  $this->datec = $this->db->jdate($obj->datec);
864  $this->datem = $this->db->jdate($obj->datem);
865 
866  $this->note = $obj->note_private; // deprecated
867  $this->note_private = $obj->note_private;
868  $this->percentage = $obj->percentage;
869 
870  $this->authorid = $obj->fk_user_author;
871  $this->usermodid = $obj->fk_user_mod;
872 
873  if (!is_object($this->author)) {
874  $this->author = new User($this->db); // To avoid warning
875  }
876  $this->author->id = $obj->fk_user_author; // deprecated
877  $this->author->firstname = $obj->firstname; // deprecated
878  $this->author->lastname = $obj->lastname; // deprecated
879  if (!is_object($this->usermod)) {
880  $this->usermod = new User($this->db); // To avoid warning
881  }
882  $this->usermod->id = $obj->fk_user_mod; // deprecated
883 
884  $this->userownerid = $obj->fk_user_action;
885  $this->priority = $obj->priority;
886  $this->fulldayevent = $obj->fulldayevent;
887  $this->location = $obj->location;
888  $this->transparency = $obj->transparency;
889 
890  $this->socid = $obj->fk_soc; // To have fetch_thirdparty method working
891  $this->contact_id = $obj->fk_contact; // To have fetch_contact method working
892  $this->fk_project = $obj->fk_project; // To have fetch_projet method working
893 
894  //$this->societe->id = $obj->fk_soc; // deprecated
895  //$this->contact->id = $obj->fk_contact; // deprecated
896 
897  $this->fk_element = $obj->elementid;
898  $this->elementid = $obj->elementid;
899  $this->elementtype = $obj->elementtype;
900 
901  $this->num_vote = $obj->num_vote;
902  $this->event_paid = $obj->event_paid;
903  $this->status = $obj->status;
904 
905  //email information
906  $this->email_msgid=$obj->email_msgid;
907  $this->email_from=$obj->email_from;
908  $this->email_sender=$obj->email_sender;
909  $this->email_to=$obj->email_to;
910  $this->email_tocc=$obj->email_tocc;
911  $this->email_tobcc=$obj->email_tobcc;
912  $this->email_subject=$obj->email_subject;
913  $this->errors_to=$obj->errors_to;
914 
915  $this->fetch_optionals();
916 
917  if ($loadresources) {
918  $this->fetchResources();
919  }
920  }
921 
922  $this->db->free($resql);
923  } else {
924  $this->error = $this->db->lasterror();
925  return -1;
926  }
927 
928  return $num;
929  }
930 
936  public function fetchResources()
937  {
938  $this->userassigned = array();
939  $this->socpeopleassigned = array();
940 
941  $sql = 'SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency';
942  $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm_resources';
943  $sql .= ' WHERE fk_actioncomm = '.((int) $this->id);
944  $sql .= " AND element_type IN ('user', 'socpeople')";
945  $resql = $this->db->query($sql);
946  if ($resql) {
947  // If owner is known, we must but id first into list
948  if ($this->userownerid > 0) {
949  $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid); // Set first so will be first into list.
950  }
951 
952  while ($obj = $this->db->fetch_object($resql)) {
953  if ($obj->fk_element > 0) {
954  switch ($obj->element_type) {
955  case 'user':
956  $this->userassigned[$obj->fk_element] = array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
957  if (empty($this->userownerid)) {
958  $this->userownerid = $obj->fk_element; // If not defined (should not happened, we fix this)
959  }
960  break;
961  case 'socpeople':
962  $this->socpeopleassigned[$obj->fk_element] = array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
963  break;
964  }
965  }
966  }
967 
968  return 1;
969  } else {
970  dol_print_error($this->db);
971  return -1;
972  }
973  }
974 
975  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
982  public function fetch_userassigned($override = true)
983  {
984  // phpcs:enable
985  $sql = "SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency";
986  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_resources";
987  $sql .= " WHERE element_type = 'user' AND fk_actioncomm = ".((int) $this->id);
988 
989  $resql2 = $this->db->query($sql);
990  if ($resql2) {
991  $this->userassigned = array();
992 
993  // If owner is known, we must but id first into list
994  if ($this->userownerid > 0) {
995  // Set first so will be first into list.
996  $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid);
997  }
998 
999  while ($obj = $this->db->fetch_object($resql2)) {
1000  if ($obj->fk_element > 0) {
1001  $this->userassigned[$obj->fk_element] = array('id'=>$obj->fk_element,
1002  'mandatory'=>$obj->mandatory,
1003  'answer_status'=>$obj->answer_status,
1004  'transparency'=>$obj->transparency);
1005  }
1006 
1007  if ($override === true) {
1008  // If not defined (should not happened, we fix this)
1009  if (empty($this->userownerid)) {
1010  $this->userownerid = $obj->fk_element;
1011  }
1012  }
1013  }
1014 
1015  return 1;
1016  } else {
1017  dol_print_error($this->db);
1018  return -1;
1019  }
1020  }
1021 
1029  public function delete($notrigger = 0)
1030  {
1031  global $user;
1032 
1033  $error = 0;
1034 
1035  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1036 
1037  $this->db->begin();
1038 
1039  // remove categorie association
1040  if (!$error) {
1041  $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_actioncomm";
1042  $sql .= " WHERE fk_actioncomm=".((int) $this->id);
1043 
1044  $res = $this->db->query($sql);
1045  if (!$res) {
1046  $this->error = $this->db->lasterror();
1047  $error++;
1048  }
1049  }
1050 
1051  // remove actioncomm_resources
1052  if (!$error) {
1053  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources";
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  if (!$error) {
1064  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
1065  $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
1066 
1067  $res = $this->db->query($sql);
1068  if (!$res) {
1069  $this->error = $this->db->lasterror();
1070  $error++;
1071  }
1072  }
1073 
1074  // Removed extrafields
1075  if (!$error) {
1076  $result = $this->deleteExtraFields();
1077  if ($result < 0) {
1078  $error++;
1079  dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
1080  }
1081  }
1082 
1083  // remove actioncomm
1084  if (!$error) {
1085  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm";
1086  $sql .= " WHERE id=".((int) $this->id);
1087 
1088  $res = $this->db->query($sql);
1089  if (!$res) {
1090  $this->error = $this->db->lasterror();
1091  $error++;
1092  }
1093  }
1094 
1095  if (!$error) {
1096  if (!$notrigger) {
1097  // Call trigger
1098  $result = $this->call_trigger('ACTION_DELETE', $user);
1099  if ($result < 0) {
1100  $error++;
1101  }
1102  // End call triggers
1103  }
1104 
1105  if (!$error) {
1106  $this->db->commit();
1107  return 1;
1108  } else {
1109  $this->db->rollback();
1110  return -2;
1111  }
1112  } else {
1113  $this->db->rollback();
1114  $this->error = $this->db->lasterror();
1115  return -1;
1116  }
1117  }
1118 
1127  public function update(User $user, $notrigger = 0)
1128  {
1129  global $langs, $conf, $hookmanager;
1130 
1131  $error = 0;
1132 
1133  // Clean parameters
1134  $this->label = trim($this->label);
1135  $this->note_private = dol_htmlcleanlastbr(trim(!isset($this->note_private) ? $this->note : $this->note_private));
1136  if (empty($this->percentage)) {
1137  $this->percentage = 0;
1138  }
1139  if (empty($this->priority) || !is_numeric($this->priority)) {
1140  $this->priority = 0;
1141  }
1142  if (empty($this->transparency)) {
1143  $this->transparency = 0;
1144  }
1145  if (empty($this->fulldayevent)) {
1146  $this->fulldayevent = 0;
1147  }
1148  if ($this->percentage > 100) {
1149  $this->percentage = 100;
1150  }
1151  //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date;
1152  if ($this->datep && $this->datef) {
1153  $this->durationp = ($this->datef - $this->datep); // deprecated
1154  }
1155  //if ($this->date && $this->dateend) $this->durationa=($this->dateend - $this->date);
1156  if ($this->datep && $this->datef && $this->datep > $this->datef) {
1157  $this->datef = $this->datep;
1158  }
1159  //if ($this->date && $this->dateend && $this->date > $this->dateend) $this->dateend=$this->date;
1160  if ($this->fk_project < 0) {
1161  $this->fk_project = 0;
1162  }
1163 
1164  // Check parameters
1165  if ($this->percentage == 0 && $this->userdoneid > 0) {
1166  $this->error = "ErrorCantSaveADoneUserWithZeroPercentage";
1167  return -1;
1168  }
1169 
1170  $socid = (($this->socid > 0) ? $this->socid : 0);
1171  $contactid = (($this->contact_id > 0) ? $this->contact_id : 0);
1172  $userownerid = ($this->userownerid ? $this->userownerid : 0);
1173  $userdoneid = ($this->userdoneid ? $this->userdoneid : 0);
1174 
1175  // If a type_id is set, we must also have the type_code set
1176  if ($this->type_id > 0) {
1177  if (empty($this->type_code)) {
1178  $cactioncomm = new CActionComm($this->db);
1179  $result = $cactioncomm->fetch($this->type_id);
1180  if ($result >= 0 && !empty($cactioncomm->code)) {
1181  $this->type_code = $cactioncomm->code;
1182  }
1183  }
1184  }
1185 
1186  $code = $this->code;
1187  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
1188  $code = $this->type_code;
1189  }
1190 
1191  $this->db->begin();
1192 
1193  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm";
1194  $sql .= " SET percent = '".$this->db->escape($this->percentage)."'";
1195  $sql .= ", fk_action = ".(int) $this->type_id;
1196  $sql .= ", code = " . ($code ? "'".$this->db->escape($code)."'" : "null");
1197  $sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "null");
1198  $sql .= ", datep = ".(strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : 'null');
1199  $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null');
1200  $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated
1201  $sql .= ", note = '".$this->db->escape($this->note_private)."'";
1202  $sql .= ", fk_project =".($this->fk_project > 0 ? ((int) $this->fk_project) : "null");
1203  $sql .= ", fk_soc =".($socid > 0 ? ((int) $socid) : "null");
1204  $sql .= ", fk_contact =".($contactid > 0 ? ((int) $contactid) : "null");
1205  $sql .= ", priority = '".$this->db->escape($this->priority)."'";
1206  $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'";
1207  $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null");
1208  $sql .= ", transparency = '".$this->db->escape($this->transparency)."'";
1209  $sql .= ", fk_user_mod = ".((int) $user->id);
1210  $sql .= ", fk_user_action = ".($userownerid > 0 ? ((int) $userownerid) : "null");
1211  $sql .= ", fk_user_done = ".($userdoneid > 0 ? ((int) $userdoneid) : "null");
1212  if (!empty($this->fk_element)) {
1213  $sql .= ", fk_element=".($this->fk_element ? ((int) $this->fk_element) : "null");
1214  }
1215  if (!empty($this->elementtype)) {
1216  $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null");
1217  }
1218  if (!empty($this->num_vote)) {
1219  $sql .= ", num_vote=".($this->num_vote ? (int) $this->num_vote : null);
1220  }
1221  if (!empty($this->event_paid)) {
1222  $sql .= ", event_paid=".($this->event_paid ? (int) $this->event_paid : 0);
1223  }
1224  if (!empty($this->status)) {
1225  $sql .= ", status=".($this->status ? (int) $this->status : 0);
1226  }
1227  $sql .= " WHERE id=".((int) $this->id);
1228 
1229  dol_syslog(get_class($this)."::update", LOG_DEBUG);
1230  if ($this->db->query($sql)) {
1231  $action = 'update';
1232 
1233  // Actions on extra fields
1234  if (!$error) {
1235  $result = $this->insertExtraFields();
1236  if ($result < 0) {
1237  $error++;
1238  }
1239  }
1240 
1241  // Now insert assignedusers
1242  if (!$error) {
1243  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".((int) $this->id)." AND element_type = 'user'";
1244  $resql = $this->db->query($sql);
1245 
1246  $already_inserted = array();
1247  foreach ($this->userassigned as $key => $val) {
1248  if (!is_array($val)) { // For backward compatibility when val=id
1249  $val = array('id'=>$val);
1250  }
1251  if (!empty($already_inserted[$val['id']])) {
1252  continue;
1253  }
1254 
1255  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
1256  $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'])).")";
1257 
1258  $resql = $this->db->query($sql);
1259  if (!$resql) {
1260  $error++;
1261  $this->errors[] = $this->db->lasterror();
1262  } else {
1263  $already_inserted[$val['id']] = true;
1264  }
1265  //var_dump($sql);exit;
1266  }
1267  }
1268 
1269  if (!$error) {
1270  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".((int) $this->id)." AND element_type = 'socpeople'";
1271  $resql = $this->db->query($sql);
1272 
1273  if (!empty($this->socpeopleassigned)) {
1274  $already_inserted = array();
1275  foreach (array_keys($this->socpeopleassigned) as $key => $val) {
1276  if (!is_array($val)) { // For backward compatibility when val=id
1277  $val = array('id'=>$val);
1278  }
1279  if (!empty($already_inserted[$val['id']])) {
1280  continue;
1281  }
1282 
1283  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
1284  $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $val['id']).", 0, 0, 0)";
1285 
1286  $resql = $this->db->query($sql);
1287  if (!$resql) {
1288  $error++;
1289  $this->errors[] = $this->db->lasterror();
1290  } else {
1291  $already_inserted[$val['id']] = true;
1292  }
1293  }
1294  }
1295  }
1296 
1297  if (!$error && !$notrigger) {
1298  // Call trigger
1299  $result = $this->call_trigger('ACTION_MODIFY', $user);
1300  if ($result < 0) {
1301  $error++;
1302  }
1303  // End call triggers
1304  }
1305 
1306  if (!$error) {
1307  $this->db->commit();
1308  return 1;
1309  } else {
1310  $this->db->rollback();
1311  dol_syslog(get_class($this)."::update ".join(',', $this->errors), LOG_ERR);
1312  return -2;
1313  }
1314  } else {
1315  $this->db->rollback();
1316  $this->error = $this->db->lasterror();
1317  return -1;
1318  }
1319  }
1320 
1334  public function getActions($socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0)
1335  {
1336  global $conf, $langs, $hookmanager;
1337 
1338  $resarray = array();
1339 
1340  dol_syslog(get_class()."::getActions", LOG_DEBUG);
1341 
1342  // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
1343  if (!is_object($hookmanager)) {
1344  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1345  $hookmanager = new HookManager($this->db);
1346  }
1347  $hookmanager->initHooks(array('agendadao'));
1348 
1349  $sql = "SELECT a.id";
1350  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
1351  // Fields from hook
1352  $parameters = array('sql' => &$sql, 'socid' => $socid, 'fk_element' => $fk_element, 'elementtype' => $elementtype);
1353  $reshook = $hookmanager->executeHooks('getActionsListFrom', $parameters); // Note that $action and $object may have been modified by hook
1354  if (!empty($hookmanager->resPrint)) {
1355  $sql.= $hookmanager->resPrint;
1356  }
1357  $sql .= " WHERE a.entity IN (".getEntity('agenda').")";
1358  if (!empty($socid)) {
1359  $sql .= " AND a.fk_soc = ".((int) $socid);
1360  }
1361  if (!empty($elementtype)) {
1362  if ($elementtype == 'project') {
1363  $sql .= ' AND a.fk_project = '.((int) $fk_element);
1364  } elseif ($elementtype == 'contact') {
1365  $sql .= ' AND a.id IN';
1366  $sql .= " (SELECT fk_actioncomm FROM ".MAIN_DB_PREFIX."actioncomm_resources WHERE";
1367  $sql .= " element_type = 'socpeople' AND fk_element = ".((int) $fk_element).')';
1368  } else {
1369  $sql .= " AND a.fk_element = ".((int) $fk_element)." AND a.elementtype = '".$this->db->escape($elementtype)."'";
1370  }
1371  }
1372  if (!empty($filter)) {
1373  $sql .= $filter;
1374  }
1375  // Fields where hook
1376  $parameters = array('sql' => &$sql, 'socid' => $socid, 'fk_element' => $fk_element, 'elementtype' => $elementtype);
1377  $reshook = $hookmanager->executeHooks('getActionsListWhere', $parameters); // Note that $action and $object may have been modified by hook
1378  if (!empty($hookmanager->resPrint)) {
1379  $sql.= $hookmanager->resPrint;
1380  }
1381  if ($sortorder && $sortfield) {
1382  $sql .= $this->db->order($sortfield, $sortorder);
1383  }
1384  $sql .= $this->db->plimit($limit, 0);
1385 
1386  $resql = $this->db->query($sql);
1387  if ($resql) {
1388  $num = $this->db->num_rows($resql);
1389 
1390  if ($num) {
1391  for ($i = 0; $i < $num; $i++) {
1392  $obj = $this->db->fetch_object($resql);
1393  $actioncommstatic = new ActionComm($this->db);
1394  $actioncommstatic->fetch($obj->id);
1395  $resarray[$i] = $actioncommstatic;
1396  }
1397  }
1398  $this->db->free($resql);
1399  return $resarray;
1400  } else {
1401  return $this->db->lasterror();
1402  }
1403  }
1404 
1405  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1413  public function load_board($user, $load_state_board = 0)
1414  {
1415  // phpcs:enable
1416  global $conf, $langs;
1417 
1418  if (empty($load_state_board)) {
1419  $sql = "SELECT a.id, a.datep as dp";
1420  } else {
1421  $this->nb = array();
1422  $sql = "SELECT count(a.id) as nb";
1423  }
1424  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
1425  if (!$user->hasRight('societe', 'client', 'voir') && !$user->socid) {
1426  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc";
1427  }
1428  if (!$user->hasRight('agenda', 'allactions', 'read')) {
1429  $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);
1430  }
1431  $sql .= " WHERE 1 = 1";
1432  if (empty($load_state_board)) {
1433  $sql .= " AND a.percent >= 0 AND a.percent < 100";
1434  }
1435  $sql .= " AND a.entity IN (".getEntity('agenda').")";
1436  if (!$user->hasRight('societe', 'client', 'voir') && !$user->socid) {
1437  $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".((int) $user->id).")";
1438  }
1439  if ($user->socid) {
1440  $sql .= " AND a.fk_soc = ".((int) $user->socid);
1441  }
1442  if (!$user->hasRight('agenda', 'allactions', 'read')) {
1443  $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);
1444  $sql .= " OR ar.fk_element = ".((int) $user->id);
1445  $sql .= ")";
1446  }
1447 
1448  $resql = $this->db->query($sql);
1449  if ($resql) {
1450  if (empty($load_state_board)) {
1451  $agenda_static = new ActionComm($this->db);
1452  $response = new WorkboardResponse();
1453  $response->warning_delay = $conf->agenda->warning_delay / 60 / 60 / 24;
1454  $response->label = $langs->trans("ActionsToDo");
1455  $response->labelShort = $langs->trans("ActionsToDoShort");
1456  $response->url = DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&actioncode=0&status=todo&mainmenu=agenda';
1457  if ($user->hasRight("agenda", "allactions", "read")) {
1458  $response->url .= '&filtert=-1';
1459  }
1460  $response->img = img_object('', "action", 'class="inline-block valigntextmiddle"');
1461  }
1462  // This assignment in condition is not a bug. It allows walking the results.
1463  while ($obj = $this->db->fetch_object($resql)) {
1464  if (empty($load_state_board)) {
1465  $response->nbtodo++;
1466  $agenda_static->datep = $this->db->jdate($obj->dp);
1467  if ($agenda_static->hasDelay()) {
1468  $response->nbtodolate++;
1469  }
1470  } else {
1471  $this->nb["actionscomm"] = $obj->nb;
1472  }
1473  }
1474 
1475  $this->db->free($resql);
1476  if (empty($load_state_board)) {
1477  return $response;
1478  } else {
1479  return 1;
1480  }
1481  } else {
1482  dol_print_error($this->db);
1483  $this->error = $this->db->error();
1484  return -1;
1485  }
1486  }
1487 
1488 
1495  public function info($id)
1496  {
1497  $sql = 'SELECT ';
1498  $sql .= ' a.id,';
1499  $sql .= ' datec,';
1500  $sql .= ' tms as datem,';
1501  $sql .= ' fk_user_author,';
1502  $sql .= ' fk_user_mod';
1503  $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a';
1504  $sql .= ' WHERE a.id = '.((int) $id);
1505 
1506  dol_syslog(get_class($this)."::info", LOG_DEBUG);
1507  $result = $this->db->query($sql);
1508  if ($result) {
1509  if ($this->db->num_rows($result)) {
1510  $obj = $this->db->fetch_object($result);
1511 
1512  $this->id = $obj->id;
1513 
1514  $this->user_creation_id = $obj->fk_user_author;
1515  $this->user_modification_id = $obj->fk_user_mod;
1516  $this->date_creation = $this->db->jdate($obj->datec);
1517  $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1518  }
1519  $this->db->free($result);
1520  } else {
1521  dol_print_error($this->db);
1522  }
1523  }
1524 
1525 
1533  public function getLibStatut($mode, $hidenastatus = 0)
1534  {
1535  return $this->LibStatut($this->percentage, $mode, $hidenastatus, $this->datep);
1536  }
1537 
1538  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1548  public function LibStatut($percent, $mode, $hidenastatus = 0, $datestart = '')
1549  {
1550  // phpcs:enable
1551  global $langs;
1552 
1553  $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable');
1554  if ($percent == -1 && !$hidenastatus) {
1555  $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable');
1556  } elseif ($percent == 0) {
1557  $labelStatus = $langs->transnoentitiesnoconv('StatusActionToDo').' (0%)';
1558  } elseif ($percent > 0 && $percent < 100) {
1559  $labelStatus = $langs->transnoentitiesnoconv('StatusActionInProcess').' ('.$percent.'%)';
1560  } elseif ($percent >= 100) {
1561  $labelStatus = $langs->transnoentitiesnoconv('StatusActionDone').' (100%)';
1562  }
1563 
1564  $labelStatusShort = $langs->transnoentitiesnoconv('StatusNotApplicable');
1565  if ($percent == -1 && !$hidenastatus) {
1566  $labelStatusShort = $langs->trans('NA');
1567  } elseif ($percent == 0) {
1568  $labelStatusShort = '0%';
1569  } elseif ($percent > 0 && $percent < 100) {
1570  $labelStatusShort = $percent.'%';
1571  } elseif ($percent >= 100) {
1572  $labelStatusShort = '100%';
1573  }
1574 
1575  $statusType = 'status9';
1576  if ($percent == -1 && !$hidenastatus) {
1577  $statusType = 'status9';
1578  }
1579  if ($percent == 0) {
1580  $statusType = 'status1';
1581  }
1582  if ($percent > 0 && $percent < 100) {
1583  $statusType = 'status3';
1584  }
1585  if ($percent >= 100) {
1586  $statusType = 'status6';
1587  }
1588 
1589  return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1590  }
1591 
1598  public function getTooltipContentArray($params)
1599  {
1600  global $conf, $langs, $user;
1601  $langs->load('agenda');
1602 
1603  $datas = array();
1604  $nofetch = !empty($params['nofetch']);
1605 
1606  // Set label of type
1607  $labeltype = '';
1608  if ($this->type_code) {
1609  $langs->load("commercial");
1610  $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label;
1611  }
1612  if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1613  if ($this->type_code != 'AC_OTH_AUTO') {
1614  $labeltype = $langs->trans('ActionAC_MANUAL');
1615  }
1616  }
1617 
1618  $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans('Action').'</u>';
1619  if (!empty($this->ref)) {
1620  $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
1621  }
1622  if (!empty($this->label)) {
1623  $datas['title'] = '<br><b>'.$langs->trans('Title').':</b> '.dol_escape_htmltag($this->label);
1624  }
1625  if (!empty($labeltype)) {
1626  $datas['labeltype'] = '<br><b>'.$langs->trans('Type').':</b> '.dol_escape_htmltag($labeltype);
1627  }
1628  if (!empty($this->location)) {
1629  $datas['location'] = '<br><b>'.$langs->trans('Location').':</b> '.dol_escape_htmltag($this->location);
1630  }
1631  if (isset($this->transparency)) {
1632  $datas['transparency'] = '<br><b>'.$langs->trans('Busy').':</b> '.yn($this->transparency);
1633  }
1634  if (!empty($this->email_msgid)) {
1635  $langs->load("mails");
1636  $datas['space'] = '<br>';
1637  // $datas['email'] = '<br><b>'.img_picto('', 'email').' '.$langs->trans("Email").'</b>';
1638  $datas['mailtopic'] = '<br><b>'.$langs->trans('MailTopic').':</b> '.dol_escape_htmltag($this->email_subject);
1639  $datas['mailfrom'] = '<br><b>'.$langs->trans('MailFrom').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_from);
1640  $datas['mailto'] = '<br><b>'.$langs->trans('MailTo').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_to);
1641  if (!empty($this->email_tocc)) {
1642  $datas['mailcc'] = '<br><b>'.$langs->trans('MailCC').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_tocc);
1643  }
1644  /* Disabled because bcc must remain by defintion not visible
1645  if (!empty($this->email_tobcc)) {
1646  $datas['mailccc'] = '<br><b>'.$langs->trans('MailCCC').':</b> '.$this->email_tobcc;
1647  } */
1648  }
1649  if (!empty($this->note_private)) {
1650  $datas['description'] = '<br><b>'.$langs->trans('Description').':</b><br>';
1651  // Try to limit length of content
1652  $texttoshow = dolGetFirstLineOfText($this->note_private, 10);
1653  // Restrict height of content into the tooltip
1654  $datas['note'] = '<div class="tenlinesmax">';
1655  $datas['note'] .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
1656  $datas['note'] .= '</div>';
1657  }
1658  // show categories for this record only in ajax to not overload lists
1659  if (isModEnabled('categorie') && !$nofetch) {
1660  require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1661  $form = new Form($this->db);
1662  $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACTIONCOMM, 1);
1663  }
1664 
1665  return $datas;
1666  }
1667 
1681  public function getNomUrl($withpicto = 0, $maxlength = 0, $classname = '', $option = '', $overwritepicto = 0, $notooltip = 0, $save_lastsearch_value = -1)
1682  {
1683  global $conf, $langs, $user, $hookmanager, $action;
1684 
1685  if (!empty($conf->dol_no_mouse_hover)) {
1686  $notooltip = 1; // Force disable tooltips
1687  }
1688 
1689  $canread = 0;
1690  if ($user->hasRight('agenda', 'myactions', 'read') && ($this->authorid == $user->id || $this->userownerid == $user->id)) {
1691  $canread = 1; // Can read my event
1692  }
1693  if ($user->hasRight('agenda', 'myactions', 'read') && array_key_exists($user->id, $this->userassigned)) {
1694  $canread = 1; // Can read my event i am assigned
1695  }
1696  if ($user->hasRight('agenda', 'allactions', 'read')) {
1697  $canread = 1; // Can read all event of other
1698  }
1699  if (!$canread) {
1700  $option = 'nolink';
1701  }
1702 
1703  $label = $this->label;
1704  if (empty($label)) {
1705  $label = $this->libelle; // For backward compatibility
1706  }
1707 
1708  $result = '';
1709 
1710  // Set label of type
1711  $labeltype = '';
1712  if ($this->type_code) {
1713  $langs->load("commercial");
1714  $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label;
1715  }
1716  if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1717  if ($this->type_code != 'AC_OTH_AUTO') {
1718  $labeltype = $langs->trans('ActionAC_MANUAL');
1719  }
1720  }
1721 
1722  $tooltip = img_picto('', $this->picto).' <u>'.$langs->trans('Action').'</u>';
1723  if (!empty($this->ref)) {
1724  $tooltip .= '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
1725  }
1726  if (!empty($label)) {
1727  $tooltip .= '<br><b>'.$langs->trans('Title').':</b> '.dol_escape_htmltag($label);
1728  }
1729  if (!empty($labeltype)) {
1730  $tooltip .= '<br><b>'.$langs->trans('Type').':</b> '.dol_escape_htmltag($labeltype);
1731  }
1732  if (!empty($this->location)) {
1733  $tooltip .= '<br><b>'.$langs->trans('Location').':</b> '.dol_escape_htmltag($this->location);
1734  }
1735  if (isset($this->transparency)) {
1736  $tooltip .= '<br><b>'.$langs->trans('Busy').':</b> '.yn($this->transparency);
1737  }
1738  if (!empty($this->email_msgid)) {
1739  $langs->load("mails");
1740  $tooltip .= '<br>';
1741  //$tooltip .= '<br><b>'.img_picto('', 'email').' '.$langs->trans("Email").'</b>';
1742  $tooltip .= '<br><b>'.$langs->trans('MailTopic').':</b> '.dol_escape_htmltag($this->email_subject);
1743  $tooltip .= '<br><b>'.$langs->trans('MailFrom').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), !empty($this->email_from) ? $this->email_from : '');
1744  $tooltip .= '<br><b>'.$langs->trans('MailTo').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), !empty($this->email_to) ? $this->email_to : '');
1745  if (!empty($this->email_tocc)) {
1746  $tooltip .= '<br><b>'.$langs->trans('MailCC').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_tocc);
1747  }
1748  /* Disabled because bcc must remain by defintion not visible
1749  if (!empty($this->email_tobcc)) {
1750  $tooltip .= '<br><b>'.$langs->trans('MailCCC').':</b> '.$this->email_tobcc;
1751  } */
1752  }
1753  if (!empty($this->note_private)) {
1754  $tooltip .= '<br><br><b>'.$langs->trans('Description').':</b><br>';
1755  $texttoshow = dolGetFirstLineOfText($this->note_private, 8); // Try to limit length of content
1756  $tooltip .= '<div class="tenlinesmax">'; // Restrict height of content into the tooltip
1757  $tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
1758  $tooltip .= '</div>';
1759  }
1760  $linkclose = '';
1761  $classfortooltip = 'classfortooltip';
1762  $dataparams = '';
1763  if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1764  $params = [
1765  'id' => $this->id,
1766  'objecttype' => $this->element,
1767  'option' => $option,
1768  'nofetch' => 1,
1769  ];
1770  $classfortooltip = 'classforajaxtooltip';
1771  $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1772  $tooltip = '';
1773  }
1774  //if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color)
1775  // $linkclose = ' style="background-color:#'.$this->type_color.'"';
1776  if (empty($notooltip)) {
1777  if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1778  $label = $langs->trans("ShowAction");
1779  $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"';
1780  }
1781  $linkclose .= ($tooltip ? ' title="'.dol_escape_htmltag($tooltip, 1).'"' : ' title="tocomplete"');
1782  $linkclose .= $dataparams.' class="'.$classname.' '.$classfortooltip.'"';
1783  } else {
1784  $linkclose .= ' class="'.$classname.'"';
1785  }
1786 
1787  $url = '';
1788  if ($option == 'birthday') {
1789  $url = DOL_URL_ROOT.'/contact/perso.php?id='.$this->id;
1790  } elseif ($option == 'holiday') {
1791  $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1792  } else {
1793  $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id;
1794  }
1795 
1796  if ($option !== 'nolink') {
1797  // Add param to save lastsearch_values or not
1798  $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1799  if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1800  $add_save_lastsearch_values = 1;
1801  }
1802  if ($add_save_lastsearch_values) {
1803  $url .= '&save_lastsearch_values=1';
1804  }
1805  }
1806 
1807  $linkstart = '<a href="'.$url.'"';
1808  $linkstart .= $linkclose.'>';
1809  $linkend = '</a>';
1810 
1811  if ($option == 'nolink') {
1812  $linkstart = '';
1813  $linkend = '';
1814  }
1815 
1816  if ($withpicto == 2) {
1817  if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1818  $label = $labeltype;
1819  }
1820  $labelshort = '';
1821  } else {
1822  if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && empty($label)) {
1823  $label = $labeltype;
1824  }
1825  if ($maxlength < 0) {
1826  $labelshort = $this->ref;
1827  } else {
1828  $labelshort = dol_trunc($label, $maxlength);
1829  }
1830  }
1831 
1832  if ($withpicto) {
1833  if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) { // Add code into ()
1834  if ($labeltype) {
1835  $label .= (preg_match('/'.preg_quote($labeltype, '/').'/', $label) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')');
1836  }
1837  }
1838  }
1839 
1840  $result .= $linkstart;
1841  if ($withpicto) {
1842  $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);
1843  }
1844  $result .= dol_escape_htmltag($labelshort);
1845  $result .= $linkend;
1846 
1847  global $action;
1848  $hookmanager->initHooks(array('actiondao'));
1849  $parameters = array('id'=>$this->id, 'getnomurl' => &$result);
1850  $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1851  if ($reshook > 0) {
1852  $result = $hookmanager->resPrint;
1853  } else {
1854  $result .= $hookmanager->resPrint;
1855  }
1856 
1857  return $result;
1858  }
1859 
1867  public function getTypePicto($morecss = 'pictofixedwidth paddingright', $titlealt = '')
1868  {
1869  global $conf;
1870 
1871  $imgpicto = '';
1872  if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1873  $color = '';
1874  if ($this->type_color) {
1875  $color = 'style="color: #'.$this->type_color.' !important;"';
1876  }
1877  if ($this->type_picto) {
1878  $imgpicto = img_picto($titlealt, $this->type_picto, '', false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1879  } else {
1880  if ($this->type_code == 'AC_RDV') {
1881  $imgpicto = img_picto($titlealt, 'meeting', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1882  } elseif ($this->type_code == 'AC_TEL') {
1883  $imgpicto = img_picto($titlealt, 'object_phoning', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1884  } elseif ($this->type_code == 'AC_FAX') {
1885  $imgpicto = img_picto($titlealt, 'object_phoning_fax', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1886  } elseif ($this->type_code == 'AC_EMAIL' || $this->type_code == 'AC_EMAIL_IN' || (!empty($this->code) && preg_match('/_SENTBYMAIL/', $this->code))) {
1887  $imgpicto = img_picto($titlealt, 'object_email', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1888  } elseif ($this->type_code == 'AC_INT') {
1889  $imgpicto = img_picto($titlealt, 'object_intervention', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1890  } elseif (!empty($this->code) && preg_match('/^TICKET_MSG/', $this->code)) {
1891  $imgpicto = img_picto($titlealt, 'object_conversation', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1892  } elseif ($this->type != 'systemauto') {
1893  $imgpicto = img_picto($titlealt, 'user-cog', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1894  } else {
1895  $imgpicto = img_picto($titlealt, 'cog', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1896  }
1897  }
1898  } else {
1899  // 2 picto: 1 for auto, 1 for manual
1900  if ($this->type != 'systemauto') {
1901  $imgpicto = img_picto($titlealt, 'user-cog', '', false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1902  } else {
1903  $imgpicto = img_picto($titlealt, 'cog', '', false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1904  }
1905  }
1906 
1907  return $imgpicto;
1908  }
1909 
1910 
1921  public function setCategories($categories)
1922  {
1923  // Handle single category
1924  if (!is_array($categories)) {
1925  $categories = array($categories);
1926  }
1927 
1928  // Get current categories
1929  include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1930  $c = new Categorie($this->db);
1931  $existing = $c->containing($this->id, Categorie::TYPE_ACTIONCOMM, 'id');
1932 
1933  // Diff
1934  if (is_array($existing)) {
1935  $to_del = array_diff($existing, $categories);
1936  $to_add = array_diff($categories, $existing);
1937  } else {
1938  $to_del = array(); // Nothing to delete
1939  $to_add = $categories;
1940  }
1941 
1942  // Process
1943  foreach ($to_del as $del) {
1944  if ($c->fetch($del) > 0) {
1945  $c->del_type($this, Categorie::TYPE_ACTIONCOMM);
1946  }
1947  }
1948  foreach ($to_add as $add) {
1949  if ($c->fetch($add) > 0) {
1950  $c->add_type($this, Categorie::TYPE_ACTIONCOMM);
1951  }
1952  }
1953  return 1;
1954  }
1955 
1956  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1968  public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0)
1969  {
1970  global $hookmanager;
1971 
1972  // phpcs:enable
1973  global $conf, $langs, $dolibarr_main_url_root, $mysoc;
1974 
1975  require_once DOL_DOCUMENT_ROOT."/core/lib/xcal.lib.php";
1976  require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
1977  require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
1978 
1979  dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG);
1980 
1981  // Check parameters
1982  if (empty($format)) {
1983  return -1;
1984  }
1985 
1986  // Clean parameters
1987  if (!$filename) {
1988  $extension = 'vcs';
1989  if ($format == 'ical') {
1990  $extension = 'ics';
1991  }
1992  $filename = $format.'.'.$extension;
1993  }
1994 
1995  // Create dir and define output file (definitive and temporary)
1996  $result = dol_mkdir($conf->agenda->dir_temp);
1997  $outputfile = $conf->agenda->dir_temp.'/'.$filename;
1998 
1999  $result = 0;
2000 
2001  $buildfile = true;
2002  $login = '';
2003  $logina = '';
2004  $logind = '';
2005  $logint = '';
2006 
2007  $now = dol_now();
2008 
2009  if ($cachedelay) {
2010  $nowgmt = dol_now();
2011  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
2012  if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay)) {
2013  dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled");
2014  $buildfile = false;
2015  }
2016  }
2017 
2018  if ($buildfile) {
2019  // Build event array
2020  $eventarray = array();
2021 
2022  $sql = "SELECT a.id,";
2023  $sql .= " a.datep,"; // Start
2024  $sql .= " a.datep2,"; // End
2025  $sql .= " a.durationp,"; // deprecated
2026  $sql .= " a.datec, a.tms as datem,";
2027  $sql .= " a.label, a.code, a.note as note_private, a.fk_action as type_id,";
2028  $sql .= " a.fk_soc,";
2029  $sql .= " a.fk_user_author, a.fk_user_mod,";
2030  $sql .= " a.fk_user_action,";
2031  $sql .= " a.fk_contact, a.percent as percentage,";
2032  $sql .= " a.fk_element, a.elementtype,";
2033  $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
2034  $sql .= " u.firstname, u.lastname, u.email,";
2035  $sql .= " s.nom as socname,";
2036  $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label,";
2037  $sql .= " num_vote, event_paid, a.status";
2038  $sql .= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)";
2039  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export
2040  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
2041 
2042  $parameters = array('filters' => $filters);
2043  $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
2044  $sql .= $hookmanager->resPrint;
2045 
2046  // We must filter on assignement table
2047  if ($filters['logint']) {
2048  $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar";
2049  }
2050  $sql .= " WHERE a.fk_action=c.id";
2051  $sql .= " AND a.entity IN (".getEntity('agenda').")";
2052  foreach ($filters as $key => $value) {
2053  if ($key == 'notolderthan' && $value != '') {
2054  $sql .= " AND a.datep >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'";
2055  }
2056  if ($key == 'year') {
2057  $sql .= " AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'";
2058  }
2059  if ($key == 'id') {
2060  $sql .= " AND a.id=".(is_numeric($value) ? $value : 0);
2061  }
2062  if ($key == 'idfrom') {
2063  $sql .= " AND a.id >= ".(is_numeric($value) ? $value : 0);
2064  }
2065  if ($key == 'idto') {
2066  $sql .= " AND a.id <= ".(is_numeric($value) ? $value : 0);
2067  }
2068  if ($key == 'project') {
2069  $sql .= " AND a.fk_project=".(is_numeric($value) ? $value : 0);
2070  }
2071  if ($key == 'actiontype') {
2072  $sql .= " AND c.type = '".$this->db->escape($value)."'";
2073  }
2074  if ($key == 'notactiontype') {
2075  $sql .= " AND c.type <> '".$this->db->escape($value)."'";
2076  }
2077  // We must filter on assignement table
2078  if ($key == 'logint') {
2079  $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
2080  }
2081  if ($key == 'logina') {
2082  $logina = $value;
2083  $condition = '=';
2084  if (preg_match('/^!/', $logina)) {
2085  $logina = preg_replace('/^!/', '', $logina);
2086  $condition = '<>';
2087  }
2088  $userforfilter = new User($this->db);
2089  $result = $userforfilter->fetch('', $logina);
2090  if ($result > 0) {
2091  $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id;
2092  } elseif ($result < 0 || $condition == '=') {
2093  $sql .= " AND a.fk_user_author = 0";
2094  }
2095  }
2096  if ($key == 'logint') {
2097  $logint = $value;
2098  $condition = '=';
2099  if (preg_match('/^!/', $logint)) {
2100  $logint = preg_replace('/^!/', '', $logint);
2101  $condition = '<>';
2102  }
2103  $userforfilter = new User($this->db);
2104  $result = $userforfilter->fetch('', $logint);
2105  if ($result > 0) {
2106  $sql .= " AND ar.fk_element = ".((int) $userforfilter->id);
2107  } elseif ($result < 0 || $condition == '=') {
2108  $sql .= " AND ar.fk_element = 0";
2109  }
2110  }
2111  if ($key == 'module') {
2112  $sql .= " AND c.module LIKE '%".$this->db->escape($value)."'";
2113  }
2114  if ($key == 'status') {
2115  $sql .= " AND a.status =".((int) $value);
2116  }
2117  }
2118 
2119  $sql .= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import
2120 
2121  $parameters = array('filters' => $filters);
2122  $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
2123  $sql .= $hookmanager->resPrint;
2124 
2125  $sql .= " ORDER by datep";
2126  //print $sql;exit;
2127 
2128  dol_syslog(get_class($this)."::build_exportfile select events", LOG_DEBUG);
2129  $resql = $this->db->query($sql);
2130  if ($resql) {
2131  $diff = 0;
2132  while ($obj = $this->db->fetch_object($resql)) {
2133  $qualified = true;
2134 
2135  // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author'
2136  $event = array();
2137  $event['uid'] = 'dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"];
2138  $event['type'] = $type;
2139 
2140  $datestart = $this->db->jdate($obj->datep) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2141 
2142  // fix for -> Warning: A non-numeric value encountered
2143  if (is_numeric($this->db->jdate($obj->datep2))) {
2144  $dateend = $this->db->jdate($obj->datep2) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2145  } else {
2146  // use start date as fall-back to avoid pb with empty end date on ICS readers
2147  $dateend = $datestart;
2148  }
2149 
2150  $duration = ($datestart && $dateend) ? ($dateend - $datestart) : 0;
2151  $event['summary'] = $obj->label.($obj->socname ? " (".$obj->socname.")" : "");
2152 
2153  $event['desc'] = $obj->note_private;
2154  $event['startdate'] = $datestart;
2155  $event['enddate'] = $dateend; // Not required with type 'journal'
2156  $event['duration'] = $duration; // Not required with type 'journal'
2157  $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2158  $event['priority'] = $obj->priority;
2159  $event['fulldayevent'] = $obj->fulldayevent;
2160  $event['location'] = $obj->location;
2161  $event['transparency'] = (($obj->transparency > 0) ? 'OPAQUE' : 'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy)
2162  $event['category'] = $obj->type_label;
2163  $event['email'] = $obj->email;
2164  // Define $urlwithroot
2165  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2166  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
2167  //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
2168  $url = $urlwithroot.'/comm/action/card.php?id='.$obj->id;
2169  $event['url'] = $url;
2170  $event['created'] = $this->db->jdate($obj->datec) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2171  $event['modified'] = $this->db->jdate($obj->datem) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2172  $event['num_vote'] = $this->num_vote;
2173  $event['event_paid'] = $this->event_paid;
2174  $event['status'] = $this->status;
2175 
2176  // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties
2177  $this->id = $obj->id;
2178  $this->fetch_userassigned(false);
2179 
2180  $assignedUserArray = array();
2181 
2182  foreach ($this->userassigned as $key => $value) {
2183  $assignedUser = new User($this->db);
2184  $assignedUser->fetch($value['id']);
2185 
2186  $assignedUserArray[$key] = $assignedUser;
2187  }
2188 
2189  $event['assignedUsers'] = $assignedUserArray;
2190 
2191  if ($qualified && $datestart) {
2192  $eventarray[] = $event;
2193  }
2194  $diff++;
2195  }
2196 
2197  $parameters = array('filters' => $filters, 'eventarray' => &$eventarray);
2198  $reshook = $hookmanager->executeHooks('addMoreEventsExport', $parameters); // Note that $action and $object may have been modified by hook
2199  if ($reshook > 0) {
2200  $eventarray = $hookmanager->resArray;
2201  }
2202  } else {
2203  $this->error = $this->db->lasterror();
2204  return -1;
2205  }
2206 
2207  if ($exportholiday == 1) {
2208  $langs->load("holiday");
2209  $title = $langs->transnoentities("Holidays");
2210 
2211  $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";
2212  $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u";
2213  $sql .= " WHERE u.rowid = x.fk_user";
2214  $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user)
2215  $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved)
2216 
2217  $resql = $this->db->query($sql);
2218  if ($resql) {
2219  $num = $this->db->num_rows($resql);
2220  $i = 0;
2221 
2222  while ($i < $num) {
2223  $obj = $this->db->fetch_object($resql);
2224  $event = array();
2225 
2226  if ($obj->halfday == 1) {
2227  $event['fulldayevent'] = false;
2228 
2229  $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2230  $timestampEnd = dol_stringtotime($obj->date_end." 12:00:00", 0);
2231  } elseif ($obj->halfday == -1) {
2232  $event['fulldayevent'] = false;
2233 
2234  $timestampStart = dol_stringtotime($obj->date_start." 12:00:00", 0);
2235  $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2236  } else {
2237  $event['fulldayevent'] = true;
2238 
2239  $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2240  $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2241  }
2242 
2243  if (getDolGlobalString('AGENDA_EXPORT_FIX_TZ')) {
2244  $timestampStart = $timestampStart - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2245  $timestampEnd = $timestampEnd - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2246  }
2247 
2248  $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2249  $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
2250  $url = $urlwithroot.'/holiday/card.php?id='.$obj->rowid;
2251 
2252  $event['uid'] = 'dolibarrholiday-'.$this->db->database_name.'-'.$obj->rowid."@".$_SERVER["SERVER_NAME"];
2253  $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2254  $event['type'] = 'event';
2255  $event['category'] = "Holiday";
2256  $event['transparency'] = 'OPAQUE';
2257  $event['email'] = $obj->email;
2258  $event['created'] = $timestampStart;
2259  $event['modified'] = $timestampStart;
2260  $event['startdate'] = $timestampStart;
2261  $event['enddate'] = $timestampEnd;
2262  $event['duration'] = $timestampEnd - $timestampStart;
2263  $event['url'] = $url;
2264 
2265  if ($obj->status == 2) {
2266  // 2 = leave wait for approval
2267  $event['summary'] = $title." - ".$obj->lastname." (wait for approval)";
2268  } else {
2269  // 3 = leave approved
2270  $event['summary'] = $title." - ".$obj->lastname;
2271  }
2272 
2273  $eventarray[] = $event;
2274 
2275  $i++;
2276  }
2277  }
2278  }
2279 
2280  $langs->load("agenda");
2281 
2282  // Define title and desc
2283  $more = '';
2284  if ($login) {
2285  $more = $langs->transnoentities("User").' '.$login;
2286  }
2287  if ($logina) {
2288  $more = $langs->transnoentities("ActionsAskedBy").' '.$logina;
2289  }
2290  if ($logint) {
2291  $more = $langs->transnoentities("ActionsToDoBy").' '.$logint;
2292  }
2293  if ($logind) {
2294  $more = $langs->transnoentities("ActionsDoneBy").' '.$logind;
2295  }
2296  if ($more) {
2297  $title = 'Dolibarr actions '.$mysoc->name.' - '.$more;
2298  $desc = $more;
2299  $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2300  } else {
2301  $title = 'Dolibarr actions '.$mysoc->name;
2302  $desc = $langs->transnoentities('ListOfActions');
2303  $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2304  }
2305 
2306  // Create temp file
2307  $outputfiletmp = tempnam($conf->agenda->dir_temp, 'tmp'); // Temporary file (allow call of function by different threads
2308  dolChmod($outputfiletmp);
2309 
2310  // Write file
2311  if ($format == 'vcal') {
2312  $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2313  } elseif ($format == 'ical') {
2314  $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2315  } elseif ($format == 'rss') {
2316  $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp);
2317  }
2318 
2319  if ($result >= 0) {
2320  if (dol_move($outputfiletmp, $outputfile, 0, 1, 0, 0)) {
2321  $result = 1;
2322  } else {
2323  $this->error = 'Failed to rename '.$outputfiletmp.' into '.$outputfile;
2324  dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR);
2325  dol_delete_file($outputfiletmp, 0, 1);
2326  $result = -1;
2327  }
2328  } else {
2329  dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR);
2330  dol_delete_file($outputfiletmp, 0, 1);
2331  $langs->load("errors");
2332  $this->error = $langs->trans("ErrorFailToCreateFile", $outputfile);
2333  }
2334  }
2335 
2336  return $result;
2337  }
2338 
2346  public function initAsSpecimen()
2347  {
2348  global $user;
2349 
2350  $now = dol_now();
2351 
2352  // Initialise parametres
2353  $this->id = 0;
2354  $this->specimen = 1;
2355 
2356  $this->type_code = 'AC_OTH';
2357  $this->code = 'AC_SPECIMEN_CODE';
2358  $this->label = 'Label of event Specimen';
2359  $this->datec = $now;
2360  $this->datem = $now;
2361  $this->datep = $now;
2362  $this->datef = $now;
2363  $this->fulldayevent = 0;
2364  $this->percentage = 0;
2365  $this->status = 0;
2366  $this->location = 'Location';
2367  $this->transparency = 1; // 1 means opaque
2368  $this->priority = 1;
2369  //$this->note_public = "This is a 'public' note.";
2370  $this->note_private = "This is a 'private' note.";
2371 
2372  $this->userownerid = $user->id;
2373  $this->userassigned[$user->id] = array('id'=>$user->id, 'transparency'=> 1);
2374  return 1;
2375  }
2376 
2385  public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2386  {
2387  $tables = array(
2388  'actioncomm'
2389  );
2390 
2391  return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
2392  }
2393 
2402  public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id)
2403  {
2404  $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id);
2405  // using $dbs, not $this->db because function is static
2406  if (!$dbs->query($sql)) {
2407  //$this->errors = $dbs->lasterror();
2408  return false;
2409  }
2410 
2411  return true;
2412  }
2413 
2419  public function hasDelay()
2420  {
2421  global $conf;
2422 
2423  $now = dol_now();
2424 
2425  return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay));
2426  }
2427 
2428 
2437  public function loadReminders($type = '', $fk_user = 0, $onlypast = true)
2438  {
2439  global $conf, $langs, $user;
2440 
2441  $error = 0;
2442 
2443  $this->reminders = array();
2444 
2445  //Select all action comm reminders for event
2446  $sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user, fk_email_template, lasterror";
2447  $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2448  $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
2449  if ($onlypast) {
2450  $sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'";
2451  }
2452  if ($type) {
2453  $sql .= " AND typeremind = '".$this->db->escape($type)."'";
2454  }
2455  if ($fk_user > 0) {
2456  $sql .= " AND fk_user = ".((int) $fk_user);
2457  }
2458  if (!getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
2459  $sql .= " AND typeremind <> 'email'";
2460  }
2461  if (!getDolGlobalString('AGENDA_REMINDER_BROWSER')) {
2462  $sql .= " AND typeremind <> 'browser'";
2463  }
2464 
2465  $sql .= $this->db->order("dateremind", "ASC");
2466  $resql = $this->db->query($sql);
2467 
2468  if ($resql) {
2469  while ($obj = $this->db->fetch_object($resql)) {
2470  $tmpactioncommreminder = new ActionCommReminder($this->db);
2471  $tmpactioncommreminder->id = $obj->id;
2472  $tmpactioncommreminder->typeremind = $obj->typeremind;
2473  $tmpactioncommreminder->dateremind = $obj->dateremind;
2474  $tmpactioncommreminder->offsetvalue = $obj->offsetvalue;
2475  $tmpactioncommreminder->offsetunit = $obj->offsetunit;
2476  $tmpactioncommreminder->status = $obj->status;
2477  $tmpactioncommreminder->fk_user = $obj->fk_user;
2478  $tmpactioncommreminder->fk_email_template = $obj->fk_email_template;
2479  $tmpactioncommreminder->lasterror = $obj->lasterror;
2480 
2481  $this->reminders[$obj->id] = $tmpactioncommreminder;
2482  }
2483  } else {
2484  $this->error = $this->db->lasterror();
2485  $error++;
2486  }
2487 
2488  return count($this->reminders);
2489  }
2490 
2491 
2498  public function sendEmailsReminder()
2499  {
2500  global $conf, $langs, $user;
2501 
2502  $error = 0;
2503  $this->output = '';
2504  $this->error = '';
2505  $nbMailSend = 0;
2506  $errorsMsg = array();
2507 
2508  if (!isModEnabled('agenda')) { // Should not happen. If module disabled, cron job should not be visible.
2509  $langs->load("agenda");
2510  $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2511  return 0;
2512  }
2513  if (!getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
2514  $langs->load("agenda");
2515  $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2516  return 0;
2517  }
2518 
2519  $now = dol_now();
2520  $actionCommReminder = new ActionCommReminder($this->db);
2521 
2522  dol_syslog(__METHOD__." start", LOG_INFO);
2523 
2524  $this->db->begin();
2525 
2526  //Select all action comm reminders
2527  $sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2528  $sql .= " WHERE typeremind = 'email'";
2529  $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.
2530  $sql .= " AND dateremind <= '".$this->db->idate($now)."'";
2531  $sql .= " AND entity IN (".getEntity('actioncomm').")";
2532  $sql .= $this->db->order("dateremind", "ASC");
2533  $resql = $this->db->query($sql);
2534 
2535  if ($resql) {
2536  require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2537  $formmail = new FormMail($this->db);
2538 
2539  while ($obj = $this->db->fetch_object($resql)) {
2540  $res = $actionCommReminder->fetch($obj->id);
2541  if ($res < 0) {
2542  $error++;
2543  $errorsMsg[] = "Failed to load invoice ActionComm Reminder";
2544  }
2545 
2546  if (!$error) {
2547  //Select email template
2548  $arraymessage = $formmail->getEMailTemplate($this->db, 'actioncomm_send', $user, $langs, (!empty($actionCommReminder->fk_email_template)) ? $actionCommReminder->fk_email_template : -1, 1);
2549 
2550  // Load event
2551  $res = $this->fetch($actionCommReminder->fk_actioncomm);
2552  if ($res > 0) {
2553  // PREPARE EMAIL
2554  $errormesg = '';
2555 
2556  // Make substitution in email content
2557  $substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this);
2558 
2559  complete_substitutions_array($substitutionarray, $langs, $this);
2560 
2561  // Content
2562  $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
2563 
2564  //Topic
2565  $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder'));
2566 
2567  // Recipient
2568  $recipient = new User($this->db);
2569  $res = $recipient->fetch($actionCommReminder->fk_user);
2570  if ($res > 0) {
2571  if (!empty($recipient->email)) {
2572  $to = $recipient->email;
2573  } else {
2574  $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user.";
2575  $error++;
2576  }
2577  } else {
2578  $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user;
2579  $error++;
2580  }
2581 
2582  // Sender
2583  $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
2584  if (empty($from)) {
2585  $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
2586  $error++;
2587  }
2588 
2589  if (!$error) {
2590  // Errors Recipient
2591  $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');
2592 
2593  // Mail Creation
2594  $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
2595 
2596  // Sending Mail
2597  if ($cMailFile->sendfile()) {
2598  $nbMailSend++;
2599  } else {
2600  $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.join(',', $cMailFile->errors);
2601  $error++;
2602  }
2603  }
2604 
2605  if (!$error) {
2606  $actionCommReminder->status = $actionCommReminder::STATUS_DONE;
2607 
2608  $res = $actionCommReminder->update($user);
2609  if ($res < 0) {
2610  $errorsMsg[] = "Failed to update status to done of ActionComm Reminder";
2611  $error++;
2612  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.
2613  }
2614  } else {
2615  $actionCommReminder->status = $actionCommReminder::STATUS_ERROR;
2616  $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1);
2617 
2618  $res = $actionCommReminder->update($user);
2619  if ($res < 0) {
2620  $errorsMsg[] = "Failed to update status to error of ActionComm Reminder";
2621  $error++;
2622  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.
2623  } else {
2624  $errorsMsg[] = $errormesg;
2625  }
2626  }
2627  } else {
2628  $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm;
2629  $error++;
2630  }
2631  }
2632  }
2633  } else {
2634  $error++;
2635  }
2636 
2637  if (!$error) {
2638  // Delete also very old past events (we do not keep more than 1 month record in past)
2639  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2640  $sql .= " WHERE dateremind < '".$this->db->idate($now - (3600 * 24 * 32))."'";
2641  $sql .= " AND status = ".((int) $actionCommReminder::STATUS_DONE);
2642  $resql = $this->db->query($sql);
2643 
2644  if (!$resql) {
2645  $errorsMsg[] = 'Failed to delete old reminders';
2646  //$error++; // If this fails, we must not rollback other SQL requests already done. Never mind.
2647  }
2648  }
2649 
2650  if (!$error) {
2651  $this->output = 'Nb of emails sent : '.$nbMailSend;
2652  $this->db->commit();
2653 
2654  dol_syslog(__METHOD__." end - ".$this->output, LOG_INFO);
2655 
2656  return 0;
2657  } else {
2658  $this->db->commit(); // We commit also on error, to have the error message recorded.
2659  $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error;
2660 
2661  dol_syslog(__METHOD__." end - ".$this->error, LOG_INFO);
2662 
2663  return $error;
2664  }
2665  }
2666 
2675  public function updatePercent($id, $percent, $usermodid = 0)
2676  {
2677  $this->db->begin();
2678 
2679  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm ";
2680  $sql .= " SET percent = ".(int) $percent;
2681  if ($usermodid > 0) {
2682  $sql .= ", fk_user_mod = ".$usermodid;
2683  }
2684  $sql .= " WHERE id = ".((int) $id);
2685 
2686  if ($this->db->query($sql)) {
2687  $this->db->commit();
2688  return 1;
2689  } else {
2690  $this->db->rollback();
2691  $this->error = $this->db->lasterror();
2692  return -1;
2693  }
2694  }
2695 }
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Definition: security.php:604
$object ref
Definition: info.php:79
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.
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...
getTypePicto($morecss='pictofixedwidth paddingright', $titlealt='')
Return Picto of type of event.
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') &&!getDolGlobalString('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') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&!getDolGlobalString('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:591
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:423
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:610
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array())
Move a file into another name.
Definition: files.lib.php:949
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:600
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:1358
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 a Dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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:121
print *****$script_file(".$version.") pid code
! Closing after partial payment: discount_vat, badsupplier, abandon ! Closing when no payment: replac...
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