Passed
Branch develop (5cbde9)
by
unknown
26:38
created

Thirdparties::getCategories()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 27
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 12
c 0
b 0
f 0
nc 5
nop 5
dl 0
loc 27
rs 8.8333
1
<?php
2
/* Copyright (C) 2015   Jean-François Ferry     <[email protected]>
3
 * Copyright (C) 2018   Pierre Chéné            <[email protected]>
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 <http://www.gnu.org/licenses/>.
17
 */
18
19
use Luracast\Restler\RestException;
20
21
22
/**
23
 * API class for thirdparties
24
 *
25
 * @access protected
26
 * @class  DolibarrApiAccess {@requires user,external}
27
 *
28
 */
29
class Thirdparties extends DolibarrApi
30
{
31
	/**
32
	 *
33
	 * @var array   $FIELDS     Mandatory fields, checked when create and update object
34
	 */
35
	static $FIELDS = array(
36
		'name'
37
	);
38
39
	/**
40
	 * @var Societe $company {@type Societe}
41
	 */
42
	public $company;
43
44
	/**
45
	 * Constructor
46
	 */
47
    public function __construct()
48
	{
49
		global $db, $conf;
50
		$this->db = $db;
51
52
		require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
53
		require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
54
		require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
55
		require_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
56
57
		$this->company = new Societe($this->db);
58
59
		if (! empty($conf->global->SOCIETE_EMAIL_MANDATORY)) {
60
			static::$FIELDS[] = 'email';
61
		}
62
	}
63
64
	/**
65
	 * Get properties of a thirdparty object
66
	 *
67
	 * Return an array with thirdparty informations
68
	 *
69
	 * @param 	int 	$id ID of thirdparty
70
	 * @return 	array|mixed data without useless information
71
	 *
72
	 * @throws 	RestException
73
	 */
74
    public function get($id)
75
	{
76
		if(! DolibarrApiAccess::$user->rights->societe->lire) {
77
			throw new RestException(401);
78
		}
79
80
		$result = $this->company->fetch($id);
81
		if( ! $result ) {
82
			throw new RestException(404, 'Thirdparty not found');
83
		}
84
85
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
86
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
87
		}
88
89
		if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $conf seems to be never defined.
Loading history...
90
			$filterabsolutediscount = "fk_facture_source IS NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
91
			$filtercreditnote = "fk_facture_source IS NOT NULL"; // If we want deposit to be substracted to payments only and not to total of final invoice
92
		} else {
93
			$filterabsolutediscount = "fk_facture_source IS NULL OR (description LIKE '(DEPOSIT)%' AND description NOT LIKE '(EXCESS RECEIVED)%')";
94
			$filtercreditnote = "fk_facture_source IS NOT NULL AND (description NOT LIKE '(DEPOSIT)%' OR description LIKE '(EXCESS RECEIVED)%')";
95
		}
96
97
		$absolute_discount = $this->company->getAvailableDiscounts('', $filterabsolutediscount);
98
		$absolute_creditnote = $this->company->getAvailableDiscounts('', $filtercreditnote);
99
		$this->company->absolute_discount = price2num($absolute_discount, 'MT');
0 ignored issues
show
Bug introduced by
The property absolute_discount does not seem to exist on Societe.
Loading history...
100
		$this->company->absolute_creditnote = price2num($absolute_creditnote, 'MT');
0 ignored issues
show
Bug introduced by
The property absolute_creditnote does not seem to exist on Societe.
Loading history...
101
102
		return $this->_cleanObjectDatas($this->company);
103
	}
104
105
	/**
106
	 * List thirdparties
107
	 *
108
	 * Get a list of thirdparties
109
	 *
110
	 * @param   string  $sortfield  Sort field
111
	 * @param   string  $sortorder  Sort order
112
	 * @param   int     $limit      Limit for list
113
	 * @param   int     $page       Page number
114
	 * @param   int     $mode       Set to 1 to show only customers
115
	 *                              Set to 2 to show only prospects
116
	 *                              Set to 3 to show only those are not customer neither prospect
117
	 * @param   string  $sqlfilters Other criteria to filter answers separated by a comma. Syntax example "(t.nom:like:'TheCompany%') and (t.date_creation:<:'20160101')"
118
	 * @return  array               Array of thirdparty objects
119
	 */
120
    public function index($sortfield = "t.rowid", $sortorder = 'ASC', $limit = 100, $page = 0, $mode = 0, $sqlfilters = '')
121
    {
122
		global $db, $conf;
123
124
		$obj_ret = array();
125
126
		// case of external user, we force socids
127
		$socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : '';
1 ignored issue
show
Deprecated Code introduced by
The property User::$societe_id has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

127
		$socids = DolibarrApiAccess::$user->societe_id ? /** @scrutinizer ignore-deprecated */ DolibarrApiAccess::$user->societe_id : '';
Loading history...
128
129
		// If the internal user must only see his customers, force searching by him
130
		$search_sale = 0;
131
		if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id;
132
133
		$sql = "SELECT t.rowid";
134
		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)
135
		$sql.= " FROM ".MAIN_DB_PREFIX."societe as t";
136
137
		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
138
		$sql.= ", ".MAIN_DB_PREFIX."c_stcomm as st";
139
		$sql.= " WHERE t.fk_stcomm = st.id";
140
		if ($mode == 1) $sql.= " AND t.client IN (1, 3)";
141
		if ($mode == 2) $sql.= " AND t.client IN (2, 3)";
142
		if ($mode == 3) $sql.= " AND t.client IN (0)";
143
		$sql.= ' AND t.entity IN ('.getEntity('societe').')';
144
		if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc";
145
		//if ($email != NULL) $sql.= " AND s.email = \"".$email."\"";
146
		if ($socid) $sql.= " AND t.rowid IN (".$socids.")";
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $socid does not exist. Did you maybe mean $socids?
Loading history...
147
		if ($search_sale > 0) $sql.= " AND t.rowid = sc.fk_soc";		// Join for the needed table to filter by sale
148
		// Insert sale filter
149
		if ($search_sale > 0)
150
		{
151
			$sql .= " AND sc.fk_user = ".$search_sale;
152
		}
153
		// Add sql filters
154
		if ($sqlfilters)
155
		{
156
			if (! DolibarrApi::_checkFilters($sqlfilters))
157
			{
158
				throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters);
159
			}
160
			$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
161
			$sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")";
162
		}
163
164
		$sql.= $db->order($sortfield, $sortorder);
165
166
		if ($limit) {
167
			if ($page < 0)
168
			{
169
				$page = 0;
170
			}
171
			$offset = $limit * $page;
172
173
			$sql.= $db->plimit($limit + 1, $offset);
174
		}
175
176
		$result = $db->query($sql);
177
		if ($result)
178
		{
179
			$num = $db->num_rows($result);
180
			$min = min($num, ($limit <= 0 ? $num : $limit));
181
			while ($i < $min)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $i seems to be never defined.
Loading history...
182
			{
183
				$obj = $db->fetch_object($result);
184
				$soc_static = new Societe($db);
185
				if($soc_static->fetch($obj->rowid)) {
186
					$obj_ret[] = $this->_cleanObjectDatas($soc_static);
187
				}
188
				$i++;
189
			}
190
		}
