Passed
Push — main ( f1540e...02d90d )
by Rafael
45:15
created

Company::getAvailableDiscounts()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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

1087
        $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...
1088
        $this->setUpperOrLowerCase();
1089
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

1089
        /** @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...
1090
        if (empty($this->client)) {
1091
            $this->client = 0;
1092
        }
1093
        if (empty($this->fournisseur)) {
1094
            $this->fournisseur = 0;
1095
        }
1096
        $this->import_key = trim((string) $this->import_key);
1097
1098
        $this->accountancy_code_customer = trim((string) $this->code_compta);
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

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

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

1730
        $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...
1731
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

1731
        /** @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...
1732
        $this->name_alias = trim((string) $this->name_alias);
1733
        $this->ref_ext = (empty($this->ref_ext) ? '' : trim($this->ref_ext));
1734
        $this->address = trim((string) $this->address);
1735
        $this->zip = trim((string) $this->zip);
1736
        $this->town = trim((string) $this->town);
1737
        $this->state_id = (is_numeric($this->state_id)) ? (int) trim($this->state_id) : 0;
1738
        $this->country_id = ($this->country_id > 0) ? $this->country_id : 0;
1739
        $this->phone = trim((string) $this->phone);
1740
        $this->phone = preg_replace("/\s/", "", $this->phone);
1741
        $this->phone = preg_replace("/\./", "", $this->phone);
1742
        $this->phone_mobile = trim((string) $this->phone_mobile);
1743
        $this->phone_mobile = preg_replace("/\s/", "", $this->phone_mobile);
1744
        $this->phone_mobile = preg_replace("/\./", "", $this->phone_mobile);
1745
        $this->fax = trim((string) $this->fax);
1746
        $this->fax = preg_replace("/\s/", "", $this->fax);
1747
        $this->fax = preg_replace("/\./", "", $this->fax);
1748
        $this->email = trim((string) $this->email);
1749
        $this->url = $this->url ? clean_url($this->url, 0) : '';
1750
        $this->note_private = (empty($this->note_private) ? '' : trim($this->note_private));
1751
        $this->note_public = (empty($this->note_public) ? '' : trim($this->note_public));
1752
        $this->idprof1 = trim((string) $this->idprof1);
1753
        $this->idprof2 = trim((string) $this->idprof2);
1754
        $this->idprof3 = trim((string) $this->idprof3);
1755
        $this->idprof4 = trim((string) $this->idprof4);
1756
        $this->idprof5 = (!empty($this->idprof5) ? trim($this->idprof5) : '');
1757
        $this->idprof6 = (!empty($this->idprof6) ? trim($this->idprof6) : '');
1758
        $this->prefix_comm = trim((string) $this->prefix_comm);
1759
        $this->outstanding_limit = price2num($this->outstanding_limit);
1760
        $this->order_min_amount = price2num($this->order_min_amount);
1761
        $this->supplier_order_min_amount = price2num($this->supplier_order_min_amount);
1762
1763
        $this->tva_assuj = (is_numeric($this->tva_assuj)) ? (int) trim($this->tva_assuj) : 0;
1764
        $this->tva_intra = dol_sanitizeFileName($this->tva_intra, '');
1765
        $this->vat_reverse_charge = empty($this->vat_reverse_charge) ? 0 : 1;
1766
        if (empty($this->status)) {
1767
            $this->status = 0;
1768
        }
1769
1770
        if (!empty($this->multicurrency_code)) {
1771
            $this->fk_multicurrency = MultiCurrency::getIdFromCode($this->db, $this->multicurrency_code);
1772
        }
1773
        if (empty($this->fk_multicurrency)) {
1774
            $this->multicurrency_code = '';
1775
            $this->fk_multicurrency = 0;
1776
        }
1777
1778
        // Local taxes
1779
        $this->localtax1_assuj = trim($this->localtax1_assuj);
1780
        $this->localtax2_assuj = trim($this->localtax2_assuj);
1781
1782
        $this->localtax1_value = trim($this->localtax1_value);
1783
        $this->localtax2_value = trim($this->localtax2_value);
1784
1785
        $this->capital = ($this->capital != '') ? (float) price2num(trim($this->capital)) : null;
1786
1787
        $this->effectif_id = trim($this->effectif_id);
1788
        $this->forme_juridique_code = trim($this->forme_juridique_code);
1789
1790
        //Gencod
1791
        $this->barcode = trim($this->barcode);
1792
1793
        // For automatic creation
1794
        if ($this->code_client == -1 || $this->code_client === 'auto') {
1795
            $this->get_codeclient($this, 0);
1796
        }
1797
        if ($this->code_fournisseur == '-1' || $this->code_fournisseur === 'auto') {
1798
            $this->get_codefournisseur($this, 1);
1799
        }
1800
1801
        $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 DoliModules\Company\Model\Company::$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

1801
        $this->code_compta_client = trim(empty($this->code_compta) ? $this->code_compta_client : /** @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...
1802
        $this->code_compta = $this->code_compta_client; // for backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

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

2180
                    /** @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...
2181
                } elseif ($type == 'supplier') {
2182
                    $this->code_compta_fournisseur = $mod->code;
2183
                }
2184
2185
                return $result;
2186
            } else {
2187
                $this->error = 'ErrorAccountancyCodeNotDefined';
2188
                return -1;
2189
            }
2190
        } else {
2191
            if ($type == 'customer') {
2192
                $this->code_compta_client = '';
2193
                $this->code_compta = '';
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

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

2356
                /** @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...
2357
                $this->name_alias = $obj->name_alias;
2358
                $this->ref_ext = $obj->ref_ext;
2359
2360
                $this->date_creation = $this->db->jdate($obj->date_creation);
2361
                $this->date_modification = $this->db->jdate($obj->date_modification);
2362
                $this->user_creation_id = $obj->fk_user_creat;
2363
                $this->user_modification_id = $obj->fk_user_modif;
2364
2365
                $this->address = $obj->address;
2366
                $this->zip = $obj->zip;
2367
                $this->town = $obj->town;
2368
2369
                $this->country_id = $obj->country_id;
2370
                $this->country_code = $obj->country_id ? $obj->country_code : '';
2371
                $this->country = $obj->country_id ? (($langs->transnoentities('Country' . $obj->country_code) != 'Country' . $obj->country_code) ? $langs->transnoentities('Country' . $obj->country_code) : $obj->country) : '';
2372
2373
                $this->state_id = $obj->state_id;
2374
                $this->state_code = $obj->state_code;
2375
                $this->region_id = $obj->region_id;
2376
                $this->region_code = $obj->region_code;
2377
                $this->state = ($obj->state != '-' ? $obj->state : '');
2378
2379
                $transcode = $langs->trans('StatusProspect' . $obj->fk_stcomm);
2380
                $label = ($transcode != 'StatusProspect' . $obj->fk_stcomm ? $transcode : $obj->stcomm);
2381
                $this->stcomm_id = $obj->fk_stcomm; // id status prospect
2382
                $this->status_prospect_label = $label; // label status prospect
2383
                $this->stcomm_picto = $obj->stcomm_picto; // picto statut commercial
2384
2385
                $this->email = $obj->email;
2386
                $this->socialnetworks = ($obj->socialnetworks ? (array) json_decode($obj->socialnetworks, true) : []);
2387
2388
                $this->url = $obj->url;
2389
                $this->phone = $obj->phone;
2390
                $this->phone_mobile = $obj->phone_mobile;
2391
                $this->fax = $obj->fax;
2392
2393
                $this->parent = $obj->parent;
2394
2395
                $this->idprof1 = $obj->idprof1;
2396
                $this->idprof2 = $obj->idprof2;
2397
                $this->idprof3 = $obj->idprof3;
2398
                $this->idprof4 = $obj->idprof4;
2399
                $this->idprof5 = $obj->idprof5;
2400
                $this->idprof6 = $obj->idprof6;
2401
2402
                $this->capital = $obj->capital;
2403
2404
                $this->code_client = $obj->code_client;
2405
                $this->code_fournisseur = $obj->code_fournisseur;
2406
2407
                $this->code_compta = $obj->code_compta;         // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

2407
                /** @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...
2408
                $this->code_compta_client = $obj->code_compta;
2409
                $this->code_compta_fournisseur = $obj->code_compta_fournisseur;
2410
2411
                $this->barcode = $obj->barcode;
2412
2413
                $this->tva_assuj = $obj->tva_assuj;
2414
                $this->tva_intra = $obj->tva_intra;
2415
2416
                if (!empty($obj->spe_vat_reverse_charge)) {
2417
                    $this->vat_reverse_charge = $obj->spe_vat_reverse_charge;
2418
                } elseif (!empty($obj->soc_vat_reverse_charge)) {
2419
                    $this->vat_reverse_charge = $obj->soc_vat_reverse_charge;
2420
                } else {
2421
                    $this->vat_reverse_charge = 0;
2422
                }
2423
2424
                $this->status = $obj->status;
2425
2426
                // Local Taxes
2427
                $this->localtax1_assuj = $obj->localtax1_assuj;
2428
                $this->localtax2_assuj = $obj->localtax2_assuj;
2429
2430
                $this->localtax1_value = $obj->localtax1_value;
2431
                $this->localtax2_value = $obj->localtax2_value;
2432
2433
                $this->typent_id = $obj->typent_id;
2434
                $this->typent_code = $obj->typent_code;
2435
2436
                $this->effectif_id = $obj->effectif_id;
2437
                $this->effectif = $obj->effectif_id ? $obj->effectif : '';
2438
2439
                $this->forme_juridique_code = $obj->forme_juridique_code;
2440
                $this->forme_juridique = $obj->forme_juridique_code ? $obj->forme_juridique : '';
2441
2442
                $this->fk_prospectlevel = $obj->fk_prospectlevel;
2443
2444
                $this->prefix_comm = $obj->prefix_comm;
2445
2446
                $this->remise_percent = $obj->remise_client ? price2num($obj->remise_client) : 0; // 0.000000 must be 0
2447
                $this->remise_supplier_percent = $obj->remise_supplier;
2448
2449
                $this->mode_reglement_id = $obj->mode_reglement;
2450
                $this->cond_reglement_id = $obj->cond_reglement;
2451
                $this->deposit_percent = $obj->deposit_percent;
2452
                $this->transport_mode_id = $obj->transport_mode;
2453
                $this->mode_reglement_supplier_id = $obj->mode_reglement_supplier;
2454
                $this->cond_reglement_supplier_id = $obj->cond_reglement_supplier;
2455
                $this->transport_mode_supplier_id = $obj->transport_mode_supplier;
2456
                $this->shipping_method_id = ($obj->fk_shipping_method > 0) ? $obj->fk_shipping_method : null;
2457
                $this->fk_account = $obj->fk_account;
2458
2459
                $this->client = $obj->client;
2460
                $this->fournisseur = $obj->fournisseur;
2461
2462
                $this->note = $obj->note_private; // TODO Deprecated for backward comtability
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

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

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

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

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

3619
        /** @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...
3620
        $this->address = getDolGlobalString('MAIN_INFO_SOCIETE_ADDRESS');
3621
        $this->zip = getDolGlobalString('MAIN_INFO_SOCIETE_ZIP');
3622
        $this->town = getDolGlobalString('MAIN_INFO_SOCIETE_TOWN');
3623
        $this->region_code = getDolGlobalString('MAIN_INFO_SOCIETE_REGION');
3624
3625
        $this->socialobject = getDolGlobalString('MAIN_INFO_SOCIETE_OBJECT');
3626
3627
        $this->note_private = getDolGlobalString('MAIN_INFO_SOCIETE_NOTE');
3628
3629
        // We define country_id, country_code and country
3630
        $country_id = 0;
3631
        $country_code = $country_label = '';
3632
        if (getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY')) {
3633
            $tmp = explode(':', getDolGlobalString('MAIN_INFO_SOCIETE_COUNTRY'));
3634
            $country_id = (is_numeric($tmp[0])) ? (int) $tmp[0] : 0;
3635
            if (!empty($tmp[1])) {   // If $conf->global->MAIN_INFO_SOCIETE_COUNTRY is "id:code:label"
3636
                $country_code = $tmp[1];
3637
                $country_label = $tmp[2];
3638
            } else {
3639
                // For backward compatibility
3640
                dol_syslog("Your country setup use an old syntax. Reedit it using setup area.", LOG_WARNING);
3641
                include_once BASE_PATH . '/../Dolibarr/Lib/Company.php';
3642
                $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
3643
                $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
3644
            }
3645
        }
3646
        $this->country_id = $country_id;
3647
        $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...
3648
        $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...
3649
        if (is_object($langs)) {
3650
            $this->country = ($langs->trans('Country' . $country_code) != 'Country' . $country_code) ? $langs->trans('Country' . $country_code) : $country_label;
3651
        }
3652
3653
        //TODO This could be replicated for region but function `getRegion` didn't exist, so I didn't added it.
3654
        // We define state_id, state_code and state
3655
        $state_id = 0;
3656
        $state_code = $state_label = '';
3657
        if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) {
3658
            $tmp = explode(':', getDolGlobalString('MAIN_INFO_SOCIETE_STATE'));
3659
            $state_id = $tmp[0];
3660
            if (!empty($tmp[1])) {   // If $conf->global->MAIN_INFO_SOCIETE_STATE is "id:code:label"
3661
                $state_code = $tmp[1];
3662
                $state_label = $tmp[2];
3663
            } else { // For backward compatibility
3664
                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);
3665
                include_once BASE_PATH . '/../Dolibarr/Lib/Company.php';
3666
                $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
3667
                $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
3668
            }
3669
        }
3670
        $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...
3671
        $this->state_code = $state_code;
3672
        $this->state = $state_label;
3673
        if (is_object($langs)) {
3674
            $this->state = ($langs->trans('State' . $state_code) != 'State' . $state_code) ? $langs->trans('State' . $state_code) : $state_label;
3675
        }
3676
3677
        $this->phone = getDolGlobalString('MAIN_INFO_SOCIETE_TEL');
3678
        $this->phone_mobile = getDolGlobalString('MAIN_INFO_SOCIETE_MOBILE');
3679
        $this->fax = getDolGlobalString('MAIN_INFO_SOCIETE_FAX');
3680
        $this->url = getDolGlobalString('MAIN_INFO_SOCIETE_WEB');
3681
3682
        // Social networks
3683
        $facebook_url = getDolGlobalString('MAIN_INFO_SOCIETE_FACEBOOK_URL');
3684
        $twitter_url = getDolGlobalString('MAIN_INFO_SOCIETE_TWITTER_URL');
3685
        $linkedin_url = getDolGlobalString('MAIN_INFO_SOCIETE_LINKEDIN_URL');
3686
        $instagram_url = getDolGlobalString('MAIN_INFO_SOCIETE_INSTAGRAM_URL');
3687
        $youtube_url = getDolGlobalString('MAIN_INFO_SOCIETE_YOUTUBE_URL');
3688
        $github_url = getDolGlobalString('MAIN_INFO_SOCIETE_GITHUB_URL');
3689
        $this->socialnetworks = [];
3690
        if (!empty($facebook_url)) {
3691
            $this->socialnetworks['facebook'] = $facebook_url;
3692
        }
3693
        if (!empty($twitter_url)) {
3694
            $this->socialnetworks['twitter'] = $twitter_url;
3695
        }
3696
        if (!empty($linkedin_url)) {
3697
            $this->socialnetworks['linkedin'] = $linkedin_url;
3698
        }
3699
        if (!empty($instagram_url)) {
3700
            $this->socialnetworks['instagram'] = $instagram_url;
3701
        }
3702
        if (!empty($youtube_url)) {
3703
            $this->socialnetworks['youtube'] = $youtube_url;
3704
        }
3705
        if (!empty($github_url)) {
3706
            $this->socialnetworks['github'] = $github_url;
3707
        }
3708
3709
        // Id prof generiques
3710
        $this->idprof1 = getDolGlobalString('MAIN_INFO_SIREN');
3711
        $this->idprof2 = getDolGlobalString('MAIN_INFO_SIRET');
3712
        $this->idprof3 = getDolGlobalString('MAIN_INFO_APE');
3713
        $this->idprof4 = getDolGlobalString('MAIN_INFO_RCS');
3714
        $this->idprof5 = getDolGlobalString('MAIN_INFO_PROFID5');
3715
        $this->idprof6 = getDolGlobalString('MAIN_INFO_PROFID6');
3716
        $this->tva_intra = getDolGlobalString('MAIN_INFO_TVAINTRA'); // VAT number, not necessarily INTRA.
3717
        $this->managers = getDolGlobalString('MAIN_INFO_SOCIETE_MANAGERS');
3718
        $this->capital = is_numeric(getDolGlobalString('MAIN_INFO_CAPITAL')) ? (float) price2num(getDolGlobalString('MAIN_INFO_CAPITAL')) : 0;
3719
        $this->forme_juridique_code = getDolGlobalString('MAIN_INFO_SOCIETE_FORME_JURIDIQUE');
3720
        $this->email = getDolGlobalString('MAIN_INFO_SOCIETE_MAIL');
3721
        $this->default_lang = getDolGlobalString('MAIN_LANG_DEFAULT', 'auto');
3722
        $this->logo = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO');
3723
        $this->logo_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SMALL');
3724
        $this->logo_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_MINI');
3725
        $this->logo_squarred = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED');
3726
        $this->logo_squarred_small = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_SMALL');
3727
        $this->logo_squarred_mini = getDolGlobalString('MAIN_INFO_SOCIETE_LOGO_SQUARRED_MINI');
3728
3729
        // Define if company use vat or not
3730
        $this->tva_assuj = getDolGlobalInt('FACTURE_TVAOPTION');
3731
3732
        // Define if company use local taxes
3733
        $this->localtax1_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX1_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX1_OPTION') == 'localtax1on')) ? 1 : 0);
3734
        $this->localtax2_assuj = ((isset($conf->global->FACTURE_LOCAL_TAX2_OPTION) && (getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == '1' || getDolGlobalString('FACTURE_LOCAL_TAX2_OPTION') == 'localtax2on')) ? 1 : 0);
3735
    }
3736
3737
    /**
3738
     *  Initialise an instance with random values.
3739
     *  Used to build previews or test instances.
3740
     *  id must be 0 if object instance is a specimen.
3741
     *
3742
     * @return int >0 if ok
3743
     */
