Passed
Branch develop (f95612)
by
unknown
98:25
created

Boms::getLines()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 12
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 20
rs 9.5555
1
<?php
2
/* Copyright (C) 2015   Jean-François Ferry     <[email protected]>
3
 * Copyright (C) 2019 Maxime Kohlhaas <[email protected]>
4
 * Copyright (C) 2020     	Frédéric France		<[email protected]>
5
 * Copyright (C) 2022     	Christian Humpel		<[email protected]>
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
use Luracast\Restler\RestException;
22
23
require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
24
25
26
/**
27
 * \file    bom/class/api_boms.class.php
28
 * \ingroup bom
29
 * \brief   File for API management of BOM.
30
 */
31
32
/**
33
 * API class for BOM
34
 *
35
 * @access protected
36
 * @class  DolibarrApiAccess {@requires user,external}
37
 */
38
class Boms extends DolibarrApi
39
{
40
	/**
41
	 * @var BOM $bom {@type BOM}
42
	 */
43
	public $bom;
44
45
	/**
46
	 * Constructor
47
	 */
48
	public function __construct()
49
	{
50
		global $db, $conf;
51
		$this->db = $db;
52
		$this->bom = new BOM($this->db);
53
	}
54
55
	/**
56
	 * Get properties of a bom object
57
	 *
58
	 * Return an array with bom informations
59
	 *
60
	 * @param 	int 	$id ID of bom
61
	 * @return 	array|mixed data without useless information
62
	 *
63
	 * @url	GET {id}
64
	 * @throws 	RestException
65
	 */
66
	public function get($id)
67
	{
68
		if (!DolibarrApiAccess::$user->rights->bom->read) {
69
			throw new RestException(401);
70
		}
71
72
		$result = $this->bom->fetch($id);
73
		if (!$result) {
74
			throw new RestException(404, 'BOM not found');
75
		}
76
77
		if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) {
78
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
79
		}
80
81
		return $this->_cleanObjectDatas($this->bom);
82
	}
83
84
85
	/**
86
	 * List boms
87
	 *
88
	 * Get a list of boms
89
	 *
90
	 * @param string	       $sortfield	        Sort field
91
	 * @param string	       $sortorder	        Sort order
92
	 * @param int		       $limit		        Limit for list
93
	 * @param int		       $page		        Page number
94
	 * @param string           $sqlfilters          Other criteria to filter answers separated by a comma. Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
95
	 * @return  array                               Array of order objects
96
	 *
97
	 * @throws RestException
98
	 */
99
	public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $sqlfilters = '')
100
	{
101
		global $db, $conf;
102
103
		if (!DolibarrApiAccess::$user->rights->bom->read) {
104
			throw new RestException(401);
105
		}
106
107
		$obj_ret = array();
108
		$tmpobject = new BOM($this->db);
109
110
		$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : '';
111
112
		$restrictonsocid = 0; // Set to 1 if there is a field socid in table of object
113
114
		// If the internal user must only see his customers, force searching by him
115
		$search_sale = 0;
116
		if ($restrictonsocid && !DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) {
117
			$search_sale = DolibarrApiAccess::$user->id;
118
		}
119
120
		$sql = "SELECT t.rowid";
121
		if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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.$tmpobject->table_element." as t";
125
126
		if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $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
		$sql .= " WHERE 1 = 1";
130
131
		// Example of use $mode
132
		//if ($mode == 1) $sql.= " AND s.client IN (1, 3)";
133
		//if ($mode == 2) $sql.= " AND s.client IN (2, 3)";
134
135
		if ($tmpobject->ismultientitymanaged) {
136
			$sql .= ' AND t.entity IN ('.getEntity($tmpobject->element).')';
137
		}
138
		if ($restrictonsocid && (!DolibarrApiAccess::$user->rights->societe->client->voir && !$socid) || $search_sale > 0) {
139
			$sql .= " AND t.fk_soc = sc.fk_soc";
140
		}
141
		if ($restrictonsocid && $socid) {
142
			$sql .= " AND t.fk_soc = ".((int) $socid);
143
		}
144
		if ($restrictonsocid && $search_sale > 0) {
145
			$sql .= " AND t.rowid = sc.fk_soc"; // Join for the needed table to filter by sale
146
		}
147
		// Insert sale filter
148
		if ($restrictonsocid && $search_sale > 0) {
149
			$sql .= " AND sc.fk_user = ".((int) $search_sale);
150
		}
151
		if ($sqlfilters) {
152
			$errormessage = '';
153
			if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) {
154
				throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage);
155
			}
