Completed
Branch develop (7b1a70)
by
unknown
28:52
created

Societe::delete()   F

Complexity

Conditions 24
Paths 12100

Size

Total Lines 117

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 24
nc 12100
nop 3
dl 0
loc 117
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/* Copyright (C) 2002-2006  Rodolphe Quiedeville    <[email protected]>
3
 * Copyright (C) 2004-2015  Laurent Destailleur     <[email protected]>
4
 * Copyright (C) 2004       Eric Seigne             <[email protected]>
5
 * Copyright (C) 2003       Brian Fraval            <[email protected]>
6
 * Copyright (C) 2006       Andre Cianfarani        <[email protected]>
7
 * Copyright (C) 2005-2017  Regis Houssin           <[email protected]>
8
 * Copyright (C) 2008       Patrick Raguin          <[email protected]>
9
 * Copyright (C) 2010-2014  Juanjo Menent           <[email protected]>
10
 * Copyright (C) 2013       Florian Henry           <[email protected]>
11
 * Copyright (C) 2013       Alexandre Spangaro      <[email protected]>
12
 * Copyright (C) 2013       Peter Fontaine          <[email protected]>
13
 * Copyright (C) 2014-2015  Marcos García           <[email protected]>
14
 * Copyright (C) 2015       Raphaël Doursenaud      <[email protected]>
15
 * Copyright (C) 2017       Rui Strecht			    <[email protected]>
16
 *
17
 * This program is free software; you can redistribute it and/or modify
18
 * it under the terms of the GNU General Public License as published by
19
 * the Free Software Foundation; either version 3 of the License, or
20
 * (at your option) any later version.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25
 * GNU General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU General Public License
28
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29
 */
30
31
/**
32
 *	\file       htdocs/societe/class/societe.class.php
33
 *	\ingroup    societe
34
 *	\brief      File for third party class
35
 */
36
require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
37
require_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
38
39
/**
40
 *	Class to manage third parties objects (customers, suppliers, prospects...)
41
 */
42
class Societe extends CommonObject
43
{
44
	/**
45
	 * @var string ID to identify managed object
46
	 */
47
	public $element='societe';
48
49
	/**
50
	 * @var string Name of table without prefix where object is stored
51
	 */
52
	public $table_element = 'societe';
53
54
	public $fk_element='fk_soc';
55
	public $fieldsforcombobox='nom,name_alias';
56
	protected $childtables=array("supplier_proposal"=>'SupplierProposal',"propal"=>'Proposal',"commande"=>'Order',"facture"=>'Invoice',"facture_rec"=>'RecurringInvoiceTemplate',"contrat"=>'Contract',"fichinter"=>'Fichinter',"facture_fourn"=>'SupplierInvoice',"commande_fournisseur"=>'SupplierOrder',"projet"=>'Project',"expedition"=>'Shipment',"prelevement_lignes"=>'DirectDebitRecord');    // To test if we can delete object
57
	protected $childtablesoncascade=array("societe_prices", "societe_log", "societe_address", "product_fournisseur_price", "product_customer_price_log", "product_customer_price", "socpeople", "adherent", "societe_rib", "societe_remise", "societe_remise_except", "societe_commerciaux", "categorie", "notify", "notify_def", "actioncomm");
58
	public $picto = 'company';
59
60
	/**
61
	 * 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
62
	 * @var int
63
	 */
64
	public $ismultientitymanaged = 1;
65
	/**
66
	 * 0=Default, 1=View may be restricted to sales representative only if no permission to see all or to company of external user if external user
67
	 * @var integer
68
	 */
69
	public $restrictiononfksoc = 1;
70
71
72
	// BEGIN MODULEBUILDER PROPERTIES
73
	/**
74
	 * @var array  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
75
	 */
76
	public $fields=array(
77
		'rowid'         =>array('type'=>'integer',      'label'=>'TechnicalID',      'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'index'=>1, 'position'=>1, 'comment'=>'Id'),
78
		'nom'           =>array('type'=>'varchar(128)', 'label'=>'Name',            'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
79
		'name_alias'    =>array('type'=>'varchar(128)', 'label'=>'Name',            'enabled'=>1, 'visible'=>1,  'notnull'=>1,  'showoncombobox'=>1, 'index'=>1, 'position'=>10, 'searchall'=>1, 'comment'=>'Reference of object'),
80
		'entity'        =>array('type'=>'integer',      'label'=>'Entity',           'enabled'=>1, 'visible'=>0,  'default'=>1, 'notnull'=>1,  'index'=>1, 'position'=>20),
81
		'note_public'   =>array('type'=>'text',			'label'=>'NotePublic',		 'enabled'=>1, 'visible'=>0,  'position'=>60),
82
		'note_private'  =>array('type'=>'text',			'label'=>'NotePrivate',		 'enabled'=>1, 'visible'=>0,  'position'=>61),
83
		'date_creation' =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>500),
84
		'tms'           =>array('type'=>'timestamp',    'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>501),
85
		//'date_valid'    =>array('type'=>'datetime',     'label'=>'DateCreation',     'enabled'=>1, 'visible'=>-2, 'position'=>502),
86
		'fk_user_creat' =>array('type'=>'integer',      'label'=>'UserAuthor',       'enabled'=>1, 'visible'=>-2, 'notnull'=>1,  'position'=>510),
87
		'fk_user_modif' =>array('type'=>'integer',      'label'=>'UserModif',        'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'position'=>511),
88
		//'fk_user_valid' =>array('type'=>'integer',      'label'=>'UserValidation',        'enabled'=>1, 'visible'=>-1, 'position'=>512),
89
		'import_key'    =>array('type'=>'varchar(14)',  'label'=>'ImportId',         'enabled'=>1, 'visible'=>-2, 'notnull'=>-1, 'index'=>1,  'position'=>1000),
90
	);
91
92
93
	public $entity;
94
95
	/**
96
	 * Thirdparty name
97
	 * @var string
98
	 * @deprecated Use $name instead
99
	 * @see name
100
	 */
101
	public $nom;
102
103
	/**
104
	 * Alias names (commercial, trademark or alias names)
105
	 * @var string
106
	 */
107
	public $name_alias;
108
109
	public $particulier;
110
	public $address;
111
	public $zip;
112
	public $town;
113
114
	/**
115
	 * Thirdparty status : 0=activity ceased, 1= in activity
116
	 * @var int
117
	 */
118
	public $status=1;
119
120
	/**
121
	 * Id of department
122
	 * @var int
123
	 */
124
	public $state_id;
125
	public $state_code;
126
	public $state;
127
128
	/**
129
	 * Id of region
130
	 * @var int
131
	 */
132
	public $region_code;
133
	public $region;
134
135
	/**
136
	 * State code
137
	 * @var string
138
	 * @deprecated Use state_code instead
139
	 * @see state_code
140
	 */
141
	public $departement_code;
142
143
	/**
144
	 * @var string
145
	 * @deprecated Use state instead
146
	 * @see state
147
	 */
148
	public $departement;
149
150
	/**
151
	 * @var string
152
	 * @deprecated Use country instead
153
	 * @see country
154
	 */
155
	public $pays;
156
157
	/**
158
	 * Phone number
159
	 * @var string
160
	 */
161
	public $phone;
162
	/**
163
	 * Fax number
164
	 * @var string
165
	 */
166
	public $fax;
167
	/**
168
	 * Email
169
	 * @var string
170
	 */
171
	public $email;
172
	/**
173
	 * Skype username
174
	 * @var string
175
	 */
176
	public $skype;
177
	/**
178
	 * Webpage
179
	 * @var string
180
	 */
181
	public $url;
182
183
	//! barcode
184
	/**
185
	 * Barcode value
186
	 * @var string
187
	 */
188
	public $barcode;
189
190
	// 6 professional id (usage depends on country)
191
192
	/**
193
	 * Professional ID 1 (Ex: Siren in France)
194
	 * @var string
195
	 */
196
	public $idprof1;
197
198
	/**
199
	 * Professional ID 2 (Ex: Siret in France)
200
	 * @var string
201
	 */
202
	public $idprof2;
203
204
	/**
205
	 * Professional ID 3 (Ex: Ape in France)
206
	 * @var string
207
	 */
208
	public $idprof3;
209
210
	/**
211
	 * Professional ID 4 (Ex: RCS in France)
212
	 * @var string
213
	 */
214
	public $idprof4;
215
216
	/**
217
	 * Professional ID 5
218
	 * @var string
219
	 */
220
	public $idprof5;
221
222
	/**
223
	 * Professional ID 6
224
	 * @var string
225
	 */
226
	public $idprof6;
227
228
	public $prefix_comm;
229
230
	public $tva_assuj=1;
231
	/**
232
	 * Intracommunitary VAT ID
233
	 * @var string
234
	 */
235
	public $tva_intra;
236
237
	// Local taxes
238
	public $localtax1_assuj;
239
	public $localtax1_value;
240
	public $localtax2_assuj;
241
	public $localtax2_value;
242
243
	public $managers;
244
	public $capital;
245
	public $typent_id=0;
246
	public $typent_code;
247
	public $effectif;
248
	public $effectif_id=0;
249
	public $forme_juridique_code;
250
	public $forme_juridique=0;
251
252
	public $remise_percent;
253
	public $remise_supplier_percent;
254
	public $mode_reglement_supplier_id;
255
	public $cond_reglement_supplier_id;
256
	public $fk_prospectlevel;
257
	public $name_bis;
258
259
	//Log data
260
261
	/**
262
	 * Date of last update
263
	 * @var string
264
	 */
265
	public $date_modification;
266
	/**
267
	 * User that made last update
268
	 * @var string
269
	 */
270
	public $user_modification;
271
	/**
272
	 * Date of creation
273
	 * @var string
274
	 */
275
	public $date_creation;
276
	/**
277
	 * User that created the thirdparty
278
	 * @var User
279
	 */
280
	public $user_creation;
281
282
283
	public $specimen;
284
285
	/**
286
	 * 0=no customer, 1=customer, 2=prospect, 3=customer and prospect
287
	 * @var int
288
	 */
289
	public $client=0;
290
	/**
291
	 * 0=no prospect, 1=prospect
292
	 * @var int
293
	 */
294
	public $prospect=0;
295
	/**
296
	 * 0=no supplier, 1=supplier
297
	 * @var int
298
	 */
299
	public $fournisseur;
300
301
	/**
302
	 * Client code. E.g: CU2014-003
303
	 * @var string
304
	 */
305
	public $code_client;
306
307
	/**
308
	 * Supplier code. E.g: SU2014-003
309
	 * @var string
310
	 */
311
	public $code_fournisseur;
312
313
	/**
314
	 * Accounting code for client
315
	 * @var string
316
	 */
317
	public $code_compta;
318
319
	/**
320
	 * Accounting code for suppliers
321
	 * @var string
322
	 */
323
	public $code_compta_fournisseur;
324
325
	/**
326
	 * @var string
327
	 * @deprecated Note is split in public and private notes
328
	 * @see note_public, note_private
329
	 */
330
	public $note;
331
332
	/**
333
	 * Private note
334
	 * @var string
335
	 */
336
	public $note_private;
337
338
	/**
339
	 * Public note
340
	 * @var string
341
	 */
342
	public $note_public;
343
344
	//! code statut prospect
345
	public $stcomm_id;
346
	public $statut_commercial;
347
348
	/**
349
	 * Assigned price level
350
	 * @var int
351
	 */
352
	public $price_level;
353
	public $outstanding_limit;
354
355
	/**
356
	 * Min order amounts
357
	 */
358
	public $order_min_amount;
359
	public $supplier_order_min_amount;
360
361
	/**
362
	 * Id of sales representative to link (used for thirdparty creation). Not filled by a fetch, because we can have several sales representatives.
363
	 * @var int
364
	 */
365
	public $commercial_id;
366
	/**
367
	 * Id of parent thirdparty (if one)
368
	 * @var int
369
	 */
370
	public $parent;
371
	/**
372
	 * Default language code of thirdparty (en_US, ...)
373
	 * @var string
374
	 */
375
	public $default_lang;
376
377
	public $ref;
378
	public $ref_int;
379
	/**
380
	 * External user reference.
381
	 * This is to allow external systems to store their id and make self-developed synchronizing functions easier to
382
	 * build.
383
	 * @var string
384
	 */
385
	public $ref_ext;
386
387
	/**
388
	 * Import key.
389
	 * Set when the thirdparty has been created through an import process. This is to relate those created thirdparties
390
	 * to an import process
391
	 * @var string
392
	 */
393
	public $import_key;
394
395
	/**
396
	 * Supplier WebServices URL
397
	 * @var string
398
	 */
399
	public $webservices_url;
400
401
	/**
402
	 * Supplier WebServices Key
403
	 * @var string
404
	 */
405
	public $webservices_key;
406
407
	public $logo;
408
	public $logo_small;
409
	public $logo_mini;
410
411
	public $array_options;
412
413
	// Incoterms
414
	public $fk_incoterms;
415
	public $location_incoterms;
416
	public $libelle_incoterms;  //Used into tooltip
417
418
	// Multicurrency
419
	public $fk_multicurrency;
420
	public $multicurrency_code;
421
422
423
	// END MODULEBUILDER PROPERTIES
424
425
426
	/**
427
	 *    Constructor
428
	 *
429
	 *    @param	DoliDB		$db		Database handler
430
	 */
431
	public function __construct($db)
432
	{
433
		$this->db = $db;
434
435
		$this->client = 0;
436
		$this->prospect = 0;
437
		$this->fournisseur = 0;
438
		$this->typent_id  = 0;
439
		$this->effectif_id  = 0;
440
		$this->forme_juridique_code  = 0;
441
		$this->tva_assuj = 1;
442
		$this->status = 1;
443
	}
444
445
446
	/**
447
	 *    Create third party in database.
448
	 *    $this->code_client = -1 and $this->code_fournisseur = -1 means automatic assignement.
449
	 *
450
	 *    @param	User	$user       Object of user that ask creation
451
	 *    @return   int         		>= 0 if OK, < 0 if KO
452
	 */
453
	function create(User $user)
454
	{
455
		global $langs,$conf,$mysoc;
456
457
		$error=0;
458
459
		// Clean parameters
460
		if (empty($this->status)) $this->status=0;
461
		$this->name=$this->name?trim($this->name):trim($this->nom);
462
		if (! empty($conf->global->MAIN_FIRST_TO_UPPER)) $this->name=ucwords($this->name);
463
		$this->nom=$this->name; // For backward compatibility
464
		if (empty($this->client))      $this->client=0;
465
		if (empty($this->fournisseur)) $this->fournisseur=0;
466
		$this->import_key = trim($this->import_key);
467
468
		if (!empty($this->multicurrency_code)) $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
469
		if (empty($this->fk_multicurrency))
470
		{
471
			$this->multicurrency_code = '';
472
			$this->fk_multicurrency = 0;
473
		}
474
475
		dol_syslog(get_class($this)."::create ".$this->name);
476
477
		$now=dol_now();
478
479
		$this->db->begin();
480
481
		// For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts)
482
		if ($this->code_client == -1 || $this->code_client === 'auto')           $this->get_codeclient($this,0);
483
		if ($this->code_fournisseur == -1 || $this->code_fournisseur === 'auto') $this->get_codefournisseur($this,1);
484
485
		// Check more parameters (including mandatory setup
486
		// If error, this->errors[] is filled
487
		$result = $this->verify();
488
489
		if ($result >= 0)
490
		{
491
			$this->entity = ((isset($this->entity) && is_numeric($this->entity))?$this->entity:$conf->entity);
492
493
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe (nom, name_alias, entity, datec, fk_user_creat, canvas, status, ref_int, ref_ext, fk_stcomm, fk_incoterms, location_incoterms ,import_key, fk_multicurrency, multicurrency_code)";
494
			$sql.= " VALUES ('".$this->db->escape($this->name)."', '".$this->db->escape($this->name_alias)."', ".$this->db->escape($this->entity).", '".$this->db->idate($now)."'";
495
			$sql.= ", ".(! empty($user->id) ? "'".$user->id."'":"null");
496
			$sql.= ", ".(! empty($this->canvas) ? "'".$this->db->escape($this->canvas)."'":"null");
497
			$sql.= ", ".$this->status;
498
			$sql.= ", ".(! empty($this->ref_int) ? "'".$this->db->escape($this->ref_int)."'":"null");
499
			$sql.= ", ".(! empty($this->ref_ext) ? "'".$this->db->escape($this->ref_ext)."'":"null");
500
			$sql.= ", 0";
501
			$sql.= ", ".(int) $this->fk_incoterms;
502
			$sql.= ", '".$this->db->escape($this->location_incoterms)."'";
503
			$sql.= ", ".(! empty($this->import_key) ? "'".$this->db->escape($this->import_key)."'":"null");
504
			$sql.= ", ".(int) $this->fk_multicurrency;
505
			$sql.= ", '".$this->db->escape($this->multicurrency_code)."')";
506
507
			dol_syslog(get_class($this)."::create", LOG_DEBUG);
508
			$result=$this->db->query($sql);
509
			if ($result)
510
			{
511
				$this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."societe");
512
513
				$ret = $this->update($this->id,$user,0,1,1,'add');
514
515
				// Ajout du commercial affecte
516
				if ($this->commercial_id != '' && $this->commercial_id != -1)
517
				{
518
					$this->add_commercial($user, $this->commercial_id);
519
				}
520
				// si un commercial cree un client il lui est affecte automatiquement
521
				else if (empty($user->rights->societe->client->voir))
522
				{
523
					$this->add_commercial($user, $user->id);
524
				}
525
526
				if ($ret >= 0)
527
				{
528
					// Call trigger
529
					$result=$this->call_trigger('COMPANY_CREATE',$user);
530
					if ($result < 0) $error++;
531
					// End call triggers
532
				}
533
				else $error++;
534
535
				if (! $error)
536
				{
537
					dol_syslog(get_class($this)."::Create success id=".$this->id);
538
					$this->db->commit();
539
					return $this->id;
540
				}
541
				else
542
				{
543
					dol_syslog(get_class($this)."::Create echec update ".$this->error." ".join(',',$this->errors), LOG_ERR);
544
					$this->db->rollback();
545
					return -4;
546
				}
547
			}
548
			else
549
			{
550
				if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
551
				{
552
					$this->error=$langs->trans("ErrorCompanyNameAlreadyExists",$this->name);    // duplicate on a field (code or profid or ...)
553
					$result=-1;
554
				}
555
				else
556
				{
557
					$this->error=$this->db->lasterror();
558
					$result=-2;
559
				}
560
				$this->db->rollback();
561
				return $result;
562
			}
563
564
		}
565
		else
566
		{
567
			$this->db->rollback();
568
			dol_syslog(get_class($this)."::Create fails verify ".join(',',$this->errors), LOG_WARNING);
569
			return -3;
570
		}
571
	}
572
573
574
	/**
575
	 * Create a contact/address from thirdparty
576
	 *
577
	 * @param 	User	$user		Object user
578
	 * @return 	int					<0 if KO, >0 if OK
579
	 */
580
	function create_individual(User $user)
581
	{
582
		require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
583
		$contact=new Contact($this->db);
584
585
		$contact->name              = $this->name_bis;
586
		$contact->firstname         = $this->firstname;
587
		$contact->civility_id       = $this->civility_id;
588
		$contact->socid             = $this->id;	// fk_soc
589
		$contact->statut            = 1;
590
		$contact->priv              = 0;
591
		$contact->country_id        = $this->country_id;
592
		$contact->state_id          = $this->state_id;
593
		$contact->address           = $this->address;
594
		$contact->email             = $this->email;
595
		$contact->zip               = $this->zip;
596
		$contact->town              = $this->town;
597
		$contact->phone_pro         = $this->phone;
598
599
		$result = $contact->create($user);
600
		if ($result < 0)
601
		{
602
			$this->error = $contact->error;
603
			$this->errors = $contact->errors;
604
			dol_syslog(get_class($this)."::create_individual ERROR:" . $this->error, LOG_ERR);
605
		}
606
607
		return $result;
608
	}
609
610
	/**
611
	 *    Check properties of third party are ok (like name, third party codes, ...)
612
	 *    Used before an add or update.
613
	 *
614
	 *    @return     int		0 if OK, <0 if KO
615
	 */
616
	function verify()
617
	{
618
		global $conf, $langs, $mysoc;
619
620
		$error = 0;
621
		$this->errors=array();
622
623
		$result = 0;
624
		$this->name	= trim($this->name);
625
		$this->nom=$this->name; // For backward compatibility
626
627
		if (! $this->name)
628
		{
629
			$this->errors[] = 'ErrorBadThirdPartyName';
630
			$result = -2;
631
		}
632
633
		if ($this->client)
634
		{
635
			$rescode = $this->check_codeclient();
636
			if ($rescode <> 0)
637
			{
638
				if ($rescode == -1)
639
				{
640
					$this->errors[] = 'ErrorBadCustomerCodeSyntax';
641
				}
642
				if ($rescode == -2)
643
				{
644
					$this->errors[] = 'ErrorCustomerCodeRequired';
645
				}
646
				if ($rescode == -3)
647
				{
648
					$this->errors[] = 'ErrorCustomerCodeAlreadyUsed';
649
				}
650
				if ($rescode == -4)
651
				{
652
					$this->errors[] = 'ErrorPrefixRequired';
653
				}
654
				$result = -3;
655
			}
656
		}
657
658
		if ($this->fournisseur)
659
		{
660
			$rescode = $this->check_codefournisseur();
661
			if ($rescode <> 0)
662
			{
663
				if ($rescode == -1)
664
				{
665
					$this->errors[] = 'ErrorBadSupplierCodeSyntax';
666
				}
667
				if ($rescode == -2)
668
				{
669
					$this->errors[] = 'ErrorSupplierCodeRequired';
670
				}
671
				if ($rescode == -3)
672
				{
673
					$this->errors[] = 'ErrorSupplierCodeAlreadyUsed';
674
				}
675
				if ($rescode == -5)
676
				{
677
					$this->errors[] = 'ErrorprefixRequired';
678
				}
679
				$result = -3;
680
			}
681
		}
682
683
		// Check for duplicate or mandatory fields defined into setup
684
		$array_to_check=array('IDPROF1','IDPROF2','IDPROF3','IDPROF4','IDPROF5','IDPROF6','EMAIL');
685
		foreach($array_to_check as $key)
686
		{
687
			$keymin=strtolower($key);
688
			$i=(int) preg_replace('/[^0-9]/','',$key);
689
			$vallabel=$this->$keymin;
690
691
			if ($i > 0)
692
			{
693
				if ($this->isACompany())
694
				{
695
					// Check for unicity
696
					if ($vallabel && $this->id_prof_verifiable($i))
697
					{
698
						if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0)))
699
						{
700
							$langs->load("errors");
701
							$error++; $this->errors[] = $langs->transcountry('ProfId'.$i, $this->country_code)." ".$langs->trans("ErrorProdIdAlreadyExist", $vallabel).' ('.$langs->trans("ForbiddenBySetupRules").')';
702
						}
703
					}
704
705
					// Check for mandatory prof id (but only if country is other than ours)
706
					if ($mysoc->country_id > 0 && $this->country_id == $mysoc->country_id)
707
					{
708
						$idprof_mandatory ='SOCIETE_'.$key.'_MANDATORY';
709
						if (! $vallabel && ! empty($conf->global->$idprof_mandatory))
710
						{
711
							$langs->load("errors");
712
							$error++;
713
							$this->errors[] = $langs->trans("ErrorProdIdIsMandatory", $langs->transcountry('ProfId'.$i, $this->country_code)).' ('.$langs->trans("ForbiddenBySetupRules").')';
714
						}
715
					}
716
				}
717
			}
718
			else
719
			{
720
				//var_dump($conf->global->SOCIETE_EMAIL_UNIQUE);
721
				//var_dump($conf->global->SOCIETE_EMAIL_MANDATORY);
722
				if ($key == 'EMAIL')
723
				{
724
					// Check for unicity
725
					if ($vallabel && ! empty($conf->global->SOCIETE_EMAIL_UNIQUE))
726
					{
727
						if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0)))
728
						{
729
							$langs->load("errors");
730
							$error++; $this->errors[] = $langs->trans('Email')." ".$langs->trans("ErrorProdIdAlreadyExist", $vallabel).' ('.$langs->trans("ForbiddenBySetupRules").')';
731
						}
732
					}
733
734
					// Check for mandatory
735
					if (! empty($conf->global->SOCIETE_EMAIL_MANDATORY) && ! isValidEMail($this->email))
736
					{
737
						$langs->load("errors");
738
						$error++;
739
						$this->errors[] = $langs->trans("ErrorBadEMail", $this->email).' ('.$langs->trans("ForbiddenBySetupRules").')';
740
					}
741
				}
