Societe::id_prof_url()   D
last analyzed

Complexity

Conditions 17
Paths 130

Size

Total Lines 45
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 27
nc 130
nop 2
dl 0
loc 45
rs 4.9666
c 0
b 0
f 0

How to fix   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
3
/* Copyright (C) 2002-2006  Rodolphe Quiedeville        <[email protected]>
4
 * Copyright (C) 2004-2021  Laurent Destailleur         <[email protected]>
5
 * Copyright (C) 2004       Eric Seigne                 <[email protected]>
6
 * Copyright (C) 2003       Brian Fraval                <[email protected]>
7
 * Copyright (C) 2006       Andre Cianfarani            <[email protected]>
8
 * Copyright (C) 2005-2017  Regis Houssin               <[email protected]>
9
 * Copyright (C) 2008       Patrick Raguin              <[email protected]>
10
 * Copyright (C) 2010-2018  Juanjo Menent               <[email protected]>
11
 * Copyright (C) 2013       Florian Henry               <[email protected]>
12
 * Copyright (C) 2013-2023  Alexandre Spangaro          <[email protected]>
13
 * Copyright (C) 2013       Peter Fontaine              <[email protected]>
14
 * Copyright (C) 2014-2015  Marcos García               <[email protected]>
15
 * Copyright (C) 2015       Raphaël Doursenaud          <[email protected]>
16
 * Copyright (C) 2017       Rui Strecht			        <[email protected]>
17
 * Copyright (C) 2018	    Philippe Grand	            <[email protected]>
18
 * Copyright (C) 2019-2020  Josep Lluís Amador          <[email protected]>
19
 * Copyright (C) 2019-2024  Frédéric France             <[email protected]>
20
 * Copyright (C) 2020       Open-Dsi         		    <[email protected]>
21
 * Copyright (C) 2022		ButterflyOfFire             <[email protected]>
22
 * Copyright (C) 2023       Alexandre Janniaux          <[email protected]>
23
 * Copyright (C) 2024		William Mead			    <[email protected]>
24
 * Copyright (C) 2024		MDW							<[email protected]>
25
 * Copyright (C) 2024       Rafael San José             <[email protected]>
26
 *
27
 * This program is free software; you can redistribute it and/or modify
28
 * it under the terms of the GNU General Public License as published by
29
 * the Free Software Foundation; either version 3 of the License, or
30
 * (at your option) any later version.
31
 *
32
 * This program is distributed in the hope that it will be useful,
33
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
35
 * GNU General Public License for more details.
36
 *
37
 * You should have received a copy of the GNU General Public License
38
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
39
 */
40
41
namespace Dolibarr\Code\Societe\Classes;
42
43
use Dolibarr\Code\Adherents\Classes\Adherent;
44
use Dolibarr\Code\Categories\Classes\Categorie;
45
use Dolibarr\Code\Compta\Classes\Account;
46
use Dolibarr\Code\Compta\Classes\BonPrelevement;
47
use Dolibarr\Code\Compta\Classes\Facture;
48
use Dolibarr\Code\Contact\Classes\Contact;
49
use Dolibarr\Code\Contact\Trait\Mailing;
50
use Dolibarr\Code\Core\Classes\Conf;
51
use Dolibarr\Code\Core\Classes\DiscountAbsolute;
52
use Dolibarr\Code\Core\Classes\Form;
53
use Dolibarr\Code\Core\Classes\Interfaces;
54
use Dolibarr\Code\Core\Classes\Translate;
55
use Dolibarr\Code\Core\Traits\CommonIncoterm;
56
use Dolibarr\Code\Core\Traits\CommonPeople;
57
use Dolibarr\Code\Core\Traits\CommonSocialNetworks;
58
use Dolibarr\Code\Fourn\Classes\FactureFournisseur;
59
use Dolibarr\Code\MultiCurrency\Classes\MultiCurrency;
60
use Dolibarr\Code\User\Classes\User;
61
use Dolibarr\Core\Base\CommonObject;
62
use DoliDB;
63
64
/**
65
 *  Class to manage third parties objects (customers, suppliers, prospects...)
66
 */
67
class Societe extends CommonObject
68
{
69
    use CommonIncoterm;
0 ignored issues
show
Bug introduced by
The trait Dolibarr\Code\Core\Traits\CommonIncoterm requires the property $code which is not provided by Dolibarr\Code\Societe\Classes\Societe.
Loading history...
70
    use CommonSocialNetworks;
71
    use CommonPeople;
0 ignored issues
show
introduced by
The trait Dolibarr\Code\Core\Traits\CommonPeople requires some properties which are not provided by Dolibarr\Code\Societe\Classes\Societe: $MAIN_SHOW_REGION_IN_STATE_SELECT, $phone_perso, $user_mobile, $office_phone, $attributes, $global, $civility_code, $use_javascript_ajax, $societe, $office_fax
Loading history...
72
    use Mailing;
73
74
    const STATUS_CEASED = 0;
75
    const STATUS_INACTIVITY = 1;
76
77
    /**
78
     * Third party type is no customer
79
     */
80
    const NO_CUSTOMER = 0;
81
82
    /**
83
     * Third party type is a customer
84
     */
85
    const CUSTOMER = 1;
86
87
    /**
88
     * Third party type is a prospect
89
     */
90
    const PROSPECT = 2;
91
92
    /**
93
     * Third party type is a customer and a prospect
94
     */
95
    const CUSTOMER_AND_PROSPECT = 3;
96
97
    /**
98
     * Third party supplier flag is not supplier
99
     */
100
    const NO_SUPPLIER = 0;
101
102
    /**
103
     * Third party supplier flag is a supplier
104
     */
105
    const SUPPLIER = 1;
106
107
    /**
108
     * @var string ID of module.
109
     */
110
    public $module = 'societe';
111
112
    /**
113
     * @var string ID to identify managed object
114
     */
115
    public $element = 'societe';
116
117
    /**
118
     * @var string Name of table without prefix where object is stored
119
     */
120
    public $table_element = 'societe';
121
122
    /**
123
     * @var string Field with ID of parent key if this field has a parent or for child tables
124
     */
125
    public $fk_element = 'fk_soc';
126
127
    /**
128
     * @var string Fields for combobox
129
     */
130
    public $fieldsforcombobox = 'nom,name_alias';
131
    /**
132
     * @var string String with name of icon for myobject. Must be the part after the 'object_' into object_myobject.png
133
     */
134
    public $picto = 'company';
135
    /**
136
     * 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
137
     * @var integer
138
     */
139
    public $restrictiononfksoc = 1;
140
    /**
141
     * @var static To store a cloned copy of object before to edit it and keep track of old properties
142
     */
143
    public $oldcopy;
144
    /**
145
     * array of supplier categories
146
     * @var array
147
     */
148
    public $SupplierCategories = array();
149
    /**
150
     * prefixCustomerIsRequired
151
     * @var int
152
     */
153
    public $prefixCustomerIsRequired;
154
    /**
155
     * @var array<string,array{type:string,length?:string|int,label:string,enabled:int<0,2>|string,position:int,notnull?:int,visible:int,noteditable?:int,default?:string,index?:int,foreignkey?:string,searchall?:int,isameasure?:int,css?:string,csslist?:string,help?:string,showoncombobox?:int,disabled?:int,arrayofkeyval?:array<int,string>,comment?:string}>  Array with all fields and their property. Do not use it as a static var. It may be modified by constructor.
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<string,array{type:...ring>,comment?:string}> at position 22 could not be parsed: Expected '}' at position 22, but found 'int'.
Loading history...
156
     */
157
    public $fields = array(
158
        'rowid' => array('type' => 'integer', 'label' => 'TechnicalID', 'enabled' => 1, 'visible' => -2, 'noteditable' => 1, 'notnull' => 1, 'index' => 1, 'position' => 1, 'comment' => 'Id', 'css' => 'left'),
159
        'parent' => array('type' => 'integer', 'label' => 'Parent', 'enabled' => 1, 'visible' => -1, 'position' => 20),
160
        'tms' => array('type' => 'timestamp', 'label' => 'DateModification', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 25),
161
        'datec' => array('type' => 'datetime', 'label' => 'DateCreation', 'enabled' => 1, 'visible' => -1, 'position' => 30),
162
        'nom' => array('type' => 'varchar(128)', 'length' => 128, 'label' => 'Nom', 'enabled' => 1, 'visible' => -1, 'position' => 35, 'showoncombobox' => 1, 'csslist' => 'tdoverflowmax150'),
163
        'name_alias' => array('type' => 'varchar(128)', 'label' => 'Name alias', 'enabled' => 1, 'visible' => -1, 'position' => 36, 'showoncombobox' => 2),
164
        'entity' => array('type' => 'integer', 'label' => 'Entity', 'default' => '1', 'enabled' => 1, 'visible' => -2, 'notnull' => 1, 'position' => 40, 'index' => 1),
165
        'ref_ext' => array('type' => 'varchar(255)', 'label' => 'RefExt', 'enabled' => 1, 'visible' => 0, 'position' => 45),
166
        'code_client' => array('type' => 'varchar(24)', 'label' => 'CustomerCode', 'enabled' => 1, 'visible' => -1, 'position' => 55),
167
        'code_fournisseur' => array('type' => 'varchar(24)', 'label' => 'SupplierCode', 'enabled' => 1, 'visible' => -1, 'position' => 60),
168
        'code_compta' => array('type' => 'varchar(24)', 'label' => 'CustomerAccountancyCode', 'enabled' => 1, 'visible' => -1, 'position' => 65),
169
        'code_compta_fournisseur' => array('type' => 'varchar(24)', 'label' => 'SupplierAccountancyCode', 'enabled' => 1, 'visible' => -1, 'position' => 70),
170
        'address' => array('type' => 'varchar(255)', 'label' => 'Address', 'enabled' => 1, 'visible' => -1, 'position' => 75),
171
        'zip' => array('type' => 'varchar(25)', 'label' => 'Zip', 'enabled' => 1, 'visible' => -1, 'position' => 80),
172
        'town' => array('type' => 'varchar(50)', 'label' => 'Town', 'enabled' => 1, 'visible' => -1, 'position' => 85),
173
        'fk_departement' => array('type' => 'integer', 'label' => 'State', 'enabled' => 1, 'visible' => -1, 'position' => 90),
174
        'fk_pays' => array('type' => 'integer:Ccountry:core/class/ccountry.class.php', 'label' => 'Country', 'enabled' => 1, 'visible' => -1, 'position' => 95),
175
        'phone' => array('type' => 'varchar(20)', 'label' => 'Phone', 'enabled' => 1, 'visible' => -1, 'position' => 100),
176
        'phone_mobile' => array('type' => 'varchar(20)', 'label' => 'PhoneMobile', 'enabled' => 1, 'visible' => -1, 'position' => 102),
177
        'fax' => array('type' => 'varchar(20)', 'label' => 'Fax', 'enabled' => 1, 'visible' => -1, 'position' => 105),
178
        'url' => array('type' => 'varchar(255)', 'label' => 'Url', 'enabled' => 1, 'visible' => -1, 'position' => 110),
179
        'email' => array('type' => 'varchar(128)', 'label' => 'Email', 'enabled' => 1, 'visible' => -1, 'position' => 115),
180
        'socialnetworks' => array('type' => 'text', 'label' => 'Socialnetworks', 'enabled' => 1, 'visible' => -1, 'position' => 120),
181
        'fk_effectif' => array('type' => 'integer', 'label' => 'Workforce', 'enabled' => 1, 'visible' => -1, 'position' => 170),
182
        'fk_typent' => array('type' => 'integer', 'label' => 'TypeOfCompany', 'enabled' => 1, 'visible' => -1, 'position' => 175, 'csslist' => 'minwidth200'),
183
        'fk_forme_juridique' => array('type' => 'integer', 'label' => 'JuridicalStatus', 'enabled' => 1, 'visible' => -1, 'position' => 180),
184
        'fk_currency' => array('type' => 'varchar(3)', 'label' => 'Currency', 'enabled' => 1, 'visible' => -1, 'position' => 185),
185
        'siren' => array('type' => 'varchar(128)', 'label' => 'Idprof1', 'enabled' => 1, 'visible' => -1, 'position' => 190),
186
        'siret' => array('type' => 'varchar(128)', 'label' => 'Idprof2', 'enabled' => 1, 'visible' => -1, 'position' => 195),
187
        'ape' => array('type' => 'varchar(128)', 'label' => 'Idprof3', 'enabled' => 1, 'visible' => -1, 'position' => 200),
188
        'idprof4' => array('type' => 'varchar(128)', 'label' => 'Idprof4', 'enabled' => 1, 'visible' => -1, 'position' => 205),
189
        'idprof5' => array('type' => 'varchar(128)', 'label' => 'Idprof5', 'enabled' => 1, 'visible' => -1, 'position' => 206),
190
        'idprof6' => array('type' => 'varchar(128)', 'label' => 'Idprof6', 'enabled' => 1, 'visible' => -1, 'position' => 207),
191
        'tva_intra' => array('type' => 'varchar(20)', 'label' => 'Tva intra', 'enabled' => 1, 'visible' => -1, 'position' => 210),
192
        'capital' => array('type' => 'double(24,8)', 'label' => 'Capital', 'enabled' => 1, 'visible' => -1, 'position' => 215),
193
        'fk_stcomm' => array('type' => 'integer', 'label' => 'CommercialStatus', 'enabled' => 1, 'visible' => -1, 'notnull' => 1, 'position' => 220),
194
        'note_public' => array('type' => 'html', 'label' => 'NotePublic', 'enabled' => 1, 'visible' => 0, 'position' => 225),
195
        'note_private' => array('type' => 'html', 'label' => 'NotePrivate', 'enabled' => 1, 'visible' => 0, 'position' => 230),
196
        'prefix_comm' => array('type' => 'varchar(5)', 'label' => 'Prefix comm', 'enabled' => "getDolGlobalInt('SOCIETE_USEPREFIX')", 'visible' => -1, 'position' => 235),
197
        'client' => array('type' => 'tinyint(4)', 'label' => 'Client', 'enabled' => 1, 'visible' => -1, 'position' => 240),
198
        'fournisseur' => array('type' => 'tinyint(4)', 'label' => 'Fournisseur', 'enabled' => 1, 'visible' => -1, 'position' => 245),
199
        'supplier_account' => array('type' => 'varchar(32)', 'label' => 'Supplier account', 'enabled' => 1, 'visible' => -1, 'position' => 250),
200
        'fk_prospectlevel' => array('type' => 'varchar(12)', 'label' => 'ProspectLevel', 'enabled' => 1, 'visible' => -1, 'position' => 255),
201
        'customer_bad' => array('type' => 'tinyint(4)', 'label' => 'Customer bad', 'enabled' => 1, 'visible' => -1, 'position' => 260),
202
        'customer_rate' => array('type' => 'double', 'label' => 'Customer rate', 'enabled' => 1, 'visible' => -1, 'position' => 265),
203
        'supplier_rate' => array('type' => 'double', 'label' => 'Supplier rate', 'enabled' => 1, 'visible' => -1, 'position' => 270),
204
        'fk_user_creat' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserAuthor', 'enabled' => 1, 'visible' => -2, 'position' => 275),
205
        'fk_user_modif' => array('type' => 'integer:User:user/class/user.class.php', 'label' => 'UserModif', 'enabled' => 1, 'visible' => -2, 'notnull' => -1, 'position' => 280),
206
        //'remise_client' =>array('type'=>'double', 'label'=>'CustomerDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>285, 'isameasure'=>1),
207
        //'remise_supplier' =>array('type'=>'double', 'label'=>'SupplierDiscount', 'enabled'=>1, 'visible'=>-1, 'position'=>290, 'isameasure'=>1),
208
        'mode_reglement' => array('type' => 'tinyint(4)', 'label' => 'Mode reglement', 'enabled' => 1, 'visible' => -1, 'position' => 295),
209
        'cond_reglement' => array('type' => 'tinyint(4)', 'label' => 'Cond reglement', 'enabled' => 1, 'visible' => -1, 'position' => 300),
210
        'deposit_percent' => array('type' => 'varchar(63)', 'label' => 'DepositPercent', 'enabled' => 1, 'visible' => -1, 'position' => 301),
211
        'mode_reglement_supplier' => array('type' => 'integer', 'label' => 'Mode reglement supplier', 'enabled' => 1, 'visible' => -1, 'position' => 305),
212
        'cond_reglement_supplier' => array('type' => 'integer', 'label' => 'Cond reglement supplier', 'enabled' => 1, 'visible' => -1, 'position' => 308),
213
        'outstanding_limit' => array('type' => 'double(24,8)', 'label' => 'OutstandingBill', 'enabled' => 1, 'visible' => -1, 'position' => 310, 'isameasure' => 1),
214
        'order_min_amount' => array('type' => 'double(24,8)', 'label' => 'Order min amount', 'enabled' => 'isModEnabled("order") && !empty($conf->global->ORDER_MANAGE_MIN_AMOUNT)', 'visible' => -1, 'position' => 315, 'isameasure' => 1),
215
        'supplier_order_min_amount' => array('type' => 'double(24,8)', 'label' => 'Supplier order min amount', 'enabled' => 'isModEnabled("order") && !empty($conf->global->ORDER_MANAGE_MIN_AMOUNT)', 'visible' => -1, 'position' => 320, 'isameasure' => 1),
216
        'fk_shipping_method' => array('type' => 'integer', 'label' => 'Fk shipping method', 'enabled' => 1, 'visible' => -1, 'position' => 330),
217
        'tva_assuj' => array('type' => 'tinyint(4)', 'label' => 'Tva assuj', 'enabled' => 1, 'visible' => -1, 'position' => 335),
218
        'localtax1_assuj' => array('type' => 'tinyint(4)', 'label' => 'Localtax1 assuj', 'enabled' => 1, 'visible' => -1, 'position' => 340),
219
        'localtax1_value' => array('type' => 'double(6,3)', 'label' => 'Localtax1 value', 'enabled' => 1, 'visible' => -1, 'position' => 345),
220
        'localtax2_assuj' => array('type' => 'tinyint(4)', 'label' => 'Localtax2 assuj', 'enabled' => 1, 'visible' => -1, 'position' => 350),
221
        'localtax2_value' => array('type' => 'double(6,3)', 'label' => 'Localtax2 value', 'enabled' => 1, 'visible' => -1, 'position' => 355),
222
        'vat_reverse_charge' => array('type' => 'tinyint(4)', 'label' => 'Vat reverse charge', 'enabled' => 1, 'visible' => -1, 'position' => 335),
223
        'barcode' => array('type' => 'varchar(255)', 'label' => 'Barcode', 'enabled' => 1, 'visible' => -1, 'position' => 360),
224
        'price_level' => array('type' => 'integer', 'label' => 'Price level', 'enabled' => '$conf->global->PRODUIT_MULTIPRICES || getDolGlobalString("PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES")', 'visible' => -1, 'position' => 365),
225
        'default_lang' => array('type' => 'varchar(6)', 'label' => 'Default lang', 'enabled' => 1, 'visible' => -1, 'position' => 370),
226
        'canvas' => array('type' => 'varchar(32)', 'label' => 'Canvas', 'enabled' => 1, 'visible' => -1, 'position' => 375),
227
        'fk_barcode_type' => array('type' => 'integer', 'label' => 'Fk barcode type', 'enabled' => 1, 'visible' => -1, 'position' => 405),
228
        'webservices_url' => array('type' => 'varchar(255)', 'label' => 'Webservices url', 'enabled' => 1, 'visible' => -1, 'position' => 410),
229
        'webservices_key' => array('type' => 'varchar(128)', 'label' => 'Webservices key', 'enabled' => 1, 'visible' => -1, 'position' => 415),
230
        'fk_incoterms' => array('type' => 'integer', 'label' => 'Fk incoterms', 'enabled' => 1, 'visible' => -1, 'position' => 425),
231
        'location_incoterms' => array('type' => 'varchar(255)', 'label' => 'Location incoterms', 'enabled' => 1, 'visible' => -1, 'position' => 430),
232
        'model_pdf' => array('type' => 'varchar(255)', 'label' => 'Model pdf', 'enabled' => 1, 'visible' => 0, 'position' => 435),
233
        'last_main_doc' => array('type' => 'varchar(255)', 'label' => 'LastMainDoc', 'enabled' => 1, 'visible' => -1, 'position' => 270),
234
        'fk_multicurrency' => array('type' => 'integer', 'label' => 'Fk multicurrency', 'enabled' => 1, 'visible' => -1, 'position' => 440),
235
        'multicurrency_code' => array('type' => 'varchar(255)', 'label' => 'Multicurrency code', 'enabled' => 1, 'visible' => -1, 'position' => 445),
236
        'fk_account' => array('type' => 'integer', 'label' => 'PaymentBankAccount', 'enabled' => 1, 'visible' => -1, 'position' => 450),
237
        'fk_warehouse' => array('type' => 'integer', 'label' => 'Warehouse', 'enabled' => 1, 'visible' => -1, 'position' => 455),
238
        'logo' => array('type' => 'varchar(255)', 'label' => 'Logo', 'enabled' => 1, 'visible' => -1, 'position' => 400),
239
        'logo_squarred' => array('type' => 'varchar(255)', 'label' => 'Logo squarred', 'enabled' => 1, 'visible' => -1, 'position' => 401),
240
        'status' => array('type' => 'tinyint(4)', 'label' => 'Status', 'enabled' => 1, 'visible' => -1, 'position' => 500),
241
        'import_key' => array('type' => 'varchar(14)', 'label' => 'ImportId', 'enabled' => 1, 'visible' => -2, 'position' => 1000),
242
    );
243
    /**
244
     * @var int Entity
245
     */
246
    public $entity;
247
248
    /**
249
     *  'type' field format ('integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]', 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter]]]', 'varchar(x)', 'double(24,8)', 'real', 'price', 'text', 'text:none', 'html', 'date', 'datetime', 'timestamp', 'duration', 'mail', 'phone', 'url', 'password')
250
     *         Note: Filter can be a string like "(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.nature:is:NULL)"
251
     *  'label' the translation key.
252
     *  'picto' is code of a picto to show before value in forms
253
     *  'enabled' is a condition when the field must be managed (Example: 1 or 'getDolGlobalString("MY_SETUP_PARAM")'
254
     *  'position' is the sort order of field.
255
     *  'notnull' is set to 1 if not null in database. Set to -1 if we must set data to null if empty ('' or 0).
256
     *  'visible' says if field is visible in list (Examples: 0=Not visible, 1=Visible on list and create/update/view forms, 2=Visible on list only, 3=Visible on create/update/view form only (not list), 4=Visible on list and update/view form only (not create). 5=Visible on list and view only (not create/not update). Using a negative value means field is not shown by default on list but can be selected for viewing)
257
     *  'noteditable' says if field is not editable (1 or 0)
258
     *  'default' is a default value for creation (can still be overwrote by the Setup of Default Values if field is editable in creation form). Note: If default is set to '(PROV)' and field is 'ref', the default value will be set to '(PROVid)' where id is rowid when a new record is created.
259
     *  'index' if we want an index in database.
260
     *  'foreignkey'=>'tablename.field' if the field is a foreign key (it is recommended to name the field fk_...).
261
     *  'searchall' is 1 if we want to search in this field when making a search from the quick search button.
262
     *  'isameasure' must be set to 1 if you want to have a total on list for this field. Field type must be summable like integer or double(24,8).
263
     *  'css' and 'cssview' and 'csslist' is the CSS style to use on field. 'css' is used in creation and update. 'cssview' is used in view mode. 'csslist' is used for columns in lists. For example: 'maxwidth200', 'wordbreak', 'tdoverflowmax200'
264
     *  'help' is a 'TranslationString' to use to show a tooltip on field. You can also use 'TranslationString:keyfortooltiponlick' for a tooltip on click.
265
     *  'showoncombobox' if value of the field must be visible into the label of the combobox that list record
266
     *  'disabled' is 1 if we want to have the field locked by a 'disabled' attribute. In most cases, this is never set into the definition of $fields into class, but is set dynamically by some part of code.
267
     *  'arrayofkeyval' to set list of value if type is a list of predefined values. For example: array("0"=>"Draft","1"=>"Active","-1"=>"Cancel")
268
     *  'autofocusoncreate' to have field having the focus on a create form. Only 1 field should have this property set to 1.
269
     *  'comment' is not used. You can store here any text of your choice. It is not used by application.
270
     *
271
     *  Note: To have value dynamic, you can set value to 0 in definition and edit the value on the fly into the constructor.
272
     */
273
    /**
274
     * Thirdparty name
275
     * @var string
276
     * @deprecated Use $name instead
277
     * @see $name
278
     */
279
    public $nom;
280
    /**
281
     * @var string Thirdparty name
282
     */
283
    public $name;
284
    /**
285
     * Alias names (commercial, trademark or alias names)
286
     * @var string
287
     */
288
    public $name_alias;
289
    /**
290
     * @var int Physical thirdparty not a company
291
     */
292
    public $particulier;
293
    /**
294
     * Thirdparty status : 0=activity ceased, 1= in activity
295
     * @var int
296
     */
297
    public $status = 1;
298
    /**
299
     * @var string  region code
300
     */
301
    public $region_code;
302
    /**
303
     * @var string Region name
304
     */
305
    public $region;
306
    /**
307
     * @var int country_id
308
     */
309
    public $country_id;
310
    /**
311
     * @var string State code
312
     * @deprecated Use $state_code instead
313
     * @see $state_code
314
     */
315
    public $departement_code;
316
    /**
317
     * @var string
318
     * @deprecated Use $state instead
319
     * @see $state
320
     */
321
    public $departement;
322
    /**
323
     * @var string
324
     * @deprecated Use $country instead
325
     * @see $country
326
     */
327
    public $pays;
328
    /**
329
     * Phone number
330
     * @var string
331
     */
332
    public $phone;
333
    /**
334
     * PhoneMobile number
335
     * @var string
336
     */
337
    public $phone_mobile;
338
    /**
339
     * Fax number
340
     * @var string
341
     */
342
    public $fax;
343
    /**
344
     * Email
345
     * @var string
346
     */
347
    public $email;
348
    /**
349
     * No Email
350
     * @var int     Set if company email found into unsubscribe of emailing list table
351
     */
352
    public $no_email;
353
    /**
354
     * Skype username
355
     * @var string
356
     * @deprecated
357
     */
358
    public $skype;
359
    /**
360
     * Twitter username
361
     * @var string
362
     * @deprecated
363
     */
364
    public $twitter;
365
    /**
366
     * Facebook username
367
     * @var string
368
     * @deprecated
369
     */
370
    public $facebook;
371
    /**
372
     * LinkedIn username
373
     * @var string
374
     * @deprecated
375
     */
376
    public $linkedin;
377
    /**
378
     * Webpage
379
     * @var string
380
     */
381
    public $url;
382
    /**
383
     * Barcode value
384
     * @var string
385
     */
386
    public $barcode;
387
    /**
388
     * Professional ID 1 (Ex: Siren in France)
389
     * @var string
390
     */
391
    public $idprof1;
392
    /**
393
     * @var string Professional ID 1
394
     * @deprecated Use $idprof1 instead
395
     * @see $idprof1
396
     */
397
    public $siren;
398
399
    // 6 professional id (usage depends on country)
400
    /**
401
     * Professional ID 2 (Ex: Siret in France)
402
     * @var string
403
     */
404
    public $idprof2;
405
    /**
406
     * @var string Professional ID 2
407
     * @deprecated Use $idprof2 instead
408
     * @see $idprof2
409
     */
410
    public $siret;
411
    /**
412
     * Professional ID 3 (Ex: Ape in France)
413
     * @var string
414
     */
415
    public $idprof3;
416
    /**
417
     * @var string Professional ID 3
418
     * @deprecated Use $idprof3 instead
419
     * @see $idprof3
420
     */
421
    public $ape;
422
    /**
423
     * Professional ID 4 (Ex: RCS in France)
424
     * @var string
425
     */
426
    public $idprof4;
427
    /**
428
     * Professional ID 5
429
     * @var string
430
     */
431
    public $idprof5;
432
    /**
433
     * Professional ID 6
434
     * @var string
435
     */
436
    public $idprof6;
437
    /**
438
     * Professional ID 7
439
     * @var string
440
     */
441
    public $idprof7;
442
    /**
443
     * Professional ID 8
444
     * @var string
445
     */
446
    public $idprof8;
447
    /**
448
     * Professional ID 9
449
     * @var string
450
     */
451
    public $idprof9;
452
    /**
453
     * Professional ID 10
454
     * @var string
455
     */
456
    public $idprof10;
457
    /**
458
     * Social object of the company
459
     * @var string
460
     */
461
    public $socialobject;
462
    /**
463
     * @var string Prefix comm
464
     */
465
    public $prefix_comm;
466
    /**
467
     * @var int     Vat concerned
468
     */
469
    public $tva_assuj = 1;
470
    /**
471
     * @var string  Intracommunitary VAT ID
472
     */
473
    public $tva_intra;
474
    /**
475
     * @var int     Vat reverse-charge concerned
476
     */
477
    public $vat_reverse_charge = 0;
478
    public $localtax1_assuj;
479
    public $localtax1_value;
480
481
    // Local taxes
482
    public $localtax2_assuj;
483
    public $localtax2_value;
484
    /**
485
     * @var string Manager
486
     */
487
    public $managers;
488
    /**
489
     * @var float Capital
490
     */
491
    public $capital;
492
    /**
493
     * @var int Type thirdparty
494
     */
495
    public $typent_id = 0;
496
    public $typent_code;
497
    public $effectif;
498
    public $effectif_id = 0;
499
    public $forme_juridique_code;
500
    public $forme_juridique = 0;
501
    public $remise_percent;
502
    public $remise_supplier_percent;
503
    public $mode_reglement_id;
504
    public $cond_reglement_id;
505
    public $deposit_percent;
506
    public $mode_reglement_supplier_id;
507
    public $cond_reglement_supplier_id;
508
    public $transport_mode_supplier_id;
509
    /**
510
     * @var string  Prospect level. ie: 'PL_LOW', 'PL...'
511
     */
512
    public $fk_prospectlevel;
513
    /**
514
     * @var string second name
515
     */
516
    public $name_bis;
517
    /**
518
     * Date of last update
519
     * @var integer|string
520
     */
521
    public $date_modification;
522
    /**
523
     * User that made last update
524
     * @var User
525
     * @deprecated
526
     */
527
    public $user_modification;
528
529
    //Log data
530
    /**
531
     * Date of creation
532
     * @var integer|string
533
     */
534
    public $date_creation;
535
    /**
536
     * User that created the thirdparty
537
     * @var User
538
     * @deprecated
539
     */
540
    public $user_creation;
541
    /**
542
     * 0=no customer, 1=customer, 2=prospect, 3=customer and prospect
543
     * @var int
544
     */
545
    public $client = 0;
546
    /**
547
     * 0=no prospect, 1=prospect
548
     * @var int
549
     */
550
    public $prospect = 0;
551
    /**
552
     * 0=no supplier, 1=supplier
553
     * @var int
554
     */
555
    public $fournisseur;
556
    /**
557
     * Client code. E.g: CU2014-003
558
     * @var string
559
     */
560
    public $code_client;
561
    /**
562
     * Supplier code. E.g: SU2014-003
563
     * @var string
564
     */
565
    public $code_fournisseur;
566
    /**
567
     * Accounting code for client
568
     * @var string
569
     */
570
    public $code_compta_client;
571
    /**
572
     * Duplicate of code_compta_client (for backward compatibility)
573
     * @var string
574
     * @deprecated  Use $code_compta_client
575
     * @see $code_compta_client
576
     */
577
    public $code_compta;
578
    /**
579
     * Accounting code for customer
580
     * @var string
581
     */
582
    public $accountancy_code_customer;
583
    /**
584
     * Accounting code for supplier
585
     * @var string
586
     */
587
    public $code_compta_fournisseur;
588
    /**
589
     * Accounting code for supplier
590
     * @var string
591
     */
592
    public $accountancy_code_supplier;
593
    /**
594
     * Accounting code for product (for level 3 of suggestion of product accounting account)
595
     * @var string
596
     */
597
    public $code_compta_product;
598
    /**
599
     * @var string
600
     * @deprecated Use $note_public, $note_private - Note is split in public and private notes
601
     * @see $note_public, $note_private
602
     */
603
    public $note;
604
    /**
605
     * Private note
606
     * @var string
607
     */
608
    public $note_private;
609
    /**
610
     * Public note
611
     * @var string
612
     */
613
    public $note_public;
614
    /**
615
     * Status prospect id
616
     * @var int
617
     */
618
    public $stcomm_id;
619
    /**
620
     * Status prospect picto
621
     * @var string
622
     */
623
    public $stcomm_picto;
624
    /**
625
     * Status prospect label
626
     * @var int
627
     */
628
    public $status_prospect_label;
629
    /**
630
     * Assigned price level
631
     * @var int
632
     */
633
    public $price_level;
634
    /**
635
     * @var string outstanding limit
636
     */
637
    public $outstanding_limit;
638
    /**
639
     * @var string Min order amount
640
     */
641
    public $order_min_amount;
642
    /**
643
     * @var string Supplier min order amount
644
     */
645
    public $supplier_order_min_amount;
646
    /**
647
     * Id of sales representative to link (used for thirdparty creation). Not filled by a fetch, because we can have several sales representatives.
648
     * @var int
649
     */
650
    public $commercial_id;
651
    /**
652
     * Id of parent thirdparty (if one)
653
     * @var int
654
     */
655
    public $parent;
656
    /**
657
     * Default language code of thirdparty (en_US, ...)
658
     * @var string
659
     */
660
    public $default_lang;
661
    /**
662
     * @var string Ref
663
     */
664
    public $ref;
665
    /**
666
     * External user reference.
667
     * This is to allow external systems to store their id and make self-developed synchronizing functions easier to build.
668
     * @var string
669
     */
670
    public $ref_ext;
671
    /**
672
     * Import key.
673
     * Set when the thirdparty has been created through an import process. This is to relate those created thirdparties
674
     * to an import process
675
     * @var string
676
     */
677
    public $import_key;
678
    /**
679
     * Supplier WebServices URL
680
     * @var string
681
     */
682
    public $webservices_url;
683
    /**
684
     * Supplier WebServices Key
685
     * @var string
686
     */
687
    public $webservices_key;
688
    /**
689
     * @var string Logo
690
     */
691
    public $logo;
692
    /**
693
     * @var string logo small
694
     */
695
    public $logo_small;
696
    /**
697
     * @var string Logo mini
698
     */
699
    public $logo_mini;
700
    /**
701
     * @var string Logo squarred
702
     */
703
    public $logo_squarred;
704
    /**
705
     * @var string Logo squarred small
706
     */
707
    public $logo_squarred_small;
708
    /**
709
     * @var string Logo squarred mini
710
     */
711
    public $logo_squarred_mini;
712
    /**
713
     * @var string Accountancy account for sales
714
     */
715
    public $accountancy_code_sell;
716
    /**
717
     * @var string Accountancy account for bought
718
     */
719
    public $accountancy_code_buy;
720
    /**
721
     * @var int ID
722
     */
723
    public $fk_multicurrency;
724
    /**
725
     * @var int ID
726
     */
727
    public $fk_warehouse;
728
729
    // Multicurrency
730
    /**
731
     * @var string Multicurrency code
732
     */
733
    public $multicurrency_code;
734
735
    // Warehouse
736
    public $partnerships = array();
737
    /**
738
     * @var Account|string Default BAN account
739
     */
740
    public $bank_account;
741
742
    // Fields loaded by fetchPartnerships()
743
    /**
744
     * @var array<string, array<string>>    List of child tables. To test if we can delete object.
745
     */
746
    protected $childtables = array(
747
        'supplier_proposal' => array('name' => 'SupplierProposal'),
748
        'propal' => array('name' => 'Proposal'),
749
        'commande' => array('name' => 'Order'),
750
        'facture' => array('name' => 'Invoice'),
751
        'facture_rec' => array('name' => 'RecurringInvoiceTemplate'),
752
        'contrat' => array('name' => 'Contract'),
753
        'fichinter' => array('name' => 'Fichinter'),
754
        'facture_fourn' => array('name' => 'SupplierInvoice'),
755
        'commande_fournisseur' => array('name' => 'SupplierOrder'),
756
        'projet' => array('name' => 'Project'),
757
        'expedition' => array('name' => 'Shipment'),
758
        'prelevement_lignes' => array('name' => 'DirectDebitRecord'),
759
    );
760
    /**
761
     * @var string[]    List of child tables. To know object to delete on cascade.
762
     *               if name like with @ClassName:FilePathClass:ParentFkFieldName' it will call method deleteByParentField (with parentId as parameters) and FieldName to fetch and delete child object
763
     */
764
    protected $childtablesoncascade = array(
765
        'societe_prices',
766
        'product_fournisseur_price',
767
        'product_customer_price_log',
768
        'product_customer_price',
769
        '@Contact:/contact/class/contact.class.php:fk_soc',
770
        'adherent',
771
        'societe_account',
772
        'societe_rib',
773
        'societe_remise',
774
        'societe_remise_except',
775
        'societe_commerciaux',
776
        'categorie',
777
        'notify',
778
        'notify_def',
779
        'actioncomm',
780
    );
781
782
    /**
783
     *    Constructor
784
     *
785
     * @param DoliDB $db Database handler
786
     */
787
    public function __construct($db)
788
    {
789
        global $conf;
790
791
        $this->db = $db;
792
793
        $this->ismultientitymanaged = 1;
794
        $this->isextrafieldmanaged = 1;
795
        $this->client = 0;
796
        $this->prospect = 0;
797
        $this->fournisseur = 0;
798
        $this->typent_id = 0;
799
        $this->effectif_id = 0;
800
        $this->forme_juridique_code = 0;
801
        $this->tva_assuj = 1;
802
        $this->vat_reverse_charge = 0;
803
        $this->status = 1;
804
805
        if (getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST')) {
806
            $this->fields['address']['showoncombobox'] = getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST');
807
            $this->fields['zip']['showoncombobox'] = getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST');
808
            $this->fields['town']['showoncombobox'] = getDolGlobalString('COMPANY_SHOW_ADDRESS_SELECTLIST');
809
            //$this->fields['fk_pays']['showoncombobox'] = $conf->global->COMPANY_SHOW_ADDRESS_SELECTLIST;
810
        }
811
    }
812
813
    /**
814
     *  Define third party as a customer
815
     *
816
     * @return     int     Return integer <0 if KO, >0 if OK
817
     * @deprecated Use setAsCustomer() instead
818
     * @see setAsCustomer()
819
     */
820
    public function set_as_client()
821
    {
822
        global $conf;
823
        // phpcs:enable
824
        dol_syslog(get_only_class($this) . "::set_as_client is deprecated use setAsCustomer instead", LOG_NOTICE);
825
        return $this->setAsCustomer();
826
    }
827
828
829
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
830
831
    /**
832
     *  Define third party as a customer
833
     *
834
     * @return     int     Return integer <0 if KO, >0 if OK
835
     * @since dolibarr v19
836
     */
837
    public function setAsCustomer()
838
    {
839
        if ($this->id) {
840
            $newclient = 1;
841
            if (($this->client == 2 || $this->client == 3) && !getDolGlobalInt('SOCIETE_DISABLE_PROSPECTSCUSTOMERS')) {
842
                $newclient = 3; //If prospect, we keep prospect tag
843
            }
844
            $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element;
845
            $sql .= " SET client = " . ((int)$newclient);
846
            $sql .= " WHERE rowid = " . ((int)$this->id);
847
848
            $resql = $this->db->query($sql);
849
            if ($resql) {
850
                $this->client = $newclient;
851
                return 1;
852
            } else {
853
                return -1;
854
            }
855
        }
856
        return 0;
857
    }
858
859
    /**
860
     *  Defines the company as a customer
861
     *
862
     * @param float $remise Value in % of the discount
863
     * @param string $note Note/Reason for changing the discount
864
     * @param User $user User who sets the discount
865
     * @return int                 Return integer <0 if KO, >0 if OK
866
     */
867
    public function set_remise_client($remise, $note, User $user)
868
    {
869
        // phpcs:enable
870
        global $conf, $langs;
871
872
        // Parameter cleaning
873
        $note = trim($note);
874
        if (!$note) {
875
            $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NoteReason"));
876
            return -2;
877
        }
878
879
        dol_syslog(get_only_class($this) . "::set_remise_client " . $remise . ", " . $note . ", " . $user->id);
880
881
        if ($this->id) {
882
            $this->db->begin();
883
884
            $now = dol_now();
885
886
            // Position current discount
887
            $sql = "UPDATE " . MAIN_DB_PREFIX . "societe ";
888
            $sql .= " SET remise_client = '" . $this->db->escape($remise) . "'";
889
            $sql .= " WHERE rowid = " . ((int)$this->id);
890
            $resql = $this->db->query($sql);
891
            if (!$resql) {
892
                $this->db->rollback();
893
                $this->error = $this->db->error();
894
                return -1;
895
            }
896
897
            // Writes trace in discount history
898
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_remise";
899
            $sql .= " (entity, datec, fk_soc, remise_client, note, fk_user_author)";
900
            $sql .= " VALUES (" . $conf->entity . ", '" . $this->db->idate($now) . "', " . ((int)$this->id) . ", '" . $this->db->escape($remise) . "',";
901
            $sql .= " '" . $this->db->escape($note) . "',";
902
            $sql .= " " . ((int)$user->id);
903
            $sql .= ")";
904
905
            $resql = $this->db->query($sql);
906
            if (!$resql) {
907
                $this->db->rollback();
908
                $this->error = $this->db->lasterror();
909
                return -1;
910
            }
911
912
            $this->db->commit();
913
914
            return 1;
915
        }
916
        return -1;
917
    }
918
919
    /**
920
     *  Defines the company as a customer
921
     *
922
     * @param float $remise Value in % of the discount
923
     * @param string $note Note/Reason for changing the discount
924
     * @param User $user User who sets the discount
925
     * @return int                 Return integer <0 if KO, >0 if OK
926
     */
927
    public function set_remise_supplier($remise, $note, User $user)
928
    {
929
        // phpcs:enable
930
        global $conf, $langs;
931
932
        // Parameter cleaning
933
        $note = trim($note);
934
        if (!$note) {
935
            $this->error = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("NoteReason"));
936
            return -2;
937
        }
938
939
        dol_syslog(get_only_class($this) . "::set_remise_supplier " . $remise . ", " . $note . ", " . $user->id);
940
941
        if ($this->id) {
942
            $this->db->begin();
943
944
            $now = dol_now();
945
946
            // Position current discount
947
            $sql = "UPDATE " . MAIN_DB_PREFIX . "societe ";
948
            $sql .= " SET remise_supplier = '" . $this->db->escape($remise) . "'";
949
            $sql .= " WHERE rowid = " . ((int)$this->id);
950
            $resql = $this->db->query($sql);
951
            if (!$resql) {
952
                $this->db->rollback();
953
                $this->error = $this->db->error();
954
                return -1;
955
            }
956
957
            // Writes trace in discount history
958
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_remise_supplier";
959
            $sql .= " (entity, datec, fk_soc, remise_supplier, note, fk_user_author)";
960
            $sql .= " VALUES (" . $conf->entity . ", '" . $this->db->idate($now) . "', " . ((int)$this->id) . ", '" . $this->db->escape($remise) . "',";
961
            $sql .= " '" . $this->db->escape($note) . "',";
962
            $sql .= " " . ((int)$user->id);
963
            $sql .= ")";
964
965
            $resql = $this->db->query($sql);
966
            if (!$resql) {
967
                $this->db->rollback();
968
                $this->error = $this->db->lasterror();
969
                return -1;
970
            }
971
972
            $this->db->commit();
973
            return 1;
974
        }
975
976
        return -1;
977
    }