156
			$regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
157
			$sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
158
		}
159
160
		$sql .= $this->db->order($sortfield, $sortorder);
161
		if ($limit) {
162
			if ($page < 0) {
163
				$page = 0;
164
			}
165
			$offset = $limit * $page;
166
167
			$sql .= $this->db->plimit($limit + 1, $offset);
168
		}
169
170
		$result = $this->db->query($sql);
171
		if ($result) {
172
			$num = $this->db->num_rows($result);
173
			$i = 0;
174
			while ($i < $num) {
175
				$obj = $this->db->fetch_object($result);
176
				$bom_static = new BOM($this->db);
177
				if ($bom_static->fetch($obj->rowid)) {
178
					$obj_ret[] = $this->_cleanObjectDatas($bom_static);
179
				}
180
				$i++;
181
			}
182
		} else {
183
			throw new RestException(503, 'Error when retrieve bom list');
184
		}
185
		if (!count($obj_ret)) {
186
			throw new RestException(404, 'No bom found');
187
		}
188
		return $obj_ret;
189
	}
190
191
	/**
192
	 * Create bom object
193
	 *
194
	 * @param array $request_data   Request datas
195
	 * @return int  ID of bom
196
	 */
197
	public function post($request_data = null)
198
	{
199
		if (!DolibarrApiAccess::$user->rights->bom->write) {
200
			throw new RestException(401);
201
		}
202
		// Check mandatory fields
203
		$result = $this->_validate($request_data);
204
205
		foreach ($request_data as $field => $value) {
206
			$this->bom->$field = $value;
207
		}
208
		if (!$this->bom->create(DolibarrApiAccess::$user)) {
209
			throw new RestException(500, "Error creating BOM", array_merge(array($this->bom->error), $this->bom->errors));
210
		}
211
		return $this->bom->id;
212
	}
213
214
	/**
215
	 * Update bom
216
	 *
217
	 * @param int   $id             Id of bom to update
218
	 * @param array $request_data   Datas
219
	 *
220
	 * @return int
221
	 */
222
	public function put($id, $request_data = null)
223
	{
224
		if (!DolibarrApiAccess::$user->rights->bom->write) {
225
			throw new RestException(401);
226
		}
227
228
		$result = $this->bom->fetch($id);
229
		if (!$result) {
230
			throw new RestException(404, 'BOM not found');
231
		}
232
233
		if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) {
234
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
235
		}
236
237
		foreach ($request_data as $field => $value) {
238
			if ($field == 'id') {
239
				continue;
240
			}
241
			$this->bom->$field = $value;
242
		}
243
244
		if ($this->bom->update(DolibarrApiAccess::$user) > 0) {
245
			return $this->get($id);
246
		} else {
247
			throw new RestException(500, $this->bom->error);
248
		}
249
	}
250
251
	/**
252
	 * Delete bom
253
	 *
254
	 * @param   int     $id   BOM ID
255
	 * @return  array
256
	 */
257
	public function delete($id)
258
	{
259
		if (!DolibarrApiAccess::$user->rights->bom->delete) {
260
			throw new RestException(401);
261
		}
262
		$result = $this->bom->fetch($id);
263
		if (!$result) {
264
			throw new RestException(404, 'BOM not found');
265
		}
266
267
		if (!DolibarrApi::_checkAccessToResource('bom', $this->bom->id, 'bom_bom')) {
268
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
269
		}
270
271
		if (!$this->bom->delete(DolibarrApiAccess::$user)) {
272
			throw new RestException(500, 'Error when deleting BOM : '.$this->bom->error);
273
		}
274
275
		return array(
276
			'success' => array(
277
				'code' => 200,
278
				'message' => 'BOM deleted'
279
			)
280
		);
281
	}
