--- /tmp/dsg/dolibarr/htdocs/projet/class/github_api_projects.class.php +++ /tmp/dsg/dolibarr/htdocs/projet/class/client_api_projects.class.php @@ -30,284 +30,286 @@ class Projects extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - static $FIELDS = array( - 'ref', - 'title' - ); - - /** - * @var Project $project {@type Project} - */ - public $project; - - /** - * Constructor - */ - public function __construct() - { - global $db, $conf; - $this->db = $db; - $this->project = new Project($this->db); - $this->task = new Task($this->db); - } - - /** - * Get properties of a project object - * - * Return an array with project informations - * - * @param int $id ID of project - * @return array|mixed data without useless information - * - * @throws RestException - */ - public function get($id) - { - if (!DolibarrApiAccess::$user->rights->projet->lire) { - throw new RestException(401); - } - - $result = $this->project->fetch($id); - if (!$result) { - throw new RestException(404, 'Project not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $this->project->fetchObjectLinked(); - return $this->_cleanObjectDatas($this->project); - } - - - - /** - * List projects - * - * Get a list of projects - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $thirdparty_ids Thirdparty ids to filter projects of (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i} + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'ref', + 'title' + ); + + /** + * @var Project $project {@type Project} + */ + public $project; + + /** + * Constructor + */ + public function __construct() + { + global $db, $conf; + $this->db = $db; + $this->project = new Project($this->db); + $this->task = new Task($this->db); + } + + /** + * Get properties of a project object + * + * Return an array with project informations + * + * @param int $id ID of project + * @return array|mixed data without useless information + * + * @throws RestException + */ + public function get($id) + { + if (!DolibarrApiAccess::$user->rights->projet->lire) { + throw new RestException(401); + } + + $result = $this->project->fetch($id); + if (!$result) { + throw new RestException(404, 'Project not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->project->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->project); + } + + + + /** + * List projects + * + * Get a list of projects + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter projects of (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i} * @param int $category Use this param to filter list by category * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" - * @return array Array of project objects - */ - public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $category = 0, $sqlfilters = '') - { - global $db, $conf; - - $obj_ret = array(); - - // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; - - // If the internal user must only see his customers, force searching by him - $search_sale = 0; - if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; - - $sql = "SELECT t.rowid"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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."projet as t"; - if ($category > 0) { + * @return array Array of project objects + */ + public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $category = 0, $sqlfilters = '') + { + global $db, $conf; + + $obj_ret = array(); + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; + + // If the internal user must only see his customers, force searching by him + $search_sale = 0; + if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT t.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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."projet as t"; + if ($category > 0) { $sql .= ", ".MAIN_DB_PREFIX."categorie_project as c"; - } - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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('project').')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; - if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")"; - if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - // Insert sale filter - if ($search_sale > 0) - { - $sql .= " AND sc.fk_user = ".$search_sale; - } - // Select projects of given category - if ($category > 0) { - $sql .= " AND c.fk_categorie = ".$this->db->escape($category)." AND c.fk_project = t.rowid "; - } - // 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); - } - - dol_syslog("API Rest request"); - $result = $this->db->query($sql); - - if ($result) - { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - $i = 0; - while ($i < $min) { - $obj = $this->db->fetch_object($result); - $project_static = new Project($this->db); - if ($project_static->fetch($obj->rowid)) { - $obj_ret[] = $this->_cleanObjectDatas($project_static); - } - $i++; - } - } else { - throw new RestException(503, 'Error when retrieve project list : '.$this->db->lasterror()); - } - if (!count($obj_ret)) { - throw new RestException(404, 'No project found'); - } - return $obj_ret; - } - - /** - * Create project object - * - * @param array $request_data Request data - * @return int ID of project - */ - public function post($request_data = null) - { - if (!DolibarrApiAccess::$user->rights->projet->creer) { - throw new RestException(401, "Insuffisant rights"); - } - // Check mandatory fields - $result = $this->_validate($request_data); - - foreach ($request_data as $field => $value) { - $this->project->$field = $value; - } - /*if (isset($request_data["lines"])) { + } + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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('project').')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + // Select projects of given category + if ($category > 0) { + $sql .= " AND c.fk_categorie = ".$db->escape($category)." AND c.fk_project = t.rowid "; + } + // 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); + } + + dol_syslog("API Rest request"); + $result = $db->query($sql); + + if ($result) + { + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + while ($i < $min) + { + $obj = $db->fetch_object($result); + $project_static = new Project($db); + if ($project_static->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($project_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve project list : '.$db->lasterror()); + } + if (!count($obj_ret)) { + throw new RestException(404, 'No project found'); + } + return $obj_ret; + } + + /** + * Create project object + * + * @param array $request_data Request data + * @return int ID of project + */ + public function post($request_data = null) + { + if (!DolibarrApiAccess::$user->rights->projet->creer) { + throw new RestException(401, "Insuffisant rights"); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach ($request_data as $field => $value) { + $this->project->$field = $value; + } + /*if (isset($request_data["lines"])) { $lines = array(); foreach ($request_data["lines"] as $line) { array_push($lines, (object) $line); } $this->project->lines = $lines; }*/ - if ($this->project->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, "Error creating project", array_merge(array($this->project->error), $this->project->errors)); - } - - return $this->project->id; - } - - /** - * Get tasks of a project. - * See also API /tasks - * - * @param int $id Id of project - * @param int $includetimespent 0=Return only list of tasks. 1=Include a summary of time spent, 2=Include details of time spent lines (2 is no implemented yet) - * @return int - * - * @url GET {id}/tasks - */ - public function getLines($id, $includetimespent = 0) - { - if (!DolibarrApiAccess::$user->rights->projet->lire) { - throw new RestException(401); - } - - $result = $this->project->fetch($id); - if (!$result) { - throw new RestException(404, 'Project not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - $this->project->getLinesArray(DolibarrApiAccess::$user); - $result = array(); - foreach ($this->project->lines as $line) // $line is a task - { - if ($includetimespent == 1) - { - $timespent = $line->getSummaryOfTimeSpent(0); - } - if ($includetimespent == 1) - { - // TODO - // Add class for timespent records and loop and fill $line->lines with records of timespent - } - array_push($result, $this->_cleanObjectDatas($line)); - } - return $result; - } - - - /** - * Get roles a user is assigned to a project with - * - * @param int $id Id of project - * @param int $userid Id of user (0 = connected user) - * - * @url GET {id}/roles - * - * @return int - */ - public function getRoles($id, $userid = 0) - { - global $db; - - if (!DolibarrApiAccess::$user->rights->projet->lire) { - throw new RestException(401); - } - - $result = $this->project->fetch($id); - if (!$result) { - throw new RestException(404, 'Project not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; - $taskstatic = new Task($this->db); - $userp = DolibarrApiAccess::$user; - if ($userid > 0) - { - $userp = new User($this->db); - $userp->fetch($userid); - } - $this->project->roles = $taskstatic->getUserRolesForProjectsOrTasks($userp, 0, $id, 0); - $result = array(); - foreach ($this->project->roles as $line) { - array_push($result, $this->_cleanObjectDatas($line)); - } - return $result; - } - - - /** - * Add a task to given project - * - * @param int $id Id of project to update - * @param array $request_data Projectline data - * - * @url POST {id}/tasks - * - * @return int - */ - /* + if ($this->project->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating project", array_merge(array($this->project->error), $this->project->errors)); + } + + return $this->project->id; + } + + /** + * Get tasks of a project. + * See also API /tasks + * + * @param int $id Id of project + * @param int $includetimespent 0=Return only list of tasks. 1=Include a summary of time spent, 2=Include details of time spent lines (2 is no implemented yet) + * @return int + * + * @url GET {id}/tasks + */ + public function getLines($id, $includetimespent = 0) + { + if (!DolibarrApiAccess::$user->rights->projet->lire) { + throw new RestException(401); + } + + $result = $this->project->fetch($id); + if (!$result) { + throw new RestException(404, 'Project not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $this->project->getLinesArray(DolibarrApiAccess::$user); + $result = array(); + foreach ($this->project->lines as $line) // $line is a task + { + if ($includetimespent == 1) + { + $timespent = $line->getSummaryOfTimeSpent(0); + } + if ($includetimespent == 1) + { + // TODO + // Add class for timespent records and loop and fill $line->lines with records of timespent + } + array_push($result, $this->_cleanObjectDatas($line)); + } + return $result; + } + + + /** + * Get roles a user is assigned to a project with + * + * @param int $id Id of project + * @param int $userid Id of user (0 = connected user) + * + * @url GET {id}/roles + * + * @return int + */ + public function getRoles($id, $userid = 0) + { + global $db; + + if (!DolibarrApiAccess::$user->rights->projet->lire) { + throw new RestException(401); + } + + $result = $this->project->fetch($id); + if (!$result) { + throw new RestException(404, 'Project not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; + $taskstatic = new Task($this->db); + $userp = DolibarrApiAccess::$user; + if ($userid > 0) + { + $userp = new User($this->db); + $userp->fetch($userid); + } + $this->project->roles = $taskstatic->getUserRolesForProjectsOrTasks($userp, 0, $id, 0); + $result = array(); + foreach ($this->project->roles as $line) { + array_push($result, $this->_cleanObjectDatas($line)); + } + return $result; + } + + + /** + * Add a task to given project + * + * @param int $id Id of project to update + * @param array $request_data Projectline data + * + * @url POST {id}/tasks + * + * @return int + */ + /* public function postLine($id, $request_data = null) { if(! DolibarrApiAccess::$user->rights->projet->creer) { @@ -359,18 +361,18 @@ } */ - /** - * Update a task to given project - * - * @param int $id Id of project to update - * @param int $taskid Id of task to update - * @param array $request_data Projectline data - * - * @url PUT {id}/tasks/{taskid} - * - * @return object - */ - /* + /** + * Update a task to given project + * + * @param int $id Id of project to update + * @param int $taskid Id of task to update + * @param array $request_data Projectline data + * + * @url PUT {id}/tasks/{taskid} + * + * @return object + */ + /* public function putLine($id, $lineid, $request_data = null) { if(! DolibarrApiAccess::$user->rights->projet->creer) { @@ -420,194 +422,196 @@ - /** - * Update project general fields (won't touch lines of project) - * - * @param int $id Id of project to update - * @param array $request_data Datas - * - * @return int - */ - public function put($id, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->projet->creer) { - throw new RestException(401); - } - - $result = $this->project->fetch($id); - if ($result <= 0) { - throw new RestException(404, 'Project not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - foreach ($request_data as $field => $value) { - if ($field == 'id') continue; - $this->project->$field = $value; - } - - if ($this->project->update(DolibarrApiAccess::$user) >= 0) - { - return $this->get($id); - } else { - throw new RestException(500, $this->project->error); - } - } - - /** - * Delete project - * - * @param int $id Project ID - * - * @return array - */ - public function delete($id) - { - if (!DolibarrApiAccess::$user->rights->projet->supprimer) { - throw new RestException(401); - } - $result = $this->project->fetch($id); - if (!$result) { - throw new RestException(404, 'Project not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - if (!$this->project->delete(DolibarrApiAccess::$user)) { - throw new RestException(500, 'Error when delete project : '.$this->project->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Project deleted' - ) - ); - } - - /** - * Validate a project. - * You can test this API with the following input message - * { "notrigger": 0 } - * - * @param int $id Project ID - * @param int $notrigger 1=Does not execute triggers, 0= execute triggers - * - * @url POST {id}/validate - * - * @return array - * FIXME An error 403 is returned if the request has an empty body. - * Error message: "Forbidden: Content type `text/plain` is not supported." - * Workaround: send this in the body - * { - * "notrigger": 0 - * } - */ - public function validate($id, $notrigger = 0) - { - if (!DolibarrApiAccess::$user->rights->projet->creer) { - throw new RestException(401); - } - $result = $this->project->fetch($id); - if (!$result) { - throw new RestException(404, 'Project not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger); - if ($result == 0) { - throw new RestException(304, 'Error nothing done. May be object is already validated'); - } - if ($result < 0) { - throw new RestException(500, 'Error when validating Project: '.$this->project->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Project validated' - ) - ); - } - - - // 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->datec); - unset($object->datem); - unset($object->barcode_type); - unset($object->barcode_type_code); - unset($object->barcode_type_label); - unset($object->barcode_type_coder); - 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->note); - 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->mode_reglement_id); - unset($object->country); - unset($object->country_id); - unset($object->country_code); - - unset($object->weekWorkLoad); - unset($object->weekWorkLoad); - - //unset($object->lines); // for task we use timespent_lines, but for project we use lines - - unset($object->total_ht); - unset($object->total_tva); - unset($object->total_localtax1); - unset($object->total_localtax2); - unset($object->total_ttc); - - unset($object->comments); - - return $object; - } - - /** - * Validate fields before create or update object - * - * @param array $data Array with data to verify - * @return array - * @throws RestException - */ - private function _validate($data) - { - $object = array(); - foreach (self::$FIELDS as $field) { - if (!isset($data[$field])) - throw new RestException(400, "$field field missing"); - $object[$field] = $data[$field]; - } - return $object; - } - - - // TODO - // getSummaryOfTimeSpent + /** + * Update project general fields (won't touch lines of project) + * + * @param int $id Id of project to update + * @param array $request_data Datas + * + * @return int + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->projet->creer) { + throw new RestException(401); + } + + $result = $this->project->fetch($id); + if ($result <= 0) { + throw new RestException(404, 'Project not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + foreach ($request_data as $field => $value) { + if ($field == 'id') continue; + $this->project->$field = $value; + } + + if ($this->project->update(DolibarrApiAccess::$user) >= 0) + { + return $this->get($id); + } + else + { + throw new RestException(500, $this->project->error); + } + } + + /** + * Delete project + * + * @param int $id Project ID + * + * @return array + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->rights->projet->supprimer) { + throw new RestException(401); + } + $result = $this->project->fetch($id); + if (!$result) { + throw new RestException(404, 'Project not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if (!$this->project->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete project : '.$this->project->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Project deleted' + ) + ); + } + + /** + * Validate a project. + * You can test this API with the following input message + * { "notrigger": 0 } + * + * @param int $id Project ID + * @param int $notrigger 1=Does not execute triggers, 0= execute triggers + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "notrigger": 0 + * } + */ + public function validate($id, $notrigger = 0) + { + if (!DolibarrApiAccess::$user->rights->projet->creer) { + throw new RestException(401); + } + $result = $this->project->fetch($id); + if (!$result) { + throw new RestException(404, 'Project not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger); + if ($result == 0) { + throw new RestException(304, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Project: '.$this->project->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Project validated' + ) + ); + } + + + // 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->datec); + unset($object->datem); + unset($object->barcode_type); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + unset($object->barcode_type_coder); + 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->note); + 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->mode_reglement_id); + unset($object->country); + unset($object->country_id); + unset($object->country_code); + + unset($object->weekWorkLoad); + unset($object->weekWorkLoad); + + //unset($object->lines); // for task we use timespent_lines, but for project we use lines + + unset($object->total_ht); + unset($object->total_tva); + unset($object->total_localtax1); + unset($object->total_localtax2); + unset($object->total_ttc); + + unset($object->comments); + + return $object; + } + + /** + * Validate fields before create or update object + * + * @param array $data Array with data to verify + * @return array + * @throws RestException + */ + private function _validate($data) + { + $object = array(); + foreach (self::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $object[$field] = $data[$field]; + } + return $object; + } + + + // TODO + // getSummaryOfTimeSpent } --- /tmp/dsg/dolibarr/htdocs/projet/class/github_api_tasks.class.php +++ /tmp/dsg/dolibarr/htdocs/projet/class/client_api_tasks.class.php @@ -30,51 +30,50 @@ class Tasks extends DolibarrApi { - /** - * @var array $FIELDS Mandatory fields, checked when create and update object - */ - static $FIELDS = array( - 'ref', - 'label', - 'fk_project' - ); - - /** - * @var Task $task {@type Task} - */ - public $task; - - /** - * Constructor - */ - public function __construct() - { - global $db, $conf; - $this->db = $db; - $this->task = new Task($this->db); - } - - /** - * Get properties of a task object + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'ref', + 'label' + ); + + /** + * @var Task $task {@type Task} + */ + public $task; + + /** + * Constructor + */ + public function __construct() + { + global $db, $conf; + $this->db = $db; + $this->task = new Task($this->db); + } + + /** + * Get properties of a task object + * + * Return an array with task informations + * + * @param int $id ID of task + * @param int $includetimespent 0=Return only task. 1=Include a summary of time spent, 2=Include details of time spent lines (2 is no implemented yet) + * @return array|mixed data without useless information * - * Return an array with task informations - * - * @param int $id ID of task - * @param int $includetimespent 0=Return only task. 1=Include a summary of time spent, 2=Include details of time spent lines (2 is no implemented yet) - * @return array|mixed data without useless information - * - * @throws RestException - */ - public function get($id, $includetimespent = 0) - { + * @throws RestException + */ + public function get($id, $includetimespent = 0) + { if (!DolibarrApiAccess::$user->rights->projet->lire) { throw new RestException(401); } - $result = $this->task->fetch($id); - if (!$result) { - throw new RestException(404, 'Task not found'); - } + $result = $this->task->fetch($id); + if (!$result) { + throw new RestException(404, 'Task not found'); + } if (!DolibarrApi::_checkAccessToResource('task', $this->task->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); @@ -82,147 +81,148 @@ if ($includetimespent == 1) { - $timespent = $this->task->getSummaryOfTimeSpent(0); + $timespent = $this->task->getSummaryOfTimeSpent(0); } if ($includetimespent == 1) { - // TODO - // Add class for timespent records and loop and fill $line->lines with records of timespent + // TODO + // Add class for timespent records and loop and fill $line->lines with records of timespent } return $this->_cleanObjectDatas($this->task); - } - - - - /** - * List tasks - * - * Get a list of tasks - * - * @param string $sortfield Sort field - * @param string $sortorder Sort order - * @param int $limit Limit for list - * @param int $page Page number - * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" - * @return array Array of project objects - */ - public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') - { - global $db, $conf; - - $obj_ret = array(); - - // case of external user, $thirdparty_ids param is ignored and replaced by user's socid - $socids = DolibarrApiAccess::$user->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 && !$socids) $search_sale = DolibarrApiAccess::$user->id; - - $sql = "SELECT t.rowid"; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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."projet_task as t"; - - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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('project').')'; - if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; - if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")"; - if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale - // 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); - } - - dol_syslog("API Rest request"); - $result = $this->db->query($sql); - - if ($result) - { - $num = $this->db->num_rows($result); - $min = min($num, ($limit <= 0 ? $num : $limit)); - $i = 0; - while ($i < $min) - { - $obj = $this->db->fetch_object($result); - $task_static = new Task($this->db); - if ($task_static->fetch($obj->rowid)) { - $obj_ret[] = $this->_cleanObjectDatas($task_static); - } - $i++; - } - } else { - throw new RestException(503, 'Error when retrieve task list : '.$this->db->lasterror()); - } - if (!count($obj_ret)) { - throw new RestException(404, 'No task found'); - } + } + + + + /** + * List tasks + * + * Get a list of tasks + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" + * @return array Array of project objects + */ + public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') + { + global $db, $conf; + + $obj_ret = array(); + + // case of external user, $thirdparty_ids param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->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 && !$socids) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT t.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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."projet_task as t"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $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('project').')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; + if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + // 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); + } + + dol_syslog("API Rest request"); + $result = $db->query($sql); + + if ($result) + { + $num = $db->num_rows($result); + $min = min($num, ($limit <= 0 ? $num : $limit)); + $i = 0; + while ($i < $min) + { + $obj = $db->fetch_object($result); + $task_static = new Task($db); + if ($task_static->fetch($obj->rowid)) { + $obj_ret[] = $this->_cleanObjectDatas($task_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve task list : '.$db->lasterror()); + } + if (!count($obj_ret)) { + throw new RestException(404, 'No task found'); + } return $obj_ret; - } - - /** - * Create task object - * - * @param array $request_data Request data - * @return int ID of project - */ - public function post($request_data = null) - { - if (!DolibarrApiAccess::$user->rights->projet->creer) { - throw new RestException(401, "Insuffisant rights"); - } - // Check mandatory fields - $result = $this->_validate($request_data); - - foreach ($request_data as $field => $value) { - $this->task->$field = $value; - } - /*if (isset($request_data["lines"])) { + } + + /** + * Create task object + * + * @param array $request_data Request data + * @return int ID of project + */ + public function post($request_data = null) + { + if (!DolibarrApiAccess::$user->rights->projet->creer) { + throw new RestException(401, "Insuffisant rights"); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach ($request_data as $field => $value) { + $this->task->$field = $value; + } + /*if (isset($request_data["lines"])) { $lines = array(); foreach ($request_data["lines"] as $line) { array_push($lines, (object) $line); } $this->project->lines = $lines; }*/ - if ($this->task->create(DolibarrApiAccess::$user) < 0) { - throw new RestException(500, "Error creating task", array_merge(array($this->task->error), $this->task->errors)); - } - - return $this->task->id; - } - - // /** - // * Get time spent of a task - // * - // * @param int $id Id of task - // * @return int - // * - // * @url GET {id}/tasks - // */ - /* + if ($this->task->create(DolibarrApiAccess::$user) < 0) { + throw new RestException(500, "Error creating task", array_merge(array($this->task->error), $this->task->errors)); + } + + return $this->task->id; + } + + // /** + // * Get time spent of a task + // * + // * @param int $id Id of task + // * @return int + // * + // * @url GET {id}/tasks + // */ + /* public function getLines($id, $includetimespent=0) { if(! DolibarrApiAccess::$user->rights->projet->lire) { @@ -256,59 +256,59 @@ } */ - /** - * Get roles a user is assigned to a task with - * - * @param int $id Id of task - * @param int $userid Id of user (0 = connected user) - * - * @url GET {id}/roles - * - * @return int - */ - public function getRoles($id, $userid = 0) - { - global $db; - - if (!DolibarrApiAccess::$user->rights->projet->lire) { - throw new RestException(401); - } - - $result = $this->task->fetch($id); - if (!$result) { - throw new RestException(404, 'Task not found'); - } - - if (!DolibarrApi::_checkAccessToResource('tasks', $this->task->id)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $usert = DolibarrApiAccess::$user; - if ($userid > 0) - { - $usert = new User($this->db); - $usert->fetch($userid); - } - $this->task->roles = $this->task->getUserRolesForProjectsOrTasks(0, $usert, 0, $id); - $result = array(); - foreach ($this->task->roles as $line) { - array_push($result, $this->_cleanObjectDatas($line)); - } - return $result; - } - - - // /** - // * Add a task to given project - // * - // * @param int $id Id of project to update - // * @param array $request_data Projectline data - // * - // * @url POST {id}/tasks - // * - // * @return int - // */ - /* + /** + * Get roles a user is assigned to a task with + * + * @param int $id Id of task + * @param int $userid Id of user (0 = connected user) + * + * @url GET {id}/roles + * + * @return int + */ + public function getRoles($id, $userid = 0) + { + global $db; + + if (!DolibarrApiAccess::$user->rights->projet->lire) { + throw new RestException(401); + } + + $result = $this->task->fetch($id); + if (!$result) { + throw new RestException(404, 'Task not found'); + } + + if (!DolibarrApi::_checkAccessToResource('tasks', $this->task->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $usert = DolibarrApiAccess::$user; + if ($userid > 0) + { + $usert = new User($this->db); + $usert->fetch($userid); + } + $this->task->roles = $this->task->getUserRolesForProjectsOrTasks(0, $usert, 0, $id); + $result = array(); + foreach ($this->task->roles as $line) { + array_push($result, $this->_cleanObjectDatas($line)); + } + return $result; + } + + + // /** + // * Add a task to given project + // * + // * @param int $id Id of project to update + // * @param array $request_data Projectline data + // * + // * @url POST {id}/tasks + // * + // * @return int + // */ + /* public function postLine($id, $request_data = null) { if(! DolibarrApiAccess::$user->rights->projet->creer) { @@ -360,18 +360,18 @@ } */ - // /** - // * Update a task to given project - // * - // * @param int $id Id of project to update - // * @param int $taskid Id of task to update - // * @param array $request_data Projectline data - // * - // * @url PUT {id}/tasks/{taskid} - // * - // * @return object - // */ - /* + // /** + // * Update a task to given project + // * + // * @param int $id Id of project to update + // * @param int $taskid Id of task to update + // * @param array $request_data Projectline data + // * + // * @url PUT {id}/tasks/{taskid} + // * + // * @return object + // */ + /* public function putLine($id, $lineid, $request_data = null) { if(! DolibarrApiAccess::$user->rights->projet->creer) { @@ -420,201 +420,203 @@ }*/ - /** - * Update task general fields (won't touch time spent of task) - * - * @param int $id Id of task to update - * @param array $request_data Datas - * - * @return int - */ - public function put($id, $request_data = null) - { - if (!DolibarrApiAccess::$user->rights->projet->creer) { - throw new RestException(401); - } - - $result = $this->task->fetch($id); - if (!$result) { - throw new RestException(404, 'Task not found'); - } + /** + * Update task general fields (won't touch time spent of task) + * + * @param int $id Id of task to update + * @param array $request_data Datas + * + * @return int + */ + public function put($id, $request_data = null) + { + if (!DolibarrApiAccess::$user->rights->projet->creer) { + throw new RestException(401); + } + + $result = $this->task->fetch($id); + if (!$result) { + throw new RestException(404, 'Task not found'); + } if (!DolibarrApi::_checkAccessToResource('tasks', $this->project->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - foreach ($request_data as $field => $value) { - if ($field == 'id') continue; - $this->task->$field = $value; - } - - if ($this->task->update(DolibarrApiAccess::$user) > 0) - { - return $this->get($id); - } else { - throw new RestException(500, $this->task->error); - } - } - - /** - * Delete task - * - * @param int $id Task ID - * - * @return array - */ - public function delete($id) - { - if (!DolibarrApiAccess::$user->rights->projet->supprimer) { - throw new RestException(401); - } - $result = $this->task->fetch($id); - if (!$result) { - throw new RestException(404, 'Task not found'); - } + foreach ($request_data as $field => $value) { + if ($field == 'id') continue; + $this->task->$field = $value; + } + + if ($this->task->update(DolibarrApiAccess::$user) > 0) + { + return $this->get($id); + } + else + { + throw new RestException(500, $this->task->error); + } + } + + /** + * Delete task + * + * @param int $id Task ID + * + * @return array + */ + public function delete($id) + { + if (!DolibarrApiAccess::$user->rights->projet->supprimer) { + throw new RestException(401); + } + $result = $this->task->fetch($id); + if (!$result) { + throw new RestException(404, 'Task not found'); + } if (!DolibarrApi::_checkAccessToResource('tasks', $this->project->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - if (!$this->task->delete(DolibarrApiAccess::$user)) { - throw new RestException(500, 'Error when delete task : '.$this->task->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Task deleted' - ) - ); - } - - - /** - * Add time spent to a task of a project. - * You can test this API with the following input message - * { "date": "2016-12-31 23:15:00", "duration": 1800, "user_id": 1, "note": "My time test" } - * - * @param int $id Task ID - * @param datetime $date Date (YYYY-MM-DD HH:MI:SS in GMT) - * @param int $duration Duration in seconds (3600 = 1h) - * @param int $user_id User (Use 0 for connected user) - * @param string $note Note - * - * @url POST {id}/addtimespent - * - * @return array - */ - public function addTimeSpent($id, $date, $duration, $user_id = 0, $note = '') - { - if (!DolibarrApiAccess::$user->rights->projet->creer) { - throw new RestException(401); - } - $result = $this->task->fetch($id); - if ($result <= 0) { - throw new RestException(404, 'Task not found'); - } - - if (!DolibarrApi::_checkAccessToResource('project', $this->task->fk_project)) { - throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); - } - - $uid = $user_id; - if (empty($uid)) $uid = DolibarrApiAccess::$user->id; - - $newdate = dol_stringtotime($date, 1); - $this->task->timespent_date = $newdate; - $this->task->timespent_datehour = $newdate; - $this->task->timespent_withhour = 1; - $this->task->timespent_duration = $duration; - $this->task->timespent_fk_user = $user_id; - $this->task->timespent_note = $note; - - $result = $this->task->addTimeSpent(DolibarrApiAccess::$user, 0); - if ($result == 0) { - throw new RestException(304, 'Error nothing done. May be object is already validated'); - } - if ($result < 0) { - throw new RestException(500, 'Error when adding time: '.$this->task->error); - } - - return array( - 'success' => array( - 'code' => 200, - 'message' => 'Time spent added' - ) - ); - } - - - // 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->barcode_type); - unset($object->barcode_type_code); - unset($object->barcode_type_label); - unset($object->barcode_type_coder); - 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->note); - 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->mode_reglement_id); - unset($object->country); - unset($object->country_id); - unset($object->country_code); - - unset($object->weekWorkLoad); - unset($object->weekWorkLoad); - - //unset($object->lines); // for task we use timespent_lines, but for project we use lines - - unset($object->total_ht); - unset($object->total_tva); - unset($object->total_localtax1); - unset($object->total_localtax2); - unset($object->total_ttc); - - unset($object->comments); - - return $object; - } - - /** - * Validate fields before create or update object - * - * @param array $data Array with data to verify - * @return array - * @throws RestException - */ - private function _validate($data) - { - $object = array(); - foreach (self::$FIELDS as $field) { - if (!isset($data[$field])) - throw new RestException(400, "$field field missing"); - $object[$field] = $data[$field]; - } - return $object; - } - - - // \todo - // getSummaryOfTimeSpent + if (!$this->task->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete task : '.$this->task->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Task deleted' + ) + ); + } + + + /** + * Add time spent to a task of a project. + * You can test this API with the following input message + * { "date": "2016-12-31 23:15:00", "duration": 1800, "user_id": 1, "note": "My time test" } + * + * @param int $id Task ID + * @param datetime $date Date (YYYY-MM-DD HH:MI:SS in GMT) + * @param int $duration Duration in seconds (3600 = 1h) + * @param int $user_id User (Use 0 for connected user) + * @param string $note Note + * + * @url POST {id}/addtimespent + * + * @return array + */ + public function addTimeSpent($id, $date, $duration, $user_id = 0, $note = '') + { + if (!DolibarrApiAccess::$user->rights->projet->creer) { + throw new RestException(401); + } + $result = $this->task->fetch($id); + if ($result <= 0) { + throw new RestException(404, 'Task not found'); + } + + if (!DolibarrApi::_checkAccessToResource('project', $this->task->fk_project)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $uid = $user_id; + if (empty($uid)) $uid = DolibarrApiAccess::$user->id; + + $newdate = dol_stringtotime($date, 1); + $this->task->timespent_date = $newdate; + $this->task->timespent_datehour = $newdate; + $this->task->timespent_withhour = 1; + $this->task->timespent_duration = $duration; + $this->task->timespent_fk_user = $user_id; + $this->task->timespent_note = $note; + + $result = $this->task->addTimeSpent(DolibarrApiAccess::$user, 0); + if ($result == 0) { + throw new RestException(304, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when adding time: '.$this->task->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Time spent added' + ) + ); + } + + + // 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->barcode_type); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + unset($object->barcode_type_coder); + 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->note); + 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->mode_reglement_id); + unset($object->country); + unset($object->country_id); + unset($object->country_code); + + unset($object->weekWorkLoad); + unset($object->weekWorkLoad); + + //unset($object->lines); // for task we use timespent_lines, but for project we use lines + + unset($object->total_ht); + unset($object->total_tva); + unset($object->total_localtax1); + unset($object->total_localtax2); + unset($object->total_ttc); + + unset($object->comments); + + return $object; + } + + /** + * Validate fields before create or update object + * + * @param array $data Array with data to verify + * @return array + * @throws RestException + */ + private function _validate($data) + { + $object = array(); + foreach (self::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $object[$field] = $data[$field]; + } + return $object; + } + + + // \todo + // getSummaryOfTimeSpent } --- /tmp/dsg/dolibarr/htdocs/projet/class/github_project.class.php +++ /tmp/dsg/dolibarr/htdocs/projet/class/client_project.class.php @@ -45,17 +45,17 @@ public $table_element = 'projet'; /** - * @var string Name of subtable line + * @var int Name of subtable line */ public $table_element_line = 'projet_task'; /** - * @var string Name of field date + * @var int Name of field date */ public $table_element_date; /** - * @var string Field with ID of parent key if this field has a parent + * @var int Field with ID of parent key if this field has a parent */ public $fk_element = 'fk_projet'; @@ -114,8 +114,6 @@ public $opp_status; // opportunity status, into table llx_c_lead_status public $opp_percent; // opportunity probability - public $email_msgid; - public $oldcopy; public $weekWorkLoad; // Used to store workload details of a projet @@ -151,79 +149,52 @@ public $lines; /** - * 'type' if the field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password') - * Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)" - * 'label' the translation key. - * 'enabled' is a condition when the field must be managed. - * 'position' is the sort order of field. - * 'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0). - * 'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing) - * 'noteditable' says if field is not editable (1 or 0) - * 'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created. - * 'index' if we want an index in database. - * 'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommanded to name the field fk_...). - * 'searchall' is 1 if we want to search in this field when making a search from the quick search button. - * 'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8). - * 'css' is the CSS style to use on field. For example: 'maxwidth200' - * 'help' is a string visible as a tooltip on field - * 'showoncombobox' if value of the field must be visible into the label of the combobox that list record - * 'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code. - * 'arraykeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel") - * 'comment' is not used. You can store here any text of your choice. It is not used by application. - * - * Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor. - */ - - // BEGIN MODULEBUILDER PROPERTIES - /** - * @var array Array with all fields and their property. Do not use it as a static var. It may be modified by constructor. - */ - public $fields = array( + * Draft status + */ + const STATUS_DRAFT = 0; + + /** + * Open/Validated status + */ + const STATUS_VALIDATED = 1; + + /** + * Closed status + */ + const STATUS_CLOSED = 2; + + + public $fields=array( 'rowid' =>array('type'=>'integer', 'label'=>'ID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), - 'ref' =>array('type'=>'varchar(50)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>15, 'searchall'=>1), - 'title' =>array('type'=>'varchar(255)', 'label'=>'ProjectLabel', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>17, 'showoncombobox'=>1, 'searchall'=>1), - 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>3, 'notnull'=>1, 'position'=>19), - 'fk_soc' =>array('type'=>'integer', 'label'=>'Thirdparty', 'enabled'=>1, 'visible'=>0, 'position'=>20), - 'dateo' =>array('type'=>'date', 'label'=>'DateStart', 'enabled'=>1, 'visible'=>1, 'position'=>30), - 'datee' =>array('type'=>'date', 'label'=>'DateEnd', 'enabled'=>1, 'visible'=>1, 'position'=>35), - 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>55, 'searchall'=>1), - 'public' =>array('type'=>'integer', 'label'=>'Visibility', 'enabled'=>1, 'visible'=>1, 'position'=>65), - 'fk_opp_status' =>array('type'=>'integer', 'label'=>'OpportunityStatusShort', 'enabled'=>1, 'visible'=>1, 'position'=>75), - 'opp_percent' =>array('type'=>'double(5,2)', 'label'=>'OpportunityProbabilityShort', 'enabled'=>1, 'visible'=>1, 'position'=>80), - 'note_private' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>85, 'searchall'=>1), - 'note_public' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>90, 'searchall'=>1), - 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'ModelPdf', 'enabled'=>1, 'visible'=>0, 'position'=>95), - 'date_close' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>0, 'position'=>105), - 'fk_user_close' =>array('type'=>'integer', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>0, 'position'=>110), - 'opp_amount' =>array('type'=>'double(24,8)', 'label'=>'OpportunityAmountShort', 'enabled'=>1, 'visible'=>1, 'position'=>115), - 'budget_amount' =>array('type'=>'double(24,8)', 'label'=>'Budget', 'enabled'=>1, 'visible'=>1, 'position'=>119), - 'usage_bill_time' =>array('type'=>'integer', 'label'=>'UsageBillTimeShort', 'enabled'=>1, 'visible'=>-1, 'position'=>130), - 'usage_opportunity' =>array('type'=>'integer', 'label'=>'UsageOpportunity', 'enabled'=>1, 'visible'=>-1, 'position'=>135), - 'usage_task' =>array('type'=>'integer', 'label'=>'UsageTasks', 'enabled'=>1, 'visible'=>-1, 'position'=>140), + 'fk_soc' =>array('type'=>'integer', 'label'=>'Fk soc', 'enabled'=>1, 'visible'=>-1, 'position'=>15), + 'datec' =>array('type'=>'datetime', 'label'=>'Datec', 'enabled'=>1, 'visible'=>-1, 'position'=>20), + 'tms' =>array('type'=>'timestamp', 'label'=>'Tms', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25), + 'dateo' =>array('type'=>'date', 'label'=>'Dateo', 'enabled'=>1, 'visible'=>-1, 'position'=>30), + 'datee' =>array('type'=>'date', 'label'=>'Datee', 'enabled'=>1, 'visible'=>-1, 'position'=>35), + 'ref' =>array('type'=>'varchar(50)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'showoncombobox'=>1, 'position'=>40), + 'entity' =>array('type'=>'integer', 'label'=>'Entity', 'default'=>1, 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>45), + 'title' =>array('type'=>'varchar(255)', 'label'=>'Title', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>50, 'showoncombobox'=>1), + 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>55), + 'fk_user_creat' =>array('type'=>'integer', 'label'=>'Fk user creat', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>60), + 'public' =>array('type'=>'integer', 'label'=>'Public', 'enabled'=>1, 'visible'=>-1, 'position'=>65), + 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Fk statut', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>500), + 'fk_opp_status' =>array('type'=>'integer', 'label'=>'Fk opp status', 'enabled'=>1, 'visible'=>-1, 'position'=>75), + 'opp_percent' =>array('type'=>'double(5,2)', 'label'=>'Opp percent', 'enabled'=>1, 'visible'=>-1, 'position'=>80), + 'note_private' =>array('type'=>'text', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>85), + 'note_public' =>array('type'=>'text', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>90), + 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>95), + 'budget_amount' =>array('type'=>'double(24,8)', 'label'=>'Budget amount', 'enabled'=>1, 'visible'=>-1, 'position'=>100), + 'date_close' =>array('type'=>'datetime', 'label'=>'Date close', 'enabled'=>1, 'visible'=>-1, 'position'=>105), + 'fk_user_close' =>array('type'=>'integer', 'label'=>'Fk user close', 'enabled'=>1, 'visible'=>-1, 'position'=>110), + 'opp_amount' =>array('type'=>'double(24,8)', 'label'=>'Opp amount', 'enabled'=>1, 'visible'=>-1, 'position'=>115), + 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-1, 'position'=>120), + 'fk_user_modif' =>array('type'=>'integer', 'label'=>'Fk user modif', 'enabled'=>1, 'visible'=>-1, 'position'=>125), + 'usage_bill_time' =>array('type'=>'integer', 'label'=>'Usage bill time', 'enabled'=>1, 'visible'=>-1, 'position'=>130), + 'usage_opportunity' =>array('type'=>'integer', 'label'=>'Usage opportunity', 'enabled'=>1, 'visible'=>-1, 'position'=>135), + 'usage_task' =>array('type'=>'integer', 'label'=>'Usage task', 'enabled'=>1, 'visible'=>-1, 'position'=>140), 'usage_organize_event' =>array('type'=>'integer', 'label'=>'Usage organize event', 'enabled'=>1, 'visible'=>-1, 'position'=>145), - 'datec' =>array('type'=>'datetime', 'label'=>'DateCreationShort', 'enabled'=>1, 'visible'=>-2, 'position'=>200), - 'tms' =>array('type'=>'timestamp', 'label'=>'DateModificationShort', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1, 'position'=>205), - 'fk_user_creat' =>array('type'=>'integer', 'label'=>'UserCreation', 'enabled'=>1, 'visible'=>0, 'notnull'=>1, 'position'=>210), - 'fk_user_modif' =>array('type'=>'integer', 'label'=>'UserModification', 'enabled'=>1, 'visible'=>0, 'position'=>215), - 'import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>0, 'position'=>220), - 'fk_statut' =>array('type'=>'smallint(6)', 'label'=>'Status', 'enabled'=>1, 'visible'=>1, 'notnull'=>1, 'position'=>500) ); - // END MODULEBUILDER PROPERTIES - - /** - * Draft status - */ - const STATUS_DRAFT = 0; - - /** - * Open/Validated status - */ - const STATUS_VALIDATED = 1; - - /** - * Closed status - */ - const STATUS_CLOSED = 2; + /** * Constructor @@ -236,26 +207,6 @@ $this->statuts_short = array(0 => 'Draft', 1 => 'Opened', 2 => 'Closed'); $this->statuts_long = array(0 => 'Draft', 1 => 'Opened', 2 => 'Closed'); - - global $conf; - - if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID)) $this->fields['rowid']['visible'] = 0; - - if (empty($conf->global->PROJECT_USE_OPPORTUNITIES)) { - $this->fields['fk_opp_status']['enabled'] = 0; - $this->fields['opp_percent']['enabled'] = 0; - $this->fields['opp_amount']['enabled'] = 0; - $this->fields['usage_opportunity']['enabled'] = 0; - } - - if (empty($conf->global->PROJECT_HIDE_TASKS)) { - $this->fields['usage_bill_time']['visible'] = 0; - $this->fields['usage_task']['visible'] = 0; - } - - if (empty($conf->global->PROJECT_ORGANIZE_EVENTS)) { - $this->fields['usage_organize_event']['visible'] = 0; - } } /** @@ -314,7 +265,6 @@ $sql .= ", usage_task"; $sql .= ", usage_bill_time"; $sql .= ", usage_organize_event"; - $sql .= ", email_msgid"; $sql .= ", note_private"; $sql .= ", note_public"; $sql .= ", entity"; @@ -337,7 +287,6 @@ $sql .= ", ".($this->usage_task ? 1 : 0); $sql .= ", ".($this->usage_bill_time ? 1 : 0); $sql .= ", ".($this->usage_organize_event ? 1 : 0); - $sql .= ", ".($this->email_msgid ? "'".$this->db->escape($this->email_msgid)."'" : 'null'); $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : 'null'); $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : 'null'); $sql .= ", ".$conf->entity; @@ -357,7 +306,9 @@ if ($result < 0) { $error++; } // End call triggers } - } else { + } + else + { $this->error = $this->db->lasterror(); $this->errno = $this->db->lasterrno(); $error++; @@ -382,7 +333,9 @@ { $this->db->commit(); return $ret; - } else { + } + else + { $this->db->rollback(); return -1; } @@ -488,23 +441,31 @@ { $this->db->commit(); $result = 1; - } else { + } + else + { $this->db->rollback(); $result = -1; } - } else { + } + else + { $this->error = $this->db->lasterror(); $this->errors[] = $this->error; $this->db->rollback(); if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { $result = -4; - } else { + } + else + { $result = -2; } dol_syslog(get_class($this)."::update error ".$result." ".$this->error, LOG_ERR); } - } else { + } + else + { dol_syslog(get_class($this)."::update ref null"); $result = -1; } @@ -515,34 +476,28 @@ /** * Get object from database * - * @param int $id Id of object to load - * @param string $ref Ref of project - * @param string $ref_ext Ref ext of project - * @param string $email_msgid Email msgid - * @return int >0 if OK, 0 if not found, <0 if KO - */ - public function fetch($id, $ref = '', $ref_ext = '', $email_msgid = '') + * @param int $id Id of object to load + * @param string $ref Ref of project + * @return int >0 if OK, 0 if not found, <0 if KO + */ + public function fetch($id, $ref = '') { global $conf; if (empty($id) && empty($ref)) return -1; - $sql = "SELECT rowid, entity, ref, title, description, public, datec, opp_amount, budget_amount,"; + $sql = "SELECT rowid, ref, title, description, public, datec, opp_amount, budget_amount,"; $sql .= " tms, dateo, datee, date_close, fk_soc, fk_user_creat, fk_user_modif, fk_user_close, fk_statut as status, fk_opp_status, opp_percent,"; - $sql .= " note_private, note_public, model_pdf, usage_opportunity, usage_task, usage_bill_time, usage_organize_event, email_msgid"; + $sql .= " note_private, note_public, model_pdf, usage_opportunity, usage_task, usage_bill_time, usage_organize_event, entity"; $sql .= " FROM ".MAIN_DB_PREFIX."projet"; if (!empty($id)) { - $sql .= " WHERE rowid = ".$id; - } else { - $sql .= " WHERE entity IN (".getEntity('project').")"; - if (!empty($ref)) { - $sql .= " AND ref = '".$this->db->escape($ref)."'"; - } elseif (!empty($ref_ext)) { - $sql .= " AND ref_ext = '".$this->db->escape($ref_ext)."'"; - } else { - $sql .= " AND email_msgid = '".$this->db->escape($email_msgid)."'"; - } + $sql .= " WHERE rowid=".$id; + } + elseif (!empty($ref)) + { + $sql .= " WHERE ref='".$this->db->escape($ref)."'"; + $sql .= " AND entity IN (".getEntity('project').")"; } dol_syslog(get_class($this)."::fetch", LOG_DEBUG); @@ -556,7 +511,6 @@ $obj = $this->db->fetch_object($resql); $this->id = $obj->rowid; - $this->entity = $obj->entity; $this->ref = $obj->ref; $this->title = $obj->title; $this->description = $obj->description; @@ -580,17 +534,16 @@ $this->opp_amount = $obj->opp_amount; $this->opp_percent = $obj->opp_percent; $this->budget_amount = $obj->budget_amount; - $this->model_pdf = $obj->model_pdf; - $this->modelpdf = $obj->model_pdf; // deprecated + $this->modelpdf = $obj->model_pdf; $this->usage_opportunity = (int) $obj->usage_opportunity; $this->usage_task = (int) $obj->usage_task; $this->usage_bill_time = (int) $obj->usage_bill_time; $this->usage_organize_event = (int) $obj->usage_organize_event; - $this->email_msgid = $obj->email_msgid; + $this->entity = $obj->entity; $this->db->free($resql); - // Retrieve all extrafield + // Retreive all extrafield // fetch optionals attributes and labels $this->fetch_optionals(); @@ -600,7 +553,9 @@ $this->db->free($resql); return 0; - } else { + } + else + { $this->error = $this->db->lasterror(); return -1; } @@ -621,9 +576,6 @@ public function get_element_list($type, $tablename, $datefieldname = '', $dates = '', $datee = '', $projectkey = 'fk_projet') { // phpcs:enable - - global $hookmanager; - $elements = array(); if ($this->id <= 0) return $elements; @@ -633,56 +585,51 @@ if ($type == 'agenda') { $sql = "SELECT id as rowid FROM ".MAIN_DB_PREFIX."actioncomm WHERE fk_project IN (".$ids.") AND entity IN (".getEntity('agenda').")"; - } elseif ($type == 'expensereport') + } + elseif ($type == 'expensereport') { $sql = "SELECT ed.rowid FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".getEntity('expensereport').") AND ed.fk_projet IN (".$ids.")"; - } elseif ($type == 'project_task') + } + elseif ($type == 'project_task') { $sql = "SELECT DISTINCT pt.rowid FROM ".MAIN_DB_PREFIX."projet_task as pt WHERE pt.fk_projet IN (".$ids.")"; - } elseif ($type == 'project_task_time') // Case we want to duplicate line foreach user + } + elseif ($type == 'project_task_time') // Case we want to duplicate line foreach user { $sql = "SELECT DISTINCT pt.rowid, ptt.fk_user FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet IN (".$ids.")"; - } elseif ($type == 'stock_mouvement') + } + elseif ($type == 'stock_mouvement') { $sql = 'SELECT ms.rowid, ms.fk_user_author as fk_user FROM '.MAIN_DB_PREFIX."stock_mouvement as ms, ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".getEntity('stock').") AND ms.origintype = 'project' AND ms.fk_origin IN (".$ids.") AND ms.type_mouvement = 1"; - } elseif ($type == 'loan') + } + elseif ($type == 'loan') { $sql = 'SELECT l.rowid, l.fk_user_author as fk_user FROM '.MAIN_DB_PREFIX."loan as l WHERE l.entity IN (".getEntity('loan').") AND l.fk_projet IN (".$ids.")"; - } else { + } + else + { $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$tablename." WHERE ".$projectkey." IN (".$ids.") AND entity IN (".getEntity($type).")"; } - if ($dates > 0 && $type == 'loan') { + if($dates > 0 && $type == 'loan'){ $sql .= " AND (dateend > '".$this->db->idate($dates)."' OR dateend IS NULL)"; - } elseif ($dates > 0 && ($type != 'project_task')) // For table project_taks, we want the filter on date apply on project_time_spent table + } + elseif ($dates > 0 && ($type != 'project_task')) // For table project_taks, we want the filter on date apply on project_time_spent table { if (empty($datefieldname) && !empty($this->table_element_date)) $datefieldname = $this->table_element_date; if (empty($datefieldname)) return 'Error this object has no date field defined'; $sql .= " AND (".$datefieldname." >= '".$this->db->idate($dates)."' OR ".$datefieldname." IS NULL)"; } - if ($datee > 0 && $type == 'loan') { + if($datee > 0 && $type == 'loan'){ $sql .= " AND (datestart < '".$this->db->idate($datee)."' OR datestart IS NULL)"; - } elseif ($datee > 0 && ($type != 'project_task')) // For table project_taks, we want the filter on date apply on project_time_spent table + } + elseif ($datee > 0 && ($type != 'project_task')) // For table project_taks, we want the filter on date apply on project_time_spent table { if (empty($datefieldname) && !empty($this->table_element_date)) $datefieldname = $this->table_element_date; if (empty($datefieldname)) return 'Error this object has no date field defined'; $sql .= " AND (".$datefieldname." <= '".$this->db->idate($datee)."' OR ".$datefieldname." IS NULL)"; } - - $parameters = array( - 'sql'=>$sql, - 'type' => $type, - 'tablename' => $tablename, - 'datefieldname' => $datefieldname, - 'dates' => $dates, - 'datee' => $datee, - 'fk_projet' => $projectkey - ); - $reshook = $hookmanager->executeHooks('getElementList', $parameters, $object, $action); - if ($reshook > 0) $sql = $hookmanager->resPrint; - else $sql .= $hookmanager->resPrint; - if (!$sql) return -1; //print $sql; @@ -707,7 +654,9 @@ /* Return array even if empty*/ return $elements; - } else { + } + else + { dol_print_error($this->db); } } @@ -857,7 +806,9 @@ { $this->db->commit(); return 1; - } else { + } + else + { foreach ($this->errors as $errmsg) { dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR); @@ -867,45 +818,6 @@ $this->db->rollback(); return -1; } - } - - /** - * Return the count of a type of linked elements of this project - * - * @param string $type The type of the linked elements (e.g. 'propal', 'order', 'invoice', 'order_supplier', 'invoice_supplier') - * @param string $tablename The name of table associated of the type - * @param string $projectkey (optional) Equivalent key to fk_projet for actual type - * @return integer The count of the linked elements (the count is zero on request error too) - */ - public function getElementCount($type, $tablename, $projectkey = 'fk_projet') - { - if ($this->id <= 0) return 0; - - if ($type == 'agenda') { - $sql = "SELECT COUNT(id) as nb FROM ".MAIN_DB_PREFIX."actioncomm WHERE fk_project = ".$this->id." AND entity IN (".getEntity('agenda').")"; - } elseif ($type == 'expensereport') { - $sql = "SELECT COUNT(ed.rowid) as nb FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."expensereport_det as ed WHERE e.rowid = ed.fk_expensereport AND e.entity IN (".getEntity('expensereport').") AND ed.fk_projet = ".$this->id; - } elseif ($type == 'project_task') { - $sql = "SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX."projet_task as pt WHERE pt.fk_projet = ".$this->id; - } elseif ($type == 'project_task_time') { // Case we want to duplicate line foreach user - $sql = "SELECT DISTINCT COUNT(pt.rowid) as nb FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet_task_time as ptt WHERE pt.rowid = ptt.fk_task AND pt.fk_projet = ".$this->id; - } elseif ($type == 'stock_mouvement') { - $sql = 'SELECT COUNT(ms.rowid) as nb FROM '.MAIN_DB_PREFIX."stock_mouvement as ms, ".MAIN_DB_PREFIX."entrepot as e WHERE e.rowid = ms.fk_entrepot AND e.entity IN (".getEntity('stock').") AND ms.origintype = 'project' AND ms.fk_origin = ".$this->id." AND ms.type_mouvement = 1"; - } elseif ($type == 'loan') { - $sql = 'SELECT COUNT(l.rowid) as nb FROM '.MAIN_DB_PREFIX."loan as l WHERE l.entity IN (".getEntity('loan').") AND l.fk_projet = ".$this->id; - } else { - $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX.$tablename." WHERE ".$projectkey." = ".$this->id." AND entity IN (".getEntity($type).")"; - } - - $result = $this->db->query($sql); - - if (!$result) return 0; - - $obj = $this->db->fetch_object($result); - - $this->db->free($result); - - return $obj->nb; } /** @@ -988,13 +900,17 @@ $this->statut = 1; $this->db->commit(); return 1; - } else { + } + else + { $this->db->rollback(); $this->error = join(',', $this->errors); dol_syslog(get_class($this)."::setValid ".$this->error, LOG_ERR); return -1; } - } else { + } + else + { $this->db->rollback(); $this->error = $this->db->lasterror(); return -1; @@ -1044,13 +960,17 @@ $this->statut = 2; $this->db->commit(); return 1; - } else { + } + else + { $this->db->rollback(); $this->error = join(',', $this->errors); dol_syslog(get_class($this)."::setClose ".$this->error, LOG_ERR); return -1; } - } else { + } + else + { $this->db->rollback(); $this->error = $this->db->lasterror(); return -1; @@ -1118,15 +1038,12 @@ if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips $result = ''; - if (!empty($conf->global->PROJECT_OPEN_ALWAYS_ON_TAB)) { + if (! empty($conf->global->PROJECT_OPEN_ALWAYS_ON_TAB)) { $option = $conf->global->PROJECT_OPEN_ALWAYS_ON_TAB; } $label = ''; - if ($option != 'nolink') $label = img_picto('', $this->picto).' '.$langs->trans("Project").''; - if (isset($this->status)) { - $label .= ' '.$this->getLibStatut(5); - } + if ($option != 'nolink') $label = ''.$langs->trans("Project").''; $label .= ($label ? '
' : '').''.$langs->trans('Ref').': '.$this->ref; // The space must be after the : to not being explode when showing the title in img_picto $label .= ($label ? '
' : '').''.$langs->trans('Label').': '.$this->title; // The space must be after the : to not being explode when showing the title in img_picto if (isset($this->public)) { @@ -1142,19 +1059,26 @@ $label .= ($label ? '
' : '').''.$langs->trans('DateEnd').': '.dol_print_date($this->datee, 'day'); // The space must be after the : to not being explode when showing the title in img_picto } if ($moreinpopup) $label .= '
'.$moreinpopup; + if (isset($this->status)) { + $label .= '
'.$langs->trans("Status").": ".$this->getLibStatut(5); + } $url = ''; if ($option != 'nolink') { if (preg_match('/\.php$/', $option)) { $url = dol_buildpath($option, 1).'?id='.$this->id; - } elseif ($option == 'task') + } + elseif ($option == 'task') { $url = DOL_URL_ROOT.'/projet/tasks.php?id='.$this->id; - } elseif ($option == 'preview') + } + elseif ($option == 'preview') { $url = DOL_URL_ROOT.'/projet/element.php?id='.$this->id; - } else { + } + else + { $url = DOL_URL_ROOT.'/projet/card.php?id='.$this->id; } // Add param to save lastsearch_values or not @@ -1254,17 +1178,20 @@ * @param string $mode Type of permission we want to know: 'read', 'write' * @return int >0 if user has permission, <0 if user has no permission */ - public function restrictedProjectArea(User $user, $mode = 'read') + public function restrictedProjectArea($user, $mode = 'read') { // To verify role of users $userAccess = 0; if (($mode == 'read' && !empty($user->rights->projet->all->lire)) || ($mode == 'write' && !empty($user->rights->projet->all->creer)) || ($mode == 'delete' && !empty($user->rights->projet->all->supprimer))) { $userAccess = 1; - } elseif ($this->public && (($mode == 'read' && !empty($user->rights->projet->lire)) || ($mode == 'write' && !empty($user->rights->projet->creer)) || ($mode == 'delete' && !empty($user->rights->projet->supprimer)))) + } + elseif ($this->public && (($mode == 'read' && !empty($user->rights->projet->lire)) || ($mode == 'write' && !empty($user->rights->projet->creer)) || ($mode == 'delete' && !empty($user->rights->projet->supprimer)))) { $userAccess = 1; - } else { // No access due to permission to read all projects, so we check if we are a contact of project + } + else + { foreach (array('internal', 'external') as $source) { $userRole = $this->liste_contact(4, $source); @@ -1273,13 +1200,7 @@ $nblinks = 0; while ($nblinks < $num) { - if ($source == 'internal' && $user->id == $userRole[$nblinks]['id']) // $userRole[$nblinks]['id'] is id of user (llx_user) for internal contacts - { - if ($mode == 'read' && $user->rights->projet->lire) $userAccess++; - if ($mode == 'write' && $user->rights->projet->creer) $userAccess++; - if ($mode == 'delete' && $user->rights->projet->supprimer) $userAccess++; - } - if ($source == 'external' && $user->socid > 0 && $user->socid == $userRole[$nblinks]['socid']) // $userRole[$nblinks]['id'] is id of contact (llx_socpeople) or external contacts + if ($source == 'internal' && preg_match('/^PROJECT/', $userRole[$nblinks]['code']) && $user->id == $userRole[$nblinks]['id']) { if ($mode == 'read' && $user->rights->projet->lire) $userAccess++; if ($mode == 'write' && $user->rights->projet->creer) $userAccess++; @@ -1316,56 +1237,61 @@ $temp = array(); $sql = "SELECT ".(($mode == 0 || $mode == 1) ? "DISTINCT " : "")."p.rowid, p.ref"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; + $sql.= " FROM " . MAIN_DB_PREFIX . "projet as p"; if ($mode == 0) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."element_contact as ec ON ec.element_id = p.rowid"; - } elseif ($mode == 1) - { - $sql .= ", ".MAIN_DB_PREFIX."element_contact as ec"; - } elseif ($mode == 2) + $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "element_contact as ec ON ec.element_id = p.rowid"; + } + elseif ($mode == 1) + { + $sql.= ", " . MAIN_DB_PREFIX . "element_contact as ec"; + } + elseif ($mode == 2) { // No filter. Use this if user has permission to see all project } - $sql .= " WHERE p.entity IN (".getEntity('project').")"; + $sql.= " WHERE p.entity IN (".getEntity('project').")"; // Internal users must see project he is contact to even if project linked to a third party he can't see. //if ($socid || ! $user->rights->societe->client->voir) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; - if ($socid > 0) $sql .= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = ".$socid.")"; + if ($socid > 0) $sql.= " AND (p.fk_soc IS NULL OR p.fk_soc = 0 OR p.fk_soc = " . $socid . ")"; // Get id of types of contacts for projects (This list never contains a lot of elements) - $listofprojectcontacttype = array(); + $listofprojectcontacttype=array(); $sql2 = "SELECT ctc.rowid, ctc.code FROM ".MAIN_DB_PREFIX."c_type_contact as ctc"; - $sql2 .= " WHERE ctc.element = '".$this->db->escape($this->element)."'"; - $sql2 .= " AND ctc.source = 'internal'"; + $sql2.= " WHERE ctc.element = '" . $this->db->escape($this->element) . "'"; + $sql2.= " AND ctc.source = 'internal'"; $resql = $this->db->query($sql2); if ($resql) { - while ($obj = $this->db->fetch_object($resql)) - { - $listofprojectcontacttype[$obj->rowid] = $obj->code; - } - } else dol_print_error($this->db); - if (count($listofprojectcontacttype) == 0) $listofprojectcontacttype[0] = '0'; // To avoid syntax error if not found + while($obj = $this->db->fetch_object($resql)) + { + $listofprojectcontacttype[$obj->rowid]=$obj->code; + } + } + else dol_print_error($this->db); + if (count($listofprojectcontacttype) == 0) $listofprojectcontacttype[0]='0'; // To avoid syntax error if not found if ($mode == 0) { - $sql .= " AND ( p.public = 1"; - $sql .= " OR ( ec.fk_c_type_contact IN (".join(',', array_keys($listofprojectcontacttype)).")"; - $sql .= " AND ec.fk_socpeople = ".$user->id.")"; - $sql .= " )"; - } elseif ($mode == 1) - { - $sql .= " AND ec.element_id = p.rowid"; - $sql .= " AND ("; - $sql .= " ( ec.fk_c_type_contact IN (".join(',', array_keys($listofprojectcontacttype)).")"; - $sql .= " AND ec.fk_socpeople = ".$user->id.")"; - $sql .= " )"; - } elseif ($mode == 2) + $sql.= " AND ( p.public = 1"; + $sql.= " OR ( ec.fk_c_type_contact IN (".join(',', array_keys($listofprojectcontacttype)).")"; + $sql.= " AND ec.fk_socpeople = ".$user->id.")"; + $sql.= " )"; + } + elseif ($mode == 1) + { + $sql.= " AND ec.element_id = p.rowid"; + $sql.= " AND ("; + $sql.= " ( ec.fk_c_type_contact IN (".join(',', array_keys($listofprojectcontacttype)).")"; + $sql.= " AND ec.fk_socpeople = ".$user->id.")"; + $sql.= " )"; + } + elseif ($mode == 2) { // No filter. Use this if user has permission to see all project } - $sql .= $filter; + $sql.= $filter; //print $sql; $resql = $this->db->query($sql); @@ -1389,7 +1315,9 @@ $result = implode(',', $temp); return $result; } - } else { + } + else + { dol_print_error($this->db); } @@ -1496,26 +1424,32 @@ { $clone_project->note_private = ''; $clone_project->note_public = ''; - } else { + } + else + { $this->db->begin(); - $res = $clone_project->update_note(dol_html_entity_decode($clone_project->note_public, ENT_QUOTES | ENT_HTML5), '_public'); + $res = $clone_project->update_note(dol_html_entity_decode($clone_project->note_public, ENT_QUOTES), '_public'); if ($res < 0) { $this->error .= $clone_project->error; $error++; $this->db->rollback(); - } else { + } + else + { $this->db->commit(); } $this->db->begin(); - $res = $clone_project->update_note(dol_html_entity_decode($clone_project->note_private, ENT_QUOTES | ENT_HTML5), '_private'); + $res = $clone_project->update_note(dol_html_entity_decode($clone_project->note_private, ENT_QUOTES), '_private'); if ($res < 0) { $this->error .= $clone_project->error; $error++; $this->db->rollback(); - } else { + } + else + { $this->db->commit(); } } @@ -1538,7 +1472,9 @@ $langs->load("errors"); $this->error .= $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"); $error++; - } else { + } + else + { if ($clone_project->error != '') { $this->error .= $clone_project->error; @@ -1569,7 +1505,9 @@ $error++; } } - } else { + } + else + { $this->error .= $langs->trans('ErrorInternalErrorDetected').':dol_mkdir'; $error++; } @@ -1578,17 +1516,17 @@ //Duplicate task if ($clone_task) { - require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; + require_once DOL_DOCUMENT_ROOT . '/projet/class/task.class.php'; $taskstatic = new Task($this->db); // Security check - $socid = 0; + $socid=0; if ($user->socid > 0) $socid = $user->socid; - $tasksarray = $taskstatic->getTasksArray(0, 0, $fromid, $socid, 0); - - $tab_conv_child_parent = array(); + $tasksarray=$taskstatic->getTasksArray(0, 0, $fromid, $socid, 0); + + $tab_conv_child_parent=array(); // Loop on each task, to clone it foreach ($tasksarray as $tasktoclone) @@ -1598,7 +1536,9 @@ { $this->error .= $result_clone->error; $error++; - } else { + } + else + { $new_task_id = $result_clone; $taskstatic->fetch($tasktoclone->id); @@ -1636,7 +1576,9 @@ { $this->db->commit(); return $clone_project_id; - } else { + } + else + { $this->db->rollback(); dol_syslog(get_class($this)."::createFromClone nbError: ".$error." error : ".$this->error, LOG_ERR); return -1; @@ -1654,30 +1596,30 @@ { global $user, $langs, $conf; - $error = 0; + $error=0; $taskstatic = new Task($this->db); // Security check - $socid = 0; + $socid=0; if ($user->socid > 0) $socid = $user->socid; - $tasksarray = $taskstatic->getTasksArray(0, 0, $this->id, $socid, 0); + $tasksarray=$taskstatic->getTasksArray(0, 0, $this->id, $socid, 0); foreach ($tasksarray as $tasktoshiftdate) { - $to_update = false; + $to_update=false; // Fetch only if update of date will be made if ((!empty($tasktoshiftdate->date_start)) || (!empty($tasktoshiftdate->date_end))) { //dol_syslog(get_class($this)."::shiftTaskDate to_update", LOG_DEBUG); - $to_update = true; + $to_update=true; $task = new Task($this->db); $result = $task->fetch($tasktoshiftdate->id); if (!$result) { $error++; - $this->error .= $task->error; + $this->error.=$task->error; } } //print "$this->date_start + $tasktoshiftdate->date_start - $old_project_dt_start";exit; @@ -1729,7 +1671,9 @@ { $sql .= " SET fk_project=".$this->id; $sql .= " WHERE id=".$elementSelectId; - } else { + } + else + { $sql .= " SET fk_projet=".$this->id; $sql .= " WHERE rowid=".$elementSelectId; } @@ -1763,7 +1707,8 @@ { $sql .= " SET fk_project=NULL"; $sql .= " WHERE id=".$elementSelectId; - } else { + } else + { $sql .= " SET ".$projectfield."=NULL"; $sql .= " WHERE rowid=".$elementSelectId; } @@ -1790,16 +1735,16 @@ */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) { - global $conf, $langs; + global $conf,$langs; $langs->load("projects"); - if (!dol_strlen($modele)) { + if (! dol_strlen($modele)) { $modele = 'baleine'; - if ($this->model_pdf) { - $modele = $this->model_pdf; - } elseif (!empty($conf->global->PROJECT_ADDON_PDF)) { + if ($this->modelpdf) { + $modele = $this->modelpdf; + } elseif (! empty($conf->global->PROJECT_ADDON_PDF)) { $modele = $conf->global->PROJECT_ADDON_PDF; } } @@ -1821,49 +1766,53 @@ */ public function loadTimeSpent($datestart, $taskid = 0, $userid = 0) { - $error = 0; - - $this->weekWorkLoad = array(); - $this->weekWorkLoadPerTask = array(); + $error=0; + + $this->weekWorkLoad=array(); + $this->weekWorkLoadPerTask=array(); if (empty($datestart)) dol_print_error('', 'Error datestart parameter is empty'); $sql = "SELECT ptt.rowid as taskid, ptt.task_duration, ptt.task_date, ptt.task_datehour, ptt.fk_task"; - $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; - $sql .= " WHERE ptt.fk_task = pt.rowid"; - $sql .= " AND pt.fk_projet = ".$this->id; - $sql .= " AND (ptt.task_date >= '".$this->db->idate($datestart)."' "; - $sql .= " AND ptt.task_date <= '".$this->db->idate(dol_time_plus_duree($datestart, 1, 'w') - 1)."')"; - if ($taskid) $sql .= " AND ptt.fk_task=".$taskid; - if (is_numeric($userid)) $sql .= " AND ptt.fk_user=".$userid; + $sql.= " FROM ".MAIN_DB_PREFIX."projet_task_time AS ptt, ".MAIN_DB_PREFIX."projet_task as pt"; + $sql.= " WHERE ptt.fk_task = pt.rowid"; + $sql.= " AND pt.fk_projet = ".$this->id; + $sql.= " AND (ptt.task_date >= '".$this->db->idate($datestart)."' "; + $sql.= " AND ptt.task_date <= '".$this->db->idate(dol_time_plus_duree($datestart, 1, 'w') - 1)."')"; + if ($taskid) $sql.= " AND ptt.fk_task=".$taskid; + if (is_numeric($userid)) $sql.= " AND ptt.fk_user=".$userid; //print $sql; - $resql = $this->db->query($sql); + $resql=$this->db->query($sql); if ($resql) { - $daylareadyfound = array(); + $daylareadyfound=array(); $num = $this->db->num_rows($resql); $i = 0; // Loop on each record found, so each couple (project id, task id) while ($i < $num) { - $obj = $this->db->fetch_object($resql); - $day = $this->db->jdate($obj->task_date); // task_date is date without hours + $obj=$this->db->fetch_object($resql); + $day=$this->db->jdate($obj->task_date); // task_date is date without hours if (empty($daylareadyfound[$day])) { $this->weekWorkLoad[$day] = $obj->task_duration; $this->weekWorkLoadPerTask[$day][$obj->fk_task] = $obj->task_duration; - } else { + } + else + { $this->weekWorkLoad[$day] += $obj->task_duration; $this->weekWorkLoadPerTask[$day][$obj->fk_task] += $obj->task_duration; } - $daylareadyfound[$day] = 1; + $daylareadyfound[$day]=1; $i++; } $this->db->free($resql); return 1; - } else { + } + else + { $this->error = "Error ".$this->db->lasterror(); dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR); return -1; @@ -1917,7 +1866,9 @@ { $this->monthWorkLoad[$week_number] = $obj->task_duration; $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] = $obj->task_duration; - } else { + } + else + { $this->monthWorkLoad[$week_number] += $obj->task_duration; $this->monthWorkLoadPerTask[$week_number][$obj->fk_task] += $obj->task_duration; } @@ -1926,7 +1877,9 @@ } $this->db->free($resql); return 1; - } else { + } + else + { $this->error = "Error ".$this->db->lasterror(); dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR); return -1; @@ -1995,7 +1948,9 @@ } return $response; - } else { + } + else + { $this->error = $this->db->error(); return -1; } @@ -2052,7 +2007,9 @@ } $this->db->free($resql); return 1; - } else { + } + else + { dol_print_error($this->db); $this->error = $this->db->error(); return -1; @@ -2118,7 +2075,9 @@ } $this->db->free($result); - } else { + } + else + { dol_print_error($this->db); } } --- /tmp/dsg/dolibarr/htdocs/projet/class/github_projectstats.class.php +++ /tmp/dsg/dolibarr/htdocs/projet/class/client_projectstats.class.php @@ -24,25 +24,25 @@ */ class ProjectStats extends Stats { - private $project; - public $userid; - public $socid; - public $year; - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ - public function __construct($db) - { - global $conf, $user; - - $this->db = $db; - - require_once 'project.class.php'; - $this->project = new Project($this->db); - } + private $project; + public $userid; + public $socid; + public $year; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + public function __construct($db) + { + global $conf, $user; + + $this->db = $db; + + require_once 'project.class.php'; + $this->project = new Project($this->db); + } /** @@ -92,7 +92,9 @@ $label.' ('.price(price2num($row[0], 'MT'), 1, $langs, 1, -1, -1, $conf->currency).')', $row[0] ); - } else $other += $row[1]; + } + else + $other += $row[1]; $i++; } if ($num > $limit) @@ -279,7 +281,9 @@ $foundintocache = 1; $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $filedate; - } else { + } + else + { dol_syslog(get_class($this).'::'.__FUNCTION__." cache file ".$newpathofdestfile." is not found or older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we can't use it."); } } @@ -289,7 +293,9 @@ { dol_syslog(get_class($this).'::'.__FUNCTION__." read data from cache file ".$newpathofdestfile." ".$filedate."."); $data = json_decode(file_get_contents($newpathofdestfile), true); - } else { + } + else + { $year = $startyear; while ($year <= $endyear) { @@ -323,7 +329,8 @@ fclose($fp); if (!empty($conf->global->MAIN_UMASK)) $newmask = $conf->global->MAIN_UMASK; @chmod($newpathofdestfile, octdec($newmask)); - } else dol_syslog("Failed to write cache file", LOG_ERR); + } + else dol_syslog("Failed to write cache file", LOG_ERR); $this->lastfetchdate[get_class($this).'_'.__FUNCTION__] = $nowgmt; } --- /tmp/dsg/dolibarr/htdocs/projet/class/github_task.class.php +++ /tmp/dsg/dolibarr/htdocs/projet/class/client_task.class.php @@ -45,14 +45,14 @@ public $table_element = 'projet_task'; /** - * @var string Field with ID of parent key if this field has a parent + * @var int Field with ID of parent key if this field has a parent */ public $fk_element = 'fk_task'; /** - * @var string String with name of icon for myobject. - */ - public $picto = 'projecttask'; + * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png + */ + public $picto = 'task'; /** * @var array List of child tables. To test if we can delete object. @@ -60,14 +60,14 @@ protected $childtables = array('projet_task_time'); /** - * @var int ID parent task - */ - public $fk_task_parent = 0; - - /** - * @var string Label of task - */ - public $label; + * @var int ID parent task + */ + public $fk_task_parent; + + /** + * @var string Label of task + */ + public $label; /** * @var string description @@ -82,20 +82,20 @@ public $progress; /** - * @var int ID - */ + * @var int ID + */ public $fk_statut; public $priority; /** - * @var int ID - */ + * @var int ID + */ public $fk_user_creat; /** - * @var int ID - */ + * @var int ID + */ public $fk_user_valid; public $rang; @@ -144,9 +144,6 @@ public function create($user, $notrigger = 0) { global $conf, $langs; - - //For the date - $now = dol_now(); $error = 0; @@ -178,7 +175,7 @@ $sql .= ", ".$this->fk_task_parent; $sql .= ", '".$this->db->escape($this->label)."'"; $sql .= ", '".$this->db->escape($this->description)."'"; - $sql .= ", '".$this->db->idate($now)."'"; + $sql .= ", '".$this->db->idate($this->date_c)."'"; $sql .= ", ".$user->id; $sql .= ", ".($this->date_start != '' ? "'".$this->db->idate($this->date_start)."'" : 'null'); $sql .= ", ".($this->date_end != '' ? "'".$this->db->idate($this->date_end)."'" : 'null'); @@ -228,7 +225,9 @@ } $this->db->rollback(); return -1 * $error; - } else { + } + else + { $this->db->commit(); return $this->id; } @@ -317,7 +316,7 @@ $this->task_parent_position = $obj->task_parent_position; } - // Retrieve all extrafield + // Retreive all extrafield $this->fetch_optionals(); } @@ -329,7 +328,9 @@ } else { return 0; } - } else { + } + else + { $this->error = "Error ".$this->db->lasterror(); return -1; } @@ -438,7 +439,9 @@ } $this->db->rollback(); return -1 * $error; - } else { + } + else + { $this->db->commit(); return 1; } @@ -540,7 +543,9 @@ } $this->db->rollback(); return -1 * $error; - } else { + } + else + { //Delete associated link file if ($conf->projet->dir_output) { @@ -584,7 +589,9 @@ dol_syslog(get_class($this)."::hasChildren", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } else { + if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } + else + { $obj = $this->db->fetch_object($resql); if ($obj) $ret = $obj->nb; $this->db->free($resql); @@ -593,7 +600,9 @@ if (!$error) { return $ret; - } else { + } + else + { return -1; } } @@ -614,7 +623,9 @@ dol_syslog(get_class($this)."::hasTimeSpent", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } else { + if (!$resql) { $error++; $this->errors[] = "Error ".$this->db->lasterror(); } + else + { $obj = $this->db->fetch_object($resql); if ($obj) $ret = $obj->nb; $this->db->free($resql); @@ -623,7 +634,9 @@ if (!$error) { return $ret; - } else { + } + else + { return -1; } } @@ -648,7 +661,7 @@ if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips $result = ''; - $label = img_picto('', $this->picto).' '.$langs->trans("Task").''; + $label = ''.$langs->trans("ShowTask").''; if (!empty($this->ref)) $label .= '
'.$langs->trans('Ref').': '.$this->ref; if (!empty($this->label)) @@ -673,9 +686,7 @@ $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; - $linkclose .= ' class="classfortooltip nowraponall"'; - } else { - $linkclose .= ' class="nowraponall"'; + $linkclose .= ' class="classfortooltip"'; } $linkstart = ' 0) { $sql .= ", ".MAIN_DB_PREFIX."element_contact as ec2"; $sql .= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; } - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)"; - $sql .= " WHERE p.entity IN (".getEntity('project').")"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)"; + $sql .= " WHERE p.entity IN (".getEntity('project').")"; $sql .= " AND t.fk_projet = p.rowid"; - } elseif ($mode == 1) + } + elseif ($mode == 1) { if ($filteronprojuser > 0) { @@ -800,20 +812,23 @@ $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; if ($includebilltime) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; } $sql .= ", ".MAIN_DB_PREFIX."element_contact as ec2"; $sql .= ", ".MAIN_DB_PREFIX."c_type_contact as ctc2"; - } else { + } + else + { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task as t on t.fk_projet = p.rowid"; if ($includebilltime) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_time as tt ON tt.fk_task = t.rowid"; } } - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)"; - $sql .= " WHERE p.entity IN (".getEntity('project').")"; - } else return 'BadValueForParameterMode'; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_task_extrafields as efpt ON (t.rowid = efpt.fk_object)"; + $sql .= " WHERE p.entity IN (".getEntity('project').")"; + } + else return 'BadValueForParameterMode'; if ($filteronprojuser > 0) { @@ -849,12 +864,12 @@ $sql .= $hookmanager->resPrint; if ($includebilltime) { - $sql .= " GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.usage_bill_time,"; - $sql .= " t.datec, t.dateo, t.datee, t.tms,"; - $sql .= " t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,"; - $sql .= " t.dateo, t.datee, t.planned_workload, t.rang,"; - $sql .= " t.description, "; - $sql .= " s.rowid, s.nom, s.email,"; + $sql .= " GROUP BY p.rowid, p.ref, p.title, p.public, p.fk_statut, p.usage_bill_time,"; + $sql .= " t.datec, t.dateo, t.datee, t.tms,"; + $sql .= " t.rowid, t.ref, t.label, t.description, t.fk_task_parent, t.duration_effective, t.progress, t.fk_statut,"; + $sql .= " t.dateo, t.datee, t.planned_workload, t.rang,"; + $sql .= " t.description, "; + $sql .= " s.rowid, s.nom, s.email,"; $sql .= " p.fk_opp_status, p.opp_amount, p.opp_percent, p.budget_amount"; if (!empty($extrafields->attributes['projet']['label'])) { @@ -907,13 +922,7 @@ $tasks[$i]->projectref = $obj->ref; $tasks[$i]->projectlabel = $obj->plabel; $tasks[$i]->projectstatus = $obj->projectstatus; - - $tasks[$i]->fk_opp_status = $obj->fk_opp_status; - $tasks[$i]->opp_amount = $obj->opp_amount; - $tasks[$i]->opp_percent = $obj->opp_percent; - $tasks[$i]->budget_amount = $obj->budget_amount; $tasks[$i]->usage_bill_time = $obj->usage_bill_time; - $tasks[$i]->label = $obj->label; $tasks[$i]->description = $obj->description; $tasks[$i]->fk_parent = $obj->fk_task_parent; // deprecated @@ -921,10 +930,8 @@ $tasks[$i]->duration = $obj->duration_effective; $tasks[$i]->planned_workload = $obj->planned_workload; - if ($includebilltime) { - $tasks[$i]->tobill = $obj->tobill; - $tasks[$i]->billed = $obj->billed; - } + $tasks[$i]->tobill = $obj->tobill; + $tasks[$i]->billed = $obj->billed; $tasks[$i]->progress = $obj->progress; $tasks[$i]->fk_statut = $obj->status; @@ -938,29 +945,38 @@ $tasks[$i]->thirdparty_name = $obj->thirdparty_name; $tasks[$i]->thirdparty_email = $obj->thirdparty_email; - if (!empty($extrafields->attributes['projet']['label'])) - { - foreach ($extrafields->attributes['projet']['label'] as $key => $val) - { - if ($extrafields->attributes['projet']['type'][$key] != 'separate') - $tasks[$i]->{'options_'.$key} = $obj->{'options_'.$key}; - } - } - - if (!empty($extrafields->attributes['projet_task']['label'])) - { - foreach ($extrafields->attributes['projet_task']['label'] as $key => $val) - { - if ($extrafields->attributes['projet_task']['type'][$key] != 'separate') - $tasks[$i]->{'options_'.$key} = $obj->{'options_'.$key}; - } - } + + $tasks[$i]->fk_opp_status = $obj->fk_opp_status; + $tasks[$i]->opp_amount = $obj->opp_amount; + $tasks[$i]->opp_percent = $obj->opp_percent; + $tasks[$i]->budget_amount = $obj->budget_amount; + $tasks[$i]->usage_bill_time = $obj->usage_bill_time; + + if (!empty($extrafields->attributes['projet']['label'])) + { + foreach ($extrafields->attributes['projet']['label'] as $key => $val) + { + if ($extrafields->attributes['projet']['type'][$key] != 'separate') + $tasks[$i]->{'options_'.$key} = $obj->{'options_'.$key}; + } + } + + if (!empty($extrafields->attributes['projet_task']['label'])) + { + foreach ($extrafields->attributes['projet_task']['label'] as $key => $val) + { + if ($extrafields->attributes['projet_task']['type'][$key] != 'separate') + $tasks[$i]->{'options_'.$key} = $obj->{'options_'.$key}; + } + } } $i++; } $this->db->free($resql); - } else { + } + else + { dol_print_error($this->db); } @@ -1038,7 +1054,9 @@ $i++; } $this->db->free($resql); - } else { + } + else + { dol_print_error($this->db); } @@ -1062,7 +1080,7 @@ while ($i < $num) { if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid']; - else $contactAlreadySelected[$i] = $tab[$i]['id']; + else $contactAlreadySelected[$i] = $tab[$i]['id']; $i++; } return $contactAlreadySelected; @@ -1129,7 +1147,9 @@ if ($result < 0) { $ret = -1; } // End call triggers } - } else { + } + else + { $this->error = $this->db->lasterror(); $ret = -1; } @@ -1164,7 +1184,9 @@ if ($ret > 0) { $this->db->commit(); - } else { + } + else + { $this->db->rollback(); } return $ret; @@ -1224,7 +1246,9 @@ $this->timespent_nblines = ($obj->nblines ? $obj->nblines : 0); $this->db->free($resql); - } else { + } + else + { dol_print_error($this->db); } return $result; @@ -1279,7 +1303,9 @@ $this->db->free($resql); return $result; - } else { + } + else + { dol_print_error($this->db); return $result; } @@ -1330,7 +1356,9 @@ $this->db->free($resql); return 1; - } else { + } + else + { $this->error = "Error ".$this->db->lasterror(); return -1; } @@ -1415,7 +1443,9 @@ } $this->db->free($resql); - } else { + } + else + { dol_print_error($this->db); $this->error = "Error ".$this->db->lasterror(); return -1; @@ -1440,13 +1470,13 @@ // Check parameters if ($this->timespent_date == '') { - $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentities("Date")); - return -1; + $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentities("Date")); + return -1; } if (!($this->timespent_fk_user > 0)) { - $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentities("User")); - return -1; + $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentities("User")); + return -1; } // Clean parameters @@ -1475,10 +1505,14 @@ { $this->db->rollback(); $ret = -1; - } else $ret = 1; + } + else $ret = 1; // End call triggers - } else $ret = 1; - } else { + } + else $ret = 1; + } + else + { $this->error = $this->db->lasterror(); $this->db->rollback(); $ret = -1; @@ -1548,7 +1582,9 @@ if ($this->db->query($sql)) { $result = 0; - } else { + } + else + { $this->error = $this->db->lasterror(); $result = -2; } @@ -1564,14 +1600,16 @@ } $this->db->rollback(); return -1 * $error; - } else { + } + else + { $this->db->commit(); return 1; } } - /** Load an object from its id and create a new one in database - * + /** Load an object from its id and create a new one in database + * * @param User $user User making the clone * @param int $fromid Id of object to clone * @param int $project_id Id of project to attach clone task @@ -1583,7 +1621,7 @@ * @param bool $clone_note clone note of project * @param bool $clone_prog clone progress of project * @return int New id of clone - */ + */ public function createFromClone(User $user, $fromid, $project_id, $parent_task_id, $clone_change_dt = false, $clone_affectation = false, $clone_time = false, $clone_file = false, $clone_note = false, $clone_prog = false) { global $langs, $conf; @@ -1676,26 +1714,32 @@ { $clone_task->note_private = ''; $clone_task->note_public = ''; - } else { + } + else + { $this->db->begin(); - $res = $clone_task->update_note(dol_html_entity_decode($clone_task->note_public, ENT_QUOTES | ENT_HTML5), '_public'); + $res = $clone_task->update_note(dol_html_entity_decode($clone_task->note_public, ENT_QUOTES), '_public'); if ($res < 0) { $this->error .= $clone_task->error; $error++; $this->db->rollback(); - } else { + } + else + { $this->db->commit(); } $this->db->begin(); - $res = $clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES | ENT_HTML5), '_private'); + $res = $clone_task->update_note(dol_html_entity_decode($clone_task->note_private, ENT_QUOTES), '_private'); if ($res < 0) { $this->error .= $clone_task->error; $error++; $this->db->rollback(); - } else { + } + else + { $this->db->commit(); } } @@ -1705,7 +1749,7 @@ { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - //retrieve project origin ref to know folder to copy + //retreive project origin ref to know folder to copy $projectstatic = new Project($this->db); $projectstatic->fetch($ori_project_id); $ori_project_ref = $projectstatic->ref; @@ -1714,7 +1758,9 @@ { $projectstatic->fetch($project_id); $clone_project_ref = $projectstatic->ref; - } else { + } + else + { $clone_project_ref = $ori_project_ref; } @@ -1761,7 +1807,9 @@ $langs->load("errors"); $this->error .= $langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"); $error++; - } else { + } + else + { if ($clone_task->error != '') { $this->error .= $clone_task->error; @@ -1785,7 +1833,9 @@ { $this->db->commit(); return $clone_task_id; - } else { + } + else + { $this->db->rollback(); dol_syslog(get_class($this)."::createFromClone nbError: ".$error." error : ".$this->error, LOG_ERR); return -1; @@ -1804,7 +1854,7 @@ return $this->LibStatut($this->fk_statut, $mode); } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Return status label for an object * @@ -1814,7 +1864,7 @@ */ public function LibStatut($status, $mode = 0) { - // phpcs:enable + // phpcs:enable global $langs; // list of Statut of the task @@ -1832,10 +1882,12 @@ if ($mode == 0) { return $langs->trans($this->statuts[$status]); - } elseif ($mode == 1) + } + elseif ($mode == 1) { return $langs->trans($this->statuts_short[$status]); - } elseif ($mode == 2) + } + elseif ($mode == 2) { if ($status == 0) return img_picto($langs->trans($this->statuts_short[$status]), 'statut0').' '.$langs->trans($this->statuts_short[$status]); elseif ($status == 1) return img_picto($langs->trans($this->statuts_short[$status]), 'statut1').' '.$langs->trans($this->statuts_short[$status]); @@ -1843,7 +1895,8 @@ elseif ($status == 3) return img_picto($langs->trans($this->statuts_short[$status]), 'statut6').' '.$langs->trans($this->statuts_short[$status]); elseif ($status == 4) return img_picto($langs->trans($this->statuts_short[$status]), 'statut6').' '.$langs->trans($this->statuts_short[$status]); elseif ($status == 5) return img_picto($langs->trans($this->statuts_short[$status]), 'statut5').' '.$langs->trans($this->statuts_short[$status]); - } elseif ($mode == 3) + } + elseif ($mode == 3) { if ($status == 0) return img_picto($langs->trans($this->statuts_short[$status]), 'statut0'); elseif ($status == 1) return img_picto($langs->trans($this->statuts_short[$status]), 'statut1'); @@ -1851,7 +1904,8 @@ elseif ($status == 3) return img_picto($langs->trans($this->statuts_short[$status]), 'statut6'); elseif ($status == 4) return img_picto($langs->trans($this->statuts_short[$status]), 'statut6'); elseif ($status == 5) return img_picto($langs->trans($this->statuts_short[$status]), 'statut5'); - } elseif ($mode == 4) + } + elseif ($mode == 4) { if ($status == 0) return img_picto($langs->trans($this->statuts_short[$status]), 'statut0').' '.$langs->trans($this->statuts[$status]); elseif ($status == 1) return img_picto($langs->trans($this->statuts_short[$status]), 'statut1').' '.$langs->trans($this->statuts[$status]); @@ -1859,7 +1913,8 @@ elseif ($status == 3) return img_picto($langs->trans($this->statuts_short[$status]), 'statut6').' '.$langs->trans($this->statuts[$status]); elseif ($status == 4) return img_picto($langs->trans($this->statuts_short[$status]), 'statut6').' '.$langs->trans($this->statuts[$status]); elseif ($status == 5) return img_picto($langs->trans($this->statuts_short[$status]), 'statut5').' '.$langs->trans($this->statuts[$status]); - } elseif ($mode == 5) + } + elseif ($mode == 5) { /*if ($status==0) return $langs->trans($this->statuts_short[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut0'); elseif ($status==1) return $langs->trans($this->statuts_short[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut1'); @@ -1870,7 +1925,8 @@ */ //else return $this->progress.' %'; return ' '; - } elseif ($mode == 6) + } + elseif ($mode == 6) { /*if ($status==0) return $langs->trans($this->statuts[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut0'); elseif ($status==1) return $langs->trans($this->statuts[$status]).' '.img_picto($langs->trans($this->statuts_short[$status]),'statut1'); @@ -1896,16 +1952,14 @@ */ public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0) { - global $conf; - - $outputlangs->load("projects"); + global $conf, $langs; + + $langs->load("projects"); if (!dol_strlen($modele)) { $modele = 'nodefault'; - if (!empty($this->model_pdf)) { - $modele = $this->model_pdf; - } elseif (!empty($this->modelpdf)) { // deprecated + if ($this->modelpdf) { $modele = $this->modelpdf; } elseif (!empty($conf->global->PROJECT_TASK_ADDON_PDF)) { $modele = $conf->global->PROJECT_TASK_ADDON_PDF; @@ -1918,7 +1972,7 @@ } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Load indicators for dashboard (this->nbtodo and this->nbtodolate) * @@ -1927,7 +1981,7 @@ */ public function load_board($user) { - // phpcs:enable + // phpcs:enable global $conf, $langs; // For external user, no check is done on company because readability is managed by public status of project and assignement. @@ -1984,14 +2038,16 @@ } return $response; - } else { + } + else + { $this->error = $this->db->error(); return -1; } } - // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps + // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** * Charge indicateurs this->nb de tableau de bord * @@ -1999,7 +2055,7 @@ */ public function load_state_board() { - // phpcs:enable + // phpcs:enable global $user; $mine = 0; $socid = $user->socid; @@ -2031,7 +2087,9 @@ } $this->db->free($resql); return 1; - } else { + } + else + { dol_print_error($this->db); $this->error = $this->db->error(); return -1; --- /tmp/dsg/dolibarr/htdocs/projet/class/github_taskstats.class.php +++ /tmp/dsg/dolibarr/htdocs/projet/class/client_taskstats.class.php @@ -29,11 +29,11 @@ public $socid; public $year; - /** - * Constructor of the class - * - * @param DoliDb $db Database handler - */ + /** + * Constructor of the class + * + * @param DoliDb $db Database handler + */ public function __construct($db) { $this->db = $db; @@ -82,7 +82,9 @@ $row[1], $row[0] ); - } else $other += $row[1]; + } + else + $other += $row[1]; $i++; } if ($num > $limit) @@ -161,7 +163,7 @@ * Return Task number by month for a year * * @param int $year Year to scan - * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is month number, 2=Label of abscissa is first letter of month + * @param int $format 0=Label of abscissa is a translated text, 1=Label of abscissa is month number, 2=Label of abscissa is first letter of month * @return array Array of values */ public function getNbByMonth($year, $format = 0)