3744
    public function initAsSpecimen()
3745
    {
3746
        $now = dol_now();
3747
3748
        // Initialize parameters
3749
        $this->id = 0;
3750
        $this->entity = 1;
3751
        $this->name = 'THIRDPARTY SPECIMEN ' . dol_print_date($now, 'dayhourlog');
3752
        $this->nom = $this->name; // For backward compatibility
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

3752
        /** @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...
3753
        $this->ref_ext = 'Ref ext';
3754
        $this->specimen = 1;
3755
        $this->address = '21 jump street';
3756
        $this->zip = '99999';
3757
        $this->town = 'MyTown';
3758
        $this->state_id = 1;
3759
        $this->state_code = 'AA';
3760
        $this->state = 'MyState';
3761
        $this->country_id = 1;
3762
        $this->country_code = 'FR';
3763
        $this->email = '[email protected]';
3764
        $this->socialnetworks = [
3765
            'skype' => 'skypepseudo',
3766
            'twitter' => 'twitterpseudo',
3767
            'facebook' => 'facebookpseudo',
3768
            'linkedin' => 'linkedinpseudo',
3769
        ];
3770
        $this->url = 'http://www.specimen.com';
3771
3772
        $this->phone = '0909090901';
3773
        $this->phone_mobile = '0909090901';
3774
        $this->fax = '0909090909';
3775
3776
        $this->code_client = 'CC-' . dol_print_date($now, 'dayhourlog');
3777
        $this->code_fournisseur = 'SC-' . dol_print_date($now, 'dayhourlog');
3778
        $this->capital = 10000;
3779
        $this->client = 1;
3780
        $this->prospect = 1;
3781
        $this->fournisseur = 1;
3782
        $this->tva_assuj = 1;
3783
        $this->tva_intra = 'EU1234567';
3784
        $this->note_public = 'This is a comment (public)';
3785
        $this->note_private = 'This is a comment (private)';
3786
3787
        $this->idprof1 = 'idprof1';
3788
        $this->idprof2 = 'idprof2';
3789
        $this->idprof3 = 'idprof3';
3790
        $this->idprof4 = 'idprof4';
3791
        $this->idprof5 = 'idprof5';
3792
        $this->idprof6 = 'idprof6';
3793
3794
        return 1;
3795
    }
3796
3797
    /**
3798
     *  Check if we must use localtax feature or not according to country (country of $mysoc in most cases).
3799
     *
3800
     * @param int $localTaxNum To get info for only localtax1 or localtax2
3801
     *
3802
     * @return     boolean                 true or false
3803
     */
3804
    public function useLocalTax($localTaxNum = 0)
3805
    {
3806
        $sql = "SELECT t.localtax1, t.localtax2";
3807
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
3808
        $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
3809
        $sql .= " AND t.active = 1";
3810
        $sql .= " AND t.entity IN (" . getEntity('c_tva') . ")";
3811
        if (empty($localTaxNum)) {
3812
            $sql .= " AND (t.localtax1_type <> '0' OR t.localtax2_type <> '0')";
3813
        } elseif ($localTaxNum == 1) {
3814
            $sql .= " AND t.localtax1_type <> '0'";
3815
        } elseif ($localTaxNum == 2) {
3816
            $sql .= " AND t.localtax2_type <> '0'";
3817
        }
3818
3819
        $resql = $this->db->query($sql);
3820
        if ($resql) {
3821
            return ($this->db->num_rows($resql) > 0);
3822
        } else {
3823
            return false;
3824
        }
3825
    }
3826
3827
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3828
3829
    /**
3830
     *  Check if we must use NPR Vat (french stupid rule) or not according to country (country of $mysoc in most cases).
3831
     *
3832
     * @return     boolean                 true or false
3833
     */
3834
    public function useNPR()
3835
    {
3836
        $sql = "SELECT t.rowid";
3837
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_tva as t, " . MAIN_DB_PREFIX . "c_country as c";
3838
        $sql .= " WHERE t.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
3839
        $sql .= " AND t.active = 1 AND t.recuperableonly = 1";
3840
        $sql .= " AND t.entity IN (" . getEntity('c_tva') . ")";
3841
3842
        dol_syslog("useNPR", LOG_DEBUG);
3843
        $resql = $this->db->query($sql);
3844
        if ($resql) {
3845
            return ($this->db->num_rows($resql) > 0);
3846
        } else {
3847
            return false;
3848
        }
3849
    }
3850
3851
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3852
3853
    /**
3854
     *  Check if we must use revenue stamps feature or not according to country (country of $mysocin most cases).
3855
     *  Table c_revenuestamp contains the country and value of stamp per invoice.
3856
     *
3857
     * @return     boolean         true or false
3858
     */
3859
    public function useRevenueStamp()
3860
    {
3861
        $sql = "SELECT COUNT(*) as nb";
3862
        $sql .= " FROM " . MAIN_DB_PREFIX . "c_revenuestamp as r, " . MAIN_DB_PREFIX . "c_country as c";
3863
        $sql .= " WHERE r.fk_pays = c.rowid AND c.code = '" . $this->db->escape($this->country_code) . "'";
3864
        $sql .= " AND r.active = 1";
3865
3866
        dol_syslog("useRevenueStamp", LOG_DEBUG);
3867
        $resql = $this->db->query($sql);
3868
        if ($resql) {
3869
            $obj = $this->db->fetch_object($resql);
3870
            return (($obj->nb > 0) ? true : false);
3871
        } else {
3872
            $this->error = $this->db->lasterror();
3873
            return false;
3874
        }
3875
    }
3876
3877
    /**
3878
     *  Return prostect level
3879
     *
3880
     * @return     string        Label of prospect status
3881
     */
3882
    public function getLibProspLevel()
3883
    {
3884
        return $this->LibProspLevel($this->fk_prospectlevel);
3885
    }
3886
3887
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
3888
3889
    /**
3890
     *  Return label of prospect level
3891
     *
3892
     * @param string $fk_prospectlevel Prospect level
3893
     *
3894
     * @return string                          label of level
3895
     */
3896
    public function LibProspLevel($fk_prospectlevel)
3897
    {
3898
        // phpcs:enable
3899
        global $langs;
3900
3901
        $label = '';
3902
        if ($fk_prospectlevel != '') {
3903
            $label = $langs->trans("ProspectLevel" . $fk_prospectlevel);
3904
            // If label is not found in language file, we get label from cache/database
3905
            if ($label == "ProspectLevel" . $fk_prospectlevel) {
3906
                $label = $langs->getLabelFromKey($this->db, $fk_prospectlevel, 'c_prospectlevel', 'code', 'label');
3907
            }
3908
        }
3909
3910
        return $label;
3911
    }
3912
3913
    /**
3914
     *  Return status of prospect
3915
     *
3916
     * @param int    $mode  0=label long, 1=label short, 2=Picto + Label short, 3=Picto, 4=Picto + Label long
3917
     * @param string $label Label to use for status for added status
3918
     *
3919
     * @return string              Label
3920
     */
3921
    public function getLibProspCommStatut($mode = 0, $label = '')
3922
    {
3923
        return $this->LibProspCommStatut($this->stcomm_id, $mode, $label, $this->stcomm_picto);
3924
    }
3925
3926
    /**
3927
     *  Return label of a given status
3928
     *
3929
     * @param int|string $status            Id or code for prospection status
3930
     * @param int        $mode              0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long
3931
     *                                      label, 5=Short label + Picto
3932
     * @param string     $label             Label to use for status for added status
3933
     * @param string     $picto             Name of image file to show ('filenew', ...)
3934
     *                                      If no extension provided, we use '.png'. Image must be stored into
3935
     *                                      theme/xxx/img directory. Example: picto.png                  if picto.png
3936
     *                                      is stored into htdocs/theme/mytheme/img Example: picto.png@mymodule
3937
     *                                      if picto.png is stored into htdocs/mymodule/img Example:
3938
     *                                      /mydir/mysubdir/picto.png  if picto.png is stored into
3939
     *                                      htdocs/mydir/mysubdir (pictoisfullpath must be set to 1)
3940
     *
3941
     * @return string                      Label of prospection status
3942
     */
3943
    public function LibProspCommStatut($status, $mode = 0, $label = '', $picto = '')
3944
    {
3945
        // phpcs:enable
3946
        global $langs;
3947
3948
        $langs->load('customers');
3949
3950
        if ($mode == 2) {
3951
            if ($status == '-1' || $status == 'ST_NO') {
3952
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect-1");
3953
            } elseif ($status == '0' || $status == 'ST_NEVER') {
3954
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect0");
3955
            } elseif ($status == '1' || $status == 'ST_TODO') {
3956
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect1");
3957
            } elseif ($status == '2' || $status == 'ST_PEND') {
3958
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect2");
3959
            } elseif ($status == '3' || $status == 'ST_DONE') {
3960
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect3");
3961
            } else {
3962
                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);
3963
            }
3964
        } elseif ($mode == 3) {
3965
            if ($status == '-1' || $status == 'ST_NO') {
3966
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"');
3967
            } elseif ($status == '0' || $status == 'ST_NEVER') {
3968
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"');
3969
            } elseif ($status == '1' || $status == 'ST_TODO') {
3970
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"');
3971
            } elseif ($status == '2' || $status == 'ST_PEND') {
3972
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"');
3973
            } elseif ($status == '3' || $status == 'ST_DONE') {
3974
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"');
3975
            } else {
3976
                return img_action(($langs->trans("StatusProspect" . $status) != "StatusProspect" . $status) ? $langs->trans("StatusProspect" . $status) : $label, 0, $picto, 'class="inline-block valignmiddle"');
3977
            }
3978
        } elseif ($mode == 4) {
3979
            if ($status == '-1' || $status == 'ST_NO') {
3980
                return img_action($langs->trans("StatusProspect-1"), -1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect-1");
3981
            } elseif ($status == '0' || $status == 'ST_NEVER') {
3982
                return img_action($langs->trans("StatusProspect0"), 0, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect0");
3983
            } elseif ($status == '1' || $status == 'ST_TODO') {
3984
                return img_action($langs->trans("StatusProspect1"), 1, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect1");
3985
            } elseif ($status == '2' || $status == 'ST_PEND') {
3986
                return img_action($langs->trans("StatusProspect2"), 2, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect2");
3987
            } elseif ($status == '3' || $status == 'ST_DONE') {
3988
                return img_action($langs->trans("StatusProspect3"), 3, $picto, 'class="inline-block valignmiddle"') . ' ' . $langs->trans("StatusProspect3");
3989
            } else {
3990
                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);
3991
            }
3992
        }
3993
3994
        return "Error, mode/status not found";
3995
    }
3996
3997
    /**
3998
     *  Return amount of proposal not yet paid and total an dlist of all proposals
3999
     *
4000
     * @param string $mode 'customer' or 'supplier'
4001
     *
4002
     * @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total
4003
     *                                 amount without tax of all objects paid or not, 'total_ttc'=>Total amount
4004
     *                                 including tax of all object paid or not)
4005
     */
4006
    public function getOutstandingProposals($mode = 'customer')
4007
    {
4008
        $table = 'propal';
4009
        if ($mode == 'supplier') {
4010
            $table = 'supplier_proposal';
4011
        }
4012
4013
        $sql = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM " . MAIN_DB_PREFIX . $table . " as f";
4014
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
4015
        if ($mode == 'supplier') {
4016
            $sql .= " AND entity IN (" . getEntity('supplier_proposal') . ")";
4017
        } else {
4018
            $sql .= " AND entity IN (" . getEntity('propal') . ")";
4019
        }
4020
4021
        dol_syslog("getOutstandingProposals for fk_soc = " . ((int) $this->id), LOG_DEBUG);
4022
4023
        $resql = $this->db->query($sql);
4024
        if ($resql) {
4025
            $outstandingOpened = 0;
4026
            $outstandingTotal = 0;
4027
            $outstandingTotalIncTax = 0;
4028
            $arrayofref = [];
4029
            while ($obj = $this->db->fetch_object($resql)) {
4030
                $arrayofref[$obj->rowid] = $obj->ref;
4031
                $outstandingTotal += $obj->total_ht;
4032
                $outstandingTotalIncTax += $obj->total_ttc;
4033
                if ($obj->status != 0) {
4034
                    // Not a draft
4035
                    $outstandingOpened += $obj->total_ttc;
4036
                }
4037
            }
4038
            return ['opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref]; // 'opened' is 'incl taxes'
4039
        } else {
4040
            return [];
4041
        }
4042
    }
4043
4044
    /**
4045
     *  Return amount of order not yet paid and total and list of all orders
4046
     *
4047
     * @param string $mode 'customer' or 'supplier'
4048
     *
4049
     * @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total
4050
     *                                 amount without tax of all objects paid or not, 'total_ttc'=>Total amount
4051
     *                                 including tax of all object paid or not)
4052
     */
4053
    public function getOutstandingOrders($mode = 'customer')
4054
    {
4055
        $table = 'commande';
4056
        if ($mode == 'supplier') {
4057
            $table = 'commande_fournisseur';
4058
        }
4059
4060
        $sql = "SELECT rowid, ref, total_ht, total_ttc, fk_statut as status FROM " . MAIN_DB_PREFIX . $table . " as f";
4061
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
4062
        if ($mode == 'supplier') {
4063
            $sql .= " AND entity IN (" . getEntity('supplier_order') . ")";
4064
        } else {
4065
            $sql .= " AND entity IN (" . getEntity('commande') . ")";
4066
        }
4067
4068
        dol_syslog("getOutstandingOrders", LOG_DEBUG);
4069
        $resql = $this->db->query($sql);
4070
        if ($resql) {
4071
            $outstandingOpened = 0;
4072
            $outstandingTotal = 0;
4073
            $outstandingTotalIncTax = 0;
4074
            $arrayofref = [];
4075
            while ($obj = $this->db->fetch_object($resql)) {
4076
                $arrayofref[$obj->rowid] = $obj->ref;
4077
                $outstandingTotal += $obj->total_ht;
4078
                $outstandingTotalIncTax += $obj->total_ttc;
4079
                if ($obj->status != 0) {
4080
                    // Not a draft
4081
                    $outstandingOpened += $obj->total_ttc;
4082
                }
4083
            }
4084
            return ['opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref]; // 'opened' is 'incl taxes'
4085
        } else {
4086
            return [];
4087
        }
4088
    }
4089
4090
    /**
4091
     *  Return amount of bill not yet paid and total of all invoices
4092
     *
4093
     * @param string $mode 'customer' or 'supplier'
4094
     * @param int    $late 0 => all invoice, 1=> only late
4095
     *
4096
     * @return    array                array('opened'=>Amount including tax that remains to pay, 'total_ht'=>Total
4097
     *                                 amount without tax of all objects paid or not, 'total_ttc'=>Total amount
4098
     *                                 including tax of all object paid or not)
4099
     */
4100
    public function getOutstandingBills($mode = 'customer', $late = 0)
4101
    {
4102
        $table = 'facture';
4103
        if ($mode == 'supplier') {
4104
            $table = 'facture_fourn';
4105
        }
4106
4107
        /* Accurate value of remain to pay is to sum remaintopay for each invoice
4108
         $paiement = $invoice->getSommePaiement();
4109
         $creditnotes=$invoice->getSumCreditNotesUsed();
4110
         $deposits=$invoice->getSumDepositsUsed();
4111
         $alreadypayed=price2num($paiement + $creditnotes + $deposits,'MT');
4112
         $remaintopay=price2num($invoice->total_ttc - $paiement - $creditnotes - $deposits,'MT');
4113
         */
4114
        $sql = "SELECT rowid, ref, total_ht, total_ttc, paye, type, fk_statut as status, close_code FROM " . MAIN_DB_PREFIX . $table . " as f";
4115
        $sql .= " WHERE fk_soc = " . ((int) $this->id);
4116
        if (!empty($late)) {
4117
            $sql .= " AND date_lim_reglement < '" . $this->db->idate(dol_now()) . "'";
4118
        }
4119
        if ($mode == 'supplier') {
4120
            $sql .= " AND entity IN (" . getEntity('facture_fourn') . ")";
4121
        } else {
4122
            $sql .= " AND entity IN (" . getEntity('invoice') . ")";
4123
        }
4124
4125
        dol_syslog("getOutstandingBills", LOG_DEBUG);
4126
        $resql = $this->db->query($sql);
4127
        if ($resql) {
4128
            $outstandingOpened = 0;
4129
            $outstandingTotal = 0;
4130
            $outstandingTotalIncTax = 0;
4131
            $arrayofref = [];
4132
            $arrayofrefopened = [];
4133
            if ($mode == 'supplier') {
4134
                $tmpobject = new FactureFournisseur($this->db);
4135
            } else {
4136
                $tmpobject = new Facture($this->db);
4137
            }
4138
            while ($obj = $this->db->fetch_object($resql)) {
4139
                $arrayofref[$obj->rowid] = $obj->ref;
4140
                $tmpobject->id = $obj->rowid;
4141
4142
                if (
4143
                    $obj->status != $tmpobject::STATUS_DRAFT                                           // Not a draft
4144
                    && !($obj->status == $tmpobject::STATUS_ABANDONED && $obj->close_code == 'replaced')  // Not a replaced invoice
4145
                ) {
4146
                    $outstandingTotal += $obj->total_ht;
4147
                    $outstandingTotalIncTax += $obj->total_ttc;
4148
                }
4149
4150
                $remaintopay = 0;
4151
4152
                if (
4153
                    $obj->paye == 0
4154
                    && $obj->status != $tmpobject::STATUS_DRAFT         // Not a draft
4155
                    && $obj->status != $tmpobject::STATUS_ABANDONED     // Not abandoned
4156
                    && $obj->status != $tmpobject::STATUS_CLOSED
4157
                ) {     // Not classified as paid
4158
                    //$sql .= " AND (status <> 3 OR close_code <> 'abandon')";      // Not abandoned for undefined reason
4159
                    $paiement = $tmpobject->getSommePaiement();
4160
                    $creditnotes = $tmpobject->getSumCreditNotesUsed();
4161
                    $deposits = $tmpobject->getSumDepositsUsed();
4162
4163
                    $remaintopay = ($obj->total_ttc - $paiement - $creditnotes - $deposits);
4164
                    $outstandingOpened += $remaintopay;
4165
                }
4166
4167
                //if credit note is converted but not used
4168
                // TODO Do this also for customer ?
4169
                if ($mode == 'supplier' && $obj->type == FactureFournisseur::TYPE_CREDIT_NOTE && $tmpobject->isCreditNoteUsed()) {
4170
                    $remainingcreditnote = $tmpobject->getSumFromThisCreditNotesNotUsed();
4171
                    $remaintopay -= $remainingcreditnote;
4172
                    $outstandingOpened -= $remainingcreditnote;
4173
                }
4174
4175
                if ($remaintopay) {
4176
                    $arrayofrefopened[$obj->rowid] = $obj->ref;
4177
                }
4178
            }
4179
            return ['opened' => $outstandingOpened, 'total_ht' => $outstandingTotal, 'total_ttc' => $outstandingTotalIncTax, 'refs' => $arrayofref, 'refsopened' => $arrayofrefopened]; // 'opened' is 'incl taxes'
4180
        } else {
4181
            dol_syslog("Sql error " . $this->db->lasterror, LOG_ERR);
4182
            return [];
4183
        }
4184
    }
4185
4186
    /**
4187
     * Return label of status customer is prospect/customer
4188
     *
4189
     * @return   string         Label
4190
     * @see getTypeUrl()
4191
     */
4192
    public function getLibCustProspStatut()
4193
    {
4194
        return $this->LibCustProspStatut($this->client);
4195
    }
4196
4197
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4198
4199
    /**
4200
     *  Return the label of the customer/prospect status
4201
     *
4202
     * @param int $status Id of prospection status
4203
     *
4204
     * @return string                  Label of prospection status
4205
     */
4206
    public function LibCustProspStatut($status)
4207
    {
4208
        // phpcs:enable
4209
        global $langs;
4210
        $langs->load('companies');
4211
4212
        if ($status == 0) {
4213
            return $langs->trans("NorProspectNorCustomer");
4214
        } elseif ($status == 1) {
4215
            return $langs->trans("Customer");
4216
        } elseif ($status == 2) {
4217
            return $langs->trans("Prospect");
4218
        } elseif ($status == 3) {
4219
            return $langs->trans("ProspectCustomer");
4220
        }
4221
4222
        return '';
4223
    }
4224
4225
    /**
4226
     *  Create a document onto disk according to template module.
4227
     *
4228
     * @param string     $modele      Generator to use. Caller must set it to obj->model_pdf.
4229
     * @param Translate  $outputlangs object lang a utiliser pour traduction
0 ignored issues
show
Bug introduced by
The type DoliModules\Company\Model\Translate was not found. Did you mean Translate? If so, make sure to prefix the type with \.
Loading history...
4230
     * @param int        $hidedetails Hide details of lines
4231
     * @param int        $hidedesc    Hide description
4232
     * @param int        $hideref     Hide ref
4233
     * @param null|array $moreparams  Array to provide more information
4234
     *
4235
     * @return int                         Return integer <0 if KO, >0 if OK
4236
     */
4237
    public function generateDocument($modele, $outputlangs, $hidedetails = 0, $hidedesc = 0, $hideref = 0, $moreparams = null)
4238
    {
4239
        global $langs;
4240
4241
        if (!empty($moreparams) && !empty($moreparams['use_companybankid'])) {
4242
            $modelpath = "core/modules/bank/doc/";
4243
4244
            include_once DOL_DOCUMENT_ROOT . '/societe/class/companybankaccount.class.php';
4245
            $companybankaccount = new CompanyBankAccount($this->db);
4246
            $result = $companybankaccount->fetch($moreparams['use_companybankid']);
4247
            if (!$result) {
4248
                dol_print_error($this->db, $companybankaccount->error, $companybankaccount->errors);
4249
            }
4250
            $result = $companybankaccount->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4251
            $this->last_main_doc = $companybankaccount->last_main_doc;
4252
        } else {
4253
            // Positionne le modele sur le nom du modele a utiliser
4254
            if (!dol_strlen($modele)) {
4255
                if (getDolGlobalString('COMPANY_ADDON_PDF')) {
4256
                    $modele = getDolGlobalString('COMPANY_ADDON_PDF');
4257
                } else {
4258
                    print $langs->trans("Error") . " " . $langs->trans("Error_COMPANY_ADDON_PDF_NotDefined");
4259
                    return 0;
4260
                }
4261
            }
4262
4263
            if (!isset($this->bank_account)) {
4264
                $bac = new CompanyBankAccount($this->db);
4265
                // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
4266
                $result = $bac->fetch(0, $this->id);
4267
                if ($result > 0) {
4268
                    $this->bank_account = $bac;
4269
                } else {
4270
                    $this->bank_account = '';
4271
                }
4272
            }
4273
4274
            $modelpath = "core/modules/societe/doc/";
4275
4276
            $result = $this->commonGenerateDocument($modelpath, $modele, $outputlangs, $hidedetails, $hidedesc, $hideref, $moreparams);
4277
        }
4278
4279
        return $result;
4280
    }
4281
4282
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4283
4284
    /**
4285
     * Sets sales representatives of the thirdparty
4286
     *
4287
     * @param int[]|int $salesrep User ID or array of user IDs
4288
     * @param bool      $onlyAdd  Only add (no delete before)
4289
     *
4290
     * @return  int                         Return integer <0 if KO, >0 if OK
4291
     */
4292
    public function setSalesRep($salesrep, $onlyAdd = false)
4293
    {
4294
        global $user;
4295
4296
        // Handle single user
4297
        if (!is_array($salesrep)) {
4298
            $salesrep = [$salesrep];
4299
        }
4300
4301
        $to_del = []; // Nothing to delete
4302
        $to_add = $salesrep;
4303
        if ($onlyAdd === false) {
4304
            // Get current users
4305
            $existing = $this->getSalesRepresentatives($user, 1);
4306
4307
            // Diff
4308
            if (is_array($existing)) {
4309
                $to_del = array_diff($existing, $salesrep);
4310
                $to_add = array_diff($salesrep, $existing);
4311
            }
4312
        }
4313
4314
        $error = 0;
4315
4316
        // Process
4317
        foreach ($to_del as $del) {
4318
            $this->del_commercial($user, $del);
4319
        }
4320
        foreach ($to_add as $add) {
4321
            $result = $this->add_commercial($user, $add);
4322
            if ($result < 0) {
4323
                $error++;
4324
                break;
4325
            }
4326
        }
4327
4328
        return $error ? -1 : 1;
4329
    }
4330
4331
    /**
4332
     *  Return array of sales representatives
4333
     *
4334
     * @param User   $user      Object user (not used)
4335
     * @param int    $mode      0=Array with properties, 1=Array of id.
4336
     * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda,t2.fieldb'
4337
     * @param string $sortorder Sort order, separated by comma. Example: 'ASC,DESC';
4338
     *
4339
     * @return array|int                   Array of sales representatives of third party or <0 if KO
4340
     */
4341
    public function getSalesRepresentatives(User $user, $mode = 0, $sortfield = null, $sortorder = null)
4342
    {
4343
        global $conf;
4344
4345
        $reparray = [];
4346
4347
        $sql = "SELECT DISTINCT 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";
4348
        $sql .= ", u.office_fax, u.user_mobile, u.personal_mobile";
4349
        $sql .= " FROM " . MAIN_DB_PREFIX . "societe_commerciaux as sc, " . MAIN_DB_PREFIX . "user as u";
4350
        if (isModEnabled('multicompany') && getDolGlobalString('MULTICOMPANY_TRANSVERSE_MODE')) {
4351
            $sql .= ", " . MAIN_DB_PREFIX . "usergroup_user as ug";
4352
            $sql .= " WHERE ((ug.fk_user = sc.fk_user";
4353
            $sql .= " AND ug.entity = " . $conf->entity . ")";
4354
            $sql .= " OR u.admin = 1)";
4355
        } else {
4356
            $sql .= " WHERE entity in (0, " . $conf->entity . ")";
4357
        }
4358
4359
        $sql .= " AND u.rowid = sc.fk_user AND sc.fk_soc = " . ((int) $this->id);
4360
        if (empty($sortfield) && empty($sortorder)) {
4361
            $sortfield = 'u.lastname,u.firstname';
4362
            $sortorder = 'ASC,ASC';
4363
        }
4364
        $sql .= $this->db->order($sortfield, $sortorder);
4365
4366
        $resql = $this->db->query($sql);
4367
        if ($resql) {
4368
            $num = $this->db->num_rows($resql);
4369
            $i = 0;
4370
            while ($i < $num) {
4371
                $obj = $this->db->fetch_object($resql);
4372
4373
                if (empty($mode)) {
4374
                    $reparray[$i]['id'] = $obj->rowid;
4375
                    $reparray[$i]['lastname'] = $obj->lastname;
4376
                    $reparray[$i]['firstname'] = $obj->firstname;
4377
                    $reparray[$i]['email'] = $obj->email;
4378
                    $reparray[$i]['phone'] = $obj->office_phone;
4379
                    $reparray[$i]['office_phone'] = $obj->office_phone;         // Pro phone
4380
                    $reparray[$i]['office_fax'] = $obj->office_fax;
4381
                    $reparray[$i]['user_mobile'] = $obj->user_mobile;           // Pro mobile
4382
                    $reparray[$i]['personal_mobile'] = $obj->personal_mobile;   // Personal mobile
4383
                    $reparray[$i]['job'] = $obj->job;
4384
                    $reparray[$i]['statut'] = $obj->status; // deprecated
4385
                    $reparray[$i]['status'] = $obj->status;
4386
                    $reparray[$i]['entity'] = $obj->entity;
4387
                    $reparray[$i]['login'] = $obj->login;
4388
                    $reparray[$i]['photo'] = $obj->photo;
4389
                    $reparray[$i]['gender'] = $obj->gender;
4390
                } else {
4391
                    $reparray[] = $obj->rowid;
4392
                }
4393
                $i++;
4394
            }
4395
            return $reparray;
4396
        } else {
4397
            dol_print_error($this->db);
4398
            return -1;
4399
        }
4400
    }
4401
4402
    /**
4403
     *  Add link to sales representative
4404
     *
4405
     * @param User $user   Object user
4406
     * @param int  $commid Id of user
4407
     *
4408
     * @return int                 Return <0 if KO, >0 if OK
4409
     */
4410
    public function del_commercial(User $user, $commid)
4411
    {
4412
        // phpcs:enable
4413
        $error = 0;
4414
        $this->context = ['commercial_modified' => $commid];
4415
4416
        $result = $this->call_trigger('COMPANY_UNLINK_SALE_REPRESENTATIVE', $user);
4417
        if ($result < 0) {
4418
            $error++;
4419
        }
4420
4421
        if ($this->id > 0 && $commid > 0) {
4422
            $sql = "DELETE FROM  " . MAIN_DB_PREFIX . "societe_commerciaux ";
4423
            $sql .= " WHERE fk_soc = " . ((int) $this->id) . " AND fk_user = " . ((int) $commid);
4424
4425
            if (!$this->db->query($sql)) {
4426
                $error++;
4427
                dol_syslog(get_class($this) . "::del_commercial Erreur");
4428
            }
4429
        }
4430
4431
        if ($error) {
4432
            return -1;
4433
        } else {
4434
            return 1;
4435
        }
4436
    }
4437
4438
    /**
4439
     *    Define third-party type of current company
4440
     *
4441
     * @param int $typent_id third party type rowid in llx_c_typent
4442
     *
4443
     * @return   int                 Return integer <0 if KO, >0 if OK
4444
     */
4445
    public function setThirdpartyType($typent_id)
4446
    {
4447
        global $user;
4448
4449
        dol_syslog(__METHOD__, LOG_DEBUG);
4450
4451
        if ($this->id) {
4452
            $result = $this->setValueFrom('fk_typent', $typent_id, '', null, '', '', $user, 'COMPANY_MODIFY');
4453
4454
            if ($result > 0) {
4455
                $this->typent_id = $typent_id;
4456
                $this->typent_code = dol_getIdFromCode($this->db, $this->typent_id, 'c_typent', 'id', 'code');
4457
                return 1;
4458
            } else {
4459
                return -1;
4460
            }
4461
        } else {
4462
            return -1;
4463
        }
4464
    }
4465
4466
    /**
4467
     * Sets an accountancy code for a thirdparty.
4468
     * Also calls COMPANY_MODIFY trigger when modified
4469
     *
4470
     * @param string $type  It can be only 'buy' or 'sell'
4471
     * @param string $value Accountancy code
4472
     *
4473
     * @return  int             Return integer <0 KO >0 OK
4474
     */
4475
    public function setAccountancyCode($type, $value)
4476
    {
4477
        global $user, $langs, $conf;
4478
4479
        $this->db->begin();
4480
4481
        if ($type == 'buy') {
4482
            $field = 'accountancy_code_buy';
4483
        } elseif ($type == 'sell') {
4484
            $field = 'accountancy_code_sell';
4485
        } else {
4486
            return -1;
4487
        }
4488
4489
        $sql = "UPDATE " . MAIN_DB_PREFIX . $this->table_element . " SET ";
4490
        $sql .= $field . " = '" . $this->db->escape($value) . "'";
4491
        $sql .= " WHERE rowid = " . ((int) $this->id);
4492
4493
        dol_syslog(get_class($this) . "::" . __FUNCTION__, LOG_DEBUG);
4494
        $resql = $this->db->query($sql);
4495
4496
        if ($resql) {
4497
            // Call triggers
4498
            include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
4499
            $interface = new Interfaces($this->db);
4500
            $result = $interface->run_triggers('COMPANY_MODIFY', $this, $user, $langs, $conf);
4501
            if ($result < 0) {
4502
                $this->errors = $interface->errors;
4503
                $this->db->rollback();
4504
                return -1;
4505
            }
4506
            // End call triggers
4507
4508
            $this->$field = $value;
4509
4510
            $this->db->commit();
4511
            return 1;
4512
        } else {
4513
            $this->error = $this->db->lasterror();
4514
            $this->db->rollback();
4515
            return -1;
4516
        }
4517
    }
4518
4519
    // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
4520
4521
    /**
4522
     *  Function to get partnerships array
4523
     *
4524
     * @param string $mode 'member' or 'thirdparty'
4525
     *
4526
     * @return     int                     Return integer <0 if KO, >0 if OK
4527
     */
4528
    public function fetchPartnerships($mode)
4529
    {
4530
        global $langs;
4531
4532
        require_once DOL_DOCUMENT_ROOT . '/partnership/class/partnership.class.php';
4533
4534
4535
        $this->partnerships[] = [];
4536
4537
        return 1;
4538
    }
4539
4540
    /**
4541
     *  Return clicable link of object (with eventually picto)
4542
     *
4543
     * @param string $option    Where point the link (0=> main card, 1,2 => shipment, 'nolink'=>No link)
4544
     * @param array  $arraydata Array of data
4545
     *
4546
     * @return     string                              HTML Code for Kanban thumb.
4547
     */
4548
    public function getKanbanView($option = '', $arraydata = null)
4549
    {
4550
        $selected = (empty($arraydata['selected']) ? 0 : $arraydata['selected']);
4551
4552
        $return = '<div class="box-flex-item box-flex-grow-zero">';
4553
        $return .= '<div class="info-box info-box-sm">';
4554
        $return .= '<span class="info-box-icon bg-infobox-action">';
4555
        $return .= img_picto('', $this->picto);
4556
        $return .= '</span>';
4557
        $return .= '<div class="info-box-content">';
4558
        $return .= '<span class="info-box-ref inline-block tdoverflowmax150 valignmiddle">' . (method_exists($this, 'getNomUrl') ? $this->getNomUrl() : $this->ref) . '</span>';
4559
        if ($selected >= 0) {
4560
            $return .= '<input id="cb' . $this->id . '" class="flat checkforselect fright" type="checkbox" name="toselect[]" value="' . $this->id . '"' . ($selected ? ' checked="checked"' : '') . '>';
4561
        }
4562
        if (property_exists($this, 'code_client')) {
4563
            $return .= '<br><span class="info-box-label opacitymedium">' . $this->code_client . '</span>';
4564
        }
4565
        if (method_exists($this, 'getLibStatut')) {
4566
            $return .= '<br><div class="info-box-status">' . $this->getLibStatut(3) . '</div>';
4567
        }
4568
        $return .= '</div>';
4569
        $return .= '</div>';
4570
        $return .= '</div>';
4571
4572
        return $return;
4573
    }
4574
4575
    /**
4576
     *      Return a link on thirdparty (with picto)
4577
     *
4578
     * @param int    $withpicto             Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
4579
     * @param string $option                Target of link ('', 'customer', 'prospect', 'supplier', 'project')
4580
     * @param int    $maxlen                Max length of name
4581
     * @param int    $notooltip             1=Disable tooltip
4582
     * @param int    $save_lastsearch_value -1=Auto, 0=No save of lastsearch_values when clicking, 1=Save
4583
     *                                      lastsearch_values whenclicking
4584
     * @param int    $noaliasinname         1=Do not add alias into the link ref
4585
     * @param string $target                add attribute target
4586
     * @param string $morecss               More CSS
4587
     *
4588
     * @return string                              String with URL
4589
     */
4590
    public function getNomUrl($withpicto = 0, $option = '', $maxlen = 0, $notooltip = 0, $save_lastsearch_value = -1, $noaliasinname = 0, $target = '', $morecss = '')
4591
    {
4592
        global $conf, $langs, $hookmanager, $user;
4593
4594
        if (!empty($conf->dol_no_mouse_hover)) {
4595
            $notooltip = 1; // Force disable tooltips
4596
        }
4597
4598
        $name = $this->name ? $this->name : $this->nom;
0 ignored issues
show
Deprecated Code introduced by
The property DoliModules\Company\Model\Company::$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

4598
        $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...
4599
4600
        if (getDolGlobalString('SOCIETE_ON_SEARCH_AND_LIST_GO_ON_CUSTOMER_OR_SUPPLIER_CARD')) {
4601
            if (empty($option) && $this->client > 0) {
4602
                $option = 'customer';
4603
            }
4604
            if (empty($option) && $this->fournisseur > 0) {
4605
                $option = 'supplier';
4606
            }
4607
        }
4608
4609
        if (getDolGlobalString('SOCIETE_ADD_REF_IN_LIST') && (!empty($withpicto))) {
4610
            $code = '';
4611
            if (($this->client) && (!empty($this->code_client)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 2)) {
4612
                $code = $this->code_client . ' - ';
4613
            }
4614
4615
            if (($this->fournisseur) && (!empty($this->code_fournisseur)) && (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1 || getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 3)) {
4616
                $code .= $this->code_fournisseur . ' - ';
4617
            }
4618
4619
            if ($code) {
4620
                if (getDolGlobalInt('SOCIETE_ADD_REF_IN_LIST') == 1) {
4621
                    $name = $code . ' ' . $name;
4622
                } else {
4623
                    $name = $code;
4624
                }
4625
            }
4626
        }
4627
4628
        if (!empty($this->name_alias) && empty($noaliasinname)) {
4629
            $name .= ' (' . $this->name_alias . ')';
4630
        }
4631
4632
        $result = '';
4633
        $params = [
4634
            'id' => $this->id,
4635
            'objecttype' => $this->element,
4636
            'option' => $option,
4637
            'nofetch' => 1,
4638
        ];
4639
        $classfortooltip = 'classfortooltip';
4640
        $dataparams = '';
4641
        if (getDolGlobalInt('MAIN_ENABLE_AJAX_TOOLTIP')) {
4642
            $classfortooltip = 'classforajaxtooltip';
4643
            $dataparams = ' data-params="' . dol_escape_htmltag(json_encode($params)) . '"';
4644
            $label = '';
4645
        } else {
4646
            $label = implode($this->getTooltipContentArray($params));
4647
        }
4648
4649
        $linkstart = '';
4650
        $linkend = '';
4651
4652
        if ($option == 'customer' || $option == 'compta' || $option == 'category') {
4653
            $linkstart = '<a href="' . DOL_URL_ROOT . '/comm/card.php?socid=' . $this->id;
4654
        } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
4655
            $linkstart = '<a href="' . DOL_URL_ROOT . '/comm/card.php?socid=' . $this->id;
4656
        } elseif ($option == 'supplier' || $option == 'category_supplier') {
4657
            $linkstart = '<a href="' . DOL_URL_ROOT . '/fourn/card.php?socid=' . $this->id;
4658
        } elseif ($option == 'agenda') {
4659
            $linkstart = '<a href="' . DOL_URL_ROOT . '/societe/agenda.php?socid=' . $this->id;
4660
        } elseif ($option == 'project') {
4661
            $linkstart = '<a href="' . DOL_URL_ROOT . '/societe/project.php?socid=' . $this->id;
4662
        } elseif ($option == 'margin') {
4663
            $linkstart = '<a href="' . DOL_URL_ROOT . '/margin/tabs/thirdpartyMargins.php?socid=' . $this->id . '&type=1';
4664
        } elseif ($option == 'contact') {
4665
            $linkstart = '<a href="' . DOL_URL_ROOT . '/societe/contact.php?socid=' . $this->id;
4666
        } elseif ($option == 'ban') {
4667
            $linkstart = '<a href="' . DOL_URL_ROOT . '/societe/paymentmodes.php?socid=' . $this->id;
4668
        }
4669
4670
        // By default
4671
        if (empty($linkstart)) {
4672
            $linkstart = '<a href="' . DOL_URL_ROOT . '/societe/card.php?socid=' . $this->id;
4673
        }
4674
4675
        // Add type of canvas
4676
        $linkstart .= (!empty($this->canvas) ? '&canvas=' . $this->canvas : '');
4677
        // Add param to save lastsearch_values or not
4678
        $add_save_lastsearch_values = ($save_lastsearch_value == 1 ? 1 : 0);
4679
        if ($save_lastsearch_value == -1 && isset($_SERVER['PHP_SELF']) && preg_match('/list\.php/', $_SERVER['PHP_SELF'])) {
4680
            $add_save_lastsearch_values = 1;
4681
        }
4682
        if ($add_save_lastsearch_values) {
4683
            $linkstart .= '&save_lastsearch_values=1';
4684
        }
4685
        $linkstart .= '"';
4686
4687
        $linkclose = '';
4688
        if (empty($notooltip)) {
4689
            if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
4690
                $label = $langs->trans("ShowCompany");
4691
                $linkclose .= ' alt="' . dol_escape_htmltag($label, 1) . '"';
4692
            }
4693
            $linkclose .= ($label ? ' title="' . dol_escape_htmltag($label, 1) . '"' : ' title="tocomplete"');
4694
            $linkclose .= $dataparams . ' class="' . $classfortooltip . ($morecss ? ' ' . $morecss : '') . ' refurl valignmiddle"';
4695
            $target_value = ['_self', '_blank', '_parent', '_top'];
4696
            if (in_array($target, $target_value)) {
4697
                $linkclose .= ' target="' . dol_escape_htmltag($target) . '"';
4698
            }
4699
        } else {
4700
            $linkclose .= ' class="valignmiddle' . ($morecss ? ' ' . $morecss : '') . '"';
4701
        }
4702
        $linkstart .= $linkclose . '>';
4703
        $linkend = '</a>';
4704
4705
        if (!$user->hasRight('societe', 'client', 'voir') && $user->socid > 0 && $this->id != $user->socid) {
4706
            $linkstart = '';
4707
            $linkend = '';
4708
        }
4709
4710
        $result .= $linkstart;
4711
        if ($withpicto) {
4712
            $result .= img_object(($notooltip ? '' : $label), ($this->picto ? $this->picto : 'generic'), (' class="' . (($withpicto != 2) ? 'paddingright' : '') . '"'), 0, 0, $notooltip ? 0 : 1);
4713
        }
4714
        if ($withpicto != 2) {
4715
            $result .= dol_escape_htmltag($maxlen ? dol_trunc($name, $maxlen) : $name);
4716
        }
4717
        $result .= $linkend;
4718
4719
        global $action;
4720
        $hookmanager->initHooks(['thirdpartydao']);
4721
        $parameters = [
4722
            'id' => $this->id,
4723
            'getnomurl' => &$result,
4724
            'withpicto ' => $withpicto,
4725
            'option' => $option,
4726
            'maxlen' => $maxlen,
4727
            'notooltip' => $notooltip,
4728
            'save_lastsearch_value' => $save_lastsearch_value,
4729
        ];
4730
        $reshook = $hookmanager->executeHooks('getNomUrl', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
4731
        if ($reshook > 0) {
4732
            $result = $hookmanager->resPrint;
4733
        } else {
4734
            $result .= $hookmanager->resPrint;
4735
        }
4736
4737
        return $result;
4738
    }
4739
4740
    /**
4741
     * getTooltipContentArray
4742
     *
4743
     * @param array $params params to construct tooltip data
4744
     *
4745
     * @return array
4746
     * @since v18
4747
     */
4748
    public function getTooltipContentArray($params)
4749
    {
4750
        global $conf, $langs, $user;
4751
4752
        $langs->loadLangs(['companies', 'commercial']);
4753
4754
        $datas = [];
4755
4756
        $option = $params['option'] ?? '';
4757
        $nofetch = !empty($params['nofetch']);
4758
4759
        $noaliasinname = (empty($params['noaliasinname']) ? 0 : $params['noaliasinname']);
4760
4761
        if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
4762
            return ['optimize' => $langs->trans("ShowCompany")];
4763
        }
4764
4765
        if (!empty($this->logo) && class_exists('Form')) {
4766
            $photo = '<div class="photointooltip floatright">';
4767
            $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.
4768
            $photo .= '</div>';
4769
            $datas['photo'] = $photo;
4770
        } elseif (!empty($this->logo_squarred) && class_exists('Form')) {
4771
            /*$label.= '<div class="photointooltip">';
4772
            $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.
4773
            $label.= '</div><div style="clear: both;"></div>';*/
4774
        }
4775
4776
        $datas['divopen'] = '<div class="centpercent">';
4777
4778
        if ($option == 'customer' || $option == 'compta' || $option == 'category') {
4779
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Customer") . '</u>';
4780
        } elseif ($option == 'prospect' && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
4781
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Prospect") . '</u>';
4782
        } elseif ($option == 'supplier' || $option == 'category_supplier') {
4783
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("Supplier") . '</u>';
4784
        } elseif ($option == 'agenda') {
4785
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4786
        } elseif ($option == 'project') {
4787
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4788
        } elseif ($option == 'margin') {
4789
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4790
        } elseif ($option == 'contact') {
4791
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4792
        } elseif ($option == 'ban') {
4793
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4794
        }
4795
4796
        // By default
4797
        if (empty($datas['picto'])) {
4798
            $datas['picto'] = img_picto('', $this->picto) . ' <u class="paddingrightonly">' . $langs->trans("ThirdParty") . '</u>';
4799
        }
4800
        if (isset($this->status)) {
4801
            $datas['status'] = ' ' . $this->getLibStatut(5);
4802
        }
4803
        if (isset($this->client) && isset($this->fournisseur)) {
4804
            $datas['type'] = ' &nbsp; ' . $this->getTypeUrl(1);
4805
        }
4806
        $datas['name'] = '<br><b>' . $langs->trans('Name') . ':</b> ' . dol_escape_htmltag(dol_string_nohtmltag($this->name));
4807
        if (!empty($this->name_alias) && empty($noaliasinname)) {
4808
            $datas['namealias'] = ' (' . dol_escape_htmltag(dol_string_nohtmltag($this->name_alias)) . ')';
4809
        }
4810
        if (!empty($this->email)) {
4811
            $datas['email'] = '<br>' . img_picto('', 'email', 'class="pictofixedwidth"') . $this->email;
4812
        }
4813
        if (!empty($this->url)) {
4814
            $datas['url'] = '<br>' . img_picto('', 'globe', 'class="pictofixedwidth"') . $this->url;
4815
        }
4816
        if (!empty($this->phone) || !empty($this->phone_mobile) || !empty($this->fax)) {
4817
            $phonelist = [];
4818
            if ($this->phone) {
4819
                $phonelist[] = dol_print_phone($this->phone, $this->country_code, $this->id, 0, '', '&nbsp', 'phone');
4820
            }
4821
            // deliberately not making new list because fax uses same list as phone
4822
            if ($this->phone_mobile) {
4823
                $phonelist[] = dol_print_phone($this->phone_mobile, $this->country_code, $this->id, 0, '', '&nbsp', 'phone_mobile');
4824
            }
4825
            if ($this->fax) {
4826
                $phonelist[] = dol_print_phone($this->fax, $this->country_code, $this->id, 0, '', '&nbsp', 'fax');
4827
            }
4828
            $datas['phonelist'] = '<br>' . implode('&nbsp;', $phonelist);
4829
        }
4830
4831
        if (!empty($this->address)) {
4832
            $datas['address'] = '<br><b>' . $langs->trans("Address") . ':</b> ' . dol_format_address($this, 1, ' ', $langs); // Address + country
4833
        } elseif (!empty($this->country_code)) {
4834
            $datas['address'] = '<br><b>' . $langs->trans('Country') . ':</b> ' . $this->country_code;
4835
        }
4836
        if (!empty($this->tva_intra) || (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP') && strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'vatnumber') !== false)) {
4837
            $datas['vatintra'] = '<br><b>' . $langs->trans('VATIntra') . ':</b> ' . dol_escape_htmltag($this->tva_intra);
4838
        }
4839
4840
        if (getDolGlobalString('SOCIETE_SHOW_FIELD_IN_TOOLTIP')) {
4841
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid1') !== false && $langs->trans('ProfId1' . $this->country_code) != '-') {
4842
                $datas['profid1'] = '<br><b>' . $langs->trans('ProfId1' . $this->country_code) . ':</b> ' . $this->idprof1;
4843
            }
4844
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid2') !== false && $langs->trans('ProfId2' . $this->country_code) != '-') {
4845
                $datas['profid2'] = '<br><b>' . $langs->trans('ProfId2' . $this->country_code) . ':</b> ' . $this->idprof2;
4846
            }
4847
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid3') !== false && $langs->trans('ProfId3' . $this->country_code) != '-') {
4848
                $datas['profid3'] = '<br><b>' . $langs->trans('ProfId3' . $this->country_code) . ':</b> ' . $this->idprof3;
4849
            }
4850
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid4') !== false && $langs->trans('ProfId4' . $this->country_code) != '-') {
4851
                $datas['profid4'] = '<br><b>' . $langs->trans('ProfId4' . $this->country_code) . ':</b> ' . $this->idprof4;
4852
            }
4853
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid5') !== false && $langs->trans('ProfId5' . $this->country_code) != '-') {
4854
                $datas['profid5'] = '<br><b>' . $langs->trans('ProfId5' . $this->country_code) . ':</b> ' . $this->idprof5;
4855
            }
4856
            if (strpos($conf->global->SOCIETE_SHOW_FIELD_IN_TOOLTIP, 'profid6') !== false && $langs->trans('ProfId6' . $this->country_code) != '-') {
4857
                $datas['profid6'] = '<br><b>' . $langs->trans('ProfId6' . $this->country_code) . ':</b> ' . $this->idprof6;
4858
            }
4859
        }