978
979
    /**
980
     *      Add a discount for third party
981
     *
982
     * @param float $remise Amount of discount
983
     * @param User $user User adding discount
984
     * @param string $desc Reason of discount
985
     * @param string $vatrate VAT rate (may contain the vat code too). Example: '1.23', '1.23 (ABC)', ...
986
     * @param int $discount_type 0 => customer discount, 1 => supplier discount
987
     * @param string $price_base_type Price base type 'HT' or 'TTC'
988
     * @return int                         Return integer <0 if KO, id of discount record if OK
989
     */
990
    public function set_remise_except($remise, User $user, $desc, $vatrate = '', $discount_type = 0, $price_base_type = 'HT')
991
    {
992
        // phpcs:enable
993
        global $langs;
994
995
        // Clean parameters
996
        $remise = price2num($remise);
997
        $desc = trim($desc);
998
999
        // Check parameters
1000
        if (!($remise > 0)) {
1001
            $this->error = $langs->trans("ErrorWrongValueForParameter", "1");
1002
            return -1;
1003
        }
1004
        if (!$desc) {
1005
            $this->error = $langs->trans("ErrorWrongValueForParameter", "3");
1006
            return -2;
1007
        }
1008
1009
        if ($this->id > 0) {
1010
            // Clean vat code
1011
            $reg = array();
1012
            $vat_src_code = '';
1013
            if (preg_match('/\((.*)\)/', $vatrate, $reg)) {
1014
                $vat_src_code = $reg[1];
1015
                $vatrate = preg_replace('/\s*\(.*\)/', '', $vatrate); // Remove code into vatrate.
1016
            }
1017
1018
1019
            $discount = new DiscountAbsolute($this->db);
1020
            $discount->fk_soc = $this->id;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Core\Class...scountAbsolute::$fk_soc has been deprecated: Use socid instead. ( Ignorable by Annotation )

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

1020
            /** @scrutinizer ignore-deprecated */ $discount->fk_soc = $this->id;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1021
            $discount->socid = $this->id;
1022
1023
            $discount->discount_type = $discount_type;
1024
1025
            if ($price_base_type == 'TTC') {
1026
                $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($remise, 'MT');
1027
                $discount->amount_ht = $discount->multicurrency_amount_ht = price2num((float)$remise / (1 + (float)$vatrate / 100), 'MT');
1028
                $discount->amount_tva = $discount->multicurrency_amount_tva = price2num((float)$discount->amount_ttc - (float)$discount->amount_ht, 'MT');
1029
            } else {
1030
                $discount->amount_ht = $discount->multicurrency_amount_ht = price2num($remise, 'MT');
1031
                $discount->amount_tva = $discount->multicurrency_amount_tva = price2num((float)$remise * (float)$vatrate / 100, 'MT');
1032
                $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num((float)$discount->amount_ht + (float)$discount->amount_tva, 'MT');
1033
            }
1034
1035
            $discount->tva_tx = (float)price2num($vatrate);
1036
            $discount->vat_src_code = $vat_src_code;
1037
1038
            $discount->description = $desc;
1039
1040
            $result = $discount->create($user);
1041
            if ($result > 0) {
1042
                return $result;
1043
            } else {
1044
                $this->error = $discount->error;
1045
                return -3;
1046
            }
1047
        } else {
1048
            return 0;
1049
        }
1050
    }
1051
1052
    /**
1053
     *    Create third party in database.
1054
     *    $this->code_client = -1 and $this->code_fournisseur = -1 means automatic assignment.
1055
     *
1056
     * @param User $user Object of user that ask creation
1057
     * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
1058
     * @return   int                     >=0 if OK, <0 if KO
1059
     */
1060
    public function create(User $user, $notrigger = 0)
1061
    {
1062
        global $langs, $conf;
1063
1064
        $error = 0;
1065
1066
        // Clean parameters
1067
        if (empty($this->status)) {
1068
            $this->status = 0;
1069
        }
1070
        $this->name = $this->name ? trim($this->name) : trim((string)$this->nom);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1070
        $this->name = $this->name ? trim($this->name) : trim((string)/** @scrutinizer ignore-deprecated */ $this->nom);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1071
        $this->setUpperOrLowerCase();
1072
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1072
        /** @scrutinizer ignore-deprecated */ $this->nom = $this->name; // For backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1073
        if (empty($this->client)) {
1074
            $this->client = 0;
1075
        }
1076
        if (empty($this->fournisseur)) {
1077
            $this->fournisseur = 0;
1078
        }
1079
        $this->import_key = trim((string)$this->import_key);
1080
1081
        $this->accountancy_code_customer = trim((string)$this->code_compta);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

1081
        $this->accountancy_code_customer = trim((string)/** @scrutinizer ignore-deprecated */ $this->code_compta);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1082
        $this->accountancy_code_supplier = trim((string)$this->code_compta_fournisseur);
1083
        $this->accountancy_code_buy = trim((string)$this->accountancy_code_buy);
1084
        $this->accountancy_code_sell = trim((string)$this->accountancy_code_sell);
1085
1086
        if (!empty($this->multicurrency_code)) {
1087
            $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
1088
        }
1089
        if (empty($this->fk_multicurrency)) {
1090
            $this->multicurrency_code = '';
1091
            $this->fk_multicurrency = 0;
1092
        }
1093
1094
        dol_syslog(get_only_class($this) . "::create " . $this->name);
1095
1096
        $now = dol_now();
1097
1098
        if (empty($this->date_creation)) {
1099
            $this->date_creation = $now;
1100
        }
1101
1102
        $this->db->begin();
1103
1104
        // For automatic creation during create action (not used by Dolibarr GUI, can be used by scripts)
1105
        if ($this->code_client == -1 || $this->code_client === 'auto') {
1106
            $this->get_codeclient($this, 0);
1107
        }
1108
        if ($this->code_fournisseur == '-1' || $this->code_fournisseur === 'auto') {
1109
            $this->get_codefournisseur($this, 1);
1110
        }
1111
1112
        // Check more parameters (including mandatory setup
1113
        // If error, this->errors[] is filled
1114
        $result = $this->verify();
1115
1116
        if ($result >= 0) {
1117
            $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
1118
1119
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe (";
1120
            $sql .= "nom";
1121
            $sql .= ", name_alias";
1122
            $sql .= ", entity";
1123
            $sql .= ", datec";
1124
            $sql .= ", fk_user_creat";
1125
            $sql .= ", fk_typent";
1126
            $sql .= ", canvas";
1127
            $sql .= ", status";
1128
            $sql .= ", ref_ext";
1129
            $sql .= ", fk_stcomm";
1130
            $sql .= ", fk_incoterms";
1131
            $sql .= ", location_incoterms";
1132
            $sql .= ", import_key";
1133
            $sql .= ", fk_multicurrency";
1134
            $sql .= ", multicurrency_code";
1135
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1136
                $sql .= ", vat_reverse_charge";
1137
                $sql .= ", accountancy_code_buy";
1138
                $sql .= ", accountancy_code_sell";
1139
            }
1140
            $sql .= ") VALUES ('" . $this->db->escape($this->name) . "',";
1141
            $sql .= " '" . $this->db->escape($this->name_alias) . "',";
1142
            $sql .= " " . ((int)$this->entity) . ",";
1143
            $sql .= " '" . $this->db->idate($this->date_creation) . "'";
1144
            $sql .= ", " . (!empty($user->id) ? ((int)$user->id) : "null");
1145
            $sql .= ", " . (!empty($this->typent_id) ? ((int)$this->typent_id) : "null");
1146
            $sql .= ", " . (!empty($this->canvas) ? "'" . $this->db->escape($this->canvas) . "'" : "null");
1147
            $sql .= ", " . ((int)$this->status);
1148
            $sql .= ", " . (!empty($this->ref_ext) ? "'" . $this->db->escape($this->ref_ext) . "'" : "null");
1149
            $sql .= ", 0";
1150
            $sql .= ", " . (int)$this->fk_incoterms;
1151
            $sql .= ", '" . $this->db->escape($this->location_incoterms) . "'";
1152
            $sql .= ", " . (!empty($this->import_key) ? "'" . $this->db->escape($this->import_key) . "'" : "null");
1153
            $sql .= ", " . (int)$this->fk_multicurrency;
1154
            $sql .= ", '" . $this->db->escape($this->multicurrency_code) . "'";
1155
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1156
                $sql .= ", " . (empty($this->vat_reverse_charge) ? '0' : '1');
1157
                $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
1158
                $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
1159
            }
1160
            $sql .= ")";
1161
1162
            dol_syslog(get_only_class($this) . "::create", LOG_DEBUG);
1163
1164
            $result = $this->db->query($sql);
1165
            if ($result) {
1166
                $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "societe");
1167
1168
                $ret = $this->update($this->id, $user, 0, 1, 1, 'add');
1169
1170
                // update accountancy for this entity
1171
                if (!$error && getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1172
                    $this->db->query("DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity WHERE fk_soc = " . ((int)$this->id) . " AND entity = " . ((int)$conf->entity));
1173
1174
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_perentity (";
1175
                    $sql .= " fk_soc";
1176
                    $sql .= ", entity";
1177
                    $sql .= ", vat_reverse_charge";
1178
                    $sql .= ", accountancy_code_customer";
1179
                    $sql .= ", accountancy_code_supplier";
1180
                    $sql .= ", accountancy_code_buy";
1181
                    $sql .= ", accountancy_code_sell";
1182
                    $sql .= ") VALUES (";
1183
                    $sql .= $this->id;
1184
                    $sql .= ", " . ((int)$conf->entity);
1185
                    $sql .= ", " . (empty($this->vat_reverse_charge) ? '0' : '1');
1186
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_customer) . "'";
1187
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_supplier) . "'";
1188
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
1189
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
1190
                    $sql .= ")";
1191
                    $result = $this->db->query($sql);
1192
                    if (!$result) {
1193
                        $error++;
1194
                        $this->error = 'ErrorFailedToUpdateAccountancyForEntity';
1195
                    }
1196
                }
1197
1198
                // Ajout du commercial affecte
1199
                if ($this->commercial_id != '' && $this->commercial_id != -1) {
1200
                    $this->add_commercial($user, $this->commercial_id);
1201
                } elseif (!$user->hasRight('societe', 'client', 'voir')) {
1202
                    // si un commercial cree un client il lui est affecte automatiquement
1203
                    $this->add_commercial($user, $user->id);
1204
                }
1205
1206
                if ($ret >= 0) {
1207
                    if (!$notrigger) {
1208
                        // Call trigger
1209
                        $result = $this->call_trigger('COMPANY_CREATE', $user);
1210
                        if ($result < 0) {
1211
                            $error++;
1212
                        }
1213
                        // End call triggers
1214
                    }
1215
                } else {
1216
                    $error++;
1217
                }
1218
1219
                if (!$error) {
1220
                    dol_syslog(get_only_class($this) . "::Create success id=" . $this->id);
1221
                    $this->db->commit();
1222
                    return $this->id;
1223
                } else {
1224
                    dol_syslog(get_only_class($this) . "::Create echec update " . $this->error . (empty($this->errors) ? '' : ' ' . implode(',', $this->errors)), LOG_ERR);
1225
                    $this->db->rollback();
1226
                    return -4;
1227
                }
1228
            } else {
1229
                if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
1230
                    $this->error = $langs->trans("ErrorCompanyNameAlreadyExists", $this->name); // duplicate on a field (code or profid or ...)
1231
                    $result = -1;
1232
                } else {
1233
                    $this->error = $this->db->lasterror();
1234
                    $result = -2;
1235
                }
1236
                $this->db->rollback();
1237
                return $result;
1238
            }
1239
        } else {
1240
            $this->db->rollback();
1241
            dol_syslog(get_only_class($this) . "::Create fails verify " . implode(',', $this->errors), LOG_WARNING);
1242
            return -3;
1243
        }
1244
    }
1245
1246
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1247
1248
    /**
1249
     *  Assigns a customer code from the code control module.
1250
     *  Return value is stored into this->code_client
1251
     *
1252
     * @param Societe $objsoc Object thirdparty
1253
     * @param int $type Should be 0 to say customer
1254
     * @return void
1255
     */
1256
    public function get_codeclient($objsoc = null, $type = 0)
1257
    {
1258
        // phpcs:enable
1259
        global $conf;
1260
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
1261
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
1262
1263
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
1264
            foreach ($dirsociete as $dirroot) {
1265
                $res = dol_include_once($dirroot . $module . '.php');
1266
                if ($res) {
1267
                    break;
1268
                }
1269
            }
1270
            /** @var ModeleThirdPartyCode $mod */
1271
            $mod = new $module($this->db);
1272
1273
            $this->code_client = $mod->getNextValue($objsoc, $type);
1274
            $this->prefixCustomerIsRequired = $mod->prefixIsRequired;
1275
1276
            dol_syslog(get_only_class($this) . "::get_codeclient code_client=" . $this->code_client . " module=" . $module);
1277
        }
1278
    }
1279
1280
    /**
1281
     *  Assigns a vendor code from the code control module.
1282
     *  Return value is stored into this->code_fournisseur
1283
     *
1284
     * @param Societe $objsoc Object thirdparty
1285
     * @param int $type Should be 1 to say supplier
1286
     * @return void
1287
     */
1288
    public function get_codefournisseur($objsoc = null, $type = 1)
1289
    {
1290
        // phpcs:enable
1291
        global $conf;
1292
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
1293
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
1294
1295
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
1296
            foreach ($dirsociete as $dirroot) {
1297
                $res = dol_include_once($dirroot . $module . '.php');
1298
                if ($res) {
1299
                    break;
1300
                }
1301
            }
1302
            /** @var ModeleThirdPartyCode $mod */
1303
            $mod = new $module($this->db);
1304
1305
            $this->code_fournisseur = $mod->getNextValue($objsoc, $type);
1306
1307
            dol_syslog(get_only_class($this) . "::get_codefournisseur code_fournisseur=" . $this->code_fournisseur . " module=" . $module);
1308
        }
1309
    }
1310
1311
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1312
1313
    /**
1314
     *    Check properties of third party are ok (like name, third party codes, ...)
1315
     *    Used before an add or update.
1316
     *
1317
     * @return     int       0 if OK, <0 if KO
1318
     */
1319
    public function verify()
