dolibarr 21.0.0-alpha
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-2024 Frédéric France <frederic.france@free.fr>
9 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
10 * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <https://www.gnu.org/licenses/>.
24 */
25
31require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
34require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php';
35
36
41{
45 public $element = 'action';
46
50 public $table_element = 'actioncomm';
51
55 public $table_rowid = 'id';
56
60 public $picto = 'action';
61
67 public $restrictiononfksoc = 2;
68
72 public $id;
73
77 public $ref;
78
83 public $type_id;
84
89 public $type;
90
95 public $type_code;
96
100 public $type_label;
101
105 public $type_color;
106
110 public $type_picto;
111
116 public $code;
117
121 public $label;
122
126 public $datec;
127
131 public $duree;
132
136 public $datem;
137
143 public $author;
144
150 public $usermod;
151
155 public $authorid;
156
160 public $usermodid;
161
165 public $datep;
166
170 public $datef;
171
175 public $date_start_in_calendar;
176
180 public $date_end_in_calendar;
181
185 public $datep2;
186
191 public $durationp = -1;
192
196 public $fulldayevent = 0;
197
201 public $ponctuel;
202
206 public $percentage;
207
211 public $location;
212
216 public $transparency;
217
221 public $priority;
222
226 public $userassigned = array();
227
231 public $userownerid;
232
236 public $socpeopleassigned = array();
237
241 public $otherassigned = array();
242
246 public $reminders = array();
247
251 public $socid;
252
256 public $contact_id;
257
258
264 public $societe;
265
271 public $contact;
272
273 // Properties for links to other objects
277 public $fk_element; // Id of record
278
282 public $elementid;
283
287 public $elementtype;
288
292 public $fk_bookcal_calendar;
293
297 public $icalname;
298
302 public $icalcolor;
303
307 public $extraparams;
308
312 public $actions = array();
313
317 public $email_msgid;
318
322 public $email_from;
323
327 public $email_sender;
328
332 public $email_to;
333
337 public $email_tocc;
341 public $email_tobcc;
342
346 public $email_subject;
347
351 public $errors_to;
352
356 public $num_vote;
357
361 public $event_paid;
362
366 public $status;
367
371 public $ip;
372
373 /*
374 * Properties to manage the recurring events
375 */
377 public $recurid;
379 public $recurrule;
381 public $recurdateend;
382
384 public $calling_duration;
385
386
390 const EVENT_TODO = 0;
391
396
400 const EVENT_FINISHED = 100;
401
402
403 public $fields = array();
404
410 public function __construct(DoliDB $db)
411 {
412 $this->db = $db;
413
414 $this->ismultientitymanaged = 1;
415 }
416
425 public function create(User $user, $notrigger = 0)
426 {
427 global $langs, $conf;
428
429 $error = 0;
430 $now = dol_now();
431
432 // Check parameters
433 if (!isset($this->userownerid) || (string) $this->userownerid === '') { // $this->userownerid may be 0 (anonymous event) or > 0
434 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);
435 $this->errors[] = 'ErrorActionCommPropertyUserowneridNotDefined';
436 return -1;
437 }
438
439 // Clean parameters
440 $this->label = dol_trunc(trim($this->label), 128);
441 $this->location = (!empty($this->location) ? dol_trunc(trim($this->location), 128) : "");
442 $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private));
443 if (empty($this->percentage)) {
444 $this->percentage = 0;
445 }
446 if (empty($this->priority) || !is_numeric($this->priority)) {
447 $this->priority = 0;
448 }
449 if (empty($this->fulldayevent)) {
450 $this->fulldayevent = 0;
451 }
452 if (empty($this->transparency)) {
453 $this->transparency = 0;
454 }
455 if ($this->percentage > 100) {
456 $this->percentage = 100;
457 }
458 if (empty($this->datep) && $this->datep != '0') { // We should not insert event in calendar without a start date
459 $this->datep = $now;
460 }
461 if (!empty($this->datep) && !empty($this->datef)) {
462 $this->durationp = ($this->datef - $this->datep); // deprecated
463 }
464 if (!empty($this->datep) && !empty($this->datef) && $this->datep > $this->datef) {
465 $this->datef = $this->datep;
466 }
467 if (!isset($this->fk_project) || $this->fk_project < 0) {
468 $this->fk_project = 0;
469 }
470 // For backward compatibility
471 if ($this->elementtype == 'facture') {
472 $this->elementtype = 'invoice';
473 }
474 if ($this->elementtype == 'commande') {
475 $this->elementtype = 'order';
476 }
477 if ($this->elementtype == 'contrat') {
478 $this->elementtype = 'contract';
479 }
480 if (empty($this->fk_element) && !empty($this->elementid)) {
481 $this->fk_element = $this->elementid;
482 }
483
484 if (!is_array($this->userassigned) && !empty($this->userassigned)) { // For backward compatibility when userassigned was an int instead of an array
485 $tmpid = (int) $this->userassigned;
486 $this->userassigned = array();
487 $this->userassigned[$tmpid] = array('id' => $tmpid, 'transparency' => $this->transparency);
488 }
489
490 $userownerid = $this->userownerid;
491
492 // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...).
493 if (empty($this->userassigned) || count($this->userassigned) == 0 || !is_array($this->userassigned)) {
494 $this->userassigned = array($userownerid => array('id' => $userownerid, 'transparency' => $this->transparency));
495 }
496
497 if (!$this->type_id || !$this->type_code) {
498 $key = empty($this->type_id) ? $this->type_code : $this->type_id;
499
500 // Get id from code
501 $cactioncomm = new CActionComm($this->db);
502 $result = $cactioncomm->fetch($key);
503
504 if ($result > 0) {
505 $this->type_id = $cactioncomm->id;
506 $this->type_code = $cactioncomm->code;
507 } elseif ($result == 0) {
508 $this->error = $langs->trans('ErrorActionCommBadType', $this->type_id, $this->type_code);
509 return -1;
510 } else {
511 $this->error = $cactioncomm->error;
512 return -1;
513 }
514 }
515 $code = empty($this->code) ? $this->type_code : $this->code;
516
517 // Check parameters
518 if (!$this->type_id) {
519 $this->error = "ErrorWrongParameters";
520 return -1;
521 }
522
523 $this->db->begin();
524
525 $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm";
526 $sql .= "(ref,";
527 $sql .= "datec,";
528 $sql .= "datep,";
529 $sql .= "datep2,";
530 $sql .= "durationp,"; // deprecated
531 $sql .= "fk_action,";
532 $sql .= "code,";
533 $sql .= "ref_ext,";
534 $sql .= "fk_soc,";
535 $sql .= "fk_project,";
536 $sql .= "note,";
537 $sql .= "fk_contact,";
538 $sql .= "fk_user_author,";
539 $sql .= "fk_user_action,";
540 $sql .= "label,percent,priority,fulldayevent,location,";
541 $sql .= "transparency,";
542 $sql .= "fk_element,";
543 $sql .= "elementtype,";
544 $sql .= "fk_bookcal_calendar,";
545 $sql .= "entity,";
546 $sql .= "extraparams,";
547 // Fields emails
548 $sql .= "email_msgid,";
549 $sql .= "email_from,";
550 $sql .= "email_sender,";
551 $sql .= "email_to,";
552 $sql .= "email_tocc,";
553 $sql .= "email_tobcc,";
554 $sql .= "email_subject,";
555 $sql .= "errors_to,";
556 $sql .= "recurid,";
557 $sql .= "recurrule,";
558 $sql .= "recurdateend,";
559 $sql .= "num_vote,";
560 $sql .= "event_paid,";
561 $sql .= "status,";
562 $sql .= "ip";
563 $sql .= ") VALUES (";
564 $sql .= "'(PROV)', ";
565 $sql .= "'".$this->db->idate($now)."', "; // date creation
566 $sql .= "'".$this->db->idate($this->datep)."', "; // date start event
567 $sql .= (strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : "null").", ";
568 $sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated
569 $sql .= (isset($this->type_id) ? $this->type_id : "null").",";
570 $sql .= ($code ? ("'".$this->db->escape($code)."'") : "null").", ";
571 $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").", ";
572 $sql .= ((isset($this->socid) && $this->socid > 0) ? ((int) $this->socid) : "null").", ";
573 $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? ((int) $this->fk_project) : "null").", ";
574 $sql .= " '".$this->db->escape($this->note_private)."', ";
575 $sql .= ((isset($this->contact_id) && $this->contact_id > 0) ? ((int) $this->contact_id) : "null").", "; // deprecated, use ->socpeopleassigned
576 $sql .= (isset($user->id) && $user->id > 0 ? $user->id : "null").", ";
577 $sql .= ($userownerid > 0 ? $userownerid : "null").", ";
578 $sql .= "'".$this->db->escape($this->label)."', ";
579 $sql .= "'".$this->db->escape($this->percentage)."', ";
580 $sql .= "'".$this->db->escape($this->priority)."', ";
581 $sql .= "'".$this->db->escape($this->fulldayevent)."', ";
582 $sql .= "'".$this->db->escape($this->location)."', ";
583 $sql .= "'".$this->db->escape($this->transparency)."', ";
584 $sql .= (!empty($this->fk_element) ? ((int) $this->fk_element) : "null").", ";
585 $sql .= (!empty($this->elementtype) ? "'".$this->db->escape($this->elementtype)."'" : "null").", ";
586 $sql .= (!empty($this->fk_bookcal_calendar) ? "'".$this->db->escape($this->fk_bookcal_calendar)."'" : "null").", ";
587 $sql .= ((int) $conf->entity).",";
588 $sql .= (!empty($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").", ";
589 // Fields emails
590 $sql .= (!empty($this->email_msgid) ? "'".$this->db->escape($this->email_msgid)."'" : "null").", ";
591 $sql .= (!empty($this->email_from) ? "'".$this->db->escape($this->email_from)."'" : "null").", ";
592 $sql .= (!empty($this->email_sender) ? "'".$this->db->escape($this->email_sender)."'" : "null").", ";
593 $sql .= (!empty($this->email_to) ? "'".$this->db->escape($this->email_to)."'" : "null").", ";
594 $sql .= (!empty($this->email_tocc) ? "'".$this->db->escape($this->email_tocc)."'" : "null").", ";
595 $sql .= (!empty($this->email_tobcc) ? "'".$this->db->escape($this->email_tobcc)."'" : "null").", ";
596 $sql .= (!empty($this->email_subject) ? "'".$this->db->escape($this->email_subject)."'" : "null").", ";
597 $sql .= (!empty($this->errors_to) ? "'".$this->db->escape($this->errors_to)."'" : "null").", ";
598 $sql .= (!empty($this->recurid) ? "'".$this->db->escape($this->recurid)."'" : "null").", ";
599 $sql .= (!empty($this->recurrule) ? "'".$this->db->escape($this->recurrule)."'" : "null").", ";
600 $sql .= (!empty($this->recurdateend) ? "'".$this->db->idate($this->recurdateend)."'" : "null").", ";
601 $sql .= (!empty($this->num_vote) ? (int) $this->num_vote : "null").", ";
602 $sql .= (!empty($this->event_paid) ? (int) $this->event_paid : 0).", ";
603 $sql .= (!empty($this->status) ? (int) $this->status : "0").", ";
604 $sql .= (!empty($this->ip) ? "'".$this->db->escape($this->ip)."'" : "null");
605 $sql .= ")";
606
607 dol_syslog(get_class($this)."::add", LOG_DEBUG);
608 $resql = $this->db->query($sql);
609 if ($resql) {
610 $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm", "id");
611 $this->ref = (string) $this->id;
612 $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm SET ref='".$this->db->escape($this->ref)."' WHERE id=".$this->id;
613 $resql = $this->db->query($sql);
614 if (!$resql) {
615 $error++;
616 dol_syslog('Error to process ref: '.$this->db->lasterror(), LOG_ERR);
617 $this->errors[] = $this->db->lasterror();
618 }
619 // Now insert assigned users
620 if (!$error) {
621 //dol_syslog(var_export($this->userassigned, true));
622 $already_inserted = array();
623 foreach ($this->userassigned as $key => $val) {
624 // Common value with new behavior is to have $val = array('id'=>iduser, 'transparency'=>0|1) and $this->userassigned is an array of iduser => $val.
625 if (!is_array($val)) { // For backward compatibility when $val='id'.
626 $val = array('id' => $val);
627 }
628
629 if ($val['id'] > 0) {
630 if (!empty($already_inserted[$val['id']])) {
631 continue;
632 }
633
634 $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
635 $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'])).")";
636
637 $resql = $this->db->query($sql);
638 if (!$resql) {
639 $error++;
640 dol_syslog('Error to process userassigned: ' . $this->db->lasterror(), LOG_ERR);
641 $this->errors[] = $this->db->lasterror();
642 } else {
643 $already_inserted[$val['id']] = true;
644 }
645 //var_dump($sql);exit;
646 }
647 }
648 }
649
650 if (!$error) {
651 if (!empty($this->socpeopleassigned)) {
652 $already_inserted = array();
653 foreach ($this->socpeopleassigned as $id => $val) {
654 // Common value with new behavior is to have $this->socpeopleassigned an array of idcontact => dummyvalue
655 if (!empty($already_inserted[$id])) {
656 continue;
657 }
658
659 $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
660 $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $id).", 0, 0, 0)";
661
662 $resql = $this->db->query($sql);
663 if (!$resql) {
664 $error++;
665 dol_syslog('Error to process socpeopleassigned: ' . $this->db->lasterror(), LOG_ERR);
666 $this->errors[] = $this->db->lasterror();
667 } else {
668 $already_inserted[$id] = true;
669 }
670 }
671 }
672 }
673
674 if (!$error) {
675 // Actions on extra fields
676 $result = $this->insertExtraFields();
677 if ($result < 0) {
678 $error++;
679 }
680 }
681
682 if (!$error && !$notrigger) {
683 // Call trigger
684 $result = $this->call_trigger('ACTION_CREATE', $user);
685 if ($result < 0) {
686 $error++;
687 }
688 // End call triggers
689 }
690
691 if (!$error) {
692 $this->db->commit();
693 return $this->id;
694 } else {
695 $this->db->rollback();
696 return -1;
697 }
698 } else {
699 $this->db->rollback();
700 $this->error = $this->db->lasterror();
701 return -1;
702 }
703 }
704
712 public function createFromClone(User $fuser, $socid)
713 {
714 global $hookmanager;
715
716 $error = 0;
717
718 $this->db->begin();
719
720 // Load source object
721 $objFrom = clone $this;
722
723 // Retrieve all extrafield
724 // fetch optionals attributes and labels
725 $this->fetch_optionals();
726
727 //$this->fetch_userassigned();
728 $this->fetchResources();
729
730 $this->id = 0;
731 $this->recurid = '';
732 $this->recurrule = '';
733 $this->recurdateend = '';
734
735 // Create clone
736 $this->context['createfromclone'] = 'createfromclone';
737 $result = $this->create($fuser);
738 if ($result < 0) {
739 $error++;
740 }
741
742 if (!$error) {
743 // Hook of thirdparty module
744 if (is_object($hookmanager)) {
745 $parameters = array('objFrom' => $objFrom);
746 $action = '';
747 $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
748 if ($reshook < 0) {
749 $this->setErrorsFromObject($hookmanager);
750 $error++;
751 }
752 }
753
754 // Call trigger
755 $result = $this->call_trigger('ACTION_CLONE', $fuser);
756 if ($result < 0) {
757 $error++;
758 }
759 // End call triggers
760 }
761
762 unset($this->context['createfromclone']);
763
764 // End
765 if (!$error) {
766 $this->db->commit();
767 return $this->id;
768 } else {
769 $this->db->rollback();
770 return -1;
771 }
772 }
773
784 public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '', $loadresources = 1)
785 {
786 global $langs;
787
788 if (empty($id) && empty($ref) && empty($ref_ext) && empty($email_msgid)) {
789 dol_syslog(get_class($this)."::fetch Bad parameters", LOG_WARNING);
790 return -1;
791 }
792
793 $sql = "SELECT a.id,";
794 $sql .= " a.ref as ref,";
795 $sql .= " a.entity,";
796 $sql .= " a.ref_ext,";
797 $sql .= " a.datep,";
798 $sql .= " a.datep2,";
799 $sql .= " a.durationp,"; // deprecated
800 $sql .= " a.datec,";
801 $sql .= " a.tms as datem,";
802 $sql .= " a.code, a.label, a.note as note_private,";
803 $sql .= " a.fk_soc,";
804 $sql .= " a.fk_project,";
805 $sql .= " a.fk_user_author, a.fk_user_mod,";
806 $sql .= " a.fk_user_action,";
807 $sql .= " a.fk_contact, a.percent as percentage,";
808 $sql .= " a.fk_element as elementid, a.elementtype,";
809 $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
810 $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,";
811 $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,";
812 $sql .= " s.nom as socname,";
813 $sql .= " u.firstname, u.lastname as lastname,";
814 $sql .= " num_vote, event_paid, a.status";
815 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a ";
816 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action=c.id ";
817 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author";
818 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
819 $sql .= " WHERE ";
820 if ($ref) {
821 $sql .= " a.ref = '".$this->db->escape($ref)."'";
822 } elseif ($ref_ext) {
823 $sql .= " a.ref_ext = '".$this->db->escape($ref_ext)."'";
824 } elseif ($email_msgid) {
825 $sql .= " a.email_msgid = '".$this->db->escape($email_msgid)."'";
826 } else {
827 $sql .= " a.id = ".((int) $id);
828 }
829
830 dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
831 $resql = $this->db->query($sql);
832 if ($resql) {
833 $num = $this->db->num_rows($resql);
834 if ($num) {
835 $obj = $this->db->fetch_object($resql);
836
837 $this->id = $obj->id;
838 $this->entity = $obj->entity;
839 $this->ref = $obj->ref;
840 $this->ref_ext = $obj->ref_ext;
841
842 // Properties of parent table llx_c_actioncomm
843 $this->type_id = $obj->type_id;
844 $this->type_code = $obj->type_code;
845 $this->type_color = $obj->type_color;
846 $this->type_picto = $obj->type_picto;
847 $this->type = $obj->type_type;
848 /*$transcode = $langs->trans("Action".$obj->type_code);
849 $this->type = (($transcode != "Action".$obj->type_code) ? $transcode : $obj->type_label); */
850 $transcode = $langs->trans("Action".$obj->type_code.'Short');
851
852 $this->code = $obj->code;
853 $this->label = $obj->label;
854 $this->datep = $this->db->jdate($obj->datep);
855 $this->datef = $this->db->jdate($obj->datep2);
856
857 $this->datec = $this->db->jdate($obj->datec);
858 $this->datem = $this->db->jdate($obj->datem);
859
860 $this->note = $obj->note_private; // deprecated
861 $this->note_private = $obj->note_private;
862 $this->percentage = $obj->percentage;
863
864 $this->authorid = $obj->fk_user_author;
865 $this->usermodid = $obj->fk_user_mod;
866
867 if (!is_object($this->author)) {
868 $this->author = new User($this->db); // To avoid warning
869 }
870 $this->author->id = $obj->fk_user_author; // deprecated
871 $this->author->firstname = $obj->firstname; // deprecated
872 $this->author->lastname = $obj->lastname; // deprecated
873 if (!is_object($this->usermod)) {
874 $this->usermod = new User($this->db); // To avoid warning
875 }
876 $this->usermod->id = $obj->fk_user_mod; // deprecated
877
878 $this->userownerid = $obj->fk_user_action;
879 $this->priority = $obj->priority;
880 $this->fulldayevent = $obj->fulldayevent;
881 $this->location = $obj->location;
882 $this->transparency = $obj->transparency;
883
884 $this->socid = $obj->fk_soc; // To have fetch_thirdparty method working
885 $this->contact_id = $obj->fk_contact; // To have fetch_contact method working
886 $this->fk_project = $obj->fk_project; // To have fetch_projet method working
887
888 //$this->societe->id = $obj->fk_soc; // deprecated
889 //$this->contact->id = $obj->fk_contact; // deprecated
890
891 $this->fk_element = $obj->elementid;
892 $this->elementid = $obj->elementid;
893 $this->elementtype = $obj->elementtype;
894
895 $this->num_vote = $obj->num_vote;
896 $this->event_paid = $obj->event_paid;
897 $this->status = $obj->status;
898
899 //email information
900 $this->email_msgid = $obj->email_msgid;
901 $this->email_from = $obj->email_from;
902 $this->email_sender = $obj->email_sender;
903 $this->email_to = $obj->email_to;
904 $this->email_tocc = $obj->email_tocc;
905 $this->email_tobcc = $obj->email_tobcc;
906 $this->email_subject = $obj->email_subject;
907 $this->errors_to = $obj->errors_to;
908
909 $this->fetch_optionals();
910
911 if ($loadresources) {
912 $this->fetchResources();
913 }
914 }
915
916 $this->db->free($resql);
917 } else {
918 $this->error = $this->db->lasterror();
919 return -1;
920 }
921
922 return $num;
923 }
924
930 public function fetchResources()
931 {
932 $this->userassigned = array();
933 $this->socpeopleassigned = array();
934
935 $sql = 'SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency';
936 $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm_resources';
937 $sql .= ' WHERE fk_actioncomm = '.((int) $this->id);
938 $sql .= " AND element_type IN ('user', 'socpeople')";
939 $resql = $this->db->query($sql);
940 if ($resql) {
941 // If owner is known, we must but id first into list
942 if ($this->userownerid > 0) {
943 $this->userassigned[$this->userownerid] = array('id' => $this->userownerid); // Set first so will be first into list.
944 }
945
946 while ($obj = $this->db->fetch_object($resql)) {
947 if ($obj->fk_element > 0) {
948 switch ($obj->element_type) {
949 case 'user':
950 $this->userassigned[$obj->fk_element] = array('id' => $obj->fk_element, 'mandatory' => $obj->mandatory, 'answer_status' => $obj->answer_status, 'transparency' => $obj->transparency);
951 if (empty($this->userownerid)) {
952 $this->userownerid = $obj->fk_element; // If not defined (should not happened, we fix this)
953 }
954 break;
955 case 'socpeople':
956 $this->socpeopleassigned[$obj->fk_element] = array('id' => $obj->fk_element, 'mandatory' => $obj->mandatory, 'answer_status' => $obj->answer_status, 'transparency' => $obj->transparency);
957 break;
958 }
959 }
960 }
961
962 return 1;
963 } else {
964 dol_print_error($this->db);
965 return -1;
966 }
967 }
968
969 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
976 public function fetch_userassigned($override = true)
977 {
978 // phpcs:enable
979 $sql = "SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency";
980 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_resources";
981 $sql .= " WHERE element_type = 'user' AND fk_actioncomm = ".((int) $this->id);
982
983 $resql2 = $this->db->query($sql);
984 if ($resql2) {
985 $this->userassigned = array();
986
987 // If owner is known, we must but id first into list
988 if ($this->userownerid > 0) {
989 // Set first so will be first into list.
990 $this->userassigned[$this->userownerid] = array('id' => $this->userownerid);
991 }
992
993 while ($obj = $this->db->fetch_object($resql2)) {
994 if ($obj->fk_element > 0) {
995 $this->userassigned[$obj->fk_element] = array('id' => $obj->fk_element,
996 'mandatory' => $obj->mandatory,
997 'answer_status' => $obj->answer_status,
998 'transparency' => $obj->transparency);
999 }
1000
1001 if ($override === true) {
1002 // If not defined (should not happened, we fix this)
1003 if (empty($this->userownerid)) {
1004 $this->userownerid = $obj->fk_element;
1005 }
1006 }
1007 }
1008
1009 return 1;
1010 } else {
1011 dol_print_error($this->db);
1012 return -1;
1013 }
1014 }
1015
1023 public function delete($user, $notrigger = 0)
1024 {
1025 $error = 0;
1026
1027 dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1028
1029 $this->db->begin();
1030
1031 // remove categorie association
1032 if (!$error) {
1033 $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_actioncomm";
1034 $sql .= " WHERE fk_actioncomm=".((int) $this->id);
1035
1036 $res = $this->db->query($sql);
1037 if (!$res) {
1038 $this->error = $this->db->lasterror();
1039 $error++;
1040 }
1041 }
1042
1043 // remove actioncomm_resources
1044 if (!$error) {
1045 $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources";
1046 $sql .= " WHERE fk_actioncomm=".((int) $this->id);
1047
1048 $res = $this->db->query($sql);
1049 if (!$res) {
1050 $this->error = $this->db->lasterror();
1051 $error++;
1052 }
1053 }
1054
1055 if (!$error) {
1056 $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
1057 $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
1058
1059 $res = $this->db->query($sql);
1060 if (!$res) {
1061 $this->error = $this->db->lasterror();
1062 $error++;
1063 }
1064 }
1065
1066 // Removed extrafields
1067 if (!$error) {
1068 $result = $this->deleteExtraFields();
1069 if ($result < 0) {
1070 $error++;
1071 dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
1072 }
1073 }
1074
1075 // remove actioncomm
1076 if (!$error) {
1077 $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm";
1078 $sql .= " WHERE id=".((int) $this->id);
1079
1080 $res = $this->db->query($sql);
1081 if (!$res) {
1082 $this->error = $this->db->lasterror();
1083 $error++;
1084 }
1085 }
1086
1087 if (!$error) {
1088 if (!$notrigger) {
1089 // Call trigger
1090 $result = $this->call_trigger('ACTION_DELETE', $user);
1091 if ($result < 0) {
1092 $error++;
1093 }
1094 // End call triggers
1095 }
1096
1097 if (!$error) {
1098 $this->db->commit();
1099 return 1;
1100 } else {
1101 $this->db->rollback();
1102 return -2;
1103 }
1104 } else {
1105 $this->db->rollback();
1106 $this->error = $this->db->lasterror();
1107 return -1;
1108 }
1109 }
1110
1119 public function update(User $user, $notrigger = 0)
1120 {
1121 $error = 0;
1122
1123 // Clean parameters
1124 $this->label = trim($this->label);
1125 $this->note_private = dol_htmlcleanlastbr(trim(!isset($this->note_private) ? $this->note : $this->note_private));
1126 if (empty($this->percentage)) {
1127 $this->percentage = 0;
1128 }
1129 if (empty($this->priority) || !is_numeric($this->priority)) {
1130 $this->priority = 0;
1131 }
1132 if (empty($this->transparency)) {
1133 $this->transparency = 0;
1134 }
1135 if (empty($this->fulldayevent)) {
1136 $this->fulldayevent = 0;
1137 }
1138 if ($this->percentage > 100) {
1139 $this->percentage = 100;
1140 }
1141 //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date;
1142 if ($this->datep && $this->datef) {
1143 $this->durationp = ($this->datef - $this->datep); // deprecated
1144 }
1145 //if ($this->date && $this->dateend) $this->durationa=($this->dateend - $this->date);
1146 if ($this->datep && $this->datef && $this->datep > $this->datef) {
1147 $this->datef = $this->datep;
1148 }
1149 //if ($this->date && $this->dateend && $this->date > $this->dateend) $this->dateend=$this->date;
1150 if ($this->fk_project < 0) {
1151 $this->fk_project = 0;
1152 }
1153
1154 $socid = (($this->socid > 0) ? $this->socid : 0);
1155 $contactid = (($this->contact_id > 0) ? $this->contact_id : 0);
1156 $userownerid = ($this->userownerid ? $this->userownerid : 0);
1157
1158 // If a type_id is set, we must also have the type_code set
1159 if ($this->type_id > 0) {
1160 if (empty($this->type_code)) {
1161 $cactioncomm = new CActionComm($this->db);
1162 $result = $cactioncomm->fetch($this->type_id);
1163 if ($result >= 0 && !empty($cactioncomm->code)) {
1164 $this->type_code = $cactioncomm->code;
1165 }
1166 }
1167 }
1168
1169 $code = $this->code;
1170 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
1171 $code = $this->type_code;
1172 }
1173
1174 $this->db->begin();
1175
1176 $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm";
1177 $sql .= " SET percent = '".$this->db->escape($this->percentage)."'";
1178 $sql .= ", fk_action = ".(int) $this->type_id;
1179 $sql .= ", code = " . ($code ? "'".$this->db->escape($code)."'" : "null");
1180 $sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "null");
1181 $sql .= ", datep = ".(strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : 'null');
1182 $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null');
1183 $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated
1184 $sql .= ", note = '".$this->db->escape($this->note_private)."'";
1185 $sql .= ", fk_project =".($this->fk_project > 0 ? ((int) $this->fk_project) : "null");
1186 $sql .= ", fk_soc =".($socid > 0 ? ((int) $socid) : "null");
1187 $sql .= ", fk_contact =".($contactid > 0 ? ((int) $contactid) : "null");
1188 $sql .= ", priority = '".$this->db->escape($this->priority)."'";
1189 $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'";
1190 $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null");
1191 $sql .= ", transparency = '".$this->db->escape($this->transparency)."'";
1192 $sql .= ", fk_user_mod = ".((int) $user->id);
1193 $sql .= ", fk_user_action = ".($userownerid > 0 ? ((int) $userownerid) : "null");
1194 if (!empty($this->fk_element)) {
1195 $sql .= ", fk_element=".($this->fk_element ? ((int) $this->fk_element) : "null");
1196 }
1197 if (!empty($this->elementtype)) {
1198 $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null");
1199 }
1200 if (!empty($this->num_vote)) {
1201 $sql .= ", num_vote=".($this->num_vote ? (int) $this->num_vote : null);
1202 }
1203 if (!empty($this->event_paid)) {
1204 $sql .= ", event_paid=".($this->event_paid ? (int) $this->event_paid : 0);
1205 }
1206 if (!empty($this->status)) {
1207 $sql .= ", status=".($this->status ? (int) $this->status : 0);
1208 }
1209 $sql .= " WHERE id=".((int) $this->id);
1210
1211 dol_syslog(get_class($this)."::update", LOG_DEBUG);
1212 if ($this->db->query($sql)) {
1213 $action = 'update';
1214
1215 // Actions on extra fields
1216 if (!$error) {
1217 $result = $this->insertExtraFields();
1218 if ($result < 0) {
1219 $error++;
1220 }
1221 }
1222
1223 // Now insert assignedusers
1224 if (!$error) {
1225 $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".((int) $this->id)." AND element_type = 'user'";
1226 $resql = $this->db->query($sql);
1227
1228 $already_inserted = array();
1229 foreach ($this->userassigned as $key => $val) {
1230 if (!is_array($val)) { // For backward compatibility when val=id
1231 $val = array('id' => $val);
1232 }
1233 if (!empty($already_inserted[$val['id']])) {
1234 continue;
1235 }
1236
1237 $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
1238 $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'])).")";
1239
1240 $resql = $this->db->query($sql);
1241 if (!$resql) {
1242 $error++;
1243 $this->errors[] = $this->db->lasterror();
1244 } else {
1245 $already_inserted[$val['id']] = true;
1246 }
1247 //var_dump($sql);exit;
1248 }
1249 }
1250
1251 if (!$error) {
1252 $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".((int) $this->id)." AND element_type = 'socpeople'";
1253 $resql = $this->db->query($sql);
1254
1255 if (!empty($this->socpeopleassigned)) {
1256 $already_inserted = array();
1257 foreach ($this->socpeopleassigned as $val) {
1258 if (!is_array($val)) { // For backward compatibility when val=id
1259 $val = array('id' => $val);
1260 }
1261 if (!empty($already_inserted[$val['id']])) {
1262 continue;
1263 }
1264
1265 $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
1266 $sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $val['id']).", 0, 0, 0)";
1267
1268 $resql = $this->db->query($sql);
1269 if (!$resql) {
1270 $error++;
1271 $this->errors[] = $this->db->lasterror();
1272 } else {
1273 $already_inserted[$val['id']] = true;
1274 }
1275 }
1276 }
1277 }
1278
1279 if (!$error && !$notrigger) {
1280 // Call trigger
1281 $result = $this->call_trigger('ACTION_MODIFY', $user);
1282 if ($result < 0) {
1283 $error++;
1284 }
1285 // End call triggers
1286 }
1287
1288 if (!$error) {
1289 $this->db->commit();
1290 return 1;
1291 } else {
1292 $this->db->rollback();
1293 dol_syslog(get_class($this)."::update ".implode(',', $this->errors), LOG_ERR);
1294 return -2;
1295 }
1296 } else {
1297 $this->db->rollback();
1298 $this->error = $this->db->lasterror();
1299 return -1;
1300 }
1301 }
1302
1316 public function getActions($socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0)
1317 {
1318 global $hookmanager;
1319
1320 $resarray = array();
1321
1322 dol_syslog(get_class()."::getActions", LOG_DEBUG);
1323
1324 // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
1325 if (!is_object($hookmanager)) {
1326 include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
1327 $hookmanager = new HookManager($this->db);
1328 }
1329 $hookmanager->initHooks(array('agendadao'));
1330
1331 $sql = "SELECT a.id";
1332 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
1333 // Fields from hook
1334 $parameters = array('sql' => &$sql, 'socid' => $socid, 'fk_element' => $fk_element, 'elementtype' => $elementtype);
1335 $reshook = $hookmanager->executeHooks('getActionsListFrom', $parameters); // Note that $action and $object may have been modified by hook
1336 if (!empty($hookmanager->resPrint)) {
1337 $sql .= $hookmanager->resPrint;
1338 }
1339 $sql .= " WHERE a.entity IN (".getEntity('agenda').")";
1340 if (!empty($socid)) {
1341 $sql .= " AND a.fk_soc = ".((int) $socid);
1342 }
1343 if (!empty($elementtype)) {
1344 if ($elementtype == 'project') {
1345 $sql .= ' AND a.fk_project = '.((int) $fk_element);
1346 } elseif ($elementtype == 'contact') {
1347 $sql .= ' AND a.id IN';
1348 $sql .= " (SELECT fk_actioncomm FROM ".MAIN_DB_PREFIX."actioncomm_resources WHERE";
1349 $sql .= " element_type = 'socpeople' AND fk_element = ".((int) $fk_element).')';
1350 } else {
1351 $sql .= " AND a.fk_element = ".((int) $fk_element)." AND a.elementtype = '".$this->db->escape($elementtype)."'";
1352 }
1353 }
1354 if (!empty($filter)) {
1355 $sql .= $filter;
1356 }
1357 // Fields where hook
1358 $parameters = array('sql' => &$sql, 'socid' => $socid, 'fk_element' => $fk_element, 'elementtype' => $elementtype);
1359 $reshook = $hookmanager->executeHooks('getActionsListWhere', $parameters); // Note that $action and $object may have been modified by hook
1360 if (!empty($hookmanager->resPrint)) {
1361 $sql .= $hookmanager->resPrint;
1362 }
1363 if ($sortorder && $sortfield) {
1364 $sql .= $this->db->order($sortfield, $sortorder);
1365 }
1366 $sql .= $this->db->plimit($limit, 0);
1367
1368 $resql = $this->db->query($sql);
1369 if ($resql) {
1370 $num = $this->db->num_rows($resql);
1371
1372 if ($num) {
1373 for ($i = 0; $i < $num; $i++) {
1374 $obj = $this->db->fetch_object($resql);
1375 $actioncommstatic = new ActionComm($this->db);
1376 $actioncommstatic->fetch($obj->id);
1377 $resarray[$i] = $actioncommstatic;
1378 }
1379 }
1380 $this->db->free($resql);
1381 return $resarray;
1382 } else {
1383 return $this->db->lasterror();
1384 }
1385 }
1386
1387 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1395 public function load_board($user, $load_state_board = 0)
1396 {
1397 // phpcs:enable
1398 global $conf, $langs;
1399
1400 if (empty($load_state_board)) {
1401 $sql = "SELECT a.id, a.datep as dp";
1402 } else {
1403 $this->nb = array();
1404 $sql = "SELECT count(a.id) as nb";
1405 }
1406 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a";
1407 if (!$user->hasRight('agenda', 'allactions', 'read')) {
1408 $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);
1409 }
1410 $sql .= " WHERE 1 = 1";
1411 if (empty($load_state_board)) {
1412 $sql .= " AND a.percent >= 0 AND a.percent < 100";
1413 }
1414 $sql .= " AND a.entity IN (".getEntity('agenda').")";
1415 if (!$user->hasRight('agenda', 'allactions', 'read')) {
1416 $sql .= " AND (a.fk_user_author = ".((int) $user->id)." OR a.fk_user_action = ".((int) $user->id);
1417 $sql .= " OR ar.fk_element = ".((int) $user->id);
1418 $sql .= ")";
1419 }
1420 // If the internal user must only see his customers, force searching by him
1421 $search_sale = 0;
1422 if (!$user->hasRight('societe', 'client', 'voir')) {
1423 $search_sale = $user->id;
1424 }
1425 // Search on sale representative
1426 if ($search_sale && $search_sale != '-1') {
1427 if ($search_sale == -2) {
1428 $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = a.fk_soc)";
1429 } elseif ($search_sale > 0) {
1430 $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = a.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
1431 }
1432 }
1433
1434 $resql = $this->db->query($sql);
1435 if ($resql) {
1436 $response = null; // Ensure the variable is defined
1437 if (empty($load_state_board)) {
1438 $agenda_static = new ActionComm($this->db);
1439 $response = new WorkboardResponse();
1440 $response->warning_delay = $conf->agenda->warning_delay / 60 / 60 / 24;
1441 $response->label = $langs->trans("ActionsToDo");
1442 $response->labelShort = $langs->trans("ActionsToDoShort");
1443 $response->url = DOL_URL_ROOT.'/comm/action/list.php?mode=show_list&actioncode=0&status=todo&mainmenu=agenda';
1444 if ($user->hasRight("agenda", "allactions", "read")) {
1445 $response->url .= '&filtert=-1';
1446 }
1447 $response->img = img_object('', "action", 'class="inline-block valigntextmiddle"');
1448 }
1449 // This assignment in condition is not a bug. It allows walking the results.
1450 while ($obj = $this->db->fetch_object($resql)) {
1451 if (empty($load_state_board)) {
1452 '@phan-var-force WorkboardResponse $response
1453 @phan-var-force ActionComm $agenda_static';
1454 $response->nbtodo++;
1455 $agenda_static->datep = $this->db->jdate($obj->dp);
1456 if ($agenda_static->hasDelay()) {
1457 $response->nbtodolate++;
1458 }
1459 } else {
1460 $this->nb["actionscomm"] = $obj->nb;
1461 }
1462 }
1463
1464 $this->db->free($resql);
1465 if (empty($load_state_board) && $response instanceof WorkboardResponse) {
1466 return $response;
1467 } else {
1468 return 1;
1469 }
1470 } else {
1471 dol_print_error($this->db);
1472 $this->error = $this->db->error();
1473 return -1;
1474 }
1475 }
1476
1477
1484 public function info($id)
1485 {
1486 $sql = 'SELECT ';
1487 $sql .= ' a.id,';
1488 $sql .= ' datec,';
1489 $sql .= ' tms as datem,';
1490 $sql .= ' fk_user_author,';
1491 $sql .= ' fk_user_mod';
1492 $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a';
1493 $sql .= ' WHERE a.id = '.((int) $id);
1494
1495 dol_syslog(get_class($this)."::info", LOG_DEBUG);
1496 $result = $this->db->query($sql);
1497 if ($result) {
1498 if ($this->db->num_rows($result)) {
1499 $obj = $this->db->fetch_object($result);
1500
1501 $this->id = $obj->id;
1502
1503 $this->user_creation_id = $obj->fk_user_author;
1504 $this->user_modification_id = $obj->fk_user_mod;
1505 $this->date_creation = $this->db->jdate($obj->datec);
1506 $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
1507 }
1508 $this->db->free($result);
1509 } else {
1510 dol_print_error($this->db);
1511 }
1512 }
1513
1514
1522 public function getLibStatut($mode, $hidenastatus = 0)
1523 {
1524 return $this->LibStatut($this->percentage, $mode, $hidenastatus, $this->datep);
1525 }
1526
1527 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1537 public function LibStatut($percent, $mode, $hidenastatus = 0, $datestart = '')
1538 {
1539 // phpcs:enable
1540 global $langs;
1541
1542 $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable');
1543 if ($percent == -1 && !$hidenastatus) {
1544 $labelStatus = $langs->transnoentitiesnoconv('StatusNotApplicable');
1545 } elseif ($percent == 0) {
1546 $labelStatus = $langs->transnoentitiesnoconv('StatusActionToDo').' (0%)';
1547 } elseif ($percent > 0 && $percent < 100) {
1548 $labelStatus = $langs->transnoentitiesnoconv('StatusActionInProcess').' ('.$percent.'%)';
1549 } elseif ($percent >= 100) {
1550 $labelStatus = $langs->transnoentitiesnoconv('StatusActionDone').' (100%)';
1551 }
1552
1553 $labelStatusShort = $langs->transnoentitiesnoconv('StatusNotApplicable');
1554 if ($percent == -1 && !$hidenastatus) {
1555 $labelStatusShort = $langs->trans('NA');
1556 } elseif ($percent == 0) {
1557 $labelStatusShort = '0%';
1558 } elseif ($percent > 0 && $percent < 100) {
1559 $labelStatusShort = $percent.'%';
1560 } elseif ($percent >= 100) {
1561 $labelStatusShort = '100%';
1562 }
1563
1564 $statusType = 'status9';
1565 if ($percent == -1 && !$hidenastatus) {
1566 $statusType = 'status9';
1567 }
1568 if ($percent == 0) {
1569 $statusType = 'status1';
1570 }
1571 if ($percent > 0 && $percent < 100) {
1572 $statusType = 'status3';
1573 }
1574 if ($percent >= 100) {
1575 $statusType = 'status6';
1576 }
1577
1578 return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode);
1579 }
1580
1587 public function getTooltipContentArray($params)
1588 {
1589 global $conf, $langs, $user;
1590 $langs->load('agenda');
1591
1592 $datas = array();
1593 $nofetch = !empty($params['nofetch']);
1594
1595 // Set label of type
1596 $labeltype = '';
1597 if ($this->type_code) {
1598 $langs->load("commercial");
1599 $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label;
1600 }
1601 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1602 if ($this->type_code != 'AC_OTH_AUTO') {
1603 $labeltype = $langs->trans('ActionAC_MANUAL');
1604 }
1605 }
1606 $datas['picto'] = img_picto('', $this->picto).' <u>'.$langs->trans('Action').'</u>';
1607 if (!empty($this->ref)) {
1608 $datas['ref'] = '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
1609 }
1610 if (!empty($this->label)) {
1611 $datas['title'] = '<br><b>'.$langs->trans('Title').':</b> '.dol_escape_htmltag($this->label);
1612 }
1613 if (!empty($labeltype)) {
1614 $datas['labeltype'] = '<br><b>'.$langs->trans('Type').':</b> '.dol_escape_htmltag($labeltype);
1615 }
1616 if (!empty($this->location)) {
1617 $datas['location'] = '<br><b>'.$langs->trans('Location').':</b> '.dol_escape_htmltag($this->location);
1618 }
1619 if (isset($this->transparency)) {
1620 $datas['transparency'] = '<br><b>'.$langs->trans('Busy').':</b> '.yn($this->transparency);
1621 }
1622 if (!empty($this->email_msgid)) {
1623 $langs->load("mails");
1624 $datas['space'] = '<br>';
1625 // $datas['email'] = '<br><b>'.img_picto('', 'email').' '.$langs->trans("Email").'</b>';
1626 $datas['mailtopic'] = '<br><b>'.$langs->trans('MailTopic').':</b> '.dol_escape_htmltag($this->email_subject);
1627 $datas['mailfrom'] = '<br><b>'.$langs->trans('MailFrom').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_from);
1628 $datas['mailto'] = '<br><b>'.$langs->trans('MailTo').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_to);
1629 if (!empty($this->email_tocc)) {
1630 $datas['mailcc'] = '<br><b>'.$langs->trans('MailCC').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_tocc);
1631 }
1632 /* Disabled because bcc must remain by definition not visible
1633 if (!empty($this->email_tobcc)) {
1634 $datas['mailccc'] = '<br><b>'.$langs->trans('MailCCC').':</b> '.$this->email_tobcc;
1635 } */
1636 }
1637 if (!empty($this->note_private)) {
1638 $datas['description'] = '<br><b>'.$langs->trans('Description').':</b><br>';
1639 // Try to limit length of content
1640 $texttoshow = dolGetFirstLineOfText($this->note_private, 10);
1641 // Restrict height of content into the tooltip
1642 $datas['note'] = '<div class="tenlinesmax">';
1643 $datas['note'] .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
1644 $datas['note'] .= '</div>';
1645 }
1646 // show categories for this record only in ajax to not overload lists
1647 if (isModEnabled('category') && !$nofetch) {
1648 require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
1649 $form = new Form($this->db);
1650 $datas['categories'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_ACTIONCOMM, 1);
1651 }
1652
1653 return $datas;
1654 }
1655
1669 public function getNomUrl($withpicto = 0, $maxlength = 0, $classname = '', $option = '', $overwritepicto = 0, $notooltip = 0, $save_lastsearch_value = -1)
1670 {
1671 global $conf, $langs, $user, $hookmanager, $action;
1672
1673 if (!empty($conf->dol_no_mouse_hover)) {
1674 $notooltip = 1; // Force disable tooltips
1675 }
1676
1677 $canread = 0;
1678 if ($user->hasRight('agenda', 'myactions', 'read') && ($this->authorid == $user->id || $this->userownerid == $user->id)) {
1679 $canread = 1; // Can read my event
1680 }
1681 if ($user->hasRight('agenda', 'myactions', 'read') && array_key_exists($user->id, $this->userassigned)) {
1682 $canread = 1; // Can read my event i am assigned
1683 }
1684 if ($user->hasRight('agenda', 'allactions', 'read')) {
1685 $canread = 1; // Can read all event of other
1686 }
1687 if (!$canread) {
1688 $option = 'nolink';
1689 }
1690
1691 $label = $this->label;
1692
1693 $result = '';
1694
1695 // Set label of type
1696 $labeltype = '';
1697 if ($this->type_code) {
1698 $langs->load("commercial");
1699 $labeltype = ($langs->transnoentities("Action".$this->type_code) != "Action".$this->type_code) ? $langs->transnoentities("Action".$this->type_code) : $this->type_label;
1700 }
1701 if (!getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1702 if ($this->type_code != 'AC_OTH_AUTO') {
1703 $labeltype = $langs->trans('ActionAC_MANUAL');
1704 }
1705 }
1706
1707 $tooltip = img_picto('', $this->picto).' <u>'.$langs->trans('Action').'</u>';
1708 if (!empty($this->ref)) {
1709 $tooltip .= '<br><b>'.$langs->trans('Ref').':</b> '.dol_escape_htmltag($this->ref);
1710 }
1711 if (!empty($label)) {
1712 $tooltip .= '<br><b>'.$langs->trans('Title').':</b> '.dol_escape_htmltag($label);
1713 }
1714 if (!empty($labeltype)) {
1715 $tooltip .= '<br><b>'.$langs->trans('Type').':</b> '.dol_escape_htmltag($labeltype);
1716 }
1717 if (!empty($this->location)) {
1718 $tooltip .= '<br><b>'.$langs->trans('Location').':</b> '.dol_escape_htmltag($this->location);
1719 }
1720 if (isset($this->transparency)) {
1721 $tooltip .= '<br><b>'.$langs->trans('Busy').':</b> '.yn($this->transparency);
1722 }
1723 if (!empty($this->email_msgid)) {
1724 $langs->load("mails");
1725 $tooltip .= '<br>';
1726 //$tooltip .= '<br><b>'.img_picto('', 'email').' '.$langs->trans("Email").'</b>';
1727 $tooltip .= '<br><b>'.$langs->trans('MailTopic').':</b> '.dol_escape_htmltag($this->email_subject);
1728 $tooltip .= '<br><b>'.$langs->trans('MailFrom').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), !empty($this->email_from) ? $this->email_from : '');
1729 $tooltip .= '<br><b>'.$langs->trans('MailTo').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), !empty($this->email_to) ? $this->email_to : '');
1730 if (!empty($this->email_tocc)) {
1731 $tooltip .= '<br><b>'.$langs->trans('MailCC').':</b> '.str_replace(array('<', '>'), array('&amp;lt', '&amp;gt'), $this->email_tocc);
1732 }
1733 /* Disabled because bcc must remain by definition not visible
1734 if (!empty($this->email_tobcc)) {
1735 $tooltip .= '<br><b>'.$langs->trans('MailCCC').':</b> '.$this->email_tobcc;
1736 } */
1737 }
1738 if (!empty($this->note_private)) {
1739 $tooltip .= '<br><br><b>'.$langs->trans('Description').':</b><br>';
1740 $texttoshow = dolGetFirstLineOfText($this->note_private, 8); // Try to limit length of content
1741 $tooltip .= '<div class="tenlinesmax">'; // Restrict height of content into the tooltip
1742 $tooltip .= (dol_textishtml($texttoshow) ? str_replace(array("\r", "\n"), "", $texttoshow) : str_replace(array("\r", "\n"), '<br>', $texttoshow));
1743 $tooltip .= '</div>';
1744 }
1745 $linkclose = '';
1746 $classfortooltip = 'classfortooltip';
1747 $dataparams = '';
1748 if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
1749 $params = [
1750 'id' => $this->id,
1751 'objecttype' => $this->element,
1752 'option' => $option,
1753 'nofetch' => 1,
1754 ];
1755 $classfortooltip = 'classforajaxtooltip';
1756 $dataparams = ' data-params="'.dol_escape_htmltag(json_encode($params)).'"';
1757 $tooltip = '';
1758 }
1759 if (empty($notooltip)) {
1760 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
1761 $label = $langs->trans("ShowAction");
1762 $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"';
1763 }
1764 $linkclose .= ($tooltip ? ' title="'.dol_escape_htmltag($tooltip, 1).'"' : ' title="tocomplete"');
1765 $linkclose .= $dataparams.' class="'.$classname.' '.$classfortooltip.'"';
1766 } else {
1767 $linkclose .= ' class="'.$classname.'"';
1768 }
1769
1770 $url = '';
1771 if ($option == 'birthday') {
1772 $url = DOL_URL_ROOT.'/contact/perso.php?id='.$this->id;
1773 } elseif ($option == 'holiday') {
1774 $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id;
1775 } else {
1776 $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id;
1777 }
1778
1779 if ($option !== 'nolink') {
1780 // Add param to save lastsearch_values or not
1781 $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
1782 if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
1783 $add_save_lastsearch_values = 1;
1784 }
1785 if ($add_save_lastsearch_values) {
1786 $url .= '&save_lastsearch_values=1';
1787 }
1788 }
1789
1790 $linkstart = '<a href="'.$url.'"';
1791 $linkstart .= $linkclose.'>';
1792 $linkend = '</a>';
1793
1794 if ($option == 'nolink') {
1795 $linkstart = '';
1796 $linkend = '';
1797 }
1798
1799 if ($withpicto == 2) {
1800 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1801 $label = $labeltype;
1802 }
1803 $labelshort = '';
1804 } else {
1805 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE') && empty($label)) {
1806 $label = $labeltype;
1807 }
1808 if ($maxlength < 0) {
1809 $labelshort = $this->ref;
1810 } else {
1811 $labelshort = dol_trunc($label, $maxlength);
1812 }
1813 }
1814
1815 if ($withpicto) {
1816 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) { // Add code into ()
1817 if ($labeltype) {
1818 $label .= (preg_match('/'.preg_quote($labeltype, '/').'/', $label) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')');
1819 }
1820 }
1821 }
1822
1823 $result .= $linkstart;
1824 if ($withpicto) {
1825 $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);
1826 }
1827 $result .= dol_escape_htmltag($labelshort);
1828 $result .= $linkend;
1829
1830 global $action;
1831 $hookmanager->initHooks(array('actiondao'));
1832 $parameters = array('id' => $this->id, 'getnomurl' => &$result);
1833 $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1834 if ($reshook > 0) {
1835 $result = $hookmanager->resPrint;
1836 } else {
1837 $result .= $hookmanager->resPrint;
1838 }
1839
1840 return $result;
1841 }
1842
1850 public function getTypePicto($morecss = 'pictofixedwidth paddingright valignmiddle', $titlealt = '')
1851 {
1852 global $conf;
1853
1854 $imgpicto = '';
1855 if (getDolGlobalString('AGENDA_USE_EVENT_TYPE')) {
1856 $color = '';
1857 if ($this->type_color) {
1858 $color = 'style="color: #'.$this->type_color.' !important;"';
1859 }
1860 if ($this->type_picto) {
1861 $imgpicto = img_picto($titlealt, $this->type_picto, '', false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1862 } else {
1863 if ($this->type_code == 'AC_RDV') {
1864 $imgpicto = img_picto($titlealt, 'meeting', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1865 } elseif ($this->type_code == 'AC_TEL') {
1866 $imgpicto = img_picto($titlealt, 'object_phoning', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1867 } elseif ($this->type_code == 'AC_FAX') {
1868 $imgpicto = img_picto($titlealt, 'object_phoning_fax', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1869 } elseif ($this->type_code == 'AC_EMAIL' || $this->type_code == 'AC_EMAIL_IN' || (!empty($this->code) && preg_match('/_SENTBYMAIL/', $this->code))) {
1870 $imgpicto = img_picto($titlealt, 'object_email', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1871 } elseif ($this->type_code == 'AC_INT') {
1872 $imgpicto = img_picto($titlealt, 'object_intervention', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1873 } elseif (!empty($this->code) && preg_match('/^TICKET_MSG/', $this->code)) {
1874 $imgpicto = img_picto($titlealt, 'object_conversation', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1875 } elseif ($this->type != 'systemauto') {
1876 $imgpicto = img_picto($titlealt, 'user-cog', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1877 } else {
1878 $imgpicto = img_picto($titlealt, 'cog', $color, false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1879 }
1880 }
1881 } else {
1882 // 2 picto: 1 for auto, 1 for manual
1883 if ($this->type != 'systemauto') {
1884 $imgpicto = img_picto($titlealt, 'user-cog', '', false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1885 } else {
1886 $imgpicto = img_picto($titlealt, 'cog', '', false, 0, 0, '', ($morecss ? ' '.$morecss : ''));
1887 }
1888 }
1889
1890 return $imgpicto;
1891 }
1892
1893
1904 public function setCategories($categories)
1905 {
1906 // Handle single category
1907 if (!is_array($categories)) {
1908 $categories = array($categories);
1909 }
1910
1911 // Get current categories
1912 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1913 $c = new Categorie($this->db);
1914 $existing = $c->containing($this->id, Categorie::TYPE_ACTIONCOMM, 'id');
1915
1916 // Diff
1917 if (is_array($existing)) {
1918 $to_del = array_diff($existing, $categories);
1919 $to_add = array_diff($categories, $existing);
1920 } else {
1921 $to_del = array(); // Nothing to delete
1922 $to_add = $categories;
1923 }
1924
1925 // Process
1926 foreach ($to_del as $del) {
1927 if ($c->fetch($del) > 0) {
1928 $c->del_type($this, Categorie::TYPE_ACTIONCOMM);
1929 }
1930 }
1931 foreach ($to_add as $add) {
1932 if ($c->fetch($add) > 0) {
1933 $c->add_type($this, Categorie::TYPE_ACTIONCOMM);
1934 }
1935 }
1936 return 1;
1937 }
1938
1939 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1951 public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0)
1952 {
1953 global $hookmanager;
1954
1955 // phpcs:enable
1956 global $conf, $langs, $dolibarr_main_url_root, $mysoc;
1957
1958 require_once DOL_DOCUMENT_ROOT."/core/lib/xcal.lib.php";
1959 require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php";
1960 require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
1961
1962 dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG);
1963
1964 // Check parameters
1965 if (empty($format)) {
1966 return -1;
1967 }
1968
1969 // Clean parameters
1970 if (!$filename) {
1971 $extension = 'vcs';
1972 if ($format == 'ical') {
1973 $extension = 'ics';
1974 }
1975 $filename = $format.'.'.$extension;
1976 }
1977
1978 // Create dir and define output file (definitive and temporary)
1979 $result = dol_mkdir($conf->agenda->dir_temp);
1980 $outputfile = $conf->agenda->dir_temp.'/'.$filename;
1981
1982 $result = 0;
1983
1984 $buildfile = true;
1985 $login = '';
1986 $logina = '';
1987 $logint = '';
1988 $eventorganization = '';
1989
1990 $now = dol_now();
1991
1992 if ($cachedelay) {
1993 $nowgmt = dol_now();
1994 include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1995 if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay)) {
1996 dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled");
1997 $buildfile = false;
1998 }
1999 }
2000
2001 if ($buildfile) {
2002 // Build event array
2003 $eventarray = array();
2004
2005 if (!empty($filters['module']) && $filters['module'] == 'project@eventorganization') {
2006 $sql = "SELECT p.rowid as id,";
2007 $sql .= " p.date_start_event as datep,"; // Start
2008 $sql .= " p.date_end_event as datep2,"; // End
2009 $sql .= " p.datec, p.tms as datem,";
2010 $sql .= " p.title as label, '' as code, p.note_public, p.note_private, 0 as type_id,";
2011 $sql .= " p.fk_soc,";
2012 $sql .= " p.fk_user_creat as fk_user_author, p.fk_user_modif as fk_user_mod,";
2013 $sql .= " 0 as fk_user_action,";
2014 $sql .= " 0 as fk_contact, 100 as percentage,";
2015 $sql .= " 0 as fk_element, '' as elementtype,";
2016 $sql .= " 1 as priority, 0 as fulldayevent, p.location, 0 as transparency,";
2017 $sql .= " u.firstname, u.lastname, '".$this->db->escape(getDolGlobalString("MAIN_INFO_SOCIETE_MAIL"))."' as email,";
2018 $sql .= " s.nom as socname,";
2019 $sql .= " 0 as type_id, '' as type_code, '' as type_label";
2020 $sql .= " FROM ".MAIN_DB_PREFIX."projet as p";
2021 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = p.fk_user_creat"; // Link to get author of event for export
2022 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = p.fk_soc";
2023
2024 $parameters = array('filters' => $filters);
2025 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
2026 $sql .= $hookmanager->resPrint;
2027
2028 $sql .= " WHERE p.entity IN (".getEntity('project').")";
2029
2030 foreach ($filters as $key => $value) {
2031 if ($key == 'notolderthan' && $value != '') {
2032 $sql .= " AND p.date_start_event >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'";
2033 }
2034 if ($key == 'year') {
2035 $sql .= " AND p.date_start_event BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'";
2036 }
2037 if ($key == 'id') {
2038 $sql .= " AND p.id = ".(is_numeric($value) ? $value : 0);
2039 }
2040 if ($key == 'idfrom') {
2041 $sql .= " AND p.id >= ".(is_numeric($value) ? $value : 0);
2042 }
2043 if ($key == 'idto') {
2044 $sql .= " AND p.id <= ".(is_numeric($value) ? $value : 0);
2045 }
2046 if ($key == 'project') {
2047 $sql .= " AND p.rowid = ".(is_numeric($value) ? $value : 0);
2048 }
2049 if ($key == 'status') {
2050 $sql .= " AND p.fk_statut = ".((int) $value);
2051 }
2052 // TODO Add filters on event code of meetings/talks only
2053 }
2054
2055 $sql .= " ORDER by date_start_event";
2056
2057 $eventorganization = 'project';
2058 } else {
2059 $sql = "SELECT a.id,";
2060 $sql .= " a.datep,"; // Start
2061 $sql .= " a.datep2,"; // End
2062 $sql .= " a.datec, a.tms as datem,";
2063 $sql .= " a.label, a.code, '' as note_public, a.note as note_private, a.fk_action as type_id,";
2064 $sql .= " a.fk_soc,";
2065 $sql .= " a.fk_user_author, a.fk_user_mod,";
2066 $sql .= " a.fk_user_action,";
2067 $sql .= " a.fk_contact, a.percent as percentage,";
2068 $sql .= " a.fk_element, a.elementtype,";
2069 $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,";
2070 $sql .= " u.firstname, u.lastname, u.email,";
2071 $sql .= " s.nom as socname,";
2072 $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label,";
2073 $sql .= " num_vote, event_paid, a.status";
2074 $sql .= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)";
2075 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export
2076 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc";
2077
2078 $parameters = array('filters' => $filters);
2079 $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
2080 $sql .= $hookmanager->resPrint;
2081
2082 // We must filter on assignment table
2083 if (!empty($filters['logint']) && $filters['logint']) {
2084 $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar";
2085 }
2086 $sql .= " WHERE a.fk_action = c.id";
2087 $sql .= " AND a.entity IN (".getEntity('agenda').")";
2088
2089 foreach ($filters as $key => $value) {
2090 if ($key == 'notolderthan' && $value != '') {
2091 $sql .= " AND a.datep >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'";
2092 }
2093 if ($key == 'year') {
2094 $sql .= " AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'";
2095 }
2096 if ($key == 'id') {
2097 $sql .= " AND a.id = ".(is_numeric($value) ? $value : 0);
2098 }
2099 if ($key == 'idfrom') {
2100 $sql .= " AND a.id >= ".(is_numeric($value) ? $value : 0);
2101 }
2102 if ($key == 'idto') {
2103 $sql .= " AND a.id <= ".(is_numeric($value) ? $value : 0);
2104 }
2105 if ($key == 'project') {
2106 $sql .= " AND a.fk_project = ".(is_numeric($value) ? $value : 0);
2107 }
2108 if ($key == 'notactiontype') { // deprecated
2109 $sql .= " AND c.type <> '".$this->db->escape($value)."'";
2110 }
2111 if ($key == 'actiontype') { // 'system', 'systemauto', 'module', ...
2112 $newvalue = $value;
2113 $usenotin = 0;
2114 if (preg_match('/^!/', $newvalue)) {
2115 $newvalue = preg_replace('/^!/', '', $value);
2116 $usenotin = 1;
2117 }
2118 $arraynewvalue = explode(',', $newvalue);
2119 $newvalue = "";
2120 foreach ($arraynewvalue as $tmpval) {
2121 $newvalue .= ($newvalue ? "," : "")."'".$tmpval."'";
2122 }
2123 if ($usenotin) {
2124 $sql .= " AND c.type NOT IN (".$this->db->sanitize($newvalue, 1).")";
2125 } else {
2126 $sql .= " AND c.type IN (".$this->db->sanitize($newvalue, 1).")";
2127 }
2128 }
2129 if ($key == 'actioncode') { // 'AC_COMPANY_CREATE', 'AC_COMPANY_MODIFY', ...
2130 $newvalue = $value;
2131 $usenotin = 0;
2132 if (preg_match('/^!/', $newvalue)) {
2133 $newvalue = preg_replace('/^!/', '', $value);
2134 $usenotin = 1;
2135 }
2136 $arraynewvalue = explode(',', $newvalue);
2137 $newvalue = "";
2138 foreach ($arraynewvalue as $tmpval) {
2139 $newvalue .= ($newvalue ? "," : "")."'".$tmpval."'";
2140 }
2141 if ($usenotin) {
2142 $sql .= " AND a.code NOT IN (".$this->db->sanitize($newvalue, 1).")";
2143 } else {
2144 $sql .= " AND a.code IN (".$this->db->sanitize($newvalue, 1).")";
2145 }
2146 }
2147
2148 // We must filter on assignment table
2149 if ($key == 'logint') {
2150 $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
2151 }
2152 if ($key == 'logina') {
2153 $logina = $value;
2154 $condition = '=';
2155 if (preg_match('/^!/', $logina)) {
2156 $logina = preg_replace('/^!/', '', $logina);
2157 $condition = '<>';
2158 }
2159 $userforfilter = new User($this->db);
2160 $result = $userforfilter->fetch(0, $logina);
2161 if ($result > 0) {
2162 $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id;
2163 } elseif ($result < 0 || $condition == '=') {
2164 $sql .= " AND a.fk_user_author = 0";
2165 }
2166 }
2167 if ($key == 'logint') {
2168 $logint = $value;
2169 $condition = '=';
2170 if (preg_match('/^!/', $logint)) {
2171 $logint = preg_replace('/^!/', '', $logint);
2172 $condition = '<>';
2173 }
2174 $userforfilter = new User($this->db);
2175 $result = $userforfilter->fetch(0, $logint);
2176 if ($result > 0) {
2177 $sql .= " AND ar.fk_element = ".((int) $userforfilter->id);
2178 } elseif ($result < 0 || $condition == '=') {
2179 $sql .= " AND ar.fk_element = 0";
2180 }
2181 }
2182 if ($key == 'module') {
2183 if ($value == 'conforbooth@eventorganization') {
2184 $value = '@eventorganization';
2185 }
2186 $sql .= " AND c.module LIKE '%".$this->db->escape($value)."'";
2187 }
2188 if ($key == 'status') {
2189 $sql .= " AND a.status = ".((int) $value);
2190 }
2191 }
2192
2193 $sql .= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import
2194
2195 $parameters = array('filters' => $filters);
2196 $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
2197 $sql .= $hookmanager->resPrint;
2198
2199 $sql .= " ORDER by datep";
2200 }
2201
2202 if (!empty($filters['limit'])) {
2203 $sql .= $this->db->plimit((int) $filters['limit']);
2204 }
2205
2206 //print $sql;exit;
2207
2208 dol_syslog(get_class($this)."::build_exportfile select event(s)", LOG_DEBUG);
2209
2210 $resql = $this->db->query($sql);
2211 if ($resql) {
2212 $diff = 0;
2213 while ($obj = $this->db->fetch_object($resql)) {
2214 $qualified = true;
2215
2216 // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author'
2217 $event = array();
2218 $event['uid'] = 'dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"];
2219 $event['type'] = $type;
2220
2221 $datestart = $this->db->jdate($obj->datep) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2222
2223 // fix for -> Warning: A non-numeric value encountered
2224 if (is_numeric($this->db->jdate($obj->datep2))) {
2225 $dateend = $this->db->jdate($obj->datep2) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2226 } else {
2227 // use start date as fall-back to avoid pb with empty end date on ICS readers
2228 $dateend = $datestart;
2229 }
2230
2231 $duration = ($datestart && $dateend) ? ($dateend - $datestart) : 0;
2232 $event['summary'] = $obj->label.($obj->socname ? " (".$obj->socname.")" : "");
2233
2234 if (!empty($filters['module']) && $filters['module'] == 'project@eventorganization') {
2235 $event['desc'] = $obj->note_public;
2236 } else {
2237 $event['desc'] = $obj->note_private;
2238 }
2239 $event['startdate'] = $datestart;
2240 $event['enddate'] = $dateend; // Not required with type 'journal'
2241 $event['duration'] = $duration; // Not required with type 'journal'
2242 $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2243 $event['priority'] = $obj->priority;
2244 $event['fulldayevent'] = $obj->fulldayevent;
2245 $event['location'] = $obj->location;
2246 $event['transparency'] = (($obj->transparency > 0) ? 'OPAQUE' : 'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy)
2247 $event['category'] = $obj->type_label;
2248 $event['email'] = $obj->email;
2249
2250 // Public URL of event
2251 if ($eventorganization != '') {
2252 $link_subscription = $dolibarr_main_url_root.'/public/eventorganization/attendee_new.php?id='.((int) $obj->id).'&type=global&noregistration=1';
2253 $encodedsecurekey = dol_hash(getDolGlobalString('EVENTORGANIZATION_SECUREKEY').'conferenceorbooth'.((int) $obj->id), 'md5');
2254 $link_subscription .= '&securekey='.urlencode($encodedsecurekey);
2255
2256 $event['url'] = $link_subscription;
2257 }
2258
2259 $event['created'] = $this->db->jdate($obj->datec) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2260 $event['modified'] = $this->db->jdate($obj->datem) - (!getDolGlobalString('AGENDA_EXPORT_FIX_TZ') ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600));
2261 $event['num_vote'] = $this->num_vote;
2262 $event['event_paid'] = $this->event_paid;
2263 $event['status'] = $this->status;
2264
2265 // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties
2266 $this->id = $obj->id;
2267 $this->fetch_userassigned(false);
2268
2269 $assignedUserArray = array();
2270
2271 foreach ($this->userassigned as $key => $value) {
2272 $assignedUser = new User($this->db);
2273 $assignedUser->fetch($value['id']);
2274
2275 $assignedUserArray[$key] = $assignedUser;
2276 }
2277
2278 $event['assignedUsers'] = $assignedUserArray;
2279
2280 if ($qualified && $datestart) {
2281 $eventarray[] = $event;
2282 }
2283 $diff++;
2284 }
2285
2286 $parameters = array('filters' => $filters, 'eventarray' => &$eventarray);
2287 $reshook = $hookmanager->executeHooks('addMoreEventsExport', $parameters); // Note that $action and $object may have been modified by hook
2288 if ($reshook > 0) {
2289 $eventarray = $hookmanager->resArray;
2290 }
2291 } else {
2292 $this->error = $this->db->lasterror();
2293 return -1;
2294 }
2295
2296 if ($exportholiday == 1) {
2297 $langs->load("holiday");
2298 $title = $langs->transnoentities("Holidays");
2299
2300 $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";
2301 $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u";
2302 $sql .= " WHERE u.rowid = x.fk_user";
2303 $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user)
2304 $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved)
2305
2306 $resql = $this->db->query($sql);
2307 if ($resql) {
2308 $num = $this->db->num_rows($resql);
2309 $i = 0;
2310
2311 while ($i < $num) {
2312 $obj = $this->db->fetch_object($resql);
2313 $event = array();
2314
2315 if ($obj->halfday == 1) {
2316 $event['fulldayevent'] = false;
2317
2318 $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2319 $timestampEnd = dol_stringtotime($obj->date_end." 12:00:00", 0);
2320 } elseif ($obj->halfday == -1) {
2321 $event['fulldayevent'] = false;
2322
2323 $timestampStart = dol_stringtotime($obj->date_start." 12:00:00", 0);
2324 $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2325 } else {
2326 $event['fulldayevent'] = true;
2327
2328 $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0);
2329 $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0);
2330 }
2331
2332 if (getDolGlobalString('AGENDA_EXPORT_FIX_TZ')) {
2333 $timestampStart -= ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2334 $timestampEnd -= ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600);
2335 }
2336
2337 $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
2338 $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT;
2339 $url = $urlwithroot.'/holiday/card.php?id='.$obj->rowid;
2340
2341 $event['uid'] = 'dolibarrholiday-'.$this->db->database_name.'-'.$obj->rowid."@".$_SERVER["SERVER_NAME"];
2342 $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2343 $event['type'] = 'event';
2344 $event['category'] = "Holiday";
2345 $event['transparency'] = 'OPAQUE';
2346 $event['email'] = $obj->email;
2347 $event['created'] = $timestampStart;
2348 $event['modified'] = $timestampStart;
2349 $event['startdate'] = $timestampStart;
2350 $event['enddate'] = $timestampEnd;
2351 $event['duration'] = $timestampEnd - $timestampStart;
2352 $event['url'] = $url;
2353
2354 if ($obj->status == 2) {
2355 // 2 = leave wait for approval
2356 $event['summary'] = $title." - ".$obj->lastname." (wait for approval)";
2357 } else {
2358 // 3 = leave approved
2359 $event['summary'] = $title." - ".$obj->lastname;
2360 }
2361
2362 $eventarray[] = $event;
2363
2364 $i++;
2365 }
2366 }
2367 }
2368
2369 $langs->load("agenda");
2370
2371 // Define title and desc
2372 $title = '';
2373 $more = '';
2374 if ($login) {
2375 $more = $langs->transnoentities("User").' '.$login;
2376 }
2377 if ($logina) {
2378 $more = $langs->transnoentities("ActionsAskedBy").' '.$logina;
2379 }
2380 if ($logint) {
2381 $more = $langs->transnoentities("ActionsToDoBy").' '.$logint;
2382 }
2383 if ($eventorganization) {
2384 $langs->load("eventorganization");
2385 $title = $langs->transnoentities("OrganizedEvent").(empty($eventarray[0]['label']) ? '' : ' '.$eventarray[0]['label']);
2386 $more = 'ICS file - '.$langs->transnoentities("OrganizedEvent").(empty($eventarray[0]['label']) ? '' : ' '.$eventarray[0]['label']);
2387 }
2388 if ($more) {
2389 if (empty($title)) {
2390 $title = 'Dolibarr actions '.$mysoc->name.' - '.$more;
2391 }
2392 $desc = $more;
2393 $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2394 } else {
2395 if (empty($title)) {
2396 $title = 'Dolibarr actions '.$mysoc->name;
2397 }
2398 $desc = $langs->transnoentities('ListOfActions');
2399 $desc .= ' ('.$mysoc->name.' - built by Dolibarr)';
2400 }
2401
2402 // Create temp file
2403 $outputfiletmp = tempnam($conf->agenda->dir_temp, 'tmp'); // Temporary file (allow call of function by different threads
2404 dolChmod($outputfiletmp);
2405
2406 // Write file
2407 if ($format == 'vcal') {
2408 $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2409 } elseif ($format == 'ical') {
2410 $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp);
2411 } elseif ($format == 'rss') {
2412 $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp);
2413 }
2414
2415 if ($result >= 0) {
2416 if (dol_move($outputfiletmp, $outputfile, 0, 1, 0, 0)) {
2417 $result = 1;
2418 } else {
2419 $this->error = 'Failed to rename '.$outputfiletmp.' into '.$outputfile;
2420 dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR);
2421 dol_delete_file($outputfiletmp, 0, 1);
2422 $result = -1;
2423 }
2424 } else {
2425 dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR);
2426 dol_delete_file($outputfiletmp, 0, 1);
2427 $langs->load("errors");
2428 $this->error = $langs->trans("ErrorFailToCreateFile", $outputfile);
2429 }
2430 }
2431
2432 return $result;
2433 }
2434
2442 public function initAsSpecimen()
2443 {
2444 global $user;
2445
2446 $now = dol_now();
2447
2448 // Initialise parameters
2449 $this->id = 0;
2450 $this->specimen = 1;
2451
2452 $this->type_code = 'AC_OTH';
2453 $this->code = 'AC_SPECIMEN_CODE';
2454 $this->label = 'Label of event Specimen';
2455 $this->datec = $now;
2456 $this->datem = $now;
2457 $this->datep = $now;
2458 $this->datef = $now;
2459 $this->fulldayevent = 0;
2460 $this->percentage = 0;
2461 $this->status = 0;
2462 $this->location = 'Location';
2463 $this->transparency = 1; // 1 means opaque
2464 $this->priority = 1;
2465 //$this->note_public = "This is a 'public' note.";
2466 $this->note_private = "This is a 'private' note.";
2467
2468 $this->userownerid = $user->id;
2469 $this->userassigned[$user->id] = array('id' => $user->id, 'transparency' => 1);
2470 return 1;
2471 }
2472
2481 public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
2482 {
2483 $tables = array(
2484 'actioncomm'
2485 );
2486
2487 return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
2488 }
2489
2498 public static function replaceProduct(DoliDB $dbs, $origin_id, $dest_id)
2499 {
2500 $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'actioncomm SET fk_element = ' . ((int) $dest_id) . ' WHERE elementtype="product" AND fk_element = '.((int) $origin_id);
2501 // using $dbs, not $this->db because function is static
2502 if (!$dbs->query($sql)) {
2503 //$this->errors = $dbs->lasterror();
2504 return false;
2505 }
2506
2507 return true;
2508 }
2509
2515 public function hasDelay()
2516 {
2517 global $conf;
2518
2519 $now = dol_now();
2520
2521 return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay));
2522 }
2523
2524
2533 public function loadReminders($type = '', $fk_user = 0, $onlypast = true)
2534 {
2535 global $conf, $langs, $user;
2536
2537 $error = 0;
2538
2539 $this->reminders = array();
2540
2541 //Select all action comm reminders for event
2542 $sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user, fk_email_template, lasterror";
2543 $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2544 $sql .= " WHERE fk_actioncomm = ".((int) $this->id);
2545 if ($onlypast) {
2546 $sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'";
2547 }
2548 if ($type) {
2549 $sql .= " AND typeremind = '".$this->db->escape($type)."'";
2550 }
2551 if ($fk_user > 0) {
2552 $sql .= " AND fk_user = ".((int) $fk_user);
2553 }
2554 if (!getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
2555 $sql .= " AND typeremind <> 'email'";
2556 }
2557 if (!getDolGlobalString('AGENDA_REMINDER_BROWSER')) {
2558 $sql .= " AND typeremind <> 'browser'";
2559 }
2560
2561 $sql .= $this->db->order("dateremind", "ASC");
2562 $resql = $this->db->query($sql);
2563
2564 if ($resql) {
2565 while ($obj = $this->db->fetch_object($resql)) {
2566 $tmpactioncommreminder = new ActionCommReminder($this->db);
2567 $tmpactioncommreminder->id = $obj->id;
2568 $tmpactioncommreminder->typeremind = $obj->typeremind;
2569 $tmpactioncommreminder->dateremind = $obj->dateremind;
2570 $tmpactioncommreminder->offsetvalue = $obj->offsetvalue;
2571 $tmpactioncommreminder->offsetunit = $obj->offsetunit;
2572 $tmpactioncommreminder->status = $obj->status;
2573 $tmpactioncommreminder->fk_user = $obj->fk_user;
2574 $tmpactioncommreminder->fk_email_template = $obj->fk_email_template;
2575 $tmpactioncommreminder->lasterror = $obj->lasterror;
2576
2577 $this->reminders[$obj->id] = $tmpactioncommreminder;
2578 }
2579 } else {
2580 $this->error = $this->db->lasterror();
2581 $error++;
2582 }
2583
2584 return count($this->reminders);
2585 }
2586
2587
2594 public function sendEmailsReminder()
2595 {
2596 global $conf, $langs, $user;
2597
2598 $error = 0;
2599 $this->output = '';
2600 $this->error = '';
2601 $nbMailSend = 0;
2602 $errorsMsg = array();
2603
2604 if (!isModEnabled('agenda')) { // Should not happen. If module disabled, cron job should not be visible.
2605 $langs->load("agenda");
2606 $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2607 return 0;
2608 }
2609 if (!getDolGlobalString('AGENDA_REMINDER_EMAIL')) {
2610 $langs->load("agenda");
2611 $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda"));
2612 return 0;
2613 }
2614
2615 $now = dol_now();
2616 $actionCommReminder = new ActionCommReminder($this->db);
2617
2618 dol_syslog(__METHOD__." start", LOG_INFO);
2619
2620 $this->db->begin();
2621
2622 //Select all action comm reminders
2623 $sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2624 $sql .= " WHERE typeremind = 'email'";
2625 $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.
2626 $sql .= " AND dateremind <= '".$this->db->idate($now)."'";
2627 $sql .= " AND entity IN (".getEntity('actioncomm').")";
2628 $sql .= $this->db->order("dateremind", "ASC");
2629 $resql = $this->db->query($sql);
2630
2631 if ($resql) {
2632 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
2633 $formmail = new FormMail($this->db);
2634 $to = null; // Ensure 'to' is defined for static analysis
2635
2636 while ($obj = $this->db->fetch_object($resql)) {
2637 $res = $actionCommReminder->fetch($obj->id);
2638 if ($res < 0) {
2639 $error++;
2640 $errorsMsg[] = "Failed to load invoice ActionComm Reminder";
2641 }
2642
2643 if (!$error) {
2644 //Select email template
2645 $arraymessage = $formmail->getEMailTemplate($this->db, 'actioncomm_send', $user, $langs, (!empty($actionCommReminder->fk_email_template)) ? $actionCommReminder->fk_email_template : -1, 1);
2646
2647 // Load event
2648 $res = $this->fetch($actionCommReminder->fk_actioncomm);
2649 if ($res > 0) {
2650 // PREPARE EMAIL
2651 $errormesg = '';
2652
2653 // Make substitution in email content
2654 $substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this);
2655
2656 complete_substitutions_array($substitutionarray, $langs, $this);
2657
2658 // Content
2659 $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
2660
2661 //Topic
2662 $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder'));
2663
2664 // Recipient
2665 $recipient = new User($this->db);
2666 $res = $recipient->fetch($actionCommReminder->fk_user);
2667 if ($res > 0) {
2668 if (!empty($recipient->email)) {
2669 $to = $recipient->email;
2670 } else {
2671 $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user.";
2672 $error++;
2673 }
2674 } else {
2675 $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user;
2676 $error++;
2677 }
2678
2679 // Sender
2680 $from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
2681 if (empty($from)) {
2682 $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
2683 $error++;
2684 }
2685
2686 if (!$error) {
2687 // Errors Recipient
2688 $errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');
2689
2690 // Mail Creation
2691 $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
2692
2693 // Sending Mail
2694 if ($cMailFile->sendfile()) {
2695 $nbMailSend++;
2696 } else {
2697 $errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.implode(',', $cMailFile->errors);
2698 $error++;
2699 }
2700 }
2701
2702 if (!$error) {
2703 $actionCommReminder->status = $actionCommReminder::STATUS_DONE;
2704
2705 $res = $actionCommReminder->update($user);
2706 if ($res < 0) {
2707 $errorsMsg[] = "Failed to update status to done of ActionComm Reminder";
2708 $error++;
2709 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.
2710 }
2711 } else {
2712 $actionCommReminder->status = $actionCommReminder::STATUS_ERROR;
2713 $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1);
2714
2715 $res = $actionCommReminder->update($user);
2716 if ($res < 0) {
2717 $errorsMsg[] = "Failed to update status to error of ActionComm Reminder";
2718 $error++;
2719 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.
2720 } else {
2721 $errorsMsg[] = $errormesg;
2722 }
2723 }
2724 } else {
2725 $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm;
2726 $error++;
2727 }
2728 }
2729 }
2730 } else {
2731 $error++;
2732 }
2733
2734 if (!$error) {
2735 // Delete also very old past events (we do not keep more than 1 month record in past)
2736 $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
2737 $sql .= " WHERE dateremind < '".$this->db->idate($now - (3600 * 24 * 32))."'";
2738 $sql .= " AND status = ".((int) $actionCommReminder::STATUS_DONE);
2739 $resql = $this->db->query($sql);
2740
2741 if (!$resql) {
2742 $errorsMsg[] = 'Failed to delete old reminders';
2743 //$error++; // If this fails, we must not rollback other SQL requests already done. Never mind.
2744 }
2745 }
2746
2747 if (!$error) {
2748 $this->output = 'Nb of emails sent : '.$nbMailSend;
2749 $this->db->commit();
2750
2751 dol_syslog(__METHOD__." end - ".$this->output, LOG_INFO);
2752
2753 return 0;
2754 } else {
2755 $this->db->commit(); // We commit also on error, to have the error message recorded.
2756 $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg) ? implode(', ', $errorsMsg) : $error);
2757
2758 dol_syslog(__METHOD__." end - ".$this->error, LOG_INFO);
2759
2760 return $error;
2761 }
2762 }
2763
2772 public function updatePercent($id, $percent, $usermodid = 0)
2773 {
2774 $this->db->begin();
2775
2776 $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm ";
2777 $sql .= " SET percent = ".(int) $percent;
2778 if ($usermodid > 0) {
2779 $sql .= ", fk_user_mod = ".$usermodid;
2780 }
2781 $sql .= " WHERE id = ".((int) $id);
2782
2783 if ($this->db->query($sql)) {
2784 $this->db->commit();
2785 return 1;
2786 } else {
2787 $this->db->rollback();
2788 $this->error = $this->db->lasterror();
2789 return -1;
2790 }
2791 }
2792}
print $langs trans("AuditedSecurityEvents").'</strong >< span class="opacitymedium"></span >< br > status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition security.php:626
$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 information 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.
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)
Update the percent value of a event with the given id.
loadReminders($type='', $fk_user=0, $onlypast=true)
Load event reminder of events.
fetchResources()
Initialize $this->userassigned & this->socpeopleassigned array with list of id of user and contact as...
static replaceProduct(DoliDB $dbs, $origin_id, $dest_id)
Function used to replace a product id with another one.
getTypePicto($morecss='pictofixedwidth paddingright valignmiddle', $titlealt='')
Return Picto of type of event.
__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.
Class permettant la generation du formulaire html d'envoi de mail unitaire Usage: $formail = new Form...
Class to manage hooks.
Class to manage Dolibarr users.
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:594
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:426
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:613
dol_filemtime($pathoffile)
Return time of a file.
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.
dol_move($srcfile, $destfile, $newmask='0', $overwriteifexists=1, $testvirus=0, $indexdatabase=1, $moreinfo=array())
Move a file into another name.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0)
Show a picto called object_picto (generic function)
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
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.
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.
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...
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_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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.
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:139
dol_hash($chain, $type='0', $nosalt=0)
Returns a hash (non reversible encryption) of a string.
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