4860
4861
        $datas['separator'] = '<br>';
4862
4863
        if (!empty($this->code_client) && ($this->client == 1 || $this->client == 3)) {
4864
            $datas['customercode'] = '<br><b>' . $langs->trans('CustomerCode') . ':</b> ' . $this->code_client;
4865
        }
4866
        if (isModEnabled('accounting') && ($this->client == 1 || $this->client == 3)) {
4867
            $langs->load('compta');
4868
            $datas['accountancycustomercode'] = '<br><b>' . $langs->trans('CustomerAccountancyCode') . ':</b> ' . ($this->code_compta ? $this->code_compta : $this->code_compta_client);
4869
        }
4870
        // show categories for this record only in ajax to not overload lists
4871
        if (!$nofetch && isModEnabled('category') && $this->client) {
4872
            $form = new Form($this->db);
4873
            $datas['categories_customer'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_CUSTOMER, 1, 1);
4874
        }
4875
        if (!empty($this->code_fournisseur) && $this->fournisseur) {
4876
            $datas['suppliercode'] = '<br><b>' . $langs->trans('SupplierCode') . ':</b> ' . $this->code_fournisseur;
4877
        }
4878
        if (isModEnabled('accounting') && $this->fournisseur) {
4879
            $langs->load('compta');
4880
            $datas['accountancysuppliercode'] = '<br><b>' . $langs->trans('SupplierAccountancyCode') . ':</b> ' . $this->code_compta_fournisseur;
4881
        }