282
283
	/**
284
	 * Get lines of an BOM
285
	 *
286
	 * @param int   $id             Id of BOM
287
	 *
288
	 * @url	GET {id}/lines
289
	 *
290
	 * @return array
291
	 */
292
	public function getLines($id)
293
	{
294
		if (!DolibarrApiAccess::$user->rights->bom->read) {
295
			throw new RestException(401);
296
		}
297
298
		$result = $this->bom->fetch($id);
299
		if (!$result) {
300
			throw new RestException(404, 'BOM not found');
301
		}
302
303
		if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) {
304
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
305
		}
306
		$this->bom->getLinesArray();
307
		$result = array();
308
		foreach ($this->bom->lines as $line) {
309
			array_push($result, $this->_cleanObjectDatas($line));
310
		}
311
		return $result;
312
	}
313
314
	/**
315
	 * Add a line to given BOM
316
	 *
317
	 * @param int   $id             Id of BOM to update
318
	 * @param array $request_data   BOMLine data
319
	 *
320
	 * @url	POST {id}/lines
321
	 *
322
	 * @return int
323
	 */
324
	public function postLine($id, $request_data = null)
325
	{
326
		if (!DolibarrApiAccess::$user->rights->bom->write) {
327
			throw new RestException(401);
328
		}
329
330
		$result = $this->bom->fetch($id);
331
		if (!$result) {
332
			throw new RestException(404, 'BOM not found');
333
		}
334
335
		if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) {
336
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
337
		}
338
339
		$request_data = (object) $request_data;
340
341
		$updateRes = $this->bom->addLine(
342
			$request_data->fk_product,
343
			$request_data->qty,
344
			$request_data->qty_frozen,
345
			$request_data->disable_stock_change,
346
			$request_data->efficiency,
347
			$request_data->position,
348
			$request_data->fk_bom_child,
349
			$request_data->import_key
350
		);
351
352
		if ($updateRes > 0) {
353
			return $updateRes;
354
		} else {
355
			throw new RestException(400, $this->bom->error);
356
		}
357
	}
358
359
	/**
360
	 * Update a line to given BOM
361
	 *
362
	 * @param int   $id             Id of BOM to update
363
	 * @param int   $lineid         Id of line to update
364
	 * @param array $request_data   BOMLine data
365
	 *
366
	 * @url	PUT {id}/lines/{lineid}
367
	 *
368
	 * @return array|bool
369
	 */
370
	public function putLine($id, $lineid, $request_data = null)
371
	{
372
		if (!DolibarrApiAccess::$user->rights->bom->write) {
373
			throw new RestException(401);
374
		}
375
376
		$result = $this->bom->fetch($id);
377
		if (!$result) {
378
			throw new RestException(404, 'BOM not found');
379
		}
380
381
		if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) {
382
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
383
		}
384
385
		$request_data = (object) $request_data;
386
387
		$updateRes = $this->bom->updateLine(
388
			$lineid,
389
			$request_data->qty,
390
			$request_data->qty_frozen,
391
			$request_data->disable_stock_change,
392
			$request_data->efficiency,
393
			$request_data->position,
394
			$request_data->fk_bom_child,
395
			$request_data->import_key
396
		);
397
398
		if ($updateRes > 0) {
399
			$result = $this->get($id);
400
			unset($result->line);
401
			return $this->_cleanObjectDatas($result);
402
		}
403
		return false;
404
	}
405
406
	/**
407
	 * Delete a line to given BOM
408
	 *
409
	 *
410
	 * @param int   $id             Id of BOM to update
411
	 * @param int   $lineid         Id of line to delete
412
	 *
413
	 * @url	DELETE {id}/lines/{lineid}
414
	 *
415
	 * @return int
416
	 *
417
	 * @throws RestException 401
418
	 * @throws RestException 404
419
	 * @throws RestException 500
420
	 */