1320
    {
1321
        global $conf, $langs, $mysoc;
1322
1323
        $error = 0;
1324
        $this->errors = array();
1325
1326
        $result = 0;
1327
        $this->name = trim($this->name);
1328
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1328
        /** @scrutinizer ignore-deprecated */ $this->nom = $this->name; // For backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1329
1330
        if (!$this->name) {
1331
            $this->errors[] = 'ErrorBadThirdPartyName';
1332
            $result = -2;
1333
        }
1334
1335
        if ($this->client) {
1336
            $rescode = $this->check_codeclient();
1337
            if ($rescode != 0 && $rescode != -5) {
1338
                if ($rescode == -1) {
1339
                    $this->errors[] = 'ErrorBadCustomerCodeSyntax';
1340
                } elseif ($rescode == -2) {
1341
                    $this->errors[] = 'ErrorCustomerCodeRequired';
1342
                } elseif ($rescode == -3) {
1343
                    $this->errors[] = 'ErrorCustomerCodeAlreadyUsed';
1344
                } elseif ($rescode == -4) {
1345
                    $this->errors[] = 'ErrorPrefixRequired';
1346
                } else {
1347
                    $this->errors[] = 'ErrorUnknownOnCustomerCodeCheck';
1348
                }
1349
1350
                $result = -3;
1351
            }
1352
        }
1353
1354
        if ($this->fournisseur) {
1355
            $rescode = $this->check_codefournisseur();
1356
            if ($rescode != 0 && $rescode != -5) {
1357
                if ($rescode == -1) {
1358
                    $this->errors[] = 'ErrorBadSupplierCodeSyntax';
1359
                } elseif ($rescode == -2) {
1360
                    $this->errors[] = 'ErrorSupplierCodeRequired';
1361
                } elseif ($rescode == -3) {
1362
                    $this->errors[] = 'ErrorSupplierCodeAlreadyUsed';
1363
                } elseif ($rescode == -4) {
1364
                    $this->errors[] = 'ErrorPrefixRequired';
1365
                } else {
1366
                    $this->errors[] = 'ErrorUnknownOnSupplierCodeCheck';
1367
                }
1368
                $result = -3;
1369
            }
1370
        }
1371
1372
        // Check for duplicate or mandatory fields defined into setup
1373
        $array_to_check = array('IDPROF1', 'IDPROF2', 'IDPROF3', 'IDPROF4', 'IDPROF5', 'IDPROF6', 'EMAIL', 'TVA_INTRA', 'ACCOUNTANCY_CODE_CUSTOMER', 'ACCOUNTANCY_CODE_SUPPLIER');
1374
        foreach ($array_to_check as $key) {
1375
            $keymin = strtolower($key);
1376
            if ($key == 'ACCOUNTANCY_CODE_CUSTOMER') {
1377
                $keymin = 'code_compta';
1378
            } elseif ($key == 'ACCOUNTANCY_CODE_SUPPLIER') {
1379
                $keymin = 'code_compta_fournisseur';
1380
            }
1381
            $i = (int)preg_replace('/[^0-9]/', '', $key);
1382
            $vallabel = $this->$keymin;
1383
1384
            if ($i > 0) {
1385
                if ($this->isACompany()) {
1386
                    // Check for mandatory prof id (but only if country is same than ours)
1387
                    if ($mysoc->country_id > 0 && $this->country_id == $mysoc->country_id) {
1388
                        $idprof_mandatory = 'SOCIETE_' . $key . '_MANDATORY';
1389
                        if (!$vallabel && getDolGlobalString($idprof_mandatory)) {
1390
                            $langs->load("errors");
1391
                            $error++;
1392
                            $this->errors[] = $langs->trans("ErrorProdIdIsMandatory", $langs->transcountry('ProfId' . $i, $this->country_code)) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1393
                        }
1394
                    }
1395
                }
1396
1397
                // Check for unicity on profid
1398
                if (!$error && $vallabel && $this->id_prof_verifiable($i)) {
1399
                    if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1400
                        $langs->load("errors");
1401
                        $error++;
1402
                        $this->errors[] = $langs->transcountry('ProfId' . $i, $this->country_code) . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1403
                    }
1404
                }
1405
            } else {
1406
                //var_dump($conf->global->SOCIETE_EMAIL_UNIQUE);
1407
                //var_dump($conf->global->SOCIETE_EMAIL_MANDATORY);
1408
                if ($key == 'EMAIL') {
1409
                    // Check for mandatory
1410
                    if (getDolGlobalString('SOCIETE_EMAIL_MANDATORY') && !isValidEmail($this->email)) {
1411
                        $langs->load("errors");
1412
                        $error++;
1413
                        $this->errors[] = $langs->trans("ErrorBadEMail", $this->email) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1414
                    }
1415
1416
                    // Check for unicity
1417
                    if (!$error && $vallabel && getDolGlobalString('SOCIETE_EMAIL_UNIQUE')) {
1418
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1419
                            $langs->load("errors");
1420
                            $error++;
1421
                            $this->errors[] = $langs->trans('Email') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1422
                        }
1423
                    }
1424
                } elseif ($key == 'TVA_INTRA') {
1425
                    // Check for unicity
1426
                    if ($vallabel && getDolGlobalString('SOCIETE_VAT_INTRA_UNIQUE')) {
1427
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1428
                            $langs->load("errors");
1429
                            $error++;
1430
                            $this->errors[] = $langs->trans('VATIntra') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1431
                        }
1432
                    }
1433
                } elseif ($key == 'ACCOUNTANCY_CODE_CUSTOMER' && !empty($this->client)) {
1434
                    // Check for unicity
1435
                    if ($vallabel && getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_UNIQUE')) {
1436
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1437
                            $langs->loadLangs(array("errors", 'compta'));
1438
                            $error++;
1439
                            $this->errors[] = $langs->trans('CustomerAccountancyCodeShort') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1440
                        }
1441
                    }
1442
1443
                    // Check for mandatory
1444
                    if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_CUSTOMER_MANDATORY') && (!isset($vallabel) || trim($vallabel) === '')) {
1445
                        $langs->loadLangs(array("errors", 'compta'));
1446
                        $error++;
1447
                        $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('CustomerAccountancyCodeShort')) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1448
                    }
1449
                } elseif ($key == 'ACCOUNTANCY_CODE_SUPPLIER' && !empty($this->fournisseur)) {
1450
                    // Check for unicity
1451
                    if ($vallabel && getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_SUPPLIER_UNIQUE')) {
1452
                        if ($this->id_prof_exists($keymin, $vallabel, ($this->id > 0 ? $this->id : 0))) {
1453
                            $langs->loadLangs(array("errors", 'compta'));
1454
                            $error++;
1455
                            $this->errors[] = $langs->trans('SupplierAccountancyCodeShort') . " " . $langs->trans("ErrorProdIdAlreadyExist", $vallabel) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1456
                        }
1457
                    }
1458
1459
                    // Check for mandatory
1460
                    if (getDolGlobalString('SOCIETE_ACCOUNTANCY_CODE_SUPPLIER_MANDATORY') && (!isset($vallabel) || trim($vallabel) === '')) {
1461
                        $langs->loadLangs(array("errors", 'compta'));
1462
                        $error++;
1463
                        $this->errors[] = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv('SupplierAccountancyCodeShort')) . ' (' . $langs->trans("ForbiddenBySetupRules") . ')';
1464
                    }
1465
                }
1466
            }
1467
        }
1468
1469
        if ($error) {
1470
            $result = -4;
1471
        }
1472
1473
        return $result;
1474
    }
1475
1476
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1477
1478
    /**
1479
     *  Check customer code
1480
     *
1481
     * @return     int             0 if OK
1482
     *                              -1 ErrorBadCustomerCodeSyntax
1483
     *                              -2 ErrorCustomerCodeRequired
1484
     *                              -3 ErrorCustomerCodeAlreadyUsed
1485
     *                              -4 ErrorPrefixRequired
1486
     *                              -5 NotConfigured - Setup empty so any value may be ok or not
1487
     *                              -6 Other (see this->error)
1488
     */
1489
    public function check_codeclient()
1490
    {
1491
        // phpcs:enable
1492
        global $conf;
1493
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
1494
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
1495
1496
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
1497
            foreach ($dirsociete as $dirroot) {
1498
                $res = dol_include_once($dirroot . $module . '.php');
1499
                if ($res) {
1500
                    break;
1501
                }
1502
            }
1503
1504
            $mod = new $module($this->db);
1505
1506
            dol_syslog(get_only_class($this) . "::check_codeclient code_client=" . $this->code_client . " module=" . $module);
1507
            $result = $mod->verif($this->db, $this->code_client, $this, 0);
1508
            if ($result) {  // If error
1509
                $this->error = $mod->error;
1510
                $this->errors = $mod->errors;
1511
            }
1512
            return $result;
1513
        } else {
1514
            return 0;
1515
        }
1516
    }
1517
1518
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1519
1520
    /**
1521
     *    Check supplier code
1522
     *
1523
     * @return     int       0 if OK
1524
     *                          -1 ErrorBadCustomerCodeSyntax
1525
     *                          -2 ErrorCustomerCodeRequired
1526
     *                          -3 ErrorCustomerCodeAlreadyUsed
1527
     *                          -4 ErrorPrefixRequired
1528
     *                          -5 NotConfigured - Setup empty so any value may be ok or not
1529
     *                          -6 Other (see this->error)
1530
     */
1531
    public function check_codefournisseur()
1532
    {
1533
        // phpcs:enable
1534
        global $conf;
1535
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
1536
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
1537
1538
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
1539
            foreach ($dirsociete as $dirroot) {
1540
                $res = dol_include_once($dirroot . $module . '.php');
1541
                if ($res) {
1542
                    break;
1543
                }
1544
            }
1545
1546
            $mod = new $module($this->db);
1547
1548
            dol_syslog(get_only_class($this) . "::check_codefournisseur code_fournisseur=" . $this->code_fournisseur . " module=" . $module);
1549
            $result = $mod->verif($this->db, $this->code_fournisseur, $this, 1);
1550
            if ($result) {  // If error
1551
                $this->error = $mod->error;
1552
                $this->errors = $mod->errors;
1553
            }
1554
            return $result;
1555
        } else {
1556
            return 0;
1557
        }
1558
    }
1559
1560
    /**
1561
     *  Check if third party is a company (Business) or an end user (Consumer)
1562
     *
1563
     * @return     boolean     if a company: true || if a user: false
1564
     */
1565
    public function isACompany()
1566
    {
1567
        // Define if third party is treated as company (or not) when nature is unknown
1568
        $isACompany = getDolGlobalInt('MAIN_UNKNOWN_CUSTOMERS_ARE_COMPANIES');
1569
1570
        // Now try to guess using different tips
1571
        if (!empty($this->tva_intra)) {
1572
            $isACompany = 1;
1573
        } elseif (!empty($this->idprof1) || !empty($this->idprof2) || !empty($this->idprof3) || !empty($this->idprof4) || !empty($this->idprof5) || !empty($this->idprof6)) {
1574
            $isACompany = 1;
1575
        } else {
1576
            if (!getDolGlobalString('MAIN_CUSTOMERS_ARE_COMPANIES_EVEN_IF_SET_AS_INDIVIDUAL')) {
1577
                // TODO Add a field is_a_company into dictionary
1578
                if (preg_match('/^TE_PRIVATE/', $this->typent_code)) {
1579
                    $isACompany = 0;
1580
                } else {
1581
                    $isACompany = 1;
1582
                }
1583
            } else {
1584
                $isACompany = 1;
1585
            }
1586
        }
1587
1588
        return (bool)$isACompany;
1589
    }
1590
1591
    /**
1592
     *  Returns if a profid should be verified to be unique
1593
     *
1594
     * @param int $idprof 1,2,3,4,5,6 (Example: 1=siren, 2=siret, 3=naf, 4=rcs/rm, 5=eori, 6=idprof6)
1595
     * @return boolean             true if the ID must be unique
1596
     */
1597
    public function id_prof_verifiable($idprof)
1598
    {
1599
        // phpcs:enable
1600
        global $conf;
1601
1602
        switch ($idprof) {
1603
            case 1:
1604
                $ret = (!getDolGlobalString('SOCIETE_IDPROF1_UNIQUE') ? false : true);
1605
                break;
1606
            case 2:
1607
                $ret = (!getDolGlobalString('SOCIETE_IDPROF2_UNIQUE') ? false : true);
1608
                break;
1609
            case 3:
1610
                $ret = (!getDolGlobalString('SOCIETE_IDPROF3_UNIQUE') ? false : true);
1611
                break;
1612
            case 4:
1613
                $ret = (!getDolGlobalString('SOCIETE_IDPROF4_UNIQUE') ? false : true);
1614
                break;
1615
            case 5:
1616
                $ret = (!getDolGlobalString('SOCIETE_IDPROF5_UNIQUE') ? false : true);
1617
                break;
1618
            case 6:
1619
                $ret = (!getDolGlobalString('SOCIETE_IDPROF6_UNIQUE') ? false : true);
1620
                break;
1621
            default:
1622
                $ret = false;
1623
        }
1624
1625
        return $ret;
1626
    }
1627
1628
    /**
1629
     *    Verify if a profid exists into database for others thirds
1630
     *
1631
     * @param string $idprof 'idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','email' (Example: idprof1=siren, idprof2=siret, idprof3=naf, idprof4=rcs/rm)
1632
     * @param string $value Value of profid
1633
     * @param int $socid Id of thirdparty to exclude (if update)
1634
     * @return   boolean             True if exists, False if not
1635
     */
1636
    public function id_prof_exists($idprof, $value, $socid = 0)
1637
    {
1638
        // phpcs:enable
1639
        $field = $idprof;
1640
1641
        switch ($idprof) {  // For backward compatibility
1642
            case '1':
1643
            case 'idprof1':
1644
                $field = "siren";
1645
                break;
1646
            case '2':
1647
            case 'idprof2':
1648
                $field = "siret";
1649
                break;
1650
            case '3':
1651
            case 'idprof3':
1652
                $field = "ape";
1653
                break;
1654
            case '4':
1655
            case 'idprof4':
1656
                $field = "idprof4";
1657
                break;
1658
            case '5':
1659
                $field = "idprof5";
1660
                break;
1661
            case '6':
1662
                $field = "idprof6";
1663
                break;
1664
        }
1665
1666
        //Verify duplicate entries
1667
        $sql = "SELECT COUNT(*) as nb FROM " . MAIN_DB_PREFIX . "societe WHERE " . $field . " = '" . $this->db->escape($value) . "' AND entity IN (" . getEntity('societe') . ")";
1668
        if ($socid) {
1669
            $sql .= " AND rowid <> " . $socid;
1670
        }
1671
        $resql = $this->db->query($sql);
1672
        if ($resql) {
1673
            $obj = $this->db->fetch_object($resql);
1674
            $count = $obj->nb;
1675
        } else {
1676
            $count = 0;
1677
            print $this->db->error();
1678
        }
1679
        $this->db->free($resql);
1680
1681
        if ($count > 0) {
1682
            return true;
1683
        } else {
1684
            return false;
1685
        }
1686
    }
1687
1688
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
1689
1690
    /**
1691
     *      Update parameters of third party
1692
     *
1693
     * @param int $id Id of company (deprecated, use 0 here and call update on an object loaded by a fetch)
1694
     * @param User $user User who requests the update
1695
     * @param int $call_trigger 0=no, 1=yes
1696
     * @param int $allowmodcodeclient Inclut modif code client et code compta
1697
     * @param int $allowmodcodefournisseur Inclut modif code fournisseur et code compta fournisseur
1698
     * @param string $action 'add' or 'update' or 'merge'
1699
     * @param int $nosyncmember Do not synchronize info of linked member
1700
     * @return int                                 Return integer <0 if KO, >=0 if OK
1701
     */
1702
    public function update($id, User $user, $call_trigger = 1, $allowmodcodeclient = 0, $allowmodcodefournisseur = 0, $action = 'update', $nosyncmember = 1)
1703
    {
1704
        global $langs, $conf, $hookmanager;
1705
1706
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/functions2.lib.php';
1707
1708
        if (empty($id)) {
1709
            $id = $this->id;
1710
        }
1711
1712
        $error = 0;
1713
1714
        dol_syslog(get_only_class($this) . "::Update id=" . $id . " call_trigger=" . $call_trigger . " allowmodcodeclient=" . $allowmodcodeclient . " allowmodcodefournisseur=" . $allowmodcodefournisseur);
1715
1716
        $now = dol_now();
1717
1718
        // Clean parameters
1719
        $this->id = $id;
1720
        $this->entity = ((isset($this->entity) && is_numeric($this->entity)) ? $this->entity : $conf->entity);
1721
        $this->name = $this->name ? trim($this->name) : trim((string)$this->nom);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1721
        $this->name = $this->name ? trim($this->name) : trim((string)/** @scrutinizer ignore-deprecated */ $this->nom);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1722
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

1722
        /** @scrutinizer ignore-deprecated */ $this->nom = $this->name; // For backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1723
        $this->name_alias = trim((string)$this->name_alias);
1724
        $this->ref_ext = (empty($this->ref_ext) ? '' : trim($this->ref_ext));
1725
        $this->address = trim((string)$this->address);
1726
        $this->zip = trim((string)$this->zip);
1727
        $this->town = trim((string)$this->town);
1728
        $this->state_id = (is_numeric($this->state_id)) ? (int)trim((string)$this->state_id) : 0;
1729
        $this->country_id = ($this->country_id > 0) ? $this->country_id : 0;
1730
        $this->phone = trim((string)$this->phone);
1731
        $this->phone = preg_replace("/\s/", "", $this->phone);
1732
        $this->phone = preg_replace("/\./", "", $this->phone);
1733
        $this->phone_mobile = trim((string)$this->phone_mobile);
1734
        $this->phone_mobile = preg_replace("/\s/", "", $this->phone_mobile);
1735
        $this->phone_mobile = preg_replace("/\./", "", $this->phone_mobile);
1736
        $this->fax = trim((string)$this->fax);
1737
        $this->fax = preg_replace("/\s/", "", $this->fax);
1738
        $this->fax = preg_replace("/\./", "", $this->fax);
1739
        $this->email = trim((string)$this->email);
1740
        $this->url = $this->url ? clean_url($this->url, 0) : '';
1741
        $this->note_private = (empty($this->note_private) ? '' : trim($this->note_private));
1742
        $this->note_public = (empty($this->note_public) ? '' : trim($this->note_public));
1743
        $this->idprof1 = trim((string)$this->idprof1);
1744
        $this->idprof2 = trim((string)$this->idprof2);
1745
        $this->idprof3 = trim((string)$this->idprof3);
1746
        $this->idprof4 = trim((string)$this->idprof4);
1747
        $this->idprof5 = (!empty($this->idprof5) ? trim($this->idprof5) : '');
1748
        $this->idprof6 = (!empty($this->idprof6) ? trim($this->idprof6) : '');
1749
        $this->prefix_comm = trim((string)$this->prefix_comm);
1750
        $this->outstanding_limit = price2num($this->outstanding_limit);
1751
        $this->order_min_amount = price2num($this->order_min_amount);
1752
        $this->supplier_order_min_amount = price2num($this->supplier_order_min_amount);
1753
1754
        $this->tva_assuj = (is_numeric($this->tva_assuj)) ? (int)trim((string)$this->tva_assuj) : 0;
1755
        $this->tva_intra = dol_sanitizeFileName($this->tva_intra, '');
1756
        $this->vat_reverse_charge = empty($this->vat_reverse_charge) ? 0 : 1;
1757
        if (empty($this->status)) {
1758
            $this->status = 0;
1759
        }
1760
1761
        if (!empty($this->multicurrency_code)) {
1762
            $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
1763
        }
1764
        if (empty($this->fk_multicurrency)) {
1765
            $this->multicurrency_code = '';
1766
            $this->fk_multicurrency = 0;
1767
        }
1768
1769
        // Local taxes
1770
        $this->localtax1_assuj = trim($this->localtax1_assuj);
1771
        $this->localtax2_assuj = trim($this->localtax2_assuj);
1772
1773
        $this->localtax1_value = trim($this->localtax1_value);
1774
        $this->localtax2_value = trim($this->localtax2_value);
1775
1776
        $this->capital = ($this->capital != '') ? (float)price2num(trim((string)$this->capital)) : null;
1777
1778
        $this->effectif_id = trim((string)$this->effectif_id);
1779
        $this->forme_juridique_code = trim((string)$this->forme_juridique_code);
1780
1781
        //Gencod
1782
        $this->barcode = trim($this->barcode);
1783
1784
        // For automatic creation
1785
        if ($this->code_client == -1 || $this->code_client === 'auto') {
1786
            $this->get_codeclient($this, 0);
1787
        }
1788
        if ($this->code_fournisseur == '-1' || $this->code_fournisseur === 'auto') {
1789
            $this->get_codefournisseur($this, 1);
1790
        }
1791
1792
        $this->code_compta_client = trim(empty($this->code_compta) ? $this->code_compta_client : $this->code_compta);
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

1792
        $this->code_compta_client = trim(empty(/** @scrutinizer ignore-deprecated */ $this->code_compta) ? $this->code_compta_client : $this->code_compta);

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1793
        $this->code_compta = $this->code_compta_client; // for backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

1793
        /** @scrutinizer ignore-deprecated */ $this->code_compta = $this->code_compta_client; // for backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
1794
        $this->code_compta_fournisseur = (empty($this->code_compta_fournisseur) ? '' : trim($this->code_compta_fournisseur));
1795
1796
        // Check parameters. More tests are done later in the ->verify()
1797
        if (!is_numeric($this->client) && !is_numeric($this->fournisseur)) {
1798
            $langs->load("errors");
1799
            $this->error = $langs->trans("BadValueForParameterClientOrSupplier");
1800
            return -1;
1801
        }
1802
1803
        $customer = false;
1804
        if (!empty($allowmodcodeclient) && !empty($this->client)) {
1805
            // If $allowmodcodeclient is set and value is not set, we generate it
1806
            if (empty($this->code_compta_client)) {
1807
                $ret = $this->get_codecompta('customer');
1808
                if ($ret < 0) {
1809
                    return -1;
1810
                }
1811
            }
1812
1813
            $customer = true;
1814
        }
1815
1816
        $supplier = false;
1817
        if (!empty($allowmodcodefournisseur) && !empty($this->fournisseur)) {
1818
            // If $allowmodcodefournisseur is set and value is not set, we generate it
1819
            if (empty($this->code_compta_fournisseur)) {
1820
                $ret = $this->get_codecompta('supplier');
1821
                if ($ret < 0) {
1822
                    return -1;
1823
                }
1824
            }
1825
1826
            $supplier = true;
1827
        }
1828
1829
        //Web services
1830
        $this->webservices_url = $this->webservices_url ? clean_url($this->webservices_url, 0) : '';
1831
        $this->webservices_key = trim($this->webservices_key);
1832
1833
        $this->accountancy_code_buy = (empty($this->accountancy_code_buy) ? '' : trim($this->accountancy_code_buy));
1834
        $this->accountancy_code_sell = (empty($this->accountancy_code_sell) ? '' : trim($this->accountancy_code_sell));
1835
1836
        //Incoterms
1837
        $this->fk_incoterms = (int)$this->fk_incoterms;
1838
        $this->location_incoterms = trim($this->location_incoterms);
1839
1840
        $this->db->begin();
1841
1842
        // Check name is required and codes are ok or unique.
1843
        // If error, this->errors[] is filled
1844
        $result = 0;
1845
        if ($action != 'add' && $action != 'merge') {
1846
            // We don't check when update called during a create because verify was already done.
1847
            // 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
1848
            $result = $this->verify();
1849
1850
            // If there is only one error and error is ErrorBadCustomerCodeSyntax and we don't change customer code, we allow the update
1851
            // So we can update record that were using and old numbering rule.
1852
            if (is_array($this->errors)) {
1853
                if (in_array('ErrorBadCustomerCodeSyntax', $this->errors) && is_object($this->oldcopy) && $this->oldcopy->code_client == $this->code_client) {
1854
                    if (($key = array_search('ErrorBadCustomerCodeSyntax', $this->errors)) !== false) {
1855
                        unset($this->errors[$key]); // Remove error message
1856
                    }
1857
                }
1858
                if (in_array('ErrorBadSupplierCodeSyntax', $this->errors) && is_object($this->oldcopy) && $this->oldcopy->code_fournisseur == $this->code_fournisseur) {
1859
                    if (($key = array_search('ErrorBadSupplierCodeSyntax', $this->errors)) !== false) {
1860
                        unset($this->errors[$key]); // Remove error message
1861
                    }
1862
                }
1863
                if (empty($this->errors)) { // If there is no more error, we can make like if there is no error at all
1864
                    $result = 0;
1865
                }
1866
            }
1867
        }
1868
        $this->setUpperOrLowerCase();
1869
        if ($result >= 0) {
1870
            dol_syslog(get_only_class($this) . "::update verify ok or not done");
1871
1872
            $sql = "UPDATE " . MAIN_DB_PREFIX . "societe SET ";
1873
            $sql .= "entity = " . $this->db->escape($this->entity);
1874
            $sql .= ",nom = '" . $this->db->escape($this->name) . "'"; // Required
1875
            $sql .= ",name_alias = '" . $this->db->escape($this->name_alias) . "'";
1876
            $sql .= ",ref_ext = " . (!empty($this->ref_ext) ? "'" . $this->db->escape($this->ref_ext) . "'" : "null");
1877
            $sql .= ",address = '" . $this->db->escape($this->address) . "'";
1878
1879
            $sql .= ",zip = " . (!empty($this->zip) ? "'" . $this->db->escape($this->zip) . "'" : "null");
1880
            $sql .= ",town = " . (!empty($this->town) ? "'" . $this->db->escape($this->town) . "'" : "null");
1881
1882
            $sql .= ",fk_departement = " . ((!empty($this->state_id) && $this->state_id > 0) ? ((int)$this->state_id) : 'null');
1883
            $sql .= ",fk_pays = " . ((!empty($this->country_id) && $this->country_id > 0) ? ((int)$this->country_id) : 'null');
1884
1885
            $sql .= ",phone = " . (!empty($this->phone) ? "'" . $this->db->escape($this->phone) . "'" : "null");
1886
            $sql .= ",phone_mobile = " . (!empty($this->phone_mobile) ? "'" . $this->db->escape($this->phone_mobile) . "'" : "null");
1887
            $sql .= ",fax = " . (!empty($this->fax) ? "'" . $this->db->escape($this->fax) . "'" : "null");
1888
            $sql .= ",email = " . (!empty($this->email) ? "'" . $this->db->escape($this->email) . "'" : "null");
1889
            $sql .= ",socialnetworks = '" . $this->db->escape(json_encode($this->socialnetworks)) . "'";
1890
            $sql .= ",url = " . (!empty($this->url) ? "'" . $this->db->escape($this->url) . "'" : "null");
1891
1892
            $sql .= ",parent = " . ($this->parent > 0 ? $this->parent : "null");
1893
1894
            $sql .= ",note_private = " . (!empty($this->note_private) ? "'" . $this->db->escape($this->note_private) . "'" : "null");
1895
            $sql .= ",note_public = " . (!empty($this->note_public) ? "'" . $this->db->escape($this->note_public) . "'" : "null");
1896
1897
            $sql .= ",siren   = '" . $this->db->escape($this->idprof1) . "'";
1898
            $sql .= ",siret   = '" . $this->db->escape($this->idprof2) . "'";
1899
            $sql .= ",ape     = '" . $this->db->escape($this->idprof3) . "'";
1900
            $sql .= ",idprof4 = '" . $this->db->escape($this->idprof4) . "'";
1901
            $sql .= ",idprof5 = '" . $this->db->escape($this->idprof5) . "'";
1902
            $sql .= ",idprof6 = '" . $this->db->escape($this->idprof6) . "'";
1903
1904
            $sql .= ",tva_assuj = " . ($this->tva_assuj != '' ? "'" . $this->db->escape($this->tva_assuj) . "'" : "null");
1905
            $sql .= ",tva_intra = '" . $this->db->escape($this->tva_intra) . "'";
1906
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1907
                $sql .= ",vat_reverse_charge = " . ($this->vat_reverse_charge != '' ? "'" . $this->db->escape($this->vat_reverse_charge) . "'" : 0);
1908
            }
1909
            $sql .= ",status = " . ((int)$this->status);
1910
1911
            // Local taxes
1912
            $sql .= ",localtax1_assuj = " . ($this->localtax1_assuj != '' ? "'" . $this->db->escape($this->localtax1_assuj) . "'" : "null");
1913
            $sql .= ",localtax2_assuj = " . ($this->localtax2_assuj != '' ? "'" . $this->db->escape($this->localtax2_assuj) . "'" : "null");
1914
            if ($this->localtax1_assuj == 1) {
1915
                if ($this->localtax1_value != '') {
1916
                    $sql .= ",localtax1_value =" . $this->localtax1_value;
1917
                } else {
1918
                    $sql .= ",localtax1_value =0.000";
1919
                }
1920
            } else {
1921
                $sql .= ",localtax1_value =0.000";
1922
            }
1923
1924
            if ($this->localtax2_assuj == 1) {
1925
                if ($this->localtax2_value != '') {
1926
                    $sql .= ",localtax2_value =" . $this->localtax2_value;
1927
                } else {
1928
                    $sql .= ",localtax2_value =0.000";
1929
                }
1930
            } else {
1931
                $sql .= ",localtax2_value =0.000";
1932
            }
1933
1934
            $sql .= ",capital = " . ($this->capital === null ? "null" : $this->capital);
1935
1936
            $sql .= ",prefix_comm = " . (!empty($this->prefix_comm) ? "'" . $this->db->escape($this->prefix_comm) . "'" : "null");
1937
1938
            $sql .= ",fk_effectif = " . ($this->effectif_id > 0 ? ((int)$this->effectif_id) : "null");
1939
            if (isset($this->stcomm_id)) {
1940
                $sql .= ",fk_stcomm=" . (int)$this->stcomm_id;
1941
            }
1942
            if (isset($this->typent_id)) {
1943
                $sql .= ",fk_typent = " . ($this->typent_id > 0 ? ((int)$this->typent_id) : "0");
1944
            }
1945
1946
            $sql .= ",fk_forme_juridique = " . (!empty($this->forme_juridique_code) ? "'" . $this->db->escape($this->forme_juridique_code) . "'" : "null");
1947
1948
            $sql .= ",mode_reglement = " . (!empty($this->mode_reglement_id) ? "'" . $this->db->escape($this->mode_reglement_id) . "'" : "null");
1949
            $sql .= ",cond_reglement = " . (!empty($this->cond_reglement_id) ? "'" . $this->db->escape($this->cond_reglement_id) . "'" : "null");
1950
            $sql .= ",deposit_percent = " . (!empty($this->deposit_percent) ? "'" . $this->db->escape($this->deposit_percent) . "'" : "null");
1951
            $sql .= ",transport_mode = " . (!empty($this->transport_mode_id) ? "'" . $this->db->escape($this->transport_mode_id) . "'" : "null");
1952
            $sql .= ",mode_reglement_supplier = " . (!empty($this->mode_reglement_supplier_id) ? "'" . $this->db->escape($this->mode_reglement_supplier_id) . "'" : "null");
1953
            $sql .= ",cond_reglement_supplier = " . (!empty($this->cond_reglement_supplier_id) ? "'" . $this->db->escape($this->cond_reglement_supplier_id) . "'" : "null");
1954
            $sql .= ",transport_mode_supplier = " . (!empty($this->transport_mode_supplier_id) ? "'" . $this->db->escape($this->transport_mode_supplier_id) . "'" : "null");
1955
            $sql .= ",fk_shipping_method = " . (!empty($this->shipping_method_id) ? "'" . $this->db->escape($this->shipping_method_id) . "'" : "null");
1956
1957
            $sql .= ",client = " . (!empty($this->client) ? $this->client : 0);
1958
            $sql .= ",fournisseur = " . (!empty($this->fournisseur) ? $this->fournisseur : 0);
1959
            $sql .= ",barcode = " . (!empty($this->barcode) ? "'" . $this->db->escape($this->barcode) . "'" : "null");
1960
            $sql .= ",default_lang = " . (!empty($this->default_lang) ? "'" . $this->db->escape($this->default_lang) . "'" : "null");
1961
            $sql .= ",logo = " . (!empty($this->logo) ? "'" . $this->db->escape($this->logo) . "'" : "null");
1962
            $sql .= ",logo_squarred = " . (!empty($this->logo_squarred) ? "'" . $this->db->escape($this->logo_squarred) . "'" : "null");
1963
            $sql .= ",outstanding_limit= " . ($this->outstanding_limit != '' ? $this->outstanding_limit : 'null');
1964
            $sql .= ",order_min_amount= " . ($this->order_min_amount != '' ? $this->order_min_amount : 'null');
1965
            $sql .= ",supplier_order_min_amount= " . ($this->supplier_order_min_amount != '' ? $this->supplier_order_min_amount : 'null');
1966
            $sql .= ",fk_prospectlevel='" . $this->db->escape($this->fk_prospectlevel) . "'";
1967
            if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
1968
                $sql .= ", accountancy_code_buy = '" . $this->db->escape($this->accountancy_code_buy) . "'";
1969
                $sql .= ", accountancy_code_sell= '" . $this->db->escape($this->accountancy_code_sell) . "'";
1970
                if ($customer) {
1971
                    $sql .= ", code_compta = " . (!empty($this->code_compta_client) ? "'" . $this->db->escape($this->code_compta_client) . "'" : "null");
1972
                }
1973
1974
                if ($supplier) {
1975
                    $sql .= ", code_compta_fournisseur = " . (($this->code_compta_fournisseur != "") ? "'" . $this->db->escape($this->code_compta_fournisseur) . "'" : "null");
1976
                }
1977
            }