742
			}
743
		}
744
745
		if ($error) $result = -4;
746
747
		return $result;
748
	}
749
750
	/**
751
	 *      Update parameters of third party
752
	 *
753
	 *      @param	int		$id              			Id of company (deprecated, use 0 here and call update on an object loaded by a fetch)
754
	 *      @param  User	$user            			Utilisateur qui demande la mise a jour
755
	 *      @param  int		$call_trigger    			0=no, 1=yes
756
	 *		@param	int		$allowmodcodeclient			Inclut modif code client et code compta
757
	 *		@param	int		$allowmodcodefournisseur	Inclut modif code fournisseur et code compta fournisseur
758
	 *		@param	string	$action						'add' or 'update' or 'merge'
759
	 *		@param	int		$nosyncmember				Do not synchronize info of linked member
760
	 *      @return int  			           			<0 if KO, >=0 if OK
761
	 */
762
	function update($id, $user='', $call_trigger=1, $allowmodcodeclient=0, $allowmodcodefournisseur=0, $action='update', $nosyncmember=1)
763
	{
764
		global $langs,$conf,$hookmanager;
765
766
		require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
767
768
		if (empty($id)) $id = $this->id;
769
770
		$error=0;
771
772
		dol_syslog(get_class($this)."::Update id=".$id." call_trigger=".$call_trigger." allowmodcodeclient=".$allowmodcodeclient." allowmodcodefournisseur=".$allowmodcodefournisseur);
773
774
		$now=dol_now();
775
776
		// Clean parameters
777
		$this->id			= $id;
778
		$this->entity		= ((isset($this->entity) && is_numeric($this->entity))?$this->entity:$conf->entity);
779
		$this->name			= $this->name?trim($this->name):trim($this->nom);
780
		$this->nom			= $this->name;	// For backward compatibility
781
		$this->name_alias	= trim($this->name_alias);
782
		$this->ref_ext		= trim($this->ref_ext);
783
		$this->address		= $this->address?trim($this->address):trim($this->address);
784
		$this->zip			= $this->zip?trim($this->zip):trim($this->zip);
785
		$this->town			= $this->town?trim($this->town):trim($this->town);
786
		$this->state_id		= trim($this->state_id);
0 ignored issues
show
Documentation Bug introduced by
The property $state_id was declared of type integer, but trim($this->state_id) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
787
		$this->country_id	= ($this->country_id > 0)?$this->country_id:0;
788
		$this->phone		= trim($this->phone);
789
		$this->phone		= preg_replace("/\s/","",$this->phone);
790
		$this->phone		= preg_replace("/\./","",$this->phone);
791
		$this->fax			= trim($this->fax);
792
		$this->fax			= preg_replace("/\s/","",$this->fax);
793
		$this->fax			= preg_replace("/\./","",$this->fax);
794
		$this->email		= trim($this->email);
795
		$this->skype		= trim($this->skype);
796
		$this->url			= $this->url?clean_url($this->url,0):'';
797
		$this->note_private = trim($this->note_private);
798
		$this->note_public  = trim($this->note_public);
799
		$this->idprof1		= trim($this->idprof1);
800
		$this->idprof2		= trim($this->idprof2);
801
		$this->idprof3		= trim($this->idprof3);
802
		$this->idprof4		= trim($this->idprof4);
803
		$this->idprof5		= (! empty($this->idprof5)?trim($this->idprof5):'');
804
		$this->idprof6		= (! empty($this->idprof6)?trim($this->idprof6):'');
805
		$this->prefix_comm	= trim($this->prefix_comm);
806
		$this->outstanding_limit = price2num($this->outstanding_limit);
807
		$this->order_min_amount = price2num($this->order_min_amount);
808
		$this->supplier_order_min_amount = price2num($this->supplier_order_min_amount);
809
810
		$this->tva_assuj	= trim($this->tva_assuj);
0 ignored issues
show
Documentation Bug introduced by
The property $tva_assuj was declared of type integer, but trim($this->tva_assuj) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
811
		$this->tva_intra	= dol_sanitizeFileName($this->tva_intra,'');
812
		if (empty($this->status)) $this->status = 0;
813
814
		if (!empty($this->multicurrency_code)) $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
815
		if (empty($this->fk_multicurrency))
816
		{
817
			$this->multicurrency_code = '';
818
			$this->fk_multicurrency = 0;
819
		}
820
821
		// Local taxes
822
		$this->localtax1_assuj=trim($this->localtax1_assuj);
823
		$this->localtax2_assuj=trim($this->localtax2_assuj);
824
825
		$this->localtax1_value=trim($this->localtax1_value);
826
		$this->localtax2_value=trim($this->localtax2_value);
827
828
		if ($this->capital != '') $this->capital=price2num(trim($this->capital));
829
		if (! is_numeric($this->capital)) $this->capital = '';     // '' = undef
830
831
		$this->effectif_id=trim($this->effectif_id);
0 ignored issues
show
Documentation Bug introduced by
The property $effectif_id was declared of type integer, but trim($this->effectif_id) is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
832
		$this->forme_juridique_code=trim($this->forme_juridique_code);
833
834
		//Gencod
835
		$this->barcode=trim($this->barcode);
836
837
		// For automatic creation
838
		if ($this->code_client == -1 || $this->code_client === 'auto')           $this->get_codeclient($this,0);
839
		if ($this->code_fournisseur == -1 || $this->code_fournisseur === 'auto') $this->get_codefournisseur($this,1);
840
841
		$this->code_compta=trim($this->code_compta);
842
		$this->code_compta_fournisseur=trim($this->code_compta_fournisseur);
843
844
		// Check parameters. More tests are done later in the ->verify()
845
		if (! is_numeric($this->client) && ! is_numeric($this->fournisseur))
846
		{
847
			$langs->load("errors");
848
			$this->error = $langs->trans("BadValueForParameterClientOrSupplier");
849
			return -1;
850
		}
851
852
		$customer=false;
853
		if (! empty($allowmodcodeclient) && ! empty($this->client))
854
		{
855
			// Attention get_codecompta peut modifier le code suivant le module utilise
856
			if (empty($this->code_compta))
857
			{
858
				$ret=$this->get_codecompta('customer');
859
				if ($ret < 0) return -1;
860
			}
861
862
			$customer=true;
863
		}
864
865
		$supplier=false;
866
		if (! empty($allowmodcodefournisseur) && ! empty($this->fournisseur))
867
		{
868
			// Attention get_codecompta peut modifier le code suivant le module utilise
869
			if (empty($this->code_compta_fournisseur))
870
			{
871
				$ret=$this->get_codecompta('supplier');
872
				if ($ret < 0) return -1;
873
			}
874
875
			$supplier=true;
876
		}
877
878
		//Web services
879
		$this->webservices_url = $this->webservices_url?clean_url($this->webservices_url,0):'';
880
		$this->webservices_key = trim($this->webservices_key);
881
882
		//Incoterms
883
		$this->fk_incoterms = (int) $this->fk_incoterms;
884
		$this->location_incoterms = trim($this->location_incoterms);
885
886
		$this->db->begin();
887
888
		// Check name is required and codes are ok or unique.
889
		// If error, this->errors[] is filled
890
		$result = 0;
891
		if ($action != 'add' && $action != 'merge')
892
		{
893
			// We don't check when update called during a create because verify was already done.
894
			// For a merge, we suppose source data is clean and a customer code of a deleted thirdparty must be accepted into a target thirdparty with empty code without duplicate error
895
			$result = $this->verify();
896
		}
897
898
		if ($result >= 0)
899
		{
900
			dol_syslog(get_class($this)."::update verify ok or not done");
901
902
			$sql  = "UPDATE ".MAIN_DB_PREFIX."societe SET ";
903
			$sql .= "entity = " . $this->db->escape($this->entity);
904
			$sql .= ",nom = '" . $this->db->escape($this->name) ."'"; // Required
905
			$sql .= ",name_alias = '" . $this->db->escape($this->name_alias) ."'";
906
			$sql .= ",ref_ext = " .(! empty($this->ref_ext)?"'".$this->db->escape($this->ref_ext) ."'":"null");
907
			$sql .= ",address = '" . $this->db->escape($this->address) ."'";
908
909
			$sql .= ",zip = ".(! empty($this->zip)?"'".$this->db->escape($this->zip)."'":"null");
910
			$sql .= ",town = ".(! empty($this->town)?"'".$this->db->escape($this->town)."'":"null");
911
912
			$sql .= ",fk_departement = '" . (! empty($this->state_id)?$this->state_id:'0') ."'";
913
			$sql .= ",fk_pays = '" . (! empty($this->country_id)?$this->country_id:'0') ."'";
914
915
			$sql .= ",phone = ".(! empty($this->phone)?"'".$this->db->escape($this->phone)."'":"null");
916
			$sql .= ",fax = ".(! empty($this->fax)?"'".$this->db->escape($this->fax)."'":"null");
917
			$sql .= ",email = ".(! empty($this->email)?"'".$this->db->escape($this->email)."'":"null");
918
			$sql .= ",skype = ".(! empty($this->skype)?"'".$this->db->escape($this->skype)."'":"null");
919
			$sql .= ",url = ".(! empty($this->url)?"'".$this->db->escape($this->url)."'":"null");
920
921
			$sql .= ",parent = " . ($this->parent > 0 ? $this->parent : "null");
922
923
			$sql .= ",note_private = ".(! empty($this->note_private)?"'".$this->db->escape($this->note_private)."'":"null");
924
			$sql .= ",note_public = ".(! empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"null");
925
926
			$sql .= ",siren   = '". $this->db->escape($this->idprof1) ."'";
927
			$sql .= ",siret   = '". $this->db->escape($this->idprof2) ."'";
928
			$sql .= ",ape     = '". $this->db->escape($this->idprof3) ."'";
929
			$sql .= ",idprof4 = '". $this->db->escape($this->idprof4) ."'";
930
			$sql .= ",idprof5 = '". $this->db->escape($this->idprof5) ."'";
931
			$sql .= ",idprof6 = '". $this->db->escape($this->idprof6) ."'";
932
933
			$sql .= ",tva_assuj = ".($this->tva_assuj!=''?"'".$this->db->escape($this->tva_assuj)."'":"null");
934
			$sql .= ",tva_intra = '" . $this->db->escape($this->tva_intra) ."'";
935
			$sql .= ",status = " .$this->status;
936
937
			// Local taxes
938
			$sql .= ",localtax1_assuj = ".($this->localtax1_assuj!=''?"'".$this->db->escape($this->localtax1_assuj)."'":"null");
939
			$sql .= ",localtax2_assuj = ".($this->localtax2_assuj!=''?"'".$this->db->escape($this->localtax2_assuj)."'":"null");
940
			if($this->localtax1_assuj==1)
941
			{
942
				if($this->localtax1_value!='')
943
				{
944
					$sql .=",localtax1_value =".$this->localtax1_value;
945
				}
946
				else $sql .=",localtax1_value =0.000";
947
948
			}
949
			else $sql .=",localtax1_value =0.000";
950
951
			if($this->localtax2_assuj==1)
952
			{
953
				if($this->localtax2_value!='')
954
				{
955
					$sql .=",localtax2_value =".$this->localtax2_value;
956
				}
957
				else $sql .=",localtax2_value =0.000";
958
959
			}
960
			else $sql .=",localtax2_value =0.000";
961
962
			$sql .= ",capital = ".($this->capital == '' ? "null" : $this->capital);
963
964
			$sql .= ",prefix_comm = ".(! empty($this->prefix_comm)?"'".$this->db->escape($this->prefix_comm)."'":"null");
965
966
			$sql .= ",fk_effectif = ".(! empty($this->effectif_id)?"'".$this->db->escape($this->effectif_id)."'":"null");
967
			if (isset($this->stcomm_id))
968
			{
969
				$sql .= ",fk_stcomm=".(!empty($this->stcomm_id)  ? $this->stcomm_id : "0");
970
			}
971
			$sql .= ",fk_typent = ".(! empty($this->typent_id)?"'".$this->db->escape($this->typent_id)."'":"0");
972
973
			$sql .= ",fk_forme_juridique = ".(! empty($this->forme_juridique_code)?"'".$this->db->escape($this->forme_juridique_code)."'":"null");
974
975
			$sql .= ",mode_reglement = ".(! empty($this->mode_reglement_id)?"'".$this->db->escape($this->mode_reglement_id)."'":"null");
976
			$sql .= ",cond_reglement = ".(! empty($this->cond_reglement_id)?"'".$this->db->escape($this->cond_reglement_id)."'":"null");
977
			$sql .= ",mode_reglement_supplier = ".(! empty($this->mode_reglement_supplier_id)?"'".$this->db->escape($this->mode_reglement_supplier_id)."'":"null");
978
			$sql .= ",cond_reglement_supplier = ".(! empty($this->cond_reglement_supplier_id)?"'".$this->db->escape($this->cond_reglement_supplier_id)."'":"null");
979
			$sql .= ",fk_shipping_method = ".(! empty($this->shipping_method_id)?"'".$this->db->escape($this->shipping_method_id)."'":"null");
980
981
			$sql .= ",client = " . (! empty($this->client)?$this->client:0);
982
			$sql .= ",fournisseur = " . (! empty($this->fournisseur)?$this->fournisseur:0);
983
			$sql .= ",barcode = ".(! empty($this->barcode)?"'".$this->db->escape($this->barcode)."'":"null");
984
			$sql .= ",default_lang = ".(! empty($this->default_lang)?"'".$this->db->escape($this->default_lang)."'":"null");
985
			$sql .= ",logo = ".(! empty($this->logo)?"'".$this->db->escape($this->logo)."'":"null");
986
			$sql .= ",outstanding_limit= ".($this->outstanding_limit!=''?$this->outstanding_limit:'null');
987
			$sql .= ",order_min_amount= ".($this->order_min_amount!=''?$this->order_min_amount:'null');
988
			$sql .= ",supplier_order_min_amount= ".($this->supplier_order_min_amount!=''?$this->supplier_order_min_amount:'null');
989
			$sql .= ",fk_prospectlevel='".$this->db->escape($this->fk_prospectlevel)."'";
990
991
			$sql .= ",webservices_url = ".(! empty($this->webservices_url)?"'".$this->db->escape($this->webservices_url)."'":"null");
992
			$sql .= ",webservices_key = ".(! empty($this->webservices_key)?"'".$this->db->escape($this->webservices_key)."'":"null");
993
994
			//Incoterms
995
			$sql.= ", fk_incoterms = ".$this->fk_incoterms;
996
			$sql.= ", location_incoterms = ".(! empty($this->location_incoterms)?"'".$this->db->escape($this->location_incoterms)."'":"null");
997
998
			if ($customer)
999
			{
1000
				$sql .= ", code_client = ".(! empty($this->code_client)?"'".$this->db->escape($this->code_client)."'":"null");
1001
				$sql .= ", code_compta = ".(! empty($this->code_compta)?"'".$this->db->escape($this->code_compta)."'":"null");
1002
			}
1003
1004
			if ($supplier)
1005
			{
1006
				$sql .= ", code_fournisseur = ".(! empty($this->code_fournisseur)?"'".$this->db->escape($this->code_fournisseur)."'":"null");
1007
				$sql .= ", code_compta_fournisseur = ".(! empty($this->code_compta_fournisseur)?"'".$this->db->escape($this->code_compta_fournisseur)."'":"null");
1008
			}
1009
			$sql .= ", fk_user_modif = ".($user->id > 0 ? $user->id:"null");
1010
			$sql .= ", fk_multicurrency = ".(int) $this->fk_multicurrency;
1011
			$sql .= ", multicurrency_code = '".$this->db->escape($this->multicurrency_code)."'";
1012
			$sql .= " WHERE rowid = " . (int) $id;
1013
1014
			$resql=$this->db->query($sql);
1015
			if ($resql)
1016
			{
1017
				unset($this->country_code);		// We clean this because it may have been changed after an update of country_id
1018
				unset($this->country);
1019
				unset($this->state_code);
1020
				unset($this->state);
1021
1022
				$nbrowsaffected = $this->db->affected_rows($resql);
1023
1024
				if (! $error && $nbrowsaffected)
1025
				{
1026
					// Update information on linked member if it is an update
1027
					if (! $nosyncmember && ! empty($conf->adherent->enabled))
1028
					{
1029
						require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1030
1031
						dol_syslog(get_class($this)."::update update linked member");
1032
1033
						$lmember=new Adherent($this->db);
1034
						$result=$lmember->fetch(0, 0, $this->id);
1035
1036
						if ($result > 0)
1037
						{
1038
							$lmember->societe=$this->name;
1039
							//$lmember->firstname=$this->firstname?$this->firstname:$lmember->firstname;	// We keep firstname and lastname of member unchanged
1040
							//$lmember->lastname=$this->lastname?$this->lastname:$lmember->lastname;		// We keep firstname and lastname of member unchanged
1041
							$lmember->address=$this->address;
1042
							$lmember->email=$this->email;
1043
							$lmember->skype=$this->skype;
1044
							$lmember->phone=$this->phone;
1045
1046
							$result=$lmember->update($user,0,1,1,1);	// Use nosync to 1 to avoid cyclic updates
0 ignored issues
show
Bug introduced by
It seems like $user defined by parameter $user on line 762 can also be of type string; however, Adherent::update() does only seem to accept object<User>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1047
							if ($result < 0)
1048
							{
1049
								$this->error=$lmember->error;
1050
								dol_syslog(get_class($this)."::update ".$this->error,LOG_ERR);
1051
								$error++;
1052
							}
1053
						}
1054
						else if ($result < 0)
1055
						{
1056
							$this->error=$lmember->error;
1057
							$error++;
1058
						}
1059
					}
1060
				}
1061
1062
				$action='update';
1063
1064
				// Actions on extra fields
1065
				if (! $error && empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) // For avoid conflicts if trigger used
1066
				{
1067
					$result=$this->insertExtraFields();
1068
					if ($result < 0)
1069
					{
1070
						$error++;
1071
					}
1072
				}
1073
1074
				if (! $error && $call_trigger)
1075
				{
1076
					// Call trigger
1077
					$result=$this->call_trigger('COMPANY_MODIFY',$user);
0 ignored issues
show
Bug introduced by
It seems like $user defined by parameter $user on line 762 can also be of type string; however, CommonObject::call_trigger() does only seem to accept object<User>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
1078
					if ($result < 0) $error++;
1079
					// End call triggers
1080
				}
1081
1082
				if (! $error)
1083
				{
1084
					dol_syslog(get_class($this)."::Update success");
1085
					$this->db->commit();
1086
					return 1;
1087
				}
1088
				else
1089
				{
1090
					$this->db->rollback();
1091
					return -1;
1092
				}
1093
			}
1094
			else
1095
			{
1096
				if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
1097
				{
1098
					// Doublon
1099
					$this->error = $langs->trans("ErrorDuplicateField");
1100
					$result = -1;
1101
				}
1102
				else
1103
				{
1104
					$this->error = $this->db->lasterror();
1105
					$result = -2;
1106
				}
1107
				$this->db->rollback();
1108
				return $result;
1109
			}
1110
		}
1111
		else
1112
	   {
1113
			$this->db->rollback();
1114
			dol_syslog(get_class($this)."::Update fails verify ".join(',',$this->errors), LOG_WARNING);
1115
			return -3;
1116
		}
1117
	}
