dolibarr  7.0.0-beta
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@capnetworks.com>
5  * Copyright (C) 2011-2017 Juanjo Menent <jmenent@2byte.es>
6  * Copyright (C) 2015 Marcos GarcĂ­a <marcosgdf@gmail.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
27 require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
28 require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
29 
30 
34 class ActionComm extends CommonObject
35 {
36  public $element='action';
37  public $table_element = 'actioncomm';
38  public $table_rowid = 'id';
39  public $picto='action';
44  public $ismultientitymanaged = 1;
49  public $restrictiononfksoc = 2;
50 
55  var $id;
56 
61  public $ref;
62 
63  var $type_id; // Id into parent table llx_c_actioncomm (used only if option to use type is set)
64  var $type_code; // Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH.
65  var $type; // Label into parent table llx_c_actioncomm (used only if option to use type is set)
66  var $type_color; // Color into parent table llx_c_actioncomm (used only if option to use type is set)
67  var $code; // Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...)
68 
69  var $label;
70 
76  public $libelle;
77 
78  var $datec; // Date creation record (datec)
79  var $datem; // Date modification record (tms)
80 
87  var $author;
88 
95  var $usermod;
96  var $authorid; // Id user that create action
97  var $usermodid; // Id user that modified action
98 
99  var $datep; // Date action start (datep)
100  var $datef; // Date action end (datep2)
101 
106  var $durationp = -1;
107  var $fulldayevent = 0; // 1=Event on full day
108 
114  var $punctual = 1;
115  var $percentage; // Percentage
116  var $location; // Location
117 
118  var $transparency; // Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events)
119  var $priority; // Small int (0 By default)
120 
121  var $userassigned = array(); // Array of user ids
122  var $userownerid; // Id of user owner = fk_user_action into table
123  var $userdoneid; // Id of user done (deprecated)
124 
125  var $socpeopleassigned = array(); // Array of contact ids
126 
127  var $otherassigned = array(); // Array of other contact emails (not user, not contact)
128 
129 
136  var $usertodo;
137 
144  var $userdone;
145 
146  var $socid;
147  var $contactid;
148 
155  var $societe;
156 
163  var $contact;
164 
165  // Properties for links to other objects
166  var $fk_element; // Id of record
167  var $elementtype; // Type of record. This if property ->element of object linked to.
168 
169  // Ical
170  var $icalname;
171  var $icalcolor;
172 
173  var $actions=array();
174 
175  // Fields for emails
176  var $email_msgid;
177  var $email_from;
178  var $email_sender;
179  var $email_to;
180  var $email_tocc;
181  var $email_tobcc;
182  var $email_subject;
183  var $errors_to;
184 
185 
191  public function __construct(DoliDB $db)
192  {
193  $this->db = $db;
194 
195  $this->societe = new stdClass(); // deprecated
196  $this->contact = new stdClass(); // deprecated
197  }
198 
207  public function create(User $user, $notrigger = 0)
208  {
209  global $langs,$conf,$hookmanager;
210 
211  $error=0;
212  $now=dol_now();
213 
214  // Check parameters
215  if (empty($this->userownerid))
216  {
217  dol_syslog("You tried to create an event but mandatory property ownerid was not defined", LOG_WARNING);
218  $this->errors[]='ErrorPropertyUserowneridNotDefined';
219  return -1;
220  }
221 
222  // Clean parameters
223  $this->label=dol_trunc(trim($this->label),128);
224  $this->location=dol_trunc(trim($this->location),128);
225  $this->note=dol_htmlcleanlastbr(trim($this->note));
226  if (empty($this->percentage)) $this->percentage = 0;
227  if (empty($this->priority) || ! is_numeric($this->priority)) $this->priority = 0;
228  if (empty($this->fulldayevent)) $this->fulldayevent = 0;
229  if (empty($this->punctual)) $this->punctual = 0;
230  if (empty($this->transparency)) $this->transparency = 0;
231  if ($this->percentage > 100) $this->percentage = 100;
232  //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date;
233  if (! empty($this->datep) && ! empty($this->datef)) $this->durationp=($this->datef - $this->datep); // deprecated
234  //if (! empty($this->date) && ! empty($this->dateend)) $this->durationa=($this->dateend - $this->date);
235  if (! empty($this->datep) && ! empty($this->datef) && $this->datep > $this->datef) $this->datef=$this->datep;
236  //if (! empty($this->date) && ! empty($this->dateend) && $this->date > $this->dateend) $this->dateend=$this->date;
237  if (! isset($this->fk_project) || $this->fk_project < 0) $this->fk_project = 0;
238  if ($this->elementtype=='facture') $this->elementtype='invoice';
239  if ($this->elementtype=='commande') $this->elementtype='order';
240  if ($this->elementtype=='contrat') $this->elementtype='contract';
241 
242  if (! is_array($this->userassigned) && ! empty($this->userassigned)) // For backward compatibility when userassigned was an int instead fo array
243  {
244  $tmpid=$this->userassigned;
245  $this->userassigned=array();
246  $this->userassigned[$tmpid]=array('id'=>$tmpid, 'transparency'=>$this->transparency);
247  }
248 
249  if (is_object($this->contact) && isset($this->contact->id) && $this->contact->id > 0 && ! ($this->contactid > 0)) $this->contactid = $this->contact->id; // For backward compatibility. Using this->contact->xx is deprecated
250 
251 
252  $userownerid=$this->userownerid;
253  $userdoneid=$this->userdoneid;
254 
255  // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...).
256  if (empty($this->userassigned) || count($this->userassigned) == 0 || ! is_array($this->userassigned))
257  $this->userassigned = array($userownerid=>array('id'=>$userownerid, 'transparency'=>$this->transparency));
258 
259  if (! $this->type_id || ! $this->type_code)
260  {
261  $key=empty($this->type_id)?$this->type_code:$this->type_id;
262 
263  // Get id from code
264  $cactioncomm=new CActionComm($this->db);
265  $result=$cactioncomm->fetch($key);
266 
267  if ($result > 0)
268  {
269  $this->type_id=$cactioncomm->id;
270  $this->type_code=$cactioncomm->code;
271  }
272  else if ($result == 0)
273  {
274  $this->error='Failed to get record with id '.$this->type_id.' code '.$this->type_code.' from dictionary "type of events"';
275  return -1;
276  }
277  else
278  {
279  $this->error=$cactioncomm->error;
280  return -1;
281  }
282  }
283 
284  // Check parameters
285  if (! $this->type_id)
286  {
287  $this->error="ErrorWrongParameters";
288  return -1;
289  }
290 
291  $this->db->begin();
292 
293  $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm";
294  $sql.= "(datec,";
295  $sql.= "datep,";
296  $sql.= "datep2,";
297  $sql.= "durationp,"; // deprecated
298  $sql.= "fk_action,";
299  $sql.= "code,";
300  $sql.= "fk_soc,";
301  $sql.= "fk_project,";
302  $sql.= "note,";
303  $sql.= "fk_contact,";
304  $sql.= "fk_user_author,";
305  $sql.= "fk_user_action,";
306  $sql.= "fk_user_done,";
307  $sql.= "label,percent,priority,fulldayevent,location,punctual,";
308  $sql.= "transparency,";
309  $sql.= "fk_element,";
310  $sql.= "elementtype,";
311  $sql.= "entity";
312  $sql.= ") VALUES (";
313  $sql.= "'".$this->db->idate($now)."', ";
314  $sql.= (strval($this->datep)!=''?"'".$this->db->idate($this->datep)."'":"null").", ";
315  $sql.= (strval($this->datef)!=''?"'".$this->db->idate($this->datef)."'":"null").", ";
316  $sql.= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '')?"'".$this->db->escape($this->durationp)."'":"null").", "; // deprecated
317  $sql.= (isset($this->type_id)?$this->type_id:"null").",";
318  $sql.= (isset($this->type_code)?" '".$this->db->escape($this->type_code)."'":"null").", ";
319  $sql.= ((isset($this->socid) && $this->socid > 0) ? $this->socid:"null").", ";
320  $sql.= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project:"null").", ";
321  $sql.= " '".$this->db->escape($this->note)."', ";
322  $sql.= ((isset($this->contactid) && $this->contactid > 0) ? $this->contactid:"null").", ";
323  $sql.= (isset($user->id) && $user->id > 0 ? $user->id:"null").", ";
324  $sql.= ($userownerid>0 ? $userownerid:"null").", ";
325  $sql.= ($userdoneid>0 ? $userdoneid:"null").", ";
326  $sql.= "'".$this->db->escape($this->label)."','".$this->db->escape($this->percentage)."','".$this->db->escape($this->priority)."','".$this->db->escape($this->fulldayevent)."','".$this->db->escape($this->location)."','".$this->db->escape($this->punctual)."', ";
327  $sql.= "'".$this->db->escape($this->transparency)."', ";
328  $sql.= (! empty($this->fk_element)?$this->fk_element:"null").", ";
329  $sql.= (! empty($this->elementtype)?"'".$this->db->escape($this->elementtype)."'":"null").", ";
330  $sql.= $conf->entity;
331  $sql.= ")";
332 
333  dol_syslog(get_class($this)."::add", LOG_DEBUG);
334  $resql=$this->db->query($sql);
335  if ($resql)
336  {
337  $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm","id");
338 
339  // Now insert assignedusers
340  if (! $error)
341  {
342  foreach($this->userassigned as $key => $val)
343  {
344  if (! is_array($val)) // For backward compatibility when val=id
345  {
346  $val=array('id'=>$val);
347  }
348 
349  $sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
350  $sql.=" VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory'])?'0':$val['mandatory']).", ".(empty($val['transparency'])?'0':$val['transparency']).", ".(empty($val['answer_status'])?'0':$val['answer_status']).")";
351 
352  $resql = $this->db->query($sql);
353  if (! $resql)
354  {
355  $error++;
356  $this->errors[]=$this->db->lasterror();
357  }
358  //var_dump($sql);exit;
359  }
360  }
361 
362  if (!$error)
363  {
364  if (!empty($this->socpeopleassigned))
365  {
366  foreach ($this->socpeopleassigned as $id => $Tab)
367  {
368  $sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
369  $sql.=" VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)";
370 
371  $resql = $this->db->query($sql);
372  if (! $resql)
373  {
374  $error++;
375  $this->errors[]=$this->db->lasterror();
376  }
377 
378  }
379  }
380  }
381 
382  if (! $error)
383  {
384  $action='create';
385 
386  // Actions on extra fields (by external module or standard code)
387  // TODO le hook fait double emploi avec le trigger !!
388  $hookmanager->initHooks(array('actioncommdao'));
389  $parameters=array('actcomm'=>$this->id);
390  $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
391  if (empty($reshook))
392  {
393  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
394  {
395  $result=$this->insertExtraFields();
396  if ($result < 0)
397  {
398  $error++;
399  }
400  }
401  }
402  else if ($reshook < 0) $error++;
403  }
404 
405  if (! $error && ! $notrigger)
406  {
407  // Call trigger
408  $result=$this->call_trigger('ACTION_CREATE',$user);
409  if ($result < 0) { $error++; }
410  // End call triggers
411  }
412 
413  if (! $error)
414  {
415  $this->db->commit();
416  return $this->id;
417  }
418  else
419  {
420  $this->db->rollback();
421  return -1;
422  }
423  }
424  else
425  {
426  $this->db->rollback();
427  $this->error=$this->db->lasterror();
428  return -1;
429  }
430 
431  }
432 
442  public function add(User $user, $notrigger = 0)
443  {
444  return $this->create($user, $notrigger);
445  }
446 
454  function createFromClone($fuser, $socid)
455  {
456  global $db, $user, $langs, $conf, $hookmanager;
457 
458  $this->context['createfromclone']='createfromclone';
459 
460  $error=0;
461  $now=dol_now();
462 
463  $this->db->begin();
464 
465  // Load source object
466  $objFrom = clone $this;
467 
468  $this->fetch_optionals();
469 // $this->fetch_userassigned();
470  $this->fetchResources();
471 
472  $this->id=0;
473 
474  if (!is_object($fuser))
475  {
476  if ($fuser > 0)
477  {
478  $u = new User($db);
479  $u->fetch($fuser);
480  $fuser = $u;
481  }
482  else
483  {
484  $fuser = $user;
485  }
486  }
487 
488  // Create clone
489  $result=$this->create($fuser);
490  if ($result < 0) $error++;
491 
492  if (! $error)
493  {
494  // Hook of thirdparty module
495  if (is_object($hookmanager))
496  {
497  $parameters=array('objFrom'=>$objFrom);
498  $action='';
499  $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
500  if ($reshook < 0) $error++;
501  }
502 
503  // Call trigger
504  $result=$this->call_trigger('ACTION_CLONE', $fuser);
505  if ($result < 0) { $error++; }
506  // End call triggers
507  }
508 
509  unset($this->context['createfromclone']);
510 
511  // End
512  if (! $error)
513  {
514  $this->db->commit();
515  return $this->id;
516  }
517  else
518  {
519  $this->db->rollback();
520  return -1;
521  }
522  }
523 
532  function fetch($id, $ref='',$ref_ext='')
533  {
534  global $langs;
535 
536  $sql = "SELECT a.id,";
537  $sql.= " a.id as ref,";
538  $sql.= " a.ref_ext,";
539  $sql.= " a.datep,";
540  $sql.= " a.datep2,";
541  $sql.= " a.durationp,"; // deprecated
542  $sql.= " a.datec,";
543  $sql.= " a.tms as datem,";
544  $sql.= " a.code, a.label, a.note,";
545  $sql.= " a.fk_soc,";
546  $sql.= " a.fk_project,";
547  $sql.= " a.fk_user_author, a.fk_user_mod,";
548  $sql.= " a.fk_user_action, a.fk_user_done,";
549  $sql.= " a.fk_contact, a.percent as percentage,";
550  $sql.= " a.fk_element, a.elementtype,";
551  $sql.= " a.priority, a.fulldayevent, a.location, a.punctual, a.transparency,";
552  $sql.= " c.id as type_id, c.code as type_code, c.libelle as type_label, c.color as type_color, c.picto as type_picto,";
553  $sql.= " s.nom as socname,";
554  $sql.= " u.firstname, u.lastname as lastname";
555  $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a ";
556  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action=c.id ";
557  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author";
558  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
559  $sql.= " WHERE ";
560  if ($ref) $sql.= " a.id=".$ref; // No field ref, we use id
561  elseif ($ref_ext) $sql.= " a.ref_ext='".$this->db->escape($ref_ext)."'";
562  else $sql.= " a.id=".$id;
563 
564  dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
565  $resql=$this->db->query($sql);
566  if ($resql)
567  {
568  $num=$this->db->num_rows($resql);
569  if ($num)
570  {
571  $obj = $this->db->fetch_object($resql);
572 
573  $this->id = $obj->id;
574  $this->ref = $obj->ref;
575  $this->ref_ext = $obj->ref_ext;
576 
577  // Properties of parent table llx_c_actioncomm
578  $this->type_id = $obj->type_id;
579  $this->type_code = $obj->type_code;
580  $this->type_color = $obj->type_color;
581  $this->type_picto = $obj->type_picto;
582  $transcode=$langs->trans("Action".$obj->type_code);
583  $this->type = (($transcode!="Action".$obj->type_code) ? $transcode : $obj->type_label);
584  $transcode=$langs->trans("Action".$obj->type_code.'Short');
585  $this->type_short = (($transcode!="Action".$obj->type_code.'Short') ? $transcode : '');
586 
587  $this->code = $obj->code;
588  $this->label = $obj->label;
589  $this->datep = $this->db->jdate($obj->datep);
590  $this->datef = $this->db->jdate($obj->datep2);
591 // $this->durationp = $this->durationp; // deprecated
592 
593  $this->datec = $this->db->jdate($obj->datec);
594  $this->datem = $this->db->jdate($obj->datem);
595 
596  $this->note = $obj->note;
597  $this->percentage = $obj->percentage;
598 
599  $this->authorid = $obj->fk_user_author;
600  $this->usermodid = $obj->fk_user_mod;
601 
602  if (!is_object($this->author)) $this->author = new stdClass(); // To avoid warning
603  $this->author->id = $obj->fk_user_author; // deprecated
604  $this->author->firstname = $obj->firstname; // deprecated
605  $this->author->lastname = $obj->lastname; // deprecated
606  if (!is_object($this->usermod)) $this->usermod = new stdClass(); // To avoid warning
607  $this->usermod->id = $obj->fk_user_mod; // deprecated
608 
609  $this->userownerid = $obj->fk_user_action;
610  $this->userdoneid = $obj->fk_user_done;
611  $this->priority = $obj->priority;
612  $this->fulldayevent = $obj->fulldayevent;
613  $this->location = $obj->location;
614  $this->transparency = $obj->transparency;
615  $this->punctual = $obj->punctual; // deprecated
616 
617  $this->socid = $obj->fk_soc; // To have fetch_thirdparty method working
618  $this->contactid = $obj->fk_contact; // To have fetch_contact method working
619  $this->fk_project = $obj->fk_project; // To have fetch_project method working
620 
621  $this->societe->id = $obj->fk_soc; // deprecated
622  $this->contact->id = $obj->fk_contact; // deprecated
623 
624  $this->fk_element = $obj->fk_element;
625  $this->elementtype = $obj->elementtype;
626 
627  $this->fetchResources();
628  }
629  $this->db->free($resql);
630  }
631  else
632  {
633  $this->error=$this->db->lasterror();
634  return -1;
635  }
636 
637  return $num;
638 
639  }
640 
646  function fetchResources()
647  {
648  $sql ='SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency';
649  $sql.=' FROM '.MAIN_DB_PREFIX.'actioncomm_resources';
650  $sql.=' WHERE fk_actioncomm = '.$this->id;
651  $sql.=" AND element_type IN ('user', 'socpeople')";
652  $resql=$this->db->query($sql);
653  if ($resql)
654  {
655  $this->userassigned=array();
656  $this->socpeopleassigned=array();
657 
658  // If owner is known, we must but id first into list
659  if ($this->userownerid > 0) $this->userassigned[$this->userownerid]=array('id'=>$this->userownerid); // Set first so will be first into list.
660 
661  while ($obj = $this->db->fetch_object($resql))
662  {
663  if ($obj->fk_element > 0)
664  {
665  switch ($obj->element_type) {
666  case 'user':
667  $this->userassigned[$obj->fk_element]=array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
668  if (empty($this->userownerid)) $this->userownerid=$obj->fk_element; // If not defined (should not happened, we fix this)
669  break;
670  case 'socpeople':
671  $this->socpeopleassigned[$obj->fk_element]=array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
672  break;
673  }
674  }
675  }
676 
677  return 1;
678  }
679  else
680  {
681  dol_print_error($this->db);
682  return -1;
683  }
684  }
685 
692  {
693  $sql ="SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency";
694  $sql.=" FROM ".MAIN_DB_PREFIX."actioncomm_resources";
695  $sql.=" WHERE element_type = 'user' AND fk_actioncomm = ".$this->id;
696  $resql2=$this->db->query($sql);
697  if ($resql2)
698  {
699  $this->userassigned=array();
700 
701  // If owner is known, we must but id first into list
702  if ($this->userownerid > 0) $this->userassigned[$this->userownerid]=array('id'=>$this->userownerid); // Set first so will be first into list.
703 
704  while ($obj = $this->db->fetch_object($resql2))
705  {
706  if ($obj->fk_element > 0) $this->userassigned[$obj->fk_element]=array('id'=>$obj->fk_element, 'mandatory'=>$obj->mandatory, 'answer_status'=>$obj->answer_status, 'transparency'=>$obj->transparency);
707  if (empty($this->userownerid)) $this->userownerid=$obj->fk_element; // If not defined (should not happened, we fix this)
708  }
709 
710  return 1;
711  }
712  else
713  {
714  dol_print_error($this->db);
715  return -1;
716  }
717  }
718 
725  function delete($notrigger=0)
726  {
727  global $user,$langs,$conf;
728 
729  $error=0;
730 
731  $this->db->begin();
732 
733  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm";
734  $sql.= " WHERE id=".$this->id;
735 
736  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
737  $res=$this->db->query($sql);
738  if ($res < 0) {
739  $this->error=$this->db->lasterror();
740  $error++;
741  }
742 
743  if (! $error) {
744  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources";
745  $sql.= " WHERE fk_actioncomm=".$this->id;
746 
747  dol_syslog(get_class($this)."::delete", LOG_DEBUG);
748  $res=$this->db->query($sql);
749  if ($res < 0) {
750  $this->error=$this->db->lasterror();
751  $error++;
752  }
753  }
754 
755  // Removed extrafields
756  if (! $error) {
757  $result=$this->deleteExtraFields();
758  if ($result < 0)
759  {
760  $error++;
761  dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
762  }
763  }
764 
765  if (!$error)
766  {
767  if (! $notrigger)
768  {
769  // Call trigger
770  $result=$this->call_trigger('ACTION_DELETE',$user);
771  if ($result < 0) { $error++; }
772  // End call triggers
773  }
774 
775  if (! $error)
776  {
777  $this->db->commit();
778  return 1;
779  }
780  else
781  {
782  $this->db->rollback();
783  return -2;
784  }
785  }
786  else
787  {
788  $this->db->rollback();
789  $this->error=$this->db->lasterror();
790  return -1;
791  }
792  }
793 
802  function update($user,$notrigger=0)
803  {
804  global $langs,$conf,$hookmanager;
805 
806  $error=0;
807 
808  // Clean parameters
809  $this->label=trim($this->label);
810  $this->note=trim($this->note);
811  if (empty($this->percentage)) $this->percentage = 0;
812  if (empty($this->priority) || ! is_numeric($this->priority)) $this->priority = 0;
813  if (empty($this->transparency)) $this->transparency = 0;
814  if (empty($this->fulldayevent)) $this->fulldayevent = 0;
815  if ($this->percentage > 100) $this->percentage = 100;
816  //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date;
817  if ($this->datep && $this->datef) $this->durationp=($this->datef - $this->datep); // deprecated
818  //if ($this->date && $this->dateend) $this->durationa=($this->dateend - $this->date);
819  if ($this->datep && $this->datef && $this->datep > $this->datef) $this->datef=$this->datep;
820  //if ($this->date && $this->dateend && $this->date > $this->dateend) $this->dateend=$this->date;
821  if ($this->fk_project < 0) $this->fk_project = 0;
822 
823  // Check parameters
824  if ($this->percentage == 0 && $this->userdoneid > 0)
825  {
826  $this->error="ErrorCantSaveADoneUserWithZeroPercentage";
827  return -1;
828  }
829 
830  $socid=($this->socid?$this->socid:((isset($this->societe->id) && $this->societe->id > 0) ? $this->societe->id : 0));
831  $contactid=($this->contactid?$this->contactid:((isset($this->contact->id) && $this->contact->id > 0) ? $this->contact->id : 0));
832  $userownerid=($this->userownerid?$this->userownerid:0);
833  $userdoneid=($this->userdoneid?$this->userdoneid:0);
834 
835  $this->db->begin();
836 
837  $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm ";
838  $sql.= " SET percent = '".$this->db->escape($this->percentage)."'";
839  if ($this->type_id > 0) $sql.= ", fk_action = '".$this->db->escape($this->type_id)."'";
840  $sql.= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'":"null");
841  $sql.= ", datep = ".(strval($this->datep)!='' ? "'".$this->db->idate($this->datep)."'" : 'null');
842  $sql.= ", datep2 = ".(strval($this->datef)!='' ? "'".$this->db->idate($this->datef)."'" : 'null');
843  $sql.= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != ''?"'".$this->db->escape($this->durationp)."'":"null"); // deprecated
844  $sql.= ", note = ".($this->note ? "'".$this->db->escape($this->note)."'":"null");
845  $sql.= ", fk_project =". ($this->fk_project > 0 ? $this->fk_project:"null");
846  $sql.= ", fk_soc =". ($socid > 0 ? $socid:"null");
847  $sql.= ", fk_contact =". ($contactid > 0 ? $contactid:"null");
848  $sql.= ", priority = '".$this->db->escape($this->priority)."'";
849  $sql.= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'";
850  $sql.= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'":"null");
851  $sql.= ", transparency = '".$this->db->escape($this->transparency)."'";
852  $sql.= ", fk_user_mod = ".$user->id;
853  $sql.= ", fk_user_action=".($userownerid > 0 ? "'".$userownerid."'":"null");
854  $sql.= ", fk_user_done=".($userdoneid > 0 ? "'".$userdoneid."'":"null");
855  if (! empty($this->fk_element)) $sql.= ", fk_element=".($this->fk_element?$this->db->escape($this->fk_element):"null");
856  if (! empty($this->elementtype)) $sql.= ", elementtype=".($this->elementtype?"'".$this->db->escape($this->elementtype)."'":"null");
857  $sql.= " WHERE id=".$this->id;
858 
859  dol_syslog(get_class($this)."::update", LOG_DEBUG);
860  if ($this->db->query($sql))
861  {
862  $action='update';
863 
864  // Actions on extra fields (by external module or standard code)
865  // TODO le hook fait double emploi avec le trigger !!
866  $hookmanager->initHooks(array('actioncommdao'));
867  $parameters=array('actcomm'=>$this->id);
868  $reshook=$hookmanager->executeHooks('insertExtraFields',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
869  if (empty($reshook))
870  {
871  if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
872  {
873  $result=$this->insertExtraFields();
874  if ($result < 0)
875  {
876  $error++;
877  }
878  }
879  }
880  else if ($reshook < 0) $error++;
881 
882  // Now insert assignedusers
883  if (! $error)
884  {
885  $sql ="DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".$this->id." AND element_type = 'user'";
886  $resql = $this->db->query($sql);
887 
888  foreach($this->userassigned as $key => $val)
889  {
890  if (! is_array($val)) // For backward compatibility when val=id
891  {
892  $val=array('id'=>$val);
893  }
894  $sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
895  $sql.=" VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['manadatory'])?'0':$val['manadatory']).", ".(empty($val['transparency'])?'0':$val['transparency']).", ".(empty($val['answer_status'])?'0':$val['answer_status']).")";
896 
897  $resql = $this->db->query($sql);
898  if (! $resql)
899  {
900  $error++;
901  $this->errors[]=$this->db->lasterror();
902  }
903  //var_dump($sql);exit;
904  }
905  }
906 
907  if (!$error)
908  {
909  $sql ="DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".$this->id." AND element_type = 'socpeople'";
910  $resql = $this->db->query($sql);
911 
912  if (!empty($this->socpeopleassigned))
913  {
914  foreach (array_keys($this->socpeopleassigned) as $id)
915  {
916  $sql ="INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
917  $sql.=" VALUES(".$this->id.", 'socpeople', ".$id.", 0, 0, 0)";
918 
919  $resql = $this->db->query($sql);
920  if (! $resql)
921  {
922  $error++;
923  $this->errors[]=$this->db->lasterror();
924  }
925 
926  }
927  }
928  }
929 
930  if (! $error && ! $notrigger)
931  {
932  // Call trigger
933  $result=$this->call_trigger('ACTION_MODIFY',$user);
934  if ($result < 0) { $error++; }
935  // End call triggers
936  }
937 
938  if (! $error)
939  {
940  $this->db->commit();
941  return 1;
942  }
943  else
944  {
945  $this->db->rollback();
946  dol_syslog(get_class($this)."::update ".join(',',$this->errors),LOG_ERR);
947  return -2;
948  }
949  }
950  else
951  {
952  $this->db->rollback();
953  $this->error=$this->db->lasterror();
954  return -1;
955  }
956  }
957 
972  static function getActions($db, $socid=0, $fk_element=0, $elementtype='', $filter='', $sortfield='a.datep', $sortorder='DESC', $limit=0)
973  {
974  global $conf, $langs;
975 
976  $resarray=array();
977 
978  $sql = "SELECT a.id";
979  $sql.= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
980  $sql.= " WHERE a.entity IN (".getEntity('agenda').")";
981  if (! empty($socid)) $sql.= " AND a.fk_soc = ".$socid;
982  if (! empty($elementtype))
983  {
984  if ($elementtype == 'project') $sql.= ' AND a.fk_project = '.$fk_element;
985  else $sql.= " AND a.fk_element = ".(int) $fk_element." AND a.elementtype = '".$elementtype."'";
986  }
987  if (! empty($filter)) $sql.= $filter;
988  if ($sortorder && $sortfield) $sql.=$db->order($sortfield, $sortorder);
989  $sql.=$db->plimit($limit, 0);
990 
991  dol_syslog(get_class()."::getActions", LOG_DEBUG);
992  $resql=$db->query($sql);
993  if ($resql)
994  {
995  $num = $db->num_rows($resql);
996 
997  if ($num)
998  {
999  for($i=0;$i<$num;$i++)
1000  {
1001  $obj = $db->fetch_object($resql);
1002  $actioncommstatic = new ActionComm($db);
1003  $actioncommstatic->fetch($obj->id);
1004  $resarray[$i] = $actioncommstatic;
1005  }
1006  }
1007  $db->free($resql);
1008  return $resarray;
1009  }
1010  else
1011  {
1012  return $db->lasterror();
1013  }
1014  }
1015 
1023  function load_board($user, $load_state_board=0)
1024  {
1025  global $conf, $langs;
1026 
1027  if(empty($load_state_board)) $sql = "SELECT a.id, a.datep as dp";
1028  else {
1029  $this->nb=array();
1030  $sql = "SELECT count(a.id) as nb";
1031  }
1032  $sql.= " FROM (".MAIN_DB_PREFIX."actioncomm as a";
1033  $sql.= ")";
1034  if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc";
1035  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid";
1036  $sql.= " WHERE 1 = 1";
1037  if(empty($load_state_board)) $sql.= " AND a.percent >= 0 AND a.percent < 100";
1038  $sql.= " AND a.entity IN (".getEntity('agenda').")";
1039  if (! $user->rights->societe->client->voir && ! $user->societe_id) $sql.= " AND (a.fk_soc IS NULL OR sc.fk_user = " .$user->id . ")";
1040  if ($user->societe_id) $sql.=" AND a.fk_soc = ".$user->societe_id;
1041  if (! $user->rights->agenda->allactions->read) $sql.= " AND (a.fk_user_author = ".$user->id . " OR a.fk_user_action = ".$user->id . " OR a.fk_user_done = ".$user->id . ")";
1042 
1043  $resql=$this->db->query($sql);
1044  if ($resql)
1045  {
1046  if(empty($load_state_board)) {
1047  $agenda_static = new ActionComm($this->db);
1048  $response = new WorkboardResponse();
1049  $response->warning_delay = $conf->agenda->warning_delay/60/60/24;
1050  $response->label = $langs->trans("ActionsToDo");
1051  $response->url = DOL_URL_ROOT.'/comm/action/list.php?status=todo&amp;mainmenu=agenda';
1052  if ($user->rights->agenda->allactions->read) $response->url.='&amp;filtert=-1';
1053  $response->img = img_object('',"action",'class="inline-block valigntextmiddle"');
1054  }
1055  // This assignment in condition is not a bug. It allows walking the results.
1056  while ($obj=$this->db->fetch_object($resql))
1057  {
1058  if(empty($load_state_board)) {
1059  $response->nbtodo++;
1060  $agenda_static->datep = $this->db->jdate($obj->dp);
1061  if ($agenda_static->hasDelay()) $response->nbtodolate++;
1062  } else $this->nb["actionscomm"]=$obj->nb;
1063  }
1064 
1065  $this->db->free($resql);
1066  if(empty($load_state_board)) return $response;
1067  else return 1;
1068  }
1069  else
1070  {
1071  dol_print_error($this->db);
1072  $this->error=$this->db->error();
1073  return -1;
1074  }
1075  }
1076 
1077 
1084  function info($id)
1085  {
1086  $sql = 'SELECT ';
1087  $sql.= ' a.id,';
1088  $sql.= ' datec,';
1089  $sql.= ' tms as datem,';
1090  $sql.= ' fk_user_author,';
1091  $sql.= ' fk_user_mod';
1092  $sql.= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a';
1093  $sql.= ' WHERE a.id = '.$id;
1094 
1095  dol_syslog(get_class($this)."::info", LOG_DEBUG);
1096  $result=$this->db->query($sql);
1097  if ($result)
1098  {
1099  if ($this->db->num_rows($result))
1100  {
1101  $obj = $this->db->fetch_object($result);
1102  $this->id = $obj->id;
1103  if ($obj->fk_user_author)
1104  {
1105  $cuser = new User($this->db);
1106  $cuser->fetch($obj->fk_user_author);
1107  $this->user_creation = $cuser;
1108  }
1109  if ($obj->fk_user_mod)
1110  {
1111  $muser = new User($this->db);
1112  $muser->fetch($obj->fk_user_mod);
1113  $this->user_modification = $muser;
1114  }
1115 
1116  $this->date_creation = $this->db->jdate($obj->datec);
1117  if (! empty($obj->fk_user_mod)) $this->date_modification = $this->db->jdate($obj->datem);
1118  }
1119  $this->db->free($result);
1120  }
1121  else
1122  {
1123  dol_print_error($this->db);
1124  }
1125  }
1126 
1127 
1135  function getLibStatut($mode,$hidenastatus=0)
1136  {
1137  return $this->LibStatut($this->percentage,$mode,$hidenastatus,$this->datep);
1138  }
1139 
1149  function LibStatut($percent,$mode,$hidenastatus=0,$datestart='')
1150  {
1151  global $langs;
1152 
1153  if ($mode == 0)
1154  {
1155  if ($percent==-1 && ! $hidenastatus) return $langs->trans('StatusNotApplicable');
1156  else if ($percent==0) return $langs->trans('StatusActionToDo').' (0%)';
1157  else if ($percent > 0 && $percent < 100) return $langs->trans('StatusActionInProcess').' ('.$percent.'%)';
1158  else if ($percent >= 100) return $langs->trans('StatusActionDone').' (100%)';
1159  }
1160  else if ($mode == 1)
1161  {
1162  if ($percent==-1 && ! $hidenastatus) return $langs->trans('StatusNotApplicable');
1163  else if ($percent==0) return $langs->trans('StatusActionToDo');
1164  else if ($percent > 0 && $percent < 100) return $percent.'%';
1165  else if ($percent >= 100) return $langs->trans('StatusActionDone');
1166  }
1167  else if ($mode == 2)
1168  {
1169  if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9').' '.$langs->trans('StatusNotApplicable');
1170  else if ($percent==0) return img_picto($langs->trans('StatusActionToDo'),'statut1').' '.$langs->trans('StatusActionToDo');
1171  else if ($percent > 0 && $percent < 100) return img_picto($langs->trans('StatusActionInProcess'),'statut3').' '. $percent.'%';
1172  else if ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6').' '.$langs->trans('StatusActionDone');
1173  }
1174  else if ($mode == 3)
1175  {
1176  if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans("Status").': '.$langs->trans('StatusNotApplicable'),'statut9');
1177  else if ($percent==0) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionToDo').' (0%)','statut1');
1178  else if ($percent > 0 && $percent < 100) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionInProcess').' ('.$percent.'%)','statut3');
1179  else if ($percent >= 100) return img_picto($langs->trans("Status").': '.$langs->trans('StatusActionDone').' (100%)','statut6');
1180  }
1181  else if ($mode == 4)
1182  {
1183  if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9').' '.$langs->trans('StatusNotApplicable');
1184  else if ($percent==0) return img_picto($langs->trans('StatusActionToDo'),'statut1').' '.$langs->trans('StatusActionToDo').' (0%)';
1185  else if ($percent > 0 && $percent < 100) return img_picto($langs->trans('StatusActionInProcess'),'statut3').' '.$langs->trans('StatusActionInProcess').' ('.$percent.'%)';
1186  else if ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6').' '.$langs->trans('StatusActionDone').' (100%)';
1187  }
1188  else if ($mode == 5)
1189  {
1190  if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9');
1191  else if ($percent==0) return '0% '.img_picto($langs->trans('StatusActionToDo'),'statut1');
1192  else if ($percent > 0 && $percent < 100) return $percent.'% '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
1193  else if ($percent >= 100) return $langs->trans('StatusActionDone').' '.img_picto($langs->trans('StatusActionDone'),'statut6');
1194  }
1195  else if ($mode == 6)
1196  {
1197  if ($percent==-1 && ! $hidenastatus) return $langs->trans('StatusNotApplicable').' '.img_picto($langs->trans('StatusNotApplicable'),'statut9');
1198  else if ($percent==0) return $langs->trans('StatusActionToDo').' (0%) '.img_picto($langs->trans('StatusActionToDo'),'statut1');
1199  else if ($percent > 0 && $percent < 100) return $langs->trans('StatusActionInProcess').' ('.$percent.'%) '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
1200  else if ($percent >= 100) return $langs->trans('StatusActionDone').' (100%) '.img_picto($langs->trans('StatusActionDone'),'statut6');
1201  }
1202  else if ($mode == 7)
1203  {
1204  if ($percent==-1 && ! $hidenastatus) return img_picto($langs->trans('StatusNotApplicable'),'statut9');
1205  else if ($percent==0) return '0% '.img_picto($langs->trans('StatusActionToDo'),'statut1');
1206  else if ($percent > 0 && $percent < 100) return $percent.'% '.img_picto($langs->trans('StatusActionInProcess').' - '.$percent.'%','statut3');
1207  else if ($percent >= 100) return img_picto($langs->trans('StatusActionDone'),'statut6');
1208  }
1209 
1210  return '';
1211  }
1212 
1225  function getNomUrl($withpicto=0,$maxlength=0,$classname='',$option='',$overwritepicto=0, $notooltip=0)
1226  {
1227  global $conf, $langs, $user, $hookmanager, $action;
1228 
1229  if (! empty($conf->dol_no_mouse_hover)) $notooltip=1; // Force disable tooltips
1230 
1231  $label = $this->label;
1232  if (empty($label)) $label=$this->libelle; // For backward compatibility
1233 
1234  $result='';
1235 
1236  // Set label of typ
1237  $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code)?$langs->transnoentities("Action".$this->type_code):$this->type_label;
1238  if (empty($conf->global->AGENDA_USE_EVENT_TYPE))
1239  {
1240  if ($this->type_code != 'AC_OTH_AUTO') $labeltype = $langs->trans('ActionAC_MANUAL');
1241  }
1242 
1243  $tooltip = '<u>' . $langs->trans('ShowAction') . '</u>';
1244  if (! empty($this->ref))
1245  $tooltip .= '<br><b>' . $langs->trans('Ref') . ':</b> ' . $this->ref;
1246  if (! empty($label))
1247  $tooltip .= '<br><b>' . $langs->trans('Title') . ':</b> ' . $label;
1248  if (! empty($labeltype))
1249  $tooltip .= '<br><b>' . $langs->trans('Type') . ':</b> ' . $labeltype;
1250  if (! empty($this->location))
1251  $tooltip .= '<br><b>' . $langs->trans('Location') . ':</b> ' . $this->location;
1252 
1253  $linkclose='';
1254  if (! empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color)
1255  $linkclose = ' style="background-color:#'.$this->type_color.'"';
1256 
1257  if (empty($notooltip))
1258  {
1259  if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
1260  {
1261  $label=$langs->trans("ShowAction");
1262  $linkclose.=' alt="'.dol_escape_htmltag($tooltip, 1).'"';
1263  }
1264  $linkclose.=' title="'.dol_escape_htmltag($tooltip, 1).'"';
1265  $linkclose.=' class="'.$classname.' classfortooltip"';
1266 
1267  if (! is_object($hookmanager))
1268  {
1269  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1270  $hookmanager=new HookManager($this->db);
1271  }
1272  $hookmanager->initHooks(array('actiondao'));
1273  $parameters=array('id'=>$this->id);
1274  $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
1275  $linkclose = ($hookmanager->resPrint ? $hookmanager->resPrint : $linkclose);
1276  }
1277  else $linkclose.=' class="'.$classname.'"';
1278 
1279  $url='';
1280  if ($option=='birthday')
1281  $url = DOL_URL_ROOT.'/contact/perso.php?id='.$this->id;
1282  else
1283  $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id;
1284 
1285  $linkstart = '<a href="'.$url.'"';
1286  $linkstart.=$linkclose.'>';
1287  $linkend='</a>';
1288 
1289  //print 'rrr'.$this->libelle.'-'.$withpicto;
1290 
1291  if ($withpicto == 2)
1292  {
1293  $libelle=$label;
1294  if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) $libelle=$labeltype;
1295  $libelleshort='';
1296  }
1297  else
1298  {
1299  $libelle=(empty($this->libelle)?$label:$this->libelle.(($label && $label != $this->libelle)?' '.$label:''));
1300  if (! empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($libelle)) $libelle=$labeltype;
1301  if ($maxlength < 0) $libelleshort=$this->ref;
1302  else $libelleshort=dol_trunc($libelle,$maxlength);
1303  }
1304 
1305  if ($withpicto)
1306  {
1307  if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) // Add code into ()
1308  {
1309  $libelle.=(($this->type_code && $libelle!=$langs->transnoentities("Action".$this->type_code) && $langs->transnoentities("Action".$this->type_code)!="Action".$this->type_code)?' ('.$langs->transnoentities("Action".$this->type_code).')':'');
1310  }
1311  }
1312 
1313  $result.=$linkstart;
1314  if ($withpicto) $result.=img_object(($notooltip?'':$langs->trans("ShowAction").': '.$libelle), ($overwritepicto?$overwritepicto:'action'), ($notooltip?'class="'.(($withpicto != 2) ? 'paddingright ' : '').'valigntextbottom"':'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip valigntextbottom"'), 0, 0, $notooltip?0:1);
1315  $result.=$libelleshort;
1316  $result.=$linkend;
1317 
1318  return $result;
1319  }
1320 
1321 
1332  function build_exportfile($format,$type,$cachedelay,$filename,$filters)
1333  {
1334  global $conf,$langs,$dolibarr_main_url_root,$mysoc;
1335 
1336  require_once (DOL_DOCUMENT_ROOT ."/core/lib/xcal.lib.php");
1337  require_once (DOL_DOCUMENT_ROOT ."/core/lib/date.lib.php");
1338  require_once (DOL_DOCUMENT_ROOT ."/core/lib/files.lib.php");
1339 
1340  dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG);
1341 
1342  // Check parameters
1343  if (empty($format)) return -1;
1344 
1345  // Clean parameters
1346  if (! $filename)
1347  {
1348  $extension='vcs';
1349  if ($format == 'ical') $extension='ics';
1350  $filename=$format.'.'.$extension;
1351  }
1352 
1353  // Create dir and define output file (definitive and temporary)
1354  $result=dol_mkdir($conf->agenda->dir_temp);
1355  $outputfile=$conf->agenda->dir_temp.'/'.$filename;
1356 
1357  $result=0;
1358 
1359  $buildfile=true;
1360  $login='';$logina='';$logind='';$logint='';
1361 
1362  $now = dol_now();
1363 
1364  if ($cachedelay)
1365  {
1366  $nowgmt = dol_now();
1367  include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1368  if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay))
1369  {
1370  dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled");
1371  $buildfile = false;
1372  }
1373  }
1374 
1375  if ($buildfile)
1376  {
1377  // Build event array
1378  $eventarray=array();
1379 
1380  $sql = "SELECT a.id,";
1381  $sql.= " a.datep,"; // Start
1382  $sql.= " a.datep2,"; // End
1383  $sql.= " a.durationp,"; // deprecated
1384  $sql.= " a.datec, a.tms as datem,";
1385  $sql.= " a.label, a.code, a.note, a.fk_action as type_id,";
1386  $sql.= " a.fk_soc,";
1387  $sql.= " a.fk_user_author, a.fk_user_mod,";
1388  $sql.= " a.fk_user_action,";
1389  $sql.= " a.fk_contact, a.percent as percentage,";
1390  $sql.= " a.fk_element, a.elementtype,";
1391  $sql.= " a.priority, a.fulldayevent, a.location, a.punctual, a.transparency,";
1392  $sql.= " u.firstname, u.lastname,";
1393  $sql.= " s.nom as socname,";
1394  $sql.= " c.id as type_id, c.code as type_code, c.libelle";
1395  $sql.= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)";
1396  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export
1397  $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
1398  // We must filter on assignement table
1399  if ($filters['logint']) $sql.=", ".MAIN_DB_PREFIX."actioncomm_resources as ar";
1400  $sql.= " WHERE a.fk_action=c.id";
1401  $sql.= " AND a.entity IN (".getEntity('agenda').")";
1402  foreach ($filters as $key => $value)
1403  {
1404  if ($key == 'notolderthan' && $value != '') $sql.=" AND a.datep >= '".$this->db->idate($now-($value*24*60*60))."'";
1405  if ($key == 'year') $sql.=" AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value,1))."' AND '".$this->db->idate(dol_get_last_day($value,12))."'";
1406  if ($key == 'id') $sql.=" AND a.id=".(is_numeric($value)?$value:0);
1407  if ($key == 'idfrom') $sql.=" AND a.id >= ".(is_numeric($value)?$value:0);
1408  if ($key == 'idto') $sql.=" AND a.id <= ".(is_numeric($value)?$value:0);
1409  if ($key == 'project') $sql.=" AND a.fk_project=".(is_numeric($value)?$value:0);
1410  // We must filter on assignement table
1411  if ($key == 'logint') $sql.= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
1412  if ($key == 'logina')
1413  {
1414  $logina=$value;
1415  $condition='=';
1416  if (preg_match('/^!/',$logina))
1417  {
1418  $logina=preg_replace('/^!/','',$logina);
1419  $condition='<>';
1420  }
1421  $userforfilter=new User($this->db);
1422  $result=$userforfilter->fetch('',$logina);
1423  if ($result > 0) $sql.= " AND a.fk_user_author ".$condition." ".$userforfilter->id;
1424  elseif ($result < 0 || $condition == '=') $sql.= " AND a.fk_user_author = 0";
1425  }
1426  if ($key == 'logint')
1427  {
1428  $logint=$value;
1429  $condition='=';
1430  if (preg_match('/^!/',$logint))
1431  {
1432  $logint=preg_replace('/^!/','',$logint);
1433  $condition='<>';
1434  }
1435  $userforfilter=new User($this->db);
1436  $result=$userforfilter->fetch('',$logint);
1437  if ($result > 0) $sql.= " AND ar.fk_element = ".$userforfilter->id;
1438  elseif ($result < 0 || $condition == '=') $sql.= " AND ar.fk_element = 0";
1439  }
1440  }
1441  $sql.= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import
1442  $sql.= " ORDER by datep";
1443  //print $sql;exit;
1444 
1445  dol_syslog(get_class($this)."::build_exportfile select events", LOG_DEBUG);
1446  $resql=$this->db->query($sql);
1447  if ($resql)
1448  {
1449  // Note: Output of sql request is encoded in $conf->file->character_set_client
1450  // This assignment in condition is not a bug. It allows walking the results.
1451  $diff = 0;
1452  while ($obj=$this->db->fetch_object($resql))
1453  {
1454  $qualified=true;
1455 
1456  // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author'
1457  $event=array();
1458  $event['uid']='dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"];
1459  $event['type']=$type;
1460  $datestart=$this->db->jdate($obj->datep)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600));
1461  $dateend=$this->db->jdate($obj->datep2)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600));
1462  $duration=($datestart && $dateend)?($dateend - $datestart):0;
1463  $event['summary']=$obj->label.($obj->socname?" (".$obj->socname.")":"");
1464  $event['desc']=$obj->note;
1465  $event['startdate']=$datestart;
1466  $event['enddate']=$dateend; // Not required with type 'journal'
1467  $event['duration']=$duration; // Not required with type 'journal'
1468  $event['author']=dolGetFirstLastname($obj->firstname, $obj->lastname);
1469  $event['priority']=$obj->priority;
1470  $event['fulldayevent']=$obj->fulldayevent;
1471  $event['location']=$obj->location;
1472  $event['transparency']=(($obj->transparency > 0)?'OPAQUE':'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy)
1473  $event['punctual']=$obj->punctual;
1474  $event['category']=$obj->libelle; // libelle type action
1475  // Define $urlwithroot
1476  $urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
1477  $urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
1478  //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
1479  $url=$urlwithroot.'/comm/action/card.php?id='.$obj->id;
1480  $event['url']=$url;
1481  $event['created']=$this->db->jdate($obj->datec)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600));
1482  $event['modified']=$this->db->jdate($obj->datem)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600));
1483 
1484  if ($qualified && $datestart)
1485  {
1486  $eventarray[]=$event;
1487  }
1488  $diff++;
1489  }
1490  }
1491  else
1492  {
1493  $this->error=$this->db->lasterror();
1494  return -1;
1495  }
1496 
1497  $langs->load("agenda");
1498 
1499  // Define title and desc
1500  $more='';
1501  if ($login) $more=$langs->transnoentities("User").' '.$login;
1502  if ($logina) $more=$langs->transnoentities("ActionsAskedBy").' '.$logina;
1503  if ($logint) $more=$langs->transnoentities("ActionsToDoBy").' '.$logint;
1504  if ($logind) $more=$langs->transnoentities("ActionsDoneBy").' '.$logind;
1505  if ($more)
1506  {
1507  $title='Dolibarr actions '.$mysoc->name.' - '.$more;
1508  $desc=$more;
1509  $desc.=' ('.$mysoc->name.' - built by Dolibarr)';
1510  }
1511  else
1512  {
1513  $title='Dolibarr actions '.$mysoc->name;
1514  $desc=$langs->transnoentities('ListOfActions');
1515  $desc.=' ('.$mysoc->name.' - built by Dolibarr)';
1516  }
1517 
1518  // Create temp file
1519  $outputfiletmp=tempnam($conf->agenda->dir_temp,'tmp'); // Temporary file (allow call of function by different threads
1520  @chmod($outputfiletmp, octdec($conf->global->MAIN_UMASK));
1521 
1522  // Write file
1523  if ($format == 'vcal') $result=build_calfile($format,$title,$desc,$eventarray,$outputfiletmp);
1524  if ($format == 'ical') $result=build_calfile($format,$title,$desc,$eventarray,$outputfiletmp);
1525  if ($format == 'rss') $result=build_rssfile($format,$title,$desc,$eventarray,$outputfiletmp);
1526 
1527  if ($result >= 0)
1528  {
1529  if (dol_move($outputfiletmp,$outputfile,0,1)) $result=1;
1530  else
1531  {
1532  $this->error='Failed to rename '.$outputfiletmp.' into '.$outputfile;
1533  dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR);
1534  dol_delete_file($outputfiletmp,0,1);
1535  $result=-1;
1536  }
1537  }
1538  else
1539  {
1540  dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR);
1541  dol_delete_file($outputfiletmp,0,1);
1542  $langs->load("errors");
1543  $this->error=$langs->trans("ErrorFailToCreateFile",$outputfile);
1544  }
1545  }
1546 
1547  return $result;
1548  }
1549 
1557  function initAsSpecimen()
1558  {
1559  global $user;
1560 
1561  $now=dol_now();
1562 
1563  // Initialise parametres
1564  $this->id=0;
1565  $this->specimen=1;
1566 
1567  $this->type_code='AC_OTH';
1568  $this->code='AC_SPECIMEN_CODE';
1569  $this->label='Label of event Specimen';
1570  $this->datec=$now;
1571  $this->datem=$now;
1572  $this->datep=$now;
1573  $this->datef=$now;
1574  $this->author=$user;
1575  $this->usermod=$user;
1576  $this->usertodo=$user;
1577  $this->fulldayevent=0;
1578  $this->punctual=0;
1579  $this->percentage=0;
1580  $this->location='Location';
1581  $this->transparency=1; // 1 means opaque
1582  $this->priority=1;
1583  $this->note = 'Note';
1584 
1585  $this->userownerid=$user->id;
1586  $this->userassigned[$user->id]=array('id'=>$user->id, 'transparency'=> 1);
1587  }
1588 
1597  public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
1598  {
1599  $tables = array(
1600  'actioncomm'
1601  );
1602 
1603  return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
1604  }
1605 
1611  public function hasDelay()
1612  {
1613  global $conf;
1614 
1615  $now = dol_now();
1616 
1617  return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay));
1618  }
1619 
1620 
1627  public function sendEmailsReminder()
1628  {
1629  global $conf, $langs;
1630 
1631  $this->output = '';
1632  $this->error='';
1633 
1634  if (empty($conf->global->AGENDA_REMINDER_EMAIL))
1635  {
1636  $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
1637  return 0;
1638  }
1639 
1640  $now = dol_now();
1641 
1642  dol_syslog(__METHOD__, LOG_DEBUG);
1643 
1644  // TODO Scan events of type 'email' into table llx_actioncomm_reminder with status todo, send email, then set status to done
1645 
1646 
1647 
1648  // Delete also very old past events (we do not keep more than 1 month record in past)
1649  $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder WHERE dateremind < '".$this->db->jdate($now - (3600 * 24 * 32))."'";
1650  $this->db->query($sql);
1651 
1652  return 0;
1653  }
1654 
1655 }
1656 
Class to manage different types of events.
fetch_userassigned()
Initialize this->userassigned array with list of id of user assigned to event.
fetch($id, $ref='', $ref_ext='')
Load object from database.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='')
Show picto whatever it's its name (generic function)
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.
getNomUrl($withpicto=0, $maxlength=0, $classname='', $option='', $overwritepicto=0, $notooltip=0)
Return URL of event Use $this->id, $this->type_code, $this->label and $this->type_label.
Class to manage agenda events (actions)
createFromClone($fuser, $socid)
Load an object from its id and create a new one in database.
build_rssfile($format, $title, $desc, $events_array, $outputfile, $filter='')
Build a file from an array of events.
Definition: xcal.lib.php:296
if(GETPOST('cancel','alpha')) if(!GETPOST('confirmmassaction','alpha')&&$massaction!= 'presend'&&$massaction!= 'confirm_presend')
Draft customers invoices.
Definition: list.php:147
create(User $user, $notrigger=0)
Add an action/event into database.
fetchResources()
Initialize $this->userassigned & this->socpeopleassigned array with list of id of user and contact as...
Class to manage Dolibarr users.
Definition: user.class.php:39
Class to manage Dolibarr database access.
info($id)
Charge les informations d'ordre info dans l'objet facture.
load_board($user, $load_state_board=0)
Load indicators for dashboard (this->nbtodo and this->nbtodolate)
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition: date.lib.php:445
dol_print_error($db='', $error='', $errors=null)
Affiche message erreur system avec toutes les informations pour faciliter le diagnostic et la remonte...
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
LibStatut($percent, $mode, $hidenastatus=0, $datestart='')
Return label of action status.
__construct(DoliDB $db)
Constructor.
sendEmailsReminder()
Send reminders by emails CAN BE A CRON TASK.
dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1)
Move a file into another name.
Definition: files.lib.php:780
Class to manage hooks.
initAsSpecimen()
Initialise an instance with random values.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='')
Write log message into outputs.
insertExtraFields($trigger='', $userused=null)
Add/Update all extra fields values for the current object.
update($user, $notrigger=0)
Update action into database If percentage = 100, on met a jour date 100%.
if($_POST["cancel"]==$langs->trans("Cancel")&&!$id) if($action== 'setdatev'&&$user->rights->tax->charges->creer) if($action== 'add'&&$_POST["cancel"]<> $langs->trans("Cancel")) if($action== 'delete') $title
Actions.
Definition: card.php:183
static commonReplaceThirdparty(DoliDB $db, $origin_id, $dest_id, array $tables, $ignoreerrors=0)
Function used to replace a thirdparty id with another one.
img_object($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
deleteExtraFields()
Delete all extra fields values for the current object.
dol_now($mode='gmt')
Return date for now.
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...
hasDelay()
Is the action delayed?
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition: date.lib.php:459
static getActions($db, $socid=0, $fk_element=0, $elementtype='', $filter='', $sortfield='a.datep', $sortorder='DESC', $limit=0)
Load all objects with filters.
add(User $user, $notrigger=0)
Add an action/event into database.
dol_filemtime($pathoffile)
Return time of a file.
Definition: files.lib.php:528
dol_mkdir($dir, $dataroot='', $newmask=null)
Creation of a directory (this can create recursive subdir)
dol_htmlcleanlastbr($stringtodecode)
This function remove all ending and br at end.
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->societe->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if(!empty($conf->fournisseur->enabled)&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1013
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null)
Remove a file or several files with a mask.
Definition: files.lib.php:1103
getLibStatut($mode, $hidenastatus=0)
Return label of status.
call_trigger($trigger_name, $user)
Call trigger based on this instance.
type
Definition: viewcat.php:283
build_exportfile($format, $type, $cachedelay, $filename, $filters)
Export events from database into a cal file.
Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
dolGetFirstLastname($firstname, $lastname, $nameorder=-1)
Return firstname and lastname in correct order.
static replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
Function used to replace a thirdparty id with another one.