191
		else {
192
			throw new RestException(503, 'Error when retrieve thirdparties : '.$db->lasterror());
193
		}
194
		if( ! count($obj_ret)) {
195
			throw new RestException(404, 'Thirdparties not found');
196
		}
197
		return $obj_ret;
198
	}
199
200
	/**
201
	 * Create thirdparty object
202
	 *
203
	 * @param array $request_data   Request datas
204
	 * @return int  ID of thirdparty
205
	 */
206
    public function post($request_data = null)
207
	{
208
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
209
			throw new RestException(401);
210
		}
211
		// Check mandatory fields
212
		$result = $this->_validate($request_data);
213
214
		foreach($request_data as $field => $value) {
215
			$this->company->$field = $value;
216
		}
217
		if ($this->company->create(DolibarrApiAccess::$user) < 0)
218
			throw new RestException(500, 'Error creating thirdparty', array_merge(array($this->company->error), $this->company->errors));
219
220
		return $this->company->id;
221
	}
222
223
	/**
224
	 * Update thirdparty
225
	 *
226
	 * @param int   $id             Id of thirdparty to update
227
	 * @param array $request_data   Datas
228
	 * @return int
229
	 */
230
    public function put($id, $request_data = null)
231
	{
232
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
233
			throw new RestException(401);
234
		}
235
236
		$result = $this->company->fetch($id);
237
		if( ! $result ) {
238
			throw new RestException(404, 'Thirdparty not found');
239
		}
240
241
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
242
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
243
		}
244
245
		foreach($request_data as $field => $value) {
246
			if ($field == 'id') continue;
247
			$this->company->$field = $value;
248
		}
249
250
		if($this->company->update($id, DolibarrApiAccess::$user, 1, '', '', 'update'))
251
			return $this->get($id);
252
253
		return false;
254
	}
255
256
	/**
257
	 * Merge a thirdparty into another one.
258
	 *
259
	 * Merge content (properties, notes) and objects (like invoices, events, orders, proposals, ...) of a thirdparty into a target thirdparty,
260
	 * then delete the merged thirdparty.
261
	 * If a property has a defined value both in thirdparty to delete and thirdparty to keep, the value into the thirdparty to
262
	 * delete will be ignored, the value of target thirdparty will remain, except for notes (content is concatenated).
263
	 *
264
	 * @param int   $id             ID of thirdparty to keep (the target thirdparty)
265
	 * @param int   $idtodelete     ID of thirdparty to remove (the thirdparty to delete), once data has been merged into the target thirdparty.
266
	 * @return int
267
	 *
268
	 * @url PUT {id}/merge/{idtodelete}
269
	 */
270
    public function merge($id, $idtodelete)
271
	{
272
		global $db, $hookmanager;
273
274
		$error = 0;
275
276
		if ($id == $idtodelete)
277
		{
278
			throw new RestException(400, 'Try to merge a thirdparty into itself');
279
		}
280
281
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
282
			throw new RestException(401);
283
		}
284
285
		$result = $this->company->fetch($id);	// include the fetch of extra fields
286
		if( ! $result ) {
287
			throw new RestException(404, 'Thirdparty not found');
288
		}
289
290
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
291
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
292
		}
293
294
		$this->companytoremove = new Societe($db);
295
296
		$result = $this->companytoremove->fetch($idtodelete);	// include the fetch of extra fields
297
		if( ! $result ) {
298
			throw new RestException(404, 'Thirdparty not found');
299
		}
300
301
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->companytoremove->id)) {
302
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
303
		}
304
305
		$soc_origin = $this->companytoremove;
306
		$object = $this->company;
307
		$user = DolibarrApiAccess::$user;
308
309
310
		// Call same code than into action 'confirm_merge'
311
312
313
		$db->begin();
314
315
		// Recopy some data
316
		$object->client = $object->client | $soc_origin->client;
317
		$object->fournisseur = $object->fournisseur | $soc_origin->fournisseur;
318
		$listofproperties=array(
319
			'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_pro', 'fax', 'email', 'skype', 'url', 'barcode',
320
			'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
321
			'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
322
			'stcomm_id', 'outstanding_limit', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
323
			'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
324
			'model_pdf', 'fk_projet'
325
		);
326
		foreach ($listofproperties as $property)
327
		{
328
			if (empty($object->$property)) $object->$property = $soc_origin->$property;
329
		}
330
331
		// Concat some data
332
		$listofproperties=array(
333
			'note_public', 'note_private'
334
		);
335
		foreach ($listofproperties as $property)
336
		{
337
			$object->$property = dol_concatdesc($object->$property, $soc_origin->$property);
338
		}
339
340
		// Merge extrafields
341
		if (is_array($soc_origin->array_options))
342
		{
343
			foreach ($soc_origin->array_options as $key => $val)
344
			{
345
				if (empty($object->array_options[$key])) $object->array_options[$key] = $val;
346
			}
347
		}
348
349
		// Merge categories
350
		$static_cat = new Categorie($db);
351
		$custcats = $static_cat->containing($soc_origin->id, 'customer', 'id');
352
		$object->setCategories($custcats, 'customer');
353
		$suppcats = $static_cat->containing($soc_origin->id, 'supplier', 'id');
354
		$object->setCategories($suppcats, 'supplier');
355
356
		// If thirdparty has a new code that is same than origin, we clean origin code to avoid duplicate key from database unique keys.
357
		if ($soc_origin->code_client == $object->code_client
358
			|| $soc_origin->code_fournisseur == $object->code_fournisseur
359
			|| $soc_origin->barcode == $object->barcode)
360
		{
361
			dol_syslog("We clean customer and supplier code so we will be able to make the update of target");
362
			$soc_origin->code_client = '';
363
			$soc_origin->code_fournisseur = '';
364
			$soc_origin->barcode = '';
365
			$soc_origin->update($soc_origin->id, $user, 0, 1, 1, 'merge');
366
		}
367
368
		// Update
369
		$result = $object->update($object->id, $user, 0, 1, 1, 'merge');
370
		if ($result < 0)
371
		{
372
			$error++;
373
		}
374
375
		// Move links
376
		if (! $error)
377
		{
378
			$objects = array(
379
				'Adherent' => '/adherents/class/adherent.class.php',
380
				'Societe' => '/societe/class/societe.class.php',
381
				'Categorie' => '/categories/class/categorie.class.php',
382
				'ActionComm' => '/comm/action/class/actioncomm.class.php',
383
				'Propal' => '/comm/propal/class/propal.class.php',
384
				'Commande' => '/commande/class/commande.class.php',
385
				'Facture' => '/compta/facture/class/facture.class.php',
386
				'FactureRec' => '/compta/facture/class/facture-rec.class.php',
387
				'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
388
				'Contact' => '/contact/class/contact.class.php',
389
				'Contrat' => '/contrat/class/contrat.class.php',
390
				'Expedition' => '/expedition/class/expedition.class.php',
391
				'Fichinter' => '/fichinter/class/fichinter.class.php',
392
				'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
393
				'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
394
				'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
395
				'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
396
				'Livraison' => '/livraison/class/livraison.class.php',
397
				'Product' => '/product/class/product.class.php',
398
				'Project' => '/projet/class/project.class.php',
399
				'User' => '/user/class/user.class.php',
400
			);
401
402
			//First, all core objects must update their tables
403
			foreach ($objects as $object_name => $object_file)
404
			{
405
				require_once DOL_DOCUMENT_ROOT.$object_file;
406
407
				if (!$errors && !$object_name::replaceThirdparty($db, $soc_origin->id, $object->id))
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $errors does not exist. Did you maybe mean $error?
Loading history...
408
				{
409
					$errors++;
410
					//setEventMessages($db->lasterror(), null, 'errors');
411
				}
412
			}
413
		}