1118
1119
	/**
1120
	 *    Load a third party from database into memory
1121
	 *
1122
	 *    @param	int		$rowid			Id of third party to load
1123
	 *    @param    string	$ref			Reference of third party, name (Warning, this can return several records)
1124
	 *    @param    string	$ref_ext       	External reference of third party (Warning, this information is a free field not provided by Dolibarr)
1125
	 *    @param    string	$ref_int       	Internal reference of third party (not used by dolibarr)
1126
	 *    @param    string	$idprof1		Prof id 1 of third party (Warning, this can return several records)
1127
	 *    @param    string	$idprof2		Prof id 2 of third party (Warning, this can return several records)
1128
	 *    @param    string	$idprof3		Prof id 3 of third party (Warning, this can return several records)
1129
	 *    @param    string	$idprof4		Prof id 4 of third party (Warning, this can return several records)
1130
	 *    @param    string	$idprof5		Prof id 5 of third party (Warning, this can return several records)
1131
	 *    @param    string	$idprof6		Prof id 6 of third party (Warning, this can return several records)
1132
	 *    @param    string	$email   		Email of third party (Warning, this can return several records)
1133
	 *    @param    string	$ref_alias 		Name_alias of third party (Warning, this can return several records)
1134
	 *    @return   int						>0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found.
1135
	 */
1136
	function fetch($rowid, $ref='', $ref_ext='', $ref_int='', $idprof1='',$idprof2='',$idprof3='',$idprof4='',$idprof5='',$idprof6='', $email='', $ref_alias='')
1137
	{
1138
		global $langs;
1139
		global $conf;
1140
1141
		if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($ref_int) && empty($idprof1) && empty($idprof2) && empty($idprof3) && empty($idprof4) && empty($idprof5) && empty($idprof6) && empty($email)) return -1;
1142
1143
		$sql = 'SELECT s.rowid, s.nom as name, s.name_alias, s.entity, s.ref_ext, s.ref_int, s.address, s.datec as date_creation, s.prefix_comm';
1144
		$sql .= ', s.status';
1145
		$sql .= ', s.price_level';
1146
		$sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif';
1147
		$sql .= ', s.phone, s.fax, s.email, s.skype, s.url, s.zip, s.town, s.note_private, s.note_public, s.model_pdf, s.client, s.fournisseur';
1148
		$sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6';
1149
		$sql .= ', s.capital, s.tva_intra';
1150
		$sql .= ', s.fk_typent as typent_id';
1151
		$sql .= ', s.fk_effectif as effectif_id';
1152
		$sql .= ', s.fk_forme_juridique as forme_juridique_code';
1153
		$sql .= ', s.webservices_url, s.webservices_key';
1154
		$sql .= ', s.code_client, s.code_fournisseur, s.code_compta, s.code_compta_fournisseur, s.parent, s.barcode';
1155
		$sql .= ', s.fk_departement, s.fk_pays as country_id, s.fk_stcomm, s.remise_client, s.remise_supplier, s.mode_reglement, s.cond_reglement, s.fk_account, s.tva_assuj';
1156
		$sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo';
1157
		$sql .= ', s.fk_shipping_method';
1158
		$sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms';
1159
		$sql .= ', s.order_min_amount, s.supplier_order_min_amount';
1160
		$sql .= ', s.fk_multicurrency, s.multicurrency_code';
1161
		$sql .= ', fj.libelle as forme_juridique';
1162
		$sql .= ', e.libelle as effectif';
1163
		$sql .= ', c.code as country_code, c.label as country';
1164
		$sql .= ', d.code_departement as state_code, d.nom as state';
1165
		$sql .= ', st.libelle as stcomm';
1166
		$sql .= ', te.code as typent_code';
1167
		$sql .= ', i.libelle as libelle_incoterms';
1168
		$sql .= ' FROM '.MAIN_DB_PREFIX.'societe as s';
1169
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as e ON s.fk_effectif = e.id';
1170
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid';
1171
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id';
1172
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as fj ON s.fk_forme_juridique = fj.code';
1173
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid';
1174
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as te ON s.fk_typent = te.id';
1175
		$sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON s.fk_incoterms = i.rowid';
1176
1177
		$sql .= ' WHERE s.entity IN ('.getEntity($this->element).')';
1178
		if ($rowid)     $sql .= ' AND s.rowid = '.$rowid;
1179
		if ($ref)       $sql .= " AND s.nom = '".$this->db->escape($ref)."'";
1180
		if ($ref_alias) $sql .= " AND s.nom_alias = '".$this->db->escape($ref_alias)."'";
1181
		if ($ref_ext)   $sql .= " AND s.ref_ext = '".$this->db->escape($ref_ext)."'";
1182
		if ($ref_int)   $sql .= " AND s.ref_int = '".$this->db->escape($ref_int)."'";
1183
		if ($idprof1)   $sql .= " AND s.siren = '".$this->db->escape($idprof1)."'";
1184
		if ($idprof2)   $sql .= " AND s.siret = '".$this->db->escape($idprof2)."'";
1185
		if ($idprof3)   $sql .= " AND s.ape = '".$this->db->escape($idprof3)."'";
1186
		if ($idprof4)   $sql .= " AND s.idprof4 = '".$this->db->escape($idprof4)."'";
1187
		if ($idprof5)   $sql .= " AND s.idprof5 = '".$this->db->escape($idprof5)."'";
1188
		if ($idprof6)   $sql .= " AND s.idprof6 = '".$this->db->escape($idprof6)."'";
1189
		if ($email)     $sql .= " AND s.email = '".$this->db->escape($email)."'";
1190
1191
		$resql=$this->db->query($sql);
1192
		if ($resql)
1193
		{
1194
			$num=$this->db->num_rows($resql);
1195
			if ($num > 1)
1196
			{
1197
				$this->error='Fetch found several records. Rename one of tirdparties to avoid duplicate.';
1198
				dol_syslog($this->error, LOG_ERR);
1199
				$result = -2;
1200
			}
1201
			elseif ($num)   // $num = 1
1202
			{
1203
				$obj = $this->db->fetch_object($resql);
1204
1205
				$this->id           = $obj->rowid;
1206
				$this->entity       = $obj->entity;
1207
				$this->canvas		= $obj->canvas;
1208
1209
				$this->ref          = $obj->rowid;
1210
				$this->name 		= $obj->name;
1211
				$this->nom          = $obj->name;		// deprecated
1212
				$this->name_alias = $obj->name_alias;
1213
				$this->ref_ext      = $obj->ref_ext;
1214
				$this->ref_int      = $obj->ref_int;
1215
1216
				$this->date_creation     = $this->db->jdate($obj->date_creation);
1217
				$this->date_modification = $this->db->jdate($obj->date_modification);
1218
				$this->user_creation     = $obj->fk_user_creat;
1219
				$this->user_modification = $obj->fk_user_modif;
1220
1221
				$this->address 		= $obj->address;
1222
				$this->zip 			= $obj->zip;
1223
				$this->town 		= $obj->town;
1224
1225
				$this->country_id   = $obj->country_id;
1226
				$this->country_code = $obj->country_id?$obj->country_code:'';
1227
				$this->country 		= $obj->country_id?($langs->trans('Country'.$obj->country_code)!='Country'.$obj->country_code?$langs->transnoentities('Country'.$obj->country_code):$obj->country):'';
1228
1229
				$this->state_id     = $obj->fk_departement;
1230
				$this->state_code   = $obj->state_code;
1231
				$this->state        = ($obj->state!='-'?$obj->state:'');
1232
1233
				$transcode=$langs->trans('StatusProspect'.$obj->fk_stcomm);
1234
				$libelle=($transcode!='StatusProspect'.$obj->fk_stcomm?$transcode:$obj->stcomm);
1235
				$this->stcomm_id = $obj->fk_stcomm;     // id statut commercial
1236
				$this->statut_commercial = $libelle;    // libelle statut commercial
1237
1238
				$this->email = $obj->email;
1239
				$this->skype = $obj->skype;
1240
				$this->url = $obj->url;
1241
				$this->phone = $obj->phone;
1242
				$this->fax = $obj->fax;
1243
1244
				$this->parent    = $obj->parent;
1245
1246
				$this->idprof1		= $obj->idprof1;
1247
				$this->idprof2		= $obj->idprof2;
1248
				$this->idprof3		= $obj->idprof3;
1249
				$this->idprof4		= $obj->idprof4;
1250
				$this->idprof5		= $obj->idprof5;
1251
				$this->idprof6		= $obj->idprof6;
1252
1253
				$this->capital   = $obj->capital;
1254
1255
				$this->code_client = $obj->code_client;
1256
				$this->code_fournisseur = $obj->code_fournisseur;
1257
1258
				$this->code_compta = $obj->code_compta;
1259
				$this->code_compta_fournisseur = $obj->code_compta_fournisseur;
1260
1261
				$this->barcode = $obj->barcode;
1262
1263
				$this->tva_assuj      = $obj->tva_assuj;
1264
				$this->tva_intra      = $obj->tva_intra;
1265
				$this->status = $obj->status;
1266
1267
				// Local Taxes
1268
				$this->localtax1_assuj      = $obj->localtax1_assuj;
1269
				$this->localtax2_assuj      = $obj->localtax2_assuj;
1270
1271
				$this->localtax1_value		= $obj->localtax1_value;
1272
				$this->localtax2_value		= $obj->localtax2_value;
1273
1274
				$this->typent_id      = $obj->typent_id;
1275
				$this->typent_code    = $obj->typent_code;
1276
1277
				$this->effectif_id    = $obj->effectif_id;
1278
				$this->effectif       = $obj->effectif_id?$obj->effectif:'';
1279
1280
				$this->forme_juridique_code= $obj->forme_juridique_code;
1281
				$this->forme_juridique     = $obj->forme_juridique_code?$obj->forme_juridique:'';
1282
1283
				$this->fk_prospectlevel = $obj->fk_prospectlevel;
1284
1285
				$this->prefix_comm = $obj->prefix_comm;
1286
1287
				$this->remise_percent		= $obj->remise_client;
1288
				$this->remise_supplier_percent		= $obj->remise_supplier;
1289
				$this->mode_reglement_id 	= $obj->mode_reglement;
1290
				$this->cond_reglement_id 	= $obj->cond_reglement;
1291
				$this->mode_reglement_supplier_id 	= $obj->mode_reglement_supplier;
1292
				$this->cond_reglement_supplier_id 	= $obj->cond_reglement_supplier;
1293
				$this->shipping_method_id   = ($obj->fk_shipping_method>0)?$obj->fk_shipping_method:null;
1294
				$this->fk_account			= $obj->fk_account;
1295
1296
				$this->client      = $obj->client;
1297
				$this->fournisseur = $obj->fournisseur;
1298
1299
				$this->note = $obj->note_private; // TODO Deprecated for backward comtability
1300
				$this->note_private = $obj->note_private;
1301
				$this->note_public = $obj->note_public;
1302
				$this->modelpdf = $obj->model_pdf;
1303
				$this->default_lang = $obj->default_lang;
1304
				$this->logo = $obj->logo;
1305
1306
				$this->webservices_url = $obj->webservices_url;
1307
				$this->webservices_key = $obj->webservices_key;
1308
1309
				$this->outstanding_limit		= $obj->outstanding_limit;
1310
				$this->order_min_amount			= $obj->order_min_amount;
1311
				$this->supplier_order_min_amount	= $obj->supplier_order_min_amount;
1312
1313
				// multiprix
1314
				$this->price_level = $obj->price_level;
1315
1316
				$this->import_key = $obj->import_key;
1317
1318
				//Incoterms
1319
				$this->fk_incoterms = $obj->fk_incoterms;
1320
				$this->location_incoterms = $obj->location_incoterms;
1321
				$this->libelle_incoterms = $obj->libelle_incoterms;
1322
1323
				// multicurrency
1324
				$this->fk_multicurrency = $obj->fk_multicurrency;
1325
				$this->multicurrency_code = $obj->multicurrency_code;
1326
1327
				$result = 1;
1328
1329
				// fetch optionals attributes and labels
1330
				$this->fetch_optionals();
1331
			}
1332
			else
1333
			{
1334
				$result = 0;
1335
			}
1336
1337
			$this->db->free($resql);
1338
		}
1339
		else
1340
		{
1341
			$this->error=$this->db->lasterror();
1342
			$result = -3;
1343
		}
1344
1345
		// Use first price level if level not defined for third party
1346
		if (! empty($conf->global->PRODUIT_MULTIPRICES) && empty($this->price_level)) $this->price_level=1;
1347
1348
		return $result;
1349
	}
1350
1351
	/**
1352
	 *    Delete a third party from database and all its dependencies (contacts, rib...)
1353
	 *
1354
	 *    @param	int		$id             Id of third party to delete
1355
	 *    @param    User    $fuser          User who ask to delete thirparty
1356
	 *    @param    int		$call_trigger   0=No, 1=yes
1357
	 *    @return	int						<0 if KO, 0 if nothing done, >0 if OK
1358
	 */
1359
	function delete($id, User $fuser=null, $call_trigger=1)
1360
	{
1361
		global $langs, $conf, $user;
1362
1363
		if (empty($fuser)) $fuser=$user;
1364
1365
		require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
1366
1367
		$entity=isset($this->entity)?$this->entity:$conf->entity;
1368
1369
		dol_syslog(get_class($this)."::delete", LOG_DEBUG);
1370
		$error = 0;
1371
1372
		// Test if child exists
1373
		$objectisused = $this->isObjectUsed($id);
1374
		if (empty($objectisused))
1375
		{
1376
			$this->db->begin();
1377
1378
			// User is mandatory for trigger call
1379
			if (! $error && $call_trigger)
1380
			{
1381
				// Call trigger
1382
				$result=$this->call_trigger('COMPANY_DELETE',$fuser);
1383
				if ($result < 0) $error++;
1384
				// End call triggers
1385
			}
1386
1387
			if (! $error)
1388
			{
1389
				require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1390
				$static_cat = new Categorie($this->db);
1391
				$toute_categs = array();
1392
1393
				// Fill $toute_categs array with an array of (type => array of ("Categorie" instance))
1394
				if ($this->client || $this->prospect)
1395
				{
1396
					$toute_categs['customer'] = $static_cat->containing($this->id,Categorie::TYPE_CUSTOMER);
1397
				}
1398
				if ($this->fournisseur)
1399
				{
1400
					$toute_categs['supplier'] = $static_cat->containing($this->id,Categorie::TYPE_SUPPLIER);
1401
				}
1402
1403
				// Remove each "Categorie"
1404
				foreach ($toute_categs as $type => $categs_type)
1405
				{
1406
					foreach ($categs_type as $cat)
1407
					{
1408
						$cat->del_type($this, $type);
1409
					}
1410
				}
1411
			}
1412
1413
			foreach ($this->childtablesoncascade as $tabletodelete)
1414
			{
1415
				if (! $error)
1416
				{
1417
					$sql = "DELETE FROM ".MAIN_DB_PREFIX.$tabletodelete;
1418
					$sql.= " WHERE fk_soc = " . $id;
1419
					if (! $this->db->query($sql))
1420
					{
1421
						$error++;
1422
						$this->errors[] = $this->db->lasterror();
1423
					}
1424
				}
1425
			}
1426
1427
			// Removed extrafields
1428
			if ((! $error) && (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED))) // For avoid conflicts if trigger used
1429
			{
1430
				$result=$this->deleteExtraFields();
1431
				if ($result < 0)
1432
				{
1433
					$error++;
1434
					dol_syslog(get_class($this)."::delete error -3 ".$this->error, LOG_ERR);
1435
				}
1436
			}
1437
1438
			// Remove third party
1439
			if (! $error)
1440
			{
1441
				$sql = "DELETE FROM ".MAIN_DB_PREFIX."societe";
1442
				$sql.= " WHERE rowid = " . $id;
1443
				if (! $this->db->query($sql))
1444
				{
1445
					$error++;
1446
					$this->errors[] = $this->db->lasterror();
1447
				}
1448
			}
1449
1450
			if (! $error)
1451
			{
1452
				$this->db->commit();
1453
1454
				// Delete directory
1455
				if (! empty($conf->societe->multidir_output[$entity]))
1456
				{
1457
					$docdir = $conf->societe->multidir_output[$entity] . "/" . $id;
1458
					if (dol_is_dir($docdir))
1459
					{
1460
						dol_delete_dir_recursive($docdir);
1461
					}
1462
				}
1463
1464
				return 1;
1465
			}
1466
			else
1467
			{
1468
				dol_syslog($this->error, LOG_ERR);
1469
				$this->db->rollback();
1470
				return -1;
1471
			}
1472
		}
1473
		else dol_syslog("Can't remove thirdparty with id ".$id.". There is ".$objectisused." childs", LOG_WARNING);
1474
		return 0;
1475
	}