4882
        // show categories for this record only in ajax to not overload lists
4883
        if (!$nofetch && isModEnabled('category') && $this->fournisseur) {
4884
            $form = new Form($this->db);
4885
            $datas['categories_supplier'] = '<br>' . $form->showCategories($this->id, Categorie::TYPE_SUPPLIER, 1, 1);
4886
        }
4887
4888
        $datas['divclose'] = '</div>';
4889
4890
        return $datas;
4891
    }
4892
4893
    /**
4894
     *    Return label of status (activity, closed)
4895
     *
4896
     * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=Short
4897
     *                  label + Picto, 6=Long label + Picto
4898
     *
4899
     * @return   string              Label of status
4900
     */
4901
    public function getLibStatut($mode = 0)
4902
    {
4903
        return $this->LibStatut($this->status, $mode);
4904
    }
4905
4906
    /**
4907
     *  Return the label of a given status
4908
     *
4909
     * @param int $status Status id
4910
     * @param int $mode   0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short
4911
     *                    label + Picto, 6=Long label + Picto
4912
     *
4913
     * @return string                  Status label
4914
     */
4915
    public function LibStatut($status, $mode = 0)
4916
    {
4917
        // phpcs:enable
4918
        global $langs;
4919
        $langs->load('companies');
4920
4921
        $statusType = 'status4';
4922
        if ($status == 0) {
4923
            $statusType = 'status6';
4924
        }
4925
4926
        if (empty($this->labelStatus) || empty($this->labelStatusShort)) {
4927
            $this->labelStatus[0] = $langs->transnoentitiesnoconv("ActivityCeased");
4928
            $this->labelStatus[1] = $langs->transnoentitiesnoconv("InActivity");
4929
            $this->labelStatusShort[0] = $langs->transnoentitiesnoconv("ActivityCeased");
4930
            $this->labelStatusShort[1] = $langs->transnoentitiesnoconv("InActivity");
4931
        }
4932
4933
        return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode);