414
415
		// External modules should update their ones too
416
		if (!$errors)
417
		{
418
$reshook = $hookmanager->executeHooks('replaceThirdparty', array(
419
				'soc_origin' => $soc_origin->id,
420
				'soc_dest' => $object->id
421
			), $soc_dest, $action);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $action seems to be never defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable $soc_dest seems to be never defined.
Loading history...
422
423
			if ($reshook < 0)
424
			{
425
				//setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
426
				$errors++;
427
			}
428
		}
429
430
431
		if (! $error)
432
		{
433
			$object->context=array('merge'=>1, 'mergefromid'=>$soc_origin->id);
434
435
			// Call trigger
436
			$result=$object->call_trigger('COMPANY_MODIFY', $user);
437
			if ($result < 0)
438
			{
439
				//setEventMessages($object->error, $object->errors, 'errors');
440
				$error++;
441
			}
442
			// End call triggers
443
		}
444
445
		if (! $error)
446
		{
447
			//We finally remove the old thirdparty
448
			if ($soc_origin->delete($soc_origin->id, $user) < 1)
449
			{
450
				$errors++;
451
			}
452
		}
453
454
		// End of merge
455
456
		if ($error)
457
		{
458
			$db->rollback();
459
460
			throw new RestException(500, 'Error failed to merged thirdparty '.$this->companytoremove->id.' into '.$id.'. Enable and read log file for more information.');
461
		}
462
		else
463
		{
464
			$db->commit();
465
		}
466
467
		return $this->get($id);
468
	}
469
470
	/**
471
	 * Delete thirdparty
472
	 *
473
	 * @param int $id   Thirparty ID
474
	 * @return integer
475
	 */
476
    public function delete($id)
477
	{
478
		if(! DolibarrApiAccess::$user->rights->societe->supprimer) {
479
			throw new RestException(401);
480
		}
481
		$result = $this->company->fetch($id);
482
		if( ! $result ) {
483
			throw new RestException(404, 'Thirdparty not found');
484
		}
485
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
486
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
487
		}
488
		return $this->company->delete($id);
489
	}
490
491
	/**
492
	 * Get customer categories for a thirdparty
493
	 *
494
	 * @param int		$id         ID of thirdparty
495
	 * @param string	$sortfield	Sort field
496
	 * @param string	$sortorder	Sort order
497
	 * @param int		$limit		Limit for list
498
	 * @param int		$page		Page number
499
	 *
500
	 * @return mixed
501
	 *
502
	 * @url GET {id}/categories
503
	 */
504
    public function getCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
505
	{
506
		if (! DolibarrApiAccess::$user->rights->categorie->lire) {
507
			throw new RestException(401);
508
		}
509
510
		$result = $this->company->fetch($id);
511
		if( ! $result )
512
		{
513
			throw new RestException(404, 'Thirdparty not found');
514
		}
515
516
		$categories = new Categorie($this->db);
517
518
		$result = $categories->getListForItem($id, 'customer', $sortfield, $sortorder, $limit, $page);
519
520
		if (is_numeric($result) && $result < 0)
521
		{
522
			throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
523
		}
524
525
		if (is_numeric($result) && $result == 0)	// To fix a return of 0 instead of empty array of method getListForItem
526
		{
527
			return array();
528
		}
529
530
		return $result;
531
	}
532
533
	/**
534
	 * Add a customer category to a thirdparty
535
	 *
536
	 * @param int		$id				Id of thirdparty
537
	 * @param int       $category_id	Id of category
538
	 *
539
	 * @return mixed
540
	 *
541
	 * @url POST {id}/categories/{category_id}
542
	 */
543
    public function addCategory($id, $category_id)
544
	{
545
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
546
			throw new RestException(401);
547
		}
548
549
		$result = $this->company->fetch($id);
550
		if( ! $result ) {
551
			throw new RestException(404, 'Thirdparty not found');
552
		}
553
		$category = new Categorie($this->db);
554
		$result = $category->fetch($category_id);
555
		if( ! $result ) {
556
			throw new RestException(404, 'category not found');
557
		}
558
559
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
560
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
561
		}
562
		if( ! DolibarrApi::_checkAccessToResource('category', $category->id)) {
563
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
564
		}
565
566
		$category->add_type($this->company, 'customer');
567
568
		return $this->_cleanObjectDatas($this->company);
569
	}
570
571
	/**
572
	 * Remove the link between a customer category and the thirdparty
573
	 *
574
	 * @param int		$id				Id of thirdparty
575
	 * @param int		$category_id	Id of category
576
	 *
577
	 * @return mixed
578
	 *
579
	 * @url DELETE {id}/categories/{category_id}
580
	 */
581
    public function deleteCategory($id, $category_id)
582
	{
583
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
584
			throw new RestException(401);
585
		}
586
587
		$result = $this->company->fetch($id);
588
		if( ! $result ) {
589
			throw new RestException(404, 'Thirdparty not found');
590
		}
591
		$category = new Categorie($this->db);
592
		$result = $category->fetch($category_id);
593
		if( ! $result ) {
594
			throw new RestException(404, 'category not found');
595
		}
596
597
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
598
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
599
		}
600
		if( ! DolibarrApi::_checkAccessToResource('category', $category->id)) {
601
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
602
		}
603
604
		$category->del_type($this->company, 'customer');
605
606
		return $this->_cleanObjectDatas($this->company);
607
	}
608
609
	/**
610
	 * Get supplier categories for a thirdparty
611
	 *
612
	 * @param int		$id         ID of thirdparty
613
	 * @param string	$sortfield	Sort field
614
	 * @param string	$sortorder	Sort order
615
	 * @param int		$limit		Limit for list
616
	 * @param int		$page		Page number
617
	 *
618
	 * @return mixed
619
	 *
620
	 * @url GET {id}/supplier_categories
621
	 */
622
    public function getSupplierCategories($id, $sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0)
623
	{
624
		if (! DolibarrApiAccess::$user->rights->categorie->lire) {
625
			throw new RestException(401);
626
		}
627
628
		$result = $this->company->fetch($id);
629
		if( ! $result )
630
		{
631
			throw new RestException(404, 'Thirdparty not found');
632
		}
633
634
		$categories = new Categorie($this->db);
635
636
		$result = $categories->getListForItem($id, 'supplier', $sortfield, $sortorder, $limit, $page);
637
638
		if (is_numeric($result) && $result < 0)
639
		{
640
			throw new RestException(503, 'Error when retrieve category list : '.$categories->error);
641
		}
642
643
		if (is_numeric($result) && $result == 0)	// To fix a return of 0 instead of empty array of method getListForItem
644
		{
645
			return array();
646
		}
647
648
		return $result;
649
	}
650
651
	/**
652
	 * Add a supplier category to a thirdparty
653
	 *
654
	 * @param int		$id				Id of thirdparty
655
	 * @param int       $category_id	Id of category
656
	 *
657
	 * @return mixed
658
	 *
659
	 * @url POST {id}/supplier_categories/{category_id}
660
	 */