421
	public function deleteLine($id, $lineid)
422
	{
423
		if (!DolibarrApiAccess::$user->rights->bom->write) {
424
			throw new RestException(401);
425
		}
426
427
		$result = $this->bom->fetch($id);
428
		if (!$result) {
429
			throw new RestException(404, 'BOM not found');
430
		}
431
432
		if (!DolibarrApi::_checkAccessToResource('bom_bom', $this->bom->id)) {
433
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
434
		}
435
436
		//Check the rowid is a line of current bom object
437
		$lineIdIsFromObject = false;
438
		foreach ($this->bom->lines as $bl) {
439
			if ($bl->id == $lineid) {
440
				$lineIdIsFromObject = true;
441
				break;
442
			}
443
		}
444
		if (!$lineIdIsFromObject) {
445
			throw new RestException(500, 'Line to delete (rowid: '.$lineid.') is not a line of BOM (id: '.$this->bom->id.')');
446
		}
447
448
		$updateRes = $this->bom->deleteline(DolibarrApiAccess::$user, $lineid);
449
		if ($updateRes > 0) {
450
			return $this->get($id);
451
		} else {
452
			throw new RestException(405, $this->bom->error);
453
		}
454
	}
455
456
	// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
457
	/**
458
	 * Clean sensible object datas
459
	 *
460
	 * @param   Object  $object     Object to clean
461
	 * @return  Object              Object with cleaned properties
462
	 */
463
	protected function _cleanObjectDatas($object)
464
	{
465
		// phpcs:enable
466
		$object = parent::_cleanObjectDatas($object);
467
468
		unset($object->rowid);
469
		unset($object->canvas);
470
471
		unset($object->name);
472
		unset($object->lastname);
473
		unset($object->firstname);
474
		unset($object->civility_id);
475
		unset($object->statut);
476
		unset($object->state);
477
		unset($object->state_id);
478
		unset($object->state_code);
479
		unset($object->region);
480
		unset($object->region_code);
481
		unset($object->country);
482
		unset($object->country_id);
483
		unset($object->country_code);
484
		unset($object->barcode_type);
485
		unset($object->barcode_type_code);
486
		unset($object->barcode_type_label);
487
		unset($object->barcode_type_coder);
488
		unset($object->total_ht);
489
		unset($object->total_tva);
490
		unset($object->total_localtax1);
491
		unset($object->total_localtax2);
492
		unset($object->total_ttc);
493
		unset($object->fk_account);
494
		unset($object->comments);
495
		unset($object->note);
496
		unset($object->mode_reglement_id);
497
		unset($object->cond_reglement_id);
498
		unset($object->cond_reglement);
499
		unset($object->shipping_method_id);
500
		unset($object->fk_incoterms);
501
		unset($object->label_incoterms);
502
		unset($object->location_incoterms);
503
504
		// If object has lines, remove $db property
505
		if (isset($object->lines) && is_array($object->lines) && count($object->lines) > 0) {
506
			$nboflines = count($object->lines);
507
			for ($i = 0; $i < $nboflines; $i++) {
508
				$this->_cleanObjectDatas($object->lines[$i]);
509
510
				unset($object->lines[$i]->lines);
511
				unset($object->lines[$i]->note);
512
			}
513
		}
514
515
		return $object;
516
	}
517
518
	/**
519
	 * Validate fields before create or update object
520
	 *
521
	 * @param	array		$data   Array of data to validate
522
	 * @return	array
523
	 *
524
	 * @throws	RestException
525
	 */
526
	private function _validate($data)
527
	{
528
		$myobject = array();
529
		foreach ($this->bom->fields as $field => $propfield) {
530
			if (in_array($field, array('rowid', 'entity', 'date_creation', 'tms', 'fk_user_creat')) || $propfield['notnull'] != 1) {
531
				continue; // Not a mandatory field
532
			}
533
			if (!isset($data[$field])) {
534
				throw new RestException(400, "$field field missing");
535
			}
536
				$myobject[$field] = $data[$field];
537
		}
538
		return $myobject;
539
	}
540
}
541