1978
            $sql .= ",webservices_url = " . (!empty($this->webservices_url) ? "'" . $this->db->escape($this->webservices_url) . "'" : "null");
1979
            $sql .= ",webservices_key = " . (!empty($this->webservices_key) ? "'" . $this->db->escape($this->webservices_key) . "'" : "null");
1980
1981
            //Incoterms
1982
            $sql .= ", fk_incoterms = " . ((int)$this->fk_incoterms);
1983
            $sql .= ", location_incoterms = " . (!empty($this->location_incoterms) ? "'" . $this->db->escape($this->location_incoterms) . "'" : "null");
1984
1985
            if ($customer) {
1986
                $sql .= ", code_client = " . (!empty($this->code_client) ? "'" . $this->db->escape($this->code_client) . "'" : "null");
1987
            }
1988
1989
            if ($supplier) {
1990
                $sql .= ", code_fournisseur = " . (!empty($this->code_fournisseur) ? "'" . $this->db->escape($this->code_fournisseur) . "'" : "null");
1991
            }
1992
            $sql .= ", fk_user_modif = " . ($user->id > 0 ? $user->id : "null");
1993
            $sql .= ", fk_multicurrency = " . (int)$this->fk_multicurrency;
1994
            $sql .= ", multicurrency_code = '" . $this->db->escape($this->multicurrency_code) . "'";
1995
            $sql .= ", model_pdf = '" . $this->db->escape($this->model_pdf) . "'";
1996
            $sql .= " WHERE rowid = " . (int)$id;
1997
1998
            $resql = $this->db->query($sql);
1999
            if ($resql) {
2000
                if (is_object($this->oldcopy)) {    // If we have information on old values
2001
                    if ($this->oldcopy->country_id != $this->country_id) {
2002
                        unset($this->country_code);
2003
                        unset($this->country);
2004
                    }
2005
                    if ($this->oldcopy->state_id != $this->state_id) {
2006
                        unset($this->state_code);
2007
                        unset($this->state);
2008
                    }
2009
                } else {
2010
                    unset($this->country_code); // We clean this, in the doubt, because it may have been changed after an update of country_id
2011
                    unset($this->country);
2012
                    unset($this->state_code);
2013
                    unset($this->state);
2014
                }
2015
2016
                $nbrowsaffected = $this->db->affected_rows($resql);
2017
2018
                if (!$error && $nbrowsaffected) {
2019
                    // Update information on linked member if it is an update
2020
                    if (!$nosyncmember && isModEnabled('member')) {
2021
                        dol_syslog(get_only_class($this) . "::update update linked member");
2022
2023
                        $lmember = new Adherent($this->db);
2024
                        $result = $lmember->fetch(0, 0, $this->id);
2025
2026
                        if ($result > 0) {
2027
                            $lmember->company = $this->name;
2028
                            //$lmember->firstname=$this->firstname?$this->firstname:$lmember->firstname;    // We keep firstname and lastname of member unchanged
2029
                            //$lmember->lastname=$this->lastname?$this->lastname:$lmember->lastname;        // We keep firstname and lastname of member unchanged
2030
                            $lmember->address = $this->address;
2031
                            $lmember->zip = $this->zip;
2032
                            $lmember->town = $this->town;
2033
                            $lmember->email = $this->email;
2034
                            $lmember->socialnetworks = $this->socialnetworks;
2035
                            $lmember->phone = $this->phone;
2036
                            $lmember->state_id = $this->state_id;
2037
                            $lmember->country_id = $this->country_id;
2038
                            $lmember->default_lang = $this->default_lang;
2039
2040
                            $result = $lmember->update($user, 0, 1, 1, 1); // Use nosync to 1 to avoid cyclic updates
2041
                            if ($result < 0) {
2042
                                $this->error = $lmember->error;
2043
                                $this->errors = array_merge($this->errors, $lmember->errors);
2044
                                dol_syslog(get_only_class($this) . "::update " . $this->error, LOG_ERR);
2045
                                $error++;
2046
                            }
2047
                        } elseif ($result < 0) {
2048
                            $this->error = $lmember->error;
2049
                            $error++;
2050
                        }
2051
                    }
2052
                }
2053
2054
                $action = 'update';
2055
2056
                // update accountancy for this entity
2057
                if (!$error && getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
2058
                    $this->db->query("DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity WHERE fk_soc = " . ((int)$this->id) . " AND entity = " . ((int)$conf->entity));
2059
2060
                    $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_perentity (";
2061
                    $sql .= " fk_soc";
2062
                    $sql .= ", entity";
2063
                    $sql .= ", vat_reverse_charge";
2064
                    $sql .= ", accountancy_code_customer";
2065
                    $sql .= ", accountancy_code_supplier";
2066
                    $sql .= ", accountancy_code_buy";
2067
                    $sql .= ", accountancy_code_sell";
2068
                    $sql .= ") VALUES (";
2069
                    $sql .= $this->id;
2070
                    $sql .= ", " . $conf->entity;
2071
                    $sql .= ", " . (empty($this->vat_reverse_charge) ? '0' : '1');
2072
                    $sql .= ", '" . $this->db->escape($this->code_compta_client) . "'";
2073
                    $sql .= ", '" . $this->db->escape($this->code_compta_fournisseur) . "'";
2074
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_buy) . "'";
2075
                    $sql .= ", '" . $this->db->escape($this->accountancy_code_sell) . "'";
2076
                    $sql .= ")";
2077
                    $result = $this->db->query($sql);
2078
                    if (!$result) {
2079
                        $error++;
2080
                        $this->error = 'ErrorFailedToUpdateAccountancyForEntity';
2081
                    }
2082
                }
2083
2084
                // Actions on extra fields
2085
                if (!$error) {
2086
                    $result = $this->insertExtraFields();
2087
                    if ($result < 0) {
2088
                        $error++;
2089
                    }
2090
                }
2091
                // Actions on extra languages
2092
                if (!$error && !getDolGlobalString('MAIN_EXTRALANGUAGES_DISABLED')) { // For avoid conflicts if trigger used
2093
                    $result = $this->insertExtraLanguages();
2094
                    if ($result < 0) {
2095
                        $error++;
2096
                    }
2097
                }
2098
2099
                if (!$error && $call_trigger) {
2100
                    // Call trigger
2101
                    $result = $this->call_trigger('COMPANY_MODIFY', $user);
2102
                    if ($result < 0) {
2103
                        $error++;
2104
                    }
2105
                    // End call triggers
2106
                }
2107
2108
                if (!$error) {
2109
                    dol_syslog(get_only_class($this) . "::Update success");
2110
                    $this->db->commit();
2111
                    return 1;
2112
                } else {
2113
                    $this->db->rollback();
2114
                    return -1;
2115
                }
2116
            } else {
2117
                if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
2118
                    // Doublon
2119
                    $this->error = $langs->trans("ErrorDuplicateField");
2120
                    $result = -1;
2121
                } else {
2122
                    $this->error = $this->db->lasterror();
2123
                    $result = -2;
2124
                }
2125
                $this->db->rollback();
2126
                return $result;
2127
            }
2128
        } else {
2129
            $this->db->rollback();
2130
            dol_syslog(get_only_class($this) . "::Update fails verify " . implode(',', $this->errors), LOG_WARNING);
2131
            return -3;
2132
        }
2133
    }
2134
2135
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2136
2137
    /**
2138
     *      Assigns a accounting code from the accounting code module.
2139
     *      Computed value is stored into this->code_compta or this->code_compta_fournisseur according to $type.
2140
     *      May be identical to the one entered or generated automatically. Currently, only the automatic generation is implemented.
2141
     *
2142
     * @param string $type Type of thirdparty ('customer' or 'supplier')
2143
     * @return int                 0 if OK, <0 if $type is not valid
2144
     */
2145
    public function get_codecompta($type)
2146
    {
2147
        // phpcs:enable
2148
        global $conf;
2149
2150
        if (getDolGlobalString('SOCIETE_CODECOMPTA_ADDON')) {
2151
            $module = getDolGlobalString('SOCIETE_CODECOMPTA_ADDON');
2152
            $res = false;
2153
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
2154
            foreach ($dirsociete as $dirroot) {
2155
                $res = dol_include_once($dirroot . $module . '.php');
2156
                if ($res) {
2157
                    break;
2158
                }
2159
            }
2160
2161
            if ($res) {
2162
                $mod = new $module();
2163
2164
                // Set code count in $mod->code
2165
                $result = $mod->get_code($this->db, $this, $type);
2166
2167
                if ($type == 'customer') {
2168
                    $this->code_compta_client = $mod->code;
2169
                    $this->code_compta = $this->code_compta_client; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

2169
                    /** @scrutinizer ignore-deprecated */ $this->code_compta = $this->code_compta_client; // For backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2170
                } elseif ($type == 'supplier') {
2171
                    $this->code_compta_fournisseur = $mod->code;
2172
                }
2173
2174
                return $result;
2175
            } else {
2176
                $this->error = 'ErrorAccountancyCodeNotDefined';
2177
                return -1;
2178
            }
2179
        } else {
2180
            if ($type == 'customer') {
2181
                $this->code_compta_client = '';
2182
                $this->code_compta = '';
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

2182
                /** @scrutinizer ignore-deprecated */ $this->code_compta = '';

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2183
            } elseif ($type == 'supplier') {
2184
                $this->code_compta_fournisseur = '';
2185
            }
2186
2187
            return 0;
2188
        }
2189
    }
2190
2191
    /**
2192
     *    Load a third party from database into memory
2193
     *
2194
     * @param int $rowid Id of third party to load
2195
     * @param string $ref Reference of third party, name (Warning, this can return several records)
2196
     * @param string $ref_ext External reference of third party (Warning, this information is a free field not provided by Dolibarr)
2197
     * @param string $barcode Barcode of third party to load
2198
     * @param string $idprof1 Prof id 1 of third party (Warning, this can return several records)
2199
     * @param string $idprof2 Prof id 2 of third party (Warning, this can return several records)
2200
     * @param string $idprof3 Prof id 3 of third party (Warning, this can return several records)
2201
     * @param string $idprof4 Prof id 4 of third party (Warning, this can return several records)
2202
     * @param string $idprof5 Prof id 5 of third party (Warning, this can return several records)
2203
     * @param string $idprof6 Prof id 6 of third party (Warning, this can return several records)
2204
     * @param string $email Email of third party (Warning, this can return several records)
2205
     * @param string $ref_alias Name_alias of third party (Warning, this can return several records)
2206
     * @param int $is_client Only client third party
2207
     * @param int $is_supplier Only supplier third party
2208
     * @return   int                     >0 if OK, <0 if KO or if two records found for same ref or idprof, 0 if not found.
2209
     */
2210
    public function fetch($rowid, $ref = '', $ref_ext = '', $barcode = '', $idprof1 = '', $idprof2 = '', $idprof3 = '', $idprof4 = '', $idprof5 = '', $idprof6 = '', $email = '', $ref_alias = '', $is_client = 0, $is_supplier = 0)
2211
    {
2212
        global $langs;
2213
        global $conf;
2214
2215
        if (empty($rowid) && empty($ref) && empty($ref_ext) && empty($barcode) && empty($idprof1) && empty($idprof2) && empty($idprof3) && empty($idprof4) && empty($idprof5) && empty($idprof6) && empty($email) && empty($ref_alias)) {
2216
            return -1;
2217
        }
2218
2219
        $sql = 'SELECT s.rowid, s.nom as name, s.name_alias, s.entity, s.ref_ext, s.address, s.datec as date_creation, s.prefix_comm';
2220
        $sql .= ', s.status, s.fk_warehouse';
2221
        $sql .= ', s.price_level';
2222
        $sql .= ', s.tms as date_modification, s.fk_user_creat, s.fk_user_modif';
2223
        $sql .= ', s.phone, s.phone_mobile, s.fax, s.email';
2224
        $sql .= ', s.socialnetworks';
2225
        $sql .= ', s.url, s.zip, s.town, s.note_private, s.note_public, s.client, s.fournisseur';
2226
        $sql .= ', s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6';
2227
        $sql .= ', s.capital, s.tva_intra';
2228
        $sql .= ', s.fk_typent as typent_id';
2229
        $sql .= ', s.fk_effectif as effectif_id';
2230
        $sql .= ', s.fk_forme_juridique as forme_juridique_code';
2231
        $sql .= ', s.webservices_url, s.webservices_key, s.model_pdf, s.last_main_doc';
2232
        if (!getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
2233
            $sql .= ', s.code_compta, s.code_compta_fournisseur, s.accountancy_code_buy, s.accountancy_code_sell';
2234
            $sql .= ', s.vat_reverse_charge as soc_vat_reverse_charge';
2235
        } else {
2236
            $sql .= ', spe.accountancy_code_customer as code_compta, spe.accountancy_code_supplier as code_compta_fournisseur, spe.accountancy_code_buy, spe.accountancy_code_sell';
2237
            $sql .= ', spe.vat_reverse_charge as spe_vat_reverse_charge';
2238
        }
2239
        $sql .= ', s.code_client, s.code_fournisseur, s.parent, s.barcode';
2240
        $sql .= ', s.fk_departement as state_id, s.fk_pays as country_id, s.fk_stcomm, s.mode_reglement, s.cond_reglement, s.deposit_percent, s.transport_mode';
2241
        $sql .= ', s.fk_account, s.tva_assuj';
2242
        $sql .= ', s.mode_reglement_supplier, s.cond_reglement_supplier, s.transport_mode_supplier';
2243
        $sql .= ', s.localtax1_assuj, s.localtax1_value, s.localtax2_assuj, s.localtax2_value, s.fk_prospectlevel, s.default_lang, s.logo, s.logo_squarred';
2244
        $sql .= ', s.fk_shipping_method';
2245
        $sql .= ', s.outstanding_limit, s.import_key, s.canvas, s.fk_incoterms, s.location_incoterms';
2246
        $sql .= ', s.order_min_amount, s.supplier_order_min_amount';
2247
        $sql .= ', s.fk_multicurrency, s.multicurrency_code';
2248
        $sql .= ', fj.libelle as forme_juridique';
2249
        $sql .= ', e.libelle as effectif';
2250
        $sql .= ', c.code as country_code, c.label as country';
2251
        $sql .= ', d.code_departement as state_code, d.nom as state';
2252
        $sql .= ', r.rowid as region_id, r.code_region as region_code';
2253
        $sql .= ', st.libelle as stcomm, st.picto as stcomm_picto';
2254
        $sql .= ', te.code as typent_code';
2255
        $sql .= ', i.libelle as label_incoterms';
2256
        if (!isModEnabled('multicompany')) {
2257
            $sql .= ', s.remise_client, s.remise_supplier';
2258
        } else {
2259
            $sql .= ', sr.remise_client, sr2.remise_supplier';
2260
        }
2261
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe as s';
2262
        if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
2263
            $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int)$conf->entity);
2264
        }
2265
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_effectif as e ON s.fk_effectif = e.id';
2266
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_country as c ON s.fk_pays = c.rowid';
2267
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_stcomm as st ON s.fk_stcomm = st.id';
2268
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_forme_juridique as fj ON s.fk_forme_juridique = fj.code';
2269
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_departements as d ON s.fk_departement = d.rowid';
2270
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_regions as r ON d.fk_region = r.code_region ';
2271
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_typent as te ON s.fk_typent = te.id';
2272
        $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'c_incoterms as i ON s.fk_incoterms = i.rowid';
2273
        // With default setup, llx_societe_remise is a history table in default setup and current value is in llx_societe.
2274
        // We use it for real value when multicompany is on. A better place would be into llx_societe_perentity.
2275
        if (isModEnabled('multicompany')) {
2276
            $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe_remise as sr ON sr.rowid = (SELECT MAX(rowid) FROM ' . MAIN_DB_PREFIX . 'societe_remise WHERE fk_soc = s.rowid AND entity IN (' . getEntity('discount') . '))';
2277
            $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'societe_remise_supplier as sr2 ON sr2.rowid = (SELECT MAX(rowid) FROM ' . MAIN_DB_PREFIX . 'societe_remise_supplier WHERE fk_soc = s.rowid AND entity IN (' . getEntity('discount') . '))';
2278
        }
2279
        $sql .= ' WHERE s.entity IN (' . getEntity($this->element) . ')';
2280
2281
        // Filter on client or supplier, for Client::fetch() and Fournisseur::fetch()
2282
        if ($is_client) {
2283
            $sql .= ' AND s.client > 0';
2284
        }
2285
        if ($is_supplier) {
2286
            $sql .= ' AND s.fournisseur > 0';
2287
        } // if both false, no test (the thirdparty can be client and/or supplier)
2288
2289
        if ($rowid) {
2290
            $sql .= ' AND s.rowid = ' . ((int)$rowid);
2291
        }
2292
        if ($ref) {
2293
            $sql .= " AND s.nom = '" . $this->db->escape($ref) . "'";
2294
        }
2295
        if ($ref_alias) {
2296
            $sql .= " AND s.name_alias = '" . $this->db->escape($ref_alias) . "'";
2297
        }
2298
        if ($ref_ext) {
2299
            $sql .= " AND s.ref_ext = '" . $this->db->escape($ref_ext) . "'";
2300
        }
2301
        if ($barcode) {
2302
            $sql .= " AND s.barcode = '" . $this->db->escape($barcode) . "'";
2303
        }
2304
        if ($idprof1) {
2305
            $sql .= " AND s.siren = '" . $this->db->escape($idprof1) . "'";
2306
        }
2307
        if ($idprof2) {
2308
            $sql .= " AND s.siret = '" . $this->db->escape($idprof2) . "'";
2309
        }
2310
        if ($idprof3) {
2311
            $sql .= " AND s.ape = '" . $this->db->escape($idprof3) . "'";
2312
        }
2313
        if ($idprof4) {
2314
            $sql .= " AND s.idprof4 = '" . $this->db->escape($idprof4) . "'";
2315
        }
2316
        if ($idprof5) {
2317
            $sql .= " AND s.idprof5 = '" . $this->db->escape($idprof5) . "'";
2318
        }
2319
        if ($idprof6) {
2320
            $sql .= " AND s.idprof6 = '" . $this->db->escape($idprof6) . "'";
2321
        }
2322
        if ($email) {
2323
            $sql .= " AND s.email = '" . $this->db->escape($email) . "'";
2324
        }
2325
2326
        $resql = $this->db->query($sql);
2327
        if ($resql) {
2328
            $num = $this->db->num_rows($resql);
2329
            if ($num > 1) {
2330
                $this->error = 'Fetch found several records. Rename one of thirdparties to avoid duplicate.';
2331
                dol_syslog($this->error, LOG_ERR);
2332
                $result = -2;
2333
            } elseif ($num) {   // $num = 1
2334
                $obj = $this->db->fetch_object($resql);
2335
2336
                $this->id = $obj->rowid;
2337
                $this->entity = $obj->entity;
2338
                $this->canvas = $obj->canvas;
2339
2340
                $this->ref = $obj->rowid;
2341
                $this->name = $obj->name;
2342
                $this->nom = $obj->name; // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

2342
                /** @scrutinizer ignore-deprecated */ $this->nom = $obj->name; // deprecated

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2343
                $this->name_alias = $obj->name_alias;
2344
                $this->ref_ext = $obj->ref_ext;
2345
2346
                $this->date_creation = $this->db->jdate($obj->date_creation);
2347
                $this->date_modification = $this->db->jdate($obj->date_modification);
2348
                $this->user_creation_id = $obj->fk_user_creat;
2349
                $this->user_modification_id = $obj->fk_user_modif;
2350
2351
                $this->address = $obj->address;
2352
                $this->zip = $obj->zip;
2353
                $this->town = $obj->town;
2354
2355
                $this->country_id = $obj->country_id;
2356
                $this->country_code = $obj->country_id ? $obj->country_code : '';
2357
                $this->country = $obj->country_id ? (($langs->transnoentities('Country' . $obj->country_code) != 'Country' . $obj->country_code) ? $langs->transnoentities('Country' . $obj->country_code) : $obj->country) : '';
2358
2359
                $this->state_id = $obj->state_id;
2360
                $this->state_code = $obj->state_code;
2361
                $this->region_id = $obj->region_id;
2362
                $this->region_code = $obj->region_code;
2363
                $this->state = ($obj->state != '-' ? $obj->state : '');
2364
2365
                $transcode = $langs->trans('StatusProspect' . $obj->fk_stcomm);
2366
                $label = ($transcode != 'StatusProspect' . $obj->fk_stcomm ? $transcode : $obj->stcomm);
2367
                $this->stcomm_id = $obj->fk_stcomm; // id status prospect
2368
                $this->status_prospect_label = $label; // label status prospect
2369
                $this->stcomm_picto = $obj->stcomm_picto; // picto statut commercial
2370
2371
                $this->email = $obj->email;
2372
                $this->socialnetworks = ($obj->socialnetworks ? (array)json_decode($obj->socialnetworks, true) : array());
2373
2374
                $this->url = $obj->url;
2375
                $this->phone = $obj->phone;
2376
                $this->phone_mobile = $obj->phone_mobile;
2377
                $this->fax = $obj->fax;
2378
2379
                $this->parent = $obj->parent;
2380
2381
                $this->idprof1 = $obj->idprof1;
2382
                $this->idprof2 = $obj->idprof2;
2383
                $this->idprof3 = $obj->idprof3;
2384
                $this->idprof4 = $obj->idprof4;
2385
                $this->idprof5 = $obj->idprof5;
2386
                $this->idprof6 = $obj->idprof6;
2387
2388
                $this->capital = $obj->capital;
2389
2390
                $this->code_client = $obj->code_client;
2391
                $this->code_fournisseur = $obj->code_fournisseur;
2392
2393
                $this->code_compta = $obj->code_compta;         // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Cl...s\Societe::$code_compta has been deprecated: Use $code_compta_client ( Ignorable by Annotation )

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

2393
                /** @scrutinizer ignore-deprecated */ $this->code_compta = $obj->code_compta;         // For backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2394
                $this->code_compta_client = $obj->code_compta;
2395
                $this->code_compta_fournisseur = $obj->code_compta_fournisseur;
2396
2397
                $this->barcode = $obj->barcode;
2398
2399
                $this->tva_assuj = $obj->tva_assuj;
2400
                $this->tva_intra = $obj->tva_intra;
2401
2402
                if (!empty($obj->spe_vat_reverse_charge)) {
2403
                    $this->vat_reverse_charge = $obj->spe_vat_reverse_charge;
2404
                } elseif (!empty($obj->soc_vat_reverse_charge)) {
2405
                    $this->vat_reverse_charge = $obj->soc_vat_reverse_charge;
2406
                } else {
2407
                    $this->vat_reverse_charge = 0;
2408
                }
2409
2410
                $this->status = $obj->status;
2411
2412
                // Local Taxes
2413
                $this->localtax1_assuj = $obj->localtax1_assuj;
2414
                $this->localtax2_assuj = $obj->localtax2_assuj;
2415
2416
                $this->localtax1_value = $obj->localtax1_value;
2417
                $this->localtax2_value = $obj->localtax2_value;
2418
2419
                $this->typent_id = $obj->typent_id;
2420
                $this->typent_code = $obj->typent_code;
2421
2422
                $this->effectif_id = $obj->effectif_id;
2423
                $this->effectif = $obj->effectif_id ? $obj->effectif : '';
2424
2425
                $this->forme_juridique_code = $obj->forme_juridique_code;
2426
                $this->forme_juridique = $obj->forme_juridique_code ? $obj->forme_juridique : '';
2427
2428
                $this->fk_prospectlevel = $obj->fk_prospectlevel;
2429
2430
                $this->prefix_comm = $obj->prefix_comm;
2431
2432
                $this->remise_percent = $obj->remise_client ? price2num($obj->remise_client) : 0; // 0.000000 must be 0
2433
                $this->remise_supplier_percent = $obj->remise_supplier;
2434
2435
                $this->mode_reglement_id = $obj->mode_reglement;
2436
                $this->cond_reglement_id = $obj->cond_reglement;
2437
                $this->deposit_percent = $obj->deposit_percent;
2438
                $this->transport_mode_id = $obj->transport_mode;
2439
                $this->mode_reglement_supplier_id = $obj->mode_reglement_supplier;
2440
                $this->cond_reglement_supplier_id = $obj->cond_reglement_supplier;
2441
                $this->transport_mode_supplier_id = $obj->transport_mode_supplier;
2442
                $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : null;
2443
                $this->fk_account = $obj->fk_account;
2444
2445
                $this->client = $obj->client;
2446
                $this->fournisseur = $obj->fournisseur;
2447
2448
                $this->note = $obj->note_private; // TODO Deprecated for backward comtability
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$note has been deprecated: Use $note_public, $note_private - Note is split in public and private notes ( Ignorable by Annotation )

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

2448
                /** @scrutinizer ignore-deprecated */ $this->note = $obj->note_private; // TODO Deprecated for backward comtability

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2449
                $this->note_private = $obj->note_private;
2450
                $this->note_public = $obj->note_public;
2451
                $this->model_pdf = $obj->model_pdf;
2452
                $this->default_lang = $obj->default_lang;
2453
                $this->logo = $obj->logo;
2454
                $this->logo_squarred = $obj->logo_squarred;
2455
2456
                $this->webservices_url = $obj->webservices_url;
2457
                $this->webservices_key = $obj->webservices_key;
2458
2459
                $this->accountancy_code_buy = $obj->accountancy_code_buy;
2460
                $this->accountancy_code_sell = $obj->accountancy_code_sell;
2461
2462
                $this->outstanding_limit = $obj->outstanding_limit;
2463
                $this->order_min_amount = $obj->order_min_amount;
2464
                $this->supplier_order_min_amount = $obj->supplier_order_min_amount;
2465
2466
                // multiprix
2467
                $this->price_level = $obj->price_level;
2468
2469
                // warehouse
2470
                $this->fk_warehouse = $obj->fk_warehouse;
2471
2472
                $this->import_key = $obj->import_key;
2473
2474
                //Incoterms
2475
                $this->fk_incoterms = $obj->fk_incoterms;
2476
                $this->location_incoterms = $obj->location_incoterms;
2477
                $this->label_incoterms = $obj->label_incoterms;
2478
2479
                // multicurrency
2480
                $this->fk_multicurrency = $obj->fk_multicurrency;
2481
                $this->multicurrency_code = $obj->multicurrency_code;
2482
2483
                // pdf
2484
                $this->model_pdf = $obj->model_pdf;
2485
                $this->last_main_doc = $obj->last_main_doc;
2486
2487
                $result = 1;
2488
2489
                // fetch optionals attributes and labels
2490
                $this->fetch_optionals();
2491
            } else {
2492
                $result = 0;
2493
            }
2494
2495
            $this->db->free($resql);
2496
        } else {
2497
            $this->error = $this->db->lasterror();
2498
            $this->errors[] = $this->db->lasterror();
2499
            $result = -3;
2500
        }