661
    public function addSupplierCategory($id, $category_id)
662
	{
663
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
664
			throw new RestException(401);
665
		}
666
667
		$result = $this->company->fetch($id);
668
		if( ! $result ) {
669
			throw new RestException(404, 'Thirdparty not found');
670
		}
671
		$category = new Categorie($this->db);
672
		$result = $category->fetch($category_id);
673
		if( ! $result ) {
674
			throw new RestException(404, 'category not found');
675
		}
676
677
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
678
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
679
		}
680
		if( ! DolibarrApi::_checkAccessToResource('category', $category->id)) {
681
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
682
		}
683
684
		$category->add_type($this->company, 'supplier');
685
686
		return $this->_cleanObjectDatas($this->company);
687
	}
688
689
	/**
690
	 * Remove the link between a category and the thirdparty
691
	 *
692
	 * @param int		$id				Id of thirdparty
693
	 * @param int		$category_id	Id of category
694
	 *
695
	 * @return mixed
696
	 *
697
	 * @url DELETE {id}/supplier_categories/{category_id}
698
	 */
699
    public function deleteSupplierCategory($id, $category_id)
700
	{
701
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
702
			throw new RestException(401);
703
		}
704
705
		$result = $this->company->fetch($id);
706
		if( ! $result ) {
707
			throw new RestException(404, 'Thirdparty not found');
708
		}
709
		$category = new Categorie($this->db);
710
		$result = $category->fetch($category_id);
711
		if( ! $result ) {
712
			throw new RestException(404, 'category not found');
713
		}
714
715
		if( ! DolibarrApi::_checkAccessToResource('societe', $this->company->id)) {
716
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
717
		}
718
		if( ! DolibarrApi::_checkAccessToResource('category', $category->id)) {
719
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
720
		}
721
722
		$category->del_type($this->company, 'supplier');
723
724
		return $this->_cleanObjectDatas($this->company);
725
	}
726
727
728
	/**
729
	 * Get outstanding proposals of thirdparty
730
	 *
731
	 * @param 	int 	$id			ID of the thirdparty
732
	 * @param 	string 	$mode		'customer' or 'supplier'
733
	 *
734
	 * @url     GET {id}/outstandingproposals
735
	 *
736
	 * @return array  				List of outstandings proposals of thirdparty
737
	 *
738
	 * @throws 400
739
	 * @throws 401
740
	 * @throws 404
741
	 */
742
    public function getOutStandingProposals($id, $mode = 'customer')
743
	{
744
		$obj_ret = array();
745
746
		if(! DolibarrApiAccess::$user->rights->societe->lire) {
747
			throw new RestException(401);
748
		}
749
750
		if(empty($id)) {
751
			throw new RestException(400, 'Thirdparty ID is mandatory');
752
		}
753
754
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
755
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
756
		}
757
758
		$result = $this->company->fetch($id);
759
		if( ! $result ) {
760
			throw new RestException(404, 'Thirdparty not found');
761
		}
762
763
		$result = $this->company->getOutstandingProposals($mode);
764
765
		unset($result['total_ht']);
766
		unset($result['total_ttc']);
767
768
		return $result;
769
	}
770
771
772
	/**
773
	 * Get outstanding orders of thirdparty
774
	 *
775
	 * @param 	int 	$id			ID of the thirdparty
776
	 * @param 	string 	$mode		'customer' or 'supplier'
777
	 *
778
	 * @url     GET {id}/outstandingorders
779
	 *
780
	 * @return array  				List of outstandings orders of thirdparty
781
	 *
782
	 * @throws 400
783
	 * @throws 401
784
	 * @throws 404
785
	 */
786
    public function getOutStandingOrder($id, $mode = 'customer')
787
	{
788
		$obj_ret = array();
789
790
		if(! DolibarrApiAccess::$user->rights->societe->lire) {
791
			throw new RestException(401);
792
		}
793
794
		if(empty($id)) {
795
			throw new RestException(400, 'Thirdparty ID is mandatory');
796
		}
797
798
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
799
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
800
		}
801
802
		$result = $this->company->fetch($id);
803
		if( ! $result ) {
804
			throw new RestException(404, 'Thirdparty not found');
805
		}
806
807
		$result = $this->company->getOutstandingOrders($mode);
808
809
		unset($result['total_ht']);
810
		unset($result['total_ttc']);
811
812
		return $result;
813
	}
814
815
	/**
816
	 * Get outstanding invoices of thirdparty
817
	 *
818
	 * @param 	int 	$id			ID of the thirdparty
819
	 * @param 	string 	$mode		'customer' or 'supplier'
820
	 *
821
	 * @url     GET {id}/outstandinginvoices
822
	 *
823
	 * @return array  				List of outstandings invoices of thirdparty
824
	 *
825
	 * @throws 400
826
	 * @throws 401
827
	 * @throws 404
828
	 */
829
    public function getOutStandingInvoices($id, $mode = 'customer')
830
	{
831
		$obj_ret = array();
832
833
		if(! DolibarrApiAccess::$user->rights->societe->lire) {
834
			throw new RestException(401);
835
		}
836
837
		if(empty($id)) {
838
			throw new RestException(400, 'Thirdparty ID is mandatory');
839
		}
840
841
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
842
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
843
		}
844
845
		$result = $this->company->fetch($id);
846
		if( ! $result ) {
847
			throw new RestException(404, 'Thirdparty not found');
848
		}
849
850
		$result = $this->company->getOutstandingBills($mode);
851
852
		unset($result['total_ht']);
853
		unset($result['total_ttc']);
854
855
		return $result;
856
	}
857
858
	/**
859
	 * Get fixed amount discount of a thirdparty (all sources: deposit, credit note, commercial offers...)
860
	 *
861
	 * @param 	int 	$id             ID of the thirdparty
862
	 * @param 	string 	$filter    	Filter exceptional discount. "none" will return every discount, "available" returns unapplied discounts, "used" returns applied discounts   {@choice none,available,used}
863
	 * @param   string  $sortfield  	Sort field
864
	 * @param   string  $sortorder  	Sort order
865
	 *
866
	 * @url     GET {id}/fixedamountdiscounts
867
	 *
868
	 * @return array  List of fixed discount of thirdparty
869
	 *
870
	 * @throws 400
871
	 * @throws 401
872
	 * @throws 404
873
	 * @throws 503
874
	 */
875
    public function getFixedAmountDiscounts($id, $filter = "none", $sortfield = "f.type", $sortorder = 'ASC')
876
	{
877
		$obj_ret = array();
878
879
		if(! DolibarrApiAccess::$user->rights->societe->lire) {
880
			throw new RestException(401);
881
		}
882
883
		if(empty($id)) {
884
			throw new RestException(400, 'Thirdparty ID is mandatory');
885
		}
886
887
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
888
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
889
		}
890
891
		$result = $this->company->fetch($id);
892
		if( ! $result ) {
893
			throw new RestException(404, 'Thirdparty not found');
894
		}
895
896
897
		$sql = "SELECT f.ref, f.type as factype, re.fk_facture_source, re.rowid, re.amount_ht, re.amount_tva, re.amount_ttc, re.description, re.fk_facture, re.fk_facture_line";