4934
    }
4935
4936
    /**
4937
     *      Return link(s) on type of thirdparty (with picto)
4938
     *
4939
     * @param int    $withpicto Add picto into link (0=No picto, 1=Include picto with link, 2=Picto only)
4940
     * @param string $option    ''=All
4941
     * @param int    $notooltip 1=Disable tooltip
4942
     * @param string $tag       Tag 'a' or 'span'
4943
     *
4944
     * @return string                          String with URL
4945
     */
4946
    public function getTypeUrl($withpicto = 0, $option = '', $notooltip = 0, $tag = 'a')
4947
    {
4948
        global $conf, $langs;
4949
4950
        $s = '';
4951
        if (empty($option) || preg_match('/prospect/', $option)) {
4952
            if (($this->client == 2 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_PROSPECTS')) {
4953
                $s .= '<' . $tag . ' class="customer-back opacitymedium" title="' . $langs->trans("Prospect") . '" href="' . DOL_URL_ROOT . '/comm/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Prospect"), 0, 1) . '</' . $tag . '>';
4954
            }
4955
        }
4956
        if (empty($option) || preg_match('/customer/', $option)) {
4957
            if (($this->client == 1 || $this->client == 3) && !getDolGlobalString('SOCIETE_DISABLE_CUSTOMERS')) {
4958
                $s .= '<' . $tag . ' class="customer-back" title="' . $langs->trans("Customer") . '" href="' . DOL_URL_ROOT . '/comm/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Customer"), 0, 1) . '</' . $tag . '>';
4959
            }
4960
        }
4961
        if (empty($option) || preg_match('/supplier/', $option)) {
4962
            if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && $this->fournisseur) {
4963
                $s .= '<' . $tag . ' class="vendor-back" title="' . $langs->trans("Supplier") . '" href="' . DOL_URL_ROOT . '/fourn/card.php?socid=' . $this->id . '">' . dol_substr($langs->trans("Supplier"), 0, 1) . '</' . $tag . '>';
4964
            }
4965
        }
4966
        return $s;
4967
    }