1476
1477
	/**
1478
	 *  Define third party as a customer
1479
	 *
1480
	 *	@return		int		<0 if KO, >0 if OK
1481
	 */
1482
	function set_as_client()
1483
	{
1484
		if ($this->id)
1485
		{
1486
			$newclient=1;
1487
			if ($this->client == 2 || $this->client == 3) $newclient=3;	//If prospect, we keep prospect tag
1488
			$sql = "UPDATE ".MAIN_DB_PREFIX."societe";
1489
			$sql.= " SET client = ".$newclient;
1490
			$sql.= " WHERE rowid = " . $this->id;
1491
1492
			$resql=$this->db->query($sql);
1493
			if ($resql)
1494
			{
1495
				$this->client = $newclient;
1496
				return 1;
1497
			}
1498
			else return -1;
1499
		}
1500
		return 0;
1501
	}
1502
1503
	/**
1504
	 *  Definit la societe comme un client
1505
	 *
1506
	 *  @param	float	$remise		Valeur en % de la remise
1507
	 *  @param  string	$note		Note/Motif de modification de la remise
1508
	 *  @param  User	$user		Utilisateur qui definie la remise
1509
	 *	@return	int					<0 if KO, >0 if OK
1510
	 */
1511
	function set_remise_client($remise, $note, User $user)
1512
	{
1513
		global $conf, $langs;
1514
1515
		// Nettoyage parametres
1516
		$note=trim($note);
1517
		if (! $note)
1518
		{
1519
			$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("NoteReason"));
1520
			return -2;
1521
		}
1522
1523
		dol_syslog(get_class($this)."::set_remise_client ".$remise.", ".$note.", ".$user->id);
1524
1525
		if ($this->id)
1526
		{
1527
			$this->db->begin();
1528
1529
			$now=dol_now();
1530
1531
			// Positionne remise courante
1532
			$sql = "UPDATE ".MAIN_DB_PREFIX."societe ";
1533
			$sql.= " SET remise_client = '".$this->db->escape($remise)."'";
1534
			$sql.= " WHERE rowid = " . $this->id;
1535
			$resql=$this->db->query($sql);
1536
			if (! $resql)
1537
			{
1538
				$this->db->rollback();
1539
				$this->error=$this->db->error();
1540
				return -1;
1541
			}
1542
1543
			// Ecrit trace dans historique des remises
1544
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise";
1545
			$sql.= " (entity, datec, fk_soc, remise_client, note, fk_user_author)";
1546
			$sql.= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', ".$this->id.", '".$this->db->escape($remise)."',";
1547
			$sql.= " '".$this->db->escape($note)."',";
1548
			$sql.= " ".$user->id;
1549
			$sql.= ")";
1550
1551
			$resql=$this->db->query($sql);
1552
			if (! $resql)
1553
			{
1554
				$this->db->rollback();
1555
				$this->error=$this->db->lasterror();
1556
				return -1;
1557
			}
1558
1559
			$this->db->commit();
1560
			return 1;
1561
		}
1562
	}
1563
1564
	/**
1565
	 *  Definit la societe comme un client
1566
	 *
1567
	 *  @param	float	$remise		Valeur en % de la remise
1568
	 *  @param  string	$note		Note/Motif de modification de la remise
1569
	 *  @param  User	$user		Utilisateur qui definie la remise
1570
	 *	@return	int					<0 if KO, >0 if OK
1571
	 */
1572
	function set_remise_supplier($remise, $note, User $user)
1573
	{
1574
		global $conf, $langs;
1575
1576
		// Nettoyage parametres
1577
		$note=trim($note);
1578
		if (! $note)
1579
		{
1580
			$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("NoteReason"));
1581
			return -2;
1582
		}
1583
1584
		dol_syslog(get_class($this)."::set_remise_supplier ".$remise.", ".$note.", ".$user->id);
1585
1586
		if ($this->id)
1587
		{
1588
			$this->db->begin();
1589
1590
			$now=dol_now();
1591
1592
			// Positionne remise courante
1593
			$sql = "UPDATE ".MAIN_DB_PREFIX."societe ";
1594
			$sql.= " SET remise_supplier = '".$this->db->escape($remise)."'";
1595
			$sql.= " WHERE rowid = " . $this->id;
1596
			$resql=$this->db->query($sql);
1597
			if (! $resql)
1598
			{
1599
				$this->db->rollback();
1600
				$this->error=$this->db->error();
1601
				return -1;
1602
			}
1603
1604
			// Ecrit trace dans historique des remises
1605
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_remise_supplier";
1606
			$sql.= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)";
1607
			$sql.= " VALUES (".$conf->entity.", '".$this->db->idate($now)."', ".$this->id.", '".$this->db->escape($remise)."',";
1608
			$sql.= " '".$this->db->escape($note)."',";
1609
			$sql.= " ".$user->id;
1610
			$sql.= ")";
1611
1612
			$resql=$this->db->query($sql);
1613
			if (! $resql)
1614
			{
1615
				$this->db->rollback();
1616
				$this->error=$this->db->lasterror();
1617
				return -1;
1618
			}
1619
1620
			$this->db->commit();
1621
			return 1;
1622
		}
1623
	}
1624
1625
	/**
1626
	 *    	Add a discount for third party
1627
	 *
1628
	 *    	@param	float	$remise     	Amount of discount
1629
	 *    	@param  User	$user       	User adding discount
1630
	 *    	@param  string	$desc			Reason of discount
1631
	 *      @param  float	$tva_tx     	VAT rate
1632
	 *      @param	int		$discount_type	0 => customer discount, 1 => supplier discount
1633
	 *		@return	int					<0 if KO, id of discount record if OK
1634
	 */
1635
	function set_remise_except($remise, User $user, $desc, $tva_tx=0, $discount_type=0)
1636
	{
1637
		global $langs;
1638
1639
		// Clean parameters
1640
		$remise = price2num($remise);
1641
		$desc = trim($desc);
1642
1643
		// Check parameters
1644
		if (! $remise > 0)
1645
		{
1646
			$this->error=$langs->trans("ErrorWrongValueForParameter","1");
1647
			return -1;
1648
		}
1649
		if (! $desc)
1650
		{
1651
			$this->error=$langs->trans("ErrorWrongValueForParameter","3");
1652
			return -2;
1653
		}
1654
1655
		if ($this->id)
1656
		{
1657
			require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1658
1659
			$discount = new DiscountAbsolute($this->db);
1660
			$discount->fk_soc=$this->id;
1661
			$discount->discount_type=$discount_type;
1662
			$discount->amount_ht=price2num($remise,'MT');
1663
			$discount->amount_tva=price2num($remise*$tva_tx/100,'MT');
1664
			$discount->amount_ttc=price2num($discount->amount_ht+$discount->amount_tva,'MT');
1665
			$discount->tva_tx=price2num($tva_tx,'MT');
1666
			$discount->description=$desc;
1667
1668
			$result=$discount->create($user);
1669
			if ($result > 0)
1670
			{
1671
				return $result;
1672
			}
1673
			else
1674
			{
1675
				$this->error=$discount->error;
1676
				return -3;
1677
			}
1678
		}
1679
		else return 0;
1680
	}
1681
1682
	/**
1683
	 *  Renvoie montant TTC des reductions/avoirs en cours disponibles de la societe
1684
	 *
1685
	 *	@param	User	$user			Filtre sur un user auteur des remises
1686
	 * 	@param	string	$filter			Filtre autre
1687
	 * 	@param	integer	$maxvalue		Filter on max value for discount
1688
	 * 	@param	int		$discount_type	0 => customer discount, 1 => supplier discount
1689
	 *	@return	int					<0 if KO, Credit note amount otherwise
1690
	 */
1691
	function getAvailableDiscounts($user='',$filter='',$maxvalue=0,$discount_type=0)
1692
	{
1693
		require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
1694
1695
		$discountstatic=new DiscountAbsolute($this->db);
1696
		$result=$discountstatic->getAvailableDiscounts($this,$user,$filter,$maxvalue,$discount_type);
1697
		if ($result >= 0)
1698
		{
1699
			return $result;
1700
		}
1701
		else
1702
		{
1703
			$this->error=$discountstatic->error;
1704
			return -1;
1705
		}
1706
	}
1707
1708
	/**
1709
	 *  Return array of sales representatives
1710
	 *
1711
	 *  @param	User	$user		Object user
1712
	 *  @param	int		$mode		0=Array with properties, 1=Array of id.
1713
	 *  @return array       		Array of sales representatives of third party
1714
	 */
1715
	function getSalesRepresentatives(User $user, $mode=0)
1716
	{
1717
		global $conf;
1718
1719
		$reparray=array();
1720
1721
		$sql = "SELECT DISTINCT u.rowid, u.login, u.lastname, u.firstname, u.email, u.statut, u.entity, u.photo";
1722
		$sql.= " FROM ".MAIN_DB_PREFIX."societe_commerciaux as sc, ".MAIN_DB_PREFIX."user as u";
1723
		if (! empty($conf->multicompany->enabled) && ! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
1724
		{
1725
			$sql.= ", ".MAIN_DB_PREFIX."usergroup_user as ug";
1726
			$sql.= " WHERE ((ug.fk_user = sc.fk_user";
1727
			$sql.= " AND ug.entity = ".$conf->entity.")";
1728
			$sql.= " OR u.admin = 1)";
1729
		}
1730
		else
1731
			$sql.= " WHERE entity in (0, ".$conf->entity.")";
1732
1733
		$sql.= " AND u.rowid = sc.fk_user AND sc.fk_soc = ".$this->id;
1734
1735
		$resql = $this->db->query($sql);
1736
		if ($resql)
1737
		{
1738
			$num = $this->db->num_rows($resql);
1739
			$i=0;
1740
			while ($i < $num)
1741
			{
1742
				$obj = $this->db->fetch_object($resql);
1743
1744
				if (empty($mode))
1745
				{
1746
					$reparray[$i]['id']=$obj->rowid;
1747
					$reparray[$i]['lastname']=$obj->lastname;
1748
					$reparray[$i]['firstname']=$obj->firstname;
1749
					$reparray[$i]['email']=$obj->email;
1750
					$reparray[$i]['statut']=$obj->statut;
1751
					$reparray[$i]['entity']=$obj->entity;
1752
					$reparray[$i]['login']=$obj->login;
1753
					$reparray[$i]['photo']=$obj->photo;
1754
				}
1755
				else
1756
				{
1757
					$reparray[]=$obj->rowid;
1758
				}
1759
				$i++;
1760
			}
1761
			return $reparray;
1762
		}
1763
		else {
1764
			dol_print_error($this->db);
1765
			return -1;
1766
		}
1767
	}
1768
1769
	/**
1770
	 * Set the price level
1771
	 *
1772
	 * @param 	int		$price_level	Level of price
1773
	 * @param 	User	$user			Use making change
1774
	 * @return	int						<0 if KO, >0 if OK
1775
	 */
1776
	function set_price_level($price_level, User $user)
1777
	{
1778
		if ($this->id)
1779
		{
1780
			$now=dol_now();
1781
1782
			$sql  = "UPDATE ".MAIN_DB_PREFIX."societe";
1783
			$sql .= " SET price_level = '".$this->db->escape($price_level)."'";
1784
			$sql .= " WHERE rowid = " . $this->id;
1785
1786
			if (! $this->db->query($sql))
1787
			{
1788
				dol_print_error($this->db);
1789
				return -1;
1790
			}
1791
1792
			$sql  = "INSERT INTO ".MAIN_DB_PREFIX."societe_prices";
1793
			$sql .= " (datec, fk_soc, price_level, fk_user_author)";
1794
			$sql .= " VALUES ('".$this->db->idate($now)."', ".$this->id.", '".$this->db->escape($price_level)."', ".$user->id.")";
1795
1796
			if (! $this->db->query($sql))
1797
			{
1798
				dol_print_error($this->db);
1799
				return -1;
1800
			}
1801
			return 1;
1802
		}
1803
		return -1;
1804
	}
1805
1806
	/**
1807
	 *	Add link to sales representative
1808
	 *
1809
	 *	@param	User	$user		Object user
1810
	 *	@param	int		$commid		Id of user
1811
	 *	@return	void
1812
	 */
1813
	function add_commercial(User $user, $commid)
1814
	{
1815
		$error=0;
1816
1817
1818
1819
1820
		if ($this->id > 0 && $commid > 0)
1821
		{
1822
			$sql = "DELETE FROM  ".MAIN_DB_PREFIX."societe_commerciaux";
1823
			$sql.= " WHERE fk_soc = ".$this->id." AND fk_user =".$commid;
1824
1825
			$this->db->query($sql);
1826
1827
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_commerciaux";
1828
			$sql.= " ( fk_soc, fk_user )";
1829
			$sql.= " VALUES (".$this->id.",".$commid.")";
1830
1831
			if (! $this->db->query($sql) )
1832
			{
1833
				dol_syslog(get_class($this)."::add_commercial Erreur");
1834
			}
1835
			else {
1836
				$this->context=array('commercial_modified'=>$commid);
1837
1838
				$result=$this->call_trigger('COMPANY_LINK_SALE_REPRESENTATIVE',$user);
1839
                if ($result < 0) $error++;
1840
			}
1841
		}
1842
	}
1843
1844
	/**
1845
	 *	Add link to sales representative
1846
	 *
1847
	 *	@param	User	$user		Object user
1848
	 *	@param	int		$commid		Id of user
1849
	 *	@return	void
1850
	 */
1851
	function del_commercial(User $user, $commid)
1852
	{
1853
		$error=0;
1854
		$this->context=array('commercial_modified'=>$commid);
1855
1856
		$result=$this->call_trigger('COMPANY_UNLINK_SALE_REPRESENTATIVE',$user);
1857
        if ($result < 0) $error++;
1858
1859
		if ($this->id > 0 && $commid > 0)
1860
		{
1861
			$sql  = "DELETE FROM  ".MAIN_DB_PREFIX."societe_commerciaux ";
1862
			$sql .= " WHERE fk_soc = ".$this->id." AND fk_user =".$commid;
1863
1864
			if (! $this->db->query($sql) )
1865
			{
1866
				dol_syslog(get_class($this)."::del_commercial Erreur");
1867
			}
1868
		}
1869
	}
1870
1871
1872
	/**
1873
	 *    	Return a link on thirdparty (with picto)
1874
	 *
1875
	 *		@param	int		$withpicto		          Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
1876
	 *		@param	string	$option			          Target of link ('', 'customer', 'prospect', 'supplier', 'project')
1877
	 *		@param	int		$maxlen			          Max length of name
1878
	 *      @param	int  	$notooltip		          1=Disable tooltip
1879
	 *      @param  int     $save_lastsearch_value    -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
1880
	 *		@return	string					          String with URL
1881
	 */
1882
	function getNomUrl($withpicto=0, $option='', $maxlen=0, $notooltip=0, $save_lastsearch_value=-1)
1883
	{
1884
		global $conf, $langs, $hookmanager;
1885
1886
		if (! empty($conf->dol_no_mouse_hover)) $notooltip=1;   // Force disable tooltips
1887
1888
		$name=$this->name?$this->name:$this->nom;
1889
1890
		if(!empty($conf->global->SOCIETE_ON_SEARCH_AND_LIST_GO_ON_CUSTOMER_OR_SUPPLIER_CARD)){
1891
1892
             if(empty($option) && $this->client > 0) $option = 'customer';
1893
             if(empty($option) && $this->fournisseur > 0) $option = 'supplier';
1894
         }
1895
1896
1897
		if (! empty($conf->global->SOCIETE_ADD_REF_IN_LIST) && (!empty($withpicto)))
1898
		{
1899
			if (($this->client) && (! empty ( $this->code_client ))
1900
				&& ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1
1901
				|| $conf->global->SOCIETE_ADD_REF_IN_LIST == 2
1902
				)
1903
			)
1904
			$code = $this->code_client . ' - ';
1905
1906
			if (($this->fournisseur) && (! empty ( $this->code_fournisseur ))
1907
				&& ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1
1908
				|| $conf->global->SOCIETE_ADD_REF_IN_LIST == 3
1909
				)
1910
			)
1911
			$code .= $this->code_fournisseur . ' - ';
0 ignored issues
show
Bug introduced by
The variable $code does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1912
1913
			if ($conf->global->SOCIETE_ADD_REF_IN_LIST == 1)
1914
				$name =$code.' '.$name;
1915
			else
1916
				$name =$code;
1917
		}
1918
1919
		if (!empty($this->name_alias)) $name .= ' ('.$this->name_alias.')';
1920
1921
		$result=''; $label='';
1922
		$linkstart=''; $linkend='';
1923
1924
		if (! empty($this->logo) && class_exists('Form'))
1925
		{
1926
			$label.= '<div class="photointooltip">';
1927
			$label.= Form::showphoto('societe', $this, 0, 40, 0, 'photowithmargin', 'mini', 0);	// Important, we must force height so image will have height tags and if image is inside a tooltip, the tooltip manager can calculate height and position correctly the tooltip.
1928
			$label.= '</div><div style="clear: both;"></div>';
1929
		}
1930
1931
		$label.= '<div class="centpercent">';
1932
1933
		if ($option == 'customer' || $option == 'compta' || $option == 'category' || $option == 'category_supplier')
1934
		{
1935
		   $label.= '<u>' . $langs->trans("ShowCustomer") . '</u>';
1936
		   $linkstart = '<a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id;
1937
		}
1938
		else if ($option == 'prospect' && empty($conf->global->SOCIETE_DISABLE_PROSPECTS))
1939
		{
1940
			$label.= '<u>' . $langs->trans("ShowProspect") . '</u>';
1941
			$linkstart = '<a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$this->id;
1942
		}
1943
		else if ($option == 'supplier')
1944
		{
1945
			$label.= '<u>' . $langs->trans("ShowSupplier") . '</u>';
1946
			$linkstart = '<a href="'.DOL_URL_ROOT.'/fourn/card.php?socid='.$this->id;
1947
		}
1948
		else if ($option == 'agenda')
1949
		{
1950
			$label.= '<u>' . $langs->trans("ShowAgenda") . '</u>';
1951
			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/agenda.php?socid='.$this->id;
1952
		}
1953
		else if ($option == 'project')
1954
		{
1955
			$label.= '<u>' . $langs->trans("ShowProject") . '</u>';
1956
			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/project.php?socid='.$this->id;
1957
		}
1958
		else if ($option == 'margin')
1959
		{
1960
			$label.= '<u>' . $langs->trans("ShowMargin") . '</u>';
1961
			$linkstart = '<a href="'.DOL_URL_ROOT.'/margin/tabs/thirdpartyMargins.php?socid='.$this->id.'&type=1';
1962
		}
1963
		else if ($option == 'contact')
1964
		{
1965
			$label.= '<u>' . $langs->trans("ShowContacts") . '</u>';
1966
			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/contact.php?socid='.$this->id;
1967
		}
1968
		else if ($option == 'ban')
1969
		{
1970
			$label.= '<u>' . $langs->trans("ShowBan") . '</u>';
1971
			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/paymentmodes.php?socid='.$this->id;
1972
		}
1973
1974
		// By default
1975
		if (empty($linkstart))
1976
		{
1977
			$label.= '<u>' . $langs->trans("ShowCompany") . '</u>';
1978
			$linkstart = '<a href="'.DOL_URL_ROOT.'/societe/card.php?socid='.$this->id;
1979
		}
1980
1981
		if (! empty($this->name))
1982
		{
1983
			$label.= '<br><b>' . $langs->trans('Name') . ':</b> '. $this->name;
1984
			if (! empty($this->name_alias)) $label.=' ('.$this->name_alias.')';
1985
			$label.= '<br><b>' . $langs->trans('Email') . ':</b> '. $this->email;
1986
		}
1987
		if (! empty($this->country_code))
1988
			$label.= '<br><b>' . $langs->trans('Country') . ':</b> '. $this->country_code;
1989
		if (! empty($this->tva_intra))
1990
			$label.= '<br><b>' . $langs->trans('VATIntra') . ':</b> '. $this->tva_intra;
1991
		if (! empty($this->code_client) && $this->client)
1992
			$label.= '<br><b>' . $langs->trans('CustomerCode') . ':</b> '. $this->code_client;
1993
		if (! empty($this->code_fournisseur) && $this->fournisseur)
