dolibarr  19.0.0-dev
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 LEFT JOIN ".MAIN_DB_PREFIX."expedition_extrafields AS ef ON (ef.fk_object = t.rowid)"; // Modification VMR Global Solutions to include extrafields as search parameters in the API GET call, so we will be able to filter on extrafields
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  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
149  if ($errormessage) {
150  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
151  }
152  }
153 
154  $sql .= $this->db->order($sortfield, $sortorder);
155  if ($limit) {
156  if ($page < 0) {
157  $page = 0;
158  }
159  $offset = $limit * $page;
160 
161  $sql .= $this->db->plimit($limit + 1, $offset);
162  }
163 
164  dol_syslog("API Rest request");
165  $result = $this->db->query($sql);
166 
167  if ($result) {
168  $num = $this->db->num_rows($result);
169  $min = min($num, ($limit <= 0 ? $num : $limit));
170  $i = 0;
171  while ($i < $min) {
172  $obj = $this->db->fetch_object($result);
173  $shipment_static = new Expedition($this->db);
174  if ($shipment_static->fetch($obj->rowid)) {
175  $obj_ret[] = $this->_cleanObjectDatas($shipment_static);
176  }
177  $i++;
178  }
179  } else {
180  throw new RestException(503, 'Error when retrieve commande list : '.$this->db->lasterror());
181  }
182  if (!count($obj_ret)) {
183  throw new RestException(404, 'No shipment found');
184  }
185  return $obj_ret;
186  }
187 
194  public function post($request_data = null)
195  {
196  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
197  throw new RestException(401, "Insuffisant rights");
198  }
199  // Check mandatory fields
200  $result = $this->_validate($request_data);
201 
202  foreach ($request_data as $field => $value) {
203  $this->shipment->$field = $value;
204  }
205  if (isset($request_data["lines"])) {
206  $lines = array();
207  foreach ($request_data["lines"] as $line) {
208  array_push($lines, (object) $line);
209  }
210  $this->shipment->lines = $lines;
211  }
212 
213  if ($this->shipment->create(DolibarrApiAccess::$user) < 0) {
214  throw new RestException(500, "Error creating shipment", array_merge(array($this->shipment->error), $this->shipment->errors));
215  }
216 
217  return $this->shipment->id;
218  }
219 
220  // /**
221  // * Get lines of an shipment
222  // *
223  // * @param int $id Id of shipment
224  // *
225  // * @url GET {id}/lines
226  // *
227  // * @return int
228  // */
229  /*
230  public function getLines($id)
231  {
232  if(! DolibarrApiAccess::$user->rights->expedition->lire) {
233  throw new RestException(401);
234  }
235 
236  $result = $this->shipment->fetch($id);
237  if( ! $result ) {
238  throw new RestException(404, 'Shipment not found');
239  }
240 
241  if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) {
242  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
243  }
244  $this->shipment->getLinesArray();
245  $result = array();
246  foreach ($this->shipment->lines as $line) {
247  array_push($result,$this->_cleanObjectDatas($line));
248  }
249  return $result;
250  }
251  */
252 
253  // /**
254  // * Add a line to given shipment
255  // *
256  // * @param int $id Id of shipment to update
257  // * @param array $request_data ShipmentLine data
258  // *
259  // * @url POST {id}/lines
260  // *
261  // * @return int
262  // */
263  /*
264  public function postLine($id, $request_data = null)
265  {
266  if(! DolibarrApiAccess::$user->rights->expedition->creer) {
267  throw new RestException(401);
268  }
269 
270  $result = $this->shipment->fetch($id);
271  if ( ! $result ) {
272  throw new RestException(404, 'Shipment not found');
273  }
274 
275  if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->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->label = sanitizeVal($request_data->label);
283 
284  $updateRes = $this->shipment->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->info_bits,
294  $request_data->fk_remise_except,
295  'HT',
296  0,
297  $request_data->date_start,
298  $request_data->date_end,
299  $request_data->product_type,
300  $request_data->rang,
301  $request_data->special_code,
302  $fk_parent_line,
303  $request_data->fk_fournprice,
304  $request_data->pa_ht,
305  $request_data->label,
306  $request_data->array_options,
307  $request_data->fk_unit,
308  $request_data->origin,
309  $request_data->origin_id,
310  $request_data->multicurrency_subprice
311  );
312 
313  if ($updateRes > 0) {
314  return $updateRes;
315 
316  }
317  return false;
318  }*/
319 
320  // /**
321  // * Update a line to given shipment
322  // *
323  // * @param int $id Id of shipment to update
324  // * @param int $lineid Id of line to update
325  // * @param array $request_data ShipmentLine data
326  // *
327  // * @url PUT {id}/lines/{lineid}
328  // *
329  // * @return object
330  // */
331  /*
332  public function putLine($id, $lineid, $request_data = null)
333  {
334  if (! DolibarrApiAccess::$user->rights->expedition->creer) {
335  throw new RestException(401);
336  }
337 
338  $result = $this->shipment->fetch($id);
339  if ( ! $result ) {
340  throw new RestException(404, 'Shipment not found');
341  }
342 
343  if( ! DolibarrApi::_checkAccessToResource('expedition',$this->shipment->id)) {
344  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
345  }
346 
347  $request_data = (object) $request_data;
348 
349  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
350  $request_data->label = sanitizeVal($request_data->label);
351 
352  $updateRes = $this->shipment->updateline(
353  $lineid,
354  $request_data->desc,
355  $request_data->subprice,
356  $request_data->qty,
357  $request_data->remise_percent,
358  $request_data->tva_tx,
359  $request_data->localtax1_tx,
360  $request_data->localtax2_tx,
361  'HT',
362  $request_data->info_bits,
363  $request_data->date_start,
364  $request_data->date_end,
365  $request_data->product_type,
366  $request_data->fk_parent_line,
367  0,
368  $request_data->fk_fournprice,
369  $request_data->pa_ht,
370  $request_data->label,
371  $request_data->special_code,
372  $request_data->array_options,
373  $request_data->fk_unit,
374  $request_data->multicurrency_subprice
375  );
376 
377  if ($updateRes > 0) {
378  $result = $this->get($id);
379  unset($result->line);
380  return $this->_cleanObjectDatas($result);
381  }
382  return false;
383  }*/
384 
399  public function deleteLine($id, $lineid)
400  {
401  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
402  throw new RestException(401);
403  }
404 
405  $result = $this->shipment->fetch($id);
406  if (!$result) {
407  throw new RestException(404, 'Shipment not found');
408  }
409 
410  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
411  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
412  }
413 
414  // TODO Check the lineid $lineid is a line of ojbect
415 
416  $updateRes = $this->shipment->deleteline(DolibarrApiAccess::$user, $lineid);
417  if ($updateRes > 0) {
418  return $this->get($id);
419  } else {
420  throw new RestException(405, $this->shipment->error);
421  }
422  }
423 
432  public function put($id, $request_data = null)
433  {
434  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
435  throw new RestException(401);
436  }
437 
438  $result = $this->shipment->fetch($id);
439  if (!$result) {
440  throw new RestException(404, 'Shipment not found');
441  }
442 
443  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
444  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
445  }
446  foreach ($request_data as $field => $value) {
447  if ($field == 'id') {
448  continue;
449  }
450  $this->shipment->$field = $value;
451  }
452 
453  if ($this->shipment->update(DolibarrApiAccess::$user) > 0) {
454  return $this->get($id);
455  } else {
456  throw new RestException(500, $this->shipment->error);
457  }
458  }
459 
467  public function delete($id)
468  {
469  if (!DolibarrApiAccess::$user->rights->expedition->supprimer) {
470  throw new RestException(401);
471  }
472  $result = $this->shipment->fetch($id);
473  if (!$result) {
474  throw new RestException(404, 'Shipment not found');
475  }
476 
477  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
478  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
479  }
480 
481  if (!$this->shipment->delete(DolibarrApiAccess::$user)) {
482  throw new RestException(500, 'Error when deleting shipment : '.$this->shipment->error);
483  }
484 
485  return array(
486  'success' => array(
487  'code' => 200,
488  'message' => 'Shipment deleted'
489  )
490  );
491  }
492 
512  public function validate($id, $notrigger = 0)
513  {
514  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
515  throw new RestException(401);
516  }
517  $result = $this->shipment->fetch($id);
518  if (!$result) {
519  throw new RestException(404, 'Shipment not found');
520  }
521 
522  if (!DolibarrApi::_checkAccessToResource('expedition', $this->shipment->id)) {
523  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
524  }
525 
526  $result = $this->shipment->valid(DolibarrApiAccess::$user, $notrigger);
527  if ($result == 0) {
528  throw new RestException(304, 'Error nothing done. May be object is already validated');
529  }
530  if ($result < 0) {
531  throw new RestException(500, 'Error when validating Shipment: '.$this->shipment->error);
532  }
533 
534  // Reload shipment
535  $result = $this->shipment->fetch($id);
536 
537  $this->shipment->fetchObjectLinked();
538  return $this->_cleanObjectDatas($this->shipment);
539  }
540 
541 
542  // /**
543  // * Classify the shipment as invoiced
544  // *
545  // * @param int $id Id of the shipment
546  // *
547  // * @url POST {id}/setinvoiced
548  // *
549  // * @return int
550  // *
551  // * @throws RestException 400
552  // * @throws RestException 401
553  // * @throws RestException 404
554  // * @throws RestException 405
555  // */
556  /*
557  public function setinvoiced($id)
558  {
559 
560  if(! DolibarrApiAccess::$user->rights->expedition->creer) {
561  throw new RestException(401);
562  }
563  if(empty($id)) {
564  throw new RestException(400, 'Shipment ID is mandatory');
565  }
566  $result = $this->shipment->fetch($id);
567  if( ! $result ) {
568  throw new RestException(404, 'Shipment not found');
569  }
570 
571  $result = $this->shipment->classifyBilled(DolibarrApiAccess::$user);
572  if( $result < 0) {
573  throw new RestException(400, $this->shipment->error);
574  }
575  return $result;
576  }
577  */
578 
579 
580  // /**
581  // * Create a shipment using an existing order.
582  // *
583  // * @param int $orderid Id of the order
584  // *
585  // * @url POST /createfromorder/{orderid}
586  // *
587  // * @return int
588  // * @throws RestException 400
589  // * @throws RestException 401
590  // * @throws RestException 404
591  // * @throws RestException 405
592  // */
593  /*
594  public function createShipmentFromOrder($orderid)
595  {
596 
597  require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
598 
599  if(! DolibarrApiAccess::$user->rights->expedition->lire) {
600  throw new RestException(401);
601  }
602  if(! DolibarrApiAccess::$user->rights->expedition->creer) {
603  throw new RestException(401);
604  }
605  if(empty($proposalid)) {
606  throw new RestException(400, 'Order ID is mandatory');
607  }
608 
609  $order = new Commande($this->db);
610  $result = $order->fetch($proposalid);
611  if( ! $result ) {
612  throw new RestException(404, 'Order not found');
613  }
614 
615  $result = $this->shipment->createFromOrder($order, DolibarrApiAccess::$user);
616  if( $result < 0) {
617  throw new RestException(405, $this->shipment->error);
618  }
619  $this->shipment->fetchObjectLinked();
620  return $this->_cleanObjectDatas($this->shipment);
621  }
622  */
623 
634  public function close($id, $notrigger = 0)
635  {
636  if (!DolibarrApiAccess::$user->rights->expedition->creer) {
637  throw new RestException(401);
638  }
639 
640  $result = $this->shipment->fetch($id);
641  if (!$result) {
642  throw new RestException(404, 'Shipment not found');
643  }
644 
645  if (!DolibarrApi::_checkAccessToResource('expedition', $this->commande->id)) {
646  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
647  }
648 
649  $result = $this->shipment->setClosed();
650  if ($result == 0) {
651  throw new RestException(304, 'Error nothing done. May be object is already closed');
652  }
653  if ($result < 0) {
654  throw new RestException(500, 'Error when closing Order: '.$this->commande->error);
655  }
656 
657  // Reload shipment
658  $result = $this->shipment->fetch($id);
659 
660  $this->shipment->fetchObjectLinked();
661 
662  return $this->_cleanObjectDatas($this->shipment);
663  }
664 
665  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
672  protected function _cleanObjectDatas($object)
673  {
674  // phpcs:enable
675  $object = parent::_cleanObjectDatas($object);
676 
677  unset($object->thirdparty); // id already returned
678 
679  unset($object->note);
680  unset($object->address);
681  unset($object->barcode_type);
682  unset($object->barcode_type_code);
683  unset($object->barcode_type_label);
684  unset($object->barcode_type_coder);
685 
686  if (!empty($object->lines) && is_array($object->lines)) {
687  foreach ($object->lines as $line) {
688  if (is_array($line->detail_batch)) {
689  foreach ($line->detail_batch as $keytmp2 => $valtmp2) {
690  unset($line->detail_batch[$keytmp2]->db);
691  }
692  }
693  unset($line->tva_tx);
694  unset($line->vat_src_code);
695  unset($line->total_ht);
696  unset($line->total_ttc);
697  unset($line->total_tva);
698  unset($line->total_localtax1);
699  unset($line->total_localtax2);
700  unset($line->remise_percent);
701  }
702  }
703 
704  return $object;
705  }
706 
714  private function _validate($data)
715  {
716  $shipment = array();
717  foreach (Shipments::$FIELDS as $field) {
718  if (!isset($data[$field])) {
719  throw new RestException(400, "$field field missing");
720  }
721  $shipment[$field] = $data[$field];
722  }
723  return $shipment;
724  }
725 }
Class for API REST v1.
Definition: api.class.php:31
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
Class to manage shipments.
close($id, $notrigger=0)
Close a shipment (Classify it as "Delivered")
_validate($data)
Validate fields before create or update object.
put($id, $request_data=null)
Update shipment general fields (won't touch lines of shipment)
validate($id, $notrigger=0)
Validate a shipment.
__construct()
Constructor.
post($request_data=null)
Create shipment object.
_cleanObjectDatas($object)
Clean sensible object datas.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $sqlfilters='')
List shipments.
deleteLine($id, $lineid)
Delete a line to given shipment.
if(isModEnabled('facture') && $user->hasRight('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
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.