4968
4969
    /**
4970
     *    Get array of all contacts for a society (stored in societe_contacts instead of element_contacts for all other
4971
     *    objects)
4972
     *
4973
     * @param int    $list    0:Return array contains all properties, 1:Return array contains just id
4974
     * @param string $code    Filter on this code of contact type ('SHIPPING', 'BILLING', ...)
4975
     * @param string $element Filter on this element of default contact type ('facture', 'propal', 'commande' ...)
4976
     *
4977
     * @return   array|int               Array of contacts, -1 if error
4978
     *
4979
     */
4980
    public function getContacts($list = 0, $code = '', $element = '')
4981
    {
4982
        // phpcs:enable
4983
        global $langs;
4984
4985
        $tab = [];
4986
4987
        $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
4988
        $sql .= ", t.fk_soc as socid, t.statut as statuscontact";
4989
        $sql .= ", t.civility as civility, t.lastname as lastname, t.firstname, t.email";
4990
        $sql .= ", tc.source, tc.element, tc.code, tc.libelle as type_label";
4991
        $sql .= " FROM " . $this->db->prefix() . "c_type_contact tc";
4992
        $sql .= ", " . $this->db->prefix() . "societe_contacts sc";
4993
        $sql .= " LEFT JOIN " . $this->db->prefix() . "socpeople t on sc.fk_socpeople = t.rowid";
4994
        $sql .= " WHERE sc.fk_soc = " . ((int) $this->id);
4995
        $sql .= " AND sc.fk_c_type_contact = tc.rowid";
4996
        if (!empty($element)) {
4997
            $sql .= " AND tc.element = '" . $this->db->escape($element) . "'";
4998
        }
4999
        if ($code) {
5000
            $sql .= " AND tc.code = '" . $this->db->escape($code) . "'";
5001
        }
5002
        $sql .= " AND sc.entity IN (" . getEntity($this->element) . ")";
5003
        $sql .= " AND tc.source = 'external'";
5004
        $sql .= " AND tc.active = 1";
5005
5006
        $sql .= " ORDER BY t.lastname ASC";
5007
5008
        dol_syslog(get_class($this) . "::getContacts", LOG_DEBUG);
5009
        $resql = $this->db->query($sql);
5010
        if ($resql) {
5011
            $num = $this->db->num_rows($resql);
5012
            $i = 0;
5013
            while ($i < $num) {
5014
                $obj = $this->db->fetch_object($resql);
5015
5016
                if (!$list) {
5017
                    $transkey = "TypeContact_" . $obj->element . "_" . $obj->source . "_" . $obj->code;
5018
                    $libelle_type = ($langs->trans($transkey) != $transkey ? $langs->trans($transkey) : $obj->type_label);
5019
                    $tab[$i] = [
5020
                        'source' => $obj->source,
5021
                        'socid' => $obj->socid,
5022
                        'id' => $obj->id,
5023
                        'nom' => $obj->lastname, // For backward compatibility
5024
                        'civility' => $obj->civility,
5025
                        'lastname' => $obj->lastname,
5026
                        'firstname' => $obj->firstname,
5027
                        'email' => $obj->email,
5028
                        'login' => (empty($obj->login) ? '' : $obj->login),
5029
                        'photo' => (empty($obj->photo) ? '' : $obj->photo),
5030
                        'statuscontact' => $obj->statuscontact,
5031
                        'rowid' => $obj->rowid,
5032
                        'code' => $obj->code,
5033
                        'element' => $obj->element,
5034
                        'libelle' => $libelle_type,
5035
                        'status' => $obj->statuslink,
5036
                        'fk_c_type_contact' => $obj->fk_c_type_contact,
5037
                    ];
5038
                } else {
5039
                    $tab[$i] = $obj->id;
5040
                }
5041
5042
                $i++;
5043
            }
5044
5045
            return $tab;
5046
        } else {
5047
            $this->error = $this->db->lasterror();
5048
            dol_print_error($this->db);
5049
            return -1;
5050
        }
5051
    }