1994
			$label.= '<br><b>' . $langs->trans('SupplierCode') . ':</b> '. $this->code_fournisseur;
1995
		if (! empty($conf->accounting->enabled) && $this->client)
1996
			$label.= '<br><b>' . $langs->trans('CustomerAccountancyCode') . ':</b> '. ($this->code_compta ? $this->code_compta : $this->code_compta_client);
1997
		if (! empty($conf->accounting->enabled) && $this->fournisseur)
1998
			$label.= '<br><b>' . $langs->trans('SupplierAccountancyCode') . ':</b> '. $this->code_compta_fournisseur;
1999
2000
		$label.= '</div>';
2001
2002
		// Add type of canvas
2003
		$linkstart.=(!empty($this->canvas)?'&canvas='.$this->canvas:'');
2004
		// Add param to save lastsearch_values or not
2005
		$add_save_lastsearch_values=($save_lastsearch_value == 1 ? 1 : 0);
2006
		if ($save_lastsearch_value == -1 && preg_match('/list\.php/',$_SERVER["PHP_SELF"])) $add_save_lastsearch_values=1;
2007
		if ($add_save_lastsearch_values) $linkstart.='&save_lastsearch_values=1';
2008
		$linkstart.='"';
2009
2010
		$linkclose='';
2011
		if (empty($notooltip))
2012
		{
2013
			if (! empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER))
2014
			{
2015
				$label=$langs->trans("ShowCompany");
2016
				$linkclose.=' alt="'.dol_escape_htmltag($label, 1).'"';
2017
			}
2018
			$linkclose.= ' title="'.dol_escape_htmltag($label, 1).'"';
2019
			$linkclose.=' class="classfortooltip refurl"';
2020
2021
		 	/*
2022
			$hookmanager->initHooks(array('thirdpartydao'));
2023
			$parameters=array('id'=>$this->id);
2024
			$reshook=$hookmanager->executeHooks('getnomurltooltip',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
2025
			if ($reshook > 0) $linkclose = $hookmanager->resPrint;
2026
			*/
2027
		}
2028
		$linkstart.=$linkclose.'>';
2029
		$linkend='</a>';
2030
2031
		global $user;
2032
		if (! $user->rights->societe->client->voir && $user->societe_id > 0 && $this->id != $user->societe_id)
2033
		{
2034
			$linkstart='';
2035
			$linkend='';
2036
		}
2037
2038
		$result.=$linkstart;
2039
		if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip valigntextbottom"'), 0, 0, $notooltip?0:1);
2040
		if ($withpicto != 2) $result.=($maxlen?dol_trunc($name,$maxlen):$name);
2041
		$result.=$linkend;
2042
2043
		global $action;
2044
		$hookmanager->initHooks(array('thirdpartydao'));
2045
		$parameters=array('id'=>$this->id, 'getnomurl'=>$result);
2046
		$reshook=$hookmanager->executeHooks('getNomUrl',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
2047
		if ($reshook > 0) $result = $hookmanager->resPrint;
2048
		else $result .= $hookmanager->resPrint;
2049
2050
		return $result;
2051
	}
2052
2053
	/**
2054
	 *    Return label of status (activity, closed)
2055
	 *
2056
	 *    @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long, 5=Libelle court + Picto
2057
	 *    @return   string        		Libelle
2058
	 */
2059
	function getLibStatut($mode=0)
2060
	{
2061
		return $this->LibStatut($this->status,$mode);
2062
	}
2063
2064
	/**
2065
	 *  Renvoi le libelle d'un statut donne
2066
	 *
2067
	 *  @param	int		$statut         Id statut
2068
	 *  @param	int		$mode           0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto, 6=Long label + Picto
2069
	 *  @return	string          		Libelle du statut
2070
	 */
2071
	function LibStatut($statut,$mode=0)
2072
	{
2073
		global $langs;
2074
		$langs->load('companies');
2075
2076
		if ($mode == 0)
2077
		{
2078
			if ($statut==0) return $langs->trans("ActivityCeased");
2079
			if ($statut==1) return $langs->trans("InActivity");
2080
		}
2081
		if ($mode == 1)
2082
		{
2083
			if ($statut==0) return $langs->trans("ActivityCeased");
2084
			if ($statut==1) return $langs->trans("InActivity");
2085
		}
2086
		if ($mode == 2)
2087
		{
2088
			if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2089
			if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2090
		}
2091
		if ($mode == 3)
2092
		{
2093
			if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2094
			if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2095
		}
2096
		if ($mode == 4)
2097
		{
2098
			if ($statut==0) return img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"').' '.$langs->trans("ActivityCeased");
2099
			if ($statut==1) return img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"').' '.$langs->trans("InActivity");
2100
		}
2101
		if ($mode == 5)
2102
		{
2103
			if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans("ActivityCeased").'</span> '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2104
			if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans("InActivity").'</span> '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2105
		}
2106
		if ($mode == 6)
2107
		{
2108
			if ($statut==0) return '<span class="hideonsmartphone">'.$langs->trans("ActivityCeased").'</span> '.img_picto($langs->trans("ActivityCeased"),'statut5', 'class="pictostatus"');
2109
			if ($statut==1) return '<span class="hideonsmartphone">'.$langs->trans("InActivity").'</span> '.img_picto($langs->trans("InActivity"),'statut4', 'class="pictostatus"');
2110
		}
2111
	}
2112
2113
	/**
2114
	 *    Return list of contacts emails existing for third party
2115
	 *
2116
	 *	  @param	  int		$addthirdparty		1=Add also a record for thirdparty email
2117
	 *    @return     array       					Array of contacts emails
2118
	 */
2119
	function thirdparty_and_contact_email_array($addthirdparty=0)
2120
	{
2121
		global $langs;
2122
2123
		$contact_emails = $this->contact_property_array('email',1);
2124
		if ($this->email && $addthirdparty)
2125
		{
2126
			if (empty($this->name)) $this->name=$this->nom;
2127
			$contact_emails['thirdparty']=$langs->transnoentitiesnoconv("ThirdParty").': '.dol_trunc($this->name,16)." <".$this->email.">";
2128
		}
2129
		//var_dump($contact_emails)
2130
		return $contact_emails;
2131
	}
2132
2133
	/**
2134
	 *    Return list of contacts mobile phone existing for third party
2135
	 *
2136
	 *    @return     array       Array of contacts emails
2137
	 */
2138
	function thirdparty_and_contact_phone_array()
2139
	{
2140
		global $langs;
2141
2142
		$contact_phone = $this->contact_property_array('mobile');
2143
2144
		if (! empty($this->phone))	// If a phone of thirdparty is defined, we add it ot mobile of contacts
2145
		{
2146
			if (empty($this->name)) $this->name=$this->nom;
2147
			// TODO: Tester si tel non deja present dans tableau contact
2148
			$contact_phone['thirdparty']=$langs->transnoentitiesnoconv("ThirdParty").': '.dol_trunc($this->name,16)." <".$this->phone.">";
2149
		}
2150
		return $contact_phone;
2151
	}
2152
2153
	/**
2154
	 *  Return list of contacts emails or mobile existing for third party
2155
	 *
2156
	 *  @param	string	$mode       		'email' or 'mobile'
2157
	 * 	@param	int		$hidedisabled		1=Hide contact if disabled
2158
	 *  @return array       				Array of contacts emails or mobile. Example: array(id=>'Name <email>')
2159
	 */
2160
	function contact_property_array($mode='email', $hidedisabled=0)
2161
	{
2162
		global $langs;
2163
2164
		$contact_property = array();
2165
2166
2167
		$sql = "SELECT rowid, email, statut, phone_mobile, lastname, poste, firstname";
2168
		$sql.= " FROM ".MAIN_DB_PREFIX."socpeople";
2169
		$sql.= " WHERE fk_soc = ".$this->id;
2170
2171
		$resql=$this->db->query($sql);
2172
		if ($resql)
2173
		{
2174
			$nump = $this->db->num_rows($resql);
2175
			if ($nump)
2176
			{
2177
				$sepa="("; $sepb=")";
2178
				if ($mode == 'email')
2179
				{
2180
					//$sepa="&lt;"; $sepb="&gt;";
2181
					$sepa="<"; $sepb=">";
2182
				}
2183
				$i = 0;
2184
				while ($i < $nump)
2185
				{
2186
					$obj = $this->db->fetch_object($resql);
2187
					if ($mode == 'email') $property=$obj->email;
2188
					else if ($mode == 'mobile') $property=$obj->phone_mobile;
2189
					else $property=$obj->$mode;
2190
2191
					// Show all contact. If hidedisabled is 1, showonly contacts with status = 1
2192
					if ($obj->statut == 1 || empty($hidedisabled))
2193
					{
2194
						if (empty($property))
2195
						{
2196
							if ($mode == 'email') $property=$langs->transnoentitiesnoconv("NoEMail");
2197
							else if ($mode == 'mobile') $property=$langs->transnoentitiesnoconv("NoMobilePhone");
2198
						}
2199
2200
						if (!empty($obj->poste))
2201
						{
2202
							$contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname,$obj->lastname)).($obj->poste?" - ".$obj->poste:"").(($mode != 'poste' && $property)?" ".$sepa.$property.$sepb:'');
2203
						}
2204
						else
2205
						{
2206
							$contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname,$obj->lastname)).(($mode != 'poste' && $property)?" ".$sepa.$property.$sepb:'');
2207
						}
2208
					}
2209
					$i++;
2210
				}
2211
			}
2212
		}
2213
		else
2214
		{
2215
			dol_print_error($this->db);
2216
		}
2217
		return $contact_property;
2218
	}
2219
2220
2221
	/**
2222
	 *    Renvoie la liste des contacts de cette societe
2223
	 *
2224
	 *    @return     array      tableau des contacts
2225
	 */
2226
	function contact_array()
2227
	{
2228
		$contacts = array();
2229
2230
		$sql = "SELECT rowid, lastname, firstname FROM ".MAIN_DB_PREFIX."socpeople WHERE fk_soc = ".$this->id;
2231
		$resql=$this->db->query($sql);
2232
		if ($resql)
2233
		{
2234
			$nump = $this->db->num_rows($resql);
2235
			if ($nump)
2236
			{
2237
				$i = 0;
2238
				while ($i < $nump)
2239
				{
2240
					$obj = $this->db->fetch_object($resql);
2241
					$contacts[$obj->rowid] = dolGetFirstLastname($obj->firstname,$obj->lastname);
2242
					$i++;
2243
				}
2244
			}
2245
		}
2246
		else
2247
		{
2248
			dol_print_error($this->db);
2249
		}
2250
		return $contacts;
2251
	}
2252
2253
	/**
2254
	 *    Renvoie la liste des contacts de cette societe
2255
	 *
2256
	 *    @return    array    $contacts    tableau des contacts
2257
	 */
2258
	function contact_array_objects()
2259
	{
2260
		require_once DOL_DOCUMENT_ROOT . '/contact/class/contact.class.php';
2261
		$contacts = array();
2262
2263
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."socpeople WHERE fk_soc = ".$this->id;
2264
		$resql=$this->db->query($sql);
2265
		if ($resql)
2266
		{
2267
			$nump = $this->db->num_rows($resql);
2268
			if ($nump)
2269
			{
2270
				$i = 0;
2271
				while ($i < $nump)
2272
				{
2273
					$obj = $this->db->fetch_object($resql);
2274
					$contact = new Contact($this->db);
2275
					$contact->fetch($obj->rowid);
2276
					$contacts[] = $contact;
2277
					$i++;
2278
				}
2279
			}
2280
		}
2281
		else
2282
		{
2283
			dol_print_error($this->db);
2284
		}
2285
		return $contacts;
2286
	}
2287
2288
	/**
2289
	 *  Return property of contact from its id
2290
	 *
2291
	 *  @param	int		$rowid      id of contact
2292
	 *  @param  string	$mode       'email' or 'mobile'
2293
	 *  @return string  			Email of contact with format: "Full name <email>"
2294
	 */
2295
	function contact_get_property($rowid,$mode)
2296
	{
2297
		$contact_property='';
2298
2299
		if (empty($rowid)) return '';
2300
2301
		$sql = "SELECT rowid, email, phone_mobile, lastname, firstname";
2302
		$sql.= " FROM ".MAIN_DB_PREFIX."socpeople";
2303
		$sql.= " WHERE rowid = '".$rowid."'";
2304
2305
		$resql=$this->db->query($sql);
2306
		if ($resql)
2307
		{
2308
			$nump = $this->db->num_rows($resql);
2309
2310
			if ($nump)
2311
			{
2312
				$obj = $this->db->fetch_object($resql);
2313
2314
				if ($mode == 'email') $contact_property = dol_string_nospecial(dolGetFirstLastname($obj->firstname, $obj->lastname), ' ', array(","))." <".$obj->email.">";
2315
				else if ($mode == 'mobile') $contact_property = $obj->phone_mobile;
2316
			}
2317
			return $contact_property;
2318
		}
2319
		else
2320
		{
2321
			dol_print_error($this->db);
2322
		}
2323
2324
	}
2325
2326
2327
	/**
2328
	 *  Return bank number property of thirdparty (label or rum)
2329
	 *
2330
	 *	@param	string	$mode	'label' or 'rum' or 'format'
2331
	 *  @return	string			Bank number
2332
	 */
2333
	function display_rib($mode='label')
2334
	{
2335
		require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
2336
2337
		$bac = new CompanyBankAccount($this->db);
2338
		$bac->fetch(0,$this->id);
2339
2340
		if ($mode == 'label')
2341
		{
2342
			return $bac->getRibLabel(true);
2343
		}
2344
		elseif ($mode == 'rum')
2345
		{
2346
			if (empty($bac->rum))
2347
			{
2348
				require_once DOL_DOCUMENT_ROOT . '/compta/prelevement/class/bonprelevement.class.php';
2349
				$prelevement = new BonPrelevement($this->db);
2350
				$bac->fetch_thirdparty();
2351
				$bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id);
2352
			}
2353
			return $bac->rum;
2354
		}
2355
		elseif ($mode == 'format')
2356
		{
2357
			return $bac->frstrecur;
2358
		}
2359
2360
		return 'BadParameterToFunctionDisplayRib';
2361
	}
2362
2363
	/**
2364
	 * Return Array of RIB
2365
	 *
2366
	 * @return     array|int        0 if KO, Array of CompanyBanckAccount if OK
2367
	 */
2368
	function get_all_rib()
2369
	{
2370
		require_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
2371
		$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."societe_rib WHERE type='ban' AND fk_soc = ".$this->id;
2372
		$result = $this->db->query($sql);
2373
		if (!$result) {
2374
			$this->error++;
2375
			$this->errors[] = $this->db->lasterror;
2376
			return 0;
2377
		} else {
2378
			$num_rows = $this->db->num_rows($result);
2379
			$rib_array = array();
2380
			if ($num_rows) {
2381
				while ($obj = $this->db->fetch_object($result)) {
2382
					$rib = new CompanyBankAccount($this->db);
2383
					$rib->fetch($obj->rowid);
2384
					$rib_array[] = $rib;
2385
				}
2386
			}
2387
			return $rib_array;
2388
		}
2389
	}
2390
2391
	/**
2392
	 *  Attribut un code client a partir du module de controle des codes.
2393
	 *  Return value is stored into this->code_client
2394
	 *
2395
	 *	@param	Societe		$objsoc		Object thirdparty
2396
	 *	@param	int			$type		Should be 0 to say customer
2397
	 *  @return void
2398
	 */
2399
	function get_codeclient($objsoc=0,$type=0)
2400
	{
2401
		global $conf;
2402
		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
2403
		{
2404
			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
2405
2406
			$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
2407
			foreach ($dirsociete as $dirroot)
2408
			{
2409
				$res=dol_include_once($dirroot.$module.'.php');
2410
				if ($res) break;
2411
			}
2412
			$mod = new $module();
2413
2414
			$this->code_client = $mod->getNextValue($objsoc,$type);
2415
			$this->prefixCustomerIsRequired = $mod->prefixIsRequired;
2416
2417
			dol_syslog(get_class($this)."::get_codeclient code_client=".$this->code_client." module=".$module);
2418
		}
2419
	}
2420
2421
	/**
2422
	 *  Attribut un code fournisseur a partir du module de controle des codes.
2423
	 *  Return value is stored into this->code_fournisseur
2424
	 *
2425
	 *	@param	Societe		$objsoc		Object thirdparty
2426
	 *	@param	int			$type		Should be 1 to say supplier
2427
	 *  @return void
2428
	 */
2429
	function get_codefournisseur($objsoc=0,$type=1)
