dolibarr  17.0.3
api_projects.class.php
1 <?php
2 /* Copyright (C) 2015 Jean-Fran├žois Ferry <jfefe@aternatik.fr>
3  * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <https://www.gnu.org/licenses/>.
17  */
18 
19  use Luracast\Restler\RestException;
20 
21  require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
22  require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
23 
30 class Projects extends DolibarrApi
31 {
32 
36  public static $FIELDS = array(
37  'ref',
38  'title'
39  );
40 
44  public $project;
45 
49  public function __construct()
50  {
51  global $db, $conf;
52  $this->db = $db;
53  $this->project = new Project($this->db);
54  $this->task = new Task($this->db);
55  }
56 
67  public function get($id)
68  {
69  if (!DolibarrApiAccess::$user->rights->projet->lire) {
70  throw new RestException(401);
71  }
72 
73  $result = $this->project->fetch($id);
74  if (!$result) {
75  throw new RestException(404, 'Project not found');
76  }
77 
78  if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) {
79  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
80  }
81 
82  $this->project->fetchObjectLinked();
83  return $this->_cleanObjectDatas($this->project);
84  }
85 
86 
87 
102  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $category = 0, $sqlfilters = '')
103  {
104  global $db, $conf;
105 
106  if (!DolibarrApiAccess::$user->rights->projet->lire) {
107  throw new RestException(401);
108  }
109 
110  $obj_ret = array();
111 
112  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
113  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
114 
115  // If the internal user must only see his customers, force searching by him
116  $search_sale = 0;
117  if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) {
118  $search_sale = DolibarrApiAccess::$user->id;
119  }
120 
121  $sql = "SELECT t.rowid";
122  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
123  $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)
124  }
125  $sql .= " FROM ".MAIN_DB_PREFIX."projet as t";
126  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."projet_extrafields AS ef ON ef.fk_object = t.rowid"; // So we will be able to filter on extrafields
127  if ($category > 0) {
128  $sql .= ", ".MAIN_DB_PREFIX."categorie_project as c";
129  }
130  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
131  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
132  }
133 
134  $sql .= ' WHERE t.entity IN ('.getEntity('project').')';
135  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
136  $sql .= " AND t.fk_soc = sc.fk_soc";
137  }
138  if ($socids) {
139  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
140  }
141  if ($search_sale > 0) {
142  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
143  }
144  // Insert sale filter
145  if ($search_sale > 0) {
146  $sql .= " AND sc.fk_user = ".((int) $search_sale);
147  }
148  // Select projects of given category
149  if ($category > 0) {
150  $sql .= " AND c.fk_categorie = ".((int) $category)." AND c.fk_project = t.rowid ";
151  }
152  // Add sql filters
153  if ($sqlfilters) {
154  $errormessage = '';
155  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
156  if ($errormessage) {
157  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
158  }
159  }
160 
161  $sql .= $this->db->order($sortfield, $sortorder);
162  if ($limit) {
163  if ($page < 0) {
164  $page = 0;
165  }
166  $offset = $limit * $page;
167 
168  $sql .= $this->db->plimit($limit + 1, $offset);
169  }
170 
171  dol_syslog("API Rest request");
172  $result = $this->db->query($sql);
173 
174  if ($result) {
175  $num = $this->db->num_rows($result);
176  $min = min($num, ($limit <= 0 ? $num : $limit));
177  $i = 0;
178  while ($i < $min) {
179  $obj = $this->db->fetch_object($result);
180  $project_static = new Project($this->db);
181  if ($project_static->fetch($obj->rowid)) {
182  $obj_ret[] = $this->_cleanObjectDatas($project_static);
183  }
184  $i++;
185  }
186  } else {
187  throw new RestException(503, 'Error when retrieve project list : '.$this->db->lasterror());
188  }
189  if (!count($obj_ret)) {
190  throw new RestException(404, 'No project found');
191  }
192  return $obj_ret;
193  }
194 
201  public function post($request_data = null)
202  {
203  if (!DolibarrApiAccess::$user->rights->projet->creer) {
204  throw new RestException(401, "Insuffisant rights");
205  }
206  // Check mandatory fields
207  $result = $this->_validate($request_data);
208 
209  foreach ($request_data as $field => $value) {
210  $this->project->$field = $value;
211  }
212  /*if (isset($request_data["lines"])) {
213  $lines = array();
214  foreach ($request_data["lines"] as $line) {
215  array_push($lines, (object) $line);
216  }
217  $this->project->lines = $lines;
218  }*/
219  if ($this->project->create(DolibarrApiAccess::$user) < 0) {
220  throw new RestException(500, "Error creating project", array_merge(array($this->project->error), $this->project->errors));
221  }
222 
223  return $this->project->id;
224  }
225 
236  public function getLines($id, $includetimespent = 0)
237  {
238  if (!DolibarrApiAccess::$user->rights->projet->lire) {
239  throw new RestException(401);
240  }
241 
242  $result = $this->project->fetch($id);
243  if (!$result) {
244  throw new RestException(404, 'Project not found');
245  }
246 
247  if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) {
248  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
249  }
250  $this->project->getLinesArray(DolibarrApiAccess::$user);
251  $result = array();
252  foreach ($this->project->lines as $line) { // $line is a task
253  if ($includetimespent == 1) {
254  $timespent = $line->getSummaryOfTimeSpent(0);
255  }
256  if ($includetimespent == 2) {
257  $timespent = $line->fetchTimeSpentOnTask();
258  }
259  array_push($result, $this->_cleanObjectDatas($line));
260  }
261  return $result;
262  }
263 
264 
275  public function getRoles($id, $userid = 0)
276  {
277  global $db;
278 
279  if (!DolibarrApiAccess::$user->rights->projet->lire) {
280  throw new RestException(401);
281  }
282 
283  $result = $this->project->fetch($id);
284  if (!$result) {
285  throw new RestException(404, 'Project not found');
286  }
287 
288  if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) {
289  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
290  }
291 
292  require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
293  $taskstatic = new Task($this->db);
294  $userp = DolibarrApiAccess::$user;
295  if ($userid > 0) {
296  $userp = new User($this->db);
297  $userp->fetch($userid);
298  }
299  $this->project->roles = $taskstatic->getUserRolesForProjectsOrTasks($userp, 0, $id, 0);
300  $result = array();
301  foreach ($this->project->roles as $line) {
302  array_push($result, $this->_cleanObjectDatas($line));
303  }
304  return $result;
305  }
306 
307 
318  /*
319  public function postLine($id, $request_data = null)
320  {
321  if(! DolibarrApiAccess::$user->rights->projet->creer) {
322  throw new RestException(401);
323  }
324 
325  $result = $this->project->fetch($id);
326  if( ! $result ) {
327  throw new RestException(404, 'Project not found');
328  }
329 
330  if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) {
331  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
332  }
333 
334  $request_data = (object) $request_data;
335 
336  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
337 
338  $updateRes = $this->project->addline(
339  $request_data->desc,
340  $request_data->subprice,
341  $request_data->qty,
342  $request_data->tva_tx,
343  $request_data->localtax1_tx,
344  $request_data->localtax2_tx,
345  $request_data->fk_product,
346  $request_data->remise_percent,
347  $request_data->info_bits,
348  $request_data->fk_remise_except,
349  'HT',
350  0,
351  $request_data->date_start,
352  $request_data->date_end,
353  $request_data->product_type,
354  $request_data->rang,
355  $request_data->special_code,
356  $fk_parent_line,
357  $request_data->fk_fournprice,
358  $request_data->pa_ht,
359  $request_data->label,
360  $request_data->array_options,
361  $request_data->fk_unit,
362  $this->element,
363  $request_data->id
364  );
365 
366  if ($updateRes > 0) {
367  return $updateRes;
368 
369  }
370  return false;
371  }
372  */
373 
385  /*
386  public function putLine($id, $lineid, $request_data = null)
387  {
388  if(! DolibarrApiAccess::$user->rights->projet->creer) {
389  throw new RestException(401);
390  }
391 
392  $result = $this->project->fetch($id);
393  if( ! $result ) {
394  throw new RestException(404, 'Project not found');
395  }
396 
397  if( ! DolibarrApi::_checkAccessToResource('project',$this->project->id)) {
398  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
399  }
400 
401  $request_data = (object) $request_data;
402 
403  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
404 
405  $updateRes = $this->project->updateline(
406  $lineid,
407  $request_data->desc,
408  $request_data->subprice,
409  $request_data->qty,
410  $request_data->remise_percent,
411  $request_data->tva_tx,
412  $request_data->localtax1_tx,
413  $request_data->localtax2_tx,
414  'HT',
415  $request_data->info_bits,
416  $request_data->date_start,
417  $request_data->date_end,
418  $request_data->product_type,
419  $request_data->fk_parent_line,
420  0,
421  $request_data->fk_fournprice,
422  $request_data->pa_ht,
423  $request_data->label,
424  $request_data->special_code,
425  $request_data->array_options,
426  $request_data->fk_unit
427  );
428 
429  if ($updateRes > 0) {
430  $result = $this->get($id);
431  unset($result->line);
432  return $this->_cleanObjectDatas($result);
433  }
434  return false;
435  }*/
436 
437 
438 
447  public function put($id, $request_data = null)
448  {
449  if (!DolibarrApiAccess::$user->rights->projet->creer) {
450  throw new RestException(401);
451  }
452 
453  $result = $this->project->fetch($id);
454  if ($result <= 0) {
455  throw new RestException(404, 'Project not found');
456  }
457 
458  if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) {
459  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
460  }
461  foreach ($request_data as $field => $value) {
462  if ($field == 'id') {
463  continue;
464  }
465  $this->project->$field = $value;
466  }
467 
468  if ($this->project->update(DolibarrApiAccess::$user) >= 0) {
469  return $this->get($id);
470  } else {
471  throw new RestException(500, $this->project->error);
472  }
473  }
474 
482  public function delete($id)
483  {
484  if (!DolibarrApiAccess::$user->rights->projet->supprimer) {
485  throw new RestException(401);
486  }
487  $result = $this->project->fetch($id);
488  if (!$result) {
489  throw new RestException(404, 'Project not found');
490  }
491 
492  if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) {
493  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
494  }
495 
496  if (!$this->project->delete(DolibarrApiAccess::$user)) {
497  throw new RestException(500, 'Error when delete project : '.$this->project->error);
498  }
499 
500  return array(
501  'success' => array(
502  'code' => 200,
503  'message' => 'Project deleted'
504  )
505  );
506  }
507 
526  public function validate($id, $notrigger = 0)
527  {
528  if (!DolibarrApiAccess::$user->rights->projet->creer) {
529  throw new RestException(401);
530  }
531  $result = $this->project->fetch($id);
532  if (!$result) {
533  throw new RestException(404, 'Project not found');
534  }
535 
536  if (!DolibarrApi::_checkAccessToResource('project', $this->project->id)) {
537  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
538  }
539 
540  $result = $this->project->setValid(DolibarrApiAccess::$user, $notrigger);
541  if ($result == 0) {
542  throw new RestException(304, 'Error nothing done. May be object is already validated');
543  }
544  if ($result < 0) {
545  throw new RestException(500, 'Error when validating Project: '.$this->project->error);
546  }
547 
548  return array(
549  'success' => array(
550  'code' => 200,
551  'message' => 'Project validated'
552  )
553  );
554  }
555 
556 
557  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
564  protected function _cleanObjectDatas($object)
565  {
566  // phpcs:enable
567  $object = parent::_cleanObjectDatas($object);
568 
569  unset($object->datec);
570  unset($object->datem);
571  unset($object->barcode_type);
572  unset($object->barcode_type_code);
573  unset($object->barcode_type_label);
574  unset($object->barcode_type_coder);
575  unset($object->cond_reglement_id);
576  unset($object->cond_reglement);
577  unset($object->fk_delivery_address);
578  unset($object->shipping_method_id);
579  unset($object->fk_account);
580  unset($object->note);
581  unset($object->fk_incoterms);
582  unset($object->label_incoterms);
583  unset($object->location_incoterms);
584  unset($object->name);
585  unset($object->lastname);
586  unset($object->firstname);
587  unset($object->civility_id);
588  unset($object->mode_reglement_id);
589  unset($object->country);
590  unset($object->country_id);
591  unset($object->country_code);
592 
593  unset($object->weekWorkLoad);
594  unset($object->weekWorkLoad);
595 
596  //unset($object->lines); // for task we use timespent_lines, but for project we use lines
597 
598  unset($object->total_ht);
599  unset($object->total_tva);
600  unset($object->total_localtax1);
601  unset($object->total_localtax2);
602  unset($object->total_ttc);
603 
604  unset($object->comments);
605 
606  return $object;
607  }
608 
616  private function _validate($data)
617  {
618  $object = array();
619  foreach (self::$FIELDS as $field) {
620  if (!isset($data[$field])) {
621  throw new RestException(400, "$field field missing");
622  }
623  $object[$field] = $data[$field];
624  }
625  return $object;
626  }
627 
628 
629  // TODO
630  // getSummaryOfTimeSpent
631 }
db
$conf db
API class for accounts.
Definition: inc.php:41
Project
Class to manage projects.
Definition: project.class.php:35
Projects\__construct
__construct()
Constructor.
Definition: api_projects.class.php:49
Projects\index
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $category=0, $sqlfilters='')
List projects.
Definition: api_projects.class.php:102
Task
Class to manage tasks.
Definition: task.class.php:37
DolibarrApi\_checkAccessToResource
static _checkAccessToResource($resource, $resource_id=0, $dbtablename='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid')
Check access by user to a given resource.
Definition: api.class.php:283
Projects\put
put($id, $request_data=null)
Add a task to given project.
Definition: api_projects.class.php:447
DolibarrApi
Class for API REST v1.
Definition: api.class.php:30
Projects\_cleanObjectDatas
_cleanObjectDatas($object)
Clean sensible object datas.
Definition: api_projects.class.php:564
Projects\getLines
getLines($id, $includetimespent=0)
Get tasks of a project.
Definition: api_projects.class.php:236
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1628
forgeSQLFromUniversalSearchCriteria
forgeSQLFromUniversalSearchCriteria($filter, &$error='')
forgeSQLFromUniversalSearchCriteria
Definition: functions.lib.php:11561
Projects\getRoles
getRoles($id, $userid=0)
Get roles a user is assigned to a project with.
Definition: api_projects.class.php:275
User
Class to manage Dolibarr users.
Definition: user.class.php:46
Projects\post
post($request_data=null)
Create project object.
Definition: api_projects.class.php:201
Projects\validate
validate($id, $notrigger=0)
Validate a project.
Definition: api_projects.class.php:526
Projects
Definition: api_projects.class.php:30
Projects\_validate
_validate($data)
Validate fields before create or update object.
Definition: api_projects.class.php:616