898
		$sql .= " FROM ".MAIN_DB_PREFIX."societe_remise_except as re, ".MAIN_DB_PREFIX."facture as f";
899
		$sql .= " WHERE f.rowid = re.fk_facture_source AND re.fk_soc = ".$id;
900
		if ($filter == "available")  $sql .= " AND re.fk_facture IS NULL AND re.fk_facture_line IS NULL";
901
		if ($filter == "used")  $sql .= " AND (re.fk_facture IS NOT NULL OR re.fk_facture_line IS NOT NULL)";
902
903
		$sql.= $this->db->order($sortfield, $sortorder);
904
905
		$result = $this->db->query($sql);
906
		if( ! $result ) {
907
			throw new RestException(503, $this->db->lasterror());
908
		} else {
909
			$num = $this->db->num_rows($result);
910
			while ( $obj = $this->db->fetch_object($result) ) {
911
				$obj_ret[] = $obj;
912
			}
913
		}
914
915
		return $obj_ret;
916
	}
917
918
919
920
	/**
921
	 * Return list of invoices qualified to be replaced by another invoice.
922
	 *
923
	 * @param int   $id             Id of thirdparty
924
	 *
925
	 * @url     GET {id}/getinvoicesqualifiedforreplacement
926
	 *
927
	 * @return array
928
	 * @throws 400
929
	 * @throws 401
930
	 * @throws 404
931
	 * @throws 405
932
	 */
933
    public function getInvoicesQualifiedForReplacement($id)
934
    {
935
		if(! DolibarrApiAccess::$user->rights->facture->lire) {
936
			throw new RestException(401);
937
		}
938
		if(empty($id)) {
939
			throw new RestException(400, 'Thirdparty ID is mandatory');
940
		}
941
942
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
943
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
944
		}
945
946
		/*$result = $this->thirdparty->fetch($id);
947
		 if( ! $result ) {
948
		 throw new RestException(404, 'Thirdparty not found');
949
		 }*/
950
951
		$invoice = new Facture($this->db);
952
		$result = $invoice->list_replacable_invoices($id);
953
		if( $result < 0) {
954
			throw new RestException(405, $this->thirdparty->error);
0 ignored issues
show
Bug Best Practice introduced by
The property thirdparty does not exist on Thirdparties. Did you maybe forget to declare it?
Loading history...
955
		}
956
957
		return $result;
958
	}
959
960
	/**
961
	 * Return list of invoices qualified to be corrected by a credit note.
962
	 * Invoices matching the following rules are returned
963
	 * (validated + payment on process) or classified (payed completely or payed partialy) + not already replaced + not already a credit note
964
	 *
965
	 * @param int   $id             Id of thirdparty
966
	 *
967
	 * @url     GET {id}/getinvoicesqualifiedforcreditnote
968
	 *
969
	 * @return array
970
	 * @throws 400
971
	 * @throws 401
972
	 * @throws 404
973
	 * @throws 405
974
	 */
975
    public function getInvoicesQualifiedForCreditNote($id)
976
    {
977
		if(! DolibarrApiAccess::$user->rights->facture->lire) {
978
			throw new RestException(401);
979
		}
980
		if(empty($id)) {
981
			throw new RestException(400, 'Thirdparty ID is mandatory');
982
		}
983
984
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
985
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
986
		}
987
988
		/*$result = $this->thirdparty->fetch($id);
989
		 if( ! $result ) {
990
		 throw new RestException(404, 'Thirdparty not found');
991
		 }*/
992
993
		$invoice = new Facture($this->db);
994
		$result = $invoice->list_qualified_avoir_invoices($id);
995
		if( $result < 0) {
996
			throw new RestException(405, $this->thirdparty->error);
0 ignored issues
show
Bug Best Practice introduced by
The property thirdparty does not exist on Thirdparties. Did you maybe forget to declare it?
Loading history...
997
		}
998
999
		return $result;
1000
	}
1001
1002
	/**
1003
	 * Get CompanyBankAccount objects for thirdparty
1004
	 *
1005
	 * @param int $id ID of thirdparty
1006
	 *
1007
	 * @return array
1008
	 *
1009
	 * @url GET {id}/bankaccounts
1010
	 */
1011
    public function getCompanyBankAccount($id)
1012
    {
1013
		global $db, $conf;
1014
1015
		if(! DolibarrApiAccess::$user->rights->facture->lire) {
1016
			throw new RestException(401);
1017
		}
1018
		if(empty($id)) {
1019
			throw new RestException(400, 'Thirdparty ID is mandatory');
1020
		}
1021
1022
		if( ! DolibarrApi::_checkAccessToResource('societe', $id)) {
1023
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1024
		}
1025
1026
		/**
1027
		 * We select all the records that match the socid
1028
		 */
1029
1030
		$sql = "SELECT rowid, fk_soc, bank, number, code_banque, code_guichet, cle_rib, bic, iban_prefix as iban, domiciliation, proprio,";
1031
		$sql.= " owner_address, default_rib, label, datec, tms as datem, rum, frstrecur";
1032
		$sql.= " FROM ".MAIN_DB_PREFIX."societe_rib";
1033
		if ($id) $sql.= " WHERE fk_soc  = ".$id." ";
1034
1035
1036
		$result = $db->query($sql);
1037
1038
		if($result->num_rows == 0 ){
1039
			throw new RestException(404, 'Account not found');
1040
		}
1041
1042
		$i=0;
1043
1044
		$accounts = array();
1045
1046
		if ($result)
1047
		{
1048
			$num = $db->num_rows($result);
1049
			while ($i < $num)
1050
			{
1051
				$obj = $db->fetch_object($result);
1052
				$account = new CompanyBankAccount($db);
1053
				if($account->fetch($obj->rowid)) {
1054
					$accounts[] = $account;
1055
				}
1056
				$i++;
1057
			}
1058
		}
1059
		else{
1060
			throw new RestException(404, 'Account not found');
1061
		}
1062
1063
1064
		$fields = array('socid', 'default_rib', 'frstrecur', '1000110000001', 'datec', 'datem', 'label', 'bank', 'bic', 'iban', 'id', 'rum');
1065
1066
		$returnAccounts = array();
1067
1068
		foreach($accounts as $account){
1069
			$object= array();
1070
			foreach($account as $key => $value)
1071
				if(in_array($key, $fields)){
1072
					$object[$key] = $value;
1073
				}
1074
			$returnAccounts[] = $object;
1075
		}
1076
1077
		return $returnAccounts;
1078
	}
1079
1080
	/**
1081
	 * Create CompanyBankAccount object for thirdparty
1082
	 * @param int  $id ID of thirdparty
1083
	 * @param array $request_data Request data
1084
	 *
1085
	 * @return object  ID of thirdparty
1086
	 *
1087
	 * @url POST {id}/bankaccounts
1088
	 */
1089
    public function createCompanyBankAccount($id, $request_data = null)
1090
	{
1091
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1092
			throw new RestException(401);
1093
		}
1094
1095
		$account = new CompanyBankAccount($this->db);
1096
1097
		$account->socid = $id;
1098
1099
		foreach($request_data as $field => $value) {
1100
			$account->$field = $value;
1101
		}
1102
1103
		if ($account->create(DolibarrApiAccess::$user) < 0)
1104
			throw new RestException(500, 'Error creating Company Bank account');
