dolibarr  21.0.0-alpha
api_receptions.class.php
1 <?php
2 /* Copyright (C) 2022 Quatadah Nasdami <quatadah.nasdami@gmail.com>
3  * Copyright (C) 2022 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.'/reception/class/reception.class.php';
22 require_once DOL_DOCUMENT_ROOT.'/reception/class/receptionlinebatch.class.php';
23 
30 class Receptions extends DolibarrApi
31 {
35  public static $FIELDS = array(
36  'socid',
37  'origin_id',
38  'origin_type',
39  );
40 
44  public $reception;
45 
49  public function __construct()
50  {
51  global $db, $conf;
52  $this->db = $db;
53  $this->reception = new Reception($this->db);
54  }
55 
65  public function get($id)
66  {
67  if (!DolibarrApiAccess::$user->hasRight('reception', 'lire')) {
68  throw new RestException(403);
69  }
70 
71  $result = $this->reception->fetch($id);
72  if (!$result) {
73  throw new RestException(404, 'Reception not found');
74  }
75 
76  if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) {
77  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
78  }
79 
80  $this->reception->fetchObjectLinked();
81  return $this->_cleanObjectDatas($this->reception);
82  }
83 
84 
85 
102  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '', $properties = '')
103  {
104  if (!DolibarrApiAccess::$user->hasRight('reception', 'lire')) {
105  throw new RestException(403);
106  }
107 
108  $obj_ret = array();
109 
110  // case of external user, $thirdparty_ids param is ignored and replaced by user's socid
111  $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids;
112 
113  // If the internal user must only see his customers, force searching by him
114  $search_sale = 0;
115  if (!DolibarrApiAccess::$user->hasRight('societe', 'client', 'voir') && !$socids) {
116  $search_sale = DolibarrApiAccess::$user->id;
117  }
118 
119  $sql = "SELECT t.rowid";
120  $sql .= " FROM ".MAIN_DB_PREFIX."reception AS t";
121  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."reception_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
122  $sql .= ' WHERE t.entity IN ('.getEntity('reception').')';
123  if ($socids) {
124  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
125  }
126  // Search on sale representative
127  if ($search_sale && $search_sale != '-1') {
128  if ($search_sale == -2) {
129  $sql .= " AND NOT EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc)";
130  } elseif ($search_sale > 0) {
131  $sql .= " AND EXISTS (SELECT sc.fk_soc FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc WHERE sc.fk_soc = t.fk_soc AND sc.fk_user = ".((int) $search_sale).")";
132  }
133  }
134  // Add sql filters
135  if ($sqlfilters) {
136  $errormessage = '';
137  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
138  if ($errormessage) {
139  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
140  }
141  }
142 
143  $sql .= $this->db->order($sortfield, $sortorder);
144  if ($limit) {
145  if ($page < 0) {
146  $page = 0;
147  }
148  $offset = $limit * $page;
149 
150  $sql .= $this->db->plimit($limit + 1, $offset);
151  }
152 
153  dol_syslog("API Rest request");
154  $result = $this->db->query($sql);
155 
156  if ($result) {
157  $num = $this->db->num_rows($result);
158  $min = min($num, ($limit <= 0 ? $num : $limit));
159  $i = 0;
160  while ($i < $min) {
161  $obj = $this->db->fetch_object($result);
162  $reception_static = new Reception($this->db);
163  if ($reception_static->fetch($obj->rowid)) {
164  $obj_ret[] = $this->_filterObjectProperties($this->_cleanObjectDatas($reception_static), $properties);
165  }
166  $i++;
167  }
168  } else {
169  throw new RestException(503, 'Error when retrieve commande list : '.$this->db->lasterror());
170  }
171 
172  return $obj_ret;
173  }
174 
181  public function post($request_data = null)
182  {
183  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
184  throw new RestException(403, "Insuffisant rights");
185  }
186  // Check mandatory fields
187  $result = $this->_validate($request_data);
188 
189  foreach ($request_data as $field => $value) {
190  if ($field === 'caller') {
191  // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
192  $this->reception->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
193  continue;
194  }
195 
196  $this->reception->$field = $this->_checkValForAPI($field, $value, $this->reception);
197  }
198  if (isset($request_data["lines"])) {
199  $lines = array();
200  foreach ($request_data["lines"] as $line) {
201  $receptionline = new ReceptionLineBatch($this->db);
202 
203  $receptionline->fk_product = $line['fk_product'];
204  $receptionline->fk_entrepot = $line['fk_entrepot'];
205  $receptionline->fk_element = $line['fk_element'] ?? $line['origin_id']; // example: purchase order id. this->origin is 'supplier_order'
206  $receptionline->origin_line_id = $line['fk_elementdet'] ?? $line['origin_line_id']; // example: purchase order id
207  $receptionline->fk_elementdet = $line['fk_elementdet'] ?? $line['origin_line_id']; // example: purchase order line id
208  $receptionline->origin_type = $line['element_type'] ?? $line['origin_type']; // example 'supplier_order'
209  $receptionline->element_type = $line['element_type'] ?? $line['origin_type']; // example 'supplier_order'
210  $receptionline->qty = $line['qty'];
211  //$receptionline->rang = $line['rang'];
212  $receptionline->array_options = $line['array_options'];
213  $receptionline->batch = $line['batch'];
214  $receptionline->eatby = $line['eatby'];
215  $receptionline->sellby = $line['sellby'];
216  $receptionline->cost_price = $line['cost_price'];
217  $receptionline->status = $line['status'];
218 
219  $lines[] = $receptionline;
220  }
221  $this->reception->lines = $lines;
222  }
223 
224  if ($this->reception->create(DolibarrApiAccess::$user) < 0) {
225  throw new RestException(500, "Error creating reception", array_merge(array($this->reception->error), $this->reception->errors));
226  }
227 
228  return $this->reception->id;
229  }
230 
231  // /**
232  // * Get lines of an reception
233  // *
234  // * @param int $id Id of reception
235  // *
236  // * @url GET {id}/lines
237  // *
238  // * @return int
239  // */
240  /*
241  public function getLines($id)
242  {
243  if (!DolibarrApiAccess::$user->hasRight('reception', 'lire')) {
244  throw new RestException(403);
245  }
246 
247  $result = $this->reception->fetch($id);
248  if (! $result) {
249  throw new RestException(404, 'Reception not found');
250  }
251 
252  if (!DolibarrApi::_checkAccessToResource('reception',$this->reception->id)) {
253  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
254  }
255  $this->reception->getLinesArray();
256  $result = array();
257  foreach ($this->reception->lines as $line) {
258  array_push($result,$this->_cleanObjectDatas($line));
259  }
260  return $result;
261  }
262  */
263 
264  // /**
265  // * Add a line to given reception
266  // *
267  // * @param int $id Id of reception to update
268  // * @param array $request_data ShipmentLine data
269  // *
270  // * @url POST {id}/lines
271  // *
272  // * @return int
273  // */
274  /*
275  public function postLine($id, $request_data = null)
276  {
277  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
278  throw new RestException(403);
279  }
280 
281  $result = $this->reception->fetch($id);
282  if (! $result) {
283  throw new RestException(404, 'Reception not found');
284  }
285 
286  if (!DolibarrApi::_checkAccessToResource('reception',$this->reception->id)) {
287  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
288  }
289 
290  $request_data = (object) $request_data;
291 
292  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
293  $request_data->label = sanitizeVal($request_data->label);
294 
295  $updateRes = $this->reception->addline(
296  $request_data->desc,
297  $request_data->subprice,
298  $request_data->qty,
299  $request_data->tva_tx,
300  $request_data->localtax1_tx,
301  $request_data->localtax2_tx,
302  $request_data->fk_product,
303  $request_data->remise_percent,
304  $request_data->info_bits,
305  $request_data->fk_remise_except,
306  'HT',
307  0,
308  $request_data->date_start,
309  $request_data->date_end,
310  $request_data->product_type,
311  $request_data->rang,
312  $request_data->special_code,
313  $fk_parent_line,
314  $request_data->fk_fournprice,
315  $request_data->pa_ht,
316  $request_data->label,
317  $request_data->array_options,
318  $request_data->fk_unit,
319  $request_data->origin,
320  $request_data->origin_id,
321  $request_data->multicurrency_subprice
322  );
323 
324  if ($updateRes > 0) {
325  return $updateRes;
326 
327  }
328  return false;
329  }*/
330 
331  // /**
332  // * Update a line to given reception
333  // *
334  // * @param int $id Id of reception to update
335  // * @param int $lineid Id of line to update
336  // * @param array $request_data ShipmentLine data
337  // *
338  // * @url PUT {id}/lines/{lineid}
339  // *
340  // * @return object
341  // */
342  /*
343  public function putLine($id, $lineid, $request_data = null)
344  {
345  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
346  throw new RestException(403);
347  }
348 
349  $result = $this->reception->fetch($id);
350  if (! $result) {
351  throw new RestException(404, 'Reception not found');
352  }
353 
354  if (!DolibarrApi::_checkAccessToResource('reception',$this->reception->id)) {
355  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
356  }
357 
358  $request_data = (object) $request_data;
359 
360  $request_data->desc = sanitizeVal($request_data->desc, 'restricthtml');
361  $request_data->label = sanitizeVal($request_data->label);
362 
363  $updateRes = $this->reception->updateline(
364  $lineid,
365  $request_data->desc,
366  $request_data->subprice,
367  $request_data->qty,
368  $request_data->remise_percent,
369  $request_data->tva_tx,
370  $request_data->localtax1_tx,
371  $request_data->localtax2_tx,
372  'HT',
373  $request_data->info_bits,
374  $request_data->date_start,
375  $request_data->date_end,
376  $request_data->product_type,
377  $request_data->fk_parent_line,
378  0,
379  $request_data->fk_fournprice,
380  $request_data->pa_ht,
381  $request_data->label,
382  $request_data->special_code,
383  $request_data->array_options,
384  $request_data->fk_unit,
385  $request_data->multicurrency_subprice
386  );
387 
388  if ($updateRes > 0) {
389  $result = $this->get($id);
390  unset($result->line);
391  return $this->_cleanObjectDatas($result);
392  }
393  return false;
394  }*/
395 
408  public function deleteLine($id, $lineid)
409  {
410  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
411  throw new RestException(403);
412  }
413 
414  $result = $this->reception->fetch($id);
415  if (!$result) {
416  throw new RestException(404, 'Reception not found');
417  }
418 
419  if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) {
420  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
421  }
422 
423  // TODO Check the lineid $lineid is a line of object
424 
425  $updateRes = $this->reception->deleteLine(DolibarrApiAccess::$user, $lineid);
426  if ($updateRes < 0) {
427  throw new RestException(405, $this->reception->error);
428  }
429 
430  return array(
431  'success' => array(
432  'code' => 200,
433  'message' => 'Line deleted'
434  )
435  );
436  }
437 
445  public function put($id, $request_data = null)
446  {
447  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
448  throw new RestException(403);
449  }
450 
451  $result = $this->reception->fetch($id);
452  if (!$result) {
453  throw new RestException(404, 'Reception not found');
454  }
455 
456  if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) {
457  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
458  }
459  foreach ($request_data as $field => $value) {
460  if ($field == 'id') {
461  continue;
462  }
463  if ($field === 'caller') {
464  // Add a mention of caller so on trigger called after action, we can filter to avoid a loop if we try to sync back again with the caller
465  $this->reception->context['caller'] = sanitizeVal($request_data['caller'], 'aZ09');
466  continue;
467  }
468 
469  $this->reception->$field = $this->_checkValForAPI($field, $value, $this->reception);
470  }
471 
472  if ($this->reception->update(DolibarrApiAccess::$user) > 0) {
473  return $this->get($id);
474  } else {
475  throw new RestException(500, $this->reception->error);
476  }
477  }
478 
485  public function delete($id)
486  {
487  if (!DolibarrApiAccess::$user->hasRight('reception', 'supprimer')) {
488  throw new RestException(403);
489  }
490  $result = $this->reception->fetch($id);
491  if (!$result) {
492  throw new RestException(404, 'Reception not found');
493  }
494 
495  if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) {
496  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
497  }
498 
499  if (!$this->reception->delete(DolibarrApiAccess::$user)) {
500  throw new RestException(500, 'Error when deleting reception : '.$this->reception->error);
501  }
502 
503  return array(
504  'success' => array(
505  'code' => 200,
506  'message' => 'Reception deleted'
507  )
508  );
509  }
510 
530  public function validate($id, $notrigger = 0)
531  {
532  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
533  throw new RestException(403);
534  }
535  $result = $this->reception->fetch($id);
536  if (!$result) {
537  throw new RestException(404, 'Reception not found');
538  }
539 
540  if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) {
541  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
542  }
543 
544  $result = $this->reception->valid(DolibarrApiAccess::$user, $notrigger);
545  if ($result == 0) {
546  throw new RestException(304, 'Error nothing done. May be object is already validated');
547  }
548  if ($result < 0) {
549  throw new RestException(500, 'Error when validating Reception: '.$this->reception->error);
550  }
551 
552  // Reload reception
553  $result = $this->reception->fetch($id);
554 
555  $this->reception->fetchObjectLinked();
556  return $this->_cleanObjectDatas($this->reception);
557  }
558 
559 
560  // /**
561  // * Classify the reception as invoiced
562  // *
563  // * @param int $id Id of the reception
564  // *
565  // * @url POST {id}/setinvoiced
566  // *
567  // * @return int
568  // *
569  // * @throws RestException 400
570  // * @throws RestException 401
571  // * @throws RestException 404
572  // * @throws RestException 405
573  // */
574  /*
575  public function setinvoiced($id)
576  {
577 
578  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
579  throw new RestException(403);
580  }
581  if (empty($id)) {
582  throw new RestException(400, 'Reception ID is mandatory');
583  }
584  $result = $this->reception->fetch($id);
585  if (!$result) {
586  throw new RestException(404, 'Reception not found');
587  }
588 
589  $result = $this->reception->classifyBilled(DolibarrApiAccess::$user);
590  if ($result < 0) {
591  throw new RestException(400, $this->reception->error);
592  }
593  return $result;
594  }
595  */
596 
597 
598  // /**
599  // * Create a reception using an existing order.
600  // *
601  // * @param int $orderid Id of the order
602  // *
603  // * @url POST /createfromorder/{orderid}
604  // *
605  // * @return int
606  // * @throws RestException 400
607  // * @throws RestException 401
608  // * @throws RestException 404
609  // * @throws RestException 405
610  // */
611  /*
612  public function createShipmentFromOrder($orderid)
613  {
614 
615  require_once DOL_DOCUMENT_ROOT . '/commande/class/commande.class.php';
616 
617  if (!DolibarrApiAccess::$user->hasRight('reception', 'lire')) {
618  throw new RestException(403);
619  }
620  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
621  throw new RestException(403);
622  }
623  if (empty($proposalid)) {
624  throw new RestException(400, 'Order ID is mandatory');
625  }
626 
627  $order = new Commande($this->db);
628  $result = $order->fetch($proposalid);
629  if (!$result) {
630  throw new RestException(404, 'Order not found');
631  }
632 
633  $result = $this->reception->createFromOrder($order, DolibarrApiAccess::$user);
634  if( $result < 0) {
635  throw new RestException(405, $this->reception->error);
636  }
637  $this->reception->fetchObjectLinked();
638  return $this->_cleanObjectDatas($this->reception);
639  }
640  */
641 
652  public function close($id, $notrigger = 0)
653  {
654  if (!DolibarrApiAccess::$user->hasRight('reception', 'creer')) {
655  throw new RestException(403);
656  }
657 
658  $result = $this->reception->fetch($id);
659  if (!$result) {
660  throw new RestException(404, 'Reception not found');
661  }
662 
663  if (!DolibarrApi::_checkAccessToResource('reception', $this->reception->id)) {
664  throw new RestException(403, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
665  }
666 
667  $result = $this->reception->setClosed();
668  if ($result == 0) {
669  throw new RestException(304, 'Error nothing done. May be object is already closed');
670  }
671  if ($result < 0) {
672  throw new RestException(500, 'Error when closing Reception: '.$this->reception->error);
673  }
674 
675  // Reload reception
676  $result = $this->reception->fetch($id);
677 
678  $this->reception->fetchObjectLinked();
679 
680  return $this->_cleanObjectDatas($this->reception);
681  }
682 
683  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
690  protected function _cleanObjectDatas($object)
691  {
692  // phpcs:enable
693  $object = parent::_cleanObjectDatas($object);
694 
695  unset($object->thirdparty); // id already returned
696 
697  unset($object->note);
698  unset($object->address);
699  unset($object->barcode_type);
700  unset($object->barcode_type_code);
701  unset($object->barcode_type_label);
702  unset($object->barcode_type_coder);
703 
704  if (!empty($object->lines) && is_array($object->lines)) {
705  foreach ($object->lines as $line) {
706  unset($line->canvas);
707 
708  unset($line->tva_tx);
709  unset($line->vat_src_code);
710  unset($line->total_ht);
711  unset($line->total_ttc);
712  unset($line->total_tva);
713  unset($line->total_localtax1);
714  unset($line->total_localtax2);
715  unset($line->remise_percent);
716  }
717  }
718 
719  return $object;
720  }
721 
729  private function _validate($data)
730  {
731  $reception = array();
732  foreach (Receptions::$FIELDS as $field) {
733  if (!isset($data[$field])) {
734  throw new RestException(400, "$field field missing");
735  }
736  $reception[$field] = $data[$field];
737  }
738  return $reception;
739  }
740 }
if($user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition: card.php:58
Class for API REST v1.
Definition: api.class.php:30
_filterObjectProperties($object, $properties)
Filter properties that will be returned on object.
Definition: api.class.php:136
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:369
_checkValForAPI($field, $value, $object)
Check and convert a string depending on its type/name.
Definition: api.class.php:82
Class to manage receptions.
Class to manage table commandefournisseurdispatch.
close($id, $notrigger=0)
Close a reception (Classify it as "Delivered")
validate($id, $notrigger=0)
Validate a reception.
post($request_data=null)
Create reception object.
deleteLine($id, $lineid)
Delete a line to given reception.
_cleanObjectDatas($object)
Clean sensible object datas.
__construct()
Constructor.
_validate($data)
Validate fields before create or update object.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $sqlfilters='', $properties='')
List receptions.
put($id, $request_data=null)
Update reception general fields (won't touch lines of reception)
if(isModEnabled('invoice') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&!getDolGlobalString('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') && $user->hasRight('tax', 'charges', 'lire')) if(isModEnabled('invoice') &&isModEnabled('order') && $user->hasRight("commande", "lire") &&!getDolGlobalString('WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER')) $sql
Social contributions to pay.
Definition: index.php:751
forgeSQLFromUniversalSearchCriteria($filter, &$errorstr='', $noand=0, $nopar=0, $noerror=0)
forgeSQLFromUniversalSearchCriteria
sanitizeVal($out='', $check='alphanohtml', $filter=null, $options=null)
Return a sanitized or empty value after checking value against a rule.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.