dolibarr  16.0.5
api_shipments.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.'/expedition/class/expedition.class.php';
22 
29 class Shipments extends DolibarrApi
30 {
31 
35  public static $FIELDS = array(
36  'socid',
37  'origin_id',
38  'origin_type',
39  );
40 
44  public $shipment;
45 
49  public function __construct()
50  {
51  global $db, $conf;
52  $this->db = $db;
53  $this->shipment = new Expedition($this->db);
54  }
55 
66  public function get($id)
67  {
68  if (!DolibarrApiAccess::$user->rights->expedition->lire) {
69  throw new RestException(401);
70  }
71 
72  $result = $this->shipment->fetch($id);
73  if (!$result) {
74  throw new RestException(404, 'Shipment not found');
75  }
76 
77  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
78  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
79  }
80 
81  $this->shipment->fetchObjectLinked();
82  return $this->_cleanObjectDatas($this->shipment);
83  }
84 
85 
86 
102  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '')
103  {
104  global $db, $conf;
105 
106  if (!DolibarrApiAccess::$user->rights->expedition->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."expedition as t";
126 
127  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
128  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
129  }
130 
131  $sql .= ' WHERE t.entity IN ('.getEntity('expedition').')';
132  if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) {
133  $sql .= " AND t.fk_soc = sc.fk_soc";
134  }
135  if ($socids) {
136  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
137  }
138  if ($search_sale > 0) {
139  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
140  }
141  // Insert sale filter
142  if ($search_sale > 0) {
143  $sql .= " AND sc.fk_user = ".((int) $search_sale);
144  }
145  // Add sql filters
146  if ($sqlfilters) {
147  $errormessage = '';
148  if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
149  throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage);
150  }
151  $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
152  $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
153  }
154 
155  $sql .= $this->db->order($sortfield, $sortorder);
156  if ($limit) {
157  if ($page < 0) {
158  $page = 0;
159  }
160  $offset = $limit * $page;
161 
162  $sql .= $this->db->plimit($limit + 1, $offset);
163  }
164 
165  dol_syslog("API Rest request");
166  $result = $this->db->query($sql);
167 
168  if ($result) {
169  $num = $this->db->num_rows($result);
170  $min = min($num, ($limit <= 0 ? $num : $limit));
171  $i = 0;
172  while ($i < $min) {
173  $obj = $this->db->fetch_object($result);
174  $shipment_static = new Expedition($this->db);
175  if ($shipment_static->fetch($obj->rowid)) {
176  $obj_ret[] = $this->_cleanObjectDatas($shipment_static);
177  }
178  $i++;
179  }
180  } else {
181  throw new RestException(503, 'Error when retrieve commande list : '.$this->db->lasterror());
182  }
183  if (!count($obj_ret)) {
184  throw new RestException(404, 'No shipment found');
185  }
186  return $obj_ret;
187  }
188 
195  public function post($request_data = null)
196  {
197  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
198  throw new RestException(401, "Insuffisant rights");
199  }
200  // Check mandatory fields
201  $result = $this->_validate($request_data);
202 
203  foreach ($request_data as $field => $value) {
204  $this->shipment->$field = $value;
205  }
206  if (isset($request_data["lines"])) {
207  $lines = array();
208  foreach ($request_data["lines"] as $line) {
209  array_push($lines, (object) $line);
210  }
211  $this->shipment->lines = $lines;
212  }
213 
214  if ($this->shipment->create(DolibarrApiAccess::$user) < 0) {
215  throw new RestException(500, "Error creating shipment", array_merge(array($this->shipment->error), $this->shipment->errors));
216  }
217 
218  return $this->shipment->id;
219  }
220 
221  // /**
222  // * Get lines of an shipment
223  // *
224  // * @param int $id Id of shipment
225  // *
226  // * @url GET {id}/lines
227  // *
228  // * @return int
229  // */
230  /*
231  public function getLines($id)
232  {
233  if(! DolibarrApiAccess::$user->rights->expedition->lire) {
234  throw new RestException(401);
235  }
236 
237  $result = $this->shipment->fetch($id);
238  if( ! $result ) {
239  throw new RestException(404, 'Shipment not found');
240  }
241 
242  if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) {
243  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
244  }
245  $this->shipment->getLinesArray();
246  $result = array();
247  foreach ($this->shipment->lines as $line) {
248  array_push($result,$this->_cleanObjectDatas($line));
249  }
250  return $result;
251  }
252  */
253 
254  // /**
255  // * Add a line to given shipment
256  // *
257  // * @param int $id Id of shipment to update
258  // * @param array $request_data ShipmentLine data
259  // *
260  // * @url POST {id}/lines
261  // *
262  // * @return int
263  // */
264  /*
265  public function postLine($id, $request_data = null)
266  {
267  if(! DolibarrApiAccess::$user->rights->expedition->creer) {
268  throw new RestException(401);
269  }
270 
271  $result = $this->shipment->fetch($id);
272  if ( ! $result ) {
273  throw new RestException(404, 'Shipment not found');
274  }
275 
276  if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) {
277  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
278  }
279 
280  $request_data = (object) $request_data;
281 
282  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
283  $request_data->label = sanitizeVal($request_data->label);
284 
285  $updateRes = $this->shipment->addline(
286  $request_data->desc,
287  $request_data->subprice,
288  $request_data->qty,
289  $request_data->tva_tx,
290  $request_data->localtax1_tx,
291  $request_data->localtax2_tx,
292  $request_data->fk_product,
293  $request_data->remise_percent,
294  $request_data->info_bits,
295  $request_data->fk_remise_except,
296  'HT',
297  0,
298  $request_data->date_start,
299  $request_data->date_end,
300  $request_data->product_type,
301  $request_data->rang,
302  $request_data->special_code,
303  $fk_parent_line,
304  $request_data->fk_fournprice,
305  $request_data->pa_ht,
306  $request_data->label,
307  $request_data->array_options,
308  $request_data->fk_unit,
309  $request_data->origin,
310  $request_data->origin_id,
311  $request_data->multicurrency_subprice
312  );
313 
314  if ($updateRes > 0) {
315  return $updateRes;
316 
317  }
318  return false;
319  }*/
320 
321  // /**
322  // * Update a line to given shipment
323  // *
324  // * @param int $id Id of shipment to update
325  // * @param int $lineid Id of line to update
326  // * @param array $request_data ShipmentLine data
327  // *
328  // * @url PUT {id}/lines/{lineid}
329  // *
330  // * @return object
331  // */
332  /*
333  public function putLine($id, $lineid, $request_data = null)
334  {
335  if (! DolibarrApiAccess::$user->rights->expedition->creer) {
336  throw new RestException(401);
337  }
338 
339  $result = $this->shipment->fetch($id);
340  if ( ! $result ) {
341  throw new RestException(404, 'Shipment not found');
342  }
343 
344  if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) {
345  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
346  }
347 
348  $request_data = (object) $request_data;
349 
350  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
351  $request_data->label = sanitizeVal($request_data->label);
352 
353  $updateRes = $this->shipment->updateline(
354  $lineid,
355  $request_data->desc,
356  $request_data->subprice,
357  $request_data->qty,
358  $request_data->remise_percent,
359  $request_data->tva_tx,
360  $request_data->localtax1_tx,
361  $request_data->localtax2_tx,
362  'HT',
363  $request_data->info_bits,
364  $request_data->date_start,
365  $request_data->date_end,
366  $request_data->product_type,
367  $request_data->fk_parent_line,
368  0,
369  $request_data->fk_fournprice,
370  $request_data->pa_ht,
371  $request_data->label,
372  $request_data->special_code,
373  $request_data->array_options,
374  $request_data->fk_unit,
375  $request_data->multicurrency_subprice
376  );
377 
378  if ($updateRes > 0) {
379  $result = $this->get($id);
380  unset($result->line);
381  return $this->_cleanObjectDatas($result);
382  }
383  return false;
384  }*/
385 
400  public function deleteLine($id, $lineid)
401  {
402  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
403  throw new RestException(401);
404  }
405 
406  $result = $this->shipment->fetch($id);
407  if (!$result) {
408  throw new RestException(404, 'Shipment not found');
409  }
410 
411  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
412  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
413  }
414 
415  // TODO Check the lineid $lineid is a line of ojbect
416 
417  $updateRes = $this->shipment->deleteline(DolibarrApiAccess::$user, $lineid);
418  if ($updateRes > 0) {
419  return $this->get($id);
420  } else {
421  throw new RestException(405, $this->shipment->error);
422  }
423  }
424 
433  public function put($id, $request_data = null)
434  {
435  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
436  throw new RestException(401);
437  }
438 
439  $result = $this->shipment->fetch($id);
440  if (!$result) {
441  throw new RestException(404, 'Shipment not found');
442  }
443 
444  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
445  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
446  }
447  foreach ($request_data as $field => $value) {
448  if ($field == 'id') {
449  continue;
450  }
451  $this->shipment->$field = $value;
452  }
453 
454  if ($this->shipment->update(DolibarrApiAccess::$user) > 0) {
455  return $this->get($id);
456  } else {
457  throw new RestException(500, $this->shipment->error);
458  }
459  }
460 
468  public function delete($id)
469  {
470  if (!DolibarrApiAccess::$user->rights->expedition->supprimer) {
471  throw new RestException(401);
472  }
473  $result = $this->shipment->fetch($id);
474  if (!$result) {
475  throw new RestException(404, 'Shipment not found');
476  }
477 
478  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
479  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
480  }
481 
482  if (!$this->shipment->delete(DolibarrApiAccess::$user)) {
483  throw new RestException(500, 'Error when deleting shipment : '.$this->shipment->error);
484  }
485 
486  return array(
487  'success' => array(
488  'code' => 200,
489  'message' => 'Shipment deleted'
490  )
491  );
492  }
493 
513  public function validate($id, $notrigger = 0)
514  {
515  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
516  throw new RestException(401);
517  }
518  $result = $this->shipment->fetch($id);
519  if (!$result) {
520  throw new RestException(404, 'Shipment not found');
521  }
522 
523  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
524  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
525  }
526 
527  $result = $this->shipment->valid(DolibarrApiAccess::$user, $notrigger);
528  if ($result == 0) {
529  throw new RestException(304, 'Error nothing done. May be object is already validated');
530  }
531  if ($result < 0) {
532  throw new RestException(500, 'Error when validating Shipment: '.$this->shipment->error);
533  }
534 
535  // Reload shipment
536  $result = $this->shipment->fetch($id);
537 
538  $this->shipment->fetchObjectLinked();
539  return $this->_cleanObjectDatas($this->shipment);
540  }
541 
542 
543  // /**
544  // * Classify the shipment as invoiced
545  // *
546  // * @param int $id Id of the shipment
547  // *
548  // * @url POST {id}/setinvoiced
549  // *
550  // * @return int
551  // *
552  // * @throws RestException 400
553  // * @throws RestException 401
554  // * @throws RestException 404
555  // * @throws RestException 405
556  // */
557  /*
558  public function setinvoiced($id)
559  {
560 
561  if(! DolibarrApiAccess::$user->rights->expedition->creer) {
562  throw new RestException(401);
563  }
564  if(empty($id)) {
565  throw new RestException(400, 'Shipment ID is mandatory');
566  }
567  $result = $this->shipment->fetch($id);
568  if( ! $result ) {
569  throw new RestException(404, 'Shipment not found');
570  }
571 
572  $result = $this->shipment->classifyBilled(DolibarrApiAccess::$user);
573  if( $result < 0) {
574  throw new RestException(400, $this->shipment->error);
575  }
576  return $result;
577  }
578  */
579 
580 
581  // /**
582  // * Create a shipment using an existing order.
583  // *
584  // * @param int $orderid Id of the order
585  // *
586  // * @url POST /createfromorder/{orderid}
587  // *
588  // * @return int
589  // * @throws RestException 400
590  // * @throws RestException 401
591  // * @throws RestException 404
592  // * @throws RestException 405
593  // */
594  /*
595  public function createShipmentFromOrder($orderid)
596  {
597 
598  require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
599 
600  if(! DolibarrApiAccess::$user->rights->expedition->lire) {
601  throw new RestException(401);
602  }
603  if(! DolibarrApiAccess::$user->rights->expedition->creer) {
604  throw new RestException(401);
605  }
606  if(empty($proposalid)) {
607  throw new RestException(400, 'Order ID is mandatory');
608  }
609 
610  $order = new Commande($this->db);
611  $result = $order->fetch($proposalid);
612  if( ! $result ) {
613  throw new RestException(404, 'Order not found');
614  }
615 
616  $result = $this->shipment->createFromOrder($order, DolibarrApiAccess::$user);
617  if( $result < 0) {
618  throw new RestException(405, $this->shipment->error);
619  }
620  $this->shipment->fetchObjectLinked();
621  return $this->_cleanObjectDatas($this->shipment);
622  }
623  */
624 
635  public function close($id, $notrigger = 0)
636  {
637  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
638  throw new RestException(401);
639  }
640 
641  $result = $this->shipment->fetch($id);
642  if (!$result) {
643  throw new RestException(404, 'Shipment not found');
644  }
645 
646  if (!DolibarrApi::_checkAccessToResource('expedition', $this->commande->id)) {
647  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
648  }
649 
650  $result = $this->shipment->setClosed();
651  if ($result == 0) {
652  throw new RestException(304, 'Error nothing done. May be object is already closed');
653  }
654  if ($result < 0) {
655  throw new RestException(500, 'Error when closing Order: '.$this->commande->error);
656  }
657 
658  // Reload shipment
659  $result = $this->shipment->fetch($id);
660 
661  $this->shipment->fetchObjectLinked();
662 
663  return $this->_cleanObjectDatas($this->shipment);
664  }
665 
666  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
673  protected function _cleanObjectDatas($object)
674  {
675  // phpcs:enable
676  $object = parent::_cleanObjectDatas($object);
677 
678  unset($object->thirdparty); // id already returned
679 
680  unset($object->note);
681  unset($object->address);
682  unset($object->barcode_type);
683  unset($object->barcode_type_code);
684  unset($object->barcode_type_label);
685  unset($object->barcode_type_coder);
686 
687  if (!empty($object->lines) && is_array($object->lines)) {
688  foreach ($object->lines as $line) {
689  unset($line->tva_tx);
690  unset($line->vat_src_code);
691  unset($line->total_ht);
692  unset($line->total_ttc);
693  unset($line->total_tva);
694  unset($line->total_localtax1);
695  unset($line->total_localtax2);
696  unset($line->remise_percent);
697  }
698  }
699 
700  return $object;
701  }
702 
710  private function _validate($data)
711  {
712  $shipment = array();
713  foreach (Shipments::$FIELDS as $field) {
714  if (!isset($data[$field])) {
715  throw new RestException(400, "$field field missing");
716  }
717  $shipment[$field] = $data[$field];
718  }
719  return $shipment;
720  }
721 }
db
$conf db
API class for accounts.
Definition: inc.php:41
Shipments\__construct
__construct()
Constructor.
Definition: api_shipments.class.php:49
Expedition
Class to manage shipments.
Definition: expedition.class.php:52
Shipments\put
put($id, $request_data=null)
Update shipment general fields (won't touch lines of shipment)
Definition: api_shipments.class.php:433
Shipments\index
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $sqlfilters='')
List shipments.
Definition: api_shipments.class.php:102
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
Shipments\close
close($id, $notrigger=0)
Close a shipment (Classify it as "Delivered")
Definition: api_shipments.class.php:635
DolibarrApi
Class for API REST v1.
Definition: api.class.php:30
Shipments\_cleanObjectDatas
_cleanObjectDatas($object)
Clean sensible object datas.
Definition: api_shipments.class.php:673
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
Shipments\post
post($request_data=null)
Create shipment object.
Definition: api_shipments.class.php:195
Shipments\_validate
_validate($data)
Validate fields before create or update object.
Definition: api_shipments.class.php:710
Shipments\validate
validate($id, $notrigger=0)
Validate a shipment.
Definition: api_shipments.class.php:513
Shipments
Definition: api_shipments.class.php:29
Shipments\deleteLine
deleteLine($id, $lineid)
Delete a line to given shipment.
Definition: api_shipments.class.php:400