2430
	{
2431
		global $conf;
2432
		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
2433
		{
2434
			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
2435
2436
			$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
2437
			foreach ($dirsociete as $dirroot)
2438
			{
2439
				$res=dol_include_once($dirroot.$module.'.php');
2440
				if ($res) break;
2441
			}
2442
			$mod = new $module();
2443
2444
			$this->code_fournisseur = $mod->getNextValue($objsoc,$type);
2445
2446
			dol_syslog(get_class($this)."::get_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module);
2447
		}
2448
	}
2449
2450
	/**
2451
	 *    Verifie si un code client est modifiable en fonction des parametres
2452
	 *    du module de controle des codes.
2453
	 *
2454
	 *    @return     int		0=No, 1=Yes
2455
	 */
2456
	function codeclient_modifiable()
2457
	{
2458
		global $conf;
2459
		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
2460
		{
2461
			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
2462
2463
			$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
2464
			foreach ($dirsociete as $dirroot)
2465
			{
2466
				$res=dol_include_once($dirroot.$module.'.php');
2467
				if ($res) break;
2468
			}
2469
2470
			$mod = new $module();
2471
2472
			dol_syslog(get_class($this)."::codeclient_modifiable code_client=".$this->code_client." module=".$module);
2473
			if ($mod->code_modifiable_null && ! $this->code_client) return 1;
2474
			if ($mod->code_modifiable_invalide && $this->check_codeclient() < 0) return 1;
2475
			if ($mod->code_modifiable) return 1;	// A mettre en dernier
2476
			return 0;
2477
		}
2478
		else
2479
		{
2480
			return 0;
2481
		}
2482
	}
2483
2484
2485
	/**
2486
	 *    Verifie si un code fournisseur est modifiable dans configuration du module de controle des codes
2487
	 *
2488
	 *    @return     int		0=No, 1=Yes
2489
	 */
2490
	function codefournisseur_modifiable()
2491
	{
2492
		global $conf;
2493
		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
2494
		{
2495
			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
2496
2497
			$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
2498
			foreach ($dirsociete as $dirroot)
2499
			{
2500
				$res=dol_include_once($dirroot.$module.'.php');
2501
				if ($res) break;
2502
			}
2503
2504
			$mod = new $module();
2505
2506
			dol_syslog(get_class($this)."::codefournisseur_modifiable code_founisseur=".$this->code_fournisseur." module=".$module);
2507
			if ($mod->code_modifiable_null && ! $this->code_fournisseur) return 1;
2508
			if ($mod->code_modifiable_invalide && $this->check_codefournisseur() < 0) return 1;
2509
			if ($mod->code_modifiable) return 1;	// A mettre en dernier
2510
			return 0;
2511
		}
2512
		else
2513
		{
2514
			return 0;
2515
		}
2516
	}
2517
2518
2519
	/**
2520
	 *  Check customer code
2521
	 *
2522
	 *  @return     int				0 if OK
2523
	 * 								-1 ErrorBadCustomerCodeSyntax
2524
	 * 								-2 ErrorCustomerCodeRequired
2525
	 * 								-3 ErrorCustomerCodeAlreadyUsed
2526
	 * 								-4 ErrorPrefixRequired
2527
	 */
2528
	function check_codeclient()
2529
	{
2530
		global $conf;
2531
		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
2532
		{
2533
			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
2534
2535
			$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
2536
			foreach ($dirsociete as $dirroot)
2537
			{
2538
				$res=dol_include_once($dirroot.$module.'.php');
2539
				if ($res) break;
2540
			}
2541
2542
			$mod = new $module();
2543
2544
		   	dol_syslog(get_class($this)."::check_codeclient code_client=".$this->code_client." module=".$module);
2545
		   	$result = $mod->verif($this->db, $this->code_client, $this, 0);
2546
			return $result;
2547
		}
2548
		else
2549
		{
2550
			return 0;
2551
		}
2552
	}
2553
2554
	/**
2555
	 *    Check supplier code
2556
	 *
2557
	 *    @return     int		0 if OK
2558
	 * 							-1 ErrorBadCustomerCodeSyntax
2559
	 * 							-2 ErrorCustomerCodeRequired
2560
	 * 							-3 ErrorCustomerCodeAlreadyUsed
2561
	 * 							-4 ErrorPrefixRequired
2562
	 */
2563
	function check_codefournisseur()
2564
	{
2565
		global $conf;
2566
		if (! empty($conf->global->SOCIETE_CODECLIENT_ADDON))
2567
		{
2568
			$module=$conf->global->SOCIETE_CODECLIENT_ADDON;
2569
2570
			$dirsociete=array_merge(array('/core/modules/societe/'),$conf->modules_parts['societe']);
2571
			foreach ($dirsociete as $dirroot)
2572
			{
2573
				$res=dol_include_once($dirroot.$module.'.php');
2574
				if ($res) break;
2575
			}
2576
2577
			$mod = new $module();
2578
2579
			dol_syslog(get_class($this)."::check_codefournisseur code_fournisseur=".$this->code_fournisseur." module=".$module);
2580
			$result = $mod->verif($this->db, $this->code_fournisseur, $this, 1);
2581
			return $result;
2582
		}
2583
		else
2584
		{
2585
			return 0;
2586
		}
2587
	}
2588
2589
	/**
2590
	 *    	Renvoie un code compta, suivant le module de code compta.
2591
	 *      Peut etre identique a celui saisit ou genere automatiquement.
2592
	 *      A ce jour seule la generation automatique est implementee
2593
	 *
2594
	 *    	@param	string	$type		Type of thirdparty ('customer' or 'supplier')
2595
	 *		@return	string				Code compta si ok, 0 si aucun, <0 si ko
2596
	 */
2597
	function get_codecompta($type)
2598
	{
2599
		global $conf;
2600
2601
		if (! empty($conf->global->SOCIETE_CODECOMPTA_ADDON))
2602
		{
2603
			$res=false;
2604
			$dirsociete=array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
2605
			foreach ($dirsociete as $dirroot)
2606
			{
2607
				$res=dol_include_once($dirroot.$conf->global->SOCIETE_CODECOMPTA_ADDON.'.php');
2608
				if ($res) break;
2609
			}
2610
2611
			if ($res)
2612
			{
2613
				$classname = $conf->global->SOCIETE_CODECOMPTA_ADDON;
2614
				$mod = new $classname;
2615
2616
				// Defini code compta dans $mod->code
2617
				$result = $mod->get_code($this->db, $this, $type);
2618
2619
				if ($type == 'customer') $this->code_compta = $mod->code;
2620
				else if ($type == 'supplier') $this->code_compta_fournisseur = $mod->code;
2621
2622
				return $result;
2623
			}
2624
			else
2625
			{
2626
				$this->error = 'ErrorAccountancyCodeNotDefined';
2627
				return -1;
2628
			}
2629
		}
2630
		else
2631
		{
2632
			if ($type == 'customer') $this->code_compta = '';
2633
			else if ($type == 'supplier') $this->code_compta_fournisseur = '';
2634
2635
			return 0;
2636
		}
2637
	}
2638
2639
	/**
2640
	 *    Define parent commany of current company
2641
	 *
2642
	 *    @param	int		$id     Id of thirdparty to set or '' to remove
2643
	 *    @return	int     		<0 if KO, >0 if OK
2644
	 */
2645
	function set_parent($id)
2646
	{
2647
		if ($this->id)
2648
		{
2649
			$sql = "UPDATE ".MAIN_DB_PREFIX."societe";
2650
			$sql.= " SET parent = ".($id > 0 ? $id : "null");
2651
			$sql.= " WHERE rowid = " . $this->id;
2652
			dol_syslog(get_class($this).'::set_parent', LOG_DEBUG);
2653
			$resql=$this->db->query($sql);
2654
			if ($resql)
2655
			{
2656
				$this->parent = $id;
2657
				return 1;
2658
			}
2659
			else
2660
			{
2661
				return -1;
2662
			}
2663
		}
2664
		else return -1;
2665
	}
2666
2667
	/**
2668
	 *  Returns if a profid sould be verified
2669
	 *
2670
	 *  @param	int		$idprof		1,2,3,4,5,6 (Exemple: 1=siren,2=siret,3=naf,4=rcs/rm,5=idprof5,6=idprof6)
2671
	 *  @return boolean         	true , false
2672
	 */
2673
	function id_prof_verifiable($idprof)
2674
	{
2675
		global $conf;
2676
2677
	 	switch($idprof)
2678
		{
2679
			case 1:
2680
				$ret=(!$conf->global->SOCIETE_IDPROF1_UNIQUE?false:true);
2681
				break;
2682
			case 2:
2683
				$ret=(!$conf->global->SOCIETE_IDPROF2_UNIQUE?false:true);
2684
				break;
2685
			case 3:
2686
				$ret=(!$conf->global->SOCIETE_IDPROF3_UNIQUE?false:true);
2687
				break;
2688
			case 4:
2689
				$ret=(!$conf->global->SOCIETE_IDPROF4_UNIQUE?false:true);
2690
				break;
2691
			case 5:
2692
				$ret=(!$conf->global->SOCIETE_IDPROF5_UNIQUE?false:true);
2693
				break;
2694
			case 6:
2695
				$ret=(!$conf->global->SOCIETE_IDPROF6_UNIQUE?false:true);
2696
				break;
2697
			default:
2698
				$ret=false;
2699
		}
2700
2701
		return $ret;
2702
	}
2703
2704
	/**
2705
	 *    Verify if a profid exists into database for others thirds
2706
	 *
2707
	 *    @param	string	$idprof		'idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','email' (Example: idprof1=siren, idprof2=siret, idprof3=naf, idprof4=rcs/rm)
2708
	 *    @param	string	$value		Value of profid
2709
	 *    @param	int		$socid		Id of thirdparty to exclude (if update)
2710
	 *    @return   boolean				True if exists, False if not
2711
	 */
2712
	function id_prof_exists($idprof, $value, $socid=0)
2713
	{
2714
		$field = $idprof;
2715
2716
	 	switch($idprof)	// For backward compatibility
2717
		{
2718
			case '1':
2719
			case 'idprof1':
2720
				$field="siren";
2721
				break;
2722
			case '2':
2723
			case 'idprof2':
2724
				$field="siret";
2725
				break;
2726
			case '3':
2727
			case 'idprof3':
2728
				$field="ape";
2729
				break;
2730
			case '4':
2731
			case 'idprof4':
2732
				$field="idprof4";
2733
				break;
2734
			case '5':
2735
				$field="idprof5";
2736
				break;
2737
			case '6':
2738
				$field="idprof6";
2739
				break;
2740
	 	}
2741
2742
		 //Verify duplicate entries
2743
		$sql  = "SELECT COUNT(*) as idprof FROM ".MAIN_DB_PREFIX."societe WHERE ".$field." = '".$value."' AND entity IN (".getEntity('societe').")";
2744
		if($socid) $sql .= " AND rowid <> ".$socid;
2745
		$resql = $this->db->query($sql);
2746
		if ($resql)
2747
		{
2748
			$obj = $this->db->fetch_object($resql);
2749
			$count = $obj->idprof;
2750
		}
2751
		else
2752
		{
2753
			$count = 0;
2754
			print $this->db->error();
2755
		}
2756
		$this->db->free($resql);
2757
2758
		if ($count > 0) return true;
2759
		else return false;
2760
	}
2761
2762
	/**
2763
	 *  Verifie la validite d'un identifiant professionnel en fonction du pays de la societe (siren, siret, ...)
2764
	 *
2765
	 *  @param	int			$idprof         1,2,3,4 (Exemple: 1=siren,2=siret,3=naf,4=rcs/rm)
2766
	 *  @param  Societe		$soc            Objet societe
2767
	 *  @return int             			<=0 if KO, >0 if OK
2768
	 *  TODO better to have this in a lib than into a business class
2769
	 */
2770
	function id_prof_check($idprof,$soc)
2771
	{
2772
		global $conf;
2773
2774
		$ok=1;
2775
2776
		if (! empty($conf->global->MAIN_DISABLEPROFIDRULES)) return 1;
2777
2778
		// Verifie SIREN si pays FR
2779
		if ($idprof == 1 && $soc->country_code == 'FR')
2780
		{
2781
			$chaine=trim($this->idprof1);
2782
			$chaine=preg_replace('/(\s)/','',$chaine);
2783
2784
			if (!is_numeric($chaine)) return -1;
2785
			if (dol_strlen($chaine) != 9) return -1;
2786
2787
			// on prend chaque chiffre un par un
2788
			// si son index (position dans la chaîne en commence à 0 au premier caractère) est impair
2789
			// on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
2790
			// on ajoute cette valeur à la somme totale
2791
2792
			for ($index = 0; $index < 9; $index ++)
2793
			{
2794
				$number = (int) $siren[$index];
0 ignored issues
show
Bug introduced by
The variable $siren does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
2795
				if (($index % 2) != 0) { if (($number *= 2) > 9) $number -= 9; }
2796
				$sum += $number;
0 ignored issues
show
Bug introduced by
The variable $sum does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2797
			}
2798
2799
			// le numéro est valide si la somme des chiffres est multiple de 10
2800
			if (($sum % 10) != 0) return -1;
2801
		}
2802
2803
		// Verifie SIRET si pays FR
2804
		if ($idprof == 2 && $soc->country_code == 'FR')
2805
		{
2806
			$chaine=trim($this->idprof2);
2807
			$chaine=preg_replace('/(\s)/','',$chaine);
2808
2809
			if (!is_numeric($chaine)) return -1;
2810
			if (dol_strlen($chaine) != 14) return -1;
2811
2812
			// on prend chaque chiffre un par un
2813
			// si son index (position dans la chaîne en commence à 0 au premier caractère) est pair
2814
			// on double sa valeur et si cette dernière est supérieure à 9, on lui retranche 9
2815
			// on ajoute cette valeur à la somme totale
2816
2817
			for ($index = 0; $index < 14; $index ++)
2818
			{
2819
				$number = (int) $chaine[$index];
2820
				if (($index % 2) == 0) { if (($number *= 2) > 9) $number -= 9; }
2821
				$sum += $number;
2822
			}
2823
2824
			// le numéro est valide si la somme des chiffres est multiple de 10
2825
			if (($sum % 10) != 0) return -1;
2826
		}
2827
2828
		//Verify CIF/NIF/NIE if pays ES
2829
		//Returns: 1 if NIF ok, 2 if CIF ok, 3 if NIE ok, -1 if NIF bad, -2 if CIF bad, -3 if NIE bad, 0 if unexpected bad
2830
		if ($idprof == 1 && $soc->country_code == 'ES')
2831
		{
2832
			$string=trim($this->idprof1);
2833
			$string=preg_replace('/(\s)/','',$string);
2834
			$string = strtoupper($string);
2835
2836
			for ($i = 0; $i < 9; $i ++)
2837
			$num[$i] = substr($string, $i, 1);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$num was never initialized. Although not strictly required by PHP, it is generally a good practice to add $num = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2838
2839
			//Check format
2840
			if (!preg_match('/((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)/', $string))
2841
			return 0;
2842
2843
			//Check NIF
2844
			if (preg_match('/(^[0-9]{8}[A-Z]{1}$)/', $string))
2845
				if ($num[8] == substr('TRWAGMYFPDXBNJZSQVHLCKE', substr($string, 0, 8) % 23, 1))
0 ignored issues
show
Bug introduced by
The variable $num does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2846
				return 1;
2847
				else
2848
				return -1;
2849
2850
			//algorithm checking type code CIF
2851
			$sum = $num[2] + $num[4] + $num[6];
2852
			for ($i = 1; $i < 8; $i += 2)
2853
			$sum += intval(substr((2 * $num[$i]),0,1)) + intval(substr((2 * $num[$i]),1,1));
2854
			$n = 10 - substr($sum, strlen($sum) - 1, 1);
2855
2856
			//Chek special NIF
2857
			if (preg_match('/^[KLM]{1}/', $string))
2858
				if ($num[8] == chr(64 + $n) || $num[8] == substr('TRWAGMYFPDXBNJZSQVHLCKE', substr($string, 1, 8) % 23, 1))
2859
				return 1;
2860
				else
2861
				return -1;
2862
2863
			//Check CIF
2864
			if (preg_match('/^[ABCDEFGHJNPQRSUVW]{1}/', $string))
2865
				if ($num[8] == chr(64 + $n) || $num[8] == substr($n, strlen($n) - 1, 1))
2866
				return 2;
2867
				else
2868
				return -2;
2869
2870
			//Check NIE T
2871
			if (preg_match('/^[T]{1}/', $string))
2872
				if ($num[8] == preg_match('/^[T]{1}[A-Z0-9]{8}$/', $string))
2873
				return 3;
2874
				else
2875
				return -3;
2876
2877
			//Check NIE XYZ
2878
			if (preg_match('/^[XYZ]{1}/', $string))
2879
				if ($num[8] == substr('TRWAGMYFPDXBNJZSQVHLCKE', substr(str_replace(array('X','Y','Z'), array('0','1','2'), $string), 0, 8) % 23, 1))
2880
				return 3;
2881
				else
2882
				return -3;
2883
2884
			//Can not be verified
2885
			return -4;
2886
		}
2887
2888
		//Verify NIF if country is PT
2889
		//Returns: 1 if NIF ok, -1 if NIF bad, 0 if unexpected bad
2890
		if ($idprof == 1 && $soc->country_code == 'PT')
2891
		{
2892
			$string=trim($this->idprof1);
2893
			$string=preg_replace('/(\s)/','',$string);
2894
2895
			for ($i = 0; $i < 9; $i ++) {
2896
				$num[$i] = substr($string, $i, 1);
2897
			}
2898
2899
			//Check NIF
2900
			if (preg_match('/(^[0-9]{9}$)/', $string)) {
2901
				return 1;
2902
			}
2903
			else {
2904
				return -1;
2905
			}
2906
		}
2907
2908
		return $ok;
2909
	}
2910
2911
	/**
2912
	 *   Return an url to check online a professional id or empty string
2913
	 *
2914
	 *   @param		int		$idprof         1,2,3,4 (Example: 1=siren,2=siret,3=naf,4=rcs/rm)
2915
	 *   @param 	Societe	$thirdparty     Object thirdparty
2916
	 *   @return	string          		Url or empty string if no URL known
2917
	 *   TODO better in a lib than into business class
2918
	 */
2919
	function id_prof_url($idprof,$thirdparty)
2920
	{
2921
		global $conf,$langs,$hookmanager;
2922
2923
		$url='';
2924
		$action = '';
2925
2926
		$hookmanager->initHooks(array('idprofurl'));
2927
		$parameters=array('idprof'=>$idprof, 'company'=>$thirdparty);
2928
		$reshook=$hookmanager->executeHooks('getIdProfUrl',$parameters,$this,$action);    // Note that $action and $object may have been modified by some hooks
2929
		if (empty($reshook)) {
2930
			if (! empty($conf->global->MAIN_DISABLEPROFIDRULES)) {
2931
				return '';
2932
			}
2933
2934
			// TODO Move links to validate professional ID into a dictionary table "country" + "link"
2935
            $strippedIdProf1 = str_replace(' ', '', $thirdparty->idprof1);
2936
			if ($idprof == 1 && $thirdparty->country_code == 'FR') {
2937
				$url='http://www.societe.com/cgi-bin/search?champs='.$strippedIdProf1;    // See also http://avis-situation-sirene.insee.fr/
2938
			}
2939
			if ($idprof == 1 && ($thirdparty->country_code == 'GB' || $thirdparty->country_code == 'UK')) {
2940
				$url='https://beta.companieshouse.gov.uk/company/'.$strippedIdProf1;
2941
			}
2942
			if ($idprof == 1 && $thirdparty->country_code == 'ES') {
2943
				$url='http://www.e-informa.es/servlet/app/portal/ENTP/screen/SProducto/prod/ETIQUETA_EMPRESA/nif/'.$strippedIdProf1;
2944
			}
2945
			if ($idprof == 1 && $thirdparty->country_code == 'IN') {
2946
				$url='http://www.tinxsys.com/TinxsysInternetWeb/dealerControllerServlet?tinNumber='.$strippedIdProf1.';&searchBy=TIN&backPage=searchByTin_Inter.jsp';
2947
			}
2948
			if ($idprof == 1 && $thirdparty->country_code == 'PT') {
2949
				$url='http://www.nif.pt/'.$strippedIdProf1;
2950
			}
2951
2952
			if ($url) {
2953
				return '<a target="_blank" href="'.$url.'">'.$langs->trans("Check").'</a>';
2954
			}
2955
		}
2956
		else {
2957
			return $hookmanager->resPrint;
2958
		}
2959
2960
		return '';
2961
	}
2962
2963
	/**
2964
	 *   Indique si la societe a des projets
2965
	 *
2966
	 *   @return     bool	   true si la societe a des projets, false sinon
2967
	 */
2968
	function has_projects()
2969
	{
2970
		$sql = 'SELECT COUNT(*) as numproj FROM '.MAIN_DB_PREFIX.'projet WHERE fk_soc = ' . $this->id;
2971
		$resql = $this->db->query($sql);
2972
		if ($resql)
2973
		{
2974
			$obj = $this->db->fetch_object($resql);
2975
			$count = $obj->numproj;
2976
		}
2977
		else
2978
		{
2979
			$count = 0;
2980
			print $this->db->error();
2981
		}
2982
		$this->db->free($resql);
2983
		return ($count > 0);
2984
	}
2985
2986
2987
	/**
2988
	 *  Load information for tab info
2989
	 *
2990
	 *  @param  int		$id     Id of thirdparty to load
2991
	 *  @return	void
2992
	 */
2993
	function info($id)
2994
	{
2995
		$sql = "SELECT s.rowid, s.nom as name, s.datec as date_creation, tms as date_modification,";
2996
		$sql.= " fk_user_creat, fk_user_modif";
2997
		$sql.= " FROM ".MAIN_DB_PREFIX."societe as s";
2998
		$sql.= " WHERE s.rowid = ".$id;
2999
3000
		$result=$this->db->query($sql);
3001
		if ($result)
3002
		{
3003
			if ($this->db->num_rows($result))
3004
			{
3005
				$obj = $this->db->fetch_object($result);
3006
3007
				$this->id = $obj->rowid;
3008
3009
				if ($obj->fk_user_creat) {
3010
					$cuser = new User($this->db);
3011
					$cuser->fetch($obj->fk_user_creat);
3012
					$this->user_creation     = $cuser;
3013
				}
3014
3015
				if ($obj->fk_user_modif) {
3016
					$muser = new User($this->db);
3017
					$muser->fetch($obj->fk_user_modif);
3018
					$this->user_modification = $muser;
0 ignored issues
show
Documentation Bug introduced by
It seems like $muser of type object<User> is incompatible with the declared type string of property $user_modification.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
3019
				}
3020
3021
				$this->ref			     = $obj->name;
3022
				$this->date_creation     = $this->db->jdate($obj->date_creation);
3023
				$this->date_modification = $this->db->jdate($obj->date_modification);
3024
			}
3025
3026
			$this->db->free($result);
3027
3028
		}
3029
		else
3030
		{
3031
			dol_print_error($this->db);
3032
		}
3033
	}
3034
3035
	/**
3036
	 *  Return if third party is a company (Business) or an end user (Consumer)
3037
	 *
3038
	 *  @return    boolean     true=is a company, false=a and user
3039
	 */
3040
	function isACompany()
3041
	{
3042
		global $conf;
3043
3044
		// Define if third party is treated as company (or not) when nature is unknown
3045
		$isacompany=empty($conf->global->MAIN_UNKNOWN_CUSTOMERS_ARE_COMPANIES)?0:1; // 0 by default
3046
		if (! empty($this->tva_intra)) $isacompany=1;
3047
		else if (! empty($this->typent_code) && in_array($this->typent_code,array('TE_PRIVATE'))) $isacompany=0;
3048
		else if (! empty($this->typent_code) && in_array($this->typent_code,array('TE_SMALL','TE_MEDIUM','TE_LARGE','TE_GROUP'))) $isacompany=1;
3049
3050
		return $isacompany;
3051
	}
3052
3053
	/**
3054
	 *  Return if a company is inside the EEC (European Economic Community)
3055
	 *
3056
	 *  @return     boolean		true = country inside EEC, false = country outside EEC
3057
	 */
3058
	function isInEEC()
3059
	{
3060
		require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
3061
		return isInEEC($this);
3062
	}
3063
3064
	/**
3065
	 *  Charge la liste des categories fournisseurs
3066
	 *
3067
	 *  @return    int      0 if success, <> 0 if error
3068
	 */
3069
	function LoadSupplierCateg()
3070
	{
3071
		$this->SupplierCategories = array();
3072
		$sql = "SELECT rowid, label";
3073
		$sql.= " FROM ".MAIN_DB_PREFIX."categorie";
3074
		$sql.= " WHERE type = ".Categorie::TYPE_SUPPLIER;
3075
3076
		$resql=$this->db->query($sql);
3077
		if ($resql)
3078
		{
3079
			while ($obj = $this->db->fetch_object($resql) )
3080
			{
3081
				$this->SupplierCategories[$obj->rowid] = $obj->label;
3082
			}
3083
			return 0;
3084
		}
3085
		else
3086
		{
3087
			return -1;
3088
		}
3089
	}
3090
3091
	/**
3092
	 *  Insert link supplier - category
3093
	 *
3094
	 *	@param	int		$categorie_id		Id of category
3095
	 *  @return int      					0 if success, <> 0 if error
3096
	 */
3097
	function AddFournisseurInCategory($categorie_id)
3098
	{
3099
		if ($categorie_id > 0 && $this->id > 0)
3100
		{
3101
			$sql = "INSERT INTO ".MAIN_DB_PREFIX."categorie_fournisseur (fk_categorie, fk_soc) ";
3102
			$sql.= " VALUES (".$categorie_id.", ".$this->id.")";
3103
3104
			if ($resql=$this->db->query($sql)) return 0;
3105
		}
3106
		else
3107
		{
3108
			return 0;
3109
		}
3110
		return -1;
3111
	}
3112
3113
3114
	/**
3115
	 *  Create a third party into database from a member object
3116
	 *
3117
	 *  @param	Adherent	$member		Object member
3118
	 * 	@param	string	$socname		Name of third party to force
3119
	 *	@param	string	$socalias	Alias name of third party to force
3120
	 *  @return int					<0 if KO, id of created account if OK
3121
	 */
3122
	function create_from_member(Adherent $member, $socname='', $socalias='')
3123
	{
3124
		global $user,$langs;
3125
3126
		dol_syslog(get_class($this)."::create_from_member", LOG_DEBUG);
3127
3128
		$name = $socname?$socname:$member->societe;
3129
		if (empty($name)) $name=$member->getFullName($langs);
3130
3131
		$alias = $socalias?$socalias:'';
3132
3133
		// Positionne parametres
3134
		$this->nom=$name;				// TODO deprecated
3135
		$this->name=$name;
3136
		$this->name_alias=$alias;
3137
		$this->address=$member->address;
3138
		$this->zip=$member->zip;
3139
		$this->town=$member->town;
3140
		$this->country_code=$member->country_code;
3141
		$this->country_id=$member->country_id;
3142
		$this->phone=$member->phone;       // Prof phone
3143
		$this->email=$member->email;
3144
		$this->skype=$member->skype;
3145
3146
		$this->client = 1;				// A member is a customer by default
3147
		$this->code_client = -1;
0 ignored issues
show
Documentation Bug introduced by
The property $code_client was declared of type string, but -1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
3148
		$this->code_fournisseur = -1;
0 ignored issues
show
Documentation Bug introduced by
The property $code_fournisseur was declared of type string, but -1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
3149
3150
		$this->db->begin();
3151
3152
		// Cree et positionne $this->id
3153
		$result=$this->create($user);
3154
		if ($result >= 0)
3155
		{
3156
			$sql = "UPDATE ".MAIN_DB_PREFIX."adherent";
3157
			$sql.= " SET fk_soc=".$this->id;
3158
			$sql.= " WHERE rowid=".$member->id;
3159
3160
			$resql=$this->db->query($sql);
3161
			if ($resql)
3162
			{
3163
				$this->db->commit();
3164
				return $this->id;
3165
			}
3166
			else
3167
			{
3168
				$this->error=$this->db->error();
3169
3170
				$this->db->rollback();
3171
				return -1;
3172
			}
3173
		}
3174
		else
3175
		{
3176
			// $this->error deja positionne
3177
			dol_syslog(get_class($this)."::create_from_member - 2 - ".$this->error." - ".join(',',$this->errors), LOG_ERR);
3178
3179
			$this->db->rollback();
3180
			return $result;
3181
		}
3182
	}
3183
3184
	/**
3185
	 * 	Set properties with value into $conf
3186
	 *
3187
	 * 	@param	Conf	$conf		Conf object (possibility to use another entity)
3188
	 * 	@return	void
3189
	 */
3190
	function setMysoc(Conf $conf)
3191
	{
3192
		global $langs;
3193
3194
		$this->id=0;
3195
		$this->name=empty($conf->global->MAIN_INFO_SOCIETE_NOM)?'':$conf->global->MAIN_INFO_SOCIETE_NOM;
3196
		$this->address=empty($conf->global->MAIN_INFO_SOCIETE_ADDRESS)?'':$conf->global->MAIN_INFO_SOCIETE_ADDRESS;
3197
		$this->zip=empty($conf->global->MAIN_INFO_SOCIETE_ZIP)?'':$conf->global->MAIN_INFO_SOCIETE_ZIP;
3198
		$this->town=empty($conf->global->MAIN_INFO_SOCIETE_TOWN)?'':$conf->global->MAIN_INFO_SOCIETE_TOWN;
3199
		$this->state_id=empty($conf->global->MAIN_INFO_SOCIETE_STATE)?'':$conf->global->MAIN_INFO_SOCIETE_STATE;
3200
		$this->region_code=empty($conf->global->MAIN_INFO_SOCIETE_REGION)?'':$conf->global->MAIN_INFO_SOCIETE_REGION;
3201
3202
		$this->note_private=empty($conf->global->MAIN_INFO_SOCIETE_NOTE)?'':$conf->global->MAIN_INFO_SOCIETE_NOTE;
3203
3204
		$this->nom=$this->name; 									// deprecated
3205
3206
		// We define country_id, country_code and country
3207
		$country_id=$country_code=$country_label='';
3208
		if (! empty($conf->global->MAIN_INFO_SOCIETE_COUNTRY))
3209
		{
3210
			$tmp=explode(':',$conf->global->MAIN_INFO_SOCIETE_COUNTRY);
3211
			$country_id=$tmp[0];
3212
			if (! empty($tmp[1]))   // If $conf->global->MAIN_INFO_SOCIETE_COUNTRY is "id:code:label"
3213
			{
3214
				$country_code=$tmp[1];
3215
				$country_label=$tmp[2];
3216
			}
3217
			else                    // For backward compatibility
3218
			{
3219
				dol_syslog("Your country setup use an old syntax. Reedit it using setup area.", LOG_ERR);
3220
				include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
3221
				$country_code=getCountry($country_id,2,$this->db);  // This need a SQL request, but it's the old feature that should not be used anymore
3222
				$country_label=getCountry($country_id,0,$this->db);  // This need a SQL request, but it's the old feature that should not be used anymore
3223
			}
3224
		}
3225
		$this->country_id=$country_id;
3226
		$this->country_code=$country_code;
3227
		$this->country=$country_label;
3228
		if (is_object($langs)) $this->country=($langs->trans('Country'.$country_code)!='Country'.$country_code)?$langs->trans('Country'.$country_code):$country_label;
3229
3230
		$this->phone=empty($conf->global->MAIN_INFO_SOCIETE_TEL)?'':$conf->global->MAIN_INFO_SOCIETE_TEL;
3231
		$this->fax=empty($conf->global->MAIN_INFO_SOCIETE_FAX)?'':$conf->global->MAIN_INFO_SOCIETE_FAX;
3232
		$this->url=empty($conf->global->MAIN_INFO_SOCIETE_WEB)?'':$conf->global->MAIN_INFO_SOCIETE_WEB;
3233
		// Id prof generiques
3234
		$this->idprof1=empty($conf->global->MAIN_INFO_SIREN)?'':$conf->global->MAIN_INFO_SIREN;
3235
		$this->idprof2=empty($conf->global->MAIN_INFO_SIRET)?'':$conf->global->MAIN_INFO_SIRET;
3236
		$this->idprof3=empty($conf->global->MAIN_INFO_APE)?'':$conf->global->MAIN_INFO_APE;
3237
		$this->idprof4=empty($conf->global->MAIN_INFO_RCS)?'':$conf->global->MAIN_INFO_RCS;
3238
		$this->idprof5=empty($conf->global->MAIN_INFO_PROFID5)?'':$conf->global->MAIN_INFO_PROFID5;
3239
		$this->idprof6=empty($conf->global->MAIN_INFO_PROFID6)?'':$conf->global->MAIN_INFO_PROFID6;
3240
		$this->tva_intra=empty($conf->global->MAIN_INFO_TVAINTRA)?'':$conf->global->MAIN_INFO_TVAINTRA;	// VAT number, not necessarly INTRA.
3241
		$this->managers=empty($conf->global->MAIN_INFO_SOCIETE_MANAGERS)?'':$conf->global->MAIN_INFO_SOCIETE_MANAGERS;
3242
		$this->capital=empty($conf->global->MAIN_INFO_CAPITAL)?'':$conf->global->MAIN_INFO_CAPITAL;
3243
		$this->forme_juridique_code=empty($conf->global->MAIN_INFO_SOCIETE_FORME_JURIDIQUE)?'':$conf->global->MAIN_INFO_SOCIETE_FORME_JURIDIQUE;
3244
		$this->email=empty($conf->global->MAIN_INFO_SOCIETE_MAIL)?'':$conf->global->MAIN_INFO_SOCIETE_MAIL;
3245
		$this->logo=empty($conf->global->MAIN_INFO_SOCIETE_LOGO)?'':$conf->global->MAIN_INFO_SOCIETE_LOGO;
3246
		$this->logo_small=empty($conf->global->MAIN_INFO_SOCIETE_LOGO_SMALL)?'':$conf->global->MAIN_INFO_SOCIETE_LOGO_SMALL;
3247
		$this->logo_mini=empty($conf->global->MAIN_INFO_SOCIETE_LOGO_MINI)?'':$conf->global->MAIN_INFO_SOCIETE_LOGO_MINI;
3248
3249
		// Define if company use vat or not
3250
		$this->tva_assuj=$conf->global->FACTURE_TVAOPTION;
3251
3252
		// Define if company use local taxes
3253
		$this->localtax1_assuj=((isset($conf->global->FACTURE_LOCAL_TAX1_OPTION) && ($conf->global->FACTURE_LOCAL_TAX1_OPTION=='1' || $conf->global->FACTURE_LOCAL_TAX1_OPTION=='localtax1on'))?1:0);
3254
		$this->localtax2_assuj=((isset($conf->global->FACTURE_LOCAL_TAX2_OPTION) && ($conf->global->FACTURE_LOCAL_TAX2_OPTION=='1' || $conf->global->FACTURE_LOCAL_TAX2_OPTION=='localtax2on'))?1:0);
3255
	}
3256
3257
	/**
3258
	 *  Initialise an instance with random values.
3259
	 *  Used to build previews or test instances.
3260
	 *	id must be 0 if object instance is a specimen.
3261
	 *
3262
	 *  @return	void
3263
	 */
3264
	function initAsSpecimen()
3265
	{
3266
		$now=dol_now();
3267
3268
		// Initialize parameters
3269
		$this->id=0;
3270
		$this->name = 'THIRDPARTY SPECIMEN '.dol_print_date($now,'dayhourlog');
3271
		$this->nom = $this->name;   // For backward compatibility
3272
		$this->ref_ext = 'Ref ext';
3273
		$this->specimen=1;
3274
		$this->address='21 jump street';
3275
		$this->zip='99999';
3276
		$this->town='MyTown';
3277
		$this->state_id=1;
3278
		$this->state_code='AA';
3279
		$this->state='MyState';
3280
		$this->country_id=1;
3281
		$this->country_code='FR';
3282
		$this->email='[email protected]';
3283
		$this->skype='tom.hanson';
3284
		$this->url='http://www.specimen.com';
3285
3286
		$this->phone='0909090901';
3287
		$this->fax='0909090909';
3288
3289
		$this->code_client='CC-'.dol_print_date($now,'dayhourlog');
3290
		$this->code_fournisseur='SC-'.dol_print_date($now,'dayhourlog');
3291
		$this->capital=10000;
3292
		$this->client=1;
3293
		$this->prospect=1;
3294
		$this->fournisseur=1;
3295
		$this->tva_assuj=1;
3296
		$this->tva_intra='EU1234567';
3297
		$this->note_public='This is a comment (public)';
3298
		$this->note_private='This is a comment (private)';
3299
3300
		$this->idprof1='idprof1';
3301
		$this->idprof2='idprof2';
3302
		$this->idprof3='idprof3';
3303
		$this->idprof4='idprof4';
3304
		$this->idprof5='idprof5';
3305
		$this->idprof6='idprof6';
3306
	}
3307
3308
	/**
3309
	 *  Check if we must use localtax feature or not according to country (country of $mysoc in most cases).
3310
	 *
3311
	 *	@param		int		$localTaxNum	To get info for only localtax1 or localtax2
3312
	 *  @return		boolean					true or false
3313
	 */
3314
	function useLocalTax($localTaxNum=0)
3315
	{
3316
		$sql  = "SELECT t.localtax1, t.localtax2";
3317
		$sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
3318
		$sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$this->db->escape($this->country_code)."'";
3319
		$sql .= " AND t.active = 1";
3320
		if (empty($localTaxNum))   $sql .= " AND (t.localtax1_type <> '0' OR t.localtax2_type <> '0')";
3321
		elseif ($localTaxNum == 1) $sql .= " AND t.localtax1_type <> '0'";
3322
		elseif ($localTaxNum == 2) $sql .= " AND t.localtax2_type <> '0'";
3323
3324
		dol_syslog("useLocalTax", LOG_DEBUG);
3325
		$resql=$this->db->query($sql);
3326
		if ($resql)
3327
		{
3328
   			return ($this->db->num_rows($resql) > 0);
3329
		}
3330
		else return false;
3331
	}
3332
3333
	/**
3334
	 *  Check if we must use NPR Vat (french stupid rule) or not according to country (country of $mysoc in most cases).
3335
	 *
3336
	 *  @return		boolean					true or false
3337
	 */
3338
	function useNPR()
3339
	{
3340
		$sql  = "SELECT t.rowid";
3341
		$sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t, ".MAIN_DB_PREFIX."c_country as c";
3342
		$sql .= " WHERE t.fk_pays = c.rowid AND c.code = '".$this->db->escape($this->country_code)."'";
3343
		$sql .= " AND t.active = 1 AND t.recuperableonly = 1";
3344
3345
		dol_syslog("useNPR", LOG_DEBUG);
3346
		$resql=$this->db->query($sql);
3347
		if ($resql)
3348
		{
3349
			return ($this->db->num_rows($resql) > 0);
3350
		}
3351
		else return false;
3352
	}
3353
3354
	/**
3355
	 *  Check if we must use revenue stamps feature or not according to country (country of $mysocin most cases).
3356
	 *
3357
	 *  @return		boolean			true or false
3358
	 */
3359
	function useRevenueStamp()
3360
	{
3361
		$sql  = "SELECT COUNT(*) as nb";
3362
		$sql .= " FROM ".MAIN_DB_PREFIX."c_revenuestamp as r, ".MAIN_DB_PREFIX."c_country as c";
3363
		$sql .= " WHERE r.fk_pays = c.rowid AND c.code = '".$this->db->escape($this->country_code)."'";
3364
		$sql .= " AND r.active = 1";
3365
3366
		dol_syslog("useRevenueStamp", LOG_DEBUG);
3367
		$resql=$this->db->query($sql);
3368
		if ($resql)
3369
		{
3370
			$obj=$this->db->fetch_object($resql);
3371
   			return (($obj->nb > 0)?true:false);
3372
		}
3373
		else
3374
		{
3375
			$this->error=$this->db->lasterror();
3376
			return false;
3377
		}
3378
	}
3379
3380
	/**
3381
	 *	Return prostect level
3382
	 *
3383
	 *  @return     string        Libelle
3384
	 */
3385
	function getLibProspLevel()
3386
	{
3387
		return $this->LibProspLevel($this->fk_prospectlevel);
3388
	}
3389
3390
	/**
3391
	 *  Return label of prospect level
3392
	 *
3393
	 *  @param	int		$fk_prospectlevel   	Prospect level
3394
	 *  @return string        					label of level
3395
	 */
3396
	function LibProspLevel($fk_prospectlevel)
3397
	{
3398
		global $langs;
3399
3400
		$lib=$langs->trans("ProspectLevel".$fk_prospectlevel);
3401
		// If lib not found in language file, we get label from cache/databse
3402
		if ($lib == $langs->trans("ProspectLevel".$fk_prospectlevel))
3403
		{
3404
			$lib=$langs->getLabelFromKey($this->db,$fk_prospectlevel,'c_prospectlevel','code','label');
3405
		}
3406
		return $lib;
3407
	}
3408
3409
3410
	/**
3411
	 *  Set prospect level
3412
	 *
3413
	 *  @param  User	$user		Utilisateur qui definie la remise
3414
	 *	@return	int					<0 if KO, >0 if OK
3415
	 * @deprecated Use update function instead
3416
	 */
3417
	function set_prospect_level(User $user)
3418
	{
3419
		return $this->update($this->id, $user);
3420
	}
3421
3422
	/**
3423
	 *  Return status of prospect
3424
	 *
3425
	 *  @param	int		$mode       0=libelle long, 1=libelle court, 2=Picto + Libelle court, 3=Picto, 4=Picto + Libelle long
3426
	 *  @param	string	$label		Label to use for status for added status
3427
	 *  @return string        		Libelle
3428
	 */
3429
	function getLibProspCommStatut($mode=0, $label='')
3430
	{
3431
		return $this->LibProspCommStatut($this->stcomm_id, $mode, $label);
3432
	}
3433
3434
	/**
3435
	 *  Return label of a given status
3436
	 *
3437
	 *  @param	int|string	$statut        	Id or code for prospection status
3438
	 *  @param  int			$mode          	0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
3439
	 *  @param	string		$label			Label to use for status for added status
3440
	 *  @return string       	 			Libelle du statut
3441
	 */
3442
	function LibProspCommStatut($statut, $mode=0, $label='')
3443
	{
3444
		global $langs;
3445
		$langs->load('customers');
3446
3447
		if ($mode == 2)
3448
		{
3449
			if ($statut == '-1' || $statut == 'ST_NO')         return img_action($langs->trans("StatusProspect-1"),-1).' '.$langs->trans("StatusProspect-1");
3450
			elseif ($statut ==  '0' || $statut == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0).' '.$langs->trans("StatusProspect0");
3451
			elseif ($statut ==  '1' || $statut == 'ST_TODO')  return img_action($langs->trans("StatusProspect1"), 1).' '.$langs->trans("StatusProspect1");
3452
			elseif ($statut ==  '2' || $statut == 'ST_PEND')  return img_action($langs->trans("StatusProspect2"), 2).' '.$langs->trans("StatusProspect2");
3453
			elseif ($statut ==  '3' || $statut == 'ST_DONE')  return img_action($langs->trans("StatusProspect3"), 3).' '.$langs->trans("StatusProspect3");
3454
			else
3455
			{
3456
				return img_action(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label, 0).' '.(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label);
3457
			}
3458
		}
3459
		if ($mode == 3)
3460
		{
3461
			if ($statut == '-1' || $statut == 'ST_NO')         return img_action($langs->trans("StatusProspect-1"),-1);
3462
			elseif ($statut ==  '0' || $statut == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0);
3463
			elseif ($statut ==  '1' || $statut == 'ST_TODO')  return img_action($langs->trans("StatusProspect1"), 1);
3464
			elseif ($statut ==  '2' || $statut == 'ST_PEND')  return img_action($langs->trans("StatusProspect2"), 2);
3465
			elseif ($statut ==  '3' || $statut == 'ST_DONE')  return img_action($langs->trans("StatusProspect3"), 3);
3466
			else
3467
			{
3468
				return img_action(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label, 0);
3469
			}
3470
		}
3471
		if ($mode == 4)
3472
		{
3473
			if ($statut == '-1' || $statut == 'ST_NO')         return img_action($langs->trans("StatusProspect-1"),-1).' '.$langs->trans("StatusProspect-1");
3474
			elseif ($statut ==  '0' || $statut == 'ST_NEVER') return img_action($langs->trans("StatusProspect0"), 0).' '.$langs->trans("StatusProspect0");
3475
			elseif ($statut ==  '1' || $statut == 'ST_TODO')  return img_action($langs->trans("StatusProspect1"), 1).' '.$langs->trans("StatusProspect1");
3476
			elseif ($statut ==  '2' || $statut == 'ST_PEND')  return img_action($langs->trans("StatusProspect2"), 2).' '.$langs->trans("StatusProspect2");
3477
			elseif ($statut ==  '3' || $statut == 'ST_DONE')  return img_action($langs->trans("StatusProspect3"), 3).' '.$langs->trans("StatusProspect3");
3478
			else
3479
			{
3480
				return img_action(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label, 0).' '.(($langs->trans("StatusProspect".$statut) != "StatusProspect".$statut) ? $langs->trans("StatusProspect".$statut) : $label);
3481
			}
3482
		}
3483
3484
		return "Error, mode/status not found";
3485
	}
3486
3487
	/**
3488
	 *  Set outstanding value
3489
	 *
3490
	 *  @param  User	$user		User making change
3491
	 *	@return	int					<0 if KO, >0 if OK
3492
	 * @deprecated Use update function instead
3493
	 */
3494
	function set_OutstandingBill(User $user)
3495
	{
3496
		return $this->update($this->id, $user);
3497
	}
3498
3499
	/**
3500
	 *  Return amount of order not paid and total
3501
	 *
3502
	 *  @param     string      $mode    'customer' or 'supplier'
3503
	 *  @return    array				array('opened'=>Amount, 'total'=>Total amount)
3504
	 */
3505
	function getOutstandingProposals($mode='customer')
3506
	{
3507
		$table='propal';
3508
		if ($mode == 'supplier') $table = 'supplier_proposal';
3509
3510
		$sql  = "SELECT rowid, total_ht, total as total_ttc, fk_statut FROM ".MAIN_DB_PREFIX.$table." as f";
3511
		$sql .= " WHERE fk_soc = ". $this->id;
3512
		if ($mode == 'supplier') {
3513
			$sql .= " AND entity IN (".getEntity('supplier_proposal').")";
3514
		} else {
3515
			$sql .= " AND entity IN (".getEntity('propal').")";
3516
		}
3517
3518
		dol_syslog("getOutstandingProposals", LOG_DEBUG);
3519
		$resql=$this->db->query($sql);
3520
		if ($resql)
3521
		{
3522
			$outstandingOpened = 0;
3523
			$outstandingTotal = 0;
3524
			$outstandingTotalIncTax = 0;
3525
			while($obj=$this->db->fetch_object($resql)) {
3526
				$outstandingTotal+= $obj->total_ht;
3527
				$outstandingTotalIncTax+= $obj->total_ttc;
3528
				if ($obj->fk_statut != 0)    // Not a draft
3529
				{
3530
					$outstandingOpened+=$obj->total_ttc;
3531
				}
3532
			}
3533
			return array('opened'=>$outstandingOpened, 'total_ht'=>$outstandingTotal, 'total_ttc'=>$outstandingTotalIncTax);	// 'opened' is 'incl taxes'
3534
		}
3535
		else
3536
			return array();
3537
	}
3538
3539
	/**
3540
	 *  Return amount of order not paid and total
3541
	 *
3542
	 *  @param     string      $mode    'customer' or 'supplier'
3543
	 *  @return		array				array('opened'=>Amount, 'total'=>Total amount)
3544
	 */
3545
	function getOutstandingOrders($mode='customer')
3546
	{
3547
		$table='commande';
3548
		if ($mode == 'supplier') $table = 'commande_fournisseur';
3549
3550
		$sql  = "SELECT rowid, total_ht, total_ttc, fk_statut FROM ".MAIN_DB_PREFIX.$table." as f";
3551
		$sql .= " WHERE fk_soc = ". $this->id;
3552
		if ($mode == 'supplier') {
3553
			$sql .= " AND entity IN (".getEntity('supplier_order').")";
3554
		} else {
3555
			$sql .= " AND entity IN (".getEntity('commande').")";
3556
		}
3557
3558
		dol_syslog("getOutstandingOrders", LOG_DEBUG);
3559
		$resql=$this->db->query($sql);
3560
		if ($resql)
3561
		{
3562
			$outstandingOpened = 0;
3563
			$outstandingTotal = 0;
3564
			$outstandingTotalIncTax = 0;
3565
			while($obj=$this->db->fetch_object($resql)) {
3566
				$outstandingTotal+= $obj->total_ht;
3567
				$outstandingTotalIncTax+= $obj->total_ttc;
3568
				if ($obj->fk_statut != 0)    // Not a draft
3569
				{
3570
					$outstandingOpened+=$obj->total_ttc;
3571
				}
3572
			}
3573
			return array('opened'=>$outstandingOpened, 'total_ht'=>$outstandingTotal, 'total_ttc'=>$outstandingTotalIncTax);	// 'opened' is 'incl taxes'
3574
		}
3575
		else
3576
			return array();
3577
	}
3578
3579
	/**
3580
	 *  Return amount of bill not paid and total
3581
	 *
3582
	 *  @param     string      $mode    'customer' or 'supplier'
3583
	 *  @return		array				array('opened'=>Amount, 'total'=>Total amount)
3584
	 */
3585
	function getOutstandingBills($mode='customer')
3586
	{
3587
		$table='facture';
3588
		if ($mode == 'supplier') $table = 'facture_fourn';
3589
3590
		/* Accurate value of remain to pay is to sum remaintopay for each invoice
3591
		 $paiement = $invoice->getSommePaiement();
3592
		 $creditnotes=$invoice->getSumCreditNotesUsed();
3593
		 $deposits=$invoice->getSumDepositsUsed();
3594
		 $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
3595
		 $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
3596
		 */
3597
		if ($mode == 'supplier') $sql  = "SELECT rowid, total_ht as total_ht, total_ttc, paye, fk_statut, close_code FROM ".MAIN_DB_PREFIX.$table." as f";
3598
		else $sql  = "SELECT rowid, total as total_ht, total_ttc, paye, fk_statut, close_code FROM ".MAIN_DB_PREFIX.$table." as f";
3599
		$sql .= " WHERE fk_soc = ". $this->id;
3600
		if ($mode == 'supplier') {
3601
			$sql .= " AND entity IN (".getEntity('facture_fourn').")";
3602
		} else {
3603
			$sql .= " AND entity IN (".getEntity('facture').")";
3604
		}
3605
3606
		dol_syslog("getOutstandingBills", LOG_DEBUG);
3607
		$resql=$this->db->query($sql);
3608
		if ($resql)
3609
		{
3610
			$outstandingOpened = 0;
3611
			$outstandingTotal = 0;
3612
			$outstandingTotalIncTax = 0;
3613
			if ($mode == 'supplier')
3614
			{
3615
				require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
3616
				$tmpobject=new FactureFournisseur($this->db);
3617
			}
3618
			else
3619
			{
3620
				require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
3621
				$tmpobject=new Facture($this->db);
3622
			}
3623
			while($obj=$this->db->fetch_object($resql)) {
3624
				$tmpobject->id=$obj->rowid;
3625
				if ($obj->fk_statut != 0                                           // Not a draft
3626
					&& ! ($obj->fk_statut == 3 && $obj->close_code == 'replaced')  // Not a replaced invoice
3627
					)
3628
				{
3629
					$outstandingTotal+= $obj->total_ht;
3630
					$outstandingTotalIncTax+= $obj->total_ttc;
3631
				}
3632
				if ($obj->paye == 0
3633
					&& $obj->fk_statut != 0    // Not a draft
3634
					&& $obj->fk_statut != 3	   // Not abandonned
3635
					&& $obj->fk_statut != 2)   // Not classified as paid
3636
				//$sql .= " AND (fk_statut <> 3 OR close_code <> 'abandon')";		// Not abandonned for undefined reason
3637
				{
3638
					$paiement = $tmpobject->getSommePaiement();
3639
					$creditnotes = $tmpobject->getSumCreditNotesUsed();
3640
					$deposits = $tmpobject->getSumDepositsUsed();
3641
					$outstandingOpened+=$obj->total_ttc - $paiement - $creditnotes - $deposits;
3642
				}
3643
			}
3644
			return array('opened'=>$outstandingOpened, 'total_ht'=>$outstandingTotal, 'total_ttc'=>$outstandingTotalIncTax);	// 'opened' is 'incl taxes'
3645
		}
3646
		else
3647
		{
3648
			return array();
3649
		}
3650
	}
3651
3652
	/**
3653
	 *  Return amount of bill not paid
3654
	 *
3655
	 *  @return		int				Amount in debt for thirdparty
3656
	 *  @deprecated
3657
	 */
3658
	function get_OutstandingBill()
3659
	{
3660
		/* Accurate value of remain to pay is to sum remaintopay for each invoice
3661
	     $paiement = $invoice->getSommePaiement();
3662
	     $creditnotes=$invoice->getSumCreditNotesUsed();
3663
	     $deposits=$invoice->getSumDepositsUsed();
3664
	     $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
3665
	     $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
3666
	     */
3667
		$sql  = "SELECT rowid, total_ttc FROM ".MAIN_DB_PREFIX."facture as f";
3668
		$sql .= " WHERE fk_soc = ". $this->id;
3669
		$sql .= " AND paye = 0";
3670
		$sql .= " AND fk_statut <> 0";	// Not a draft
3671
		//$sql .= " AND (fk_statut <> 3 OR close_code <> 'abandon')";		// Not abandonned for undefined reason
3672
		$sql .= " AND fk_statut <> 3";		// Not abandonned
3673
		$sql .= " AND fk_statut <> 2";		// Not clasified as paid
3674
3675
		dol_syslog("get_OutstandingBill", LOG_DEBUG);
3676
		$resql=$this->db->query($sql);
3677
		if ($resql)
3678
		{
3679
			$outstandingAmount = 0;
3680
			require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
3681
			$tmpobject=new Facture($this->db);
3682
			while($obj=$this->db->fetch_object($resql)) {
3683
				$tmpobject->id=$obj->rowid;
3684
				$paiement = $tmpobject->getSommePaiement();
3685
				$creditnotes = $tmpobject->getSumCreditNotesUsed();
3686
				$deposits = $tmpobject->getSumDepositsUsed();
3687
				$outstandingAmount+= $obj->total_ttc - $paiement - $creditnotes - $deposits;
3688
			}
3689
			return $outstandingAmount;
3690
		}
3691
		else
3692
			return 0;
3693
	}
3694
3695
	/**
3696
	 * Return label of status customer is prospect/customer
3697
	 *
3698
	 * @return   string        	Label
3699
	 */
3700
	function getLibCustProspStatut()
3701
	{
3702
		return $this->LibCustProspStatut($this->client);
3703
	}
3704
3705
	/**
3706
	 *  Renvoi le libelle d'un statut donne
3707
	 *
3708
	 *  @param	int		$statut         Id statut
3709
	 *  @return	string          		Libelle du statut
3710
	 */
3711
	function LibCustProspStatut($statut)
3712
	{
3713
		global $langs;
3714
		$langs->load('companies');
3715
3716
		if ($statut==0) return $langs->trans("NorProspectNorCustomer");
3717
		if ($statut==1) return $langs->trans("Customer");
3718
		if ($statut==2) return $langs->trans("Prospect");
3719
		if ($statut==3) return $langs->trans("ProspectCustomer");
3720
3721
	}
3722
3723
3724
	/**
3725
	 *  Create a document onto disk according to template module.
3726
	 *
3727
	 *	@param	string		$modele			Generator to use. Caller must set it to obj->modelpdf or GETPOST('modelpdf') for example.
3728
	 *	@param	Translate	$outputlangs	objet lang a utiliser pour traduction
3729
	 *  @param  int			$hidedetails    Hide details of lines
3730
	 *  @param  int			$hidedesc       Hide description
3731
	 *  @param  int			$hideref        Hide ref
3732
	 *  @param  null|array  $moreparams     Array to provide more information
3733
	 *	@return int        					<0 if KO, >0 if OK
3734
	 */
3735
	public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null)
