23use Luracast\Restler\RestException;
25require_once DOL_DOCUMENT_ROOT .
'/projet/class/project.class.php';
26require_once DOL_DOCUMENT_ROOT .
'/projet/class/task.class.php';
40 public static $FIELDS = array(
63 $this->project =
new Project($this->db);
64 $this->task =
new Task($this->db);
78 public function get(
$id)
80 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
81 throw new RestException(403);
84 $result = $this->project->fetch(
$id);
86 throw new RestException(404,
'Project with supplied id not found');
90 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
93 $this->project->fetchObjectLinked();
112 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
113 throw new RestException(403);
116 $result = $this->project->fetch(0, $ref);
118 throw new RestException(404,
'Project with supplied ref not found');
122 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
125 $this->project->fetchObjectLinked();
144 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
145 throw new RestException(403);
148 $result = $this->project->fetch(0,
'', $ref_ext);
150 throw new RestException(404,
'Project with supplied ref_ext not found');
154 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
157 $this->project->fetchObjectLinked();
176 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
177 throw new RestException(403);
180 $result = $this->project->fetch(0,
'',
'', $email_msgid);
182 throw new RestException(404,
'Project with supplied email_msgid not found');
186 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
189 $this->project->fetchObjectLinked();
212 public function index($sortfield =
"t.rowid", $sortorder =
'ASC', $limit = 100, $page = 0, $thirdparty_ids =
'', $category = 0, $sqlfilters =
'', $properties =
'', $pagination_data =
false)
214 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
215 throw new RestException(403);
221 $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids;
225 if (!DolibarrApiAccess::$user->hasRight(
'societe',
'client',
'voir') && !$socids) {
226 $search_sale = DolibarrApiAccess::$user->id;
229 $sql =
"SELECT t.rowid";
230 $sql .=
" FROM " . MAIN_DB_PREFIX .
"projet as t";
231 $sql .=
" LEFT JOIN " . MAIN_DB_PREFIX .
"societe AS s ON (s.rowid = t.fk_soc)";
232 $sql .=
" LEFT JOIN " . MAIN_DB_PREFIX .
"projet_extrafields AS ef ON ef.fk_object = t.rowid";
234 $sql .=
", " . MAIN_DB_PREFIX .
"categorie_project as c";
236 $sql .=
' WHERE t.entity IN (' .
getEntity(
'project') .
')';
238 $sql .=
" AND t.fk_soc IN (" . $this->db->sanitize($socids) .
")";
241 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'all',
'lire')) {
242 $projectsListId = $this->project->getProjectsAuthorizedForUser(DolibarrApiAccess::$user, 0, 1, 0);
243 $sql .=
" AND t.rowid IN (" . $this->db->sanitize($projectsListId) .
")";
246 if ($search_sale && $search_sale !=
'-1') {
247 if ($search_sale == -2) {
248 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM " . MAIN_DB_PREFIX .
"societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
249 } elseif ($search_sale > 0) {
250 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM " . MAIN_DB_PREFIX .
"societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = " . ((int) $search_sale) .
")";
255 $sql .=
" AND c.fk_categorie = " . ((int) $category) .
" AND c.fk_project = t.rowid ";
262 throw new RestException(400,
'Error when validating parameter sqlfilters -> ' . $errormessage);
267 $sqlTotals = str_replace(
'SELECT t.rowid',
'SELECT count(t.rowid) as total', $sql);
269 $sql .= $this->db->order($sortfield, $sortorder);
274 $offset = $limit * $page;
276 $sql .= $this->db->plimit($limit + 1, $offset);
280 $result = $this->db->query($sql);
283 $num = $this->db->num_rows($result);
284 $min = min($num, ($limit <= 0 ? $num : $limit));
287 $obj = $this->db->fetch_object($result);
288 $project_static =
new Project($this->db);
289 if ($project_static->fetch($obj->rowid)) {
295 throw new RestException(503,
'Error when retrieve project list : ' . $this->db->lasterror());
299 if ($pagination_data) {
300 $totalsResult = $this->db->query($sqlTotals);
301 $total = $this->db->fetch_object($totalsResult)->total;
306 $obj_ret[
'data'] = $tmp;
307 $obj_ret[
'pagination'] = [
308 'total' => (int) $total,
310 'page_count' => ceil((
int) $total / $limit),
327 public function post($request_data =
null)
330 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
331 throw new RestException(403,
"Insufficiant rights");
334 $result = $this->
_validate($request_data);
336 foreach ($request_data as $field => $value) {
337 if ($field ===
'caller') {
339 $this->project->context[
'caller'] =
sanitizeVal($request_data[
'caller'],
'aZ09');
343 $this->project->$field = $this->
_checkValForAPI($field, $value, $this->project);
354 if ($this->project->ref == -1 || $this->project->ref ===
'auto') {
362 $dirmodels = array_merge(array(
'/'), (array)
$conf->modules_parts[
'models']);
363 foreach ($dirmodels as $reldir) {
364 $file =
dol_buildpath($reldir .
"core/modules/project/" . $modele .
'.php', 0);
365 if (file_exists($file)) {
367 $classname = $modele;
371 if ($filefound && !empty($classname)) {
372 $result =
dol_include_once($reldir .
"core/modules/project/" . $modele .
'.php');
373 if ($result !==
false && class_exists($classname)) {
374 $modProject =
new $classname();
375 '@phan-var-force ModeleNumRefProjects $modProject';
376 $defaultref = $modProject->getNextValue(
null, $this->project);
378 dol_syslog(
"Failed to include module file or invalid classname: " . $reldir .
"core/modules/project/" . $modele .
'.php', LOG_ERR);
381 dol_syslog(
"Module file not found or classname is empty: " . $modele, LOG_ERR);
384 if (is_numeric($defaultref) && $defaultref <= 0) {
388 if (empty($defaultref)) {
392 $this->project->ref = $defaultref;
395 if ($this->project->create(DolibarrApiAccess::$user) < 0) {
396 throw new RestException(500,
"Error creating project", array_merge(array($this->project->error), $this->project->errors));
399 return $this->project->id;
421 public function addContact(
$id, $fk_socpeople, $type_contact, $source, $notrigger = 0)
423 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
424 throw new RestException(403);
427 $result = $this->project->fetch(
$id);
429 throw new RestException(404,
'project not found');
433 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
436 $result = $this->project->add_contact($fk_socpeople, $type_contact, $source, $notrigger);
438 throw new RestException(500,
'Error : ' . $this->project->error);
461 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
462 throw new RestException(403);
465 $result = $this->project->fetch(
$id);
468 throw new RestException(404,
'Project not found');
472 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
474 foreach (array(
'internal',
'external') as $source) {
475 $contacts = $this->project->liste_contact(-1, $source);
477 foreach ($contacts as $contact) {
478 if ($contact[
'id'] == $contactid && $contact[
'code'] == $type) {
479 $result = $this->project->delete_contact($contact[
'rowid']);
481 throw new RestException(500,
'Error when deleted the contact');
503 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
504 throw new RestException(403);
507 $result = $this->project->fetch(
$id);
509 throw new RestException(404,
'Project not found');
513 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
515 $this->project->getLinesArray(DolibarrApiAccess::$user);
517 foreach ($this->project->lines as $line) {
518 if ($includetimespent == 1) {
519 $timespent = $line->getSummaryOfTimeSpent(0);
521 if ($includetimespent == 2) {
522 $timespent = $line->fetchTimeSpentOnTask();
544 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
545 throw new RestException(403);
548 $result = $this->project->fetch(
$id);
550 throw new RestException(404,
'Project not found');
554 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
557 require_once DOL_DOCUMENT_ROOT .
'/projet/class/task.class.php';
558 $taskstatic =
new Task($this->db);
559 $userp = DolibarrApiAccess::$user;
561 $userp =
new User($this->db);
562 $userp->fetch($userid);
564 $this->project->roles = $taskstatic->getUserRolesForProjectsOrTasks($userp,
null, (
string)
$id, 0);
566 foreach ($this->project->roles as $line) {
721 public function put(
$id, $request_data =
null)
723 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
724 throw new RestException(403);
727 $result = $this->project->fetch(
$id);
729 throw new RestException(404,
'Project not found');
733 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
735 foreach ($request_data as $field => $value) {
736 if ($field ==
'id') {
739 if ($field ===
'caller') {
741 $this->project->context[
'caller'] =
sanitizeVal($request_data[
'caller'],
'aZ09');
744 if ($field ==
'array_options' && is_array($value)) {
745 foreach ($value as $index => $val) {
751 $this->project->$field = $this->
_checkValForAPI($field, $value, $this->project);
754 if ($this->project->update(DolibarrApiAccess::$user) >= 0) {
755 return $this->
get(
$id);
757 throw new RestException(500, $this->project->error);
771 public function delete(
$id)
773 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'supprimer')) {
774 throw new RestException(403);
776 $result = $this->project->fetch(
$id);
778 throw new RestException(404,
'Project not found');
782 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
785 if (!$this->project->delete(DolibarrApiAccess::$user)) {
786 throw new RestException(500,
'Error when delete project : ' . $this->project->error);
792 'message' =>
'Project deleted'
822 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
823 throw new RestException(403);
825 $result = $this->project->fetch(
$id);
827 throw new RestException(404,
'Project not found');
831 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
834 $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger);
836 throw new RestException(304,
'Error nothing done. May be object is already validated');
839 throw new RestException(500,
'Error when validating Project: ' . $this->project->error);
845 'message' =>
'Project validated'
868 public function listTimespent($sortfield =
"t.rowid", $sortorder =
'ASC', $limit = 100, $page = 0, $thirdparty_ids =
'', $category = 0, $sqlfilters =
'', $properties =
'', $pagination_data =
false)
870 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
871 throw new RestException(403);
875 $socids = DolibarrApiAccess::$user->socid ?: $thirdparty_ids;
879 if (!DolibarrApiAccess::$user->hasRight(
'societe',
'client',
'voir') && !$socids) {
880 $search_sale = DolibarrApiAccess::$user->id;
884 $canreadsalary = ((
isModEnabled(
'salaries') && DolibarrApiAccess::$user->hasRight(
'salaries',
'read')) || !
isModEnabled(
'salaries'));
886 $sql =
"SELECT et.rowid, et.element_duration, et.element_datehour, et.fk_user, et.note as time_note,";
887 if ($canreadsalary) {
890 $sql .=
" u.login as user_login, u.firstname as user_firstname, u.lastname as user_lastname,";
891 $sql .=
" p.rowid as project_id, p.ref as project_ref, p.title as project_title,";
892 $sql .=
" t.rowid as task_id, t.ref as task_ref, t.label as task_label,";
893 $sql .=
" s.rowid as soc_id, s.nom as soc_name";
894 $sql .=
" FROM ".MAIN_DB_PREFIX.
"projet as p";
895 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"projet_task as t ON (t.fk_projet = p.rowid)";
896 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"element_time as et ON (et.fk_element = t.rowid AND et.elementtype = 'task')";
897 $sql .=
" LEFT JOIN ".MAIN_DB_PREFIX.
"societe AS s ON (s.rowid = p.fk_soc)";
898 $sql .=
" INNER JOIN ".MAIN_DB_PREFIX.
"user AS u ON (u.rowid = et.fk_user)";
899 $sql .=
' WHERE t.entity IN ('.getEntity(
'project').
')';
901 $sql .=
" AND p.fk_soc IN (".$this->db->sanitize($socids).
")";
904 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'all',
'lire')) {
905 $projectsListId = $this->project->getProjectsAuthorizedForUser(DolibarrApiAccess::$user, 0, 1, 0);
906 $sql .=
" AND p.rowid IN (".$this->db->sanitize($projectsListId).
")";
910 if ($search_sale && $search_sale !=
'-1') {
911 if ($search_sale == -2) {
912 $sql .=
" AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
913 } elseif ($search_sale > 0) {
914 $sql .=
" AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX.
"societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = ".((int) $search_sale).
")";
919 $sql .=
" AND c.fk_categorie = ".((int) $category).
" AND c.fk_project = t.rowid ";
927 throw new RestException(400,
'Error when validating parameter sqlfilters -> '.$errormessage);
932 $sqlTotals = str_replace(
'SELECT t.rowid',
'SELECT count(t.rowid) as total', $sql);
934 $sql .= $this->db->order($sortfield, $sortorder);
939 $offset = $limit * $page;
941 $sql .= $this->db->plimit($limit + 1, $offset);
945 $result = $this->db->query($sql);
948 $num = $this->db->num_rows($result);
949 $min = min($num, ($limit <= 0 ? $num : $limit));
952 $obj = $this->db->fetch_object($result);
957 throw new RestException(503,
'Error when retrieve timestamp list : '.$this->db->lasterror());
962 if ($pagination_data) {
963 $totalsResult = $this->db->query($sqlTotals);
964 $total = $this->db->fetch_object($totalsResult)->total;
967 $obj_ret[
'data'] = $tmp;
968 $obj_ret[
'pagination'] = [
969 'total' => (int) $total,
971 'page_count' => ceil((
int) $total / $limit),
997 unset(
$object->barcode_type_code);
998 unset(
$object->barcode_type_label);
999 unset(
$object->barcode_type_coder);
1000 unset(
$object->cond_reglement_id);
1001 unset(
$object->cond_reglement);
1002 unset(
$object->fk_delivery_address);
1003 unset(
$object->shipping_method_id);
1007 unset(
$object->label_incoterms);
1008 unset(
$object->location_incoterms);
1013 unset(
$object->mode_reglement_id);
1025 unset(
$object->total_localtax1);
1026 unset(
$object->total_localtax2);
1044 foreach (self::$FIELDS as $field) {
1045 if (!isset($data[$field])) {
1046 throw new RestException(400,
"$field field missing");
1048 $object[$field] = $data[$field];
1072 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
1073 throw new RestException(403);
1076 $result = $this->project->fetch(
$id);
1078 throw new RestException(404,
'Project not found');
1082 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
1085 $contacts = $this->project->liste_contact(-1,
'external', 0, $type);
1086 $socpeoples = $this->project->liste_contact(-1,
'internal', 0, $type);
1088 $contacts = array_merge($contacts, $socpeoples);
1113 public function addToContact(
$id, $fk_socpeople, $type_contact, $source, $notrigger = 0, $affect_to_tasks =
null)
1115 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
1116 throw new RestException(403);
1119 $result = $this->project->fetch(
$id);
1121 throw new RestException(404,
'Project not found');
1125 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
1129 $result = $this->project->add_contact($fk_socpeople, $type_contact, $source, $notrigger);
1131 throw new RestException(500,
'Error : ' . $this->project->error .
'result :' . $result);
1135 if ($affect_to_tasks !==
null) {
1136 $this->project->getLinesArray(DolibarrApiAccess::$user);
1137 $taskContactType = ($type_contact ==
'PROJECTLEADER' ?
'TASKEXECUTIVE' :
'TASKCONTRIBUTOR');
1139 foreach ($this->project->lines as $task) {
1142 if (empty($affect_to_tasks) || in_array($task->id, $affect_to_tasks)) {
1143 $result = $task->add_contact($fk_socpeople, $taskContactType, $source, $notrigger);
1145 throw new RestException(500,
'Error adding contact to task '.$task->id.
': '.$task->error);
1151 $result = $this->project->fetch(
$id);
1153 throw new RestException(404,
'Project not found');
1175 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'creer')) {
1176 throw new RestException(403);
1179 $result = $this->project->fetch(
$id);
1181 throw new RestException(404,
'Project not found');
1185 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
1188 foreach (array(
'internal',
'external') as $source) {
1189 $contacts = $this->project->liste_contact(-1, $source);
1191 foreach ($contacts as $contact) {
1192 if ($contact[
'id'] == $contactid && $contact[
'code'] == $type) {
1193 $result = $this->project->delete_contact($contact[
'rowid']);
1195 throw new RestException(500,
'Error when deleted the contact');
1218 if (!DolibarrApiAccess::$user->hasRight(
'projet',
'lire')) {
1219 throw new RestException(403);
1222 $result = $this->project->fetch(
$id);
1224 throw new RestException(404,
'Project not found');
1228 throw new RestException(403,
'Access not allowed for login ' . DolibarrApiAccess::$user->login);
1232 $this->project->getLinesArray(DolibarrApiAccess::$user);
1233 $allTimespent = array();
1234 foreach ($this->project->lines as $task) {
1235 $allTimespent[] = $task->getSummaryOfTimeSpent();
1243 return $allTimespent;
$id
Support class for third parties, contacts, members, users or resources.
if(! $sortfield) if(! $sortorder) $object
_checkValExtrafieldsForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $parenttableforentity='')
Check access by user to a given resource.
Class to manage projects.
addContact($id, $fk_socpeople, $type_contact, $source, $notrigger=0)
Adds a contact to an project.
post($request_data=null)
Create project object.
addToContact($id, $fk_socpeople, $type_contact, $source, $notrigger=0, $affect_to_tasks=null)
Adds a contact to a project.
getByMsgId($email_msgid)
Get properties of a project object.
getLines($id, $includetimespent=0)
Get tasks of a project.
validate($id, $notrigger=0)
Validate a project.
_validate($data)
Validate fields before create or update object.
getByRef($ref)
Get properties of a project object.
_cleanObjectDatas($object)
Clean sensible object datas @phpstan-template T.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $category=0, $sqlfilters='', $properties='', $pagination_data=false)
List projects.
getTimespent($id)
Get timespent of a project (from all its tasks)
__construct()
Constructor.
deleteToContact($id, $contactid, $type)
Delete a contact type of given project.
put($id, $request_data=null)
Add a task to given project.
listTimespent($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $category=0, $sqlfilters='', $properties='', $pagination_data=false)
Get all timespent.
deleteContact($id, $contactid, $type)
Delete a contact type of given project.
getByRefExt($ref_ext)
Get properties of a project object.
getRoles($id, $userid=0)
Get roles a user is assigned to a project with.
getContacts($id, $type='')
Get contacts of given project.
Class to manage Dolibarr users.
dol_now($mode='gmt')
Return date for now.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0, $forbiddenfields=array())
forgeSQLFromUniversalSearchCriteria
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.