5052
5053
    /**
5054
     *    Merge a company with another one, deleting the given company.
5055
     *    The company given in parameter will be removed.
5056
     *
5057
     * @param int $soc_origin_id Company to merge the data from
5058
     *
5059
     * @return   int                         -1 if error
5060
     */
5061
    public function mergeCompany($soc_origin_id)
5062
    {
5063
        global $conf, $langs, $hookmanager, $user, $action;
5064
5065
        $error = 0;
5066
        $soc_origin = new Societe($this->db);       // The thirdparty that we will delete
0 ignored issues
show
Deprecated Code introduced by
The class DoliModules\Company\Model\Societe has been deprecated: Use Company instead! ( Ignorable by Annotation )

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

5066
        $soc_origin = /** @scrutinizer ignore-deprecated */ new Societe($this->db);       // The thirdparty that we will delete
Loading history...
5067
5068
        dol_syslog("mergeCompany merge thirdparty id=" . $soc_origin_id . " (will be deleted) into the thirdparty id=" . $this->id);
5069
5070
        if (!$error && $soc_origin->fetch($soc_origin_id) < 1) {
5071
            $this->error = $langs->trans('ErrorRecordNotFound');
5072
            $error++;
5073
        }
5074
5075
        if (!$error) {
5076
            $this->db->begin();
5077
5078
            // Recopy some data
5079
            $this->client = $this->client | $soc_origin->client;
5080
            $this->fournisseur = $this->fournisseur | $soc_origin->fournisseur;
5081
            $listofproperties = [
5082
                'address', 'zip', 'town', 'state_id', 'country_id', 'phone', 'phone_mobile', 'fax', 'email', 'socialnetworks', 'url', 'barcode',
5083
                'idprof1', 'idprof2', 'idprof3', 'idprof4', 'idprof5', 'idprof6',
5084
                'tva_intra', 'effectif_id', 'forme_juridique', 'remise_percent', 'remise_supplier_percent', 'mode_reglement_supplier_id', 'cond_reglement_supplier_id', 'name_bis',
5085
                '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',
5086
                'code_client', 'code_fournisseur', 'code_compta', 'code_compta_fournisseur',
5087
                'model_pdf', 'webservices_url', 'webservices_key', 'accountancy_code_sell', 'accountancy_code_buy', 'typent_id',
5088
            ];
5089
            foreach ($listofproperties as $property) {
5090
                if (empty($this->$property)) {
5091
                    $this->$property = $soc_origin->$property;
5092
                }
5093
            }
5094
5095
            if ($this->typent_id == -1) {
5096
                $this->typent_id = $soc_origin->typent_id;
5097
            }
5098
5099
            // Concat some data
5100
            $listofproperties = [
5101
                'note_public', 'note_private',
5102
            ];
5103
            foreach ($listofproperties as $property) {
5104
                $this->$property = dol_concatdesc($this->$property, $soc_origin->$property);
5105
            }
5106
5107
            // Merge extrafields
5108
            if (is_array($soc_origin->array_options)) {
5109
                foreach ($soc_origin->array_options as $key => $val) {
5110
                    if (empty($this->array_options[$key])) {
5111
                        $this->array_options[$key] = $val;
5112
                    }
5113
                }
5114
            }
5115
5116
            // If alias name is not defined on target thirdparty, we can store in it the old name of company.
5117
            if (empty($this->name_bis) && $this->name != $soc_origin->name) {
5118
                $this->name_bis = $this->name;
5119
            }
5120
5121
            // Merge categories
5122
            $static_cat = new Categorie($this->db);
5123
5124
            $custcats_ori = $static_cat->containing($soc_origin->id, 'customer', 'id');
5125
            $custcats = $static_cat->containing($this->id, 'customer', 'id');
5126
            $custcats = array_merge($custcats, $custcats_ori);
5127
            $this->setCategories($custcats, 'customer');
5128
5129
            $suppcats_ori = $static_cat->containing($soc_origin->id, 'supplier', 'id');
5130
            $suppcats = $static_cat->containing($this->id, 'supplier', 'id');
5131
            $suppcats = array_merge($suppcats, $suppcats_ori);
5132
            $this->setCategories($suppcats, 'supplier');
5133
5134
            // If thirdparty has a new code that is same than origin, we clean origin code to avoid duplicate key from database unique keys.
5135
            if (
5136
                $soc_origin->code_client == $this->code_client
5137
                || $soc_origin->code_fournisseur == $this->code_fournisseur
5138
                || $soc_origin->barcode == $this->barcode
5139
            ) {
5140
                dol_syslog("We clean customer and supplier code so we will be able to make the update of target");
5141
                $soc_origin->code_client = '';
5142
                $soc_origin->code_fournisseur = '';
5143
                $soc_origin->barcode = '';
5144
                $soc_origin->update($soc_origin->id, $user, 0, 1, 1, 'merge');
5145
            }
5146
5147
            // Update
5148
            $result = $this->update($this->id, $user, 0, 1, 1, 'merge');
5149
5150
            if ($result < 0) {
5151
                $error++;
5152
            }
5153
5154
            // Move links
5155
            if (!$error) {
5156
                $objects = [
5157
                    'Adherent' => '/adherents/class/adherent.class.php',
5158
                    'Societe' => '/societe/class/societe.class.php',
5159
                    //'Categorie' => '/categories/class/categorie.class.php',   // Already processed previously
5160
                    'ActionComm' => '/comm/action/class/actioncomm.class.php',
5161
                    'Propal' => '/comm/propal/class/propal.class.php',
5162
                    'Commande' => '/commande/class/commande.class.php',
5163
                    'Facture' => '/compta/facture/class/facture.class.php',
5164
                    'FactureRec' => '/compta/facture/class/facture-rec.class.php',
5165
                    'LignePrelevement' => '/compta/prelevement/class/ligneprelevement.class.php',
5166
                    'Mo' => '/mrp/class/mo.class.php',
5167
                    'Contact' => '/contact/class/contact.class.php',
5168
                    'Contrat' => '/contrat/class/contrat.class.php',
5169
                    'Expedition' => '/expedition/class/expedition.class.php',
5170
                    'CommandeFournisseur' => '/fourn/class/fournisseur.commande.class.php',
5171
                    'FactureFournisseur' => '/fourn/class/fournisseur.facture.class.php',
5172
                    'FactureFournisseurRec' => '/fourn/class/fournisseur.facture-rec.class.php',
5173
                    'Reception' => '/reception/class/reception.class.php',
5174
                    'SupplierProposal' => '/supplier_proposal/class/supplier_proposal.class.php',
5175
                    'ProductFournisseur' => '/fourn/class/fournisseur.product.class.php',
5176
                    'Delivery' => '/delivery/class/delivery.class.php',
5177
                    'Product' => '/product/class/product.class.php',
5178
                    'Project' => '/projet/class/project.class.php',
5179
                    'User' => '/user/class/user.class.php',
5180
                    'Account' => '/compta/bank/class/account.class.php',
5181
                    'ConferenceOrBoothAttendee' => '/eventorganization/class/conferenceorboothattendee.class.php',
5182
                ];
5183
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'don')) {
5184
                    $objects['Don'] = '/don/class/don.class.php';
5185
                }
5186
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'partnership')) {
5187
                    $objects['PartnerShip'] = '/partnership/class/partnership.class.php';
5188
                }