2501
2502
        // Use first price level if level not defined for third party
2503
        if ((getDolGlobalString('PRODUIT_MULTIPRICES') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) && empty($this->price_level)) {
2504
            $this->price_level = 1;
2505
        }
2506
2507
        return $result;
2508
    }
2509
2510
    /**
2511
     *  Add link to sales representative
2512
     *
2513
     * @param User $user Object user
2514
     * @param int $commid Id of user
2515
     * @return int                 Return integer <=0 if KO, >0 if OK
2516
     */
2517
    public function add_commercial(User $user, $commid)
2518
    {
2519
        // phpcs:enable
2520
        $error = 0;
2521
2522
        if ($this->id > 0 && $commid > 0) {
2523
            $this->db->begin();
2524
2525
            if (!$error) {
2526
                $sql = "DELETE FROM  " . MAIN_DB_PREFIX . "societe_commerciaux";
2527
                $sql .= " WHERE fk_soc = " . ((int)$this->id) . " AND fk_user = " . ((int)$commid);
2528
2529
                $resql = $this->db->query($sql);
2530
                if (!$resql) {
2531
                    dol_syslog(get_only_class($this) . "::add_commercial Error " . $this->db->lasterror());
2532
                    $error++;
2533
                }
2534
            }
2535
2536
            if (!$error) {
2537
                $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_commerciaux";
2538
                $sql .= " (fk_soc, fk_user)";
2539
                $sql .= " VALUES (" . ((int)$this->id) . ", " . ((int)$commid) . ")";
2540
2541
                $resql = $this->db->query($sql);
2542
                if (!$resql) {
2543
                    dol_syslog(get_only_class($this) . "::add_commercial Error " . $this->db->lasterror());
2544
                    $error++;
2545
                }
2546
            }
2547
2548
            if (!$error) {
2549
                $this->context = array('commercial_modified' => $commid);
2550
2551
                $result = $this->call_trigger('COMPANY_LINK_SALE_REPRESENTATIVE', $user);
2552
                if ($result < 0) {
2553
                    $error++;
2554
                }
2555
            }
2556
2557
            if (!$error) {
2558
                $this->db->commit();
2559
                return 1;
2560
            } else {
2561
                $this->db->rollback();
2562
                return -1;
2563
            }
2564
        }
2565
2566
        return 0;
2567
    }
2568
2569
    /**
2570
     *  Returns amount of included taxes of the current discounts/credits available from the company
2571
     *
2572
     * @param  ?User $user Filter on a user author of discounts
2573
     * @param string $filter Other filter
2574
     * @param int $maxvalue Filter on max value for discount
2575
     * @param int<0,1> $discount_type 0 => customer discount, 1 => supplier discount
2576
     * @return float|int<-1,-1>        Return integer <0 if KO, Credit note amount otherwise
2577
     */
2578
    public function getAvailableDiscounts($user = null, $filter = '', $maxvalue = 0, $discount_type = 0)
2579
    {
2580
2581
        $discountstatic = new DiscountAbsolute($this->db);
2582
        $result = $discountstatic->getAvailableDiscounts($this, $user, $filter, $maxvalue, $discount_type);
2583
        if ($result >= 0) {
2584
            return $result;
2585
        } else {
2586
            $this->error = $discountstatic->error;
2587
            return -1;
2588
        }
2589
    }
2590
2591
    /**
2592
     * Set the price level
2593
     *
2594
     * @param int $price_level Level of price
2595
     * @param User $user Use making change
2596
     * @return  int                     Return integer <0 if KO, >0 if OK
2597
     */
2598
    public function setPriceLevel($price_level, User $user)
2599
    {
2600
        if ($this->id) {
2601
            $now = dol_now();
2602
2603
            $sql = "UPDATE " . MAIN_DB_PREFIX . "societe";
2604
            $sql .= " SET price_level = " . ((int)$price_level);
2605
            $sql .= " WHERE rowid = " . ((int)$this->id);
2606
2607
            if (!$this->db->query($sql)) {
2608
                dol_print_error($this->db);
2609
                return -1;
2610
            }
2611
2612
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "societe_prices";
2613
            $sql .= " (datec, fk_soc, price_level, fk_user_author)";
2614
            $sql .= " VALUES ('" . $this->db->idate($now) . "', " . ((int)$this->id) . ", " . ((int)$price_level) . ", " . ((int)$user->id) . ")";
2615
2616
            if (!$this->db->query($sql)) {
2617
                dol_print_error($this->db);
2618
                return -1;
2619
            }
2620
            return 1;
2621
        }
2622
        return -1;
2623
    }
2624
2625
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2626
2627
    /**
2628
     *    Return list of contacts emails existing for third party
2629
     *
2630
     * @param int $addthirdparty 1=Add also a record for thirdparty email, 2=Same than 1 but add text ThirdParty in grey
2631
     * @return   array                       Array of contacts emails
2632
     */
2633
    public function thirdparty_and_contact_email_array($addthirdparty = 0)
2634
    {
2635
        // phpcs:enable
2636
        global $langs;
2637
2638
        $contact_emails = $this->contact_property_array('email', 1);
2639
2640
        if ($this->email && $addthirdparty) {
2641
            if (empty($this->name)) {
2642
                $this->name = $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

2642
                $this->name = /** @scrutinizer ignore-deprecated */ $this->nom;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2643
            }
2644
            $contact_emails['thirdparty'] = ($addthirdparty == 2 ? '<span class="opacitymedium">' : '') . $langs->transnoentitiesnoconv("ThirdParty") . ($addthirdparty == 2 ? '</span>' : '') . ': ' . dol_trunc($this->name, 16) . " <" . $this->email . ">";
2645
        }
2646
2647
        //var_dump($contact_emails)
2648
        return $contact_emails;
2649
    }
2650
2651
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2652
2653
    /**
2654
     *  Return list of contacts emails or mobile existing for third party
2655
     *
2656
     * @param string $mode 'email' or 'mobile'
2657
     * @param int $hidedisabled 1=Hide contact if disabled
2658
     * @return array                       Array of contacts emails or mobile. Example: array(id=>'Name <email>')
2659
     */
2660
    public function contact_property_array($mode = 'email', $hidedisabled = 0)
2661
    {
2662
        // phpcs:enable
2663
        global $langs;
2664
2665
        $contact_property = array();
2666
2667
2668
        $sql = "SELECT rowid, email, statut as status, phone_mobile, lastname, poste, firstname";
2669
        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople";
2670
        $sql .= " WHERE fk_soc = " . ((int)$this->id);
2671
        $sql .= " AND entity IN (" . getEntity($this->element) . ")";
2672
        $sql .= " ORDER BY lastname, firstname";
2673
2674
        $resql = $this->db->query($sql);
2675
        if ($resql) {
2676
            $nump = $this->db->num_rows($resql);
2677
            if ($nump) {
2678
                $sepa = "(";
2679
                $sepb = ")";
2680
                if ($mode == 'email') {
2681
                    //$sepa="&lt;"; $sepb="&gt;";
2682
                    $sepa = "<";
2683
                    $sepb = ">";
2684
                }
2685
                $i = 0;
2686
                while ($i < $nump) {
2687
                    $obj = $this->db->fetch_object($resql);
2688
                    if ($mode == 'email') {
2689
                        $property = $obj->email;
2690
                    } elseif ($mode == 'mobile') {
2691
                        $property = $obj->phone_mobile;
2692
                    } else {
2693
                        $property = $obj->$mode;
2694
                    }
2695
2696
                    // Show all contact. If hidedisabled is 1, showonly contacts with status = 1
2697
                    if ($obj->status == 1 || empty($hidedisabled)) {
2698
                        if (empty($property)) {
2699
                            if ($mode == 'email') {
2700
                                $property = $langs->transnoentitiesnoconv("NoEMail");
2701
                            } elseif ($mode == 'mobile') {
2702
                                $property = $langs->transnoentitiesnoconv("NoMobilePhone");
2703
                            }
2704
                        }
2705
2706
                        if (!empty($obj->poste)) {
2707
                            $contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname, $obj->lastname)) . ($obj->poste ? " - " . $obj->poste : "") . (($mode != 'poste' && $property) ? " " . $sepa . $property . $sepb : '');
2708
                        } else {
2709
                            $contact_property[$obj->rowid] = trim(dolGetFirstLastname($obj->firstname, $obj->lastname)) . (($mode != 'poste' && $property) ? " " . $sepa . $property . $sepb : '');
2710
                        }
2711
                    }
2712
                    $i++;
2713
                }
2714
            }
2715
        } else {
2716
            dol_print_error($this->db);
2717
        }
2718
        return $contact_property;
2719
    }
2720
2721
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2722
2723
    /**
2724
     *    Return list of contacts mobile phone existing for third party
2725
     *
2726
     * @return     array       Array of contacts emails
2727
     */
2728
    public function thirdparty_and_contact_phone_array()
2729
    {
2730
        // phpcs:enable
2731
        global $langs;
2732
2733
        $contact_phone = $this->contact_property_array('mobile');
2734
2735
        if (!empty($this->phone)) { // If a phone of thirdparty is defined, we add it to mobile of contacts
2736
            if (empty($this->name)) {
2737
                $this->name = $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

2737
                $this->name = /** @scrutinizer ignore-deprecated */ $this->nom;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
2738
            }
2739
            // TODO: Tester si tel non deja present dans tableau contact
2740
            $contact_phone['thirdparty'] = $langs->transnoentitiesnoconv("ThirdParty") . ': ' . dol_trunc($this->name, 16) . " <" . $this->phone . ">";
2741
        }
2742
        return $contact_phone;
2743
    }
2744
2745
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2746
2747
    /**
2748
     *    Returns the contact list of this company
2749
     *
2750
     * @return     array      array of contacts
2751
     */
2752
    public function contact_array()
2753
    {
2754
        // phpcs:enable
2755
        $contacts = array();
2756
2757
        $sql = "SELECT rowid, lastname, firstname FROM " . MAIN_DB_PREFIX . "socpeople WHERE fk_soc = " . ((int)$this->id);
2758
        $resql = $this->db->query($sql);
2759
        if ($resql) {
2760
            $nump = $this->db->num_rows($resql);
2761
            if ($nump) {
2762
                $i = 0;
2763
                while ($i < $nump) {
2764
                    $obj = $this->db->fetch_object($resql);
2765
                    $contacts[$obj->rowid] = dolGetFirstLastname($obj->firstname, $obj->lastname);
2766
                    $i++;
2767
                }
2768
            }
2769
        } else {
2770
            dol_print_error($this->db);
2771
        }
2772
        return $contacts;
2773
    }
2774
2775
2776
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2777
2778
    /**
2779
     *    Returns the contact list of this company
2780
     *
2781
     * @return    array    $contacts    array of contacts
2782
     */
2783
    public function contact_array_objects()
2784
    {
2785
        $contacts = array();
2786
2787
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "socpeople WHERE fk_soc = " . ((int)$this->id);
2788
        $resql = $this->db->query($sql);
2789
        if ($resql) {
2790
            $nump = $this->db->num_rows($resql);
2791
            if ($nump) {
2792
                $i = 0;
2793
                while ($i < $nump) {
2794
                    $obj = $this->db->fetch_object($resql);
2795
                    $contact = new Contact($this->db);
2796
                    $contact->fetch($obj->rowid);
2797
                    $contacts[] = $contact;
2798
                    $i++;
2799
                }
2800
            }
2801
        } else {
2802
            dol_print_error($this->db);
2803
        }
2804
        return $contacts;
2805
    }
2806
2807
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2808
2809
    /**
2810
     *  Return property of contact from its id
2811
     *
2812
     * @param int $rowid id of contact
2813
     * @param string $mode 'email' or 'mobile'
2814
     * @return string              Email of contact with format: "Full name <email>"
2815
     */
2816
    public function contact_get_property($rowid, $mode)
2817
    {
2818
        // phpcs:enable
2819
        $contact_property = '';
2820
2821
        if (empty($rowid)) {
2822
            return '';
2823
        }
2824
2825
        $sql = "SELECT rowid, email, phone_mobile, lastname, firstname";
2826
        $sql .= " FROM " . MAIN_DB_PREFIX . "socpeople";
2827
        $sql .= " WHERE rowid = " . ((int)$rowid);
2828
2829
        $resql = $this->db->query($sql);
2830
        if ($resql) {
2831
            $nump = $this->db->num_rows($resql);
2832
2833
            if ($nump) {
2834
                $obj = $this->db->fetch_object($resql);
2835
2836
                if ($mode == 'email') {
2837
                    $contact_property = dol_string_nospecial(dolGetFirstLastname($obj->firstname, $obj->lastname), ' ', array(",")) . " <" . $obj->email . ">";
2838
                } elseif ($mode == 'mobile') {
2839
                    $contact_property = $obj->phone_mobile;
2840
                }
2841
            }
2842
            return $contact_property;
2843
        } else {
2844
            dol_print_error($this->db);
2845
        }
2846
2847
        return '';
2848
    }
2849
2850
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2851
2852
    /**
2853
     *  Return bank number property of thirdparty (label or rum)
2854
     *
2855
     * @param string $mode 'label' or 'rum' or 'format'
2856
     * @return string          Bank label or RUM or '' if no bank account found
2857
     */
2858
    public function display_rib($mode = 'label')
2859
    {
2860
        // phpcs:enable
2861
2862
        $bac = new CompanyBankAccount($this->db);
2863
        // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2864
        $bac->fetch(0, '', $this->id);
2865
2866
        if ($bac->id > 0) {     // If a bank account has been found for company $this->id
2867
            if ($mode == 'label') {
2868
                return $bac->getRibLabel(true);
2869
            } elseif ($mode == 'rum') {
2870
                if (empty($bac->rum)) {
2871
                    $prelevement = new BonPrelevement($this->db);
2872
                    $bac->fetch_thirdparty();
2873
                    $bac->rum = $prelevement->buildRumNumber($bac->thirdparty->code_client, $bac->datec, $bac->id);
2874
                }
2875
                return $bac->rum;
2876
            } elseif ($mode == 'format') {
2877
                return $bac->frstrecur;
2878
            } else {
2879
                return 'BadParameterToFunctionDisplayRib';
2880
            }
2881
        } else {
2882
            return '';
2883
        }
2884
    }
2885
2886
2887
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2888
2889
    /**
2890
     * Return Array of RIB
2891
     *
2892
     * @return    CompanyBankAccount[]|int        Return 0 if KO, Array of CompanyBankAccount if OK
2893
     */
2894
    public function get_all_rib()
2895
    {
2896
        // phpcs:enable
2897
        $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "societe_rib WHERE type='ban' AND fk_soc = " . ((int)$this->id);
2898
        $result = $this->db->query($sql);
2899
        if (!$result) {
2900
            $this->error++;
2901
            $this->errors[] = $this->db->lasterror;
2902
            return 0;
2903
        } else {
2904
            $num_rows = $this->db->num_rows($result);
2905
            $rib_array = array();
2906
            if ($num_rows) {
2907
                while ($obj = $this->db->fetch_object($result)) {
2908
                    $rib = new CompanyBankAccount($this->db);
2909
                    $rib->fetch($obj->rowid);
2910
                    $rib_array[] = $rib;
2911
                }
2912
            }
2913
            return $rib_array;
2914
        }
2915
    }
2916
2917
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2918
2919
    /**
2920
     *    Check if a client code is editable based on the parameters of the
2921
     *    code control module.
2922
     *
2923
     * @return     int       0=No, 1=Yes
2924
     */
2925
    public function codeclient_modifiable()
2926
    {
2927
        // phpcs:enable
2928
        global $conf;
2929
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
2930
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
2931
2932
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
2933
            foreach ($dirsociete as $dirroot) {
2934
                $res = dol_include_once($dirroot . $module . '.php');
2935
                if ($res) {
2936
                    break;
2937
                }
2938
            }
2939
2940
            $mod = new $module($this->db);
2941
2942
            dol_syslog(get_only_class($this) . "::codeclient_modifiable code_client=" . $this->code_client . " module=" . $module);
2943
            if ($mod->code_modifiable_null && !$this->code_client) {
2944
                return 1;
2945
            }
2946
            if ($mod->code_modifiable_invalide && $this->check_codeclient() < 0) {
2947
                return 1;
2948
            }
2949
            if ($mod->code_modifiable) {
2950
                return 1; // A mettre en dernier
2951
            }
2952
            return 0;
2953
        } else {
2954
            return 0;
2955
        }
2956
    }
2957
2958
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2959
2960
    /**
2961
     *    Check if a vendor code is editable in the code control module configuration
2962
     *
2963
     * @return     int       0=No, 1=Yes
2964
     */
2965
    public function codefournisseur_modifiable()
2966
    {
2967
        // phpcs:enable
2968
        global $conf;
2969
        if (getDolGlobalString('SOCIETE_CODECLIENT_ADDON')) {
2970
            $module = getDolGlobalString('SOCIETE_CODECLIENT_ADDON');
2971
2972
            $dirsociete = array_merge(array('/core/modules/societe/'), $conf->modules_parts['societe']);
2973
            foreach ($dirsociete as $dirroot) {
2974
                $res = dol_include_once($dirroot . $module . '.php');
2975
                if ($res) {
2976
                    break;
2977
                }
2978
            }
2979
2980
            $mod = new $module($this->db);
2981
2982
            dol_syslog(get_only_class($this) . "::codefournisseur_modifiable code_founisseur=" . $this->code_fournisseur . " module=" . $module);
2983
            if ($mod->code_modifiable_null && !$this->code_fournisseur) {
2984
                return 1;
2985
            }
2986
            if ($mod->code_modifiable_invalide && $this->check_codefournisseur() < 0) {
2987
                return 1;
2988
            }
2989
            if ($mod->code_modifiable) {
2990
                return 1; // A mettre en dernier
2991
            }
2992
            return 0;
2993
        } else {
2994
            return 0;
2995
        }
2996
    }
2997
2998
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
2999
3000
    /**
3001
     *    Define parent company of current company
3002
     *
3003
     * @param int $id Id of thirdparty to set or '' to remove
3004
     * @return   int             Return integer <0 if KO, >0 if OK
3005
     */
3006
    public function setParent($id)
3007
    {
3008
        dol_syslog(get_only_class($this) . '::setParent', LOG_DEBUG);
3009
3010
        if ($this->id) {
3011
            // Check if the id we want to add as parent has not already one parent that is the current id we try to update
3012
            if ($id > 0) {
3013
                $sameparent = $this->validateFamilyTree($id, $this->id, 0);
3014
                if ($sameparent < 0) {
3015
                    return -1;
3016
                }
3017
                if ($sameparent == 1) {
3018
                    setEventMessages('ParentCompanyToAddIsAlreadyAChildOfModifiedCompany', null, 'warnings');
3019
                    return -1;
3020
                }
3021
            }
3022
3023
            $sql = 'UPDATE ' . MAIN_DB_PREFIX . 'societe SET parent = ' . ($id > 0 ? $id : 'null') . ' WHERE rowid = ' . ((int)$this->id);
3024
3025
            $resql = $this->db->query($sql);
3026
            if ($resql) {
3027
                $this->parent = $id;
3028
                return 1;
3029
            } else {
3030
                return -1;
3031
            }
3032
        }
3033
3034
        return -1;
3035
    }
3036
3037
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3038
3039
    /**
3040
     *    Check if a thirdparty $idchild is or not inside the parents (or grand parents) of another thirdparty id $idparent.
3041
     *
3042
     * @param int $idparent Id of thirdparty to check
3043
     * @param int $idchild Id of thirdparty to compare to
3044
     * @param int $counter Counter to protect against infinite loops
3045
     * @return   int                 Return integer <0 if KO, 0 if OK or 1 if at some level a parent company was the child to compare to
3046
     */
3047
    public function validateFamilyTree($idparent, $idchild, $counter = 0)
3048
    {
3049
        if ($counter > 100) {
3050
            dol_syslog("Too high level of parent - child for company. May be an infinite loop ?", LOG_WARNING);
3051
        }
3052
3053
        $sql = 'SELECT s.parent';
3054
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe as s';
3055
        $sql .= ' WHERE rowid = ' . ((int)$idparent);
3056
        $resql = $this->db->query($sql);
3057
        if ($resql) {
3058
            $obj = $this->db->fetch_object($resql);
3059
3060
            if ($obj->parent == '') {
3061
                return 0;
3062
            } elseif ($obj->parent == $idchild) {
3063
                return 1;
3064
            } else {
3065
                $sameparent = $this->validateFamilyTree($obj->parent, $idchild, ($counter + 1));
3066
            }
3067
            return $sameparent;
3068
        } else {
3069
            return -1;
3070
        }
3071
    }
3072
3073
3074
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3075
3076
    /**
3077
     *  Get parents for company
3078
     *
3079
     * @param int $company_id ID of company to search parent
3080
     * @param array $parents List of companies ID found
3081
     * @return  array
3082
     */
3083
    public function getParentsForCompany($company_id, $parents = array())
3084
    {
3085
        global $langs;
3086
3087
        if ($company_id > 0) {
3088
            $sql = "SELECT parent FROM " . MAIN_DB_PREFIX . "societe WHERE rowid = " . ((int)$company_id);
3089
            $resql = $this->db->query($sql);
3090
            if ($resql) {
3091
                if ($obj = $this->db->fetch_object($resql)) {
3092
                    $parent = $obj->parent;
3093
                    if ($parent > 0 && !in_array($parent, $parents)) {
3094
                        $parents[] = $parent;
3095
                        return $this->getParentsForCompany($parent, $parents);
3096
                    } else {
3097
                        return $parents;
3098
                    }
3099
                }
3100
                $this->db->free($resql);
3101
            } else {
3102
                setEventMessage($langs->trans('GetCompanyParentsError', $this->db->lasterror()), 'errors');
3103
            }
3104
        }
3105
        // Return a default value when $company_id is not greater than 0
3106
        return array();
3107
    }
3108
3109
3110
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3111
3112
    /**
3113
     *  Check the validity of a professional identifier according to the country of the company (siren, siret, ...)
3114
     *
3115
     * @param int $idprof 1,2,3,4 (Example: 1=siren,2=siret,3=naf,4=rcs/rm)
3116
     * @param Societe $soc Object societe
3117
     * @return int                         Return integer <=0 if KO, >0 if OK
3118
     *  TODO better to have this in a lib than into a business class
3119
     */
3120
    public function id_prof_check($idprof, $soc)
3121
    {
3122
        // phpcs:enable
3123
        global $conf;
3124
3125
        // load the library necessary to check the professional identifiers
3126
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/profid.lib.php';
3127
3128
        $ok = 1;
3129
3130
        if (getDolGlobalString('MAIN_DISABLEPROFIDRULES')) {
3131
            return 1;
3132
        }
3133
3134
        // Check SIREN
3135
        if ($idprof == 1 && $soc->country_code == 'FR' && !isValidSiren($this->idprof1)) {
3136
            return -1;
3137
        }
3138
3139
        // Check SIRET
3140
        if ($idprof == 2 && $soc->country_code == 'FR' && !isValidSiret($this->idprof2)) {
3141
            return -1;
3142
        }
3143
3144
        //Verify CIF/NIF/NIE if pays ES
3145
        if ($idprof == 1 && $soc->country_code == 'ES') {
3146
            return isValidTinForES($this->idprof1);
3147
        }
3148
3149
        //Verify NIF if country is PT
3150
        if ($idprof == 1 && $soc->country_code == 'PT' && !isValidTinForPT($this->idprof1)) {
3151
            return -1;
3152
        }
3153
3154
        //Verify NIF if country is DZ
3155
        if ($idprof == 1 && $soc->country_code == 'DZ' && !isValidTinForDZ($this->idprof1)) {
3156
            return -1;
3157
        }
3158
3159
        //Verify ID Prof 1 if country is BE
3160
        if ($idprof == 1 && $soc->country_code == 'BE' && !isValidTinForBE($this->idprof1)) {
3161
            return -1;
3162
        }
3163
3164
        return $ok;
3165
    }
3166
3167
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3168
3169
    /**
3170
     *   Return an url to check online a professional id or empty string
3171
     *
3172
     * @param int $idprof 1,2,3,4 (Example: 1=siren,2=siret,3=naf,4=rcs/rm)
3173
     * @param Societe $thirdparty Object thirdparty
3174
     * @return    string                  Url or empty string if no URL known
3175
     *   TODO better in a lib than into business class
3176
     */
3177
    public function id_prof_url($idprof, $thirdparty)
