dolibarr  16.0.5
api_contracts.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  * Copyright (C) 2018-2020 Frédéric France <frederic.france@netlogic.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20  use Luracast\Restler\RestException;
21 
22  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
23 
30 class Contracts extends DolibarrApi
31 {
32 
36  static $FIELDS = array(
37  'socid',
38  'date_contrat',
39  'commercial_signature_id',
40  'commercial_suivi_id'
41  );
42 
46  public $contract;
47 
51  public function __construct()
52  {
53  global $db, $conf;
54  $this->db = $db;
55  $this->contract = new Contrat($this->db);
56  }
57 
68  public function get($id)
69  {
70  if (!DolibarrApiAccess::$user->rights->contrat->lire) {
71  throw new RestException(401);
72  }
73 
74  $result = $this->contract->fetch($id);
75  if (!$result) {
76  throw new RestException(404, 'Contract not found');
77  }
78 
79  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
80  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
81  }
82 
83  $this->contract->fetchObjectLinked();
84  return $this->_cleanObjectDatas($this->contract);
85  }
86 
87 
88 
105  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
106  {
107  global $db, $conf;
108 
109  if (!DolibarrApiAccess::$user->rights->contrat->lire) {
110  throw new RestException(401);
111  }
112 
113  $obj_ret = array();
114 
115  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
116  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
117 
118  // If the internal user must only see his customers, force searching by him
119  $search_sale = 0;
120  if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) {
121  $search_sale = DolibarrApiAccess::$user->id;
122  }
123 
124  $sql = "SELECT t.rowid";
125  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
126  $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)
127  }
128  $sql .= " FROM ".MAIN_DB_PREFIX."contrat as t";
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('contrat').')';
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  // Add sql filters
149  if ($sqlfilters) {
150  $errormessage = '';
151  if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
152  throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage);
153  }
154  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
155  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
156  }
157 
158  $sql .= $this->db->order($sortfield, $sortorder);
159  if ($limit) {
160  if ($page < 0) {
161  $page = 0;
162  }
163  $offset = $limit * $page;
164 
165  $sql .= $this->db->plimit($limit + 1, $offset);
166  }
167 
168  dol_syslog("API Rest request");
169  $result = $this->db->query($sql);
170 
171  if ($result) {
172  $num = $this->db->num_rows($result);
173  $min = min($num, ($limit <= 0 ? $num : $limit));
174  $i = 0;
175  while ($i < $min) {
176  $obj = $this->db->fetch_object($result);
177  $contrat_static = new Contrat($this->db);
178  if ($contrat_static->fetch($obj->rowid)) {
179  $obj_ret[] = $this->_cleanObjectDatas($contrat_static);
180  }
181  $i++;
182  }
183  } else {
184  throw new RestException(503, 'Error when retrieve contrat list : '.$this->db->lasterror());
185  }
186  if (!count($obj_ret)) {
187  throw new RestException(404, 'No contract found');
188  }
189  return $obj_ret;
190  }
191 
198  public function post($request_data = null)
199  {
200  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
201  throw new RestException(401, "Insufficient rights");
202  }
203  // Check mandatory fields
204  $result = $this->_validate($request_data);
205 
206  foreach ($request_data as $field => $value) {
207  $this->contract->$field = $value;
208  }
209  /*if (isset($request_data["lines"])) {
210  $lines = array();
211  foreach ($request_data["lines"] as $line) {
212  array_push($lines, (object) $line);
213  }
214  $this->contract->lines = $lines;
215  }*/
216  if ($this->contract->create(DolibarrApiAccess::$user) < 0) {
217  throw new RestException(500, "Error creating contract", array_merge(array($this->contract->error), $this->contract->errors));
218  }
219 
220  return $this->contract->id;
221  }
222 
232  public function getLines($id)
233  {
234  if (!DolibarrApiAccess::$user->rights->contrat->lire) {
235  throw new RestException(401);
236  }
237 
238  $result = $this->contract->fetch($id);
239  if (!$result) {
240  throw new RestException(404, 'Contract not found');
241  }
242 
243  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
244  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
245  }
246  $this->contract->getLinesArray();
247  $result = array();
248  foreach ($this->contract->lines as $line) {
249  array_push($result, $this->_cleanObjectDatas($line));
250  }
251  return $result;
252  }
253 
264  public function postLine($id, $request_data = null)
265  {
266  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
267  throw new RestException(401);
268  }
269 
270  $result = $this->contract->fetch($id);
271  if (!$result) {
272  throw new RestException(404, 'Contract not found');
273  }
274 
275  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
276  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
277  }
278 
279  $request_data = (object) $request_data;
280 
281  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
282  $request_data->price_base_type = sanitizeVal($request_data->price_base_type);
283 
284  $updateRes = $this->contract->addline(
285  $request_data->desc,
286  $request_data->subprice,
287  $request_data->qty,
288  $request_data->tva_tx,
289  $request_data->localtax1_tx,
290  $request_data->localtax2_tx,
291  $request_data->fk_product,
292  $request_data->remise_percent,
293  $request_data->date_start, // date_start = date planned start, date ouverture = date_start_real
294  $request_data->date_end, // date_end = date planned end, date_cloture = date_end_real
295  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
296  $request_data->subprice_excl_tax,
297  $request_data->info_bits,
298  $request_data->fk_fournprice,
299  $request_data->pa_ht,
300  $request_data->array_options,
301  $request_data->fk_unit,
302  $request_data->rang
303  );
304 
305  if ($updateRes > 0) {
306  return $updateRes;
307  }
308  return false;
309  }
310 
322  public function putLine($id, $lineid, $request_data = null)
323  {
324  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
325  throw new RestException(401);
326  }
327 
328  $result = $this->contract->fetch($id);
329  if (!$result) {
330  throw new RestException(404, 'Contrat not found');
331  }
332 
333  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
334  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
335  }
336 
337  $request_data = (object) $request_data;
338 
339  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
340  $request_data->price_base_type = sanitizeVal($request_data->price_base_type);
341 
342  $updateRes = $this->contract->updateline(
343  $lineid,
344  $request_data->desc,
345  $request_data->subprice,
346  $request_data->qty,
347  $request_data->remise_percent,
348  $request_data->date_ouveture_prevue,
349  $request_data->date_fin_validite,
350  $request_data->tva_tx,
351  $request_data->localtax1_tx,
352  $request_data->localtax2_tx,
353  $request_data->date_ouverture,
354  $request_data->date_cloture,
355  $request_data->price_base_type ? $request_data->price_base_type : 'HT',
356  $request_data->info_bits,
357  $request_data->fk_fourn_price,
358  $request_data->pa_ht,
359  $request_data->array_options,
360  $request_data->fk_unit
361  );
362 
363  if ($updateRes > 0) {
364  $result = $this->get($id);
365  unset($result->line);
366  return $this->_cleanObjectDatas($result);
367  }
368 
369  return false;
370  }
371 
385  public function activateLine($id, $lineid, $datestart, $dateend = null, $comment = null)
386  {
387  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
388  throw new RestException(401);
389  }
390 
391  $result = $this->contract->fetch($id);
392  if (!$result) {
393  throw new RestException(404, 'Contrat not found');
394  }
395 
396  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
397  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
398  }
399 
400  $updateRes = $this->contract->active_line(DolibarrApiAccess::$user, $lineid, $datestart, $dateend, $comment);
401 
402  if ($updateRes > 0) {
403  $result = $this->get($id);
404  unset($result->line);
405  return $this->_cleanObjectDatas($result);
406  }
407 
408  return false;
409  }
410 
423  public function unactivateLine($id, $lineid, $datestart, $comment = null)
424  {
425  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
426  throw new RestException(401);
427  }
428 
429  $result = $this->contract->fetch($id);
430  if (!$result) {
431  throw new RestException(404, 'Contrat not found');
432  }
433 
434  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
435  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
436  }
437 
438  $updateRes = $this->contract->close_line(DolibarrApiAccess::$user, $lineid, $datestart, $comment);
439 
440  if ($updateRes > 0) {
441  $result = $this->get($id);
442  unset($result->line);
443  return $this->_cleanObjectDatas($result);
444  }
445 
446  return false;
447  }
448 
463  public function deleteLine($id, $lineid)
464  {
465  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
466  throw new RestException(401);
467  }
468 
469  $result = $this->contract->fetch($id);
470  if (!$result) {
471  throw new RestException(404, 'Contrat not found');
472  }
473 
474  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
475  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
476  }
477 
478  // TODO Check the lineid $lineid is a line of object
479 
480  $updateRes = $this->contract->deleteline($lineid, DolibarrApiAccess::$user);
481  if ($updateRes > 0) {
482  return $this->get($id);
483  } else {
484  throw new RestException(405, $this->contract->error);
485  }
486  }
487 
496  public function put($id, $request_data = null)
497  {
498  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
499  throw new RestException(401);
500  }
501 
502  $result = $this->contract->fetch($id);
503  if (!$result) {
504  throw new RestException(404, 'Contrat not found');
505  }
506 
507  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
508  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
509  }
510  foreach ($request_data as $field => $value) {
511  if ($field == 'id') {
512  continue;
513  }
514  $this->contract->$field = $value;
515  }
516 
517  if ($this->contract->update(DolibarrApiAccess::$user) > 0) {
518  return $this->get($id);
519  } else {
520  throw new RestException(500, $this->contract->error);
521  }
522  }
523 
531  public function delete($id)
532  {
533  if (!DolibarrApiAccess::$user->rights->contrat->supprimer) {
534  throw new RestException(401);
535  }
536  $result = $this->contract->fetch($id);
537  if (!$result) {
538  throw new RestException(404, 'Contract not found');
539  }
540 
541  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
542  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
543  }
544 
545  if (!$this->contract->delete(DolibarrApiAccess::$user)) {
546  throw new RestException(500, 'Error when delete contract : '.$this->contract->error);
547  }
548 
549  return array(
550  'success' => array(
551  'code' => 200,
552  'message' => 'Contract deleted'
553  )
554  );
555  }
556 
573  public function validate($id, $notrigger = 0)
574  {
575  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
576  throw new RestException(401);
577  }
578  $result = $this->contract->fetch($id);
579  if (!$result) {
580  throw new RestException(404, 'Contract not found');
581  }
582 
583  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
584  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
585  }
586 
587  $result = $this->contract->validate(DolibarrApiAccess::$user, '', $notrigger);
588  if ($result == 0) {
589  throw new RestException(304, 'Error nothing done. May be object is already validated');
590  }
591  if ($result < 0) {
592  throw new RestException(500, 'Error when validating Contract: '.$this->contract->error);
593  }
594 
595  return array(
596  'success' => array(
597  'code' => 200,
598  'message' => 'Contract validated (Ref='.$this->contract->ref.')'
599  )
600  );
601  }
602 
619  public function close($id, $notrigger = 0)
620  {
621  if (!DolibarrApiAccess::$user->rights->contrat->creer) {
622  throw new RestException(401);
623  }
624  $result = $this->contract->fetch($id);
625  if (!$result) {
626  throw new RestException(404, 'Contract not found');
627  }
628 
629  if (!DolibarrApi::_checkAccessToResource('contrat', $this->contract->id)) {
630  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
631  }
632 
633  $result = $this->contract->closeAll(DolibarrApiAccess::$user, $notrigger);
634  if ($result == 0) {
635  throw new RestException(304, 'Error nothing done. May be object is already close');
636  }
637  if ($result < 0) {
638  throw new RestException(500, 'Error when closing Contract: '.$this->contract->error);
639  }
640 
641  return array(
642  'success' => array(
643  'code' => 200,
644  'message' => 'Contract closed (Ref='.$this->contract->ref.'). All services were closed.'
645  )
646  );
647  }
648 
649 
650 
651  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
658  protected function _cleanObjectDatas($object)
659  {
660  // phpcs:enable
661  $object = parent::_cleanObjectDatas($object);
662 
663  unset($object->address);
664 
665  unset($object->date_ouverture_prevue);
666  unset($object->date_ouverture);
667  unset($object->date_fin_validite);
668  unset($object->date_cloture);
669  unset($object->date_debut_prevue);
670  unset($object->date_debut_reel);
671  unset($object->date_fin_prevue);
672  unset($object->date_fin_reel);
673  unset($object->civility_id);
674 
675  return $object;
676  }
677 
685  private function _validate($data)
686  {
687  $contrat = array();
688  foreach (Contracts::$FIELDS as $field) {
689  if (!isset($data[$field])) {
690  throw new RestException(400, "$field field missing");
691  }
692  $contrat[$field] = $data[$field];
693  }
694  return $contrat;
695  }
696 }
Contracts\_cleanObjectDatas
_cleanObjectDatas($object)
Clean sensible object datas.
Definition: api_contracts.class.php:658
Contracts\postLine
postLine($id, $request_data=null)
Add a line to given contract.
Definition: api_contracts.class.php:264
db
$conf db
API class for accounts.
Definition: inc.php:41
Contracts\__construct
__construct()
Constructor.
Definition: api_contracts.class.php:51
Contracts\unactivateLine
unactivateLine($id, $lineid, $datestart, $comment=null)
Unactivate a service line of a given contract.
Definition: api_contracts.class.php:423
Contracts\getLines
getLines($id)
Get lines of a contract.
Definition: api_contracts.class.php:232
Contracts
Definition: api_contracts.class.php:30
Contracts\deleteLine
deleteLine($id, $lineid)
Delete a line to given contract.
Definition: api_contracts.class.php:463
sanitizeVal
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
Definition: functions.lib.php:825
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
Contracts\_validate
_validate($data)
Validate fields before create or update object.
Definition: api_contracts.class.php:685
DolibarrApi
Class for API REST v1.
Definition: api.class.php:30
Contracts\post
post($request_data=null)
Create contract object.
Definition: api_contracts.class.php:198
Contracts\put
put($id, $request_data=null)
Update contract general fields (won't touch lines of contract)
Definition: api_contracts.class.php:496
DolibarrApi\_checkFilters
_checkFilters($sqlfilters, &$error='')
Return if a $sqlfilters parameter is valid.
Definition: api.class.php:310
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1603
Contracts\validate
validate($id, $notrigger=0)
Validate a contract.
Definition: api_contracts.class.php:573
Contracts\activateLine
activateLine($id, $lineid, $datestart, $dateend=null, $comment=null)
Activate a service line of a given contract.
Definition: api_contracts.class.php:385
Contrat
Class to manage contracts.
Definition: contrat.class.php:43
Contracts\close
close($id, $notrigger=0)
Close all services of a contract.
Definition: api_contracts.class.php:619
Contracts\putLine
putLine($id, $lineid, $request_data=null)
Update a line to given contract.
Definition: api_contracts.class.php:322
Contracts\index
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $sqlfilters='')
List contracts.
Definition: api_contracts.class.php:105