dolibarr  18.0.6
api_supplier_orders.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.'/fourn/class/fournisseur.commande.class.php';
22 
30 {
35  public static $FIELDS = array(
36  'socid'
37  );
38 
42  public $order;
43 
47  public function __construct()
48  {
49  global $db, $conf;
50  $this->db = $db;
51  $this->order = new CommandeFournisseur($this->db);
52  }
53 
64  public function get($id)
65  {
66  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "lire")) {
67  throw new RestException(401);
68  }
69 
70  $result = $this->order->fetch($id);
71  if (!$result) {
72  throw new RestException(404, 'Supplier order not found');
73  }
74 
75  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
76  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
77  }
78 
79  $this->order->fetchObjectLinked();
80  return $this->_cleanObjectDatas($this->order);
81  }
82 
101  public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $product_ids = '', $status = '', $sqlfilters = '', $sqlfilterlines = '')
102  {
103  global $db, $conf;
104 
105  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "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->hasRight("societe", "client", "voir") && !$socids) {
117  $search_sale = DolibarrApiAccess::$user->id;
118  }
119 
120  $sql = "SELECT t.rowid";
121  if ((!DolibarrApiAccess::$user->hasRight("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."commande_fournisseur AS t LEFT JOIN ".MAIN_DB_PREFIX."commande_fournisseur_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
125 
126  if ((!DolibarrApiAccess::$user->hasRight("societe", "client", "voir") && !$socids) || $search_sale > 0) {
127  $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale
128  }
129 
130  if (!empty($product_ids)) {
131  $sql .= ", ".MAIN_DB_PREFIX."commande_fournisseurdet as cd"; // We need this table joined to the select in order to filter by product
132  }
133 
134  $sql .= ' WHERE t.entity IN ('.getEntity('supplier_order').')';
135  if ((!DolibarrApiAccess::$user->hasRight("societe", "client", "voir") && !$socids) || $search_sale > 0) {
136  $sql .= " AND t.fk_soc = sc.fk_soc";
137  }
138  if (!empty($product_ids)) {
139  $sql .= " AND cd.fk_commande = t.rowid AND cd.fk_product IN (".$this->db->sanitize($product_ids).")";
140  }
141  if ($socids) {
142  $sql .= " AND t.fk_soc IN (".$this->db->sanitize($socids).")";
143  }
144  if ($search_sale > 0) {
145  $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
146  }
147 
148  // Filter by status
149  if ($status == 'draft') {
150  $sql .= " AND t.fk_statut IN (0)";
151  }
152  if ($status == 'validated') {
153  $sql .= " AND t.fk_statut IN (1)";
154  }
155  if ($status == 'approved') {
156  $sql .= " AND t.fk_statut IN (2)";
157  }
158  if ($status == 'running') {
159  $sql .= " AND t.fk_statut IN (3)";
160  }
161  if ($status == 'received_start') {
162  $sql .= " AND t.fk_statut IN (4)";
163  }
164  if ($status == 'received_end') {
165  $sql .= " AND t.fk_statut IN (5)";
166  }
167  if ($status == 'cancelled') {
168  $sql .= " AND t.fk_statut IN (6,7)";
169  }
170  if ($status == 'refused') {
171  $sql .= " AND t.fk_statut IN (9)";
172  }
173  // Insert sale filter
174  if ($search_sale > 0) {
175  $sql .= " AND sc.fk_user = ".((int) $search_sale);
176  }
177  // Add sql filters
178  if ($sqlfilters) {
179  $errormessage = '';
180  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage);
181  if ($errormessage) {
182  throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage);
183  }
184  }
185  // Add sql filters for lines
186  if ($sqlfilterlines) {
187  $errormessage = '';
188  $sql .= " AND EXISTS (SELECT tl.rowid FROM ".MAIN_DB_PREFIX."commande_fournisseurdet AS tl WHERE tl.fk_commande = t.rowid";
189  $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilterlines, $errormessage);
190  $sql .= ")";
191  if ($errormessage) {
192  throw new RestException(400, 'Error when validating parameter sqlfilterlines -> '.$errormessage);
193  }
194  }
195 
196  $sql .= $this->db->order($sortfield, $sortorder);
197  if ($limit) {
198  if ($page < 0) {
199  $page = 0;
200  }
201  $offset = $limit * $page;
202 
203  $sql .= $this->db->plimit($limit + 1, $offset);
204  }
205 
206  $result = $this->db->query($sql);
207  if ($result) {
208  $i = 0;
209  $num = $this->db->num_rows($result);
210  $min = min($num, ($limit <= 0 ? $num : $limit));
211  while ($i < $min) {
212  $obj = $this->db->fetch_object($result);
213  $order_static = new CommandeFournisseur($this->db);
214  if ($order_static->fetch($obj->rowid)) {
215  $obj_ret[] = $this->_cleanObjectDatas($order_static);
216  }
217  $i++;
218  }
219  } else {
220  throw new RestException(503, 'Error when retrieve supplier order list : '.$this->db->lasterror());
221  }
222  if (!count($obj_ret)) {
223  throw new RestException(404, 'No supplier order found');
224  }
225  return $obj_ret;
226  }
227 
236  public function post($request_data = null)
237  {
238  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) {
239  throw new RestException(401, "Insuffisant rights");
240  }
241  // Check mandatory fields
242  $result = $this->_validate($request_data);
243 
244  foreach ($request_data as $field => $value) {
245  $this->order->$field = $value;
246  }
247  if (!array_keys($request_data, 'date')) {
248  $this->order->date = dol_now();
249  }
250  /* We keep lines as an array
251  if (isset($request_data["lines"])) {
252  $lines = array();
253  foreach ($request_data["lines"] as $line) {
254  array_push($lines, (object) $line);
255  }
256  $this->order->lines = $lines;
257  }*/
258 
259  if ($this->order->create(DolibarrApiAccess::$user) < 0) {
260  throw new RestException(500, "Error creating order", array_merge(array($this->order->error), $this->order->errors));
261  }
262  return $this->order->id;
263  }
264 
272  public function put($id, $request_data = null)
273  {
274  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) {
275  throw new RestException(401);
276  }
277 
278  $result = $this->order->fetch($id);
279  if (!$result) {
280  throw new RestException(404, 'Supplier order not found');
281  }
282 
283  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
284  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
285  }
286 
287  foreach ($request_data as $field => $value) {
288  if ($field == 'id') {
289  continue;
290  }
291  $this->order->$field = $value;
292  }
293 
294  if ($this->order->update(DolibarrApiAccess::$user)) {
295  return $this->get($id);
296  }
297 
298  return false;
299  }
300 
315  public function getContacts($id, $source, $type = '')
316  {
317  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "lire")) {
318  throw new RestException(401);
319  }
320 
321  $result = $this->order->fetch($id);
322  if (!$result) {
323  throw new RestException(404, 'Supplier order not found');
324  }
325 
326  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
327  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
328  }
329  $contacts = array();
330 
331  if ($source == 'all' || $source == 'external') {
332  $tmpContacts = $this->order->liste_contact(-1, 'external', 0, $type);
333  $contacts = array_merge($contacts, $tmpContacts);
334  }
335 
336  if ($source == 'all' || $source == 'internal') {
337  $tmpContacts = $this->order->liste_contact(-1, 'internal', 0, $type);
338  $contacts = array_merge($contacts, $tmpContacts);
339  }
340 
341  return $this->_cleanObjectDatas($contacts);
342  }
343 
358  public function postContact($id, $contactid, $type, $source)
359  {
360  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer")) {
361  throw new RestException(401);
362  }
363 
364  $result = $this->order->fetch($id);
365  if (!$result) {
366  throw new RestException(404, 'Supplier order not found');
367  }
368 
369  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
370  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
371  }
372 
373  $result = $this->order->add_contact($contactid, $type, $source);
374 
375  if ($result < 0) {
376  throw new RestException(500, 'Error when added the contact');
377  }
378 
379  if ($result == 0) {
380  throw new RestException(304, 'contact already added');
381  }
382 
383  return array(
384  'success' => array(
385  'code' => 200,
386  'message' => 'Contact linked to the order'
387  )
388  );
389  }
390 
407  public function deleteContact($id, $contactid, $type, $source)
408  {
409  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer")) {
410  throw new RestException(401);
411  }
412 
413  $result = $this->order->fetch($id);
414  if (!$result) {
415  throw new RestException(404, 'Supplier order not found');
416  }
417 
418  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
419  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
420  }
421 
422  $contacts = $this->order->liste_contact(-1, $source, 0, $type);
423 
424  $contactToUnlink = 0;
425  foreach ($contacts as $contact) {
426  if ($contact['id'] == $contactid && $contact['code'] == $type) {
427  $contactToUnlink = $contact['rowid'];
428  break;
429  }
430  }
431 
432  if ($contactToUnlink == 0) {
433  throw new RestException(404, 'Linked contact not found');
434  }
435 
436  $result = $this->order->delete_contact($contact['rowid']);
437 
438  if (!$result) {
439  throw new RestException(500, 'Error when deleted the contact');
440  }
441 
442  return array(
443  'success' => array(
444  'code' => 200,
445  'message' => 'Contact unlinked from supplier order'
446  )
447  );
448  }
449 
456  public function delete($id)
457  {
458  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "supprimer")) {
459  throw new RestException(401);
460  }
461  $result = $this->order->fetch($id);
462  if (!$result) {
463  throw new RestException(404, 'Supplier order not found');
464  }
465 
466  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
467  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
468  }
469 
470  if ($this->order->delete(DolibarrApiAccess::$user) < 0) {
471  throw new RestException(500, 'Error when deleting order');
472  }
473 
474  return array(
475  'success' => array(
476  'code' => 200,
477  'message' => 'Supplier order deleted'
478  )
479  );
480  }
481 
482 
501  public function validate($id, $idwarehouse = 0, $notrigger = 0)
502  {
503  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) {
504  throw new RestException(401);
505  }
506  $result = $this->order->fetch($id);
507  if (!$result) {
508  throw new RestException(404, 'Order not found');
509  }
510 
511  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
512  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
513  }
514 
515  $result = $this->order->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger);
516  if ($result == 0) {
517  throw new RestException(304, 'Error nothing done. May be object is already validated');
518  }
519  if ($result < 0) {
520  throw new RestException(500, 'Error when validating Order: '.$this->order->error);
521  }
522 
523  return array(
524  'success' => array(
525  'code' => 200,
526  'message' => 'Order validated (Ref='.$this->order->ref.')'
527  )
528  );
529  }
530 
549  public function approve($id, $idwarehouse = 0, $secondlevel = 0)
550  {
551  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) {
552  throw new RestException(401);
553  }
554  $result = $this->order->fetch($id);
555  if (!$result) {
556  throw new RestException(404, 'Order not found');
557  }
558 
559  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
560  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
561  }
562 
563  $result = $this->order->approve(DolibarrApiAccess::$user, $idwarehouse, $secondlevel);
564  if ($result == 0) {
565  throw new RestException(304, 'Error nothing done. May be object is already approved');
566  }
567  if ($result < 0) {
568  throw new RestException(500, 'Error when approve Order: '.$this->order->error);
569  }
570 
571  return array(
572  'success' => array(
573  'code' => 200,
574  'message' => 'Order approved (Ref='.$this->order->ref.')'
575  )
576  );
577  }
578 
579 
600  public function makeOrder($id, $date, $method, $comment = '')
601  {
602  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) {
603  throw new RestException(401);
604  }
605  $result = $this->order->fetch($id);
606  if (!$result) {
607  throw new RestException(404, 'Order not found');
608  }
609 
610  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
611  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
612  }
613 
614  $result = $this->order->commande(DolibarrApiAccess::$user, $date, $method, $comment);
615  if ($result == 0) {
616  throw new RestException(304, 'Error nothing done. May be object is already sent');
617  }
618  if ($result < 0) {
619  throw new RestException(500, 'Error when sending Order: '.$this->order->error);
620  }
621 
622  return array(
623  'success' => array(
624  'code' => 200,
625  'message' => 'Order sent (Ref='.$this->order->ref.')'
626  )
627  );
628  }
629 
663  public function receiveOrder($id, $closeopenorder, $comment, $lines)
664  {
665  if (!DolibarrApiAccess::$user->hasRight("fournisseur", "commande", "creer") && !DolibarrApiAccess::$user->hasRight("supplier_order", "creer")) {
666  throw new RestException(401);
667  }
668  $result = $this->order->fetch($id);
669  if (!$result) {
670  throw new RestException(404, 'Order not found');
671  }
672 
673  if (!DolibarrApi::_checkAccessToResource('fournisseur', $this->order->id, 'commande_fournisseur', 'commande')) {
674  throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
675  }
676 
677  foreach ($lines as $line) {
678  $lineObj =(object) $line;
679 
680  $result=$this->order->dispatchProduct(DolibarrApiAccess::$user,
681  $lineObj->fk_product,
682  $lineObj->qty,
683  $lineObj->warehouse,
684  $lineObj->price,
685  $lineObj->comment,
686  $lineObj->eatby,
687  $lineObj->sellby,
688  $lineObj->batch,
689  $lineObj->id,
690  $lineObj->notrigger);
691 
692  if ($result < 0) {
693  throw new RestException(500, 'Error dispatch order line '.$line->id.': '.$this->order->error);
694  }
695  }
696 
697  $result = $this->order->calcAndSetStatusDispatch(DolibarrApiAccess::$user, $closeopenorder, $comment);
698 
699  if ($result == 0) {
700  throw new RestException(304, 'Error nothing done. May be object is already dispatched');
701  }
702  if ($result < 0) {
703  throw new RestException(500, 'Error when receivce order: '.$this->order->error);
704  }
705 
706  return array(
707  'success' => array(
708  'code' => 200,
709  'message' => 'Order received (Ref='.$this->order->ref.')'
710  )
711  );
712  }
713 
714  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
721  protected function _cleanObjectDatas($object)
722  {
723  // phpcs:enable
724  $object = parent::_cleanObjectDatas($object);
725 
726  unset($object->rowid);
727  unset($object->barcode_type);
728  unset($object->barcode_type_code);
729  unset($object->barcode_type_label);
730  unset($object->barcode_type_coder);
731 
732  return $object;
733  }
734 
743  private function _validate($data)
744  {
745  $order = array();
746  foreach (SupplierOrders::$FIELDS as $field) {
747  if (!isset($data[$field])) {
748  throw new RestException(400, "$field field missing");
749  }
750  $order[$field] = $data[$field];
751  }
752  return $order;
753  }
754 }
Class to manage predefined suppliers products.
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
validate($id, $idwarehouse=0, $notrigger=0)
Validate an order.
index($sortfield="t.rowid", $sortorder='ASC', $limit=100, $page=0, $thirdparty_ids='', $product_ids='', $status='', $sqlfilters='', $sqlfilterlines='')
List orders.
put($id, $request_data=null)
Update supplier order.
post($request_data=null)
Create supplier order object.
_cleanObjectDatas($object)
Clean sensible object datas.
deleteContact($id, $contactid, $type, $source)
Unlink a contact type of given supplier order.
makeOrder($id, $date, $method, $comment='')
Sends an order to the vendor.
postContact($id, $contactid, $type, $source)
Add a contact type of given supplier order.
getContacts($id, $source, $type='')
Get contacts of given supplier order.
_validate($data)
Validate fields before create or update object.
approve($id, $idwarehouse=0, $secondlevel=0)
Approve an order.
receiveOrder($id, $closeopenorder, $comment, $lines)
Receives the order, dispatches products.
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_now($mode='auto')
Return date for now.