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 19use Luracast\Restler\RestException; 20 21require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; 22 23/** 24 * API class for orders 25 * 26 * @access protected 27 * @class DolibarrApiAccess {@requires user,external} 28 */ 29class Orders extends DolibarrApi 30{ 31 32 /** 33 * @var array $FIELDS Mandatory fields, checked when create and update object 34 */ 35 static $FIELDS = array( 36 'socid', 37 'date' 38 ); 39 40 /** 41 * @var Commande $commande {@type Commande} 42 */ 43 public $commande; 44 45 /** 46 * Constructor 47 */ 48 public function __construct() 49 { 50 global $db, $conf; 51 $this->db = $db; 52 $this->commande = new Commande($this->db); 53 } 54 55 /** 56 * Get properties of an order object by id 57 * 58 * Return an array with order informations 59 * 60 * @param int $id ID of order 61 * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id 62 * @return array|mixed data without useless information 63 * 64 * @throws RestException 65 */ 66 public function get($id, $contact_list = 1) 67 { 68 return $this->_fetch($id, '', '', $contact_list); 69 } 70 71 /** 72 * Get properties of an order object by ref 73 * 74 * Return an array with order informations 75 * 76 * @param string $ref Ref of object 77 * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id 78 * @return array|mixed data without useless information 79 * 80 * @url GET ref/{ref} 81 * 82 * @throws RestException 83 */ 84 public function getByRef($ref, $contact_list = 1) 85 { 86 return $this->_fetch('', $ref, '', $contact_list); 87 } 88 89 /** 90 * Get properties of an order object by ref_ext 91 * 92 * Return an array with order informations 93 * 94 * @param string $ref_ext External reference of object 95 * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id 96 * @return array|mixed data without useless information 97 * 98 * @url GET ref_ext/{ref_ext} 99 * 100 * @throws RestException 101 */ 102 public function getByRefExt($ref_ext, $contact_list = 1) 103 { 104 return $this->_fetch('', '', $ref_ext, $contact_list); 105 } 106 107 /** 108 * Get properties of an order object 109 * 110 * Return an array with order informations 111 * 112 * @param int $id ID of order 113 * @param string $ref Ref of object 114 * @param string $ref_ext External reference of object 115 * @param int $contact_list 0: Returned array of contacts/addresses contains all properties, 1: Return array contains just id 116 * @return array|mixed data without useless information 117 * 118 * @throws RestException 119 */ 120 private function _fetch($id, $ref = '', $ref_ext = '', $contact_list = 1) 121 { 122 if (!DolibarrApiAccess::$user->rights->commande->lire) { 123 throw new RestException(401); 124 } 125 126 $result = $this->commande->fetch($id, $ref, $ref_ext); 127 if (!$result) { 128 throw new RestException(404, 'Order not found'); 129 } 130 131 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 132 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 133 } 134 135 // Add external contacts ids 136 $this->commande->contacts_ids = $this->commande->liste_contact(-1, 'external', $contact_list); 137 $this->commande->fetchObjectLinked(); 138 return $this->_cleanObjectDatas($this->commande); 139 } 140 141 /** 142 * List orders 143 * 144 * Get a list of orders 145 * 146 * @param string $sortfield Sort field 147 * @param string $sortorder Sort order 148 * @param int $limit Limit for list 149 * @param int $page Page number 150 * @param string $thirdparty_ids Thirdparty ids to filter orders of (example '1' or '1,2,3') {@pattern /^[0-9,]*$/i} 151 * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" 152 * @return array Array of order objects 153 * 154 * @throws RestException 404 Not found 155 * @throws RestException 503 Error 156 */ 157 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $thirdparty_ids = '', $sqlfilters = '') 158 { 159 global $db, $conf; 160 161 $obj_ret = array(); 162 163 // case of external user, $thirdparty_ids param is ignored and replaced by user's socid 164 $socids = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : $thirdparty_ids; 165 166 // If the internal user must only see his customers, force searching by him 167 $search_sale = 0; 168 if (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; 169 170 $sql = "SELECT t.rowid"; 171 if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $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) 172 $sql .= " FROM ".MAIN_DB_PREFIX."commande as t"; 173 174 if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale 175 176 $sql .= ' WHERE t.entity IN ('.getEntity('commande').')'; 177 if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; 178 if ($socids) $sql .= " AND t.fk_soc IN (".$socids.")"; 179 if ($search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale 180 // Insert sale filter 181 if ($search_sale > 0) 182 { 183 $sql .= " AND sc.fk_user = ".$search_sale; 184 } 185 // Add sql filters 186 if ($sqlfilters) 187 { 188 if (!DolibarrApi::_checkFilters($sqlfilters)) 189 { 190 throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); 191 } 192 $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; 193 $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; 194 } 195 196 $sql .= $this->db->order($sortfield, $sortorder); 197 if ($limit) { 198 if ($page < 0) 199 { 200 $page = 0; 201 } 202 $offset = $limit * $page; 203 204 $sql .= $this->db->plimit($limit + 1, $offset); 205 } 206 207 dol_syslog("API Rest request"); 208 $result = $this->db->query($sql); 209 210 if ($result) 211 { 212 $num = $this->db->num_rows($result); 213 $min = min($num, ($limit <= 0 ? $num : $limit)); 214 $i = 0; 215 while ($i < $min) 216 { 217 $obj = $this->db->fetch_object($result); 218 $commande_static = new Commande($this->db); 219 if ($commande_static->fetch($obj->rowid)) { 220 // Add external contacts ids 221 $commande_static->contacts_ids = $commande_static->liste_contact(-1, 'external', 1); 222 $obj_ret[] = $this->_cleanObjectDatas($commande_static); 223 } 224 $i++; 225 } 226 } else { 227 throw new RestException(503, 'Error when retrieve commande list : '.$this->db->lasterror()); 228 } 229 if (!count($obj_ret)) { 230 throw new RestException(404, 'No order found'); 231 } 232 return $obj_ret; 233 } 234 235 /** 236 * Create a sale order 237 * 238 * Exemple: { "socid": 2, "date": 1595196000, "type": 0, "lines": [{ "fk_product": 2, "qty": 1 }] } 239 * 240 * @param array $request_data Request data 241 * @return int ID of order 242 */ 243 public function post($request_data = null) 244 { 245 if (!DolibarrApiAccess::$user->rights->commande->creer) { 246 throw new RestException(401, "Insuffisant rights"); 247 } 248 // Check mandatory fields 249 $result = $this->_validate($request_data); 250 251 foreach ($request_data as $field => $value) { 252 $this->commande->$field = $value; 253 } 254 /*if (isset($request_data["lines"])) { 255 $lines = array(); 256 foreach ($request_data["lines"] as $line) { 257 array_push($lines, (object) $line); 258 } 259 $this->commande->lines = $lines; 260 }*/ 261 262 if ($this->commande->create(DolibarrApiAccess::$user) < 0) { 263 throw new RestException(500, "Error creating order", array_merge(array($this->commande->error), $this->commande->errors)); 264 } 265 266 return $this->commande->id; 267 } 268 269 /** 270 * Get lines of an order 271 * 272 * @param int $id Id of order 273 * 274 * @url GET {id}/lines 275 * 276 * @return int 277 */ 278 public function getLines($id) 279 { 280 if (!DolibarrApiAccess::$user->rights->commande->lire) { 281 throw new RestException(401); 282 } 283 284 $result = $this->commande->fetch($id); 285 if (!$result) { 286 throw new RestException(404, 'Order not found'); 287 } 288 289 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 290 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 291 } 292 $this->commande->getLinesArray(); 293 $result = array(); 294 foreach ($this->commande->lines as $line) { 295 array_push($result, $this->_cleanObjectDatas($line)); 296 } 297 return $result; 298 } 299 300 /** 301 * Add a line to given order 302 * 303 * @param int $id Id of order to update 304 * @param array $request_data OrderLine data 305 * 306 * @url POST {id}/lines 307 * 308 * @return int 309 */ 310 public function postLine($id, $request_data = null) 311 { 312 if (!DolibarrApiAccess::$user->rights->commande->creer) { 313 throw new RestException(401); 314 } 315 316 $result = $this->commande->fetch($id); 317 if (!$result) { 318 throw new RestException(404, 'Order not found'); 319 } 320 321 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 322 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 323 } 324 $request_data = (object) $request_data; 325 $updateRes = $this->commande->addline( 326 $request_data->desc, 327 $request_data->subprice, 328 $request_data->qty, 329 $request_data->tva_tx, 330 $request_data->localtax1_tx, 331 $request_data->localtax2_tx, 332 $request_data->fk_product, 333 $request_data->remise_percent, 334 $request_data->info_bits, 335 $request_data->fk_remise_except, 336 'HT', 337 0, 338 $request_data->date_start, 339 $request_data->date_end, 340 $request_data->product_type, 341 $request_data->rang, 342 $request_data->special_code, 343 $request_data->fk_parent_line, 344 $request_data->fk_fournprice, 345 $request_data->pa_ht, 346 $request_data->label, 347 $request_data->array_options, 348 $request_data->fk_unit, 349 $request_data->origin, 350 $request_data->origin_id, 351 $request_data->multicurrency_subprice, 352 $request_data->ref_ext 353 ); 354 355 if ($updateRes > 0) { 356 return $updateRes; 357 } else { 358 throw new RestException(400, $this->commande->error); 359 } 360 } 361 362 /** 363 * Update a line to given order 364 * 365 * @param int $id Id of order to update 366 * @param int $lineid Id of line to update 367 * @param array $request_data OrderLine data 368 * 369 * @url PUT {id}/lines/{lineid} 370 * 371 * @return array|bool 372 */ 373 public function putLine($id, $lineid, $request_data = null) 374 { 375 if (!DolibarrApiAccess::$user->rights->commande->creer) { 376 throw new RestException(401); 377 } 378 379 $result = $this->commande->fetch($id); 380 if (!$result) { 381 throw new RestException(404, 'Order not found'); 382 } 383 384 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 385 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 386 } 387 $request_data = (object) $request_data; 388 $updateRes = $this->commande->updateline( 389 $lineid, 390 $request_data->desc, 391 $request_data->subprice, 392 $request_data->qty, 393 $request_data->remise_percent, 394 $request_data->tva_tx, 395 $request_data->localtax1_tx, 396 $request_data->localtax2_tx, 397 'HT', 398 $request_data->info_bits, 399 $request_data->date_start, 400 $request_data->date_end, 401 $request_data->product_type, 402 $request_data->fk_parent_line, 403 0, 404 $request_data->fk_fournprice, 405 $request_data->pa_ht, 406 $request_data->label, 407 $request_data->special_code, 408 $request_data->array_options, 409 $request_data->fk_unit, 410 $request_data->multicurrency_subprice, 411 0, 412 $request_data->ref_ext 413 ); 414 415 if ($updateRes > 0) { 416 $result = $this->get($id); 417 unset($result->line); 418 return $this->_cleanObjectDatas($result); 419 } 420 return false; 421 } 422 423 /** 424 * Delete a line to given order 425 * 426 * 427 * @param int $id Id of order to update 428 * @param int $lineid Id of line to delete 429 * 430 * @url DELETE {id}/lines/{lineid} 431 * 432 * @return int 433 * 434 * @throws RestException 401 435 * @throws RestException 404 436 */ 437 public function deleteLine($id, $lineid) 438 { 439 if (!DolibarrApiAccess::$user->rights->commande->creer) { 440 throw new RestException(401); 441 } 442 443 $result = $this->commande->fetch($id); 444 if (!$result) { 445 throw new RestException(404, 'Order not found'); 446 } 447 448 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 449 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 450 } 451 452 // TODO Check the lineid $lineid is a line of ojbect 453 454 $updateRes = $this->commande->deleteline(DolibarrApiAccess::$user, $lineid); 455 if ($updateRes > 0) { 456 return $this->get($id); 457 } else { 458 throw new RestException(405, $this->commande->error); 459 } 460 } 461 462 /** 463 * Get contacts of given order 464 * 465 * Return an array with contact informations 466 * 467 * @param int $id ID of order 468 * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER) 469 * 470 * @url GET {id}/contacts 471 * 472 * @return array data without useless information 473 * 474 * @throws RestException 475 */ 476 public function getContacts($id, $type = '') 477 { 478 if (!DolibarrApiAccess::$user->rights->commande->lire) { 479 throw new RestException(401); 480 } 481 482 $result = $this->commande->fetch($id); 483 if (!$result) { 484 throw new RestException(404, 'Order not found'); 485 } 486 487 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 488 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 489 } 490 491 $contacts = $this->commande->liste_contact(-1, 'external', 0, $type); 492 493 return $this->_cleanObjectDatas($contacts); 494 } 495 496 /** 497 * Add a contact type of given order 498 * 499 * @param int $id Id of order to update 500 * @param int $contactid Id of contact to add 501 * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER) 502 * 503 * @url POST {id}/contact/{contactid}/{type} 504 * 505 * @return int 506 * 507 * @throws RestException 401 508 * @throws RestException 404 509 */ 510 public function postContact($id, $contactid, $type) 511 { 512 if (!DolibarrApiAccess::$user->rights->commande->creer) { 513 throw new RestException(401); 514 } 515 516 $result = $this->commande->fetch($id); 517 if (!$result) { 518 throw new RestException(404, 'Order not found'); 519 } 520 521 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 522 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 523 } 524 525 $result = $this->commande->add_contact($contactid, $type, 'external'); 526 527 if ($result < 0) { 528 throw new RestException(500, 'Error when added the contact'); 529 } 530 531 if ($result == 0) { 532 throw new RestException(304, 'contact already added'); 533 } 534 535 return array( 536 'success' => array( 537 'code' => 200, 538 'message' => 'Contact linked to the order' 539 ) 540 ); 541 } 542 543 /** 544 * Unlink a contact type of given order 545 * 546 * @param int $id Id of order to update 547 * @param int $contactid Id of contact 548 * @param string $type Type of the contact (BILLING, SHIPPING, CUSTOMER). 549 * 550 * @url DELETE {id}/contact/{contactid}/{type} 551 * 552 * @return int 553 * 554 * @throws RestException 401 555 * @throws RestException 404 556 * @throws RestException 500 557 */ 558 public function deleteContact($id, $contactid, $type) 559 { 560 if (!DolibarrApiAccess::$user->rights->commande->creer) { 561 throw new RestException(401); 562 } 563 564 $result = $this->commande->fetch($id); 565 if (!$result) { 566 throw new RestException(404, 'Order not found'); 567 } 568 569 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 570 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 571 } 572 573 $contacts = $this->commande->liste_contact(); 574 575 foreach ($contacts as $contact) { 576 if ($contact['id'] == $contactid && $contact['code'] == $type) { 577 $result = $this->commande->delete_contact($contact['rowid']); 578 579 if (!$result) { 580 throw new RestException(500, 'Error when deleted the contact'); 581 } 582 } 583 } 584 585 return array( 586 'success' => array( 587 'code' => 200, 588 'message' => 'Contact unlinked from order' 589 ) 590 ); 591 } 592 593 /** 594 * Update order general fields (won't touch lines of order) 595 * 596 * @param int $id Id of order to update 597 * @param array $request_data Datas 598 * 599 * @return int 600 */ 601 public function put($id, $request_data = null) 602 { 603 if (!DolibarrApiAccess::$user->rights->commande->creer) { 604 throw new RestException(401); 605 } 606 607 $result = $this->commande->fetch($id); 608 if (!$result) { 609 throw new RestException(404, 'Order not found'); 610 } 611 612 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 613 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 614 } 615 foreach ($request_data as $field => $value) { 616 if ($field == 'id') continue; 617 $this->commande->$field = $value; 618 } 619 620 // Update availability 621 if (!empty($this->commande->availability_id)) { 622 if ($this->commande->availability($this->commande->availability_id) < 0) 623 throw new RestException(400, 'Error while updating availability'); 624 } 625 626 if ($this->commande->update(DolibarrApiAccess::$user) > 0) 627 { 628 return $this->get($id); 629 } else { 630 throw new RestException(500, $this->commande->error); 631 } 632 } 633 634 /** 635 * Delete order 636 * 637 * @param int $id Order ID 638 * @return array 639 */ 640 public function delete($id) 641 { 642 if (!DolibarrApiAccess::$user->rights->commande->supprimer) { 643 throw new RestException(401); 644 } 645 $result = $this->commande->fetch($id); 646 if (!$result) { 647 throw new RestException(404, 'Order not found'); 648 } 649 650 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 651 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 652 } 653 654 if (!$this->commande->delete(DolibarrApiAccess::$user)) { 655 throw new RestException(500, 'Error when deleting order : '.$this->commande->error); 656 } 657 658 return array( 659 'success' => array( 660 'code' => 200, 661 'message' => 'Order deleted' 662 ) 663 ); 664 } 665 666 /** 667 * Validate an order 668 * 669 * If you get a bad value for param notrigger check, provide this in body 670 * { 671 * "idwarehouse": 0, 672 * "notrigger": 0 673 * } 674 * 675 * @param int $id Order ID 676 * @param int $idwarehouse Warehouse ID 677 * @param int $notrigger 1=Does not execute triggers, 0= execute triggers 678 * 679 * @url POST {id}/validate 680 * 681 * @throws RestException 304 682 * @throws RestException 401 683 * @throws RestException 404 684 * @throws RestException 500 685 * 686 * @return array 687 */ 688 public function validate($id, $idwarehouse = 0, $notrigger = 0) 689 { 690 if (!DolibarrApiAccess::$user->rights->commande->creer) { 691 throw new RestException(401); 692 } 693 $result = $this->commande->fetch($id); 694 if (!$result) { 695 throw new RestException(404, 'Order not found'); 696 } 697 698 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 699 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 700 } 701 702 $result = $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); 703 if ($result == 0) { 704 throw new RestException(304, 'Error nothing done. May be object is already validated'); 705 } 706 if ($result < 0) { 707 throw new RestException(500, 'Error when validating Order: '.$this->commande->error); 708 } 709 $result = $this->commande->fetch($id); 710 if (!$result) { 711 throw new RestException(404, 'Order not found'); 712 } 713 714 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 715 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 716 } 717 718 $this->commande->fetchObjectLinked(); 719 720 return $this->_cleanObjectDatas($this->commande); 721 } 722 723 /** 724 * Tag the order as validated (opened) 725 * 726 * Function used when order is reopend after being closed. 727 * 728 * @param int $id Id of the order 729 * 730 * @url POST {id}/reopen 731 * 732 * @return int 733 * 734 * @throws RestException 304 735 * @throws RestException 400 736 * @throws RestException 401 737 * @throws RestException 404 738 * @throws RestException 405 739 */ 740 public function reopen($id) 741 { 742 743 if (!DolibarrApiAccess::$user->rights->commande->creer) { 744 throw new RestException(401); 745 } 746 if (empty($id)) { 747 throw new RestException(400, 'Order ID is mandatory'); 748 } 749 $result = $this->commande->fetch($id); 750 if (!$result) { 751 throw new RestException(404, 'Order not found'); 752 } 753 754 $result = $this->commande->set_reopen(DolibarrApiAccess::$user); 755 if ($result < 0) { 756 throw new RestException(405, $this->commande->error); 757 } elseif ($result == 0) { 758 throw new RestException(304); 759 } 760 761 return $result; 762 } 763 764 /** 765 * Classify the order as invoiced. Could be also called setbilled 766 * 767 * @param int $id Id of the order 768 * 769 * @url POST {id}/setinvoiced 770 * 771 * @return int 772 * 773 * @throws RestException 400 774 * @throws RestException 401 775 * @throws RestException 404 776 * @throws RestException 405 777 */ 778 public function setinvoiced($id) 779 { 780 781 if (!DolibarrApiAccess::$user->rights->commande->creer) { 782 throw new RestException(401); 783 } 784 if (empty($id)) { 785 throw new RestException(400, 'Order ID is mandatory'); 786 } 787 $result = $this->commande->fetch($id); 788 if (!$result) { 789 throw new RestException(404, 'Order not found'); 790 } 791 792 $result = $this->commande->classifyBilled(DolibarrApiAccess::$user); 793 if ($result < 0) { 794 throw new RestException(400, $this->commande->error); 795 } 796 797 $result = $this->commande->fetch($id); 798 if (!$result) { 799 throw new RestException(404, 'Order not found'); 800 } 801 802 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 803 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 804 } 805 806 $this->commande->fetchObjectLinked(); 807 808 return $this->_cleanObjectDatas($this->commande); 809 } 810 811 /** 812 * Close an order (Classify it as "Delivered") 813 * 814 * @param int $id Order ID 815 * @param int $notrigger Disabled triggers 816 * 817 * @url POST {id}/close 818 * 819 * @return int 820 */ 821 public function close($id, $notrigger = 0) 822 { 823 if (!DolibarrApiAccess::$user->rights->commande->creer) { 824 throw new RestException(401); 825 } 826 $result = $this->commande->fetch($id); 827 if (!$result) { 828 throw new RestException(404, 'Order not found'); 829 } 830 831 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 832 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 833 } 834 835 $result = $this->commande->cloture(DolibarrApiAccess::$user, $notrigger); 836 if ($result == 0) { 837 throw new RestException(304, 'Error nothing done. May be object is already closed'); 838 } 839 if ($result < 0) { 840 throw new RestException(500, 'Error when closing Order: '.$this->commande->error); 841 } 842 843 $result = $this->commande->fetch($id); 844 if (!$result) { 845 throw new RestException(404, 'Order not found'); 846 } 847 848 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 849 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 850 } 851 852 $this->commande->fetchObjectLinked(); 853 854 return $this->_cleanObjectDatas($this->commande); 855 } 856 857 /** 858 * Set an order to draft 859 * 860 * @param int $id Order ID 861 * @param int $idwarehouse Warehouse ID to use for stock change (Used only if option STOCK_CALCULATE_ON_VALIDATE_ORDER is on) 862 * 863 * @url POST {id}/settodraft 864 * 865 * @return array 866 */ 867 public function settodraft($id, $idwarehouse = -1) 868 { 869 if (!DolibarrApiAccess::$user->rights->commande->creer) { 870 throw new RestException(401); 871 } 872 $result = $this->commande->fetch($id); 873 if (!$result) { 874 throw new RestException(404, 'Order not found'); 875 } 876 877 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 878 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 879 } 880 881 $result = $this->commande->setDraft(DolibarrApiAccess::$user, $idwarehouse); 882 if ($result == 0) { 883 throw new RestException(304, 'Nothing done. May be object is already closed'); 884 } 885 if ($result < 0) { 886 throw new RestException(500, 'Error when closing Order: '.$this->commande->error); 887 } 888 889 $result = $this->commande->fetch($id); 890 if (!$result) { 891 throw new RestException(404, 'Order not found'); 892 } 893 894 if (!DolibarrApi::_checkAccessToResource('commande', $this->commande->id)) { 895 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 896 } 897 898 $this->commande->fetchObjectLinked(); 899 900 return $this->_cleanObjectDatas($this->commande); 901 } 902 903 904 /** 905 * Create an order using an existing proposal. 906 * 907 * 908 * @param int $proposalid Id of the proposal 909 * 910 * @url POST /createfromproposal/{proposalid} 911 * 912 * @return int 913 * @throws RestException 400 914 * @throws RestException 401 915 * @throws RestException 404 916 * @throws RestException 405 917 */ 918 public function createOrderFromProposal($proposalid) 919 { 920 921 require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; 922 923 if (!DolibarrApiAccess::$user->rights->propal->lire) { 924 throw new RestException(401); 925 } 926 if (!DolibarrApiAccess::$user->rights->commande->creer) { 927 throw new RestException(401); 928 } 929 if (empty($proposalid)) { 930 throw new RestException(400, 'Proposal ID is mandatory'); 931 } 932 933 $propal = new Propal($this->db); 934 $result = $propal->fetch($proposalid); 935 if (!$result) { 936 throw new RestException(404, 'Proposal not found'); 937 } 938 939 $result = $this->commande->createFromProposal($propal, DolibarrApiAccess::$user); 940 if ($result < 0) { 941 throw new RestException(405, $this->commande->error); 942 } 943 $this->commande->fetchObjectLinked(); 944 945 return $this->_cleanObjectDatas($this->commande); 946 } 947 948 949 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore 950 /** 951 * Clean sensible object datas 952 * 953 * @param Object $object Object to clean 954 * @return Object Object with cleaned properties 955 */ 956 protected function _cleanObjectDatas($object) 957 { 958 // phpcs:enable 959 $object = parent::_cleanObjectDatas($object); 960 961 unset($object->note); 962 unset($object->address); 963 unset($object->barcode_type); 964 unset($object->barcode_type_code); 965 unset($object->barcode_type_label); 966 unset($object->barcode_type_coder); 967 968 return $object; 969 } 970 971 /** 972 * Validate fields before create or update object 973 * 974 * @param array $data Array with data to verify 975 * @return array 976 * @throws RestException 977 */ 978 private function _validate($data) 979 { 980 $commande = array(); 981 foreach (Orders::$FIELDS as $field) { 982 if (!isset($data[$field])) 983 throw new RestException(400, $field." field missing"); 984 $commande[$field] = $data[$field]; 985 } 986 return $commande; 987 } 988} 989