1105
1106
1107
		if ($account->update(DolibarrApiAccess::$user) < 0)
1108
			throw new RestException(500, 'Error updating values');
1109
1110
		return $account;
1111
	}
1112
1113
	/**
1114
	 * Update CompanyBankAccount object for thirdparty
1115
	 *
1116
	 * @param int $id ID of thirdparty
1117
	 * @param int  $bankaccount_id ID of CompanyBankAccount
1118
	 * @param array $request_data Request data
1119
	 *
1120
	 * @return object  ID of thirdparty
1121
	 *
1122
	 * @url PUT {id}/bankaccounts/{bankaccount_id}
1123
	 */
1124
    public function updateCompanyBankAccount($id, $bankaccount_id, $request_data = null)
1125
	{
1126
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1127
			throw new RestException(401);
1128
		}
1129
1130
		$account = new CompanyBankAccount($this->db);
1131
1132
		$account->fetch($bankaccount_id, $id, -1, '');
1133
1134
		if($account->socid != $id){
1135
			throw new RestException(401);
1136
		}
1137
1138
1139
		foreach($request_data as $field => $value) {
1140
			$account->$field = $value;
1141
		}
1142
1143
		if ($account->update(DolibarrApiAccess::$user) < 0)
1144
			throw new RestException(500, 'Error updating values');
1145
1146
		return $account;
1147
	}
1148
1149
	/**
1150
	 * Delete a bank account attached to a thirdparty
1151
	 *
1152
	 * @param int $id ID of thirdparty
1153
	 * @param int $bankaccount_id ID of CompanyBankAccount
1154
	 *
1155
	 * @return int -1 if error 1 if correct deletion
1156
	 *
1157
	 * @url DELETE {id}/bankaccounts/{bankaccount_id}
1158
	 */
1159
    public function deleteCompanyBankAccount($id, $bankaccount_id)
1160
    {
1161
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1162
			throw new RestException(401);
1163
		}
1164
1165
		$account = new CompanyBankAccount($this->db);
1166
1167
		$account->fetch($bankaccount_id);
1168
1169
		if(!$account->socid == $id)
1170
			throw new RestException(401);
1171
1172
		return $account->delete(DolibarrApiAccess::$user);
1173
	}
1174
1175
	/**
1176
	 * Generate a Document from a bank account record (like SEPA mandate)
1177
	 *
1178
	 * @param int 		$id 			Thirdparty id
1179
	 * @param int 		$companybankid 	Companybank id
1180
	 * @param string 	$model 			Model of document to generate
1181
	 * @return void
1182
	 *
1183
	 * @url GET {id}/generateBankAccountDocument/{companybankid}/{model}
1184
	 */
1185
	public function generateBankAccountDocument($id, $companybankid = null, $model = 'sepamandate')
1186
	{
1187
		global $conf;
1188
1189
		$this->langs->loadLangs(array("main","dict","commercial","products","companies","banks","bills","withdrawals"));
0 ignored issues
show
Bug Best Practice introduced by
The property langs does not exist on Thirdparties. Did you maybe forget to declare it?
Loading history...
1190
1191
		$this->company->fetch($id);
1192
1193
		$action = 'builddoc';
1194
		if(! DolibarrApiAccess::$user->rights->societe->creer)
1195
			throw new RestException(401);
1196
1197
		$this->company->setDocModel(DolibarrApiAccess::$user, $model);
1198
1199
		$this->company->fk_bank = $this->company->fk_account;
0 ignored issues
show
Bug introduced by
The property fk_bank does not seem to exist on Societe.
Loading history...
1200
1201
		$outputlangs = $this->langs;
1202
		$newlang='';
1203
1204
		if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang=GETPOST('lang_id', 'aZ09');
0 ignored issues
show
Bug Best Practice introduced by
The property conf does not exist on Thirdparties. Did you maybe forget to declare it?
Loading history...
1205
		if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->company->thirdparty->default_lang)) $newlang=$this->company->thirdparty->default_lang;  // for proposal, order, invoice, ...
1206
		if ($this->conf->global->MAIN_MULTILANGS && empty($newlang) && isset($this->company->default_lang)) $newlang=$this->company->default_lang;                  // for thirdparty
1207
		if (! empty($newlang)) {
1208
			$outputlangs = new Translate("", $conf);
1209
			$outputlangs->setDefaultLang($newlang);
1210
		}
1211
1212
		// To be sure vars is defined
1213
		$hidedetails = $hidedesc = $hideref = 0;
1214
		$moreparams=null;
1215
		if (empty($hidedetails)) $hidedetails=0;
1 ignored issue
show
introduced by
The condition empty($hidedetails) is always true.
Loading history...
1216
		if (empty($hidedesc)) $hidedesc=0;
1 ignored issue
show
introduced by
The condition empty($hidedesc) is always true.
Loading history...
1217
		if (empty($hideref)) $hideref=0;
1 ignored issue
show
introduced by
The condition empty($hideref) is always true.
Loading history...
1218
		if (empty($moreparams)) $moreparams=null;
0 ignored issues
show
introduced by
The condition empty($moreparams) is always false.
Loading history...
1219
1220
1221
		$sql = "SELECT rowid";
1222
		$sql.= " FROM ".MAIN_DB_PREFIX."societe_rib";
1223
		if ($id) $sql.= " WHERE fk_soc  = ".$id." ";
1224
		if ($companybankid) $sql.= " AND id = ".$companybankid."";
1 ignored issue
show
Bug Best Practice introduced by
The expression $companybankid of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1225
1226
		$i=0;
1227
		$accounts=array();
1228
1229
		$result = $this->db->query($sql);
1230
		if ($result)
1231
		{
1232
			if ($result->num_rows == 0) {
1233
				throw new RestException(404, 'Bank account not found');
1234
			}
1235
1236
			$num = $this->db->num_rows($result);
1237
			while ($i < $num)
1238
			{
1239
				$obj = $this->db->fetch_object($result);
1240
1241
				$account = new CompanyBankAccount($this->db);
1242
				if ($account->fetch($obj->rowid)) {
1243
					$accounts[] = $account;
1244
				}
1245
				$i++;
1246
			}
1247
		}
1248
		else
1249
		{
1250
			throw new RestException(404, 'Bank account not found');
1251
		}
1252
1253
		$moreparams = array(
1254
			'use_companybankid'=>$accounts[0]->id,
1255
			'force_dir_output'=>$this->conf->societe->multidir_output[$this->company->entity].'/'.dol_sanitizeFileName($this->company->id)
1256
		);
1257
1258
		$result = 0;
1259
1260
		$result = $this->company->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
1261
1262
		if ($result > 0)
1263
		{
1264
			return array("success" => $result);
1265
		}
1266
		else
1267
		{
1268
			throw new RestException(500);
1269
		}
1270
    }
1271
1272
  /**
1273
	 * Get a specific gateway attached to a thirdparty (by specifying the site key)
1274
	 *
1275
	 * @param int $id ID of thirdparty
1276
	 * @param string $site Site key
1277
	 *
1278
	 * @return SocieteAccount[]
1279
	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
1280
	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
1281
	 *
1282
	 * @url GET {id}/gateways/
1283
	 */
1284
    public function getSocieteAccounts($id, $site = null)