5189
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'fichinter')) {
5190
                    $objects['Fichinter'] = '/fichinter/class/fichinter.class.php';
5191
                }
5192
                if ($this->db->DDLListTables($conf->db->name, $this->db->prefix() . 'ticket')) {
5193
                    $objects['Ticket'] = '/ticket/class/ticket.class.php';
5194
                }
5195
5196
                //First, all core objects must update their tables
5197
                foreach ($objects as $object_name => $object_file) {
5198
                    if (is_array($object_file)) {
5199
                        if (empty($object_file['enabled'])) {
5200
                            continue;
5201
                        }
5202
                        $object_file = $object_file['file'];
5203
                    }
5204
5205
                    require_once DOL_DOCUMENT_ROOT . $object_file;
5206
5207
                    if (!$error && !$object_name::replaceThirdparty($this->db, $soc_origin->id, $this->id)) {
5208
                        $error++;
5209
                        $this->error = $this->db->lasterror();
5210
                        break;
5211
                    }
5212
                }
5213
            }
5214
5215
            // External modules should update their ones too
5216
            if (!$error) {
5217
                $parameters = ['soc_origin' => $soc_origin->id, 'soc_dest' => $this->id];
5218
                $reshook = $hookmanager->executeHooks('replaceThirdparty', $parameters, $this, $action);
5219
5220
                if ($reshook < 0) {
5221
                    $this->error = $hookmanager->error;
5222
                    $this->errors = $hookmanager->errors;
5223
                    $error++;
5224
                }
5225
            }
5226
5227
5228
            if (!$error) {
5229
                $this->context = ['merge' => 1, 'mergefromid' => $soc_origin->id, 'mergefromname' => $soc_origin->name];
5230
5231
                // Call trigger
5232
                $result = $this->call_trigger('COMPANY_MODIFY', $user);
5233
                if ($result < 0) {
5234
                    $error++;
5235
                }
5236
                // End call triggers
5237
            }
5238
5239
            if (!$error) {
5240
                // We finally remove the old thirdparty
5241
                if ($soc_origin->delete($soc_origin->id, $user) < 1) {
5242
                    $this->error = $soc_origin->error;
5243
                    $this->errors = $soc_origin->errors;
5244
                    $error++;
5245
                }
5246
            }
5247
5248
            if (!$error) {
5249
                $this->db->commit();
5250
                return 0;
5251
            } else {
5252
                $langs->load("errors");
5253
                $this->error = $langs->trans('ErrorsThirdpartyMerge');
5254
                $this->db->rollback();
5255
                return -1;
5256
            }
5257
        }
5258
5259
        return -1;
5260
    }
5261
5262
    /**
5263
     * Function used to replace a thirdparty id with another one.
5264
     * It must be used within a transaction to avoid trouble
5265
     *
5266
     * @param DoliDB $dbs       Database handler, because function is static we name it $dbs not $db to avoid breaking
5267
     *                          coding test
5268
     * @param int    $origin_id Old thirdparty id (will be removed)
5269
     * @param int    $dest_id   New thirdparty id
5270
     *
5271
     * @return  bool                True if success, False if error
5272
     */
5273
    public static function replaceThirdparty(DoliDB $dbs, $origin_id, $dest_id)
5274
    {
5275
        if ($origin_id == $dest_id) {
5276
            dol_syslog('Error: Try to merge a thirdparty into itself');
5277
            return false;
5278
        }
5279
5280
        /**
5281
         * Thirdparty commercials cannot be the same in both thirdparties so we look for them and remove some to avoid duplicate.
5282
         * Because this function is meant to be executed within a transaction, we won't take care of begin/commit.
5283
         */
5284
        $sql = 'SELECT rowid FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux ';
5285
        $sql .= ' WHERE fk_soc = ' . (int) $dest_id . ' AND fk_user IN ( ';
5286
        $sql .= ' SELECT fk_user ';
5287
        $sql .= ' FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux ';
5288
        $sql .= ' WHERE fk_soc = ' . (int) $origin_id . ') ';
5289
5290
        $resql = $dbs->query($sql);
5291
        while ($obj = $dbs->fetch_object($resql)) {
5292
            $dbs->query('DELETE FROM ' . MAIN_DB_PREFIX . 'societe_commerciaux WHERE rowid = ' . ((int) $obj->rowid));
5293
        }
5294
5295
        /**
5296
         * llx_societe_extrafields table must not be here because we don't care about the old thirdparty extrafields that are managed directly into mergeCompany.
5297
         * Do not include llx_societe because it will be replaced later.
5298
         */
5299
        $tables = [
5300
            'societe_account',
5301
            'societe_commerciaux',
5302
            'societe_prices',
5303
            'societe_remise',
5304
            'societe_remise_except',
5305
            'societe_rib',
5306
        ];
5307
5308
        return CommonObject::commonReplaceThirdparty($dbs, $origin_id, $dest_id, $tables);
5309
    }
5310
5311
    /**
5312
     *    Delete a third party from database and all its dependencies (contacts, rib...)
5313
     *
5314
     * @param int       $id           Id of third party to delete
5315
     * @param User|null $fuser        User who ask to delete thirdparty
5316
     * @param int       $call_trigger 0=No, 1=yes
5317
     *
5318
     * @return   int                         Return integer <0 if KO, 0 if nothing done, >0 if OK
5319
     */
5320
    public function delete($id, User $fuser = null, $call_trigger = 1)
5321
    {
5322
        global $conf, $user;
5323
5324
        if (empty($fuser)) {
5325
            $fuser = $user;
5326
        }
5327
5328
        require_once BASE_PATH . '/../Dolibarr/Lib/Files.php';
5329
5330
        $entity = isset($this->entity) ? $this->entity : $conf->entity;
5331
5332
        dol_syslog(get_class($this) . "::delete", LOG_DEBUG);
5333
        $error = 0;
5334
5335
        // Test if child exists
5336
        $objectisused = $this->isObjectUsed($id);
5337
        if (empty($objectisused)) {
5338
            $this->db->begin();
5339
5340
            // User is mandatory for trigger call
5341
            if (!$error && $call_trigger) {
5342
                // Call trigger
5343
                $result = $this->call_trigger('COMPANY_DELETE', $fuser);
5344
                if ($result < 0) {
5345
                    $error++;
5346
                }
5347
                // End call triggers
5348
            }
5349
5350
            if (!$error) {
5351
                $static_cat = new Categorie($this->db);
5352
                $toute_categs = [];
5353
5354
                // Fill $toute_categs array with an array of (type => array of ("Categorie" instance))
5355
                if ($this->client || $this->prospect) {
5356
                    $toute_categs['customer'] = $static_cat->containing($this->id, Categorie::TYPE_CUSTOMER);
5357
                }
5358
                if ($this->fournisseur) {
5359
                    $toute_categs['supplier'] = $static_cat->containing($this->id, Categorie::TYPE_SUPPLIER);
5360
                }
5361
5362
                // Remove each "Categorie"
5363
                foreach ($toute_categs as $type => $categs_type) {
5364
                    foreach ($categs_type as $cat) {
5365
                        $cat->del_type($this, $type);
5366
                    }
5367
                }
5368
            }
5369
5370
            if (!$error) {
5371
                foreach ($this->childtablesoncascade as $tabletodelete) {
5372
                    $deleteFromObject = explode(':', $tabletodelete, 4);
5373
                    if (count($deleteFromObject) >= 2) {
5374
                        $className = str_replace('@', '', $deleteFromObject[0]);
5375
                        $filepath = $deleteFromObject[1];
5376
                        $columnName = $deleteFromObject[2];
5377
                        if (dol_include_once($filepath)) {
5378
                            $child_object = new $className($this->db);
5379
                            $result = $child_object->deleteByParentField($id, $columnName);
5380
                            if ($result < 0) {
5381
                                $error++;
5382
                                $this->errors[] = $child_object->error;
5383
                                break;
5384
                            }
5385
                        } else {
5386
                            $error++;
5387
                            $this->errors[] = 'Cannot include child class file ' . $filepath;
5388
                            break;
5389
                        }
5390
                    } else {
5391
                        $sql = "DELETE FROM " . MAIN_DB_PREFIX . $tabletodelete;
5392
                        $sql .= " WHERE fk_soc = " . ((int) $id);
5393
                        if (!$this->db->query($sql)) {
5394
                            $error++;
5395
                            $this->errors[] = $this->db->lasterror();
5396
                            break;
5397
                        }
5398
                    }
5399
                }
5400
            }
5401
5402
            // Removed extrafields
5403
            if (!$error) {
5404
                $result = $this->deleteExtraFields();
5405
                if ($result < 0) {
5406
                    $error++;
5407
                    dol_syslog(get_class($this) . "::delete error -3 " . $this->error, LOG_ERR);
5408
                }
5409
            }
5410
5411
            // Remove links to subsidiaries companies
5412
            if (!$error) {
5413
                $sql = "UPDATE " . MAIN_DB_PREFIX . "societe";
5414
                $sql .= " SET parent = NULL";
5415
                $sql .= " WHERE parent = " . ((int) $id);
5416
                if (!$this->db->query($sql)) {
5417
                    $error++;
5418
                    $this->errors[] = $this->db->lasterror();
5419
                }
5420
            }
5421
5422
            // Remove third party
5423
            if (!$error) {
5424
                if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
5425
                    $sql = "DELETE FROM " . MAIN_DB_PREFIX . "societe_perentity";
5426
                    $sql .= " WHERE fk_soc = " . ((int) $id);
5427
                    if (!$this->db->query($sql)) {
5428
                        $error++;
5429
                        $this->errors[] = $this->db->lasterror();
5430
                    }
5431
                }
5432
5433
                $sql = "DELETE FROM " . MAIN_DB_PREFIX . "societe";
5434
                $sql .= " WHERE rowid = " . ((int) $id);
5435
                if (!$this->db->query($sql)) {
5436
                    $error++;
5437
                    $this->errors[] = $this->db->lasterror();
5438
                }
5439
            }
5440
5441
            if (!$error) {
5442
                $this->db->commit();
5443
5444
                // Delete directory
5445
                if (!empty($conf->societe->multidir_output[$entity])) {
5446
                    $docdir = $conf->societe->multidir_output[$entity] . "/" . $id;
5447
                    if (dol_is_dir($docdir)) {
5448
                        dol_delete_dir_recursive($docdir);
5449
                    }
5450
                }
5451
5452
                return 1;
5453
            } else {
5454
                dol_syslog($this->error, LOG_ERR);
5455
                $this->db->rollback();
5456
                return -1;
5457
            }
5458
        } else {
5459
            dol_syslog("Can't remove thirdparty with id " . $id . ". There are " . $objectisused . " children", LOG_WARNING);
5460
        }
5461
        return 0;
5462
    }
5463
}
5464