3178
    {
3179
        // phpcs:enable
3180
        global $conf, $langs, $hookmanager;
3181
3182
        $url = '';
3183
        $action = '';
3184
3185
        $hookmanager->initHooks(array('idprofurl'));
3186
        $parameters = array('idprof' => $idprof, 'company' => $thirdparty);
3187
        $reshook = $hookmanager->executeHooks('getIdProfUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
3188
        if (empty($reshook)) {
3189
            if (getDolGlobalString('MAIN_DISABLEPROFIDRULES')) {
3190
                return '';
3191
            }
3192
3193
            // TODO Move links to validate professional ID into a dictionary table "country" + "link"
3194
            $strippedIdProf1 = str_replace(' ', '', $thirdparty->idprof1);
3195
            if ($idprof == 1 && $thirdparty->country_code == 'FR') {
3196
                $url = 'https://annuaire-entreprises.data.gouv.fr/entreprise/' . $strippedIdProf1; // See also http://avis-situation-sirene.insee.fr/
3197
            }
3198
            if ($idprof == 1 && ($thirdparty->country_code == 'GB' || $thirdparty->country_code == 'UK')) {
3199
                $url = 'https://beta.companieshouse.gov.uk/company/' . $strippedIdProf1;
3200
            }
3201
            if ($idprof == 1 && $thirdparty->country_code == 'ES') {
3202
                $url = 'http://www.e-informa.es/servlet/app/portal/ENTP/screen/SProducto/prod/ETIQUETA_EMPRESA/nif/' . $strippedIdProf1;
3203
            }
3204
            if ($idprof == 1 && $thirdparty->country_code == 'IN') {
3205
                $url = 'http://www.tinxsys.com/TinxsysInternetWeb/dealerControllerServlet?tinNumber=' . $strippedIdProf1 . ';&searchBy=TIN&backPage=searchByTin_Inter.jsp';
3206
            }
3207
            if ($idprof == 1 && $thirdparty->country_code == 'DZ') {
3208
                $url = 'http://nif.mfdgi.gov.dz/nif.asp?Nif=' . $strippedIdProf1;
3209
            }
3210
            if ($idprof == 1 && $thirdparty->country_code == 'PT') {
3211
                $url = 'http://www.nif.pt/' . $strippedIdProf1;
3212
            }
3213
3214
            if ($url) {
3215
                return '<a target="_blank" rel="noopener noreferrer" href="' . $url . '">' . $langs->trans("Check") . '</a>';
3216
            }
3217
        } else {
3218
            return $hookmanager->resPrint;
3219
        }
3220
3221
        return '';
3222
    }
3223
3224
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3225
3226
    /**
3227
     *   Indicates if the company has projects
3228
     *
3229
     * @return     bool      true if the company has projects, false otherwise
3230
     */
3231
    public function has_projects()
3232
    {
3233
        // phpcs:enable
3234
        $sql = "SELECT COUNT(*) as numproj FROM " . MAIN_DB_PREFIX . "projet WHERE fk_soc = " . ((int)$this->id);
3235
        $resql = $this->db->query($sql);
3236
        if ($resql) {
3237
            $obj = $this->db->fetch_object($resql);
3238
            $count = $obj->numproj;
3239
        } else {
3240
            $count = 0;
3241
            print $this->db->error();
3242
        }
3243
        $this->db->free($resql);
3244
        return ($count > 0);
3245
    }
3246
3247
    /**
3248
     *  Load information for tab info
3249
     *
3250
     * @param int $id Id of thirdparty to load
3251
     * @return void
3252
     */
3253
    public function info($id)
3254
    {
3255
        $sql = "SELECT s.rowid, s.nom as name, s.datec, tms as datem,";
3256
        $sql .= " fk_user_creat, fk_user_modif";
3257
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe as s";
3258
        $sql .= " WHERE s.rowid = " . ((int)$id);
3259
3260
        $result = $this->db->query($sql);
3261
        if ($result) {
3262
            if ($this->db->num_rows($result)) {
3263
                $obj = $this->db->fetch_object($result);
3264
3265
                $this->id = $obj->rowid;
3266
3267
                $this->user_creation_id = $obj->fk_user_creat;
3268
                $this->user_modification_id = $obj->fk_user_modif;
3269
                $this->date_creation = $this->db->jdate($obj->datec);
3270
                $this->date_modification = empty($obj->datem) ? '' : $this->db->jdate($obj->datem);
3271
3272
                $this->ref = $obj->name;
3273
            }
3274
3275
            $this->db->free($result);
3276
        } else {
3277
            dol_print_error($this->db);
3278
        }
3279
    }
3280
3281
    /**
3282
     *  Return if a company is inside the EEC (European Economic Community)
3283
     *
3284
     * @return     boolean     true = country inside EEC, false = country outside EEC
3285
     */
3286
    public function isInEEC()
3287
    {
3288
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/company.lib.php';
3289
        return isInEEC($this);
3290
    }
3291
3292
    /**
3293
     *  Load the list of provider categories
3294
     *
3295
     * @return    int      0 if success, <> 0 if error
3296
     */
3297
    public function LoadSupplierCateg()
3298
    {
3299
        // phpcs:enable
3300
        $this->SupplierCategories = array();
3301
        $sql = "SELECT rowid, label";
3302
        $sql .= " FROM " . MAIN_DB_PREFIX . "categorie";
3303
        $sql .= " WHERE type = " . Categorie::TYPE_SUPPLIER;
3304
3305
        $resql = $this->db->query($sql);
3306
        if ($resql) {
3307
            while ($obj = $this->db->fetch_object($resql)) {
3308
                $this->SupplierCategories[$obj->rowid] = $obj->label;
3309
            }
3310
            return 0;
3311
        } else {
3312
            return -1;
3313
        }
3314
    }
3315
3316
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3317
3318
    /**
3319
     *  Insert link supplier - category
3320
     *
3321
     * @param int $categorie_id Id of category
3322
     * @return int                         0 if success, <> 0 if error
3323
     */
3324
    public function AddFournisseurInCategory($categorie_id)
3325
    {
3326
        // phpcs:enable
3327
        if ($categorie_id > 0 && $this->id > 0) {
3328
            $sql = "INSERT INTO " . MAIN_DB_PREFIX . "categorie_fournisseur (fk_categorie, fk_soc) ";
3329
            $sql .= " VALUES (" . ((int)$categorie_id) . ", " . ((int)$this->id) . ")";
3330
3331
            if ($resql = $this->db->query($sql)) {
3332
                return 0;
3333
            }
3334
        } else {
3335
            return 0;
3336
        }
3337
        return -1;
3338
    }
3339
3340
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3341
3342
    /**
3343
     *  Return number of mass Emailing received by this contacts with its email
3344
     *
3345
     * @return       int     Number of EMailings
3346
     */
3347
    public function getNbOfEMailings()
3348
    {
3349
        $sql = "SELECT count(mc.email) as nb";
3350
        $sql .= " FROM " . MAIN_DB_PREFIX . "mailing_cibles as mc, " . MAIN_DB_PREFIX . "mailing as m";
3351
        $sql .= " WHERE mc.fk_mailing=m.rowid AND mc.email = '" . $this->db->escape($this->email) . "' ";
3352
        $sql .= " AND m.entity IN (" . getEntity($this->element) . ") AND mc.statut NOT IN (-1,0)"; // -1 error, 0 not sent, 1 sent with success
3353
3354
        $resql = $this->db->query($sql);
3355
        if ($resql) {
3356
            $obj = $this->db->fetch_object($resql);
3357
            $nb = $obj->nb;
3358
3359
            $this->db->free($resql);
3360
            return $nb;
3361
        } else {
3362
            $this->error = $this->db->error();
3363
            return -1;
3364
        }
3365
    }
3366
3367
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3368
3369
    /**
3370
     *  Create a third party into database from a member object
3371
     *
3372
     * @param Adherent $member Object member
3373
     * @param string $socname Name of third party to force
3374
     * @param string $socalias Alias name of third party to force
3375
     * @param string $customercode Customer code
3376
     * @return int                         Return integer <0 if KO, id of created account if OK
3377
     */
3378
    public function create_from_member(Adherent $member, $socname = '', $socalias = '', $customercode = '')
3379
    {
3380
        // phpcs:enable
3381
        global $conf, $user, $langs;
3382
3383
        dol_syslog(get_only_class($this) . "::create_from_member", LOG_DEBUG);
3384
        $fullname = $member->getFullName($langs);
3385
3386
        if ($member->morphy == 'mor') {
3387
            if (empty($socname)) {
3388
                $socname = $member->company ? $member->company : $member->societe;
3389
            }
3390
            if (!empty($fullname) && empty($socalias)) {
3391
                $socalias = $fullname;
3392
            }
3393
        } elseif (empty($socname) && $member->morphy == 'phy') {
3394
            if (empty($socname)) {
3395
                $socname = $fullname;
3396
            }
3397
            if (!empty($member->company) && empty($socalias)) {
3398
                $socalias = $member->company;
3399
            }
3400
        }
3401
3402
        $name = $socname;
3403
        $alias = $socalias ? $socalias : '';
3404
3405
        // Positionne parameters
3406
        $this->nom = $name; // TODO deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

3406
        /** @scrutinizer ignore-deprecated */ $this->nom = $name; // TODO deprecated

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
3407
        $this->name = $name;
3408
        $this->name_alias = $alias;
3409
        $this->address = $member->address;
3410
        $this->zip = $member->zip;
3411
        $this->town = $member->town;
3412
        $this->country_code = $member->country_code;
3413
        $this->country_id = $member->country_id;
3414
        $this->phone = $member->phone; // Prof phone
3415
        $this->email = $member->email;
3416
        $this->socialnetworks = $member->socialnetworks;
3417
        $this->entity = $member->entity;
3418
3419
        $this->client = 1; // A member is a customer by default
3420
        $this->code_client = ($customercode ? $customercode : -1);
3421
        $this->code_fournisseur = '-1';
3422
        $this->typent_code = ($member->morphy == 'phy' ? 'TE_PRIVATE' : 0);
3423
        $this->typent_id = $this->typent_code ? dol_getIdFromCode($this->db, $this->typent_code, 'c_typent', 'id', 'code') : 0;
3424
3425
        $this->db->begin();
3426
3427
        // Cree et positionne $this->id
3428
        $result = $this->create($user);
3429
3430
        if ($result >= 0) {
3431
            // Auto-create contact on thirdparty creation
3432
            if (getDolGlobalString('THIRDPARTY_DEFAULT_CREATE_CONTACT')) {
3433
                // Fill fields needed by contact
3434
                $this->name_bis = $member->lastname;
3435
                $this->firstname = $member->firstname;
3436
                $this->civility_id = $member->civility_id;
3437
3438
                dol_syslog("We ask to create a contact/address too", LOG_DEBUG);
3439
                $result = $this->create_individual($user);
3440
3441
                if ($result < 0) {
3442
                    setEventMessages($this->error, $this->errors, 'errors');
3443
                    $this->db->rollback();
3444
                    return -1;
3445
                }
3446
            }
3447
3448
            $sql = "UPDATE " . MAIN_DB_PREFIX . "adherent";
3449
            $sql .= " SET fk_soc = " . ((int)$this->id);
3450
            $sql .= " WHERE rowid = " . ((int)$member->id);
3451
3452
            $resql = $this->db->query($sql);
3453
            if ($resql) {
3454
                $this->db->commit();
3455
                return $this->id;
3456
            } else {
3457
                $this->error = $this->db->error();
3458
3459
                $this->db->rollback();
3460
                return -1;
3461
            }
3462
        } else {
3463
            // $this->error deja positionne
3464
            dol_syslog(get_only_class($this) . "::create_from_member - 2 - " . $this->error . " - " . implode(',', $this->errors), LOG_ERR);
3465
3466
            $this->db->rollback();
3467
            return $result;
3468
        }
3469
    }
3470
3471
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3472
3473
    /**
3474
     * Create a contact/address from thirdparty
3475
     *
3476
     * @param User $user Object user
3477
     * @param int $no_email 1=Do not send mailing, 0=Ok to receive mailing
3478
     * @param array $tags Array of tag to affect to contact
3479
     * @param int $notrigger 1=Does not execute triggers, 0= execute triggers
3480
     * @return  int                     Return integer <0 if KO, >0 if OK
3481
     */
3482
    public function create_individual(User $user, $no_email = 0, $tags = array(), $notrigger = 0)
3483
    {
3484
        global $conf;
3485
3486
        $error = 0;
3487
3488
        $this->db->begin();
3489
3490
        $contact = new Contact($this->db);
3491
3492
        $contact->name = $this->name_bis;
3493
        $contact->firstname = $this->firstname;
3494
        $contact->civility_id = $this->civility_id;
3495
        $contact->socid = $this->id; // fk_soc
3496
        $contact->statut = 1; // deprecated
3497
        $contact->status = 1;
3498
        $contact->priv = 0;
3499
        $contact->country_id = $this->country_id;
3500
        $contact->state_id = $this->state_id;
3501
        $contact->address = $this->address;
3502
        $contact->email = $this->email;
3503
        $contact->zip = $this->zip;
3504
        $contact->town = $this->town;
3505
        $this->setUpperOrLowerCase();
3506
        $contact->phone_pro = $this->phone;
3507
3508
        $contactId = $contact->create($user, $notrigger);
3509
        if ($contactId < 0) {
3510
            $error++;
3511
            $this->error = $contact->error;
3512
            $this->errors = $contact->errors;
3513
            dol_syslog(get_only_class($this) . "::create_individual ERROR:" . $this->error, LOG_ERR);
3514
        }
3515
3516
        if (empty($error) && is_array($tags) && !empty($tags)) {
3517
            $result = $contact->setCategories($tags);
3518
            if ($result < 0) {
3519
                $error++;
3520
                $this->error = $contact->error;
3521
                $this->errors = array_merge($this->errors, $contact->errors);
3522
                dol_syslog(get_only_class($this) . "::create_individual Affect Tag ERROR:" . $this->error, LOG_ERR);
3523
                $contactId = $result;
3524
            }
3525
        }
3526
3527
        if (empty($error) && isModEnabled('mailing') && !empty($contact->email) && isset($no_email)) {
3528
            $result = $contact->setNoEmail($no_email);
3529
            if ($result < 0) {
3530
                $this->error = $contact->error;
3531
                $this->errors = array_merge($this->errors, $contact->errors);
3532
                dol_syslog(get_only_class($this) . "::create_individual set mailing status ERROR:" . $this->error, LOG_ERR);
3533
                $contactId = $result;
3534
            }
3535
        }
3536
3537
        if (empty($error)) {
3538
            dol_syslog(get_only_class($this) . "::create_individual success");
3539
            $this->db->commit();
3540
        } else {
3541
            $this->db->rollback();
3542
        }
3543
3544
        return $contactId;
3545
    }
3546
3547
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3548
3549
    /**
3550
     * Sets object to supplied categories.
3551
     *
3552
     * Deletes object from existing categories not supplied.
3553
     * Adds it to non existing supplied categories.
3554
     * Existing categories are left untouch.
3555
     *
3556
     * @param int[]|int $categories Category ID or array of Categories IDs
3557
     * @param string $type_categ Category type ('customer' or 'supplier')
3558
     * @return  int                         Return integer <0 if KO, >0 if OK
3559
     */
3560
    public function setCategories($categories, $type_categ)
3561
    {
3562
        // Decode type
3563
        if (!in_array($type_categ, array(Categorie::TYPE_CUSTOMER, Categorie::TYPE_SUPPLIER))) {
3564
            dol_syslog(__METHOD__ . ': Type ' . $type_categ . 'is an unknown company category type. Done nothing.', LOG_ERR);
3565
            return -1;
3566
        }
3567
3568
        return parent::setCategoriesCommon($categories, $type_categ);
3569
    }
3570
3571
    /**
3572
     *  Set properties with value into $conf
3573
     *
3574
     * @param Conf $conf Conf object (possibility to use another entity)
3575
     * @return void
3576
     */
3577
    public function setMysoc(Conf $conf)
3578
    {
3579
        global $langs;
3580
3581
        $this->id = 0;
3582
        $this->entity = $conf->entity;
3583
        $this->name = getDolGlobalString('MAIN_INFO_SOCIETE_NOM');
3584
        $this->nom = $this->name; // deprecated
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

3584
        /** @scrutinizer ignore-deprecated */ $this->nom = $this->name; // deprecated

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
3585
        $this->address = getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS');
3586
        $this->zip = getDolGlobalString('MAIN_INFO_SOCIETE_ZIP');
3587
        $this->town = getDolGlobalString('MAIN_INFO_SOCIETE_TOWN');
3588
        $this->region_code = getDolGlobalString('MAIN_INFO_SOCIETE_REGION');
3589
3590
        $this->socialobject = getDolGlobalString('MAIN_INFO_SOCIETE_OBJECT');
3591
3592
        $this->note_private = getDolGlobalString('MAIN_INFO_SOCIETE_NOTE');
3593
3594
        // We define country_id, country_code and country
3595
        $country_id = 0;
3596
        $country_code = $country_label = '';
3597
        if (getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY')) {
3598
            $tmp = explode(':', getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY'));
3599
            $country_id = (is_numeric($tmp[0])) ? (int)$tmp[0] : 0;
3600
            if (!empty($tmp[1])) {   // If $conf->global->MAIN_INFO_SOCIETE_COUNTRY is "id:code:label"
3601
                $country_code = $tmp[1];
3602
                $country_label = $tmp[2];
3603
            } else {
3604
                // For backward compatibility
3605
                dol_syslog("Your country setup use an old syntax. Reedit it using setup area.", LOG_WARNING);
3606
                include_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
3607
                $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
3608
                $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
3609
            }
3610
        }
3611
        $this->country_id = $country_id;
3612
        $this->country_code = $country_code;
0 ignored issues
show
Documentation Bug introduced by
It seems like $country_code can also be of type array. However, the property $country_code is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
3613
        $this->country = $country_label;
0 ignored issues
show
Documentation Bug introduced by
It seems like $country_label can also be of type array. However, the property $country is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
3614
        if (is_object($langs)) {
3615
            $this->country = ($langs->trans('Country' . $country_code) != 'Country' . $country_code) ? $langs->trans('Country' . $country_code) : $country_label;
3616
        }
3617
3618
        //TODO This could be replicated for region but function `getRegion` didn't exist, so I didn't added it.
3619
        // We define state_id, state_code and state
3620
        $state_id = 0;
3621
        $state_code = $state_label = '';
3622
        if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) {
3623
            $tmp = explode(':', getDolGlobalString('MAIN_INFO_SOCIETE_STATE'));
3624
            $state_id = $tmp[0];
3625
            if (!empty($tmp[1])) {   // If $conf->global->MAIN_INFO_SOCIETE_STATE is "id:code:label"
3626
                $state_code = $tmp[1];
3627
                $state_label = $tmp[2];
3628
            } else { // For backward compatibility
3629
                dol_syslog("Your setup of State has an old syntax (entity=" . $conf->entity . "). Go in Home - Setup - Organization then Save should remove this error.", LOG_ERR);
3630
                include_once DOL_DOCUMENT_ROOT . '/core/lib/company.lib.php';
3631
                $state_code = getState($state_id, 2, $this->db); // This need a SQL request, but it's the old feature that should not be used anymore
3632
                $state_label = getState($state_id, 0, $this->db); // This need a SQL request, but it's the old feature that should not be used anymore
3633
            }
3634
        }
3635
        $this->state_id = $state_id;
0 ignored issues
show
Documentation Bug introduced by
It seems like $state_id can also be of type string. However, the property $state_id is declared as type integer. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
3636
        $this->state_code = $state_code;
3637
        $this->state = $state_label;
3638
        if (is_object($langs)) {
3639
            $this->state = ($langs->trans('State' . $state_code) != 'State' . $state_code) ? $langs->trans('State' . $state_code) : $state_label;
3640
        }
3641
3642
        $this->phone = getDolGlobalString('MAIN_INFO_SOCIETE_TEL');
3643
        $this->phone_mobile = getDolGlobalString('MAIN_INFO_SOCIETE_MOBILE');
3644
        $this->fax = getDolGlobalString('MAIN_INFO_SOCIETE_FAX');
3645
        $this->url = getDolGlobalString('MAIN_INFO_SOCIETE_WEB');
3646
3647
        // Social networks
3648
        $facebook_url = getDolGlobalString('MAIN_INFO_SOCIETE_FACEBOOK_URL');
3649
        $twitter_url = getDolGlobalString('MAIN_INFO_SOCIETE_TWITTER_URL');
3650
        $linkedin_url = getDolGlobalString('MAIN_INFO_SOCIETE_LINKEDIN_URL');
3651
        $instagram_url = getDolGlobalString('MAIN_INFO_SOCIETE_INSTAGRAM_URL');
3652
        $youtube_url = getDolGlobalString('MAIN_INFO_SOCIETE_YOUTUBE_URL');
3653
        $github_url = getDolGlobalString('MAIN_INFO_SOCIETE_GITHUB_URL');
3654
        $this->socialnetworks = array();
3655
        if (!empty($facebook_url)) {
3656
            $this->socialnetworks['facebook'] = $facebook_url;
3657
        }
3658
        if (!empty($twitter_url)) {
3659
            $this->socialnetworks['twitter'] = $twitter_url;
3660
        }
3661
        if (!empty($linkedin_url)) {
3662
            $this->socialnetworks['linkedin'] = $linkedin_url;
3663
        }
3664
        if (!empty($instagram_url)) {
3665
            $this->socialnetworks['instagram'] = $instagram_url;
3666
        }
3667
        if (!empty($youtube_url)) {
3668
            $this->socialnetworks['youtube'] = $youtube_url;
3669
        }
3670
        if (!empty($github_url)) {
3671
            $this->socialnetworks['github'] = $github_url;
3672
        }
3673
3674
        // Id prof generiques
3675
        $this->idprof1 = getDolGlobalString('MAIN_INFO_SIREN');
3676
        $this->idprof2 = getDolGlobalString('MAIN_INFO_SIRET');
3677
        $this->idprof3 = getDolGlobalString('MAIN_INFO_APE');
3678
        $this->idprof4 = getDolGlobalString('MAIN_INFO_RCS');
3679
        $this->idprof5 = getDolGlobalString('MAIN_INFO_PROFID5');
3680
        $this->idprof6 = getDolGlobalString('MAIN_INFO_PROFID6');
3681
        $this->tva_intra = getDolGlobalString('MAIN_INFO_TVAINTRA'); // VAT number, not necessarily INTRA.
3682
        $this->managers = getDolGlobalString('MAIN_INFO_SOCIETE_MANAGERS');
3683
        $this->capital = is_numeric(getDolGlobalString('MAIN_INFO_CAPITAL')) ? (float)price2num(getDolGlobalString('MAIN_INFO_CAPITAL')) : 0;
3684
        $this->forme_juridique_code = getDolGlobalString('MAIN_INFO_SOCIETE_FORME_JURIDIQUE');
3685
        $this->email = getDolGlobalString('MAIN_INFO_SOCIETE_MAIL');
3686
        $this->default_lang = getDolGlobalString('MAIN_LANG_DEFAULT', 'auto');
3687
        $this->logo = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO');
3688
        $this->logo_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SMALL');
3689
        $this->logo_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_MINI');
3690
        $this->logo_squarred = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED');
3691
        $this->logo_squarred_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_SMALL');
3692
        $this->logo_squarred_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_MINI');
3693
3694
        // Define if company use vat or not
3695
        $this->tva_assuj = getDolGlobalInt('FACTURE_TVAOPTION');
3696
3697
        // Define if company use local taxes
3698
        $this->localtax1_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX1_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')) ? 1 : 0);
3699
        $this->localtax2_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX2_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')) ? 1 : 0);
3700
    }
3701
3702
    /**
3703
     *  Initialise an instance with random values.
3704
     *  Used to build previews or test instances.
3705
     *  id must be 0 if object instance is a specimen.
3706
     *
3707
     * @return int >0 if ok
3708
     */
3709
    public function initAsSpecimen()
3710
    {
3711
        $now = dol_now();
3712
3713
        // Initialize parameters
3714
        $this->id = 0;
3715
        $this->entity = 1;
3716
        $this->name = 'THIRDPARTY SPECIMEN ' . dol_print_date($now, 'dayhourlog');
3717
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

3717
        /** @scrutinizer ignore-deprecated */ $this->nom = $this->name; // For backward compatibility

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
3718
        $this->ref_ext = 'Ref ext';
3719
        $this->specimen = 1;
3720
        $this->address = '21 jump street';
3721
        $this->zip = '99999';
3722
        $this->town = 'MyTown';
3723
        $this->state_id = 1;
3724
        $this->state_code = 'AA';
3725
        $this->state = 'MyState';
3726
        $this->country_id = 1;
3727
        $this->country_code = 'FR';
3728
        $this->email = '[email protected]';
3729
        $this->socialnetworks = array(
3730
            'skype' => 'skypepseudo',
3731
            'twitter' => 'twitterpseudo',
3732
            'facebook' => 'facebookpseudo',
3733
            'linkedin' => 'linkedinpseudo',
3734
        );
3735
        $this->url = 'http://www.specimen.com';
3736
3737
        $this->phone = '0909090901';
3738
        $this->phone_mobile = '0909090901';
3739
        $this->fax = '0909090909';
3740
3741
        $this->code_client = 'CC-' . dol_print_date($now, 'dayhourlog');
3742
        $this->code_fournisseur = 'SC-' . dol_print_date($now, 'dayhourlog');
3743
        $this->capital = 10000;
3744
        $this->client = 1;
3745
        $this->prospect = 1;
3746
        $this->fournisseur = 1;
3747
        $this->tva_assuj = 1;
3748
        $this->tva_intra = 'EU1234567';
3749
        $this->note_public = 'This is a comment (public)';
3750
        $this->note_private = 'This is a comment (private)';
3751
3752
        $this->idprof1 = 'idprof1';
3753
        $this->idprof2 = 'idprof2';
3754
        $this->idprof3 = 'idprof3';
3755
        $this->idprof4 = 'idprof4';
3756
        $this->idprof5 = 'idprof5';
3757
        $this->idprof6 = 'idprof6';
3758
3759
        return 1;
3760
    }
3761
3762
    /**
3763
     *  Check if we must use localtax feature or not according to country (country of $mysoc in most cases).
3764
     *
3765
     * @param int $localTaxNum To get info for only localtax1 or localtax2
3766
     * @return     boolean                 true or false
3767
     */
3768
    public function useLocalTax($localTaxNum = 0)
3769
    {
3770
        $sql = "SELECT t.localtax1, t.localtax2";
3771
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
3772
        $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
3773
        $sql .= " AND t.active = 1";
3774
        $sql .= " AND t.entity IN (" . getEntity('c_tva') . ")";
3775
        if (empty($localTaxNum)) {
3776
            $sql .= " AND (t.localtax1_type <> '0' OR t.localtax2_type <> '0')";
3777
        } elseif ($localTaxNum == 1) {
3778
            $sql .= " AND t.localtax1_type <> '0'";
3779
        } elseif ($localTaxNum == 2) {
3780
            $sql .= " AND t.localtax2_type <> '0'";
3781
        }
3782
3783
        $resql = $this->db->query($sql);
3784
        if ($resql) {
3785
            return ($this->db->num_rows($resql) > 0);
3786
        } else {
3787
            return false;
3788
        }
3789
    }
3790
3791
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3792
3793
    /**
3794
     *  Check if we must use NPR Vat (french stupid rule) or not according to country (country of $mysoc in most cases).
3795
     *
3796
     * @return     boolean                 true or false
3797
     */
3798
    public function useNPR()
3799
    {
3800
        $sql = "SELECT t.rowid";
3801
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
3802
        $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
3803
        $sql .= " AND t.active = 1 AND t.recuperableonly = 1";
3804
        $sql .= " AND t.entity IN (" . getEntity('c_tva') . ")";
3805
3806
        dol_syslog("useNPR", LOG_DEBUG);
3807
        $resql = $this->db->query($sql);
3808
        if ($resql) {
3809
            return ($this->db->num_rows($resql) > 0);
3810
        } else {
3811
            return false;
3812
        }
3813
    }
3814
3815
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3816
3817
    /**
3818
     *  Check if we must use revenue stamps feature or not according to country (country of $mysocin most cases).
3819
     *  Table c_revenuestamp contains the country and value of stamp per invoice.
3820
     *
3821
     * @return     boolean         true or false
3822
     */
3823
    public function useRevenueStamp()
3824
    {
3825
        $sql = "SELECT COUNT(*) as nb";
3826
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_revenuestamp as r, " . MAIN_DB_PREFIX . "c_country as c";
3827
        $sql .= " WHERE r.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
3828
        $sql .= " AND r.active = 1";
3829
3830
        dol_syslog("useRevenueStamp", LOG_DEBUG);
3831
        $resql = $this->db->query($sql);
3832
        if ($resql) {
3833
            $obj = $this->db->fetch_object($resql);
3834
            return (($obj->nb > 0) ? true : false);
3835
        } else {
3836
            $this->error = $this->db->lasterror();
3837
            return false;
3838
        }
3839
    }
3840
3841
    /**
3842
     *  Return prostect level
3843
     *
3844
     * @return     string        Label of prospect status
3845
     */
3846
    public function getLibProspLevel()
3847
    {
3848
        return $this->LibProspLevel($this->fk_prospectlevel);
3849
    }
3850
3851
    /**
3852
     *  Return label of prospect level
3853
     *
3854
     * @param string $fk_prospectlevel Prospect level
3855
     * @return string                          label of level
3856
     */
3857
    public function LibProspLevel($fk_prospectlevel)
3858
    {
3859
        // phpcs:enable
3860
        global $langs;
3861
3862
        $label = '';
3863
        if ($fk_prospectlevel != '') {
3864
            $label = $langs->trans("ProspectLevel" . $fk_prospectlevel);
3865
            // If label is not found in language file, we get label from cache/database
3866
            if ($label == "ProspectLevel" . $fk_prospectlevel) {
3867
                $label = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label');
3868
            }
3869
        }
3870
3871
        return $label;
3872
    }
3873
3874
    /**
3875
     *  Return status of prospect
3876
     *
3877
     * @param int $mode 0=label long, 1=label short, 2=Picto + Label short, 3=Picto, 4=Picto + Label long
3878
     * @param string $label Label to use for status for added status
3879
     * @return string              Label
3880
     */
3881
    public function getLibProspCommStatut($mode = 0, $label = '')
3882
    {
3883
        return $this->LibProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto);
3884
    }
3885
3886
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3887
3888
    /**
3889
     *  Return label of a given status
3890
     *
3891
     * @param int|string $status Id or code for prospection status
3892
     * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short label + Picto
3893
     * @param string $label Label to use for status for added status
3894
     * @param string $picto Name of image file to show ('filenew', ...)
3895
     *                                      If no extension provided, we use '.png'. Image must be stored into theme/xxx/img directory.
3896
     *                                      Example: picto.png                  if picto.png is stored into htdocs/theme/mytheme/img
3897
     *                                      Example: picto.png@mymodule         if picto.png is stored into htdocs/mymodule/img
3898
     *                                      Example: /mydir/mysubdir/picto.png  if picto.png is stored into htdocs/mydir/mysubdir (pictoisfullpath must be set to 1)
3899
     * @return string                      Label of prospection status
3900
     */
3901
    public function LibProspCommStatut($status, $mode = 0, $label = '', $picto = '')
