1<?php 2/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr> 3 * Copyright (C) 2019 Maxime Kohlhaas <maxime@atm-consulting.fr> 4 * Copyright (C) 2020 Frédéric France <frederic.france@netlogic.fr> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <https://www.gnu.org/licenses/>. 18 */ 19 20use Luracast\Restler\RestException; 21 22require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php'; 23 24 25/** 26 * \file bom/class/api_boms.class.php 27 * \ingroup bom 28 * \brief File for API management of BOM. 29 */ 30 31/** 32 * API class for BOM 33 * 34 * @access protected 35 * @class DolibarrApiAccess {@requires user,external} 36 */ 37class Boms extends DolibarrApi 38{ 39 /** 40 * @var BOM $bom {@type BOM} 41 */ 42 public $bom; 43 44 /** 45 * Constructor 46 */ 47 public function __construct() 48 { 49 global $db, $conf; 50 $this->db = $db; 51 $this->bom = new BOM($this->db); 52 } 53 54 /** 55 * Get properties of a bom object 56 * 57 * Return an array with bom informations 58 * 59 * @param int $id ID of bom 60 * @return array|mixed data without useless information 61 * 62 * @url GET {id} 63 * @throws RestException 64 */ 65 public function get($id) 66 { 67 if (!DolibarrApiAccess::$user->rights->bom->read) { 68 throw new RestException(401); 69 } 70 71 $result = $this->bom->fetch($id); 72 if (!$result) { 73 throw new RestException(404, 'BOM not found'); 74 } 75 76 if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { 77 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 78 } 79 80 return $this->_cleanObjectDatas($this->bom); 81 } 82 83 84 /** 85 * List boms 86 * 87 * Get a list of boms 88 * 89 * @param string $sortfield Sort field 90 * @param string $sortorder Sort order 91 * @param int $limit Limit for list 92 * @param int $page Page number 93 * @param string $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" 94 * @return array Array of order objects 95 * 96 * @throws RestException 97 */ 98 public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '') 99 { 100 global $db, $conf; 101 102 $obj_ret = array(); 103 $tmpobject = new BOM($this->db); 104 105 $socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : ''; 106 107 $restrictonsocid = 0; // Set to 1 if there is a field socid in table of object 108 109 // If the internal user must only see his customers, force searching by him 110 $search_sale = 0; 111 if ($restrictonsocid && !DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) $search_sale = DolibarrApiAccess::$user->id; 112 113 $sql = "SELECT t.rowid"; 114 if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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) 115 $sql .= " FROM ".MAIN_DB_PREFIX.$tmpobject->table_element." as t"; 116 117 if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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 118 $sql .= " WHERE 1 = 1"; 119 120 // Example of use $mode 121 //if ($mode == 1) $sql.= " AND s.client IN (1, 3)"; 122 //if ($mode == 2) $sql.= " AND s.client IN (2, 3)"; 123 124 if ($tmpobject->ismultientitymanaged) $sql .= ' AND t.entity IN ('.getEntity($tmpobject->element).')'; 125 if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) $sql .= " AND t.fk_soc = sc.fk_soc"; 126 if ($restrictonsocid && $socid) $sql .= " AND t.fk_soc = ".$socid; 127 if ($restrictonsocid && $search_sale > 0) $sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale 128 // Insert sale filter 129 if ($restrictonsocid && $search_sale > 0) 130 { 131 $sql .= " AND sc.fk_user = ".$search_sale; 132 } 133 if ($sqlfilters) 134 { 135 if (!DolibarrApi::_checkFilters($sqlfilters)) { 136 throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); 137 } 138 $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; 139 $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; 140 } 141 142 $sql .= $this->db->order($sortfield, $sortorder); 143 if ($limit) { 144 if ($page < 0) 145 { 146 $page = 0; 147 } 148 $offset = $limit * $page; 149 150 $sql .= $this->db->plimit($limit + 1, $offset); 151 } 152 153 $result = $this->db->query($sql); 154 if ($result) 155 { 156 $num = $this->db->num_rows($result); 157 $i = 0; 158 while ($i < $num) 159 { 160 $obj = $this->db->fetch_object($result); 161 $bom_static = new BOM($this->db); 162 if ($bom_static->fetch($obj->rowid)) { 163 $obj_ret[] = $this->_cleanObjectDatas($bom_static); 164 } 165 $i++; 166 } 167 } else { 168 throw new RestException(503, 'Error when retrieve bom list'); 169 } 170 if (!count($obj_ret)) { 171 throw new RestException(404, 'No bom found'); 172 } 173 return $obj_ret; 174 } 175 176 /** 177 * Create bom object 178 * 179 * @param array $request_data Request datas 180 * @return int ID of bom 181 */ 182 public function post($request_data = null) 183 { 184 if (!DolibarrApiAccess::$user->rights->bom->write) { 185 throw new RestException(401); 186 } 187 // Check mandatory fields 188 $result = $this->_validate($request_data); 189 190 foreach ($request_data as $field => $value) { 191 $this->bom->$field = $value; 192 } 193 if (!$this->bom->create(DolibarrApiAccess::$user)) { 194 throw new RestException(500, "Error creating BOM", array_merge(array($this->bom->error), $this->bom->errors)); 195 } 196 return $this->bom->id; 197 } 198 199 /** 200 * Update bom 201 * 202 * @param int $id Id of bom to update 203 * @param array $request_data Datas 204 * 205 * @return int 206 */ 207 public function put($id, $request_data = null) 208 { 209 if (!DolibarrApiAccess::$user->rights->bom->write) { 210 throw new RestException(401); 211 } 212 213 $result = $this->bom->fetch($id); 214 if (!$result) { 215 throw new RestException(404, 'BOM not found'); 216 } 217 218 if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { 219 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 220 } 221 222 foreach ($request_data as $field => $value) { 223 if ($field == 'id') continue; 224 $this->bom->$field = $value; 225 } 226 227 if ($this->bom->update(DolibarrApiAccess::$user) > 0) { 228 return $this->get($id); 229 } else { 230 throw new RestException(500, $this->bom->error); 231 } 232 } 233 234 /** 235 * Delete bom 236 * 237 * @param int $id BOM ID 238 * @return array 239 */ 240 public function delete($id) 241 { 242 if (!DolibarrApiAccess::$user->rights->bom->delete) { 243 throw new RestException(401); 244 } 245 $result = $this->bom->fetch($id); 246 if (!$result) { 247 throw new RestException(404, 'BOM not found'); 248 } 249 250 if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) { 251 throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); 252 } 253 254 if (!$this->bom->delete(DolibarrApiAccess::$user)) 255 { 256 throw new RestException(500, 'Error when deleting BOM : '.$this->bom->error); 257 } 258 259 return array( 260 'success' => array( 261 'code' => 200, 262 'message' => 'BOM deleted' 263 ) 264 ); 265 } 266 267 268 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore 269 /** 270 * Clean sensible object datas 271 * 272 * @param Object $object Object to clean 273 * @return Object Object with cleaned properties 274 */ 275 protected function _cleanObjectDatas($object) 276 { 277 // phpcs:enable 278 $object = parent::_cleanObjectDatas($object); 279 280 unset($object->rowid); 281 unset($object->canvas); 282 283 unset($object->name); 284 unset($object->lastname); 285 unset($object->firstname); 286 unset($object->civility_id); 287 unset($object->statut); 288 unset($object->state); 289 unset($object->state_id); 290 unset($object->state_code); 291 unset($object->region); 292 unset($object->region_code); 293 unset($object->country); 294 unset($object->country_id); 295 unset($object->country_code); 296 unset($object->barcode_type); 297 unset($object->barcode_type_code); 298 unset($object->barcode_type_label); 299 unset($object->barcode_type_coder); 300 unset($object->total_ht); 301 unset($object->total_tva); 302 unset($object->total_localtax1); 303 unset($object->total_localtax2); 304 unset($object->total_ttc); 305 unset($object->fk_account); 306 unset($object->comments); 307 unset($object->note); 308 unset($object->mode_reglement_id); 309 unset($object->cond_reglement_id); 310 unset($object->cond_reglement); 311 unset($object->shipping_method_id); 312 unset($object->fk_incoterms); 313 unset($object->label_incoterms); 314 unset($object->location_incoterms); 315 316 // If object has lines, remove $db property 317 if (isset($object->lines) && is_array($object->lines) && count($object->lines) > 0) { 318 $nboflines = count($object->lines); 319 for ($i = 0; $i < $nboflines; $i++) 320 { 321 $this->_cleanObjectDatas($object->lines[$i]); 322 323 unset($object->lines[$i]->lines); 324 unset($object->lines[$i]->note); 325 } 326 } 327 328 return $object; 329 } 330 331 /** 332 * Validate fields before create or update object 333 * 334 * @param array $data Array of data to validate 335 * @return array 336 * 337 * @throws RestException 338 */ 339 private function _validate($data) 340 { 341 $myobject = array(); 342 foreach ($this->bom->fields as $field => $propfield) { 343 if (in_array($field, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat')) || $propfield['notnull'] != 1) continue; // Not a mandatory field 344 if (!isset($data[$field])) 345 throw new RestException(400, "$field field missing"); 346 $myobject[$field] = $data[$field]; 347 } 348 return $myobject; 349 } 350} 351