1285
    {
1286
		global $db, $conf;
1287
1288
		if(!DolibarrApiAccess::$user->rights->societe->lire) {
1289
			throw new RestException(401);
1290
		}
1291
1292
		if(!DolibarrApi::_checkAccessToResource('societe', $id)) {
1293
			throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
1294
		}
1295
1296
		/**
1297
		 * We select all the records that match the socid
1298
		 */
1299
		$sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms FROM ".MAIN_DB_PREFIX."societe_account";
1300
		$sql.= " WHERE fk_soc = $id";
1301
		if($site) $sql .= " AND site ='$site'";
1302
1303
		$result = $db->query($sql);
1304
1305
		if($result->num_rows == 0){
1306
			throw new RestException(404, 'This thirdparty does not have any gateway attached or does not exist.');
1307
		}
1308
1309
		$i=0;
1310
1311
		$accounts = array();
1312
1313
		$num = $db->num_rows($result);
1314
		while ($i < $num)
1315
		{
1316
			$obj = $db->fetch_object($result);
1317
			$account = new SocieteAccount($db);
1318
1319
			if($account->fetch($obj->rowid)) {
1320
				$accounts[] = $account;
1321
			}
1322
			$i++;
1323
		}
1324
1325
		$fields = array('id', 'fk_soc', 'key_account', 'site', 'date_creation', 'tms');
1326
1327
		$returnAccounts = array();
1328
1329
		foreach($accounts as $account){
1330
			$object= array();
1331
			foreach($account as $key => $value)
1332
				if(in_array($key, $fields)){
1333
					$object[$key] = $value;
1334
				}
1335
			$returnAccounts[] = $object;
1336
		}
1337
1338
		return $returnAccounts;
1339
	}
1340
1341
	/**
1342
	 * Create and attach a new gateway to an existing thirdparty
1343
	 *
1344
	 * Possible fields for request_data (request body) are specified in <code>llx_societe_account</code> table.<br>
1345
	 * See <a href="https://wiki.dolibarr.org/index.php/Table_llx_societe_account">Table llx_societe_account</a> wiki page for more information<br><br>
1346
	 * <u>Example body payload :</u> <pre>{"key_account": "cus_DAVkLSs1LYyYI", "site": "stripe"}</pre>
1347
	 *
1348
	 * @param int $id ID of thirdparty
1349
	 * @param array $request_data Request data
1350
	 *
1351
	 * @return SocieteAccount
1352
	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
1353
	 * @throws 409 Conflict: A SocieteAccount entity (gateway) already exists for this company and site.
1354
	 * @throws 422 Unprocessable Entity: You must pass the site attribute in your request data !
1355
	 * @throws 500 Internal Server Error: Error creating SocieteAccount account
1356
	 * @status 201
1357
	 *
1358
	 * @url POST {id}/gateways
1359
	 */
1360
    public function createSocieteAccount($id, $request_data = null)
1361
	{
1362
		global $db;
1363
1364
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1365
			throw new RestException(401);
1366
		}
1367
1368
		if(!isset($request_data['site'])) {
1369
			throw new RestException(422, 'Unprocessable Entity: You must pass the site attribute in your request data !');
1370
		}
1371
1372
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = ".$id." AND site = '". $request_data['site']."' ";
1373
		$result = $db->query($sql);
1374
1375
		if($result->num_rows == 0 ){
1376
			$account = new SocieteAccount($this->db);
1377
			if(!isset($request_data['login'])) {
1378
				$account->login = "";
1379
			}
1380
			$account->fk_soc = $id;
1381
1382
			foreach($request_data as $field => $value) {
1383
				$account->$field = $value;
1384
			}
1385
1386
			if ($account->create(DolibarrApiAccess::$user) < 0)
1387
				throw new RestException(500, 'Error creating SocieteAccount entity. Ensure that the ID of thirdparty provided does exist!');
1388
1389
			$this->_cleanObjectDatas($account);
1390
1391
			return $account;
1392
		} else {
1393
			throw new RestException(409, 'A SocieteAccount entity already exists for this company and site.');
1394
		}
1395
	}
1396
1397
	/**
1398
	 * Create and attach a new (or replace an existing) specific site gateway to a thirdparty
1399
	 *
1400
	 * You <strong>MUST</strong> pass all values to keep (otherwise, they will be deleted) !<br>
1401
	 * If you just need to update specific fields prefer <code>PATCH /thirdparties/{id}/gateways/{site}</code> endpoint.<br><br>
1402
	 * When a <strong>SocieteAccount</strong> entity does not exist for the <code>id</code> and <code>site</code>
1403
	 * supplied, a new one will be created. In that case <code>fk_soc</code> and <code>site</code> members form
1404
	 * request body payload will be ignored and <code>id</code> and <code>site</code> query strings parameters
1405
	 * will be used instead.
1406
	 *
1407
	 * @param int $id ID of thirdparty
1408
	 * @param string $site Site key
1409
	 * @param array $request_data Request data
1410
	 *
1411
	 * @return SocieteAccount
1412
	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
1413
	 * @throws 422 Unprocessable Entity: You must pass the site attribute in your request data !
1414
	 * @throws 500 Internal Server Error: Error updating SocieteAccount entity
1415
	 *
1416
	 * @throws RestException
1417
	 * @url PUT {id}/gateways/{site}
1418
	 */
1419
    public function putSocieteAccount($id, $site, $request_data = null)
1420
	{
1421
		global $db;
1422
1423
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1424
			throw new RestException(401);
1425
		}
1426
1427
		$sql = "SELECT rowid, fk_user_creat, date_creation FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc = $id AND site = '$site' ";
1428
		$result = $db->query($sql);
1429
1430
		// We do not found an existing SocieteAccount entity for this fk_soc and site ; we then create a new one.
1431
		if($result->num_rows == 0 ){
1432
			if(!isset($request_data['key_account'])) {
1433
				throw new RestException(422, 'Unprocessable Entity: You must pass the key_account attribute in your request data !');
1434
			}
1435
			$account = new SocieteAccount($this->db);
1436
			if(!isset($request_data['login'])) {
1437
				$account->login = "";
1438
			}
1439
1440
			foreach($request_data as $field => $value) {
1441
				$account->$field = $value;
1442
			}
1443
1444
			$account->fk_soc = $id;
1445
			$account->site = $site;
1446
1447
			if ($account->create(DolibarrApiAccess::$user) < 0)
1448
				throw new RestException(500, 'Error creating SocieteAccount entity.');
1449
		// We found an existing SocieteAccount entity, we are replacing it
1450
		} else {
1451
1452
			if(isset($request_data['site']) && $request_data['site'] !== $site) {
1453
				$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = ".$id." AND site = '". $request_data['site']."' ";
1454
				$result = $db->query($sql);
1455
1456
				if($result->num_rows !== 0)
1457
					throw new RestException(409, "You are trying to update this thirdparty SocieteAccount (gateway record) from $site to ".$request_data['site'] . " but another SocieteAccount entity already exists with this site key.");
1458
			}
1459
1460
			$obj = $db->fetch_object($result);
1461
1462
			$account = new SocieteAccount($this->db);
1463
			$account->id = $obj->rowid;
1464
			$account->fk_soc = $id;
1465
			$account->site = $site;
1466
			if(!isset($request_data['login'])) {
1467
				$account->login = "";
1468
			}
1469
			$account->fk_user_creat = $obj->fk_user_creat;
1470
			$account->date_creation = $obj->date_creation;
1471
1472
			foreach($request_data as $field => $value) {
1473
				$account->$field = $value;
1474
			}
1475
1476
			if ($account->update(DolibarrApiAccess::$user) < 0)
1477
				throw new RestException(500, 'Error updating SocieteAccount entity.');
1478
		}