3902
    {
3903
        // phpcs:enable
3904
        global $langs;
3905
3906
        $langs->load('customers');
3907
3908
        if ($mode == 2) {
3909
            if ($status == '-1' || $status == 'ST_NO') {
3910
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect-1");
3911
            } elseif ($status == '0' || $status == 'ST_NEVER') {
3912
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect0");
3913
            } elseif ($status == '1' || $status == 'ST_TODO') {
3914
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect1");
3915
            } elseif ($status == '2' || $status == 'ST_PEND') {
3916
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect2");
3917
            } elseif ($status == '3' || $status == 'ST_DONE') {
3918
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect3");
3919
            } else {
3920
                return img_action(($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label, 0, $picto, 'class="inline-block valignmiddle"') . ' ' . (($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label);
3921
            }
3922
        } elseif ($mode == 3) {
3923
            if ($status == '-1' || $status == 'ST_NO') {
3924
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"');
3925
            } elseif ($status == '0' || $status == 'ST_NEVER') {
3926
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"');
3927
            } elseif ($status == '1' || $status == 'ST_TODO') {
3928
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"');
3929
            } elseif ($status == '2' || $status == 'ST_PEND') {
3930
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"');
3931
            } elseif ($status == '3' || $status == 'ST_DONE') {
3932
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"');
3933
            } else {
3934
                return img_action(($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label, 0, $picto, 'class="inline-block valignmiddle"');
3935
            }
3936
        } elseif ($mode == 4) {
3937
            if ($status == '-1' || $status == 'ST_NO') {
3938
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect-1");
3939
            } elseif ($status == '0' || $status == 'ST_NEVER') {
3940
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect0");
3941
            } elseif ($status == '1' || $status == 'ST_TODO') {
3942
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect1");
3943
            } elseif ($status == '2' || $status == 'ST_PEND') {
3944
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect2");
3945
            } elseif ($status == '3' || $status == 'ST_DONE') {
3946
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect3");
3947
            } else {
3948
                return img_action(($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label, 0, $picto, 'class="inline-block valignmiddle"') . ' ' . (($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label);
3949
            }
3950
        }
3951
3952
        return "Error, mode/status not found";
3953
    }
3954
3955
    /**
3956
     *  Return amount of proposal not yet paid and total an dlist of all proposals
3957
     *
3958
     * @param string $mode 'customer' or 'supplier'
3959
     * @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amount including tax of all object paid or not)
3960
     */
3961
    public function getOutstandingProposals($mode = 'customer')
3962
    {
3963
        $table = 'propal';
3964
        if ($mode == 'supplier') {
3965
            $table = 'supplier_proposal';
3966
        }
3967
3968
        $sql = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM " . MAIN_DB_PREFIX . $table . " as f";
3969
        $sql .= " WHERE fk_soc = " . ((int)$this->id);
3970
        if ($mode == 'supplier') {
3971
            $sql .= " AND entity IN (" . getEntity('supplier_proposal') . ")";
3972
        } else {
3973
            $sql .= " AND entity IN (" . getEntity('propal') . ")";
3974
        }
3975
3976
        dol_syslog("getOutstandingProposals for fk_soc = " . ((int)$this->id), LOG_DEBUG);
3977
3978
        $resql = $this->db->query($sql);
3979
        if ($resql) {
3980
            $outstandingOpened = 0;
3981
            $outstandingTotal = 0;
3982
            $outstandingTotalIncTax = 0;
3983
            $arrayofref = array();
3984
            while ($obj = $this->db->fetch_object($resql)) {
3985
                $arrayofref[$obj->rowid] = $obj->ref;
3986
                $outstandingTotal += $obj->total_ht;
3987
                $outstandingTotalIncTax += $obj->total_ttc;
3988
                if ($obj->status != 0) {
3989
                    // Not a draft
3990
                    $outstandingOpened += $obj->total_ttc;
3991
                }
3992
            }
3993
            return array('opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref); // 'opened' is 'incl taxes'
3994
        } else {
3995
            return array();
3996
        }
3997
    }
3998
3999
    /**
4000
     *  Return amount of order not yet paid and total and list of all orders
4001
     *
4002
     * @param string $mode 'customer' or 'supplier'
4003
     * @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amount including tax of all object paid or not)
4004
     */
4005
    public function getOutstandingOrders($mode = 'customer')
4006
    {
4007
        $table = 'commande';
4008
        if ($mode == 'supplier') {
4009
            $table = 'commande_fournisseur';
4010
        }
4011
4012
        $sql = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM " . MAIN_DB_PREFIX . $table . " as f";
4013
        $sql .= " WHERE fk_soc = " . ((int)$this->id);
4014
        if ($mode == 'supplier') {
4015
            $sql .= " AND entity IN (" . getEntity('supplier_order') . ")";
4016
        } else {
4017
            $sql .= " AND entity IN (" . getEntity('commande') . ")";
4018
        }
4019
4020
        dol_syslog("getOutstandingOrders", LOG_DEBUG);
4021
        $resql = $this->db->query($sql);
4022
        if ($resql) {
4023
            $outstandingOpened = 0;
4024
            $outstandingTotal = 0;
4025
            $outstandingTotalIncTax = 0;
4026
            $arrayofref = array();
4027
            while ($obj = $this->db->fetch_object($resql)) {
4028
                $arrayofref[$obj->rowid] = $obj->ref;
4029
                $outstandingTotal += $obj->total_ht;
4030
                $outstandingTotalIncTax += $obj->total_ttc;
4031
                if ($obj->status != 0) {
4032
                    // Not a draft
4033
                    $outstandingOpened += $obj->total_ttc;
4034
                }
4035
            }
4036
            return array('opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref); // 'opened' is 'incl taxes'
4037
        } else {
4038
            return array();
4039
        }
4040
    }
4041
4042
    /**
4043
     *  Return amount of bill not yet paid and total of all invoices
4044
     *
4045
     * @param string $mode 'customer' or 'supplier'
4046
     * @param int $late 0 => all invoice, 1=> only late
4047
     * @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total amount without tax of all objects paid or not, 'total_ttc'=>Total amount including tax of all object paid or not)
4048
     */
4049
    public function getOutstandingBills($mode = 'customer', $late = 0)
4050
    {
4051
        $table = 'facture';
4052
        if ($mode == 'supplier') {
4053
            $table = 'facture_fourn';
4054
        }
4055
4056
        /* Accurate value of remain to pay is to sum remaintopay for each invoice
4057
         $paiement = $invoice->getSommePaiement();
4058
         $creditnotes=$invoice->getSumCreditNotesUsed();
4059
         $deposits=$invoice->getSumDepositsUsed();
4060
         $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
4061
         $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
4062
         */
4063
        $sql = "SELECT rowid, ref, total_ht, total_ttc, paye, type, fk_statut as status, close_code FROM " . MAIN_DB_PREFIX . $table . " as f";
4064
        $sql .= " WHERE fk_soc = " . ((int)$this->id);
4065
        if (!empty($late)) {
4066
            $sql .= " AND date_lim_reglement < '" . $this->db->idate(dol_now()) . "'";
4067
        }
4068
        if ($mode == 'supplier') {
4069
            $sql .= " AND entity IN (" . getEntity('facture_fourn') . ")";
4070
        } else {
4071
            $sql .= " AND entity IN (" . getEntity('invoice') . ")";
4072
        }
4073
4074
        dol_syslog("getOutstandingBills", LOG_DEBUG);
4075
        $resql = $this->db->query($sql);
4076
        if ($resql) {
4077
            $outstandingOpened = 0;
4078
            $outstandingTotal = 0;
4079
            $outstandingTotalIncTax = 0;
4080
            $arrayofref = array();
4081
            $arrayofrefopened = array();
4082
            if ($mode == 'supplier') {
4083
                $tmpobject = new FactureFournisseur($this->db);
4084
            } else {
4085
                $tmpobject = new Facture($this->db);
4086
            }
4087
            while ($obj = $this->db->fetch_object($resql)) {
4088
                $arrayofref[$obj->rowid] = $obj->ref;
4089
                $tmpobject->id = $obj->rowid;
4090
4091
                if (
4092
                    $obj->status != $tmpobject::STATUS_DRAFT                                           // Not a draft
4093
                    && !($obj->status == $tmpobject::STATUS_ABANDONED && $obj->close_code == 'replaced')  // Not a replaced invoice
4094
                ) {
4095
                    $outstandingTotal += $obj->total_ht;
4096
                    $outstandingTotalIncTax += $obj->total_ttc;
4097
                }
4098
4099
                $remaintopay = 0;
4100
4101
                if (
4102
                    $obj->paye == 0
4103
                    && $obj->status != $tmpobject::STATUS_DRAFT         // Not a draft
4104
                    && $obj->status != $tmpobject::STATUS_ABANDONED     // Not abandoned
4105
                    && $obj->status != $tmpobject::STATUS_CLOSED
4106
                ) {     // Not classified as paid
4107
                    //$sql .= " AND (status <> 3 OR close_code <> 'abandon')";      // Not abandoned for undefined reason
4108
                    $paiement = $tmpobject->getSommePaiement();
4109
                    $creditnotes = $tmpobject->getSumCreditNotesUsed();
4110
                    $deposits = $tmpobject->getSumDepositsUsed();
4111
4112
                    $remaintopay = ($obj->total_ttc - $paiement - $creditnotes - $deposits);
4113
                    $outstandingOpened += $remaintopay;
4114
                }
4115
4116
                //if credit note is converted but not used
4117
                // TODO Do this also for customer ?
4118
                if ($mode == 'supplier' && $obj->type == FactureFournisseur::TYPE_CREDIT_NOTE && $tmpobject->isCreditNoteUsed()) {
0 ignored issues
show
Bug introduced by
The method isCreditNoteUsed() does not exist on Dolibarr\Code\Compta\Classes\Facture. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

4118
                if ($mode == 'supplier' && $obj->type == FactureFournisseur::TYPE_CREDIT_NOTE && $tmpobject->/** @scrutinizer ignore-call */ isCreditNoteUsed()) {
Loading history...
4119
                    $remainingcreditnote = $tmpobject->getSumFromThisCreditNotesNotUsed();
4120
                    $remaintopay -= $remainingcreditnote;
4121
                    $outstandingOpened -= $remainingcreditnote;
4122
                }
4123
4124
                if ($remaintopay) {
4125
                    $arrayofrefopened[$obj->rowid] = $obj->ref;
4126
                }
4127
            }
4128
            return array('opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref, 'refsopened' => $arrayofrefopened); // 'opened' is 'incl taxes'
4129
        } else {
4130
            dol_syslog("Sql error " . $this->db->lasterror, LOG_ERR);
4131
            return array();
4132
        }
4133
    }
4134
4135
    /**
4136
     * Return label of status customer is prospect/customer
4137
     *
4138
     * @return   string         Label
4139
     * @see getTypeUrl()
4140
     */
4141
    public function getLibCustProspStatut()
4142
    {
4143
        return $this->LibCustProspStatut($this->client);
4144
    }
4145
4146
    /**
4147
     *  Return the label of the customer/prospect status
4148
     *
4149
     * @param int $status Id of prospection status
4150
     * @return string                  Label of prospection status
4151
     */
4152
    public function LibCustProspStatut($status)
4153
    {
4154
        // phpcs:enable
4155
        global $langs;
4156
        $langs->load('companies');
4157
4158
        if ($status == 0) {
4159
            return $langs->trans("NorProspectNorCustomer");
4160
        } elseif ($status == 1) {
4161
            return $langs->trans("Customer");
4162
        } elseif ($status == 2) {
4163
            return $langs->trans("Prospect");
4164
        } elseif ($status == 3) {
4165
            return $langs->trans("ProspectCustomer");
4166
        }
4167
4168
        return '';
4169
    }
4170
4171
    /**
4172
     *  Create a document onto disk according to template module.
4173
     *
4174
     * @param string $modele Generator to use. Caller must set it to obj->model_pdf.
4175
     * @param Translate $outputlangs object lang a utiliser pour traduction
4176
     * @param int $hidedetails Hide details of lines
4177
     * @param int $hidedesc Hide description
4178
     * @param int $hideref Hide ref
4179
     * @param null|array $moreparams Array to provide more information
4180
     * @return int                         Return integer <0 if KO, >0 if OK
4181
     */
4182
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
4183
    {
4184
        global $langs;
4185
4186
        if (!empty($moreparams) && !empty($moreparams['use_companybankid'])) {
4187
            $modelpath = "core/modules/bank/doc/";
4188
4189
            include_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
4190
            $companybankaccount = new CompanyBankAccount($this->db);
4191
            $result = $companybankaccount->fetch($moreparams['use_companybankid']);
4192
            if (!$result) {
4193
                dol_print_error($this->db, $companybankaccount->error, $companybankaccount->errors);
4194
            }
4195
            $result = $companybankaccount->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4196
            $this->last_main_doc = $companybankaccount->last_main_doc;
4197
        } else {
4198
            // Positionne le modele sur le nom du modele a utiliser
4199
            if (!dol_strlen($modele)) {
4200
                if (getDolGlobalString('COMPANY_ADDON_PDF')) {
4201
                    $modele = getDolGlobalString('COMPANY_ADDON_PDF');
4202
                } else {
4203
                    print $langs->trans("Error") . " " . $langs->trans("Error_COMPANY_ADDON_PDF_NotDefined");
4204
                    return 0;
4205
                }
4206
            }
4207
4208
            if (!isset($this->bank_account)) {
4209
                $bac = new CompanyBankAccount($this->db);
4210
                // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
4211
                $result = $bac->fetch(0, '', $this->id);
4212
                if ($result > 0) {
4213
                    $this->bank_account = $bac;
4214
                } else {
4215
                    $this->bank_account = '';
4216
                }
4217
            }
4218
4219
            $modelpath = "core/modules/societe/doc/";
4220
4221
            $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4222
        }
4223
4224
        return $result;
4225
    }
4226
4227
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4228
4229
    /**
4230
     * Sets sales representatives of the thirdparty
4231
     *
4232
     * @param int[]|int $salesrep User ID or array of user IDs
4233
     * @param bool $onlyAdd Only add (no delete before)
4234
     * @return  int                         Return integer <0 if KO, >0 if OK
4235
     */
4236
    public function setSalesRep($salesrep, $onlyAdd = false)
4237
    {
4238
        global $user;
4239
4240
        // Handle single user
4241
        if (!is_array($salesrep)) {
4242
            $salesrep = array($salesrep);
4243
        }
4244
4245
        $to_del = array(); // Nothing to delete
4246
        $to_add = $salesrep;
4247
        if ($onlyAdd === false) {
4248
            // Get current users
4249
            $existing = $this->getSalesRepresentatives($user, 1);
4250
4251
            // Diff
4252
            if (is_array($existing)) {
4253
                $to_del = array_diff($existing, $salesrep);
4254
                $to_add = array_diff($salesrep, $existing);
4255
            }
4256
        }
4257
4258
        $error = 0;
4259
4260
        // Process
4261
        foreach ($to_del as $del) {
4262
            $this->del_commercial($user, $del);
4263
        }
4264
        foreach ($to_add as $add) {
4265
            $result = $this->add_commercial($user, $add);
4266
            if ($result < 0) {
4267
                $error++;
4268
                break;
4269
            }
4270
        }
4271
4272
        return $error ? -1 : 1;
4273
    }
4274
4275
    /**
4276
     *  Return array of sales representatives
4277
     *
4278
     * @param User $user Object user (not used)
4279
     * @param int $mode 0=Array with properties, 1=Array of IDs.
4280
     * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb'
4281
     * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC';
4282
     * @return array|int                   Array of sales representatives of the current third party or <0 if KO
4283
     */
4284
    public function getSalesRepresentatives(User $user, $mode = 0, $sortfield = null, $sortorder = null)
4285
    {
4286
        global $conf;
4287
4288
        $reparray = array();
4289
4290
        $sql = "SELECT u.rowid, u.login, u.lastname, u.firstname, u.office_phone, u.job, u.email, u.statut as status, u.entity, u.photo, u.gender";
4291
        $sql .= ", u.office_fax, u.user_mobile, u.personal_mobile";
4292
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_commerciaux as sc, " . MAIN_DB_PREFIX . "user as u";
4293
        // Condition here should be the same than into select_dolusers()
4294
        if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
4295
            $sql .= " WHERE u.rowid IN (SELECT ug.fk_user FROM " . $this->db->prefix() . "usergroup_user as ug WHERE ug.entity IN (" . getEntity('usergroup') . "))";
4296
        } else {
4297
            $sql .= " WHERE entity IN (0, " . $this->db->sanitize($conf->entity) . ")";
4298
        }
4299
4300
        $sql .= " AND u.rowid = sc.fk_user AND sc.fk_soc = " . ((int)$this->id);
4301
        if (empty($sortfield) && empty($sortorder)) {
4302
            $sortfield = 'u.lastname,u.firstname';
4303
            $sortorder = 'ASC,ASC';
4304
        }
4305
        $sql .= $this->db->order($sortfield, $sortorder);
4306
4307
        $resql = $this->db->query($sql);
4308
        if ($resql) {
4309
            $num = $this->db->num_rows($resql);
4310
            $i = 0;
4311
            while ($i < $num) {
4312
                $obj = $this->db->fetch_object($resql);
4313
4314
                if (empty($mode)) {
4315
                    $reparray[$i]['id'] = $obj->rowid;
4316
                    $reparray[$i]['lastname'] = $obj->lastname;
4317
                    $reparray[$i]['firstname'] = $obj->firstname;
4318
                    $reparray[$i]['email'] = $obj->email;
4319
                    $reparray[$i]['phone'] = $obj->office_phone;
4320
                    $reparray[$i]['office_phone'] = $obj->office_phone;         // Pro phone
4321
                    $reparray[$i]['office_fax'] = $obj->office_fax;
4322
                    $reparray[$i]['user_mobile'] = $obj->user_mobile;           // Pro mobile
4323
                    $reparray[$i]['personal_mobile'] = $obj->personal_mobile;   // Personal mobile
4324
                    $reparray[$i]['job'] = $obj->job;
4325
                    $reparray[$i]['statut'] = $obj->status; // deprecated
4326
                    $reparray[$i]['status'] = $obj->status;
4327
                    $reparray[$i]['entity'] = $obj->entity;
4328
                    $reparray[$i]['login'] = $obj->login;
4329
                    $reparray[$i]['photo'] = $obj->photo;
4330
                    $reparray[$i]['gender'] = $obj->gender;
4331
                } else {
4332
                    $reparray[] = $obj->rowid;
4333
                }
4334
                $i++;
4335
            }
4336
            return $reparray;
4337
        } else {
4338
            dol_print_error($this->db);
4339
            return -1;
4340
        }
4341
    }
4342
4343
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4344
4345
    /**
4346
     *  Add link to sales representative
4347
     *
4348
     * @param User $user Object user
4349
     * @param int $commid Id of user
4350
     * @return int                 Return <0 if KO, >0 if OK
4351
     */
4352
    public function del_commercial(User $user, $commid)
4353
    {
4354
        // phpcs:enable
4355
        $error = 0;
4356
        $this->context = array('commercial_modified' => $commid);
4357
4358
        $result = $this->call_trigger('COMPANY_UNLINK_SALE_REPRESENTATIVE', $user);
4359
        if ($result < 0) {
4360
            $error++;
4361
        }
4362
4363
        if ($this->id > 0 && $commid > 0) {
4364
            $sql = "DELETE FROM  " . MAIN_DB_PREFIX . "societe_commerciaux ";
4365
            $sql .= " WHERE fk_soc = " . ((int)$this->id) . " AND fk_user = " . ((int)$commid);
4366
4367
            if (!$this->db->query($sql)) {
4368
                $error++;
4369
                dol_syslog(get_only_class($this) . "::del_commercial Erreur");
4370
            }
4371
        }
4372
4373
        if ($error) {
4374
            return -1;
4375
        } else {
4376
            return 1;
4377
        }
4378
    }
4379
4380
    /**
4381
     *    Define third-party type of current company
4382
     *
4383
     * @param int $typent_id third party type rowid in llx_c_typent
4384
     * @return   int                 Return integer <0 if KO, >0 if OK
4385
     */
4386
    public function setThirdpartyType($typent_id)
4387
    {
4388
        global $user;
4389
4390
        dol_syslog(__METHOD__, LOG_DEBUG);
4391
4392
        if ($this->id) {
4393
            $result = $this->setValueFrom('fk_typent', $typent_id, '', null, '', '', $user, 'COMPANY_MODIFY');
4394
4395
            if ($result > 0) {
4396
                $this->typent_id = $typent_id;
4397
                $this->typent_code = dol_getIdFromCode($this->db, $this->typent_id, 'c_typent', 'id', 'code');
4398
                return 1;
4399
            } else {
4400
                return -1;
4401
            }
4402
        } else {
4403
            return -1;
4404
        }
4405
    }
4406
4407
    /**
4408
     * Sets an accountancy code for a thirdparty.
4409
     * Also calls COMPANY_MODIFY trigger when modified
4410
     *
4411
     * @param string $type It can be only 'buy' or 'sell'
4412
     * @param string $value Accountancy code
4413
     * @return  int             Return integer <0 KO >0 OK
4414
     */
4415
    public function setAccountancyCode($type, $value)
4416
    {
4417
        global $user, $langs, $conf;
4418
4419
        $this->db->begin();
4420
4421
        if ($type == 'buy') {
4422
            $field = 'accountancy_code_buy';
4423
        } elseif ($type == 'sell') {
4424
            $field = 'accountancy_code_sell';
4425
        } else {
4426
            return -1;
4427
        }
4428
4429
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET ";
4430
        $sql .= $field . " = '" . $this->db->escape($value) . "'";
4431
        $sql .= " WHERE rowid = " . ((int)$this->id);
4432
4433
        dol_syslog(get_only_class($this) . "::" . __FUNCTION__, LOG_DEBUG);
4434
        $resql = $this->db->query($sql);
4435
4436
        if ($resql) {
4437
            // Call triggers
4438
            $interface = new Interfaces($this->db);
4439
            $result = $interface->run_triggers('COMPANY_MODIFY', $this, $user, $langs, $conf);
4440
            if ($result < 0) {
4441
                $this->errors = $interface->errors;
4442
                $this->db->rollback();
4443
                return -1;
4444
            }
4445
            // End call triggers
4446
4447
            $this->$field = $value;
4448
4449
            $this->db->commit();
4450
            return 1;
4451
        } else {
4452
            $this->error = $this->db->lasterror();
4453
            $this->db->rollback();
4454
            return -1;
4455
        }
4456
    }
4457
4458
    /**
4459
     *  Function to get partnerships array
4460
     *
4461
     * @param string $mode 'member' or 'thirdparty'
4462
     * @return     int                     Return integer <0 if KO, >0 if OK
4463
     */
4464
    public function fetchPartnerships($mode)
4465
    {
4466
        global $langs;
4467
4468
        $this->partnerships[] = array();
4469
4470
        return 1;
4471
    }
4472
4473
    /**
4474
     *  Return clicable link of object (with eventually picto)
4475
     *
4476
     * @param string $option Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
4477
     * @param array $arraydata Array of data
4478
     * @return     string                              HTML Code for Kanban thumb.
4479
     */
4480
    public function getKanbanView($option = '', $arraydata = array())
4481
    {
4482
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
4483
4484
        $return = '<div class="box-flex-item box-flex-grow-zero">';
4485
        $return .= '<div class="info-box info-box-sm">';
4486
        $return .= '<span class="info-box-icon bg-infobox-action">';
4487
        $return .= img_picto('', $this->picto);
4488
        $return .= '</span>';
4489
        $return .= '<div class="info-box-content">';
4490
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref) . '</span>';
4491
        if ($selected >= 0) {
4492
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
4493
        }
4494
        if (property_exists($this, 'code_client')) {
4495
            $return .= '<br><span class="info-box-label opacitymedium">' . $this->code_client . '</span>';
4496
        }
4497
        if (method_exists($this, 'getLibStatut')) {
4498
            $return .= '<br><div class="info-box-status">' . $this->getLibStatut(3) . '</div>';
4499
        }
4500
        $return .= '</div>';
4501
        $return .= '</div>';
4502
        $return .= '</div>';
4503
4504
        return $return;
4505
    }
4506
4507
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4508
4509
    /**
4510
     *      Return a link on thirdparty (with picto)
4511
     *
4512
     * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
4513
     * @param string $option Target of link ('', 'customer', 'prospect', 'supplier', 'project')
4514
     * @param int $maxlen Max length of name
4515
     * @param int $notooltip 1=Disable tooltip
4516
     * @param int $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save lastsearch_values whenclicking
4517
     * @param int $noaliasinname 1=Do not add alias into the link ref
4518
     * @param string $target add attribute target
4519
     * @param string $morecss More CSS
4520
     * @return string                              String with URL
4521
     */
4522
    public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '', $morecss = '')
4523
    {
4524
        global $conf, $langs, $hookmanager, $user;
4525
4526
        if (!empty($conf->dol_no_mouse_hover)) {
4527
            $notooltip = 1; // Force disable tooltips
4528
        }
4529
4530
        $name = $this->name ? $this->name : $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property Dolibarr\Code\Societe\Classes\Societe::$nom has been deprecated: Use $name instead ( Ignorable by Annotation )

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

4530
        $name = $this->name ? $this->name : /** @scrutinizer ignore-deprecated */ $this->nom;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
4531
4532
        if (getDolGlobalString('SOCIETE_ON_SEARCH_AND_LIST_GO_ON_CUSTOMER_OR_SUPPLIER_CARD')) {
4533
            if (empty($option) && $this->client > 0) {
4534
                $option = 'customer';
4535
            }
4536
            if (empty($option) && $this->fournisseur > 0) {
4537
                $option = 'supplier';
4538
            }
4539
        }
4540
4541
        if (getDolGlobalString('SOCIETE_ADD_REF_IN_LIST') && (!empty($withpicto))) {
4542
            $code = '';
4543
            if (($this->client) && (!empty($this->code_client)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 2)) {
4544
                $code = $this->code_client . ' - ';
4545
            }
4546
4547
            if (($this->fournisseur) && (!empty($this->code_fournisseur)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 3)) {
4548
                $code .= $this->code_fournisseur . ' - ';
4549
            }
4550
4551
            if ($code) {
4552
                if (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1) {
4553
                    $name = $code . ' ' . $name;
4554
                } else {
4555
                    $name = $code;
4556
                }
4557
            }
4558
        }
4559
4560
        if (!empty($this->name_alias) && empty($noaliasinname)) {
4561
            $name .= ' (' . $this->name_alias . ')';
4562
        }
4563
4564
        $result = '';
4565
        $params = [
4566
            'id' => $this->id,
4567
            'objecttype' => $this->element,
4568
            'option' => $option,
4569
            'nofetch' => 1,
4570
        ];
4571
        $classfortooltip = 'classfortooltip';
4572
        $dataparams = '';
4573
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
4574
            $classfortooltip = 'classforajaxtooltip';
4575
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
4576
            $label = '';
4577
        } else {
4578
            $label = implode($this->getTooltipContentArray($params));
4579
        }
4580
4581
        $linkstart = '';
4582
        $linkend = '';
4583
4584
        if ($option == 'customer' || $option == 'compta' || $option == 'category') {
4585
            $linkstart = '<a href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id;
4586
        } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
4587
            $linkstart = '<a href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id;
4588
        } elseif ($option == 'supplier' || $option == 'category_supplier') {
4589
            $linkstart = '<a href="' . constant('BASE_URL') . '/fourn/card.php?socid=' . $this->id;
4590
        } elseif ($option == 'agenda') {
4591
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/agenda.php?socid=' . $this->id;
4592
        } elseif ($option == 'project') {
4593
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/project.php?socid=' . $this->id;
4594
        } elseif ($option == 'margin') {
4595
            $linkstart = '<a href="' . constant('BASE_URL') . '/margin/tabs/thirdpartyMargins.php?socid=' . $this->id . '&type=1';
4596
        } elseif ($option == 'contact') {
4597
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/contact.php?socid=' . $this->id;
4598
        } elseif ($option == 'ban') {
4599
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/paymentmodes.php?socid=' . $this->id;
4600
        }
4601
4602
        // By default
4603
        if (empty($linkstart)) {
4604
            $linkstart = '<a href="' . constant('BASE_URL') . '/societe/card.php?socid=' . $this->id;
4605
        }
4606
4607
        // Add type of canvas
4608
        $linkstart .= (!empty($this->canvas) ? '&canvas=' . $this->canvas : '');
4609
        // Add param to save lastsearch_values or not
4610
        $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
4611
        if ($save_lastsearch_value == -1 && isset($_SERVER["PHP_SELF"]) && preg_match('/list\.php/', $_SERVER["PHP_SELF"])) {
4612
            $add_save_lastsearch_values = 1;
4613
        }
4614
        if ($add_save_lastsearch_values) {
4615
            $linkstart .= '&save_lastsearch_values=1';
4616
        }
4617
        $linkstart .= '"';
4618
4619
        $linkclose = '';
4620
        if (empty($notooltip)) {
4621
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
4622
                $label = $langs->trans("ShowCompany");
4623
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
4624
            }
4625
            $linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
4626
            $linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . ' refurl valignmiddle"';
4627
            $target_value = array('_self', '_blank', '_parent', '_top');
4628
            if (in_array($target, $target_value)) {
4629
                $linkclose .= ' target="' . dol_escape_htmltag($target) . '"';
4630
            }
4631
        } else {
4632
            $linkclose .= ' class="valignmiddle' . ($morecss ? ' ' . $morecss : '') . '"';
4633
        }
4634
        $linkstart .= $linkclose . '>';
4635
        $linkend = '</a>';
4636
4637
        if (!$user->hasRight('societe', 'client', 'voir') && $user->socid > 0 && $this->id != $user->socid) {
4638
            $linkstart = '';
4639
            $linkend = '';
4640
        }
4641
4642
        $result .= $linkstart;
4643
        if ($withpicto) {
4644
            $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (' class="' . (($withpicto != 2) ? 'paddingright' : '') . '"'), 0, 0, $notooltip ? 0 : 1);
4645
        }
4646
        if ($withpicto != 2) {
4647
            $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
4648
        }
4649
        $result .= $linkend;
4650
4651
        global $action;
4652
        $hookmanager->initHooks(array('thirdpartydao'));
4653
        $parameters = array(
4654
            'id' => $this->id,
4655
            'getnomurl' => &$result,
4656
            'withpicto ' => $withpicto,
4657
            'option' => $option,
4658
            'maxlen' => $maxlen,
4659
            'notooltip' => $notooltip,
4660
            'save_lastsearch_value' => $save_lastsearch_value
4661
        );
4662
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4663
        if ($reshook > 0) {
4664
            $result = $hookmanager->resPrint;
4665
        } else {
4666
            $result .= $hookmanager->resPrint;
4667
        }
4668
4669
        return $result;
4670
    }
4671
4672
    /**
4673
     * getTooltipContentArray
4674
     *
4675
     * @param array $params params to construct tooltip data
4676
     * @return array
4677
     * @since v18
4678
     */
4679
    public function getTooltipContentArray($params)
4680
    {
4681
        global $conf, $langs, $user;
4682
4683
        $langs->loadLangs(['companies', 'commercial']);
4684
4685
        $datas = array();
4686
4687
        $option = $params['option'] ?? '';
4688
        $nofetch = !empty($params['nofetch']);
4689
4690
        $noaliasinname = (empty($params['noaliasinname']) ? 0 : $params['noaliasinname']);
4691
4692
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
4693
            return ['optimize' => $langs->trans("ShowCompany")];
4694
        }
4695
4696
        if (!empty($this->logo) && class_exists('Form')) {
4697
            $photo = '<div class="photointooltip floatright">';
4698
            $photo .= Form::showphoto('societe', $this, 0, 40, 0, 'photoref', '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.
4699
            $photo .= '</div>';
4700
            $datas['photo'] = $photo;
4701
        } elseif (!empty($this->logo_squarred) && class_exists('Form')) {
4702
            /*$label.= '<div class="photointooltip">';
4703
            $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.
4704
            $label.= '</div><div style="clear: both;"></div>';*/
4705
        }
4706
4707
        $datas['divopen'] = '<div class="centpercent">';
4708
4709
        if ($option == 'customer' || $option == 'compta' || $option == 'category') {
4710
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Customer") . '</u>';
4711
        } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
4712
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Prospect") . '</u>';
4713
        } elseif ($option == 'supplier' || $option == 'category_supplier') {
4714
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Supplier") . '</u>';
4715
        } elseif ($option == 'agenda') {
4716
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4717
        } elseif ($option == 'project') {
4718
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4719
        } elseif ($option == 'margin') {
4720
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4721
        } elseif ($option == 'contact') {
4722
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4723
        } elseif ($option == 'ban') {
4724
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4725
        }
4726
4727
        // By default
4728
        if (empty($datas['picto'])) {
4729
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4730
        }
4731
        if (isset($this->status)) {
4732
            $datas['status'] = ' ' . $this->getLibStatut(5);
4733
        }
4734
        if (isset($this->client) && isset($this->fournisseur)) {
4735
            $datas['type'] = ' &nbsp; ' . $this->getTypeUrl(1);
4736
        }
4737
        $datas['name'] = '<br><b>' . $langs->trans('Name') . ':</b> ' . dol_escape_htmltag(dol_string_nohtmltag($this->name));
4738
        if (!empty($this->name_alias) && empty($noaliasinname)) {
4739
            $datas['namealias'] = ' (' . dol_escape_htmltag(dol_string_nohtmltag($this->name_alias)) . ')';
4740
        }
4741
        if (!empty($this->email)) {
4742
            $datas['email'] = '<br>' . img_picto('', 'email', 'class="pictofixedwidth"') . $this->email;
4743
        }
4744
        if (!empty($this->url)) {
4745
            $datas['url'] = '<br>' . img_picto('', 'globe', 'class="pictofixedwidth"') . $this->url;
4746
        }
4747
        if (!empty($this->phone) || !empty($this->phone_mobile) || !empty($this->fax)) {
4748
            $phonelist = array();
4749
            if ($this->phone) {
4750
                $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', '&nbsp', 'phone');
4751
            }
4752
            // deliberately not making new list because fax uses same list as phone
4753
            if ($this->phone_mobile) {
4754
                $phonelist[] = dol_print_phone($this->phone_mobile, $this->country_code, $this->id, 0, '', '&nbsp', 'phone_mobile');
4755
            }
4756
            if ($this->fax) {
4757
                $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', '&nbsp', 'fax');
4758
            }
4759
            $datas['phonelist'] = '<br>' . implode('&nbsp;', $phonelist);
4760
        }
4761
4762
        if (!empty($this->address)) {
4763
            $datas['address'] = '<br><b>' . $langs->trans("Address") . ':</b> ' . dol_format_address($this, 1, ' ', $langs); // Address + country
4764
        } elseif (!empty($this->country_code)) {
4765
            $datas['address'] = '<br><b>' . $langs->trans('Country') . ':</b> ' . $this->country_code;
4766
        }
4767
        if (!empty($this->tva_intra) || (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP') && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) {
4768
            $datas['vatintra'] = '<br><b>' . $langs->trans('VATIntra') . ':</b> ' . dol_escape_htmltag($this->tva_intra);
4769
        }
4770
4771
        if (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP')) {
4772
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false && $langs->trans('ProfId1' . $this->country_code) != '-') {
4773
                $datas['profid1'] = '<br><b>' . $langs->trans('ProfId1' . $this->country_code) . ':</b> ' . $this->idprof1;
4774
            }
4775
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false && $langs->trans('ProfId2' . $this->country_code) != '-') {
4776
                $datas['profid2'] = '<br><b>' . $langs->trans('ProfId2' . $this->country_code) . ':</b> ' . $this->idprof2;
4777
            }
4778
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false && $langs->trans('ProfId3' . $this->country_code) != '-') {
4779
                $datas['profid3'] = '<br><b>' . $langs->trans('ProfId3' . $this->country_code) . ':</b> ' . $this->idprof3;
4780
            }
4781
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false && $langs->trans('ProfId4' . $this->country_code) != '-') {
4782
                $datas['profid4'] = '<br><b>' . $langs->trans('ProfId4' . $this->country_code) . ':</b> ' . $this->idprof4;
4783
            }
