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