1479
1480
		$this->_cleanObjectDatas($account);
1481
1482
		return $account;
1483
	}
1484
1485
	/**
1486
	 * Update specified values of a specific site gateway attached to a thirdparty
1487
	 *
1488
	 * @param int $id Id of thirdparty
1489
	 * @param string  $site Site key
1490
	 * @param array $request_data Request data
1491
	 *
1492
	 * @return SocieteAccount
1493
	 * @throws 401 Unauthorized: User does not have permission to read thirdparties
1494
	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
1495
	 * @throws 409 Conflict: Another SocieteAccount entity already exists for this thirdparty with this site key.
1496
	 * @throws 500 Internal Server Error: Error updating SocieteAccount entity
1497
	 *
1498
	 * @url PATCH {id}/gateways/{site}
1499
	 */
1500
    public function patchSocieteAccount($id, $site, $request_data = null)
1501
	{
1502
		global $db;
1503
1504
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1505
			throw new RestException(401);
1506
		}
1507
1508
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = $id AND site = '$site' ";
1509
		$result = $db->query($sql);
1510
1511
		if($result->num_rows == 0 ){
1512
			throw new RestException(404, "This thirdparty does not have $site gateway attached or does not exist.");
1513
		} else {
1514
1515
			// If the user tries to edit the site member, we check first if
1516
			if(isset($request_data['site']) && $request_data['site'] !== $site) {
1517
				$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = ".$id." AND site = '". $request_data['site']."' ";
1518
				$result = $db->query($sql);
1519
1520
				if($result->num_rows !== 0)
1521
					throw new RestException(409, "You are trying to update this thirdparty SocieteAccount (gateway record) site member from $site to ".$request_data['site'] . " but another SocieteAccount entity already exists for this thirdparty with this site key.");
1522
			}
1523
1524
			$obj = $db->fetch_object($result);
1525
			$account = new SocieteAccount($this->db);
1526
			$account->fetch($obj->rowid);
1527
1528
			foreach($request_data as $field => $value) {
1529
				$account->$field = $value;
1530
			}
1531
1532
			if ($account->update(DolibarrApiAccess::$user) < 0)
1533
				throw new RestException(500, 'Error updating SocieteAccount account');
1534
1535
			$this->_cleanObjectDatas($account);
1536
1537
			return $account;
1538
		}
1539
	}
1540
1541
	/**
1542
	 * Delete a specific site gateway attached to a thirdparty (by gateway id)
1543
	 *
1544
	 * @param int $id ID of thirdparty
1545
	 * @param int $site Site key
1546
	 *
1547
	 * @return void
1548
	 * @throws 401 Unauthorized: User does not have permission to delete thirdparties gateways
1549
	 * @throws 404 Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
1550
	 * @throws 500 Internal Server Error: Error deleting SocieteAccount entity
1551
	 *
1552
	 * @url DELETE {id}/gateways/{site}
1553
	 */
1554
    public function deleteSocieteAccount($id, $site)
1555
    {
1556
		global /** @var Database $db */
1557
		$db;
1558
1559
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1560
			throw new RestException(401);
1561
		}
1562
1563
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = $id AND site = '$site' ";
1564
		$result = $db->query($sql);
1565
1566
		if($result->num_rows == 0 ){
1567
			throw new RestException(404);
1568
		} else {
1569
			$obj = $db->fetch_object($result);
1570
			$account = new SocieteAccount($this->db);
1571
			$account->fetch($obj->rowid);
1572
1573
			if($account->delete(DolibarrApiAccess::$user) < 0) {
1574
				throw new RestException(500, "Error while deleting $site gateway attached to this third party");
1575
			}
1576
		}
1577
	}
1578
1579
	/**
1580
	 * Delete all gateways attached to a thirdparty
1581
	 *
1582
	 * @param int $id ID of thirdparty
1583
	 *
1584
	 * @return void
1585
	 * @throws RestException(401) Unauthorized: User does not have permission to delete thirdparties gateways
1586
	 * @throws RestException(404) Not Found: Specified thirdparty ID does not belongs to an existing thirdparty
1587
	 * @throws RestException(500) Internal Server Error: Error deleting SocieteAccount entity
1588
	 *
1589
	 * @url DELETE {id}/gateways
1590
	 */
1591
    public function deleteSocieteAccounts($id)
1592
    {
1593
		global /** @var Database $db */
1594
		$db;
1595
1596
		if(! DolibarrApiAccess::$user->rights->societe->creer) {
1597
			throw new RestException(401);
1598
		}
1599
1600
		/**
1601
		 * We select all the records that match the socid
1602
		 */
1603
1604
		$sql = "SELECT rowid, fk_soc, key_account, site, date_creation, tms";
1605
		$sql.= " FROM ".MAIN_DB_PREFIX."societe_account WHERE fk_soc  = $id ";
1606
1607
		$result = $db->query($sql);
1608
1609
		if($result->num_rows == 0 ){
1610
			throw new RestException(404, 'This third party does not have any gateway attached or does not exist.');
1611
		} else {
1612
			$i=0;
1613
1614
			$num = $db->num_rows($result);
1615
			while ($i < $num)
1616
			{
1617
				$obj = $db->fetch_object($result);
1618
				$account = new SocieteAccount($db);
1619
				$account->fetch($obj->rowid);
1620
1621
				if($account->delete(DolibarrApiAccess::$user) < 0) {
1622
					throw new RestException(500, 'Error while deleting gateways attached to this third party');
1623
				}
1624
				$i++;
1625
			}
1626
		}
1627
	}
1628
1629
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
1630
	/**
1631
	 * Clean sensible object datas
1632
	 *
1633
	 * @param   object  $object    Object to clean
1634
	 * @return    array    Array of cleaned object properties
1635
	 */
1636
	protected function _cleanObjectDatas($object)
1637
    {
1638
        // phpcs:enable
1639
		$object = parent::_cleanObjectDatas($object);
1640
1641
		unset($object->nom);	// ->name already defined and nom deprecated
1642
1643
		unset($object->total_ht);
1644
		unset($object->total_tva);
1645
		unset($object->total_localtax1);
1646
		unset($object->total_localtax2);
1647
		unset($object->total_ttc);
1648
1649
		unset($object->lines);
1650
		unset($object->thirdparty);
1651
1652
		return $object;
1653
	}
1654
1655
	/**
1656
	 * Validate fields before create or update object
1657
	 *
1658
	 * @param array $data   Datas to validate
1659
	 * @return array
1660
	 *
1661
	 * @throws RestException
1662
	 */
1663
    private function _validate($data)
1664
    {
1665
        $thirdparty = array();
1666
        foreach (Thirdparties::$FIELDS as $field) {
1667
            if (!isset($data[$field]))
1668
                throw new RestException(400, "$field field missing");
1669
            $thirdparty[$field] = $data[$field];
1670
        }
1671
        return $thirdparty;
1672
    }
1673
}
1674