3736
	{
3737
		global $conf,$user,$langs;
3738
3739
		if (! empty($moreparams) && ! empty($moreparams['use_companybankid']))
3740
		{
3741
			$modelpath = "core/modules/bank/doc/";
3742
3743
			include_once DOL_DOCUMENT_ROOT.'/societe/class/companybankaccount.class.php';
3744
			$companybankaccount = new CompanyBankAccount($this->db);
3745
			$result = $companybankaccount->fetch($moreparams['use_companybankid']);
3746
			if (! $result) dol_print_error($this->db, $companybankaccount->error, $companybankaccount->errors);
3747
			$result=$companybankaccount->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
0 ignored issues
show
Bug introduced by
The method commonGenerateDocument() cannot be called from this context as it is declared protected in class CommonObject.

This check looks for access to methods that are not accessible from the current context.

If you need to make a method accessible to another context you can raise its visibility level in the defining class.

Loading history...
3748
		}
3749
		else
3750
		{
3751
			// Positionne le modele sur le nom du modele a utiliser
3752
			if (! dol_strlen($modele))
3753
			{
3754
				if (! empty($conf->global->COMPANY_ADDON_PDF))
3755
				{
3756
					$modele = $conf->global->COMPANY_ADDON_PDF;
3757
				}
3758
				else
3759
				{
3760
					print $langs->trans("Error")." ".$langs->trans("Error_COMPANY_ADDON_PDF_NotDefined");
3761
					return 0;
3762
				}
3763
			}
3764
3765
			$modelpath = "core/modules/societe/doc/";
3766
3767
			$result=$this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
3768
		}
3769
3770
		return $result;
3771
	}
