--- /tmp/dsg/dolibarr/htdocs/comm/action/class/github_actioncomm.class.php +++ /tmp/dsg/dolibarr/htdocs/comm/action/class/client_actioncomm.class.php @@ -28,9 +28,6 @@ */ require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncommreminder.class.php'; /** @@ -38,507 +35,492 @@ */ class ActionComm extends CommonObject { - /** - * @var string ID to identify managed object - */ - public $element = 'action'; - - /** - * @var string Name of table without prefix where object is stored - */ - public $table_element = 'actioncomm'; - - /** - * @var string Name of id column - */ - public $table_rowid = 'id'; - - /** - * @var string Name of icon for actioncomm object. Filename of icon is object_action.png - */ - public $picto = 'action'; - - /** - * @var int 0=No test on entity, 1=Test with field entity, 2=Test with link by societe - */ - public $ismultientitymanaged = 1; - - /** - * @var integer 0=Default - * 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user - * 2=Same than 1 but accept record if fksoc is empty - */ - public $restrictiononfksoc = 2; - - /** - * @var int Id of the event - */ - public $id; - - /** - * @var int Id of the event. Use $id as possible - */ - public $ref; - - /** - * @var int Id into parent table llx_c_actioncomm (used only if option to use type is set) - */ - public $type_id; - - /** - * @var string Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH. - */ - public $type_code; - - /** - * @var string Type label - */ - public $type_label; - - /** - * @var string Label into parent table llx_c_actioncomm (used only if option to use type is set) - */ - public $type; - - /** - * @var string Color into parent table llx_c_actioncomm (used only if option to use type is set) - */ - public $type_color; - - /** - * @var string Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...) - */ - public $code; - - /** - * @var string Agenda event label - */ - public $label; - - /** - * @var integer Date creation record (datec) - */ - public $datec; - - /** - * @var integer Date end record (datef) - */ - public $datef; - - /** - * @var integer Duration (duree) - */ - public $duree; - - /** - * @var integer Date modification record (tms) - */ - public $datem; - - /** - * @var User Object user that create action - * @deprecated - * @see $authorid - */ - public $author; - - /** - * @var User Object user that modified action - * @deprecated - * @see $usermodid - */ - public $usermod; - - /** - * @var int Id user that create action - */ - public $authorid; - - /** - * @var int Id user that modified action - */ - public $usermodid; - - /** - * @var integer Date action start (datep) - */ - public $datep; - - /** - * @var integer Date action end (datep2) - */ - public $datep2; - - /** - * @var int -1=Unkown duration - * @deprecated - */ - public $durationp = -1; - - /** - * @var int 1=Event on full day - */ - public $fulldayevent = 0; - - /** - * @var integer Percentage - */ - public $percentage; - - /** - * @var string Location - */ - public $location; - - /** - * @var int Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events) - */ - public $transparency; - - /** - * @var int (0 By default) - */ - public $priority; - - /** - * @var int[] Array of user ids - */ - public $userassigned = array(); - - /** - * @var int Id of user owner = fk_user_action into table - */ - public $userownerid; - - /** - * @var int Id of user done (deprecated) - * @deprecated - */ - public $userdoneid; - - /** - * @var int[] Array of contact ids - */ - public $socpeopleassigned = array(); - - /** - * @var int[] Array of other contact emails (not user, not contact) - */ - public $otherassigned = array(); - - /** - * @var array Array of reminders - */ - public $reminders = array(); - - /** - * @var User Object user of owner - * @deprecated - * @see $userownerid - */ - public $usertodo; - - /** - * @var User Object user that did action - * @deprecated - * @see $userdoneid - */ - public $userdone; - - /** - * @var int thirdparty id linked to action - */ - public $socid; - - /** - * @var int socpeople id linked to action - */ - public $contactid; - - /** - * @var Societe|null Company linked to action (optional) - * @deprecated - * @see $socid - */ - public $societe; - - /** - * @var Contact|null Contact linked to action (optional) - * @deprecated - * @see $contactid - */ - public $contact; - - // Properties for links to other objects - /** - * @var int Id of linked object - */ - public $fk_element; // Id of record - - /** - * @var int Id of record alternative for API - */ - public $elementid; - - /** - * @var string Type of record. This if property ->element of object linked to. - */ - public $elementtype; - - /** - * @var string Ical name - */ - public $icalname; - - /** - * @var string Ical color - */ - public $icalcolor; - - /** - * @var string Extraparam - */ - public $extraparams; - - /** - * @var array Actions - */ - public $actions = array(); - - /** - * @var string Email msgid - */ - public $email_msgid; - - /** - * @var string Email from - */ - public $email_from; - - /** - * @var string Email sender - */ - public $email_sender; - - /** - * @var string Email to - */ - public $email_to; - - /** - * @var string Email tocc - */ - public $email_tocc; - /** - * @var string Email tobcc - */ - public $email_tobcc; - - /** - * @var string Email subject - */ - public $email_subject; - - /** - * @var string Email errors to - */ - public $errors_to; - - /** - * Typical value for a event that is in a todo state - */ - const EVENT_TODO = 0; - - /** - * Typical value for a event that is in a progress state - */ - const EVENT_IN_PROGRESS = 50; - - /** - * Typical value for a event that is in a finished state - */ - const EVENT_FINISHED = 100; - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct(DoliDB $db) - { - $this->db = $db; - } - - /** - * Add an action/event into database. - * $this->type_id OR $this->type_code must be set. - * - * @param User $user Object user making action - * @param int $notrigger 1 = disable triggers, 0 = enable triggers - * @return int Id of created event, < 0 if KO - */ - public function create(User $user, $notrigger = 0) - { - global $langs, $conf, $hookmanager; - - $error = 0; - $now = dol_now(); - - // Check parameters - if (!isset($this->userownerid) || $this->userownerid === '') // $this->userownerid may be 0 (anonymous event) of > 0 - { - dol_syslog("You tried to create an event but mandatory property ownerid was not defined", LOG_WARNING); - $this->errors[] = 'ErrorPropertyUserowneridNotDefined'; - return -1; - } - - // Clean parameters - $this->label = dol_trunc(trim($this->label), 128); - $this->location = dol_trunc(trim($this->location), 128); - $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private)); - if (empty($this->percentage)) $this->percentage = 0; - if (empty($this->priority) || !is_numeric($this->priority)) $this->priority = 0; - if (empty($this->fulldayevent)) $this->fulldayevent = 0; - if (empty($this->transparency)) $this->transparency = 0; - if ($this->percentage > 100) $this->percentage = 100; - //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date; - if (!empty($this->datep) && !empty($this->datef)) $this->durationp = ($this->datef - $this->datep); // deprecated - //if (! empty($this->date) && ! empty($this->dateend)) $this->durationa=($this->dateend - $this->date); - if (!empty($this->datep) && !empty($this->datef) && $this->datep > $this->datef) $this->datef = $this->datep; - //if (! empty($this->date) && ! empty($this->dateend) && $this->date > $this->dateend) $this->dateend=$this->date; - if (!isset($this->fk_project) || $this->fk_project < 0) $this->fk_project = 0; - // For backward compatibility - if ($this->elementtype == 'facture') $this->elementtype = 'invoice'; - if ($this->elementtype == 'commande') $this->elementtype = 'order'; - if ($this->elementtype == 'contrat') $this->elementtype = 'contract'; - - if (!is_array($this->userassigned) && !empty($this->userassigned)) // For backward compatibility when userassigned was an int instead fo array - { - $tmpid = $this->userassigned; - $this->userassigned = array(); - $this->userassigned[$tmpid] = array('id'=>$tmpid, 'transparency'=>$this->transparency); - } - - $userownerid = $this->userownerid; - $userdoneid = $this->userdoneid; - - // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...). - if (empty($this->userassigned) || count($this->userassigned) == 0 || !is_array($this->userassigned)) - $this->userassigned = array($userownerid=>array('id'=>$userownerid, 'transparency'=>$this->transparency)); - - if (!$this->type_id || !$this->type_code) - { - $key = empty($this->type_id) ? $this->type_code : $this->type_id; - - // Get id from code - $cactioncomm = new CActionComm($this->db); - $result = $cactioncomm->fetch($key); - - if ($result > 0) + /** + * @var string ID to identify managed object + */ + public $element = 'action'; + + /** + * @var string Name of table without prefix where object is stored + */ + public $table_element = 'actioncomm'; + + /** + * @var string Name of id column + */ + public $table_rowid = 'id'; + + /** + * @var string Name of icon for actioncomm object. Filename of icon is object_action.png + */ + public $picto = 'action'; + + /** + * @var int 0=No test on entity, 1=Test with field entity, 2=Test with link by societe + */ + public $ismultientitymanaged = 1; + + /** + * @var integer 0=Default + * 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user + * 2=Same than 1 but accept record if fksoc is empty + */ + public $restrictiononfksoc = 2; + + /** + * @var int Id of the event + */ + public $id; + + /** + * @var int Id of the event. Use $id as possible + */ + public $ref; + + /** + * @var int Id into parent table llx_c_actioncomm (used only if option to use type is set) + */ + public $type_id; + + /** + * @var string Code into parent table llx_c_actioncomm (used only if option to use type is set). With default setup, should be AC_OTH_AUTO or AC_OTH. + */ + public $type_code; + + /** + * @var string Type label + */ + public $type_label; + + /** + * @var string Label into parent table llx_c_actioncomm (used only if option to use type is set) + */ + public $type; + + /** + * @var string Color into parent table llx_c_actioncomm (used only if option to use type is set) + */ + public $type_color; + + /** + * @var string Free code to identify action. Ie: Agenda trigger add here AC_TRIGGERNAME ('AC_COMPANY_CREATE', 'AC_PROPAL_VALIDATE', ...) + */ + public $code; + + /** + * @var string Agenda event label + */ + public $label; + + /** + * @var integer Date creation record (datec) + */ + public $datec; + + /** + * @var integer Date end record (datef) + */ + public $datef; + + /** + * @var integer Duration (duree) + */ + public $duree; + + /** + * @var integer Date modification record (tms) + */ + public $datem; + + /** + * @var User Object user that create action + * @deprecated + * @see $authorid + */ + public $author; + + /** + * @var User Object user that modified action + * @deprecated + * @see $usermodid + */ + public $usermod; + + /** + * @var int Id user that create action + */ + public $authorid; + + /** + * @var int Id user that modified action + */ + public $usermodid; + + /** + * @var integer Date action start (datep) + */ + public $datep; + + /** + * @var integer Date action end (datep2) + */ + public $datep2; + + /** + * @var int -1=Unkown duration + * @deprecated + */ + public $durationp = -1; + + /** + * @var int 1=Event on full day + */ + public $fulldayevent = 0; + + /** + * @var integer Percentage + */ + public $percentage; + + /** + * @var string Location + */ + public $location; + + /** + * @var int Transparency (ical standard). Used to say if people assigned to event are busy or not by event. 0=available, 1=busy, 2=busy (refused events) + */ + public $transparency; + + /** + * @var int (0 By default) + */ + public $priority; + + /** + * @var int[] Array of user ids + */ + public $userassigned = array(); + + /** + * @var int Id of user owner = fk_user_action into table + */ + public $userownerid; + + /** + * @var int Id of user done (deprecated) + * @deprecated + */ + public $userdoneid; + + /** + * @var int[] Array of contact ids + */ + public $socpeopleassigned = array(); + + /** + * @var int[] Array of other contact emails (not user, not contact) + */ + public $otherassigned = array(); + + + /** + * @var User Object user of owner + * @deprecated + * @see $userownerid + */ + public $usertodo; + + /** + * @var User Object user that did action + * @deprecated + * @see $userdoneid + */ + public $userdone; + + /** + * @var int thirdparty id linked to action + */ + public $socid; + + /** + * @var int socpeople id linked to action + */ + public $contactid; + + /** + * @var Societe|null Company linked to action (optional) + * @deprecated + * @see $socid + */ + public $societe; + + /** + * @var Contact|null Contact linked to action (optional) + * @deprecated + * @see $contactid + */ + public $contact; + + // Properties for links to other objects + /** + * @var int Id of linked object + */ + public $fk_element; // Id of record + + /** + * @var int Id of record alternative for API + */ + public $elementid; + + /** + * @var string Type of record. This if property ->element of object linked to. + */ + public $elementtype; + + /** + * @var string Ical name + */ + public $icalname; + + /** + * @var string Ical color + */ + public $icalcolor; + + /** + * @var string Extraparam + */ + public $extraparams; + + /** + * @var array Actions + */ + public $actions = array(); + + /** + * @var string Email msgid + */ + public $email_msgid; + + /** + * @var string Email from + */ + public $email_from; + + /** + * @var string Email sender + */ + public $email_sender; + + /** + * @var string Email to + */ + public $email_to; + + /** + * @var string Email tocc + */ + public $email_tocc; + /** + * @var string Email tobcc + */ + public $email_tobcc; + + /** + * @var string Email subject + */ + public $email_subject; + + /** + * @var string Email errors to + */ + public $errors_to; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct(DoliDB $db) + { + $this->db = $db; + } + + /** + * Add an action/event into database. + * $this->type_id OR $this->type_code must be set. + * + * @param User $user Object user making action + * @param int $notrigger 1 = disable triggers, 0 = enable triggers + * @return int Id of created event, < 0 if KO + */ + public function create(User $user, $notrigger = 0) + { + global $langs, $conf, $hookmanager; + + $error = 0; + $now = dol_now(); + + // Check parameters + if (!isset($this->userownerid) || $this->userownerid === '') // $this->userownerid may be 0 (anonymous event) of > 0 + { + dol_syslog("You tried to create an event but mandatory property ownerid was not defined", LOG_WARNING); + $this->errors[] = 'ErrorPropertyUserowneridNotDefined'; + return -1; + } + + // Clean parameters + $this->label = dol_trunc(trim($this->label), 128); + $this->location = dol_trunc(trim($this->location), 128); + $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private)); + if (empty($this->percentage)) $this->percentage = 0; + if (empty($this->priority) || !is_numeric($this->priority)) $this->priority = 0; + if (empty($this->fulldayevent)) $this->fulldayevent = 0; + if (empty($this->transparency)) $this->transparency = 0; + if ($this->percentage > 100) $this->percentage = 100; + //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date; + if (!empty($this->datep) && !empty($this->datef)) $this->durationp = ($this->datef - $this->datep); // deprecated + //if (! empty($this->date) && ! empty($this->dateend)) $this->durationa=($this->dateend - $this->date); + if (!empty($this->datep) && !empty($this->datef) && $this->datep > $this->datef) $this->datef = $this->datep; + //if (! empty($this->date) && ! empty($this->dateend) && $this->date > $this->dateend) $this->dateend=$this->date; + if (!isset($this->fk_project) || $this->fk_project < 0) $this->fk_project = 0; + // For backward compatibility + if ($this->elementtype == 'facture') $this->elementtype = 'invoice'; + if ($this->elementtype == 'commande') $this->elementtype = 'order'; + if ($this->elementtype == 'contrat') $this->elementtype = 'contract'; + + if (!is_array($this->userassigned) && !empty($this->userassigned)) // For backward compatibility when userassigned was an int instead fo array + { + $tmpid = $this->userassigned; + $this->userassigned = array(); + $this->userassigned[$tmpid] = array('id'=>$tmpid, 'transparency'=>$this->transparency); + } + + $userownerid = $this->userownerid; + $userdoneid = $this->userdoneid; + + // Be sure assigned user is defined as an array of array('id'=>,'mandatory'=>,...). + if (empty($this->userassigned) || count($this->userassigned) == 0 || !is_array($this->userassigned)) + $this->userassigned = array($userownerid=>array('id'=>$userownerid, 'transparency'=>$this->transparency)); + + if (!$this->type_id || !$this->type_code) + { + $key = empty($this->type_id) ? $this->type_code : $this->type_id; + + // Get id from code + $cactioncomm = new CActionComm($this->db); + $result = $cactioncomm->fetch($key); + + if ($result > 0) + { + $this->type_id = $cactioncomm->id; + $this->type_code = $cactioncomm->code; + } + elseif ($result == 0) + { + $this->error = 'Failed to get record with id '.$this->type_id.' code '.$this->type_code.' from dictionary "type of events"'; + return -1; + } + else { - $this->type_id = $cactioncomm->id; - $this->type_code = $cactioncomm->code; - } elseif ($result == 0) - { - $this->error = 'Failed to get record with id '.$this->type_id.' code '.$this->type_code.' from dictionary "type of events"'; - return -1; - } else { - $this->error = $cactioncomm->error; - return -1; - } - } - $code = empty($this->code) ? $this->type_code : $this->code; - - // Check parameters - if (!$this->type_id) - { - $this->error = "ErrorWrongParameters"; - return -1; - } - - $this->db->begin(); - - $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm"; - $sql .= "(datec,"; - $sql .= "datep,"; - $sql .= "datep2,"; - $sql .= "durationp,"; // deprecated - $sql .= "fk_action,"; - $sql .= "code,"; + $this->error = $cactioncomm->error; + return -1; + } + } + $code = empty($this->code) ? $this->type_code : $this->code; + + // Check parameters + if (!$this->type_id) + { + $this->error = "ErrorWrongParameters"; + return -1; + } + + $this->db->begin(); + + $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm"; + $sql .= "(datec,"; + $sql .= "datep,"; + $sql .= "datep2,"; + $sql .= "durationp,"; // deprecated + $sql .= "fk_action,"; + $sql .= "code,"; $sql .= "ref_ext,"; - $sql .= "fk_soc,"; - $sql .= "fk_project,"; - $sql .= "note,"; - $sql .= "fk_contact,"; - $sql .= "fk_user_author,"; - $sql .= "fk_user_action,"; - $sql .= "fk_user_done,"; - $sql .= "label,percent,priority,fulldayevent,location,"; - $sql .= "transparency,"; - $sql .= "fk_element,"; - $sql .= "elementtype,"; - $sql .= "entity,"; - $sql .= "extraparams,"; + $sql .= "fk_soc,"; + $sql .= "fk_project,"; + $sql .= "note,"; + $sql .= "fk_contact,"; + $sql .= "fk_user_author,"; + $sql .= "fk_user_action,"; + $sql .= "fk_user_done,"; + $sql .= "label,percent,priority,fulldayevent,location,"; + $sql .= "transparency,"; + $sql .= "fk_element,"; + $sql .= "elementtype,"; + $sql .= "entity,"; + $sql .= "extraparams,"; // Fields emails - $sql .= "email_msgid,"; - $sql .= "email_from,"; - $sql .= "email_sender,"; - $sql .= "email_to,"; - $sql .= "email_tocc,"; - $sql .= "email_tobcc,"; - $sql .= "email_subject,"; - $sql .= "errors_to"; - $sql .= ") VALUES ("; - $sql .= "'".$this->db->idate($now)."', "; - $sql .= (strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : "null").", "; - $sql .= (strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : "null").", "; - $sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated - $sql .= (isset($this->type_id) ? $this->type_id : "null").","; - $sql .= ($code ? ("'".$this->db->escape($code)."'") : "null").", "; - $sql .= (!empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'" : "null").", "; - $sql .= ((isset($this->socid) && $this->socid > 0) ? $this->socid : "null").", "; - $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : "null").", "; - $sql .= " '".$this->db->escape($this->note_private)."', "; - $sql .= ((isset($this->contact_id) && $this->contact_id > 0) ? $this->contact_id : "null").", "; // deprecated, use ->socpeopleassigned - $sql .= (isset($user->id) && $user->id > 0 ? $user->id : "null").", "; - $sql .= ($userownerid > 0 ? $userownerid : "null").", "; - $sql .= ($userdoneid > 0 ? $userdoneid : "null").", "; - $sql .= "'".$this->db->escape($this->label)."','".$this->db->escape($this->percentage)."','".$this->db->escape($this->priority)."','".$this->db->escape($this->fulldayevent)."','".$this->db->escape($this->location)."', "; - $sql .= "'".$this->db->escape($this->transparency)."', "; - $sql .= (!empty($this->fk_element) ? $this->fk_element : "null").", "; - $sql .= (!empty($this->elementtype) ? "'".$this->db->escape($this->elementtype)."'" : "null").", "; - $sql .= $conf->entity.","; - $sql .= (!empty($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").", "; - // Fields emails - $sql .= (!empty($this->email_msgid) ? "'".$this->db->escape($this->email_msgid)."'" : "null").", "; - $sql .= (!empty($this->email_from) ? "'".$this->db->escape($this->email_from)."'" : "null").", "; - $sql .= (!empty($this->email_sender) ? "'".$this->db->escape($this->email_sender)."'" : "null").", "; - $sql .= (!empty($this->email_to) ? "'".$this->db->escape($this->email_to)."'" : "null").", "; - $sql .= (!empty($this->email_tocc) ? "'".$this->db->escape($this->email_tocc)."'" : "null").", "; - $sql .= (!empty($this->email_tobcc) ? "'".$this->db->escape($this->email_tobcc)."'" : "null").", "; - $sql .= (!empty($this->email_subject) ? "'".$this->db->escape($this->email_subject)."'" : "null").", "; - $sql .= (!empty($this->errors_to) ? "'".$this->db->escape($this->errors_to)."'" : "null"); - $sql .= ")"; - - dol_syslog(get_class($this)."::add", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $this->ref = $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm", "id"); - - // Now insert assigned users + $sql .= "email_msgid,"; + $sql .= "email_from,"; + $sql .= "email_sender,"; + $sql .= "email_to,"; + $sql .= "email_tocc,"; + $sql .= "email_tobcc,"; + $sql .= "email_subject,"; + $sql .= "errors_to"; + $sql .= ") VALUES ("; + $sql .= "'".$this->db->idate($now)."', "; + $sql .= (strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : "null").", "; + $sql .= (strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : "null").", "; + $sql .= ((isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '') ? "'".$this->db->escape($this->durationp)."'" : "null").", "; // deprecated + $sql .= (isset($this->type_id) ? $this->type_id : "null").","; + $sql .= ($code ? ("'".$this->db->escape($code)."'") : "null").", "; + $sql .= ($this->ref_ext ? ("'".$this->db->idate($this->ref_ext)."'") : "null").", "; + $sql .= ((isset($this->socid) && $this->socid > 0) ? $this->socid : "null").", "; + $sql .= ((isset($this->fk_project) && $this->fk_project > 0) ? $this->fk_project : "null").", "; + $sql .= " '".$this->db->escape($this->note_private)."', "; + $sql .= ((isset($this->contactid) && $this->contactid > 0) ? $this->contactid : "null").", "; + $sql .= (isset($user->id) && $user->id > 0 ? $user->id : "null").", "; + $sql .= ($userownerid > 0 ? $userownerid : "null").", "; + $sql .= ($userdoneid > 0 ? $userdoneid : "null").", "; + $sql .= "'".$this->db->escape($this->label)."','".$this->db->escape($this->percentage)."','".$this->db->escape($this->priority)."','".$this->db->escape($this->fulldayevent)."','".$this->db->escape($this->location)."', "; + $sql .= "'".$this->db->escape($this->transparency)."', "; + $sql .= (!empty($this->fk_element) ? $this->fk_element : "null").", "; + $sql .= (!empty($this->elementtype) ? "'".$this->db->escape($this->elementtype)."'" : "null").", "; + $sql .= $conf->entity.","; + $sql .= (!empty($this->extraparams) ? "'".$this->db->escape($this->extraparams)."'" : "null").", "; + // Fields emails + $sql .= (!empty($this->email_msgid) ? "'".$this->db->escape($this->email_msgid)."'" : "null").", "; + $sql .= (!empty($this->email_from) ? "'".$this->db->escape($this->email_from)."'" : "null").", "; + $sql .= (!empty($this->email_sender) ? "'".$this->db->escape($this->email_sender)."'" : "null").", "; + $sql .= (!empty($this->email_to) ? "'".$this->db->escape($this->email_to)."'" : "null").", "; + $sql .= (!empty($this->email_tocc) ? "'".$this->db->escape($this->email_tocc)."'" : "null").", "; + $sql .= (!empty($this->email_tobcc) ? "'".$this->db->escape($this->email_tobcc)."'" : "null").", "; + $sql .= (!empty($this->email_subject) ? "'".$this->db->escape($this->email_subject)."'" : "null").", "; + $sql .= (!empty($this->errors_to) ? "'".$this->db->escape($this->errors_to)."'" : "null"); + $sql .= ")"; + + dol_syslog(get_class($this)."::add", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."actioncomm", "id"); + + // Now insert assigned users if (!$error) { //dol_syslog(var_export($this->userassigned, true)); foreach ($this->userassigned as $key => $val) { - if (!is_array($val)) // For backward compatibility when val=id - { - $val = array('id'=>$val); - } - - if ($val['id'] > 0) - { + if (!is_array($val)) // For backward compatibility when val=id + { + $val = array('id'=>$val); + } + + if ($val['id'] > 0) + { $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")"; @@ -547,10 +529,10 @@ { $error++; dol_syslog('Error to process userassigned: '.$this->db->lasterror(), LOG_ERR); - $this->errors[] = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); } //var_dump($sql);exit; - } + } } } @@ -574,232 +556,237 @@ } } - if (!$error) - { - // Actions on extra fields - $result = $this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - if (!$error && !$notrigger) - { - // Call trigger - $result = $this->call_trigger('ACTION_CREATE', $user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (!$error) - { - $this->db->commit(); - return $this->id; - } else { - $this->db->rollback(); - return -1; - } - } else { - $this->db->rollback(); - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Load an object from its id and create a new one in database - * - * @param User $fuser Object user making action + if (!$error) + { + // Actions on extra fields + $result = $this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('ACTION_CREATE', $user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (!$error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + else + { + $this->db->rollback(); + $this->error = $this->db->lasterror(); + return -1; + } + } + + /** + * Load an object from its id and create a new one in database + * + * @param User $fuser Object user making action * @param int $socid Id of thirdparty - * @return int New id of clone - */ - public function createFromClone(User $fuser, $socid) - { - global $db, $conf, $hookmanager; - - $error = 0; - $now = dol_now(); - - $this->db->begin(); + * @return int New id of clone + */ + public function createFromClone(User $fuser, $socid) + { + global $db, $conf, $hookmanager; + + $error = 0; + $now = dol_now(); + + $this->db->begin(); // Load source object $objFrom = clone $this; - // Retrieve all extrafield + // Retreive all extrafield // fetch optionals attributes and labels $this->fetch_optionals(); //$this->fetch_userassigned(); $this->fetchResources(); - $this->id = 0; - - // Create clone + $this->id = 0; + + // Create clone $this->context['createfromclone'] = 'createfromclone'; $result = $this->create($fuser); - if ($result < 0) $error++; - - if (!$error) - { - // Hook of thirdparty module - if (is_object($hookmanager)) - { - $parameters = array('objFrom'=>$objFrom); - $action = ''; - $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook < 0) $error++; - } - - // Call trigger - $result = $this->call_trigger('ACTION_CLONE', $fuser); - if ($result < 0) { $error++; } - // End call triggers - } - - unset($this->context['createfromclone']); - - // End - if (!$error) - { - $this->db->commit(); - return $this->id; - } else { - $this->db->rollback(); - return -1; - } - } - - /** - * Load object from database - * - * @param int $id Id of action to get - * @param string $ref Ref of action to get - * @param string $ref_ext Ref ext to get - * @param string $email_msgid Email msgid - * @return int <0 if KO, >0 if OK - */ - public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '') - { - global $langs; - - $sql = "SELECT a.id,"; - $sql .= " a.id as ref,"; - $sql .= " a.entity,"; - $sql .= " a.ref_ext,"; - $sql .= " a.datep,"; - $sql .= " a.datep2,"; - $sql .= " a.durationp,"; // deprecated - $sql .= " a.datec,"; - $sql .= " a.tms as datem,"; - $sql .= " a.code, a.label, a.note,"; - $sql .= " a.fk_soc,"; - $sql .= " a.fk_project,"; - $sql .= " a.fk_user_author, a.fk_user_mod,"; - $sql .= " a.fk_user_action, a.fk_user_done,"; - $sql .= " a.fk_contact, a.percent as percentage,"; - $sql .= " a.fk_element as elementid, a.elementtype,"; - $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,"; - $sql .= " a.email_msgid, a.email_subject, a.email_from, a.email_to, a.email_tocc, a.email_tobcc, a.errors_to,"; - $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label, c.color as type_color, c.picto as type_picto,"; - $sql .= " s.nom as socname,"; - $sql .= " u.firstname, u.lastname as lastname"; - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a "; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action=c.id "; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc"; - $sql .= " WHERE "; - if ($ref) $sql .= " a.id = ".((int) $ref); // No field ref, we use id - elseif ($ref_ext) $sql .= " a.ref_ext = '".$this->db->escape($ref_ext)."'"; - elseif ($email_msgid) $sql .= " a.email_msgid = '".$this->db->escape($email_msgid)."'"; - else $sql .= " a.id = ".((int) $id); - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - if ($num) - { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->id; - $this->entity = $obj->entity; - $this->ref = $obj->ref; - $this->ref_ext = $obj->ref_ext; - - // Properties of parent table llx_c_actioncomm - $this->type_id = $obj->type_id; - $this->type_code = $obj->type_code; - $this->type_color = $obj->type_color; - $this->type_picto = $obj->type_picto; - $transcode = $langs->trans("Action".$obj->type_code); - $this->type = (($transcode != "Action".$obj->type_code) ? $transcode : $obj->type_label); - $transcode = $langs->trans("Action".$obj->type_code.'Short'); - $this->type_short = (($transcode != "Action".$obj->type_code.'Short') ? $transcode : ''); + if ($result < 0) $error++; + + if (!$error) + { + // Hook of thirdparty module + if (is_object($hookmanager)) + { + $parameters = array('objFrom'=>$objFrom); + $action = ''; + $reshook = $hookmanager->executeHooks('createFrom', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook < 0) $error++; + } + + // Call trigger + $result = $this->call_trigger('ACTION_CLONE', $fuser); + if ($result < 0) { $error++; } + // End call triggers + } + + unset($this->context['createfromclone']); + + // End + if (!$error) + { + $this->db->commit(); + return $this->id; + } + else + { + $this->db->rollback(); + return -1; + } + } + + /** + * Load object from database + * + * @param int $id Id of action to get + * @param string $ref Ref of action to get + * @param string $ref_ext Ref ext to get + * @return int <0 if KO, >0 if OK + */ + public function fetch($id, $ref = '', $ref_ext = '') + { + global $langs; + + $sql = "SELECT a.id,"; + $sql .= " a.id as ref,"; + $sql .= " a.entity,"; + $sql .= " a.ref_ext,"; + $sql .= " a.datep,"; + $sql .= " a.datep2,"; + $sql .= " a.durationp,"; // deprecated + $sql .= " a.datec,"; + $sql .= " a.tms as datem,"; + $sql .= " a.code, a.label, a.note,"; + $sql .= " a.fk_soc,"; + $sql .= " a.fk_project,"; + $sql .= " a.fk_user_author, a.fk_user_mod,"; + $sql .= " a.fk_user_action, a.fk_user_done,"; + $sql .= " a.fk_contact, a.percent as percentage,"; + $sql .= " a.fk_element as elementid, a.elementtype,"; + $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,"; + $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label, c.color as type_color, c.picto as type_picto,"; + $sql .= " s.nom as socname,"; + $sql .= " u.firstname, u.lastname as lastname"; + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a "; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action=c.id "; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc"; + $sql .= " WHERE "; + if ($ref) $sql .= " a.id=".$ref; // No field ref, we use id + elseif ($ref_ext) $sql .= " a.ref_ext='".$this->db->escape($ref_ext)."'"; + else $sql .= " a.id=".$id; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + if ($num) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->id; + $this->entity = $obj->entity; + $this->ref = $obj->ref; + $this->ref_ext = $obj->ref_ext; + + // Properties of parent table llx_c_actioncomm + $this->type_id = $obj->type_id; + $this->type_code = $obj->type_code; + $this->type_color = $obj->type_color; + $this->type_picto = $obj->type_picto; + $transcode = $langs->trans("Action".$obj->type_code); + $this->type = (($transcode != "Action".$obj->type_code) ? $transcode : $obj->type_label); + $transcode = $langs->trans("Action".$obj->type_code.'Short'); + $this->type_short = (($transcode != "Action".$obj->type_code.'Short') ? $transcode : ''); $this->code = $obj->code; - $this->label = $obj->label; - $this->datep = $this->db->jdate($obj->datep); - $this->datef = $this->db->jdate($obj->datep2); - - $this->datec = $this->db->jdate($obj->datec); - $this->datem = $this->db->jdate($obj->datem); - - $this->note = $obj->note; // deprecated - $this->note_private = $obj->note; - $this->percentage = $obj->percentage; - - $this->authorid = $obj->fk_user_author; - $this->usermodid = $obj->fk_user_mod; - - if (!is_object($this->author)) $this->author = new stdClass(); // To avoid warning - $this->author->id = $obj->fk_user_author; // deprecated - $this->author->firstname = $obj->firstname; // deprecated - $this->author->lastname = $obj->lastname; // deprecated - if (!is_object($this->usermod)) $this->usermod = new stdClass(); // To avoid warning - $this->usermod->id = $obj->fk_user_mod; // deprecated - - $this->userownerid = $obj->fk_user_action; - $this->userdoneid = $obj->fk_user_done; - $this->priority = $obj->priority; - $this->fulldayevent = $obj->fulldayevent; - $this->location = $obj->location; - $this->transparency = $obj->transparency; - - $this->socid = $obj->fk_soc; // To have fetch_thirdparty method working - $this->contact_id = $obj->fk_contact; // To have fetch_contact method working - $this->fk_project = $obj->fk_project; // To have fetch_projet method working - - //$this->societe->id = $obj->fk_soc; // deprecated - //$this->contact->id = $obj->fk_contact; // deprecated - - $this->fk_element = $obj->elementid; - $this->elementid = $obj->elementid; - $this->elementtype = $obj->elementtype; - - $this->fetchResources(); - } - $this->db->free($resql); - } else { - $this->error = $this->db->lasterror(); - return -1; - } - - return $num; - } - - /** - * Initialize $this->userassigned & this->socpeopleassigned array with list of id of user and contact assigned to event - * - * @return int <0 if KO, >0 if OK - */ - public function fetchResources() - { - $this->userassigned = array(); - $this->socpeopleassigned = array(); - - $sql = 'SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency'; + $this->label = $obj->label; + $this->datep = $this->db->jdate($obj->datep); + $this->datef = $this->db->jdate($obj->datep2); + + $this->datec = $this->db->jdate($obj->datec); + $this->datem = $this->db->jdate($obj->datem); + + $this->note = $obj->note; // deprecated + $this->note_private = $obj->note; + $this->percentage = $obj->percentage; + + $this->authorid = $obj->fk_user_author; + $this->usermodid = $obj->fk_user_mod; + + if (!is_object($this->author)) $this->author = new stdClass(); // To avoid warning + $this->author->id = $obj->fk_user_author; // deprecated + $this->author->firstname = $obj->firstname; // deprecated + $this->author->lastname = $obj->lastname; // deprecated + if (!is_object($this->usermod)) $this->usermod = new stdClass(); // To avoid warning + $this->usermod->id = $obj->fk_user_mod; // deprecated + + $this->userownerid = $obj->fk_user_action; + $this->userdoneid = $obj->fk_user_done; + $this->priority = $obj->priority; + $this->fulldayevent = $obj->fulldayevent; + $this->location = $obj->location; + $this->transparency = $obj->transparency; + + $this->socid = $obj->fk_soc; // To have fetch_thirdparty method working + $this->contactid = $obj->fk_contact; // To have fetch_contact method working + $this->fk_project = $obj->fk_project; // To have fetch_projet method working + + //$this->societe->id = $obj->fk_soc; // deprecated + //$this->contact->id = $obj->fk_contact; // deprecated + + $this->fk_element = $obj->elementid; + $this->elementid = $obj->elementid; + $this->elementtype = $obj->elementtype; + + $this->fetchResources(); + } + $this->db->free($resql); + } + else + { + $this->error = $this->db->lasterror(); + return -1; + } + + return $num; + } + + /** + * Initialize $this->userassigned & this->socpeopleassigned array with list of id of user and contact assigned to event + * + * @return int <0 if KO, >0 if OK + */ + public function fetchResources() + { + $this->userassigned = array(); + $this->socpeopleassigned = array(); + + $sql = 'SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency'; $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm_resources'; $sql .= ' WHERE fk_actioncomm = '.$this->id; $sql .= " AND element_type IN ('user', 'socpeople')"; @@ -809,9 +796,9 @@ // If owner is known, we must but id first into list if ($this->userownerid > 0) $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid); // Set first so will be first into list. - while ($obj = $this->db->fetch_object($resql)) - { - if ($obj->fk_element > 0) + while ($obj = $this->db->fetch_object($resql)) + { + if ($obj->fk_element > 0) { switch ($obj->element_type) { case 'user': @@ -823,86 +810,90 @@ break; } } - } - - return 1; - } else { + } + + return 1; + } + else + { dol_print_error($this->db); return -1; } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Initialize this->userassigned array with list of id of user assigned to event - * - * @param bool $override Override $this->userownerid when empty. TODO This should be false by default. True is here to fix corrupted data. - * @return int <0 if KO, >0 if OK - */ - public function fetch_userassigned($override = true) - { - // phpcs:enable - $sql = "SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency"; - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_resources"; - $sql .= " WHERE element_type = 'user' AND fk_actioncomm = ".$this->id; - - $resql2 = $this->db->query($sql); - if ($resql2) - { - $this->userassigned = array(); - - // If owner is known, we must but id first into list - if ($this->userownerid > 0) - { - // Set first so will be first into list. - $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid); - } - - while ($obj = $this->db->fetch_object($resql2)) - { - if ($obj->fk_element > 0) - { - $this->userassigned[$obj->fk_element] = array('id'=>$obj->fk_element, - 'mandatory'=>$obj->mandatory, - 'answer_status'=>$obj->answer_status, - 'transparency'=>$obj->transparency); - } - - if ($override === true) - { - // If not defined (should not happened, we fix this) - if (empty($this->userownerid)) - { - $this->userownerid = $obj->fk_element; - } - } - } - - return 1; - } else { - dol_print_error($this->db); - return -1; - } - } - - /** - * Delete event from database - * - * @param int $notrigger 1 = disable triggers, 0 = enable triggers - * @return int <0 if KO, >0 if OK - */ - public function delete($notrigger = 0) - { - global $user; - - $error = 0; - - dol_syslog(get_class($this)."::delete", LOG_DEBUG); - - $this->db->begin(); - - // remove categorie association - if (!$error) { + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Initialize this->userassigned array with list of id of user assigned to event + * + * @param bool $override Override $this->userownerid when empty. TODO This should be false by default. True is here to fix corrupted data. + * @return int <0 if KO, >0 if OK + */ + public function fetch_userassigned($override = true) + { + // phpcs:enable + $sql = "SELECT fk_actioncomm, element_type, fk_element, answer_status, mandatory, transparency"; + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_resources"; + $sql .= " WHERE element_type = 'user' AND fk_actioncomm = ".$this->id; + + $resql2 = $this->db->query($sql); + if ($resql2) + { + $this->userassigned = array(); + + // If owner is known, we must but id first into list + if ($this->userownerid > 0) + { + // Set first so will be first into list. + $this->userassigned[$this->userownerid] = array('id'=>$this->userownerid); + } + + while ($obj = $this->db->fetch_object($resql2)) + { + if ($obj->fk_element > 0) + { + $this->userassigned[$obj->fk_element] = array('id'=>$obj->fk_element, + 'mandatory'=>$obj->mandatory, + 'answer_status'=>$obj->answer_status, + 'transparency'=>$obj->transparency); + } + + if ($override === true) + { + // If not defined (should not happened, we fix this) + if (empty($this->userownerid)) + { + $this->userownerid = $obj->fk_element; + } + } + } + + return 1; + } + else + { + dol_print_error($this->db); + return -1; + } + } + + /** + * Delete event from database + * + * @param int $notrigger 1 = disable triggers, 0 = enable triggers + * @return int <0 if KO, >0 if OK + */ + public function delete($notrigger = 0) + { + global $user; + + $error = 0; + + dol_syslog(get_class($this)."::delete", LOG_DEBUG); + + $this->db->begin(); + + // remove categorie association + if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."categorie_actioncomm"; $sql .= " WHERE fk_actioncomm=".$this->id; @@ -911,160 +902,152 @@ $this->error = $this->db->lasterror(); $error++; } - } - - // remove actioncomm_resources - if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources"; - $sql .= " WHERE fk_actioncomm=".$this->id; - - $res = $this->db->query($sql); - if (!$res) { - $this->error = $this->db->lasterror(); - $error++; - } - } - - if (!$error) - { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder"; - $sql .= " WHERE fk_actioncomm = ".$this->id; - - $res = $this->db->query($sql); - if (!$res) { - $this->error = $this->db->lasterror(); - $error++; - } - } - - // Removed extrafields - if (!$error) { - $result = $this->deleteExtraFields(); - if ($result < 0) - { - $error++; - dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR); - } - } - - // remove actioncomm - if (!$error) { - $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm"; - $sql .= " WHERE id=".$this->id; - - $res = $this->db->query($sql); - if (!$res) { - $this->error = $this->db->lasterror(); - $error++; - } - } - - if (!$error) - { - if (!$notrigger) - { - // Call trigger - $result = $this->call_trigger('ACTION_DELETE', $user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (!$error) - { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - return -2; - } - } else { - $this->db->rollback(); - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Update action into database - * If percentage = 100, on met a jour date 100% - * - * @param User $user Object user making change - * @param int $notrigger 1 = disable triggers, 0 = enable triggers - * @return int <0 if KO, >0 if OK - */ - public function update($user, $notrigger = 0) - { - global $langs, $conf, $hookmanager; - - $error = 0; - - // Clean parameters - $this->label = trim($this->label); - $this->note_private = dol_htmlcleanlastbr(trim(!isset($this->note_private) ? $this->note : $this->note_private)); - if (empty($this->percentage)) $this->percentage = 0; - if (empty($this->priority) || !is_numeric($this->priority)) $this->priority = 0; - if (empty($this->transparency)) $this->transparency = 0; - if (empty($this->fulldayevent)) $this->fulldayevent = 0; - if ($this->percentage > 100) $this->percentage = 100; - //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date; - if ($this->datep && $this->datef) $this->durationp = ($this->datef - $this->datep); // deprecated - //if ($this->date && $this->dateend) $this->durationa=($this->dateend - $this->date); - if ($this->datep && $this->datef && $this->datep > $this->datef) $this->datef = $this->datep; - //if ($this->date && $this->dateend && $this->date > $this->dateend) $this->dateend=$this->date; - if ($this->fk_project < 0) $this->fk_project = 0; - - // Check parameters - if ($this->percentage == 0 && $this->userdoneid > 0) - { - $this->error = "ErrorCantSaveADoneUserWithZeroPercentage"; - return -1; - } - - $socid = (($this->socid > 0) ? $this->socid : 0); - $contactid = (($this->contact_id > 0) ? $this->contact_id : 0); + } + + // remove actioncomm_resources + if (!$error) { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources"; + $sql .= " WHERE fk_actioncomm=".$this->id; + + $res = $this->db->query($sql); + if (!$res) { + $this->error = $this->db->lasterror(); + $error++; + } + } + + // Removed extrafields + if (!$error) { + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $error++; + dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR); + } + } + + // remove actioncomm + if (!$error) { + $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm"; + $sql .= " WHERE id=".$this->id; + + $res = $this->db->query($sql); + if (!$res) { + $this->error = $this->db->lasterror(); + $error++; + } + } + + if (!$error) + { + if (!$notrigger) + { + // Call trigger + $result = $this->call_trigger('ACTION_DELETE', $user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (!$error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -2; + } + } + else + { + $this->db->rollback(); + $this->error = $this->db->lasterror(); + return -1; + } + } + + /** + * Update action into database + * If percentage = 100, on met a jour date 100% + * + * @param User $user Object user making change + * @param int $notrigger 1 = disable triggers, 0 = enable triggers + * @return int <0 if KO, >0 if OK + */ + public function update($user, $notrigger = 0) + { + global $langs, $conf, $hookmanager; + + $error = 0; + + // Clean parameters + $this->label = trim($this->label); + $this->note_private = dol_htmlcleanlastbr(trim(empty($this->note_private) ? $this->note : $this->note_private)); + if (empty($this->percentage)) $this->percentage = 0; + if (empty($this->priority) || !is_numeric($this->priority)) $this->priority = 0; + if (empty($this->transparency)) $this->transparency = 0; + if (empty($this->fulldayevent)) $this->fulldayevent = 0; + if ($this->percentage > 100) $this->percentage = 100; + //if ($this->percentage == 100 && ! $this->dateend) $this->dateend = $this->date; + if ($this->datep && $this->datef) $this->durationp = ($this->datef - $this->datep); // deprecated + //if ($this->date && $this->dateend) $this->durationa=($this->dateend - $this->date); + if ($this->datep && $this->datef && $this->datep > $this->datef) $this->datef = $this->datep; + //if ($this->date && $this->dateend && $this->date > $this->dateend) $this->dateend=$this->date; + if ($this->fk_project < 0) $this->fk_project = 0; + + // Check parameters + if ($this->percentage == 0 && $this->userdoneid > 0) + { + $this->error = "ErrorCantSaveADoneUserWithZeroPercentage"; + return -1; + } + + $socid = (($this->socid > 0) ? $this->socid : 0); + $contactid = (($this->contactid > 0) ? $this->contactid : 0); $userownerid = ($this->userownerid ? $this->userownerid : 0); $userdoneid = ($this->userdoneid ? $this->userdoneid : 0); - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm "; - $sql .= " SET percent = '".$this->db->escape($this->percentage)."'"; - if ($this->type_id > 0) $sql .= ", fk_action = '".$this->db->escape($this->type_id)."'"; - $sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "null"); - $sql .= ", datep = ".(strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : 'null'); - $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null'); - $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated - $sql .= ", note = '".$this->db->escape($this->note_private)."'"; - $sql .= ", fk_project =".($this->fk_project > 0 ? $this->fk_project : "null"); - $sql .= ", fk_soc =".($socid > 0 ? $socid : "null"); - $sql .= ", fk_contact =".($contactid > 0 ? $contactid : "null"); - $sql .= ", priority = '".$this->db->escape($this->priority)."'"; - $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'"; - $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null"); - $sql .= ", transparency = '".$this->db->escape($this->transparency)."'"; - $sql .= ", fk_user_mod = ".$user->id; - $sql .= ", fk_user_action = ".($userownerid > 0 ? "'".$this->db->escape($userownerid)."'" : "null"); - $sql .= ", fk_user_done = ".($userdoneid > 0 ? "'".$this->db->escape($userdoneid)."'" : "null"); - if (!empty($this->fk_element)) $sql .= ", fk_element=".($this->fk_element ? $this->db->escape($this->fk_element) : "null"); - if (!empty($this->elementtype)) $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null"); - $sql .= " WHERE id=".$this->id; - - dol_syslog(get_class($this)."::update", LOG_DEBUG); - if ($this->db->query($sql)) - { + $this->db->begin(); + + $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm "; + $sql .= " SET percent = '".$this->db->escape($this->percentage)."'"; + if ($this->type_id > 0) $sql .= ", fk_action = '".$this->db->escape($this->type_id)."'"; + $sql .= ", label = ".($this->label ? "'".$this->db->escape($this->label)."'" : "null"); + $sql .= ", datep = ".(strval($this->datep) != '' ? "'".$this->db->idate($this->datep)."'" : 'null'); + $sql .= ", datep2 = ".(strval($this->datef) != '' ? "'".$this->db->idate($this->datef)."'" : 'null'); + $sql .= ", durationp = ".(isset($this->durationp) && $this->durationp >= 0 && $this->durationp != '' ? "'".$this->db->escape($this->durationp)."'" : "null"); // deprecated + $sql .= ", note = '".$this->db->escape($this->note_private)."'"; + $sql .= ", fk_project =".($this->fk_project > 0 ? $this->fk_project : "null"); + $sql .= ", fk_soc =".($socid > 0 ? $socid : "null"); + $sql .= ", fk_contact =".($contactid > 0 ? $contactid : "null"); + $sql .= ", priority = '".$this->db->escape($this->priority)."'"; + $sql .= ", fulldayevent = '".$this->db->escape($this->fulldayevent)."'"; + $sql .= ", location = ".($this->location ? "'".$this->db->escape($this->location)."'" : "null"); + $sql .= ", transparency = '".$this->db->escape($this->transparency)."'"; + $sql .= ", fk_user_mod = ".$user->id; + $sql .= ", fk_user_action=".($userownerid > 0 ? "'".$userownerid."'" : "null"); + $sql .= ", fk_user_done=".($userdoneid > 0 ? "'".$userdoneid."'" : "null"); + if (!empty($this->fk_element)) $sql .= ", fk_element=".($this->fk_element ? $this->db->escape($this->fk_element) : "null"); + if (!empty($this->elementtype)) $sql .= ", elementtype=".($this->elementtype ? "'".$this->db->escape($this->elementtype)."'" : "null"); + $sql .= " WHERE id=".$this->id; + + dol_syslog(get_class($this)."::update", LOG_DEBUG); + if ($this->db->query($sql)) + { $action = 'update'; - // Actions on extra fields - if (!$error) - { - $result = $this->insertExtraFields(); - if ($result < 0) - { - $error++; - } - } - - // Now insert assignedusers + // Actions on extra fields + if (!$error) + { + $result = $this->insertExtraFields(); + if ($result < 0) + { + $error++; + } + } + + // Now insert assignedusers if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_resources where fk_actioncomm = ".$this->id." AND element_type = 'user'"; @@ -1072,10 +1055,10 @@ foreach ($this->userassigned as $key => $val) { - if (!is_array($val)) // For backward compatibility when val=id - { - $val = array('id'=>$val); - } + if (!is_array($val)) // For backward compatibility when val=id + { + $val = array('id'=>$val); + } $sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)"; $sql .= " VALUES(".$this->id.", 'user', ".$val['id'].", ".(empty($val['mandatory']) ? '0' : $val['mandatory']).", ".(empty($val['transparency']) ? '0' : $val['transparency']).", ".(empty($val['answer_status']) ? '0' : $val['answer_status']).")"; @@ -1083,7 +1066,7 @@ if (!$resql) { $error++; - $this->errors[] = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); } //var_dump($sql);exit; } @@ -1111,281 +1094,273 @@ } } - if (!$error && !$notrigger) - { - // Call trigger - $result = $this->call_trigger('ACTION_MODIFY', $user); - if ($result < 0) { $error++; } - // End call triggers - } - - if (!$error) - { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - dol_syslog(get_class($this)."::update ".join(',', $this->errors), LOG_ERR); - return -2; - } - } else { - $this->db->rollback(); - $this->error = $this->db->lasterror(); - return -1; - } - } - - /** - * Load all objects with filters. - * @todo WARNING: This make a fetch on all records instead of making one request with a join. - * - * @param DoliDb $db Not used - * @param int $socid Filter by thirdparty - * @param int $fk_element Id of element action is linked to - * @param string $elementtype Type of element action is linked to - * @param string $filter Other filter - * @param string $sortfield Sort on this field - * @param string $sortorder ASC or DESC - * @param string $limit Limit number of answers - * @return array|string Error string if KO, array with actions if OK - */ - public static function getActions($db, $socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0) - { - global $conf, $langs; - - $resarray = array(); - - dol_syslog(get_class()."::getActions", LOG_DEBUG); - - $sql = "SELECT a.id"; - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; - $sql .= " WHERE a.entity IN (".getEntity('agenda').")"; - if (!empty($socid)) $sql .= " AND a.fk_soc = ".$socid; - if (!empty($elementtype)) - { - if ($elementtype == 'project') { - $sql .= ' AND a.fk_project = '.$fk_element; - } - elseif ($elementtype == 'contact') { - $sql .= ' AND a.id IN'; - $sql .= " (SELECT fk_actioncomm FROM ".MAIN_DB_PREFIX."actioncomm_resources WHERE"; - $sql .= " element_type = 'socpeople' AND fk_element = ".$fk_element.')'; - } - else { - $sql .= " AND a.fk_element = ".(int) $fk_element." AND a.elementtype = '".$db->escape($elementtype)."'"; - } - } - if (!empty($filter)) $sql .= $filter; + if (!$error && !$notrigger) + { + // Call trigger + $result = $this->call_trigger('ACTION_MODIFY', $user); + if ($result < 0) { $error++; } + // End call triggers + } + + if (!$error) + { + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + dol_syslog(get_class($this)."::update ".join(',', $this->errors), LOG_ERR); + return -2; + } + } + else + { + $this->db->rollback(); + $this->error = $this->db->lasterror(); + return -1; + } + } + + /** + * Load all objects with filters. + * @todo WARNING: This make a fetch on all records instead of making one request with a join. + * + * @param DoliDb $db Database handler + * @param int $socid Filter by thirdparty + * @param int $fk_element Id of element action is linked to + * @param string $elementtype Type of element action is linked to + * @param string $filter Other filter + * @param string $sortfield Sort on this field + * @param string $sortorder ASC or DESC + * @param string $limit Limit number of answers + * @return array|string Error string if KO, array with actions if OK + */ + public static function getActions($db, $socid = 0, $fk_element = 0, $elementtype = '', $filter = '', $sortfield = 'a.datep', $sortorder = 'DESC', $limit = 0) + { + global $conf, $langs; + + $resarray = array(); + + dol_syslog(get_class()."::getActions", LOG_DEBUG); + + $sql = "SELECT a.id"; + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; + $sql .= " WHERE a.entity IN (".getEntity('agenda').")"; + if (!empty($socid)) $sql .= " AND a.fk_soc = ".$socid; + if (!empty($elementtype)) + { + if ($elementtype == 'project') $sql .= ' AND a.fk_project = '.$fk_element; + else $sql .= " AND a.fk_element = ".(int) $fk_element." AND a.elementtype = '".$elementtype."'"; + } + if (!empty($filter)) $sql .= $filter; if ($sortorder && $sortfield) $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($limit, 0); - $resql = $db->query($sql); - if ($resql) - { - $num = $db->num_rows($resql); - - if ($num) - { - for ($i = 0; $i < $num; $i++) - { - $obj = $db->fetch_object($resql); - $actioncommstatic = new ActionComm($db); - $actioncommstatic->fetch($obj->id); - $resarray[$i] = $actioncommstatic; - } - } - $db->free($resql); - return $resarray; - } else { - return $db->lasterror(); - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Load indicators for dashboard (this->nbtodo and this->nbtodolate) - * - * @param User $user Objet user - * @param int $load_state_board Load indicator array this->nb - * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK - */ - public function load_board($user, $load_state_board = 0) - { - // phpcs:enable - global $conf, $langs; - - if (empty($load_state_board)) { - $sql = "SELECT a.id, a.datep as dp"; - } else { - $this->nb = array(); - $sql = "SELECT count(a.id) as nb"; - } - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; - if (!$user->rights->agenda->allactions->read) { - $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 = ".$user->id; + $resql = $db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + + if ($num) + { + for ($i = 0; $i < $num; $i++) + { + $obj = $db->fetch_object($resql); + $actioncommstatic = new ActionComm($db); + $actioncommstatic->fetch($obj->id); + $resarray[$i] = $actioncommstatic; + } + } + $db->free($resql); + return $resarray; + } + else + { + return $db->lasterror(); + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Objet user + * @param int $load_state_board Charge indicateurs this->nb de tableau de bord + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + */ + public function load_board($user, $load_state_board = 0) + { + // phpcs:enable + global $conf, $langs; + + if (empty($load_state_board)) $sql = "SELECT a.id, a.datep as dp"; + else { + $this->nb = array(); + $sql = "SELECT count(a.id) as nb"; } - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; - $sql .= " WHERE 1 = 1"; - if (empty($load_state_board)) $sql .= " AND a.percent >= 0 AND a.percent < 100"; - $sql .= " AND a.entity IN (".getEntity('agenda').")"; - if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".$user->id.")"; - if ($user->socid) $sql .= " AND a.fk_soc = ".$user->socid; - if (!$user->rights->agenda->allactions->read) { - $sql .= " AND (a.fk_user_author = ".$user->id." OR a.fk_user_action = ".$user->id." OR a.fk_user_done = ".$user->id; - $sql .= " OR ar.fk_element = ".$user->id; // Added by PV - $sql .= ")"; - } - - $resql = $this->db->query($sql); - if ($resql) - { - if (empty($load_state_board)) { - $agenda_static = new ActionComm($this->db); - $response = new WorkboardResponse(); - $response->warning_delay = $conf->agenda->warning_delay / 60 / 60 / 24; - $response->label = $langs->trans("ActionsToDo"); - $response->labelShort = $langs->trans("ActionsToDoShort"); - $response->url = DOL_URL_ROOT.'/comm/action/list.php?action=show_list&actioncode=0&status=todo&mainmenu=agenda'; - if ($user->rights->agenda->allactions->read) $response->url .= '&filtert=-1'; - $response->img = img_object('', "action", 'class="inline-block valigntextmiddle"'); - } - // This assignment in condition is not a bug. It allows walking the results. - while ($obj = $this->db->fetch_object($resql)) { - if (empty($load_state_board)) { - $response->nbtodo++; - $agenda_static->datep = $this->db->jdate($obj->dp); - if ($agenda_static->hasDelay()) $response->nbtodolate++; - } else { - $this->nb["actionscomm"] = $obj->nb; - } - } - - $this->db->free($resql); - if (empty($load_state_board)) return $response; - else return 1; - } else { - dol_print_error($this->db); - $this->error = $this->db->error(); - return -1; - } - } - - - /** - * Charge les informations d'ordre info dans l'objet facture - * - * @param int $id Id de la facture a charger - * @return void - */ - public function info($id) - { - $sql = 'SELECT '; - $sql .= ' a.id,'; - $sql .= ' datec,'; - $sql .= ' tms as datem,'; - $sql .= ' fk_user_author,'; - $sql .= ' fk_user_mod'; - $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a'; - $sql .= ' WHERE a.id = '.$id; - - dol_syslog(get_class($this)."::info", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - if ($this->db->num_rows($result)) - { - $obj = $this->db->fetch_object($result); - $this->id = $obj->id; - if ($obj->fk_user_author) - { - $cuser = new User($this->db); - $cuser->fetch($obj->fk_user_author); - $this->user_creation = $cuser; - } - if ($obj->fk_user_mod) - { - $muser = new User($this->db); - $muser->fetch($obj->fk_user_mod); - $this->user_modification = $muser; - } - - $this->date_creation = $this->db->jdate($obj->datec); - if (!empty($obj->fk_user_mod)) $this->date_modification = $this->db->jdate($obj->datem); - } - $this->db->free($result); - } else { - dol_print_error($this->db); - } - } - - - /** - * Return label of status - * - * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto - * @param int $hidenastatus 1=Show nothing if status is "Not applicable" - * @return string String with status - */ - public function getLibStatut($mode, $hidenastatus = 0) - { - return $this->LibStatut($this->percentage, $mode, $hidenastatus, $this->datep); - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return label of action status - * - * @param int $percent Percent - * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto - * @param int $hidenastatus 1=Show nothing if status is "Not applicable" - * @param int $datestart Date start of event - * @return string Label - */ - public function LibStatut($percent, $mode, $hidenastatus = 0, $datestart = '') - { - // phpcs:enable - global $langs; - - $labelStatus = $langs->trans('StatusNotApplicable'); - if ($percent == -1 && !$hidenastatus) $labelStatus = $langs->trans('StatusNotApplicable'); - elseif ($percent == 0) $labelStatus = $langs->trans('StatusActionToDo').' (0%)'; - elseif ($percent > 0 && $percent < 100) $labelStatus = $langs->trans('StatusActionInProcess').' ('.$percent.'%)'; - elseif ($percent >= 100) $labelStatus = $langs->trans('StatusActionDone').' (100%)'; - - $labelStatusShort = $langs->trans('StatusNotApplicable'); - if ($percent == -1 && !$hidenastatus) $labelStatusShort = $langs->trans('NA'); - elseif ($percent == 0) $labelStatusShort = '0%'; - elseif ($percent > 0 && $percent < 100) $labelStatusShort = $percent.'%'; - elseif ($percent >= 100) $labelStatusShort = '100%'; - - $statusType = 'status9'; - if ($percent == -1 && !$hidenastatus) $statusType = 'status9'; - if ($percent == 0) $statusType = 'status1'; - if ($percent > 0 && $percent < 100) $statusType = 'status3'; - if ($percent >= 100) $statusType = 'status6'; - - return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode); - } - - /** - * Return URL of event - * Use $this->id, $this->type_code, $this->label and $this->type_label - * - * @param int $withpicto 0 = No picto, 1 = Include picto into link, 2 = Only picto - * @param int $maxlength Max number of charaters into label. If negative, use the ref as label. - * @param string $classname Force style class on a link - * @param string $option '' = Link to action, 'birthday'= Link to contact, 'holiday' = Link to leave - * @param int $overwritepicto 1 = Overwrite picto - * @param int $notooltip 1 = Disable tooltip - * @param int $save_lastsearch_value -1 = Auto, 0 = No save of lastsearch_values when clicking, 1 = Save lastsearch_values whenclicking - * @return string Chaine avec URL - */ - public function getNomUrl($withpicto = 0, $maxlength = 0, $classname = '', $option = '', $overwritepicto = 0, $notooltip = 0, $save_lastsearch_value = -1) - { - global $conf, $langs, $user, $hookmanager, $action; - - if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as a"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON a.fk_soc = sc.fk_soc"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid"; + $sql .= " WHERE 1 = 1"; + if (empty($load_state_board)) $sql .= " AND a.percent >= 0 AND a.percent < 100"; + $sql .= " AND a.entity IN (".getEntity('agenda').")"; + if (!$user->rights->societe->client->voir && !$user->socid) $sql .= " AND (a.fk_soc IS NULL OR sc.fk_user = ".$user->id.")"; + if ($user->socid) $sql .= " AND a.fk_soc = ".$user->socid; + if (!$user->rights->agenda->allactions->read) $sql .= " AND (a.fk_user_author = ".$user->id." OR a.fk_user_action = ".$user->id." OR a.fk_user_done = ".$user->id.")"; + + $resql = $this->db->query($sql); + if ($resql) + { + if (empty($load_state_board)) { + $agenda_static = new ActionComm($this->db); + $response = new WorkboardResponse(); + $response->warning_delay = $conf->agenda->warning_delay / 60 / 60 / 24; + $response->label = $langs->trans("ActionsToDo"); + $response->labelShort = $langs->trans("ActionsToDoShort"); + $response->url = DOL_URL_ROOT.'/comm/action/list.php?actioncode=0&status=todo&mainmenu=agenda'; + if ($user->rights->agenda->allactions->read) $response->url .= '&filtert=-1'; + $response->img = img_object('', "action", 'class="inline-block valigntextmiddle"'); + } + // This assignment in condition is not a bug. It allows walking the results. + while ($obj = $this->db->fetch_object($resql)) + { + if (empty($load_state_board)) { + $response->nbtodo++; + $agenda_static->datep = $this->db->jdate($obj->dp); + if ($agenda_static->hasDelay()) $response->nbtodolate++; + } else $this->nb["actionscomm"] = $obj->nb; + } + + $this->db->free($resql); + if (empty($load_state_board)) return $response; + else return 1; + } + else + { + dol_print_error($this->db); + $this->error = $this->db->error(); + return -1; + } + } + + + /** + * Charge les informations d'ordre info dans l'objet facture + * + * @param int $id Id de la facture a charger + * @return void + */ + public function info($id) + { + $sql = 'SELECT '; + $sql .= ' a.id,'; + $sql .= ' datec,'; + $sql .= ' tms as datem,'; + $sql .= ' fk_user_author,'; + $sql .= ' fk_user_mod'; + $sql .= ' FROM '.MAIN_DB_PREFIX.'actioncomm as a'; + $sql .= ' WHERE a.id = '.$id; + + dol_syslog(get_class($this)."::info", LOG_DEBUG); + $result = $this->db->query($sql); + if ($result) + { + if ($this->db->num_rows($result)) + { + $obj = $this->db->fetch_object($result); + $this->id = $obj->id; + if ($obj->fk_user_author) + { + $cuser = new User($this->db); + $cuser->fetch($obj->fk_user_author); + $this->user_creation = $cuser; + } + if ($obj->fk_user_mod) + { + $muser = new User($this->db); + $muser->fetch($obj->fk_user_mod); + $this->user_modification = $muser; + } + + $this->date_creation = $this->db->jdate($obj->datec); + if (!empty($obj->fk_user_mod)) $this->date_modification = $this->db->jdate($obj->datem); + } + $this->db->free($result); + } + else + { + dol_print_error($this->db); + } + } + + + /** + * Return label of status + * + * @param int $mode 0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto + * @param int $hidenastatus 1=Show nothing if status is "Not applicable" + * @return string String with status + */ + public function getLibStatut($mode, $hidenastatus = 0) + { + return $this->LibStatut($this->percentage, $mode, $hidenastatus, $this->datep); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return label of action status + * + * @param int $percent Percent + * @param int $mode 0=Long label, 1=Short label, 2=Picto+Short label, 3=Picto, 4=Picto+Short label, 5=Short label+Picto, 6=Picto+Long label, 7=Very short label+Picto + * @param int $hidenastatus 1=Show nothing if status is "Not applicable" + * @param int $datestart Date start of event + * @return string Label + */ + public function LibStatut($percent, $mode, $hidenastatus = 0, $datestart = '') + { + // phpcs:enable + global $langs; + + $labelStatus = $langs->trans('StatusNotApplicable'); + if ($percent == -1 && !$hidenastatus) $labelStatus = $langs->trans('StatusNotApplicable'); + elseif ($percent == 0) $labelStatus = $langs->trans('StatusActionToDo').' (0%)'; + elseif ($percent > 0 && $percent < 100) $labelStatus = $langs->trans('StatusActionInProcess').' ('.$percent.'%)'; + elseif ($percent >= 100) $labelStatus = $langs->trans('StatusActionDone').' (100%)'; + + $labelStatusShort = $langs->trans('StatusNotApplicable'); + if ($percent == -1 && !$hidenastatus) $labelStatusShort = $langs->trans('NA'); + elseif ($percent == 0) $labelStatusShort = '0%'; + elseif ($percent > 0 && $percent < 100) $labelStatusShort = $percent.'%'; + elseif ($percent >= 100) $labelStatusShort = '100%'; + + $statusType = 'status9'; + if ($percent == -1 && !$hidenastatus) $statusType = 'status9'; + if ($percent == 0) $statusType = 'status1'; + if ($percent > 0 && $percent < 100) $statusType = 'status3'; + if ($percent >= 100) $statusType = 'status6'; + + return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode); + } + + /** + * Return URL of event + * Use $this->id, $this->type_code, $this->label and $this->type_label + * + * @param int $withpicto 0 = No picto, 1 = Include picto into link, 2 = Only picto + * @param int $maxlength Max number of charaters into label. If negative, use the ref as label. + * @param string $classname Force style class on a link + * @param string $option '' = Link to action, 'birthday'= Link to contact, 'holiday' = Link to leave + * @param int $overwritepicto 1 = Overwrite picto + * @param int $notooltip 1 = Disable tooltip + * @param int $save_lastsearch_value -1 = Auto, 0 = No save of lastsearch_values when clicking, 1 = Save lastsearch_values whenclicking + * @return string Chaine avec URL + */ + public function getNomUrl($withpicto = 0, $maxlength = 0, $classname = '', $option = '', $overwritepicto = 0, $notooltip = 0, $save_lastsearch_value = -1) + { + global $conf, $langs, $user, $hookmanager, $action; + + if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips $canread = 0; if ($user->rights->agenda->myactions->read && $this->authorid == $user->id) $canread = 1; // Can read my event @@ -1393,10 +1368,10 @@ if ($user->rights->agenda->allactions->read) $canread = 1; // Can read all event of other if (!$canread) { - $option = 'nolink'; + $option = 'nolink'; } - $label = $this->label; + $label = $this->label; if (empty($label)) $label = $this->libelle; // For backward compatibility $result = ''; @@ -1409,10 +1384,10 @@ } if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) { - if ($this->type_code != 'AC_OTH_AUTO') $labeltype = $langs->trans('ActionAC_MANUAL'); + if ($this->type_code != 'AC_OTH_AUTO') $labeltype = $langs->trans('ActionAC_MANUAL'); } - $tooltip = img_picto('', $this->picto).' '.$langs->trans('Action').''; + $tooltip = ''.$langs->trans('Action').''; if (!empty($this->ref)) $tooltip .= '
'.$langs->trans('Ref').': '.$this->ref; if (!empty($label)) @@ -1421,38 +1396,38 @@ $tooltip .= '
'.$langs->trans('Type').': '.$labeltype; if (!empty($this->location)) $tooltip .= '
'.$langs->trans('Location').': '.$this->location; - if (isset($this->transparency)) - $tooltip .= '
'.$langs->trans('Busy').': '.yn($this->transparency); if (!empty($this->note_private)) - $tooltip .= '
'.$langs->trans('Note').': '.(dol_textishtml($this->note_private) ? str_replace(array("\r", "\n"), "", $this->note_private) : str_replace(array("\r", "\n"), '
', $this->note_private)); + $tooltip .= '
'.$langs->trans('Note').': '.(dol_textishtml($this->note_private) ? str_replace(array("\r", "\n"), "", $this->note_private) : str_replace(array("\r", "\n"), '
', $this->note_private)); $linkclose = ''; if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && $this->type_color) $linkclose = ' style="background-color:#'.$this->type_color.'"'; if (empty($notooltip)) { - if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { - $label = $langs->trans("ShowAction"); - $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; - } - $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1).'"'; - $linkclose .= ' class="'.$classname.' classfortooltip"'; - - /* + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) + { + $label = $langs->trans("ShowAction"); + $linkclose .= ' alt="'.dol_escape_htmltag($tooltip, 1).'"'; + } + $linkclose .= ' title="'.dol_escape_htmltag($tooltip, 1).'"'; + $linkclose .= ' class="'.$classname.' classfortooltip"'; + + /* $hookmanager->initHooks(array('actiondao')); $parameters=array('id'=>$this->id); $reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks $linkclose = ($hookmanager->resPrint ? $hookmanager->resPrint : $linkclose); */ - } else $linkclose .= ' class="'.$classname.'"'; + } + else $linkclose .= ' class="'.$classname.'"'; $url = ''; if ($option == 'birthday') $url = DOL_URL_ROOT.'/contact/perso.php?id='.$this->id; elseif ($option == 'holiday') - $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id; - else $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id; + $url = DOL_URL_ROOT.'/holiday/card.php?id='.$this->id; + else + $url = DOL_URL_ROOT.'/comm/action/card.php?id='.$this->id; if ($option !== 'nolink') { // Add param to save lastsearch_values or not @@ -1470,170 +1445,172 @@ $linkend = ''; } - if ($withpicto == 2) - { - $libelle = $label; - if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) $libelle = $labeltype; - $libelleshort = ''; - } else { - $libelle = (empty($this->libelle) ? $label : $this->libelle.(($label && $label != $this->libelle) ? ' '.$label : '')); - if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($libelle)) $libelle = $labeltype; - if ($maxlength < 0) $libelleshort = $this->ref; - else $libelleshort = dol_trunc($libelle, $maxlength); - } - - if ($withpicto) - { - if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) // Add code into () - { - if ($labeltype) - { - $libelle .= (preg_match('/'.preg_quote($labeltype, '/').'/', $libelle) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')'); - } - } - } - - $result .= $linkstart; - if ($withpicto) $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$libelle), ($overwritepicto ? $overwritepicto : 'action'), ($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - $result .= $libelleshort; - $result .= $linkend; - - global $action; - $hookmanager->initHooks(array('actiondao')); - $parameters = array('id'=>$this->id, 'getnomurl'=>$result); - $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook > 0) $result = $hookmanager->resPrint; - else $result .= $hookmanager->resPrint; - - return $result; - } - - /** - * Sets object to supplied categories. - * - * Deletes object from existing categories not supplied. - * Adds it to non existing supplied categories. - * Existing categories are left untouch. - * - * @param int[]|int $categories Category or categories IDs - * @return void - */ - public function setCategories($categories) - { - // Handle single category - if (!is_array($categories)) { - $categories = array($categories); - } - - // Get current categories - include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - $c = new Categorie($this->db); - $existing = $c->containing($this->id, Categorie::TYPE_ACTIONCOMM, 'id'); - - // Diff - if (is_array($existing)) { - $to_del = array_diff($existing, $categories); - $to_add = array_diff($categories, $existing); - } else { - $to_del = array(); // Nothing to delete - $to_add = $categories; - } - - // Process - foreach ($to_del as $del) { - if ($c->fetch($del) > 0) { - $c->del_type($this, Categorie::TYPE_ACTIONCOMM); - } - } - foreach ($to_add as $add) { - if ($c->fetch($add) > 0) { - $c->add_type($this, Categorie::TYPE_ACTIONCOMM); - } - } - return; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Export events from database into a cal file. - * - * @param string $format The format of the export 'vcal', 'ical/ics' or 'rss' - * @param string $type The type of the export 'event' or 'journal' - * @param integer $cachedelay Do not rebuild file if date older than cachedelay seconds - * @param string $filename The name for the exported file. - * @param array $filters Array of filters. Example array('notolderthan'=>99, 'year'=>..., 'idfrom'=>..., 'notactiontype'=>'systemauto', 'project'=>123, ...) - * @param integer $exportholiday 0 = don't integrate holidays into the export, 1 = integrate holidays into the export - * @return integer -1 = error on build export file, 0 = export okay - */ - public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0) - { - global $hookmanager; - - // phpcs:enable - global $conf, $langs, $dolibarr_main_url_root, $mysoc; - - require_once DOL_DOCUMENT_ROOT."/core/lib/xcal.lib.php"; - require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; - require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; - - dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG); - - // Check parameters - if (empty($format)) return -1; - - // Clean parameters - if (!$filename) - { - $extension = 'vcs'; - if ($format == 'ical') $extension = 'ics'; - $filename = $format.'.'.$extension; - } - - // Create dir and define output file (definitive and temporary) - $result = dol_mkdir($conf->agenda->dir_temp); - $outputfile = $conf->agenda->dir_temp.'/'.$filename; - - $result = 0; - - $buildfile = true; - $login = ''; $logina = ''; $logind = ''; $logint = ''; - - $now = dol_now(); - - if ($cachedelay) - { - $nowgmt = dol_now(); - include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay)) - { - dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled"); - $buildfile = false; - } - } - - if ($buildfile) - { - // Build event array - $eventarray = array(); - - $sql = "SELECT a.id,"; - $sql .= " a.datep,"; // Start - $sql .= " a.datep2,"; // End - $sql .= " a.durationp,"; // deprecated - $sql .= " a.datec, a.tms as datem,"; - $sql .= " a.label, a.code, a.note, a.fk_action as type_id,"; - $sql .= " a.fk_soc,"; - $sql .= " a.fk_user_author, a.fk_user_mod,"; - $sql .= " a.fk_user_action,"; - $sql .= " a.fk_contact, a.percent as percentage,"; - $sql .= " a.fk_element, a.elementtype,"; - $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,"; - $sql .= " u.firstname, u.lastname, u.email,"; - $sql .= " s.nom as socname,"; - $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label"; - $sql .= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)"; - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc"; + if ($withpicto == 2) + { + $libelle = $label; + if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) $libelle = $labeltype; + $libelleshort = ''; + } + else + { + $libelle = (empty($this->libelle) ? $label : $this->libelle.(($label && $label != $this->libelle) ? ' '.$label : '')); + if (!empty($conf->global->AGENDA_USE_EVENT_TYPE) && empty($libelle)) $libelle = $labeltype; + if ($maxlength < 0) $libelleshort = $this->ref; + else $libelleshort = dol_trunc($libelle, $maxlength); + } + + if ($withpicto) + { + if (!empty($conf->global->AGENDA_USE_EVENT_TYPE)) // Add code into () + { + if ($labeltype) + { + $libelle .= (preg_match('/'.preg_quote($labeltype, '/').'/', $libelle) ? '' : ' ('.$langs->transnoentities("Action".$this->type_code).')'); + } + } + } + + $result .= $linkstart; + if ($withpicto) $result .= img_object(($notooltip ? '' : $langs->trans("ShowAction").': '.$libelle), ($overwritepicto ? $overwritepicto : 'action'), ($notooltip ? 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'"' : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + $result .= $libelleshort; + $result .= $linkend; + + global $action; + $hookmanager->initHooks(array('actiondao')); + $parameters = array('id'=>$this->id, 'getnomurl'=>$result); + $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook > 0) $result = $hookmanager->resPrint; + else $result .= $hookmanager->resPrint; + + return $result; + } + + /** + * Sets object to supplied categories. + * + * Deletes object from existing categories not supplied. + * Adds it to non existing supplied categories. + * Existing categories are left untouch. + * + * @param int[]|int $categories Category or categories IDs + * @return void + */ + public function setCategories($categories) + { + // Handle single category + if (!is_array($categories)) { + $categories = array($categories); + } + + // Get current categories + include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + $c = new Categorie($this->db); + $existing = $c->containing($this->id, Categorie::TYPE_ACTIONCOMM, 'id'); + + // Diff + if (is_array($existing)) { + $to_del = array_diff($existing, $categories); + $to_add = array_diff($categories, $existing); + } else { + $to_del = array(); // Nothing to delete + $to_add = $categories; + } + + // Process + foreach ($to_del as $del) { + if ($c->fetch($del) > 0) { + $c->del_type($this, Categorie::TYPE_ACTIONCOMM); + } + } + foreach ($to_add as $add) { + if ($c->fetch($add) > 0) { + $c->add_type($this, Categorie::TYPE_ACTIONCOMM); + } + } + return; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Export events from database into a cal file. + * + * @param string $format The format of the export 'vcal', 'ical/ics' or 'rss' + * @param string $type The type of the export 'event' or 'journal' + * @param integer $cachedelay Do not rebuild file if date older than cachedelay seconds + * @param string $filename The name for the exported file. + * @param array $filters Array of filters. Example array('notolderthan'=>99, 'year'=>..., 'idfrom'=>..., 'notactiontype'=>'systemauto', 'project'=>123, ...) + * @param integer $exportholiday 0 = don't integrate holidays into the export, 1 = integrate holidays into the export + * @return integer -1 = error on build export file, 0 = export okay + */ + public function build_exportfile($format, $type, $cachedelay, $filename, $filters, $exportholiday = 0) + { + global $hookmanager; + + // phpcs:enable + global $conf, $langs, $dolibarr_main_url_root, $mysoc; + + require_once DOL_DOCUMENT_ROOT."/core/lib/xcal.lib.php"; + require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; + require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; + + dol_syslog(get_class($this)."::build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG); + + // Check parameters + if (empty($format)) return -1; + + // Clean parameters + if (!$filename) + { + $extension = 'vcs'; + if ($format == 'ical') $extension = 'ics'; + $filename = $format.'.'.$extension; + } + + // Create dir and define output file (definitive and temporary) + $result = dol_mkdir($conf->agenda->dir_temp); + $outputfile = $conf->agenda->dir_temp.'/'.$filename; + + $result = 0; + + $buildfile = true; + $login = ''; $logina = ''; $logind = ''; $logint = ''; + + $now = dol_now(); + + if ($cachedelay) + { + $nowgmt = dol_now(); + include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + if (dol_filemtime($outputfile) > ($nowgmt - $cachedelay)) + { + dol_syslog(get_class($this)."::build_exportfile file ".$outputfile." is not older than now - cachedelay (".$nowgmt." - ".$cachedelay."). Build is canceled"); + $buildfile = false; + } + } + + if ($buildfile) + { + // Build event array + $eventarray = array(); + + $sql = "SELECT a.id,"; + $sql .= " a.datep,"; // Start + $sql .= " a.datep2,"; // End + $sql .= " a.durationp,"; // deprecated + $sql .= " a.datec, a.tms as datem,"; + $sql .= " a.label, a.code, a.note, a.fk_action as type_id,"; + $sql .= " a.fk_soc,"; + $sql .= " a.fk_user_author, a.fk_user_mod,"; + $sql .= " a.fk_user_action,"; + $sql .= " a.fk_contact, a.percent as percentage,"; + $sql .= " a.fk_element, a.elementtype,"; + $sql .= " a.priority, a.fulldayevent, a.location, a.transparency,"; + $sql .= " u.firstname, u.lastname, u.email,"; + $sql .= " s.nom as socname,"; + $sql .= " c.id as type_id, c.code as type_code, c.libelle as type_label"; + $sql .= " FROM (".MAIN_DB_PREFIX."c_actioncomm as c, ".MAIN_DB_PREFIX."actioncomm as a)"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."user as u on u.rowid = a.fk_user_author"; // Link to get author of event for export + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on s.rowid = a.fk_soc"; $parameters = array('filters' => $filters); $reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook @@ -1642,129 +1619,131 @@ // We must filter on assignement table if ($filters['logint']) $sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar"; $sql .= " WHERE a.fk_action=c.id"; - $sql .= " AND a.entity IN (".getEntity('agenda').")"; - foreach ($filters as $key => $value) - { - if ($key == 'notolderthan' && $value != '') $sql .= " AND a.datep >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'"; - if ($key == 'year') $sql .= " AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'"; - if ($key == 'id') $sql .= " AND a.id=".(is_numeric($value) ? $value : 0); - if ($key == 'idfrom') $sql .= " AND a.id >= ".(is_numeric($value) ? $value : 0); - if ($key == 'idto') $sql .= " AND a.id <= ".(is_numeric($value) ? $value : 0); - if ($key == 'project') $sql .= " AND a.fk_project=".(is_numeric($value) ? $value : 0); - if ($key == 'actiontype') $sql .= " AND c.type = '".$this->db->escape($value)."'"; - if ($key == 'notactiontype') $sql .= " AND c.type <> '".$this->db->escape($value)."'"; - // We must filter on assignement table + $sql .= " AND a.entity IN (".getEntity('agenda').")"; + foreach ($filters as $key => $value) + { + if ($key == 'notolderthan' && $value != '') $sql .= " AND a.datep >= '".$this->db->idate($now - ($value * 24 * 60 * 60))."'"; + if ($key == 'year') $sql .= " AND a.datep BETWEEN '".$this->db->idate(dol_get_first_day($value, 1))."' AND '".$this->db->idate(dol_get_last_day($value, 12))."'"; + if ($key == 'id') $sql .= " AND a.id=".(is_numeric($value) ? $value : 0); + if ($key == 'idfrom') $sql .= " AND a.id >= ".(is_numeric($value) ? $value : 0); + if ($key == 'idto') $sql .= " AND a.id <= ".(is_numeric($value) ? $value : 0); + if ($key == 'project') $sql .= " AND a.fk_project=".(is_numeric($value) ? $value : 0); + if ($key == 'actiontype') $sql .= " AND c.type = '".$this->db->escape($value)."'"; + if ($key == 'notactiontype') $sql .= " AND c.type <> '".$this->db->escape($value)."'"; + // We must filter on assignement table if ($key == 'logint') $sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'"; - if ($key == 'logina') - { - $logina = $value; - $condition = '='; - if (preg_match('/^!/', $logina)) - { - $logina = preg_replace('/^!/', '', $logina); - $condition = '<>'; - } - $userforfilter = new User($this->db); - $result = $userforfilter->fetch('', $logina); - if ($result > 0) $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id; - elseif ($result < 0 || $condition == '=') $sql .= " AND a.fk_user_author = 0"; - } - if ($key == 'logint') - { - $logint = $value; - $condition = '='; - if (preg_match('/^!/', $logint)) - { - $logint = preg_replace('/^!/', '', $logint); - $condition = '<>'; - } - $userforfilter = new User($this->db); - $result = $userforfilter->fetch('', $logint); - if ($result > 0) $sql .= " AND ar.fk_element = ".$userforfilter->id; - elseif ($result < 0 || $condition == '=') $sql .= " AND ar.fk_element = 0"; - } - } - - $sql .= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import + if ($key == 'logina') + { + $logina = $value; + $condition = '='; + if (preg_match('/^!/', $logina)) + { + $logina = preg_replace('/^!/', '', $logina); + $condition = '<>'; + } + $userforfilter = new User($this->db); + $result = $userforfilter->fetch('', $logina); + if ($result > 0) $sql .= " AND a.fk_user_author ".$condition." ".$userforfilter->id; + elseif ($result < 0 || $condition == '=') $sql .= " AND a.fk_user_author = 0"; + } + if ($key == 'logint') + { + $logint = $value; + $condition = '='; + if (preg_match('/^!/', $logint)) + { + $logint = preg_replace('/^!/', '', $logint); + $condition = '<>'; + } + $userforfilter = new User($this->db); + $result = $userforfilter->fetch('', $logint); + if ($result > 0) $sql .= " AND ar.fk_element = ".$userforfilter->id; + elseif ($result < 0 || $condition == '=') $sql .= " AND ar.fk_element = 0"; + } + } + + $sql .= " AND a.datep IS NOT NULL"; // To exclude corrupted events and avoid errors in lightning/sunbird import $parameters = array('filters' => $filters); $reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook $sql .= $hookmanager->resPrint; - $sql .= " ORDER by datep"; - //print $sql;exit; - - dol_syslog(get_class($this)."::build_exportfile select events", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - // Note: Output of sql request is encoded in $conf->file->character_set_client - // This assignment in condition is not a bug. It allows walking the results. + $sql .= " ORDER by datep"; + //print $sql;exit; + + dol_syslog(get_class($this)."::build_exportfile select events", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + // Note: Output of sql request is encoded in $conf->file->character_set_client + // This assignment in condition is not a bug. It allows walking the results. $diff = 0; - while ($obj = $this->db->fetch_object($resql)) - { - $qualified = true; - - // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author' - $event = array(); - $event['uid'] = 'dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"]; - $event['type'] = $type; - $datestart = $this->db->jdate($obj->datep) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); - - // fix for -> Warning: A non-numeric value encountered - if (is_numeric($this->db->jdate($obj->datep2))) - { - $dateend = $this->db->jdate($obj->datep2) - - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); - } else { - // use start date as fall-back to avoid import erros on empty end date - $dateend = $datestart; - } - - $duration = ($datestart && $dateend) ? ($dateend - $datestart) : 0; - $event['summary'] = $obj->label.($obj->socname ? " (".$obj->socname.")" : ""); - $event['desc'] = $obj->note; - $event['startdate'] = $datestart; - $event['enddate'] = $dateend; // Not required with type 'journal' - $event['duration'] = $duration; // Not required with type 'journal' - $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname); - $event['priority'] = $obj->priority; - $event['fulldayevent'] = $obj->fulldayevent; - $event['location'] = $obj->location; - $event['transparency'] = (($obj->transparency > 0) ? 'OPAQUE' : 'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy) - $event['category'] = $obj->type_label; - $event['email'] = $obj->email; + while ($obj = $this->db->fetch_object($resql)) + { + $qualified = true; + + // 'eid','startdate','duration','enddate','title','summary','category','email','url','desc','author' + $event = array(); + $event['uid'] = 'dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"]; + $event['type'] = $type; + $datestart = $this->db->jdate($obj->datep) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); + + // fix for -> Warning: A non-numeric value encountered + if (is_numeric($this->db->jdate($obj->datep2))) + { + $dateend = $this->db->jdate($obj->datep2) + - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); + } + else + { + // use start date as fall-back to avoid import erros on empty end date + $dateend = $datestart; + } + + $duration = ($datestart && $dateend) ? ($dateend - $datestart) : 0; + $event['summary'] = $obj->label.($obj->socname ? " (".$obj->socname.")" : ""); + $event['desc'] = $obj->note; + $event['startdate'] = $datestart; + $event['enddate'] = $dateend; // Not required with type 'journal' + $event['duration'] = $duration; // Not required with type 'journal' + $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname); + $event['priority'] = $obj->priority; + $event['fulldayevent'] = $obj->fulldayevent; + $event['location'] = $obj->location; + $event['transparency'] = (($obj->transparency > 0) ? 'OPAQUE' : 'TRANSPARENT'); // OPAQUE (busy) or TRANSPARENT (not busy) + $event['category'] = $obj->type_label; + $event['email'] = $obj->email; // Define $urlwithroot $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current - $url = $urlwithroot.'/comm/action/card.php?id='.$obj->id; - $event['url'] = $url; - $event['created'] = $this->db->jdate($obj->datec) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); - $event['modified'] = $this->db->jdate($obj->datem) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); - - // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties - $this->id = $obj->id; - $this->fetch_userassigned(false); - - $assignedUserArray = array(); - - foreach ($this->userassigned as $key => $value) - { - $assignedUser = new User($this->db); - $assignedUser->fetch($value['id']); - - $assignedUserArray[$key] = $assignedUser; - } - - $event['assignedUsers'] = $assignedUserArray; - - if ($qualified && $datestart) - { - $eventarray[] = $event; - } - $diff++; - } + $url = $urlwithroot.'/comm/action/card.php?id='.$obj->id; + $event['url'] = $url; + $event['created'] = $this->db->jdate($obj->datec) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); + $event['modified'] = $this->db->jdate($obj->datem) - (empty($conf->global->AGENDA_EXPORT_FIX_TZ) ? 0 : ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600)); + + // TODO: find a way to call "$this->fetch_userassigned();" without override "$this" properties + $this->id = $obj->id; + $this->fetch_userassigned(false); + + $assignedUserArray = array(); + + foreach ($this->userassigned as $key => $value) + { + $assignedUser = new User($this->db); + $assignedUser->fetch($value['id']); + + $assignedUserArray[$key] = $assignedUser; + } + + $event['assignedUsers'] = $assignedUserArray; + + if ($qualified && $datestart) + { + $eventarray[] = $event; + } + $diff++; + } $parameters = array('filters' => $filters, 'eventarray' => &$eventarray); $reshook = $hookmanager->executeHooks('addMoreEventsExport', $parameters); // Note that $action and $object may have been modified by hook @@ -1772,175 +1751,187 @@ { $eventarray = $hookmanager->resArray; } - } else { - $this->error = $this->db->lasterror(); - return -1; - } + } + else + { + $this->error = $this->db->lasterror(); + return -1; + } if ($exportholiday == 1) - { - $langs->load("holidays"); - $title = $langs->trans("Holidays"); - - $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"; - $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; - $sql .= " WHERE u.rowid = x.fk_user"; - $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user) - $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved) - - $resql = $this->db->query($sql); - if ($resql) - { - $num = $this->db->num_rows($resql); - $i = 0; - - while ($i < $num) - { - $obj = $this->db->fetch_object($resql); - $event = array(); - - if ($obj->halfday == -1) - { - $event['fulldayevent'] = false; - - $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0); - $timestampEnd = dol_stringtotime($obj->date_end." 12:00:00", 0); - } elseif ($obj->halfday == 1) - { - $event['fulldayevent'] = false; - - $timestampStart = dol_stringtotime($obj->date_start." 12:00:00", 0); - $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0); - } else { - $event['fulldayevent'] = true; - - $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0); - $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0); - } - - if (!empty($conf->global->AGENDA_EXPORT_FIX_TZ)) - { - $timestampStart = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); - $timestampEnd = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); - } - - $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); - $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; - $url = $urlwithroot.'/holiday/card.php?id='.$obj->rowid; - - $event['uid'] = 'dolibarrholiday-'.$this->db->database_name.'-'.$obj->rowid."@".$_SERVER["SERVER_NAME"]; - $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname); - $event['type'] = 'event'; - $event['category'] = "Holiday"; - $event['transparency'] = 'OPAQUE'; - $event['email'] = $obj->email; - $event['created'] = $timestampStart; - $event['modified'] = $timestampStart; - $event['startdate'] = $timestampStart; - $event['enddate'] = $timestampEnd; - $event['duration'] = $timestampEnd - $timestampStart; - $event['url'] = $url; - - if ($obj->status == 2) - { - // 2 = leave wait for approval - $event['summary'] = $title." - ".$obj->lastname." (wait for approval)"; - } else { - // 3 = leave approved - $event['summary'] = $title." - ".$obj->lastname; - } - - $eventarray[] = $event; - - $i++; - } - } - } - - $langs->load("agenda"); - - // Define title and desc - $more = ''; - if ($login) $more = $langs->transnoentities("User").' '.$login; - if ($logina) $more = $langs->transnoentities("ActionsAskedBy").' '.$logina; - if ($logint) $more = $langs->transnoentities("ActionsToDoBy").' '.$logint; - if ($logind) $more = $langs->transnoentities("ActionsDoneBy").' '.$logind; - if ($more) - { - $title = 'Dolibarr actions '.$mysoc->name.' - '.$more; - $desc = $more; - $desc .= ' ('.$mysoc->name.' - built by Dolibarr)'; - } else { - $title = 'Dolibarr actions '.$mysoc->name; - $desc = $langs->transnoentities('ListOfActions'); - $desc .= ' ('.$mysoc->name.' - built by Dolibarr)'; - } - - // Create temp file - $outputfiletmp = tempnam($conf->agenda->dir_temp, 'tmp'); // Temporary file (allow call of function by different threads - @chmod($outputfiletmp, octdec($conf->global->MAIN_UMASK)); - - // Write file - if ($format == 'vcal') $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp); - elseif ($format == 'ical') $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp); - elseif ($format == 'rss') $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp); - - if ($result >= 0) - { - if (dol_move($outputfiletmp, $outputfile, 0, 1)) $result = 1; - else { - $this->error = 'Failed to rename '.$outputfiletmp.' into '.$outputfile; - dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR); - dol_delete_file($outputfiletmp, 0, 1); - $result = -1; - } - } else { - dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR); - dol_delete_file($outputfiletmp, 0, 1); - $langs->load("errors"); - $this->error = $langs->trans("ErrorFailToCreateFile", $outputfile); - } - } - - return $result; - } - - /** - * Initialise an instance with random values. - * Used to build previews or test instances. - * id must be 0 if object instance is a specimen. - * - * @return int >0 if ok - */ - public function initAsSpecimen() - { - global $user; - - $now = dol_now(); - - // Initialise parametres - $this->id = 0; - $this->specimen = 1; - - $this->type_code = 'AC_OTH'; - $this->code = 'AC_SPECIMEN_CODE'; - $this->label = 'Label of event Specimen'; - $this->datec = $now; - $this->datem = $now; - $this->datep = $now; - $this->datef = $now; - $this->fulldayevent = 0; - $this->percentage = 0; - $this->location = 'Location'; - $this->transparency = 1; // 1 means opaque - $this->priority = 1; - //$this->note_public = "This is a 'public' note."; + { + $langs->load("holidays"); + $title = $langs->trans("Holidays"); + + $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"; + $sql .= " FROM ".MAIN_DB_PREFIX."holiday as x, ".MAIN_DB_PREFIX."user as u"; + $sql .= " WHERE u.rowid = x.fk_user"; + $sql .= " AND u.statut = '1'"; // Show only active users (0 = inactive user, 1 = active user) + $sql .= " AND (x.statut = '2' OR x.statut = '3')"; // Show only public leaves (2 = leave wait for approval, 3 = leave approved) + + $resql = $this->db->query($sql); + if ($resql) + { + $num = $this->db->num_rows($resql); + $i = 0; + + while ($i < $num) + { + $obj = $this->db->fetch_object($resql); + $event = array(); + + if ($obj->halfday == -1) + { + $event['fulldayevent'] = false; + + $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0); + $timestampEnd = dol_stringtotime($obj->date_end." 12:00:00", 0); + } + elseif ($obj->halfday == 1) + { + $event['fulldayevent'] = false; + + $timestampStart = dol_stringtotime($obj->date_start." 12:00:00", 0); + $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0); + } + else + { + $event['fulldayevent'] = true; + + $timestampStart = dol_stringtotime($obj->date_start." 00:00:00", 0); + $timestampEnd = dol_stringtotime($obj->date_end." 23:59:59", 0); + } + + if (!empty($conf->global->AGENDA_EXPORT_FIX_TZ)) + { + $timestampStart = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampEnd = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + } + + $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); + $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; + $url = $urlwithroot.'/holiday/card.php?id='.$obj->rowid; + + $event['uid'] = 'dolibarrholiday-'.$this->db->database_name.'-'.$obj->rowid."@".$_SERVER["SERVER_NAME"]; + $event['author'] = dolGetFirstLastname($obj->firstname, $obj->lastname); + $event['type'] = 'event'; + $event['category'] = "Holiday"; + $event['transparency'] = 'OPAQUE'; + $event['email'] = $obj->email; + $event['created'] = $timestampStart; + $event['modified'] = $timestampStart; + $event['startdate'] = $timestampStart; + $event['enddate'] = $timestampEnd; + $event['duration'] = $timestampEnd - $timestampStart; + $event['url'] = $url; + + if ($obj->status == 2) + { + // 2 = leave wait for approval + $event['summary'] = $title." - ".$obj->lastname." (wait for approval)"; + } + else + { + // 3 = leave approved + $event['summary'] = $title." - ".$obj->lastname; + } + + $eventarray[] = $event; + + $i++; + } + } + } + + $langs->load("agenda"); + + // Define title and desc + $more = ''; + if ($login) $more = $langs->transnoentities("User").' '.$login; + if ($logina) $more = $langs->transnoentities("ActionsAskedBy").' '.$logina; + if ($logint) $more = $langs->transnoentities("ActionsToDoBy").' '.$logint; + if ($logind) $more = $langs->transnoentities("ActionsDoneBy").' '.$logind; + if ($more) + { + $title = 'Dolibarr actions '.$mysoc->name.' - '.$more; + $desc = $more; + $desc .= ' ('.$mysoc->name.' - built by Dolibarr)'; + } + else + { + $title = 'Dolibarr actions '.$mysoc->name; + $desc = $langs->transnoentities('ListOfActions'); + $desc .= ' ('.$mysoc->name.' - built by Dolibarr)'; + } + + // Create temp file + $outputfiletmp = tempnam($conf->agenda->dir_temp, 'tmp'); // Temporary file (allow call of function by different threads + @chmod($outputfiletmp, octdec($conf->global->MAIN_UMASK)); + + // Write file + if ($format == 'vcal') $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp); + elseif ($format == 'ical') $result = build_calfile($format, $title, $desc, $eventarray, $outputfiletmp); + elseif ($format == 'rss') $result = build_rssfile($format, $title, $desc, $eventarray, $outputfiletmp); + + if ($result >= 0) + { + if (dol_move($outputfiletmp, $outputfile, 0, 1)) $result = 1; + else + { + $this->error = 'Failed to rename '.$outputfiletmp.' into '.$outputfile; + dol_syslog(get_class($this)."::build_exportfile ".$this->error, LOG_ERR); + dol_delete_file($outputfiletmp, 0, 1); + $result = -1; + } + } + else + { + dol_syslog(get_class($this)."::build_exportfile build_xxxfile function fails to for format=".$format." outputfiletmp=".$outputfile, LOG_ERR); + dol_delete_file($outputfiletmp, 0, 1); + $langs->load("errors"); + $this->error = $langs->trans("ErrorFailToCreateFile", $outputfile); + } + } + + return $result; + } + + /** + * Initialise an instance with random values. + * Used to build previews or test instances. + * id must be 0 if object instance is a specimen. + * + * @return int >0 if ok + */ + public function initAsSpecimen() + { + global $user; + + $now = dol_now(); + + // Initialise parametres + $this->id = 0; + $this->specimen = 1; + + $this->type_code = 'AC_OTH'; + $this->code = 'AC_SPECIMEN_CODE'; + $this->label = 'Label of event Specimen'; + $this->datec = $now; + $this->datem = $now; + $this->datep = $now; + $this->datef = $now; + $this->fulldayevent = 0; + $this->percentage = 0; + $this->location = 'Location'; + $this->transparency = 1; // 1 means opaque + $this->priority = 1; + //$this->note_public = "This is a 'public' note."; $this->note_private = "This is a 'private' note."; - $this->userownerid = $user->id; - $this->userassigned[$user->id] = array('id'=>$user->id, 'transparency'=> 1); - return 1; - } + $this->userownerid = $user->id; + $this->userassigned[$user->id] = array('id'=>$user->id, 'transparency'=> 1); + return 1; + } /** * Function used to replace a thirdparty id with another one. @@ -1959,269 +1950,62 @@ return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } - /** - * Is the action delayed? - * - * @return bool - */ - public function hasDelay() - { - global $conf; - - $now = dol_now(); - - return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay)); - } - - - /** - * Load event reminder of events - * - * @param string $type Type of reminder 'browser' or 'email' - * @param int $fk_user Id of user - * @param bool $onlypast true = get only past reminder, false = get all reminders linked to this - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) - */ - public function loadReminders($type = '', $fk_user = 0, $onlypast = true) - { - global $conf, $langs, $user; - - $error = 0; - - $this->reminders = array(); - - //Select all action comm reminders for event - $sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user"; - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_reminder"; - $sql .= " WHERE fk_actioncomm = ".$this->id; - if ($onlypast) { - $sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'"; - } - if ($type) { - $sql .= " AND typeremind ='".$this->db->escape($type)."'"; - } - if ($fk_user > 0) { - $sql .= " AND fk_user = ".((int) $fk_user); - } - if (empty($conf->global->AGENDA_REMINDER_EMAIL)) $sql .= " AND typeremind != 'email'"; - if (empty($conf->global->AGENDA_REMINDER_BROWSER)) $sql .= " AND typeremind != 'browser'"; - - $sql .= $this->db->order("dateremind", "ASC"); - $resql = $this->db->query($sql); - - if ($resql) { - while ($obj = $this->db->fetch_object($resql)) { - $tmpactioncommreminder = new ActionCommReminder($this->db); - $tmpactioncommreminder->id = $obj->id; - $tmpactioncommreminder->typeremind = $obj->typeremind; - $tmpactioncommreminder->dateremind = $obj->dateremind; - $tmpactioncommreminder->offsetvalue = $obj->offsetvalue; - $tmpactioncommreminder->offsetunit = $obj->offsetunit; - $tmpactioncommreminder->status = $obj->status; - $tmpactioncommreminder->fk_user = $obj->fk_user; - - $this->reminders[$obj->id] = $tmpactioncommreminder; - } - } else { - $this->error = $this->db->lasterror(); - $error++; - } - - return count($this->reminders); - } - - - /** - * Send reminders by emails - * CAN BE A CRON TASK - * - * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) - */ - public function sendEmailsReminder() - { - global $conf, $langs, $user; - - $error = 0; - $this->output = ''; + /** + * Is the action delayed? + * + * @return bool + */ + public function hasDelay() + { + global $conf; + + $now = dol_now(); + + return $this->datep && ($this->datep < ($now - $conf->agenda->warning_delay)); + } + + + /** + * Send reminders by emails + * CAN BE A CRON TASK + * + * @return int 0 if OK, <>0 if KO (this function is used also by cron so only 0 is OK) + */ + public function sendEmailsReminder() + { + global $conf, $langs; + + $error = 0; + $this->output = ''; $this->error = ''; - $nbMailSend = 0; - $errorsMsg = array(); - - if (empty($conf->agenda->enabled)) // Should not happen. If module disabled, cron job should not be visible. + + if (empty($conf->agenda->enabled)) // Should not happen. If module disabled, cron job should not be visible. { $langs->load("agenda"); $this->output = $langs->trans('ModuleNotEnabled', $langs->transnoentitiesnoconv("Agenda")); return 0; } if (empty($conf->global->AGENDA_REMINDER_EMAIL)) - { - $langs->load("agenda"); - $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda")); - return 0; - } - - $now = dol_now(); - $actionCommReminder = new ActionCommReminder($this->db); - - dol_syslog(__METHOD__, LOG_DEBUG); - - $this->db->begin(); - - //Select all action comm reminder - $sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder"; - $sql .= " WHERE typeremind = 'email' AND status = 0"; - $sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'"; - $sql .= $this->db->order("dateremind", "ASC"); - $resql = $this->db->query($sql); - - if ($resql) { - $formmail = new FormMail($this->db); - - while ($obj = $this->db->fetch_object($resql)) { - $res = $actionCommReminder->fetch($obj->id); - if ($res < 0) { - $error++; - $errorsMsg[] = "Failed to load invoice ActionComm Reminder"; - } - - if (!$error) { - //Select email template - $arraymessage = $formmail->getEMailTemplate($this->db, 'actioncomm_send', $user, $langs, (!empty($actionCommReminder->fk_email_template)) ? $actionCommReminder->fk_email_template : -1, 1); - - // Load event - $res = $this->fetch($actionCommReminder->fk_actioncomm); - if ($res > 0) { - // PREPARE EMAIL - $errormesg = ''; - - // Make substitution in email content - $substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this); - - complete_substitutions_array($substitutionarray, $langs, $this); - - // Content - $sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray); - - //Topic - $sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->trans('EventReminder')); - - // Recipient - $recipient = new User($this->db); - $res = $recipient->fetch($actionCommReminder->fk_user); - if ($res > 0) { - if (!empty($recipient->email)) { - $to = $recipient->email; - } else { - $errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user."; - $error++; - } - } else { - $errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user; - $error++; - } - - // Sender - $from = $conf->global->MAIN_MAIL_EMAIL_FROM; - if (empty($from)) { - $errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM"; - $error++; - } - - if (!$error) { - // Errors Recipient - $errors_to = $conf->global->MAIN_MAIL_ERRORS_TO; - - // Mail Creation - $cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', ''); - - // Sending Mail - if ($cMailFile->sendfile()) { - $nbMailSend++; - } else { - $errormesg = $cMailFile->error.' : '.$to; - $error++; - } - } - - if (!$error) { - $actionCommReminder->status = $actionCommReminder::STATUS_DONE; - - $res = $actionCommReminder->update($user); - if ($res < 0) { - $errorsMsg[] = "Failed to update status to done of ActionComm Reminder"; - $error++; - 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. - } - } else { - $actionCommReminder->status = $actionCommReminder::STATUS_ERROR; - $actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1); - - $res = $actionCommReminder->update($user); - if ($res < 0) { - $errorsMsg[] = "Failed to update status to error of ActionComm Reminder"; - $error++; - 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. - } else { - $errorsMsg[] = $errormesg; - } - } - } else { - $errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm; - $error++; - } - } - } - } else { - $error++; - } - - if (!$error) { - // Delete also very old past events (we do not keep more than 1 month record in past) - $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder"; - $sql .= " WHERE dateremind < '".$this->db->idate($now - (3600 * 24 * 32))."'"; - $sql .= " AND status = ".$actionCommReminder::STATUS_DONE; - $resql = $this->db->query($sql); - - if (!$resql) { - $errorsMsg[] = 'Failed to delete old reminders'; - //$error++; // If this fails, we must not rollback other SQL requests already done. Never mind. - } - } - - if (!$error) { - $this->output = 'Nb of emails sent : '.$nbMailSend; - $this->db->commit(); - return 0; - } else { - $this->db->commit(); // We commit also on error, to have the error message recorded. - $this->error = 'Nb of emails sent : '.$nbMailSend.', '.(!empty($errorsMsg)) ? join(', ', $errorsMsg) : $error; - return $error; - } - } - - /** - * Udpate the percent value of a event with the given id - * - * @param int $id The id of the event - * @param int $percent The new percent value for the event - * @return int 1 when update of the event was suscessfull, otherwise -1 - */ - public function updatePercent($id, $percent) - { - $this->db->begin(); - - $sql = "UPDATE ".MAIN_DB_PREFIX."actioncomm "; - $sql .= " SET percent = ".(int) $percent; - $sql .= " WHERE id=".$id; - - if ($this->db->query($sql)) - { - $this->db->commit(); - return 1; - } else { - $this->db->rollback(); - $this->error = $this->db->lasterror(); - return -1; - } - } + { + $langs->load("agenda"); + $this->output = $langs->trans('EventRemindersByEmailNotEnabled', $langs->transnoentitiesnoconv("Agenda")); + return 0; + } + + $now = dol_now(); + + dol_syslog(__METHOD__, LOG_DEBUG); + + $this->db->begin(); + + // TODO Scan events of type 'email' into table llx_actioncomm_reminder with status todo, send email, then set status to done + + // Delete also very old past events (we do not keep more than 1 month record in past) + $sql = "DELETE FROM ".MAIN_DB_PREFIX."actioncomm_reminder WHERE dateremind < '".$this->db->jdate($now - (3600 * 24 * 32))."'"; + $this->db->query($sql); + + $this->db->commit(); + + return $error; + } } --- /tmp/dsg/dolibarr/htdocs/comm/action/class/github_actioncommreminder.class.php +++ /tmp/dsg/dolibarr/htdocs/comm/action/class/client_actioncommreminder.class.php @@ -50,10 +50,6 @@ */ public $picto = 'generic'; - const STATUS_TODO = 0; - const STATUS_DONE = 1; - const STATUS_ERROR = -1; - /** * 'type' if the field format. @@ -78,27 +74,18 @@ */ public $fields = array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'visible'=>-1, 'enabled'=>1, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), - 'entity' => array('type'=>'integer', 'label'=>'Entity', 'visible'=>0, 'enabled'=>1, 'position'=>20, 'notnull'=>1, 'index'=>1,), 'dateremind' => array('type'=>'datetime', 'label'=>'DateRemind', 'visible'=>1, 'enabled'=>1, 'position'=>60, 'notnull'=>1, 'index'=>1,), 'typeremind' => array('type'=>'varchar(32)', 'label'=>'TypeRemind', 'visible'=>-1, 'enabled'=>1, 'position'=>55, 'notnull'=>1, 'comment'=>"email, browser, sms",), 'fk_user' => array('type'=>'integer', 'label'=>'User', 'visible'=>-1, 'enabled'=>1, 'position'=>65, 'notnull'=>1, 'index'=>1,), 'offsetvalue' => array('type'=>'integer', 'label'=>'OffsetValue', 'visible'=>1, 'enabled'=>1, 'position'=>56, 'notnull'=>1,), - 'offsetunit' => array('type'=>'varchar(1)', 'label'=>'OffsetUnit', 'visible'=>1, 'enabled'=>1, 'position'=>57, 'notnull'=>1, 'comment'=>"y, m, d, w, h, i",), - 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>58, 'notnull'=>1, 'default'=>0, 'index'=>0, 'arrayofkeyval'=>array('0'=>'ToDo', '1'=>'Done')), - 'lasterror' => array('type'=>'varchar(128)', 'label'=>'LastError', 'visible'=>-1, 'enabled'=>1, 'position'=>59, 'index'=>0), - 'fk_actioncomm' => array('type'=>'integer', 'label'=>'Project', 'visible'=>1, 'enabled'=>1, 'position'=>70, 'notnull'=>1, 'index'=>1,), - 'fk_email_template' => array('type'=>'integer', 'label'=>'EmailTemplate', 'visible'=>1, 'enabled'=>1, 'position'=>80, 'notnull'=>0), + 'offsetunit' => array('type'=>'varchar(1)', 'label'=>'OffsetUnit', 'visible'=>1, 'enabled'=>1, 'position'=>57, 'notnull'=>1, 'comment'=>"m, h, d, w",), + 'status' => array('type'=>'integer', 'label'=>'Status', 'visible'=>1, 'enabled'=>1, 'position'=>1000, 'notnull'=>1, 'default'=>0, 'index'=>0, 'arrayofkeyval'=>array('0'=>'ToDo', '1'=>'Done')), ); /** * @var int ID */ public $rowid; - - /** - * @var int Entity - */ - public $entity; public $dateremind; public $typeremind; @@ -115,21 +102,6 @@ * @var int Status */ public $status; - - /** - * @var string Last error message - */ - public $lasterror; - - /** - * @var int Project - */ - public $fk_actioncomm; - - /** - * @var int Template Mail - */ - public $fk_email_template; // END MODULEBUILDER PROPERTIES @@ -211,7 +183,7 @@ return $this->LibStatut($this->status, $mode); } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return the status * @@ -221,22 +193,39 @@ */ public static function LibStatut($status, $mode = 0) { - // phpcs:enable + // phpcs:enable global $langs; - $labelStatus = $langs->trans('ToDo'); - if ($status == 1) $labelStatus = $langs->trans('Done'); - elseif ($status == -1) $labelStatus = $langs->trans('Error'); - - $labelStatusShort = $langs->trans('ToDo'); - if ($status == 1) $labelStatus = $langs->trans('Done'); - elseif ($status == -1) $labelStatus = $langs->trans('Error'); - - $statusType = 'status5'; - if ($status == 1) $statusType = 'status4'; - elseif ($status == -1) $statusType = 'status8'; - - return dolGetStatus($labelStatus, $labelStatusShort, '', $statusType, $mode); + if ($mode == 0 || $mode == 1) + { + if ($status == 1) return $langs->trans('Done'); + elseif ($status == 0) return $langs->trans('ToDo'); + } + elseif ($mode == 2) + { + if ($status == 1) return img_picto($langs->trans('Done'), 'statut4').' '.$langs->trans('Done'); + elseif ($status == 0) return img_picto($langs->trans('ToDo'), 'statut5').' '.$langs->trans('ToDo'); + } + elseif ($mode == 3) + { + if ($status == 1) return img_picto($langs->trans('Done'), 'statut4'); + elseif ($status == 0) return img_picto($langs->trans('ToDo'), 'statut5'); + } + elseif ($mode == 4) + { + if ($status == 1) return img_picto($langs->trans('Done'), 'statut4').' '.$langs->trans('Done'); + elseif ($status == 0) return img_picto($langs->trans('ToDo'), 'statut5').' '.$langs->trans('ToDo'); + } + elseif ($mode == 5) + { + if ($status == 1) return $langs->trans('Done').' '.img_picto($langs->trans('Done'), 'statut4'); + elseif ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'), 'statut5'); + } + elseif ($mode == 6) + { + if ($status == 1) return $langs->trans('Done').' '.img_picto($langs->trans('Done'), 'statut4'); + elseif ($status == 0) return $langs->trans('ToDo').' '.img_picto($langs->trans('ToDo'), 'statut5'); + } } /** --- /tmp/dsg/dolibarr/htdocs/comm/action/class/github_api_agendaevents.class.php +++ /tmp/dsg/dolibarr/htdocs/comm/action/class/client_api_agendaevents.class.php @@ -16,10 +16,9 @@ * along with this program. If not, see . */ -use Luracast\Restler\RestException; - -require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; - + use Luracast\Restler\RestException; + + require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php'; /** * API class for Agenda Events @@ -30,30 +29,31 @@ class AgendaEvents extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - static $FIELDS = array( - ); - - /** - * @var ActionComm $actioncomm {@type ActionComm} - */ - public $actioncomm; - - - /** - * Constructor - */ - public function __construct() - { - global $db, $conf; - $this->db = $db; - $this->actioncomm = new ActionComm($this->db); - } + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + ); + + /** + * @var ActionComm $actioncomm {@type ActionComm} + */ + public $actioncomm; + + + /** + * Constructor + */ + public function __construct() + { + global $db, $conf; + $this->db = $db; + $this->actioncomm = new ActionComm($this->db); + } /** * Get properties of a Agenda Events object + * * Return an array with Agenda Events informations * * @param int $id ID of Agenda Events @@ -66,7 +66,7 @@ if (!DolibarrApiAccess::$user->rights->agenda->myactions->read) { throw new RestException(401, "Insufficient rights to read an event"); } - if ($id === 0) { + if ($id == 0) { $result = $this->actioncomm->initAsSpecimen(); } else { $result = $this->actioncomm->fetch($id); @@ -79,311 +79,312 @@ throw new RestException(404, 'Agenda Events not found'); } - if (!DolibarrApiAccess::$user->rights->agenda->allactions->read && $this->actioncomm->userownerid != DolibarrApiAccess::$user->id) { - throw new RestException(401, "Insufficient rights to read event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); - } - - if (!DolibarrApi::_checkAccessToResource('agenda', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - return $this->_cleanObjectDatas($this->actioncomm); - } - - /** - * List Agenda Events - * - * Get a list of Agenda Events - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $user_ids User ids filter field (owners of event). Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'%dol%') and (t.datec:<:'20160101')" - * @return array Array of Agenda Events objects - */ - public function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '') - { - global $db, $conf; - - $obj_ret = array(); - - if (!DolibarrApiAccess::$user->rights->agenda->myactions->read) { - throw new RestException(401, "Insufficient rights to read events"); - } - - // case of external user - $socid = 0; - if (!empty(DolibarrApiAccess::$user->socid)) $socid = DolibarrApiAccess::$user->socid; - - // If the internal user must only see his customers, force searching by him - $search_sale = 0; - if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; - if (empty($conf->societe->enabled)) $search_sale = 0; // If module thirdparty not enabled, sale representative is something that does not exists - - $sql = "SELECT t.id as rowid"; - if (!empty($conf->societe->enabled)) - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) - $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as t"; - if (!empty($conf->societe->enabled)) - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale - $sql .= ' WHERE t.entity IN ('.getEntity('agenda').')'; - if (!empty($conf->societe->enabled)) - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; - if ($user_ids) $sql .= " AND t.fk_user_action IN (".$user_ids.")"; - if ($socid > 0) $sql .= " AND t.fk_soc = ".$socid; - // Insert sale filter - if ($search_sale > 0) - { - $sql .= " AND sc.fk_user = ".$search_sale; - } - // Add sql filters - if ($sqlfilters) - { - if (!DolibarrApi::_checkFilters($sqlfilters)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); - } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; - } - - $sql .= $this->db->order($sortfield, $sortorder); - if ($limit) { - if ($page < 0) - { - $page = 0; - } - $offset = $limit * $page; - - $sql .= $this->db->plimit($limit + 1, $offset); - } - - $result = $this->db->query($sql); - - if ($result) - { - $i = 0; - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - while ($i < $min) - { - $obj = $this->db->fetch_object($result); - $actioncomm_static = new ActionComm($this->db); - if ($actioncomm_static->fetch($obj->rowid)) { - $obj_ret[] = $this->_cleanObjectDatas($actioncomm_static); - } - $i++; - } - } else { - throw new RestException(503, 'Error when retrieve Agenda Event list : '.$this->db->lasterror()); - } - if (!count($obj_ret)) { - throw new RestException(404, 'No Agenda Event found'); - } - return $obj_ret; - } - - /** - * Create Agenda Event object - * - * @param array $request_data Request data - * @return int ID of Agenda Event - */ - public function post($request_data = null) - { - if (!DolibarrApiAccess::$user->rights->agenda->myactions->create) { - throw new RestException(401, "Insufficient rights to create your Agenda Event"); - } - if (!DolibarrApiAccess::$user->rights->agenda->allactions->create && DolibarrApiAccess::$user->id != $request_data['userownerid']) { - throw new RestException(401, "Insufficient rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); - } - - // Check mandatory fields - $result = $this->_validate($request_data); - - foreach ($request_data as $field => $value) { - $this->actioncomm->$field = $value; - } - /*if (isset($request_data["lines"])) { + if (!DolibarrApiAccess::$user->rights->agenda->allactions->read && $this->actioncomm->userownerid != DolibarrApiAccess::$user->id) { + throw new RestException(401, "Insufficient rights to read event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); + } + + if (!DolibarrApi::_checkAccessToResource('agenda', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + return $this->_cleanObjectDatas($this->actioncomm); + } + + /** + * List Agenda Events + * + * Get a list of Agenda Events + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $user_ids User ids filter field (owners of event). Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.label:like:'%dol%') and (t.datec:<:'20160101')" + * @return array Array of Agenda Events objects + */ + public function index($sortfield = "t.id", $sortorder = 'ASC', $limit = 100, $page = 0, $user_ids = 0, $sqlfilters = '') + { + global $db, $conf; + + $obj_ret = array(); + + if (!DolibarrApiAccess::$user->rights->agenda->myactions->read) { + throw new RestException(401, "Insufficient rights to read events"); + } + + // case of external user + $socid = 0; + if (!empty(DolibarrApiAccess::$user->socid)) $socid = DolibarrApiAccess::$user->socid; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; + if (empty($conf->societe->enabled)) $search_sale = 0; // If module thirdparty not enabled, sale representative is something that does not exists + + $sql = "SELECT t.id as rowid"; + if (!empty($conf->societe->enabled)) + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql .= " FROM ".MAIN_DB_PREFIX."actioncomm as t"; + if (!empty($conf->societe->enabled)) + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + $sql .= ' WHERE t.entity IN ('.getEntity('agenda').')'; + if (!empty($conf->societe->enabled)) + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; + if ($user_ids) $sql .= " AND t.fk_user_action IN (".$user_ids.")"; + if ($socid > 0) $sql .= " AND t.fk_soc = ".$socid; + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Add sql filters + if ($sqlfilters) + { + if (!DolibarrApi::_checkFilters($sqlfilters)) + { + throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + } + $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; + $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; + } + + $sql .= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql .= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + + if ($result) + { + $i = 0; + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $actioncomm_static = new ActionComm($db); + if ($actioncomm_static->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($actioncomm_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve Agenda Event list : '.$db->lasterror()); + } + if (!count($obj_ret)) { + throw new RestException(404, 'No Agenda Event found'); + } + return $obj_ret; + } + + /** + * Create Agenda Event object + * + * @param array $request_data Request data + * @return int ID of Agenda Event + */ + public function post($request_data = null) + { + if (!DolibarrApiAccess::$user->rights->agenda->myactions->create) { + throw new RestException(401, "Insufficient rights to create your Agenda Event"); + } + if (!DolibarrApiAccess::$user->rights->agenda->allactions->create && DolibarrApiAccess::$user->id != $request_data['userownerid']) { + throw new RestException(401, "Insufficient rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); + } + + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach ($request_data as $field => $value) { + $this->actioncomm->$field = $value; + } + /*if (isset($request_data["lines"])) { $lines = array(); foreach ($request_data["lines"] as $line) { array_push($lines, (object) $line); } $this->expensereport->lines = $lines; }*/ - if ($this->actioncomm->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, "Error creating event", array_merge(array($this->actioncomm->error), $this->actioncomm->errors)); - } - - return $this->actioncomm->id; - } - - - /** - * Update Agenda Event general fields - * - * @param int $id Id of Agenda Event to update - * @param array $request_data Datas - * - * @return int - */ - public function put($id, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->agenda->myactions->create) { - throw new RestException(401, "Insufficient rights to create your Agenda Event"); - } - if (!DolibarrApiAccess::$user->rights->agenda->allactions->create && DolibarrApiAccess::$user->id != $request_data['userownerid']) { - throw new RestException(401, "Insufficient rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); - } - - $result = $this->actioncomm->fetch($id); - if ($result) { - $this->actioncomm->fetch_optionals(); - $this->actioncomm->fetch_userassigned(); - $this->actioncomm->oldcopy = clone $this->actioncomm; - } - if (!$result) { - throw new RestException(404, 'actioncomm not found'); - } - - if (!DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - foreach ($request_data as $field => $value) { - if ($field == 'id') continue; - $this->actioncomm->$field = $value; - } - - if ($this->actioncomm->update(DolibarrApiAccess::$user, 1) > 0) - return $this->get($id); - - return false; - } - - /** - * Delete Agenda Event - * - * @param int $id Agenda Event ID - * - * @return array - */ - public function delete($id) - { - if (!DolibarrApiAccess::$user->rights->agenda->myactions->delete) { - throw new RestException(401, "Insufficient rights to delete your Agenda Event"); - } - - $result = $this->actioncomm->fetch($id); - if ($result) { - $this->actioncomm->fetch_optionals(); - $this->actioncomm->fetch_userassigned(); - $this->actioncomm->oldcopy = clone $this->actioncomm; - } - - if (!DolibarrApiAccess::$user->rights->agenda->allactions->delete && DolibarrApiAccess::$user->id != $this->actioncomm->userownerid) { - throw new RestException(401, "Insufficient rights to delete an Agenda Event of owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); - } - - if (!$result) { - throw new RestException(404, 'Agenda Event not found'); - } - - if (!DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - if (!$this->actioncomm->delete(DolibarrApiAccess::$user)) { - throw new RestException(500, 'Error when delete Agenda Event : '.$this->actioncomm->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Agenda Event deleted' - ) - ); - } - - /** - * Validate fields before create or update object - * - * @param array $data Array with data to verify - * @return array - * @throws RestException - */ - private function _validate($data) - { - $event = array(); - foreach (AgendaEvents::$FIELDS as $field) { - if (!isset($data[$field])) - throw new RestException(400, "$field field missing"); - $event[$field] = $data[$field]; - } - return $event; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore - /** - * Clean sensible object datas - * - * @param Object $object Object to clean - * @return Object Object with cleaned properties - */ - protected function _cleanObjectDatas($object) - { - // phpcs:enable - $object = parent::_cleanObjectDatas($object); - - unset($object->note); // alreaydy into note_private - unset($object->usermod); - unset($object->libelle); - unset($object->context); - unset($object->canvas); - unset($object->contact); - unset($object->contact_id); - unset($object->thirdparty); - unset($object->user); - unset($object->origin); - unset($object->origin_id); - unset($object->ref_ext); - unset($object->statut); - unset($object->state_code); - unset($object->state_id); - unset($object->state); - unset($object->region); - unset($object->region_code); - unset($object->country); - unset($object->country_id); - unset($object->country_code); - unset($object->barcode_type); - unset($object->barcode_type_code); - unset($object->barcode_type_label); - unset($object->barcode_type_coder); - unset($object->mode_reglement_id); - unset($object->cond_reglement_id); - unset($object->cond_reglement); - unset($object->fk_delivery_address); - unset($object->shipping_method_id); - unset($object->fk_account); - unset($object->total_ht); - unset($object->total_tva); - unset($object->total_localtax1); - unset($object->total_localtax2); - unset($object->total_ttc); - unset($object->fk_incoterms); - unset($object->label_incoterms); - unset($object->location_incoterms); - unset($object->name); - unset($object->lastname); - unset($object->firstname); - unset($object->civility_id); - unset($object->contact); - unset($object->societe); - - unset($object->actions); - unset($object->lines); - - return $object; - } + if ($this->actioncomm->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating event", array_merge(array($this->actioncomm->error), $this->actioncomm->errors)); + } + + return $this->actioncomm->id; + } + + + /** + * Update Agenda Event general fields + * + * @param int $id Id of Agenda Event to update + * @param array $request_data Datas + * + * @return int + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->agenda->myactions->create) { + throw new RestException(401, "Insufficient rights to create your Agenda Event"); + } + if (!DolibarrApiAccess::$user->rights->agenda->allactions->create && DolibarrApiAccess::$user->id != $request_data['userownerid']) { + throw new RestException(401, "Insufficient rights to create an Agenda Event for owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); + } + + $result = $this->actioncomm->fetch($id); + if ($result) { + $this->actioncomm->fetch_optionals(); + $this->actioncomm->fetch_userassigned(); + $this->actioncomm->oldcopy = clone $this->actioncomm; + } + if (!$result) { + throw new RestException(404, 'actioncomm not found'); + } + + if (!DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + foreach ($request_data as $field => $value) { + if ($field == 'id') continue; + $this->actioncomm->$field = $value; + } + + if ($this->actioncomm->update(DolibarrApiAccess::$user, 1) > 0) + return $this->get($id); + + return false; + } + + /** + * Delete Agenda Event + * + * @param int $id Agenda Event ID + * + * @return array + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->rights->agenda->myactions->delete) { + throw new RestException(401, "Insufficient rights to delete your Agenda Event"); + } + + $result = $this->actioncomm->fetch($id); + if ($result) { + $this->actioncomm->fetch_optionals(); + $this->actioncomm->fetch_userassigned(); + $this->actioncomm->oldcopy = clone $this->actioncomm; + } + + if (!DolibarrApiAccess::$user->rights->agenda->allactions->delete && DolibarrApiAccess::$user->id != $this->actioncomm->userownerid) { + throw new RestException(401, "Insufficient rights to delete an Agenda Event of owner id ".$request_data['userownerid'].' Your id is '.DolibarrApiAccess::$user->id); + } + + if (!$result) { + throw new RestException(404, 'Agenda Event not found'); + } + + if (!DolibarrApi::_checkAccessToResource('actioncomm', $this->actioncomm->id, 'actioncomm', '', 'fk_soc', 'id')) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (!$this->actioncomm->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete Agenda Event : '.$this->actioncomm->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Agenda Event deleted' + ) + ); + } + + /** + * Validate fields before create or update object + * + * @param array $data Array with data to verify + * @return array + * @throws RestException + */ + private function _validate($data) + { + $event = array(); + foreach (AgendaEvents::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $event[$field] = $data[$field]; + } + return $event; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + protected function _cleanObjectDatas($object) + { + // phpcs:enable + $object = parent::_cleanObjectDatas($object); + + unset($object->note); // alreaydy into note_private + unset($object->usermod); + unset($object->libelle); + unset($object->context); + unset($object->canvas); + unset($object->contact); + unset($object->contact_id); + unset($object->thirdparty); + unset($object->user); + unset($object->origin); + unset($object->origin_id); + unset($object->ref_ext); + unset($object->statut); + unset($object->state_code); + unset($object->state_id); + unset($object->state); + unset($object->region); + unset($object->region_code); + unset($object->country); + unset($object->country_id); + unset($object->country_code); + unset($object->barcode_type); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + unset($object->barcode_type_coder); + unset($object->mode_reglement_id); + unset($object->cond_reglement_id); + unset($object->cond_reglement); + unset($object->fk_delivery_address); + unset($object->shipping_method_id); + unset($object->fk_account); + unset($object->total_ht); + unset($object->total_tva); + unset($object->total_localtax1); + unset($object->total_localtax2); + unset($object->total_ttc); + unset($object->fk_incoterms); + unset($object->label_incoterms); + unset($object->location_incoterms); + unset($object->name); + unset($object->lastname); + unset($object->firstname); + unset($object->civility_id); + unset($object->contact); + unset($object->societe); + + unset($object->actions); + unset($object->lines); + + return $object; + } } --- /tmp/dsg/dolibarr/htdocs/comm/action/class/github_cactioncomm.class.php +++ /tmp/dsg/dolibarr/htdocs/comm/action/class/client_cactioncomm.class.php @@ -28,226 +28,207 @@ */ class CActionComm { - /** - * @var string Error code (or message) - */ - public $error = ''; - - /** - * @var DoliDB Database handler. - */ - public $db; - - /** - * @var int ID - */ - public $id; - - /** - * @var string code - */ - public $code; - - /** - * @var string type - */ - public $type; - - /** - * @var string label - * @deprecated - * @see $label - */ - public $libelle; - - /** - * @var string Type of agenda event label - */ - public $label; - - /** - * @var int active - */ - public $active; - - /** - * @var string color hex - */ - public $color; - - /** - * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png - */ - public $picto; - - /** - * @var array array of type_actions - */ - public $type_actions = array(); - - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - $this->db = $db; - } - - /** - * Load action type from database - * - * @param int|string $id id or code of action type to read - * @return int 1=ok, 0=not found, -1=error - */ - public function fetch($id) - { - $sql = "SELECT id, code, type, libelle as label, color, active, picto"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm"; - if (is_numeric($id)) $sql .= " WHERE id=".(int) $id; - else $sql .= " WHERE code='".$this->db->escape($id)."'"; - - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - if ($this->db->num_rows($resql)) + /** + * @var string Error code (or message) + */ + public $error = ''; + + /** + * @var DoliDB Database handler. + */ + public $db; + + /** + * @var int ID + */ + public $id; + + public $code; + public $type; + public $libelle; // deprecated + + /** + * @var string Type of agenda event label + */ + public $label; + + public $active; + public $color; + + /** + * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png + */ + public $picto; + + public $type_actions = array(); + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + $this->db = $db; + } + + /** + * Load action type from database + * + * @param int $id id or code of action type to read + * @return int 1=ok, 0=not found, -1=error + */ + public function fetch($id) + { + $sql = "SELECT id, code, type, libelle as label, color, active, picto"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm"; + if (is_numeric($id)) $sql .= " WHERE id=".$id; + else $sql .= " WHERE code='".$this->db->escape($id)."'"; + + dol_syslog(get_class($this)."::fetch", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + if ($this->db->num_rows($resql)) + { + $obj = $this->db->fetch_object($resql); + + $this->id = $obj->id; + $this->code = $obj->code; + $this->type = $obj->type; + $this->libelle = $obj->label; // deprecated + $this->label = $obj->label; + $this->active = $obj->active; + $this->color = $obj->color; + + $this->db->free($resql); + return 1; + } + else { - $obj = $this->db->fetch_object($resql); - - $this->id = $obj->id; - $this->code = $obj->code; - $this->type = $obj->type; - $this->libelle = $obj->label; // deprecated - $this->label = $obj->label; - $this->active = $obj->active; - $this->color = $obj->color; - - $this->db->free($resql); - return 1; - } else { - $this->db->free($resql); - return 0; - } - } else { - $this->error = $this->db->error(); - return -1; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return list of event types: array(id=>label) or array(code=>label) - * - * @param string|int $active 1 or 0 to filter on event state active or not ('' by default = no filter) - * @param string $idorcode 'id' or 'code' - * @param string $excludetype Type to exclude ('system' or 'systemauto') - * @param int $onlyautoornot 1=Group all type AC_XXX into 1 line AC_MANUAL. 0=Keep details of type, -1=Keep details and add a combined line "All manual" - * @param string $morefilter Add more SQL filter - * @param int $shortlabel 1=Get short label instead of long label - * @return mixed Array of all event types if OK, <0 if KO. Key of array is id or code depending on parameter $idorcode. - */ - public function liste_array($active = '', $idorcode = 'id', $excludetype = '', $onlyautoornot = 0, $morefilter = '', $shortlabel = 0) - { - // phpcs:enable - global $langs, $conf; - $langs->load("commercial"); - - $repid = array(); - $repcode = array(); - - $sql = "SELECT id, code, libelle as label, module, type, color, picto"; - $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm"; - $sql .= " WHERE 1=1"; - if ($active != '') { - $sql .= " AND active=".(int) $active; - } - if (!empty($excludetype)) $sql .= " AND type <> '".$this->db->escape($excludetype)."'"; - if ($morefilter) $sql .= " AND ".$morefilter; - $sql .= " ORDER BY module, position, type"; - - dol_syslog(get_class($this)."::liste_array", LOG_DEBUG); - $resql = $this->db->query($sql); - if ($resql) - { - $nump = $this->db->num_rows($resql); - if ($nump) - { - $i = 0; - while ($i < $nump) - { - $obj = $this->db->fetch_object($resql); - - $qualified = 1; - - // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto - if ($qualified && $onlyautoornot > 0 && preg_match('/^system/', $obj->type) && !preg_match('/^AC_OTH/', $obj->code)) $qualified = 0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) - - if ($qualified && $obj->module) - { - if ($obj->module == 'invoice' && !$conf->facture->enabled) $qualified = 0; - if ($obj->module == 'order' && !$conf->commande->enabled) $qualified = 0; - if ($obj->module == 'propal' && !$conf->propal->enabled) $qualified = 0; - if ($obj->module == 'invoice_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !$conf->supplier_invoice->enabled)) $qualified = 0; - if ($obj->module == 'order_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !$conf->supplier_order->enabled)) $qualified = 0; - if ($obj->module == 'shipping' && !$conf->expedition->enabled) $qualified = 0; - } - - if ($qualified) - { - $keyfortrans = ''; - $transcode = ''; - $code = $obj->code; - if ($onlyautoornot > 0 && $code == 'AC_OTH') $code = 'AC_MANUAL'; - if ($onlyautoornot > 0 && $code == 'AC_OTH_AUTO') $code = 'AC_AUTO'; - if ($shortlabel) - { - $keyfortrans = "Action".$code.'Short'; - $transcode = $langs->trans($keyfortrans); - } - if (empty($keyfortrans) || $keyfortrans == $transcode) - { - $keyfortrans = "Action".$code; - $transcode = $langs->trans($keyfortrans); - } - $label = (($transcode != $keyfortrans) ? $transcode : $langs->trans($obj->label)); - if ($onlyautoornot == -1 && !empty($conf->global->AGENDA_USE_EVENT_TYPE) && !preg_match('/auto/i', $code)) - { - $label = '  '.$label; - $repid[-99] = $langs->trans("ActionAC_MANUAL"); - $repcode['AC_NON_AUTO'] = $langs->trans("ActionAC_MANUAL"); - } - $repid[$obj->id] = $label; - $repcode[$obj->code] = $label; - if ($onlyautoornot > 0 && preg_match('/^module/', $obj->type) && $obj->module) $repcode[$obj->code] .= ' ('.$langs->trans("Module").': '.$obj->module.')'; - } - $i++; - } - } - if ($idorcode == 'id') $this->liste_array = $repid; - if ($idorcode == 'code') $this->liste_array = $repcode; - return $this->liste_array; - } else { - $this->error = $this->db->lasterror(); - return -1; - } - } - - - /** - * Return name of action type as a label translated - * - * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Picto only - * @return string Label of action type - */ - public function getNomUrl($withpicto = 0) - { - global $langs; - - // Check if translation available - $transcode = $langs->trans("Action".$this->code); - if ($transcode != "Action".$this->code) return $transcode; - } + $this->db->free($resql); + return 0; + } + } + else + { + $this->error = $this->db->error(); + return -1; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return list of event types: array(id=>label) or array(code=>label) + * + * @param string|int $active 1 or 0 to filter on event state active or not ('' by default = no filter) + * @param string $idorcode 'id' or 'code' + * @param string $excludetype Type to exclude ('system' or 'systemauto') + * @param int $onlyautoornot 1=Group all type AC_XXX into 1 line AC_MANUAL. 0=Keep details of type, -1=Keep details and add a combined line "All manual" + * @param string $morefilter Add more SQL filter + * @param int $shortlabel 1=Get short label instead of long label + * @return mixed Array of all event types if OK, <0 if KO. Key of array is id or code depending on parameter $idorcode. + */ + public function liste_array($active = '', $idorcode = 'id', $excludetype = '', $onlyautoornot = 0, $morefilter = '', $shortlabel = 0) + { + // phpcs:enable + global $langs, $conf; + $langs->load("commercial"); + + $repid = array(); + $repcode = array(); + + $sql = "SELECT id, code, libelle as label, module, type, color, picto"; + $sql .= " FROM ".MAIN_DB_PREFIX."c_actioncomm"; + $sql .= " WHERE 1=1"; + if ($active != '') $sql .= " AND active=".$active; + if (!empty($excludetype)) $sql .= " AND type <> '".$excludetype."'"; + if ($morefilter) $sql .= " AND ".$morefilter; + $sql .= " ORDER BY module, position, type"; + + dol_syslog(get_class($this)."::liste_array", LOG_DEBUG); + $resql = $this->db->query($sql); + if ($resql) + { + $nump = $this->db->num_rows($resql); + if ($nump) + { + $i = 0; + while ($i < $nump) + { + $obj = $this->db->fetch_object($resql); + + $qualified = 1; + + // $obj->type can be system, systemauto, module, moduleauto, xxx, xxxauto + if ($qualified && $onlyautoornot > 0 && preg_match('/^system/', $obj->type) && !preg_match('/^AC_OTH/', $obj->code)) $qualified = 0; // We discard detailed system events. We keep only the 2 generic lines (AC_OTH and AC_OTH_AUTO) + + if ($qualified && $obj->module) + { + if ($obj->module == 'invoice' && !$conf->facture->enabled) $qualified=0; + if ($obj->module == 'order' && !$conf->commande->enabled) $qualified=0; + if ($obj->module == 'propal' && !$conf->propal->enabled) $qualified=0; + if ($obj->module == 'invoice_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ! $conf->supplier_invoice->enabled)) $qualified=0; + if ($obj->module == 'order_supplier' && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || ! $conf->supplier_order->enabled)) $qualified=0; + if ($obj->module == 'shipping' && !$conf->expedition->enabled) $qualified=0; + } + + if ($qualified) + { + $keyfortrans = ''; + $transcode = ''; + $code = $obj->code; + if ($onlyautoornot > 0 && $code == 'AC_OTH') $code = 'AC_MANUAL'; + if ($onlyautoornot > 0 && $code == 'AC_OTH_AUTO') $code = 'AC_AUTO'; + if ($shortlabel) + { + $keyfortrans = "Action".$code.'Short'; + $transcode = $langs->trans($keyfortrans); + } + if (empty($keyfortrans) || $keyfortrans == $transcode) + { + $keyfortrans = "Action".$code; + $transcode = $langs->trans($keyfortrans); + } + $label = (($transcode != $keyfortrans) ? $transcode : $langs->trans($obj->label)); + if ($onlyautoornot == -1 && !empty($conf->global->AGENDA_USE_EVENT_TYPE) && !preg_match('/auto/i', $code)) + { + $label = '  '.$label; + $repid[-99] = $langs->trans("ActionAC_MANUAL"); + $repcode['AC_NON_AUTO'] = $langs->trans("ActionAC_MANUAL"); + } + $repid[$obj->id] = $label; + $repcode[$obj->code] = $label; + if ($onlyautoornot > 0 && preg_match('/^module/', $obj->type) && $obj->module) $repcode[$obj->code] .= ' ('.$langs->trans("Module").': '.$obj->module.')'; + } + $i++; + } + } + if ($idorcode == 'id') $this->liste_array = $repid; + if ($idorcode == 'code') $this->liste_array = $repcode; + return $this->liste_array; + } + else + { + $this->error = $this->db->lasterror(); + return -1; + } + } + + + /** + * Return name of action type as a label translated + * + * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Picto only + * @return string Label of action type + */ + public function getNomUrl($withpicto = 0) + { + global $langs; + + // Check if translation available + $transcode = $langs->trans("Action".$this->code); + if ($transcode != "Action".$this->code) return $transcode; + } } --- /tmp/dsg/dolibarr/htdocs/comm/action/class/github_ical.class.php +++ /tmp/dsg/dolibarr/htdocs/comm/action/class/client_ical.class.php @@ -32,144 +32,144 @@ */ class ICal { - // Text in file - public $file_text; - public $cal; // Array to save iCalendar parse data - public $event_count; // Number of Events - public $todo_count; // Number of Todos - public $freebusy_count; // Number of Freebusy - public $last_key; //Help variable save last key (multiline string) - - - /** - * Constructor - */ - public function __construct() - { - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Read text file, icalender text file - * - * @param string $file File - * @return string - */ - public function read_file($file) - { - // phpcs:enable - $this->file = $file; - $file_text = ''; - - $tmparray = file($file); - if (is_array($tmparray)) - { - $file_text = join("", $tmparray); //load file - $file_text = preg_replace("/[\r\n]{1,} /", "", $file_text); - } - return $file_text; // return all text - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Returns the number of calendar events - * - * @return int - */ - public function get_event_count() - { - // phpcs:enable - return $this->event_count; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Returns the number of to do - * - * @return int - */ - public function get_todo_count() - { - // phpcs:enable - return $this->todo_count; - } - - /** - * Translate Calendar - * - * @param string $uri Url - * @return array|string - */ - public function parse($uri) - { - $this->cal = array(); // new empty array - - $this->event_count = -1; - - // read FILE text - $this->file_text = $this->read_file($uri); - - $this->file_text = preg_split("[\n]", $this->file_text); - - // is this text vcalendar standard text ? on line 1 is BEGIN:VCALENDAR - if (!stristr($this->file_text[0], 'BEGIN:VCALENDAR')) return 'error not VCALENDAR'; - - $insidealarm = 0; - $tmpkey = ''; $tmpvalue = ''; $type = ''; - foreach ($this->file_text as $text) - { - $text = trim($text); // trim one line - if (!empty($text)) - { - // get Key and Value VCALENDAR:Begin -> Key = VCALENDAR, Value = begin - list($key, $value) = $this->retun_key_value($text); - //var_dump($text.' -> '.$key.' - '.$value); - - switch ($text) // search special string - { - case "BEGIN:VTODO": - $this->todo_count = $this->todo_count + 1; // new to do begin - $type = "VTODO"; - break; - - case "BEGIN:VEVENT": - $this->event_count = $this->event_count + 1; // new event begin - $type = "VEVENT"; - break; - - case "BEGIN:VFREEBUSY": - $this->freebusy_count = $this->freebusy_count + 1; // new event begin - $type = "VFREEBUSY"; - break; - - case "BEGIN:VCALENDAR": // all other special string - case "BEGIN:DAYLIGHT": - case "BEGIN:VTIMEZONE": - case "BEGIN:STANDARD": - $type = $value; // save array under value key - break; - - case "END:VTODO": // end special text - goto VCALENDAR key - case "END:VEVENT": - case "END:VFREEBUSY": - - case "END:VCALENDAR": - case "END:DAYLIGHT": - case "END:VTIMEZONE": - case "END:STANDARD": - $type = "VCALENDAR"; - break; - - // Manage VALARM that are inside a VEVENT to avoid fields of VALARM to overwrites fields of VEVENT - case "BEGIN:VALARM": - $insidealarm = 1; - break; - case "END:VALARM": - $insidealarm = 0; - break; - - default: // no special string (SUMMARY, DESCRIPTION, ...) - if ($tmpvalue) + // Text in file + public $file_text; + public $cal; // Array to save iCalendar parse data + public $event_count; // Number of Events + public $todo_count; // Number of Todos + public $freebusy_count; // Number of Freebusy + public $last_key; //Help variable save last key (multiline string) + + + /** + * Constructor + */ + public function __construct() + { + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Read text file, icalender text file + * + * @param string $file File + * @return string + */ + public function read_file($file) + { + // phpcs:enable + $this->file = $file; + $file_text = ''; + + $tmparray = file($file); + if (is_array($tmparray)) + { + $file_text = join("", $tmparray); //load file + $file_text = preg_replace("/[\r\n]{1,} /", "", $file_text); + } + return $file_text; // return all text + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Returns the number of calendar events + * + * @return int + */ + public function get_event_count() + { + // phpcs:enable + return $this->event_count; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Returns the number of to do + * + * @return int + */ + public function get_todo_count() + { + // phpcs:enable + return $this->todo_count; + } + + /** + * Translate Calendar + * + * @param string $uri Url + * @return array|string + */ + public function parse($uri) + { + $this->cal = array(); // new empty array + + $this->event_count = -1; + + // read FILE text + $this->file_text = $this->read_file($uri); + + $this->file_text = preg_split("[\n]", $this->file_text); + + // is this text vcalendar standard text ? on line 1 is BEGIN:VCALENDAR + if (!stristr($this->file_text[0], 'BEGIN:VCALENDAR')) return 'error not VCALENDAR'; + + $insidealarm = 0; + $tmpkey = ''; $tmpvalue = ''; $type = ''; + foreach ($this->file_text as $text) + { + $text = trim($text); // trim one line + if (!empty($text)) + { + // get Key and Value VCALENDAR:Begin -> Key = VCALENDAR, Value = begin + list($key, $value) = $this->retun_key_value($text); + //var_dump($text.' -> '.$key.' - '.$value); + + switch ($text) // search special string + { + case "BEGIN:VTODO": + $this->todo_count = $this->todo_count + 1; // new to do begin + $type = "VTODO"; + break; + + case "BEGIN:VEVENT": + $this->event_count = $this->event_count + 1; // new event begin + $type = "VEVENT"; + break; + + case "BEGIN:VFREEBUSY": + $this->freebusy_count = $this->freebusy_count + 1; // new event begin + $type = "VFREEBUSY"; + break; + + case "BEGIN:VCALENDAR": // all other special string + case "BEGIN:DAYLIGHT": + case "BEGIN:VTIMEZONE": + case "BEGIN:STANDARD": + $type = $value; // save array under value key + break; + + case "END:VTODO": // end special text - goto VCALENDAR key + case "END:VEVENT": + case "END:VFREEBUSY": + + case "END:VCALENDAR": + case "END:DAYLIGHT": + case "END:VTIMEZONE": + case "END:STANDARD": + $type = "VCALENDAR"; + break; + + // Manage VALARM that are inside a VEVENT to avoid fields of VALARM to overwrites fields of VEVENT + case "BEGIN:VALARM": + $insidealarm = 1; + break; + case "END:VALARM": + $insidealarm = 0; + break; + + default: // no special string (SUMMARY, DESCRIPTION, ...) + if ($tmpvalue) { $tmpvalue .= $text; if (!preg_match('/=$/', $text)) // No more lines @@ -179,97 +179,102 @@ $tmpkey = ''; $tmpvalue = ''; } - } elseif (preg_match('/^ENCODING=QUOTED-PRINTABLE:/i', $value)) - { - if (preg_match('/=$/', $value)) - { - $tmpkey = $key; - $tmpvalue = $tmpvalue.preg_replace('/=$/', "", $value); // We must wait to have next line to have complete message - } else { - $value = quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i', '', $tmpvalue.$value)); - } - } //$value=quotedPrintDecode($tmpvalue.$value); - if (!$insidealarm && !$tmpkey) $this->add_to_array($type, $key, $value); // add to array - break; - } - } - } - - //var_dump($this->cal); - return $this->cal; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Add to $this->ical array one value and key. - * - * @param string $type Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...) - * @param string $key Key ('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property - * @param string $value Value - * @return void - */ - public function add_to_array($type, $key, $value) - { - // phpcs:enable - - //print 'type='.$type.' key='.$key.' value='.$value.'
'."\n"; - - if (empty($key)) - { - $key = $this->last_key; - switch ($type) - { - case 'VEVENT': $value = $this->cal[$type][$this->event_count][$key].$value; break; - case 'VFREEBUSY': $value = $this->cal[$type][$this->freebusy_count][$key].$value; break; - case 'VTODO': $value = $this->cal[$type][$this->todo_count][$key].$value; break; - } - } - - if (($key == "DTSTAMP") || ($key == "LAST-MODIFIED") || ($key == "CREATED")) $value = $this->ical_date_to_unix($value); - //if ($key == "RRULE" ) $value = $this->ical_rrule($value); - - if (stristr($key, "DTSTART") || stristr($key, "DTEND") || stristr($key, "DTSTART;VALUE=DATE") || stristr($key, "DTEND;VALUE=DATE")) - { - if (stristr($key, "DTSTART;VALUE=DATE") || stristr($key, "DTEND;VALUE=DATE")) - { - list($key, $value) = array($key, $value); - } else { - list($key, $value) = $this->ical_dt_date($key, $value); - } - } - - switch ($type) - { - case "VTODO": - $this->cal[$type][$this->todo_count][$key] = $value; - break; - - case "VEVENT": - $this->cal[$type][$this->event_count][$key] = $value; - break; - - case "VFREEBUSY": - $this->cal[$type][$this->freebusy_count][$key] = $value; - break; - - default: - $this->cal[$type][$key] = $value; - break; - } - $this->last_key = $key; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value"); - * - * @param string $text Text - * @return array - */ - public function retun_key_value($text) - { - // phpcs:enable - /* + } + elseif (preg_match('/^ENCODING=QUOTED-PRINTABLE:/i', $value)) + { + if (preg_match('/=$/', $value)) + { + $tmpkey = $key; + $tmpvalue = $tmpvalue.preg_replace('/=$/', "", $value); // We must wait to have next line to have complete message + } + else + { + $value = quotedPrintDecode(preg_replace('/^ENCODING=QUOTED-PRINTABLE:/i', '', $tmpvalue.$value)); + } + } //$value=quotedPrintDecode($tmpvalue.$value); + if (!$insidealarm && !$tmpkey) $this->add_to_array($type, $key, $value); // add to array + break; + } + } + } + + //var_dump($this->cal); + return $this->cal; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Add to $this->ical array one value and key. + * + * @param string $type Type ('VTODO', 'VEVENT', 'VFREEBUSY', 'VCALENDAR'...) + * @param string $key Key ('DTSTART', ...). Note: Field is never 'DTSTART;TZID=...' because ';...' was before removed and added as another property + * @param string $value Value + * @return void + */ + public function add_to_array($type, $key, $value) + { + // phpcs:enable + + //print 'type='.$type.' key='.$key.' value='.$value.'
'."\n"; + + if (empty($key)) + { + $key = $this->last_key; + switch ($type) + { + case 'VEVENT': $value = $this->cal[$type][$this->event_count][$key].$value; break; + case 'VFREEBUSY': $value = $this->cal[$type][$this->freebusy_count][$key].$value; break; + case 'VTODO': $value = $this->cal[$type][$this->todo_count][$key].$value; break; + } + } + + if (($key == "DTSTAMP") || ($key == "LAST-MODIFIED") || ($key == "CREATED")) $value = $this->ical_date_to_unix($value); + //if ($key == "RRULE" ) $value = $this->ical_rrule($value); + + if (stristr($key, "DTSTART") || stristr($key, "DTEND") || stristr($key, "DTSTART;VALUE=DATE") || stristr($key, "DTEND;VALUE=DATE")) + { + if (stristr($key, "DTSTART;VALUE=DATE") || stristr($key, "DTEND;VALUE=DATE")) + { + list($key, $value) = array($key, $value); + } + else + { + list($key, $value) = $this->ical_dt_date($key, $value); + } + } + + switch ($type) + { + case "VTODO": + $this->cal[$type][$this->todo_count][$key] = $value; + break; + + case "VEVENT": + $this->cal[$type][$this->event_count][$key] = $value; + break; + + case "VFREEBUSY": + $this->cal[$type][$this->freebusy_count][$key] = $value; + break; + + default: + $this->cal[$type][$key] = $value; + break; + } + $this->last_key = $key; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Parse text "XXXX:value text some with : " and return array($key = "XXXX", $value="value"); + * + * @param string $text Text + * @return array + */ + public function retun_key_value($text) + { + // phpcs:enable + /* preg_match("/([^:]+)[:]([\w\W]+)/", $text, $matches); if (empty($matches)) @@ -281,173 +286,175 @@ $matches = array_splice($matches, 1, 2); return $matches; }*/ - return explode(':', $text, 2); - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Parse RRULE return array - * - * @param string $value string - * @return array - */ - public function ical_rrule($value) - { - // phpcs:enable - $result = array(); - $rrule = explode(';', $value); - foreach ($rrule as $line) - { - $rcontent = explode('=', $line); - $result[$rcontent[0]] = $rcontent[1]; - } - return $result; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS) - * - * @param string $ical_date String date - * @return int - */ - public function ical_date_to_unix($ical_date) - { - // phpcs:enable - $ical_date = str_replace('T', '', $ical_date); - $ical_date = str_replace('Z', '', $ical_date); - - $ntime = 0; - // TIME LIMITED EVENT - if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})([0-9]{0,2})/', $ical_date, $date)) - $ntime = dol_mktime($date[4], $date[5], $date[6], $date[2], $date[3], $date[1], true); - - //if (empty($date[4])) print 'Error bad date: '.$ical_date.' - date1='.$date[1]; - //print dol_print_date($ntime,'dayhour');exit; - return $ntime; // ntime is a GTM time - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return unix date from iCal date format - * - * @param string $key Key - * @param string $value Value - * @return array - */ - public function ical_dt_date($key, $value) - { - // phpcs:enable - $return_value = array(); - $value = $this->ical_date_to_unix($value); - - // Analyse TZID - $temp = explode(";", $key); - - if (empty($temp[1])) // not TZID - { - $value = str_replace('T', '', $value); - return array($key, $value); - } - - $key = $temp[0]; - $temp = explode("=", $temp[1]); - $return_value[$temp[0]] = $temp[1]; - $return_value['unixtime'] = $value; - - return array($key, $return_value); - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return sorted eventlist as array or false if calendar is empty - * - * @return array|false - */ - public function get_sort_event_list() - { - // phpcs:enable - $temp = $this->get_event_list(); - if (!empty($temp)) - { - usort($temp, array(&$this, "ical_dtstart_compare")); - return $temp; - } else { - return false; - } - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Compare two unix timestamp - * - * @param array $a Operand a - * @param array $b Operand b - * @return integer - */ - public function ical_dtstart_compare($a, $b) - { - // phpcs:enable - return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']); - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return eventlist array (not sorted eventlist array) - * - * @return array - */ - public function get_event_list() - { - // phpcs:enable - return (!empty($this->cal['VEVENT']) ? $this->cal['VEVENT'] : ''); - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return eventlist array (not sort eventlist array) - * - * @return array - */ - public function get_freebusy_list() - { - // phpcs:enable - return $this->cal['VFREEBUSY']; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return to do array (not sorted todo array) - * - * @return array - */ - public function get_todo_list() - { - // phpcs:enable - return $this->cal['VTODO']; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return base calendar data - * - * @return array - */ - public function get_calender_data() - { - // phpcs:enable - return $this->cal['VCALENDAR']; - } - - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps - /** - * Return array with all data - * - * @return array - */ - public function get_all_data() - { - // phpcs:enable - return $this->cal; - } + return explode(':', $text, 2); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Parse RRULE return array + * + * @param string $value string + * @return array + */ + public function ical_rrule($value) + { + // phpcs:enable + $result = array(); + $rrule = explode(';', $value); + foreach ($rrule as $line) + { + $rcontent = explode('=', $line); + $result[$rcontent[0]] = $rcontent[1]; + } + return $result; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return Unix time from ical date time fomrat (YYYYMMDD[T]HHMMSS[Z] or YYYYMMDD[T]HHMMSS) + * + * @param string $ical_date String date + * @return int + */ + public function ical_date_to_unix($ical_date) + { + // phpcs:enable + $ical_date = str_replace('T', '', $ical_date); + $ical_date = str_replace('Z', '', $ical_date); + + $ntime = 0; + // TIME LIMITED EVENT + if (preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{0,2})([0-9]{0,2})([0-9]{0,2})/', $ical_date, $date)) + $ntime = dol_mktime($date[4], $date[5], $date[6], $date[2], $date[3], $date[1], true); + + //if (empty($date[4])) print 'Error bad date: '.$ical_date.' - date1='.$date[1]; + //print dol_print_date($ntime,'dayhour');exit; + return $ntime; // ntime is a GTM time + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return unix date from iCal date format + * + * @param string $key Key + * @param string $value Value + * @return array + */ + public function ical_dt_date($key, $value) + { + // phpcs:enable + $return_value = array(); + $value = $this->ical_date_to_unix($value); + + // Analyse TZID + $temp = explode(";", $key); + + if (empty($temp[1])) // not TZID + { + $value = str_replace('T', '', $value); + return array($key, $value); + } + + $key = $temp[0]; + $temp = explode("=", $temp[1]); + $return_value[$temp[0]] = $temp[1]; + $return_value['unixtime'] = $value; + + return array($key, $return_value); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return sorted eventlist as array or false if calendar is empty + * + * @return array|false + */ + public function get_sort_event_list() + { + // phpcs:enable + $temp = $this->get_event_list(); + if (!empty($temp)) + { + usort($temp, array(&$this, "ical_dtstart_compare")); + return $temp; + } + else + { + return false; + } + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Compare two unix timestamp + * + * @param array $a Operand a + * @param array $b Operand b + * @return integer + */ + public function ical_dtstart_compare($a, $b) + { + // phpcs:enable + return strnatcasecmp($a['DTSTART']['unixtime'], $b['DTSTART']['unixtime']); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return eventlist array (not sorted eventlist array) + * + * @return array + */ + public function get_event_list() + { + // phpcs:enable + return (!empty($this->cal['VEVENT']) ? $this->cal['VEVENT'] : ''); + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return eventlist array (not sort eventlist array) + * + * @return array + */ + public function get_freebusy_list() + { + // phpcs:enable + return $this->cal['VFREEBUSY']; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return to do array (not sorted todo array) + * + * @return array + */ + public function get_todo_list() + { + // phpcs:enable + return $this->cal['VTODO']; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return base calendar data + * + * @return array + */ + public function get_calender_data() + { + // phpcs:enable + return $this->cal['VCALENDAR']; + } + + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + /** + * Return array with all data + * + * @return array + */ + public function get_all_data() + { + // phpcs:enable + return $this->cal; + } }