4784
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false && $langs->trans('ProfId5' . $this->country_code) != '-') {
4785
                $datas['profid5'] = '<br><b>' . $langs->trans('ProfId5' . $this->country_code) . ':</b> ' . $this->idprof5;
4786
            }
4787
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false && $langs->trans('ProfId6' . $this->country_code) != '-') {
4788
                $datas['profid6'] = '<br><b>' . $langs->trans('ProfId6' . $this->country_code) . ':</b> ' . $this->idprof6;
4789
            }
4790
        }
4791
4792
        $datas['separator'] = '<br>';
4793
4794
        if (!empty($this->code_client) && ($this->client == 1 || $this->client == 3)) {
4795
            $datas['customercode'] = '<br><b>' . $langs->trans('CustomerCode') . ':</b> ' . $this->code_client;
4796
        }
4797
        if (isModEnabled('accounting') && ($this->client == 1 || $this->client == 3)) {
4798
            $langs->load('compta');
4799
            $datas['accountancycustomercode'] = '<br><b>' . $langs->trans('CustomerAccountancyCode') . ':</b> ' . ($this->code_compta ? $this->code_compta : $this->code_compta_client);
4800
        }
4801
        // show categories for this record only in ajax to not overload lists
4802
        if (!$nofetch && isModEnabled('category') && $this->client) {
4803
            $form = new Form($this->db);
4804
            $datas['categories_customer'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_CUSTOMER, 1, 1);
4805
        }
4806
        if (!empty($this->code_fournisseur) && $this->fournisseur) {
4807
            $datas['suppliercode'] = '<br><b>' . $langs->trans('SupplierCode') . ':</b> ' . $this->code_fournisseur;
4808
        }
4809
        if (isModEnabled('accounting') && $this->fournisseur) {
4810
            $langs->load('compta');
4811
            $datas['accountancysuppliercode'] = '<br><b>' . $langs->trans('SupplierAccountancyCode') . ':</b> ' . $this->code_compta_fournisseur;
4812
        }
4813
        // show categories for this record only in ajax to not overload lists
4814
        if (!$nofetch && isModEnabled('category') && $this->fournisseur) {
4815
            $form = new Form($this->db);
4816
            $datas['categories_supplier'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_SUPPLIER, 1, 1);
4817
        }
4818
4819
        $datas['divclose'] = '</div>';
4820
4821
        return $datas;
4822
    }
4823
4824
    /**
4825
     *    Return label of status (activity, closed)
4826
     *
4827
     * @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
4828
     * @return   string              Label of status
4829
     */
4830
    public function getLibStatut($mode = 0)
4831
    {
4832
        return $this->LibStatut($this->status, $mode);
4833
    }
4834
4835
    /**
4836
     *  Return the label of a given status
4837
     *
4838
     * @param int $status Status id
4839
     * @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
4840
     * @return string                  Status label
4841
     */
4842
    public function LibStatut($status, $mode = 0)
4843
    {
4844
        // phpcs:enable
4845
        global $langs;
4846
        $langs->load('companies');
4847
4848
        $statusType = 'status4';
4849
        if ($status == 0) {
4850
            $statusType = 'status6';
4851
        }
4852
4853
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
4854
            $this->labelStatus[0] = $langs->transnoentitiesnoconv("ActivityCeased");
4855
            $this->labelStatus[1] = $langs->transnoentitiesnoconv("InActivity");
4856
            $this->labelStatusShort[0] = $langs->transnoentitiesnoconv("ActivityCeased");
4857
            $this->labelStatusShort[1] = $langs->transnoentitiesnoconv("InActivity");
4858
        }
4859
4860
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
4861
    }
4862
4863
    /**
4864
     *      Return link(s) on type of thirdparty (with picto)
4865
     *
4866
     * @param int $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
4867
     * @param string $option ''=All
4868
     * @param int $notooltip 1=Disable tooltip
4869
     * @param string $tag Tag 'a' or 'span'
4870
     * @return string                          String with URL
4871
     */
4872
    public function getTypeUrl($withpicto = 0, $option = '', $notooltip = 0, $tag = 'a')
4873
    {
4874
        global $conf, $langs;
4875
4876
        $s = '';
4877
        if (empty($option) || preg_match('/prospect/', $option)) {
4878
            if (($this->client == 2 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
4879
                $s .= '<' . $tag . ' class="customer-back opacitymedium" title="' . $langs->trans("Prospect") . '" href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Prospect"), 0, 1) . '</' . $tag . '>';
4880
            }
4881
        }
4882
        if (empty($option) || preg_match('/customer/', $option)) {
4883
            if (($this->client == 1 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_CUSTOMERS')) {
4884
                $s .= '<' . $tag . ' class="customer-back" title="' . $langs->trans("Customer") . '" href="' . constant('BASE_URL') . '/comm/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Customer"), 0, 1) . '</' . $tag . '>';
4885
            }
4886
        }
4887
        if (empty($option) || preg_match('/supplier/', $option)) {
4888
            if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $this->fournisseur) {
4889
                $s .= '<' . $tag . ' class="vendor-back" title="' . $langs->trans("Supplier") . '" href="' . constant('BASE_URL') . '/fourn/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Supplier"), 0, 1) . '</' . $tag . '>';
4890
            }
4891
        }
4892
        return $s;
4893
    }
4894
4895
    /**
4896
     *    Get array of all contacts for a society (stored in societe_contacts instead of element_contacts for all other objects)
4897
     *
4898
     * @param int $list 0:Return array contains all properties, 1:Return array contains just id
4899
     * @param string $code Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
4900
     * @param string $element Filter on this element of default contact type ('facture', 'propal', 'commande' ...)
4901
     * @return   array|int               Array of contacts, -1 if error
4902
     *
4903
     */
4904
    public function getContacts($list = 0, $code = '', $element = '')
4905
    {
4906
        // phpcs:enable
4907
        global $langs;
4908
4909
        $tab = array();
4910
4911
        $sql = "SELECT sc.rowid, sc.fk_socpeople as id, sc.fk_c_type_contact"; // This field contains id of llx_socpeople or id of llx_user
4912
        $sql .= ", t.fk_soc as socid, t.statut as statuscontact";
4913
        $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email";
4914
        $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label";
4915
        $sql .= " FROM " . $this->db->prefix() . "c_type_contact tc";
4916
        $sql .= ", " . $this->db->prefix() . "societe_contacts sc";
4917
        $sql .= " LEFT JOIN " . $this->db->prefix() . "socpeople t on sc.fk_socpeople = t.rowid";
4918
        $sql .= " WHERE sc.fk_soc = " . ((int)$this->id);
4919
        $sql .= " AND sc.fk_c_type_contact = tc.rowid";
4920
        if (!empty($element)) {
4921
            $sql .= " AND tc.element = '" . $this->db->escape($element) . "'";
4922
        }
4923
        if ($code) {
4924
            $sql .= " AND tc.code = '" . $this->db->escape($code) . "'";
4925
        }
4926
        $sql .= " AND sc.entity IN (" . getEntity($this->element) . ")";
4927
        $sql .= " AND tc.source = 'external'";
4928
        $sql .= " AND tc.active = 1";
4929
4930
        $sql .= " ORDER BY t.lastname ASC";
4931
4932
        dol_syslog(get_only_class($this) . "::getContacts", LOG_DEBUG);
4933
        $resql = $this->db->query($sql);
4934
        if ($resql) {
4935
            $num = $this->db->num_rows($resql);
4936
            $i = 0;
4937
            while ($i < $num) {
4938
                $obj = $this->db->fetch_object($resql);
4939
4940
                if (!$list) {
4941
                    $transkey = "TypeContact_" . $obj->element . "_" . $obj->source . "_" . $obj->code;
4942
                    $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_label);
4943
                    $tab[$i] = array(
4944
                        'source' => $obj->source,
4945
                        'socid' => $obj->socid,
4946
                        'id' => $obj->id,
4947
                        'nom' => $obj->lastname, // For backward compatibility
4948
                        'civility' => $obj->civility,
4949
                        'lastname' => $obj->lastname,
4950
                        'firstname' => $obj->firstname,
4951
                        'email' => $obj->email,
4952
                        'login' => (empty($obj->login) ? '' : $obj->login),
4953
                        'photo' => (empty($obj->photo) ? '' : $obj->photo),
4954
                        'statuscontact' => $obj->statuscontact,
4955
                        'rowid' => $obj->rowid,
4956
                        'code' => $obj->code,
4957
                        'element' => $obj->element,
4958
                        'libelle' => $libelle_type,
4959
                        'status' => $obj->statuslink,
4960
                        'fk_c_type_contact' => $obj->fk_c_type_contact
4961
                    );
4962
                } else {
4963
                    $tab[$i] = $obj->id;
4964
                }
4965
4966
                $i++;
4967
            }
4968
4969
            return $tab;
4970
        } else {
4971
            $this->error = $this->db->lasterror();
4972
            dol_print_error($this->db);
4973
            return -1;
4974
        }
4975
    }
4976
4977
    /**
4978
     *    Merge a company with current one, deleting the given company $soc_origin_id.
4979
     *    The company given in parameter will be removed.
4980
     *    This is called for example by the societe/card.php file.
4981
     *    It calls the method replaceThirdparty() of each object with relation with thirdparties,
4982
     *    including hook 'replaceThirdparty' for external modules.
4983
     *
4984
     * @param int $soc_origin_id Company to merge the data from
4985
     * @return   int                         -1 if error, >=0 if OK
4986
     */
4987
    public function mergeCompany($soc_origin_id)
4988
    {
4989
        global $conf, $langs, $hookmanager, $user, $action;
4990
4991
        $error = 0;
4992
        $soc_origin = new Societe($this->db);       // The thirdparty that we will delete
4993
4994
        dol_syslog("mergeCompany merge thirdparty id=" . $soc_origin_id . " (will be deleted) into the thirdparty id=" . $this->id);
4995
4996
        if (!$error && $soc_origin->fetch($soc_origin_id) < 1) {
4997
            $this->error = $langs->trans('ErrorRecordNotFound');
4998
            $error++;
4999
        }
5000
5001
        if (!$error) {
5002
            $this->db->begin();
5003
5004
            // Recopy some data
5005
            $this->client |= $soc_origin->client;
5006
            $this->fournisseur |= $soc_origin->fournisseur;
5007
            $listofproperties = array(
5008
                'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_mobile', 'fax', 'email', 'socialnetworks', 'url', 'barcode',
5009
                'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
5010
                'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
5011
                'stcomm_id', 'outstanding_limit', 'order_min_amount', 'supplier_order_min_amount', 'price_level', 'parent', 'default_lang', 'ref', 'ref_ext', 'import_key', 'fk_incoterms', 'fk_multicurrency',
5012
                'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
5013
                'model_pdf', 'webservices_url', 'webservices_key', 'accountancy_code_sell', 'accountancy_code_buy', 'typent_id'
5014
            );
5015
            foreach ($listofproperties as $property) {
5016
                if (empty($this->$property)) {
5017
                    $this->$property = $soc_origin->$property;
5018
                }
5019
            }
5020
5021
            if ($this->typent_id == -1) {
5022
                $this->typent_id = $soc_origin->typent_id;
5023
            }
5024
5025
            // Concat some data
5026
            $listofproperties = array(
5027
                'note_public', 'note_private'
5028
            );
5029
            foreach ($listofproperties as $property) {
5030
                $this->$property = dol_concatdesc($this->$property, $soc_origin->$property);
5031
            }
5032
5033
            // Merge extrafields
5034
            if (is_array($soc_origin->array_options)) {
5035
                foreach ($soc_origin->array_options as $key => $val) {
5036
                    if (empty($this->array_options[$key])) {
5037
                        $this->array_options[$key] = $val;
5038
                    }
5039
                }
5040
            }
5041
5042
            // If alias name is not defined on target thirdparty, we can store in it the old name of company.
5043
            if (empty($this->name_bis) && $this->name != $soc_origin->name) {
5044
                $this->name_bis = $this->name;
5045
            }
5046
5047
            // Merge categories
5048
            $static_cat = new Categorie($this->db);
5049
5050
            $custcats_ori = $static_cat->containing($soc_origin->id, 'customer', 'id');
5051
            $custcats = $static_cat->containing($this->id, 'customer', 'id');
5052
            $custcats = array_merge($custcats, $custcats_ori);
5053
            $this->setCategories($custcats, 'customer');
5054
5055
            $suppcats_ori = $static_cat->containing($soc_origin->id, 'supplier', 'id');
5056
            $suppcats = $static_cat->containing($this->id, 'supplier', 'id');
5057
            $suppcats = array_merge($suppcats, $suppcats_ori);
5058
            $this->setCategories($suppcats, 'supplier');
5059
5060
            // If thirdparty has a new code that is same than origin, we clean origin code to avoid duplicate key from database unique keys.
5061
            if (
5062
                $soc_origin->code_client == $this->code_client
5063
                || $soc_origin->code_fournisseur == $this->code_fournisseur
5064
                || $soc_origin->barcode == $this->barcode
5065
            ) {
5066
                dol_syslog("We clean customer and supplier code so we will be able to make the update of target");
5067
                $soc_origin->code_client = '';
5068
                $soc_origin->code_fournisseur = '';
5069
                $soc_origin->barcode = '';
5070
                $soc_origin->update($soc_origin->id, $user, 0, 1, 1, 'merge');
5071
            }
5072
5073
            // Update
5074
            $result = $this->update($this->id, $user, 0, 1, 1, 'merge');
5075
5076
            if ($result < 0) {
5077
                $error++;
5078
            }
5079
5080
            // Move links
5081
            if (!$error) {
5082
                $objects = array(
5083
                    'Adherent' => '/adherents/class/adherent.class.php',
5084
                    //'Categorie' => '/categories/class/categorie.class.php',   // Already processed previously
5085
                    'ActionComm' => '/comm/action/class/actioncomm.class.php',
5086
                    'Propal' => '/comm/propal/class/propal.class.php',
5087
                    'Commande' => '/commande/class/commande.class.php',
5088
                    'Facture' => '/compta/facture/class/facture.class.php',
5089
                    'FactureRec' => '/compta/facture/class/facture-rec.class.php',
5090
                    'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
5091
                    'Contact' => '/contact/class/contact.class.php',
5092
                    'Contrat' => '/contrat/class/contrat.class.php',
5093
                    'Expedition' => '/expedition/class/expedition.class.php',
5094
                    'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
5095
                    'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
5096
                    'FactureFournisseurRec' => '/fourn/class/fournisseur.facture-rec.class.php',
5097
                    'Reception' => '/reception/class/reception.class.php',
5098
                    'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
5099
                    'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
5100
                    'Product' => '/product/class/product.class.php',
5101
                    //'ProductThirparty' => '...',  // for llx_product_thirdparty
5102
                    'Project' => '/projet/class/project.class.php',
5103
                    'User' => '/user/class/user.class.php',
5104
                    'Account' => '/compta/bank/class/account.class.php',
5105
                    'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php',
5106
                    'Societe' => '/societe/class/societe.class.php',
5107
                    //'SocieteAccount', 'SocietePrice', 'SocieteRib',... are processed into the replaceThirparty of Societe.
5108
                );
5109
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'delivery')) {
5110
                    $objects['Delivery'] = '/delivery/class/delivery.class.php';
5111
                }
5112
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'mrp_mo')) {
5113
                    $objects['Mo'] = '/mrp/class/mo.class.php';
5114
                }
5115
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'don')) {
5116
                    $objects['Don'] = '/don/class/don.class.php';
5117
                }
5118
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'partnership')) {
5119
                    $objects['PartnerShip'] = '/partnership/class/partnership.class.php';
5120
                }
5121
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'fichinter')) {
5122
                    $objects['Fichinter'] = '/fichinter/class/fichinter.class.php';
5123
                }
5124
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'ticket')) {
5125
                    $objects['Ticket'] = '/ticket/class/ticket.class.php';
5126
                }
5127
5128
                //First, all core objects must update their tables
5129
                foreach ($objects as $object_name => $object_file) {
5130
                    if (is_array($object_file)) {
5131
                        if (empty($object_file['enabled'])) {
5132
                            continue;
5133
                        }
5134
                        $object_file = $object_file['file'];
5135
                    }
5136
5137
                    require_once DOL_DOCUMENT_ROOT . $object_file;
5138
5139
                    if (!$error && !$object_name::replaceThirdparty($this->db, $soc_origin->id, $this->id)) {
5140
                        $error++;
5141
                        $this->error = $this->db->lasterror();
5142
                        break;
5143
                    }
5144
                }
5145
            }
5146
5147
            // External modules should update their ones too
5148
            if (!$error) {
5149
                $parameters = array('soc_origin' => $soc_origin->id, 'soc_dest' => $this->id);
5150
                $reshook = $hookmanager->executeHooks('replaceThirdparty', $parameters, $this, $action);
5151
5152
                if ($reshook < 0) {
5153
                    $this->error = $hookmanager->error;
5154
                    $this->errors = $hookmanager->errors;
5155
                    $error++;
5156
                }
5157
            }
5158
5159
5160
            if (!$error) {
5161
                $this->context = array('merge' => 1, 'mergefromid' => $soc_origin->id, 'mergefromname' => $soc_origin->name);
5162
5163
                // Call trigger
5164
                $result = $this->call_trigger('COMPANY_MODIFY', $user);
5165
                if ($result < 0) {
5166
                    $error++;
5167
                }
5168
                // End call triggers
5169
            }
5170
5171
            if (!$error) {
5172
                // Move files from the dir of the third party to delete into the dir of the third party to keep
5173
                if (!empty($conf->societe->multidir_output[$this->entity])) {
5174
                    $srcdir = $conf->societe->multidir_output[$this->entity] . "/" . $soc_origin->id;
5175
                    $destdir = $conf->societe->multidir_output[$this->entity] . "/" . $this->id;
5176
5177
                    if (dol_is_dir($srcdir)) {
5178
                        $dirlist = dol_dir_list($srcdir, 'files', 1);
5179
                        foreach ($dirlist as $filetomove) {
5180
                            $destfile = $destdir . '/' . $filetomove['relativename'];
5181
                            //var_dump('Move file '.$filetomove['relativename'].' into '.$destfile);
5182
                            dol_move($filetomove['fullname'], $destfile, '0', 0, 0, 1);
5183
                        }
5184
                        //exit;
5185
                    }
5186
                }
5187
            }
5188
5189
5190
            if (!$error) {
5191
                // We finally remove the old thirdparty
5192
                if ($soc_origin->delete($soc_origin->id, $user) < 1) {
5193
                    $this->error = $soc_origin->error;
5194
                    $this->errors = $soc_origin->errors;
5195
                    $error++;
5196
                }
5197
            }
5198
5199
            if (!$error) {
5200
                $this->db->commit();
5201
                return 0;
5202
            } else {
5203
                $langs->load("errors");
5204
                $this->error = $langs->trans('ErrorsThirdpartyMerge');
5205
                $this->db->rollback();
5206
                return -1;
5207
            }
5208
        }
5209
5210
        return -1;
5211
    }
5212
5213
    /**
5214
     * Function used to replace a thirdparty id with another one.
5215
     * It must be used within a transaction to avoid trouble
5216
     *
5217
     * @param DoliDB $dbs Database handler, because function is static we name it $dbs not $db to avoid breaking coding test
5218
     * @param int $origin_id Old thirdparty id (will be removed)
5219
     * @param int $dest_id New thirdparty id
5220
     * @return  bool                True if success, False if error
5221
     */
5222
    public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
5223
    {
5224
        if ($origin_id == $dest_id) {
5225
            dol_syslog('Error: Try to merge a thirdparty into itself');
5226
            return false;
5227
        }
5228
5229
        // Sales representationves cannot be twice in the same thirdparties so we look for them and remove the one that are common some to avoid duplicate.
5230
        // Because this function is meant to be executed within a transaction, we won't take care of begin/commit.
5231
        $sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux ';
5232
        $sql .= ' WHERE fk_soc = ' . (int)$dest_id . ' AND fk_user IN ( ';
5233
        $sql .= ' SELECT fk_user ';
5234
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux ';
5235
        $sql .= ' WHERE fk_soc = ' . (int)$origin_id . ') ';
5236
5237
        $resql = $dbs->query($sql);
5238
        while ($obj = $dbs->fetch_object($resql)) {
5239
            $dbs->query('DELETE FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux WHERE rowid = ' . ((int)$obj->rowid));
5240
        }
5241
5242
        // llx_societe_extrafields table must not be here because we don't care about the old thirdparty extrafields that are managed directly into mergeCompany.
5243
        // Do not include llx_societe because it will be replaced later.
5244
        $tables = array(
5245
            'societe_account',
5246
            'societe_commerciaux',
5247
            'societe_prices',
5248
            'societe_remise',
5249
            'societe_remise_except',
5250
            'societe_rib'
5251
        );
5252
5253
        return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
5254
    }
5255
5256
    /**
5257
     *    Delete a third party from database and all its dependencies (contacts, rib...)
5258
     *
5259
     * @param int $id Id of third party to delete
5260
     * @param User|null $fuser User who ask to delete thirdparty
5261
     * @param int $call_trigger 0=No, 1=yes
5262
     * @return   int                         Return integer <0 if KO, 0 if nothing done, >0 if OK
5263
     */
5264
    public function delete($id, User $fuser = null, $call_trigger = 1)
5265
    {
5266
        global $conf, $user;
5267
5268
        if (empty($fuser)) {
5269
            $fuser = $user;
5270
        }
5271
5272
        require_once constant('DOL_DOCUMENT_ROOT') . '/core/lib/files.lib.php';
5273
5274
        $entity = isset($this->entity) ? $this->entity : $conf->entity;
5275
5276
        dol_syslog(get_only_class($this) . "::delete", LOG_DEBUG);
5277
        $error = 0;
5278
5279
        // Test if child exists
5280
        $objectisused = $this->isObjectUsed($id);
5281
        if (empty($objectisused)) {
5282
            $this->db->begin();
5283
5284
            // User is mandatory for trigger call
5285
            if (!$error && $call_trigger) {
5286
                // Call trigger
5287
                $result = $this->call_trigger('COMPANY_DELETE', $fuser);
5288
                if ($result < 0) {
5289
                    $error++;
5290
                }
5291
                // End call triggers
5292
            }
5293
5294
            if (!$error) {
5295
                $static_cat = new Categorie($this->db);
5296
                $toute_categs = array();
5297
5298
                // Fill $toute_categs array with an array of (type => array of ("Categorie" instance))
5299
                $toute_categs['customer'] = $static_cat->containing($this->id, Categorie::TYPE_CUSTOMER);
5300
                $toute_categs['supplier'] = $static_cat->containing($this->id, Categorie::TYPE_SUPPLIER);
5301
5302
                // Remove each "Categorie"
5303
                foreach ($toute_categs as $type => $categs_type) {
5304
                    foreach ($categs_type as $cat) {
5305
                        $cat->del_type($this, $type);
5306
                    }
5307
                }
5308
            }
5309
5310
            if (!$error) {
5311
                foreach ($this->childtablesoncascade as $tabletodelete) {
5312
                    $deleteFromObject = explode(':', $tabletodelete, 4);
5313
                    if (count($deleteFromObject) >= 2) {
5314
                        $className = str_replace('@', '', $deleteFromObject[0]);
5315
                        $filepath = $deleteFromObject[1];
5316
                        $columnName = $deleteFromObject[2];
5317
                        if (dol_include_once($filepath)) {
5318
                            $child_object = new $className($this->db);
5319
                            $result = $child_object->deleteByParentField($id, $columnName);
5320
                            if ($result < 0) {
5321
                                $error++;
5322
                                $this->errors[] = $child_object->error;
5323
                                break;
5324
                            }
5325
                        } else {
5326
                            $error++;
5327
                            $this->errors[] = 'Cannot include child class file ' . $filepath;
5328
                            break;
5329
                        }
5330
                    } else {
5331
                        $sql = "DELETE FROM " . MAIN_DB_PREFIX . $tabletodelete;
5332
                        $sql .= " WHERE fk_soc = " . ((int)$id);
5333
                        if (!$this->db->query($sql)) {
5334
                            $error++;
5335
                            $this->errors[] = $this->db->lasterror();
5336
                            break;
5337
                        }
5338
                    }
5339
                }
5340
            }
5341
5342
            // Removed extrafields
5343
            if (!$error) {
5344
                $result = $this->deleteExtraFields();
5345
                if ($result < 0) {
5346
                    $error++;
5347
                    dol_syslog(get_only_class($this) . "::delete error -3 " . $this->error, LOG_ERR);
5348
                }
5349
            }
5350
5351
            // Remove links to subsidiaries companies
5352
            if (!$error) {
5353
                $sql = "UPDATE " . MAIN_DB_PREFIX . "societe";
5354
                $sql .= " SET parent = NULL";
5355
                $sql .= " WHERE parent = " . ((int)$id);
5356
                if (!$this->db->query($sql)) {
5357
                    $error++;
5358
                    $this->errors[] = $this->db->lasterror();
5359
                }
5360
            }
5361
5362
            // Remove third party
5363
            if (!$error) {
5364
                if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
5365
                    $sql = "DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity";
5366
                    $sql .= " WHERE fk_soc = " . ((int)$id);
5367
                    if (!$this->db->query($sql)) {
5368
                        $error++;
5369
                        $this->errors[] = $this->db->lasterror();
5370
                    }
5371
                }
5372
5373
                $sql = "DELETE FROM " . MAIN_DB_PREFIX . "societe";
5374
                $sql .= " WHERE rowid = " . ((int)$id);
5375
                if (!$this->db->query($sql)) {
5376
                    $error++;
5377
                    $this->errors[] = $this->db->lasterror();
5378
                }
5379
            }
5380
5381
            if (!$error) {
5382
                $this->db->commit();
5383
5384
                // Delete directory
5385
                if (!empty($conf->societe->multidir_output[$entity])) {
5386
                    $docdir = $conf->societe->multidir_output[$entity] . "/" . $id;
5387
                    if (dol_is_dir($docdir)) {
5388
                        dol_delete_dir_recursive($docdir);
5389
                    }
5390
                }
5391
5392
                return 1;
5393
            } else {
5394
                dol_syslog($this->error, LOG_ERR);
5395
                $this->db->rollback();
5396
                return -1;
5397
            }
5398
        } else {
5399
            dol_syslog("Can't remove thirdparty with id " . $id . ". There are " . $objectisused . " children", LOG_WARNING);
5400
        }
5401
        return 0;
5402
    }
5403
}
5404