3772
3773
3774
	/**
3775
	 * Sets object to supplied categories.
3776
	 *
3777
	 * Deletes object from existing categories not supplied.
3778
	 * Adds it to non existing supplied categories.
3779
	 * Existing categories are left untouch.
3780
	 *
3781
	 * @param 	int[]|int 	$categories 	Category ID or array of Categories IDs
3782
	 * @param 	string 		$type 			Category type ('customer' or 'supplier')
3783
	 * @return	int							<0 if KO, >0 if OK
3784
	 */
3785
	public function setCategories($categories, $type)
3786
	{
3787
		require_once DOL_DOCUMENT_ROOT . '/categories/class/categorie.class.php';
3788
3789
		// Decode type
3790
		if ($type == 'customer') {
3791
			$type_id = Categorie::TYPE_CUSTOMER;
3792
			$type_text = 'customer';
3793
		} elseif ($type == 'supplier') {
3794
			$type_id = Categorie::TYPE_SUPPLIER;
3795
			$type_text = 'supplier';
3796
		} else {
3797
			dol_syslog(__METHOD__ . ': Type ' . $type .  'is an unknown company category type. Done nothing.', LOG_ERR);
3798
			return -1;
3799
		}
3800
3801
		// Handle single category
3802
		if (!is_array($categories)) {
3803
			$categories = array($categories);
3804
		}
3805
3806
		// Get current categories
3807
		$c = new Categorie($this->db);
3808
		$existing = $c->containing($this->id, $type_id, 'id');
3809
3810
		// Diff
3811
		if (is_array($existing)) {
3812
			$to_del = array_diff($existing, $categories);
3813
			$to_add = array_diff($categories, $existing);
3814
		} else {
3815
			$to_del = array(); // Nothing to delete
3816
			$to_add = $categories;
3817
		}
3818
3819
		$error = 0;
3820
3821
		// Process
3822
		foreach ($to_del as $del) {
3823
			if ($c->fetch($del) > 0) {
3824
				$c->del_type($this, $type_text);
3825
			}
3826
		}
3827
		foreach ($to_add as $add) {
3828
			if ($c->fetch($add) > 0)
3829
			{
3830
				$result = $c->add_type($this, $type_text);
3831
				if ($result < 0)
3832
				{
3833
					$error++;
3834
					$this->error = $c->error;
3835
					$this->errors = $c->errors;
3836
					break;
3837
				}
3838
			}
3839
		}
3840
3841
		return $error ? -1 : 1;
3842
	}
3843
3844
	/**
3845
	 * Sets sales representatives of the thirdparty
3846
	 *
3847
	 * @param 	int[]|int 	$salesrep	 	User ID or array of user IDs
3848
	 * @return	int							<0 if KO, >0 if OK
3849
	 */
3850
	public function setSalesRep($salesrep)
3851
	{
3852
		global $user;
3853
3854
		// Handle single user
3855
		if (!is_array($salesrep)) {
3856
			$salesrep = array($salesrep);
3857
		}
3858
3859
		// Get current users
3860
		$existing = $this->getSalesRepresentatives($user, 1);
3861
3862
		// Diff
3863
		if (is_array($existing)) {
3864
			$to_del = array_diff($existing, $salesrep);
3865
			$to_add = array_diff($salesrep, $existing);
3866
		} else {
3867
			$to_del = array(); // Nothing to delete
3868
			$to_add = $salesrep;
3869
		}
3870
3871
		$error = 0;
3872
3873
		// Process
3874
		foreach ($to_del as $del) {
3875
			$this->del_commercial($user, $del);
3876
		}
3877
		foreach ($to_add as $add) {
3878
			$result = $this->add_commercial($user, $add);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $this->add_commercial($user, $add) (which targets Societe::add_commercial()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
3879
			if ($result < 0)
3880
			{
3881
				$error++;
3882
				$this->error = $c->error;
0 ignored issues
show
Bug introduced by
The variable $c does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
3883
				$this->errors = $c->errors;
3884
				break;
3885
			}
3886
		}
3887
3888
		return $error ? -1 : 1;
3889
	}
3890
3891
3892
	/**
3893
	 * Function used to replace a thirdparty id with another one.
3894
	 * It must be used within a transaction to avoid trouble
3895
	 *
3896
	 * @param 	DoliDB 	$db 		Database handler
3897
	 * @param 	int 	$origin_id 	Old thirdparty id (will be removed)
3898
	 * @param 	int 	$dest_id 	New thirdparty id
3899
	 * @return 	bool				True if success, False if error
3900
	 */
3901
	public static function replaceThirdparty(DoliDB $db, $origin_id, $dest_id)
3902
	{
3903
		if ($origin_id == $dest_id)
3904
		{
3905
			dol_syslog('Error: Try to merge a thirdparty into itself');
3906
			return false;
3907
		}
3908
3909
		/**
3910
		 * Thirdparty commercials cannot be the same in both thirdparties so we look for them and remove some to avoid duplicate.
3911
		 * Because this function is meant to be executed within a transaction, we won't take care of begin/commit.
3912
		 */
3913
		$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'societe_commerciaux ';
3914
		$sql .= ' WHERE fk_soc = '.(int) $dest_id.' AND fk_user IN ( ';
3915
		$sql .= ' SELECT fk_user ';
3916
		$sql .= ' FROM '.MAIN_DB_PREFIX.'societe_commerciaux ';
3917
		$sql .= ' WHERE fk_soc = '.(int) $origin_id.') ';
3918
3919
		$query = $db->query($sql);
3920
3921
		while ($result = $db->fetch_object($query)) {
3922
			$db->query('DELETE FROM '.MAIN_DB_PREFIX.'societe_commerciaux WHERE rowid = '.$result->rowid);
3923
		}
3924
3925
		/**
3926
		 * llx_societe_extrafields table must not be here because we don't care about the old thirdparty data
3927
		 * Do not include llx_societe because it will be replaced later
3928
		 */
3929
		$tables = array(
3930
			'societe_address',
3931
			'societe_commerciaux',
3932
			'societe_log',
3933
			'societe_prices',
3934
			'societe_remise',
3935
			'societe_remise_except',
3936
			'societe_rib'
3937
		);
3938
3939
		return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables);
3940
	}
3941
}
3942